Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 409f64ee authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Metadata database now creates a new entry on acl connection events,...

Merge "Metadata database now creates a new entry on acl connection events, updates last_active_time on a2dp, hfp, or hearing aid active device changes, and exposes new function to get most recently connected devices ordered by last_active_time" am: b4c75fce am: 3b30dd88

Change-Id: I9b0433dd60914dd0c4721eb81da234b58a8ecc86
parents d4915030 3b30dd88
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class AdapterService extends Service {
    private static final String TAG = "BluetoothAdapterService";
@@ -1333,6 +1334,19 @@ public class AdapterService extends Service {
            return service.mAdapterProperties.discoveryEndMillis();
        }

        @Override
        public List<BluetoothDevice> getMostRecentlyConnectedDevices() {
            // don't check caller, may be called from system UI
            AdapterService service = getService();
            if (service == null) {
                return new ArrayList<>();
            }

            enforceBluetoothAdminPermission(service);

            return service.mDatabaseManager.getMostRecentlyConnectedDevices();
        }

        @Override
        public BluetoothDevice[] getBondedDevices() {
            // don't check caller, may be called from system UI
+29 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.content.BroadcastReceiver;
@@ -80,6 +81,7 @@ class PhonePolicy {
    private static final int MESSAGE_CONNECT_OTHER_PROFILES = 3;
    private static final int MESSAGE_ADAPTER_STATE_TURNED_ON = 4;
    private static final int MESSAGE_PROFILE_ACTIVE_DEVICE_CHANGED = 5;
    private static final int MESSAGE_DEVICE_CONNECTED = 6;

    // Timeouts
    @VisibleForTesting static int sConnectOtherProfilesTimeoutMillis = 6000; // 6s
@@ -116,6 +118,16 @@ class PhonePolicy {
                            BluetoothProfile.A2DP, -1, // No-op argument
                            intent).sendToTarget();
                    break;
                case BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED:
                    mHandler.obtainMessage(MESSAGE_PROFILE_ACTIVE_DEVICE_CHANGED,
                            BluetoothProfile.HEADSET, -1, // No-op argument
                            intent).sendToTarget();
                    break;
                case BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED:
                    mHandler.obtainMessage(MESSAGE_PROFILE_ACTIVE_DEVICE_CHANGED,
                            BluetoothProfile.HEARING_AID, -1, // No-op argument
                            intent).sendToTarget();
                    break;
                case BluetoothAdapter.ACTION_STATE_CHANGED:
                    // Only pass the message on if the adapter has actually changed state from
                    // non-ON to ON. NOTE: ON is the state depicting BREDR ON and not just BLE ON.
@@ -127,6 +139,8 @@ class PhonePolicy {
                case BluetoothDevice.ACTION_UUID:
                    mHandler.obtainMessage(MESSAGE_PROFILE_INIT_PRIORITIES, intent).sendToTarget();
                    break;
                case BluetoothDevice.ACTION_ACL_CONNECTED:
                    mHandler.obtainMessage(MESSAGE_DEVICE_CONNECTED, intent).sendToTarget();
                default:
                    Log.e(TAG, "Received unexpected intent, action=" + action);
                    break;
@@ -196,6 +210,11 @@ class PhonePolicy {
                    resetStates();
                    autoConnect();
                    break;
                case MESSAGE_DEVICE_CONNECTED:
                    Intent intent = (Intent) msg.obj;
                    BluetoothDevice device =
                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    processDeviceConnected(device);
            }
        }
    }
@@ -207,9 +226,12 @@ class PhonePolicy {
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
        filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
        filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        filter.addAction(BluetoothDevice.ACTION_UUID);
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        filter.addAction(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED);
        filter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);
        filter.addAction(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED);
        mAdapterService.registerReceiver(mReceiver, filter);
    }

@@ -308,9 +330,14 @@ class PhonePolicy {
    private void processActiveDeviceChanged(BluetoothDevice device, int profileId) {
        debugLog("processActiveDeviceChanged, device=" + device + ", profile=" + profileId);

        if (device != null && profileId == BluetoothProfile.A2DP) {
            mAdapterService.getDatabase().setConnection(device);
        if (device != null) {
            mAdapterService.getDatabase().setConnection(device, profileId == BluetoothProfile.A2DP);
        }
    }

    private void processDeviceConnected(BluetoothDevice device) {
        debugLog("processDeviceConnected, device=" + device);
        mAdapterService.getDatabase().setConnection(device, false);
    }

    private boolean handleAllProfilesDisconnected(BluetoothDevice device) {
+53 −16
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.google.common.collect.EvictingQueue;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -201,7 +202,7 @@ public class DatabaseManager {
                if (mMetadataCache.containsKey(address)) {
                    return;
                }
                createMetadata(address);
                createMetadata(address, false);
            } else {
                Metadata metadata = mMetadataCache.get(address);
                if (metadata != null) {
@@ -254,7 +255,7 @@ public class DatabaseManager {

            String address = device.getAddress();
            if (!mMetadataCache.containsKey(address)) {
                createMetadata(address);
                createMetadata(address, false);
            }
            Metadata data = mMetadataCache.get(address);
            byte[] oldValue = data.getCustomizedMeta(key);
@@ -337,7 +338,7 @@ public class DatabaseManager {
                if (newConnectionPolicy == BluetoothProfile.CONNECTION_POLICY_UNKNOWN) {
                    return true;
                }
                createMetadata(address);
                createMetadata(address, false);
            }
            Metadata data = mMetadataCache.get(address);
            int oldConnectionPolicy = data.getProfileConnectionPolicy(profile);
@@ -542,25 +543,33 @@ public class DatabaseManager {
     *
     * @param device is the remote bluetooth device for which we are setting the connection time
     */
    public void setConnection(BluetoothDevice device) {
    public void setConnection(BluetoothDevice device, boolean isA2dpDevice) {
        synchronized (mMetadataCache) {
            Log.d(TAG, "setConnection: device=" + device + " and isA2dpDevice=" + isA2dpDevice);
            if (device == null) {
                Log.e(TAG, "setConnection: device is null");
                return;
            }

            if (isA2dpDevice) {
                resetActiveA2dpDevice();
            }

            String address = device.getAddress();

            if (!mMetadataCache.containsKey(address)) {
                Log.d(TAG, "setConnection: Creating new metadata entry for device: " + device);
                createMetadata(address);
                createMetadata(address, isA2dpDevice);
                return;
            }
            // Updates last connected time to either current time if connected or -1 if disconnected
            // Updates last_active_time to the current counter value and increments the counter
            Metadata metadata = mMetadataCache.get(address);
            metadata.last_active_time = MetadataDatabase.sCurrentConnectionNumber++;

            // Only update is_active_a2dp_device if an a2dp device is connected
            if (isA2dpDevice) {
                metadata.is_active_a2dp_device = true;
            }

            Log.d(TAG, "Updating last connected time for device: " + device + " to "
                    + metadata.last_active_time);
@@ -600,6 +609,7 @@ public class DatabaseManager {
     * Remove a2dpActiveDevice from the current active device in the connection order table
     */
    private void resetActiveA2dpDevice() {
        synchronized (mMetadataCache) {
            Log.d(TAG, "resetActiveA2dpDevice()");
            for (Map.Entry<String, Metadata> entry : mMetadataCache.entrySet()) {
                Metadata metadata = entry.getValue();
@@ -610,6 +620,32 @@ public class DatabaseManager {
                }
            }
        }
    }

    /**
     * Gets the most recently connected bluetooth devices in order with most recently connected
     * first and least recently connected last
     *
     * @return a {@link List} of {@link BluetoothDevice} representing connected bluetooth devices
     * in order of most recently connected
     */
    public List<BluetoothDevice> getMostRecentlyConnectedDevices() {
        List<BluetoothDevice> mostRecentlyConnectedDevices = new ArrayList<>();
        synchronized (mMetadataCache) {
            List<Metadata> sortedMetadata = new ArrayList<>(mMetadataCache.values());
            sortedMetadata.sort((o1, o2) -> Long.compare(o2.last_active_time, o1.last_active_time));
            for (Metadata metadata : sortedMetadata) {
                try {
                    mostRecentlyConnectedDevices.add(BluetoothAdapter.getDefaultAdapter()
                            .getRemoteDevice(metadata.getAddress()));
                } catch (IllegalArgumentException ex) {
                    Log.d(TAG, "getBondedDevicesOrdered: Invalid address for "
                            + "device " + metadata.getAddress());
                }
            }
        }
        return mostRecentlyConnectedDevices;
    }

    /**
     * Gets the last active a2dp device
@@ -728,8 +764,9 @@ public class DatabaseManager {
        mMetadataCache.clear();
    }

    void createMetadata(String address) {
    void createMetadata(String address, boolean isActiveA2dpDevice) {
        Metadata data = new Metadata(address);
        data.is_active_a2dp_device = isActiveA2dpDevice;
        mMetadataCache.put(address, data);
        updateDatabase(data);
        logMetadataChange(address, "Metadata created");
+12 −12
Original line number Diff line number Diff line
@@ -202,10 +202,10 @@ public class PhonePolicyTest {

        // Only calls setConnection on device connectionOrder.get(0) with STATE_CONNECTED
        verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setConnection(
                connectionOrder.get(0));
        verify(mDatabaseManager, never()).setConnection(eq(connectionOrder.get(1)));
        verify(mDatabaseManager, never()).setConnection(eq(connectionOrder.get(2)));
        verify(mDatabaseManager, never()).setConnection(eq(connectionOrder.get(3)));
                connectionOrder.get(0), true);
        verify(mDatabaseManager, never()).setConnection(eq(connectionOrder.get(1)), anyBoolean());
        verify(mDatabaseManager, never()).setConnection(eq(connectionOrder.get(2)), anyBoolean());
        verify(mDatabaseManager, never()).setConnection(eq(connectionOrder.get(3)), anyBoolean());

        // Make another device active
        when(mHeadsetService.getConnectionState(connectionOrder.get(1))).thenReturn(
@@ -217,11 +217,11 @@ public class PhonePolicyTest {

        // Only calls setConnection on device connectionOrder.get(1) with STATE_CONNECTED
        verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).setConnection(
                connectionOrder.get(0));
                connectionOrder.get(0), true);
        verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).setConnection(
                connectionOrder.get(1));
        verify(mDatabaseManager, never()).setConnection(eq(connectionOrder.get(2)));
        verify(mDatabaseManager, never()).setConnection(eq(connectionOrder.get(3)));
                connectionOrder.get(1), true);
        verify(mDatabaseManager, never()).setConnection(eq(connectionOrder.get(2)), anyBoolean());
        verify(mDatabaseManager, never()).setConnection(eq(connectionOrder.get(3)), anyBoolean());

        // Disconnect a2dp for the device
        when(mHeadsetService.getConnectionState(connectionOrder.get(1))).thenReturn(
@@ -233,10 +233,10 @@ public class PhonePolicyTest {
        intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
        mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent);

        // Verify that we do not call setConnection, but instead deleteConnection on disconnect
        verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).setConnection(
                connectionOrder.get(1));
        // Verify that we do not call setConnection, but instead setDisconnection on disconnect
        verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).setConnection(
                connectionOrder.get(1), true);
        verify(mDatabaseManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).setDisconnection(
                connectionOrder.get(1));

        // Make the current active device fail to connect
@@ -250,7 +250,7 @@ public class PhonePolicyTest {
                connectionOrder.get(1));

        // Verify we didn't have any unexpected calls to setConnection or deleteConnection
        verify(mDatabaseManager, times(2)).setConnection(any(BluetoothDevice.class));
        verify(mDatabaseManager, times(2)).setConnection(any(BluetoothDevice.class), anyBoolean());
        verify(mDatabaseManager, times(1)).setDisconnection(any(BluetoothDevice.class));
    }

+95 −4
Original line number Diff line number Diff line
@@ -68,10 +68,12 @@ public final class DatabaseManagerTest {
    private DatabaseManager mDatabaseManager;
    private BluetoothDevice mTestDevice;
    private BluetoothDevice mTestDevice2;
    private BluetoothDevice mTestDevice3;

    private static final String LOCAL_STORAGE = "LocalStorage";
    private static final String TEST_BT_ADDR = "11:22:33:44:55:66";
    private static final String TEST_BT_ADDR2 = "66:55:44:33:22:11";
    private static final String TEST_BT_ADDR3 = "12:34:56:65:43:21";
    private static final String OTHER_BT_ADDR1 = "11:11:11:11:11:11";
    private static final String OTHER_BT_ADDR2 = "22:22:22:22:22:22";
    private static final String DB_NAME = "test_db";
@@ -92,6 +94,7 @@ public final class DatabaseManagerTest {

        mTestDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_BT_ADDR);
        mTestDevice2 = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_BT_ADDR2);
        mTestDevice3 = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_BT_ADDR3);

        // Create a memory database for DatabaseManager instead of use a real database.
        mDatabase = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getTargetContext(),
@@ -409,15 +412,19 @@ public final class DatabaseManagerTest {
        Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice());

        // Set the first device's connection
        mDatabaseManager.setConnection(mTestDevice);
        mDatabaseManager.setConnection(mTestDevice, true);
        // Wait for database update
        TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper());
        Assert.assertTrue(mDatabaseManager
                .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device);
        List<BluetoothDevice> mostRecentlyConnectedDevicesOrdered =
                mDatabaseManager.getMostRecentlyConnectedDevices();
        Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice());
        Assert.assertEquals(1, mostRecentlyConnectedDevicesOrdered.size());
        Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(0));

        // Setting the second device's connection
        mDatabaseManager.setConnection(mTestDevice2);
        mDatabaseManager.setConnection(mTestDevice2, true);
        // Wait for database update
        TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper());
        Assert.assertFalse(mDatabaseManager
@@ -425,9 +432,13 @@ public final class DatabaseManagerTest {
        Assert.assertTrue(mDatabaseManager
                .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device);
        Assert.assertEquals(mTestDevice2, mDatabaseManager.getMostRecentlyConnectedA2dpDevice());
        mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices();
        Assert.assertEquals(2, mostRecentlyConnectedDevicesOrdered.size());
        Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(0));
        Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1));

        // Connect first test device again
        mDatabaseManager.setConnection(mTestDevice);
        mDatabaseManager.setConnection(mTestDevice, true);
        // Wait for database update
        TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper());
        Assert.assertTrue(mDatabaseManager
@@ -435,6 +446,10 @@ public final class DatabaseManagerTest {
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device);
        Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice());
        mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices();
        Assert.assertEquals(2, mostRecentlyConnectedDevicesOrdered.size());
        Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(0));
        Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(1));

        // Disconnect first test device's connection
        mDatabaseManager.setDisconnection(mTestDevice);
@@ -445,16 +460,61 @@ public final class DatabaseManagerTest {
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device);
        Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice());
        mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices();
        Assert.assertEquals(2, mostRecentlyConnectedDevicesOrdered.size());
        Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(0));
        Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(1));

        // Connect third test device (non-a2dp device)
        mDatabaseManager.setConnection(mTestDevice3, false);
        // Wait for database update
        TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper());
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device);
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device);
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device);
        Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice());
        mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices();
        Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size());
        Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0));
        Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1));
        Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(2));

        // Connect first test device again
        mDatabaseManager.setConnection(mTestDevice);
        mDatabaseManager.setConnection(mTestDevice, true);
        // Wait for database update
        TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper());
        Assert.assertTrue(mDatabaseManager
                .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device);
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device);
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device);
        Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice());
        mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices();
        Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size());
        Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(0));
        Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(1));
        Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(2));

        // Connect third test device again and ensure it doesn't reset active a2dp device
        mDatabaseManager.setConnection(mTestDevice3, false);
        // Wait for database update
        TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper());
        Assert.assertTrue(mDatabaseManager
                .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device);
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device);
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device);
        Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice());
        mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices();
        Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size());
        Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0));
        Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1));
        Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(2));

        // Disconnect second test device
        mDatabaseManager.setDisconnection(mTestDevice2);
@@ -464,7 +524,14 @@ public final class DatabaseManagerTest {
                .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device);
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device);
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device);
        Assert.assertEquals(mTestDevice, mDatabaseManager.getMostRecentlyConnectedA2dpDevice());
        mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices();
        Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size());
        Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0));
        Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1));
        Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(2));

        // Disconnect first test device
        mDatabaseManager.setDisconnection(mTestDevice);
@@ -474,7 +541,31 @@ public final class DatabaseManagerTest {
                .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device);
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device);
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device);
        Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice());
        mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices();
        Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size());
        Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0));
        Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1));
        Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(2));

        // Disconnect third test device
        mDatabaseManager.setDisconnection(mTestDevice3);
        // Wait for database update
        TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper());
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice.getAddress()).is_active_a2dp_device);
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice2.getAddress()).is_active_a2dp_device);
        Assert.assertFalse(mDatabaseManager
                .mMetadataCache.get(mTestDevice3.getAddress()).is_active_a2dp_device);
        Assert.assertNull(mDatabaseManager.getMostRecentlyConnectedA2dpDevice());
        mostRecentlyConnectedDevicesOrdered = mDatabaseManager.getMostRecentlyConnectedDevices();
        Assert.assertEquals(3, mostRecentlyConnectedDevicesOrdered.size());
        Assert.assertEquals(mTestDevice3, mostRecentlyConnectedDevicesOrdered.get(0));
        Assert.assertEquals(mTestDevice, mostRecentlyConnectedDevicesOrdered.get(1));
        Assert.assertEquals(mTestDevice2, mostRecentlyConnectedDevicesOrdered.get(2));

        mDatabaseManager.factoryReset();
        mDatabaseManager.mMetadataCache.clear();