RemoteDevices: Optimize adding new remote devices

RemoteDevices keeps track of the Bluetooth devices which have been
seen since the Bluetooth stack was initialized.  Each time a remote
device is discovered, it is added to a hash map.  When the size of the
hash map grows beyond a few hundred devices, the performance degrades.

This patch:
 - creates the address string once per search
  reducing the average search time with 300 devices from ~20ms to ~1ms
 - uses the hash of the address string to search
  further reducing the time with 1200 devices from ~2ms to ~1ms

HashMap<BluetoothDevice, DeviceProperties> became
 HashMap<String, DeviceProperties>

mDevice now stores the BluetoothDevice in each instance of
DeviceProperties.

TEST: Used System.nanoTime() to measure the elapsed time of
      getDeviceProperties()
Bug: 30828758

Change-Id: Id44886143fb2910955294341d4938d638c72f7f9
Signed-off-by: Myles Watson <mylesgw@google.com>
(cherry picked from commit 1fb90c4f25ba33b0f951e6ac092d05f85d355e2f)
diff --git a/src/com/android/bluetooth/btservice/RemoteDevices.java b/src/com/android/bluetooth/btservice/RemoteDevices.java
index 3ae2455..9eaf7e5 100644
--- a/src/com/android/bluetooth/btservice/RemoteDevices.java
+++ b/src/com/android/bluetooth/btservice/RemoteDevices.java
@@ -45,13 +45,13 @@
     private static final int UUID_INTENT_DELAY = 6000;
     private static final int MESSAGE_UUID_INTENT = 1;
 
-    private HashMap<BluetoothDevice, DeviceProperties> mDevices;
+    private HashMap<String, DeviceProperties> mDevices;
 
     RemoteDevices(AdapterService service) {
         mAdapter = BluetoothAdapter.getDefaultAdapter();
         mAdapterService = service;
         mSdpTracker = new ArrayList<BluetoothDevice>();
-        mDevices = new HashMap<BluetoothDevice, DeviceProperties>();
+        mDevices = new HashMap<String, DeviceProperties>();
     }
 
 
@@ -70,26 +70,23 @@
 
     DeviceProperties getDeviceProperties(BluetoothDevice device) {
         synchronized (mDevices) {
-            return mDevices.get(device);
+            return mDevices.get(device.getAddress());
         }
     }
 
     BluetoothDevice getDevice(byte[] address) {
-        for (BluetoothDevice dev : mDevices.keySet()) {
-            if (dev.getAddress().equals(Utils.getAddressStringFromByte(address))) {
-                return dev;
-            }
-        }
-        return null;
+        DeviceProperties prop = mDevices.get(Utils.getAddressStringFromByte(address));
+        if (prop == null)
+           return null;
+        return prop.getDevice();
     }
 
     DeviceProperties addDeviceProperties(byte[] address) {
         synchronized (mDevices) {
             DeviceProperties prop = new DeviceProperties();
-            BluetoothDevice device =
-                    mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
+            prop.mDevice = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
             prop.mAddress = address;
-            mDevices.put(device, prop);
+            mDevices.put(Utils.getAddressStringFromByte(address), prop);
             return prop;
         }
     }
@@ -103,6 +100,7 @@
         private int mDeviceType;
         private String mAlias;
         private int mBondState;
+        private BluetoothDevice mDevice;
 
         DeviceProperties() {
             mBondState = BluetoothDevice.BOND_NONE;
@@ -145,6 +143,15 @@
         }
 
         /**
+         * @return the mDevice
+         */
+        BluetoothDevice getDevice() {
+            synchronized (mObject) {
+                return mDevice;
+            }
+        }
+
+        /**
          * @return mRssi
          */
         short getRssi() {