1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.server; 18 19 import android.os.ParcelUuid; 20 import android.util.Log; 21 22 import java.util.HashMap; 23 import java.util.Map; 24 import java.util.Set; 25 26 class BluetoothDeviceProperties { 27 28 private static final String TAG = "BluetoothDeviceProperties"; 29 30 private final HashMap<String, Map<String, String>> mPropertiesMap; 31 private final BluetoothService mService; 32 33 BluetoothDeviceProperties(BluetoothService service) { 34 mPropertiesMap = new HashMap<String, Map<String, String>>(); 35 mService = service; 36 } 37 38 Map<String, String> addProperties(String address, String[] properties) { 39 /* 40 * We get a DeviceFound signal every time RSSI changes or name changes. 41 * Don't create a new Map object every time. 42 */ 43 Map<String, String> propertyValues; 44 synchronized(mPropertiesMap) { 45 propertyValues = mPropertiesMap.get(address); 46 if (propertyValues == null) { 47 propertyValues = new HashMap<String, String>(); 48 } 49 50 for (int i = 0; i < properties.length; i++) { 51 String name = properties[i]; 52 String newValue = null; 53 int len; 54 if (name == null) { 55 Log.e(TAG, "Error: Remote Device Property at index " 56 + i + " is null"); 57 continue; 58 } 59 if (name.equals("UUIDs") || name.equals("Nodes")) { 60 StringBuilder str = new StringBuilder(); 61 len = Integer.valueOf(properties[++i]); 62 for (int j = 0; j < len; j++) { 63 str.append(properties[++i]); 64 str.append(","); 65 } 66 if (len > 0) { 67 newValue = str.toString(); 68 } 69 } else { 70 newValue = properties[++i]; 71 } 72 73 propertyValues.put(name, newValue); 74 } 75 mPropertiesMap.put(address, propertyValues); 76 } 77 78 // We have added a new remote device or updated its properties. 79 // Also update the serviceChannel cache. 80 mService.updateDeviceServiceChannelCache(address); 81 return propertyValues; 82 } 83 84 void setProperty(String address, String name, String value) { 85 synchronized(mPropertiesMap) { 86 Map <String, String> propVal = mPropertiesMap.get(address); 87 if (propVal != null) { 88 propVal.put(name, value); 89 mPropertiesMap.put(address, propVal); 90 } else { 91 Log.e(TAG, "setRemoteDeviceProperty for a device not in cache:" + address); 92 } 93 } 94 } 95 96 boolean isInCache(String address) { 97 synchronized (mPropertiesMap) { 98 return (mPropertiesMap.get(address) != null); 99 } 100 } 101 102 boolean isEmpty() { 103 synchronized (mPropertiesMap) { 104 return mPropertiesMap.isEmpty(); 105 } 106 } 107 108 Set<String> keySet() { 109 synchronized (mPropertiesMap) { 110 return mPropertiesMap.keySet(); 111 } 112 } 113 114 String getProperty(String address, String property) { 115 synchronized(mPropertiesMap) { 116 Map<String, String> properties = mPropertiesMap.get(address); 117 if (properties != null) { 118 return properties.get(property); 119 } else { 120 // Query for remote device properties, again. 121 // We will need to reload the cache when we switch Bluetooth on / off 122 // or if we crash. 123 properties = updateCache(address); 124 if (properties != null) { 125 return properties.get(property); 126 } 127 } 128 } 129 Log.e(TAG, "getRemoteDeviceProperty: " + property + " not present: " + address); 130 return null; 131 } 132 133 Map<String, String> updateCache(String address) { 134 String[] propValues = mService.getRemoteDeviceProperties(address); 135 if (propValues != null) { 136 return addProperties(address, propValues); 137 } 138 return null; 139 } 140 } 141