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

Commit 55083170 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Support metadata APIs for Bluetooth storage"

parents 28a6873c 3f2a154d
Loading
Loading
Loading
Loading
+98 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.IBluetooth;
import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothMetadataListener;
import android.bluetooth.IBluetoothSocketManager;
import android.bluetooth.OobData;
import android.bluetooth.UidTraffic;
@@ -168,6 +169,8 @@ public class AdapterService extends Service {

    private boolean mNativeAvailable;
    private boolean mCleaningUp;
    private final HashMap<BluetoothDevice, ArrayList<IBluetoothMetadataListener>>
            mMetadataListeners = new HashMap<>();
    private final HashMap<String, Integer> mProfileServicesState = new HashMap<String, Integer>();
    //Only BluetoothManagerService should be registered
    private RemoteCallbackList<IBluetoothCallback> mCallbacks;
@@ -1618,6 +1621,43 @@ public class AdapterService extends Service {
            return service.reportActivityInfo();
        }

        @Override
        public boolean registerMetadataListener(IBluetoothMetadataListener listener,
                BluetoothDevice device) {
            AdapterService service = getService();
            if (service == null) {
                return false;
            }
            return service.registerMetadataListener(listener, device);
        }

        @Override
        public boolean unregisterMetadataListener(BluetoothDevice device) {
            AdapterService service = getService();
            if (service == null) {
                return false;
            }
            return service.unregisterMetadataListener(device);
        }

        @Override
        public boolean setMetadata(BluetoothDevice device, int key, String value) {
            AdapterService service = getService();
            if (service == null) {
                return false;
            }
            return service.setMetadata(device, key, value);
        }

        @Override
        public String getMetadata(BluetoothDevice device, int key) {
            AdapterService service = getService();
            if (service == null) {
                return null;
            }
            return service.getMetadata(device, key);
        }

        @Override
        public void requestActivityInfo(ResultReceiver result) {
            Bundle bundle = new Bundle();
@@ -2531,6 +2571,64 @@ public class AdapterService extends Service {
                + ctrlState + "traffic = " + Arrays.toString(data));
    }

    boolean registerMetadataListener(IBluetoothMetadataListener listener,
            BluetoothDevice device) {
        if (mMetadataListeners == null) {
            return false;
        }

        ArrayList<IBluetoothMetadataListener> list = mMetadataListeners.get(device);
        if (list == null) {
            list = new ArrayList<>();
        } else if (list.contains(listener)) {
            // The device is already registered with this listener
            return true;
        }
        list.add(listener);
        mMetadataListeners.put(device, list);
        return true;
    }

    boolean unregisterMetadataListener(BluetoothDevice device) {
        if (mMetadataListeners == null) {
            return false;
        }
        if (mMetadataListeners.containsKey(device)) {
            mMetadataListeners.remove(device);
        }
        return true;
    }

    boolean setMetadata(BluetoothDevice device, int key, String value) {
        if (value.length() > BluetoothDevice.METADATA_MAX_LENGTH) {
            Log.e(TAG, "setMetadata: value length too long " + value.length());
            return false;
        }
        return mDatabaseManager.setCustomMeta(device, key, value);
    }

    String getMetadata(BluetoothDevice device, int key) {
        return mDatabaseManager.getCustomMeta(device, key);
    }

    /**
     * Update metadata change to registered listeners
     */
    @VisibleForTesting
    public void metadataChanged(String address, int key, String value) {
        BluetoothDevice device = mRemoteDevices.getDevice(address.getBytes());
        if (mMetadataListeners.containsKey(device)) {
            ArrayList<IBluetoothMetadataListener> list = mMetadataListeners.get(device);
            for (IBluetoothMetadataListener listener : list) {
                try {
                    listener.onMetadataChanged(device, key, value);
                } catch (RemoteException e) {
                    Log.w(TAG, "RemoteException when onMetadataChanged");
                }
            }
        }
    }

    private int getIdleCurrentMa() {
        return getResources().getInteger(R.integer.config_bluetooth_idle_cur_ma);
    }
+96 −1
Original line number Diff line number Diff line
@@ -159,6 +159,97 @@ public class DatabaseManager {
        }
    }

    boolean isValidMetaKey(int key) {
        switch (key) {
            case BluetoothDevice.METADATA_MANUFACTURER_NAME:
            case BluetoothDevice.METADATA_MODEL_NAME:
            case BluetoothDevice.METADATA_SOFTWARE_VERSION:
            case BluetoothDevice.METADATA_HARDWARE_VERSION:
            case BluetoothDevice.METADATA_COMPANION_APP:
            case BluetoothDevice.METADATA_MAIN_ICON:
            case BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET:
            case BluetoothDevice.METADATA_UNTHETHERED_LEFT_ICON:
            case BluetoothDevice.METADATA_UNTHETHERED_RIGHT_ICON:
            case BluetoothDevice.METADATA_UNTHETHERED_CASE_ICON:
            case BluetoothDevice.METADATA_UNTHETHERED_LEFT_BATTERY:
            case BluetoothDevice.METADATA_UNTHETHERED_RIGHT_BATTERY:
            case BluetoothDevice.METADATA_UNTHETHERED_CASE_BATTERY:
            case BluetoothDevice.METADATA_UNTHETHERED_LEFT_CHARGING:
            case BluetoothDevice.METADATA_UNTHETHERED_RIGHT_CHARGING:
            case BluetoothDevice.METADATA_UNTHETHERED_CASE_CHARGING:
            case BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI:
                return true;
        }
        Log.w(TAG, "Invalid metadata key " + key);
        return false;
    }

    /**
     * Set customized metadata to database with requested key
     */
    @VisibleForTesting
    public boolean setCustomMeta(BluetoothDevice device, int key, String newValue) {
        synchronized (mMetadataCache) {
            if (device == null) {
                Log.e(TAG, "setCustomMeta: device is null");
                return false;
            }
            if (!isValidMetaKey(key)) {
                Log.e(TAG, "setCustomMeta: meta key invalid " + key);
                return false;
            }

            String address = device.getAddress();
            if (VERBOSE) {
                Log.d(TAG, "setCustomMeta: " + address + ", key=" + key);
            }
            if (!mMetadataCache.containsKey(address)) {
                createMetadata(address);
            }
            Metadata data = mMetadataCache.get(address);
            String oldValue = data.getCustomizedMeta(key);
            if (oldValue != null && oldValue.equals(newValue)) {
                if (VERBOSE) {
                    Log.d(TAG, "setCustomMeta: metadata not changed.");
                }
                return true;
            }
            data.setCustomizedMeta(key, newValue);

            updateDatabase(data);
            mAdapterService.metadataChanged(address, key, newValue);
            return true;
        }
    }

    /**
     * Get customized metadata from database with requested key
     */
    @VisibleForTesting
    public String getCustomMeta(BluetoothDevice device, int key) {
        synchronized (mMetadataCache) {
            if (device == null) {
                Log.e(TAG, "getCustomMeta: device is null");
                return null;
            }
            if (!isValidMetaKey(key)) {
                Log.e(TAG, "getCustomMeta: meta key invalid " + key);
                return null;
            }

            String address = device.getAddress();

            if (!mMetadataCache.containsKey(address)) {
                Log.e(TAG, "getCustomMeta: device " + address + " is not in cache");
                return null;
            }

            Metadata data = mMetadataCache.get(address);
            String value = data.getCustomizedMeta(key);
            return value;
        }
    }

    /**
     * Set the device profile prioirty
     *
@@ -476,8 +567,12 @@ public class DatabaseManager {
                for (BluetoothDevice device : bondedDevices) {
                    if (!device.getAddress().equals(address)
                            && !address.equals(LOCAL_STORAGE)) {
                        // Report metadata change to null
                        List<Integer> list = metadata.getChangedCustomizedMeta();
                        for (int key : list) {
                            mAdapterService.metadataChanged(address, key, null);
                        }
                        Log.i(TAG, "remove unpaired device from database " + address);
                        //TODO Callback metadata change
                        deleteDatabase(mMetadataCache.get(address));
                    }
                }
+174 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.bluetooth.btservice;

import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;

import androidx.annotation.NonNull;
@@ -24,6 +25,9 @@ import androidx.room.Embedded;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

import java.util.ArrayList;
import java.util.List;

@Entity(tableName = "metadata")
class Metadata {
    @PrimaryKey
@@ -121,4 +125,174 @@ class Metadata {
        }
        return BluetoothProfile.PRIORITY_UNDEFINED;
    }

    void setCustomizedMeta(int key, String value) {
        switch (key) {
            case BluetoothDevice.METADATA_MANUFACTURER_NAME:
                publicMeta.manufacturer_name = value;
                break;
            case BluetoothDevice.METADATA_MODEL_NAME:
                publicMeta.model_name = value;
                break;
            case BluetoothDevice.METADATA_SOFTWARE_VERSION:
                publicMeta.software_version = value;
                break;
            case BluetoothDevice.METADATA_HARDWARE_VERSION:
                publicMeta.hardware_version = value;
                break;
            case BluetoothDevice.METADATA_COMPANION_APP:
                publicMeta.companion_app = value;
                break;
            case BluetoothDevice.METADATA_MAIN_ICON:
                publicMeta.main_icon = value;
                break;
            case BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET:
                publicMeta.is_unthethered_headset = value;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_LEFT_ICON:
                publicMeta.unthethered_left_icon = value;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_RIGHT_ICON:
                publicMeta.unthethered_right_icon = value;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_CASE_ICON:
                publicMeta.unthethered_case_icon = value;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_LEFT_BATTERY:
                publicMeta.unthethered_left_battery = value;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_RIGHT_BATTERY:
                publicMeta.unthethered_right_battery = value;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_CASE_BATTERY:
                publicMeta.unthethered_case_battery = value;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_LEFT_CHARGING:
                publicMeta.unthethered_left_charging = value;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_RIGHT_CHARGING:
                publicMeta.unthethered_right_charging = value;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_CASE_CHARGING:
                publicMeta.unthethered_case_charging = value;
                break;
            case BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI:
                publicMeta.enhanced_settings_ui_uri = value;
                break;
        }
    }

    String getCustomizedMeta(int key) {
        String value = null;
        switch (key) {
            case BluetoothDevice.METADATA_MANUFACTURER_NAME:
                value = publicMeta.manufacturer_name;
                break;
            case BluetoothDevice.METADATA_MODEL_NAME:
                value = publicMeta.model_name;
                break;
            case BluetoothDevice.METADATA_SOFTWARE_VERSION:
                value = publicMeta.software_version;
                break;
            case BluetoothDevice.METADATA_HARDWARE_VERSION:
                value = publicMeta.hardware_version;
                break;
            case BluetoothDevice.METADATA_COMPANION_APP:
                value = publicMeta.companion_app;
                break;
            case BluetoothDevice.METADATA_MAIN_ICON:
                value = publicMeta.main_icon;
                break;
            case BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET:
                value = publicMeta.is_unthethered_headset;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_LEFT_ICON:
                value = publicMeta.unthethered_left_icon;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_RIGHT_ICON:
                value = publicMeta.unthethered_right_icon;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_CASE_ICON:
                value = publicMeta.unthethered_case_icon;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_LEFT_BATTERY:
                value = publicMeta.unthethered_left_battery;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_RIGHT_BATTERY:
                value = publicMeta.unthethered_right_battery;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_CASE_BATTERY:
                value = publicMeta.unthethered_case_battery;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_LEFT_CHARGING:
                value = publicMeta.unthethered_left_charging;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_RIGHT_CHARGING:
                value = publicMeta.unthethered_right_charging;
                break;
            case BluetoothDevice.METADATA_UNTHETHERED_CASE_CHARGING:
                value = publicMeta.unthethered_case_charging;
                break;
            case BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI:
                value = publicMeta.enhanced_settings_ui_uri;
                break;
        }
        return value;
    }

    List<Integer> getChangedCustomizedMeta() {
        List<Integer> list = new ArrayList<>();
        if (publicMeta.manufacturer_name != null) {
            list.add(BluetoothDevice.METADATA_MANUFACTURER_NAME);
        }
        if (publicMeta.model_name != null) {
            list.add(BluetoothDevice.METADATA_MODEL_NAME);
        }
        if (publicMeta.software_version != null) {
            list.add(BluetoothDevice.METADATA_SOFTWARE_VERSION);
        }
        if (publicMeta.hardware_version != null) {
            list.add(BluetoothDevice.METADATA_HARDWARE_VERSION);
        }
        if (publicMeta.companion_app != null) {
            list.add(BluetoothDevice.METADATA_COMPANION_APP);
        }
        if (publicMeta.main_icon != null) {
            list.add(BluetoothDevice.METADATA_MAIN_ICON);
        }
        if (publicMeta.is_unthethered_headset != null) {
            list.add(BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET);
        }
        if (publicMeta.unthethered_left_icon != null) {
            list.add(BluetoothDevice.METADATA_UNTHETHERED_LEFT_ICON);
        }
        if (publicMeta.unthethered_right_icon != null) {
            list.add(BluetoothDevice.METADATA_UNTHETHERED_RIGHT_ICON);
        }
        if (publicMeta.unthethered_case_icon != null) {
            list.add(BluetoothDevice.METADATA_UNTHETHERED_CASE_ICON);
        }
        if (publicMeta.unthethered_left_battery != null) {
            list.add(BluetoothDevice.METADATA_UNTHETHERED_LEFT_BATTERY);
        }
        if (publicMeta.unthethered_right_battery != null) {
            list.add(BluetoothDevice.METADATA_UNTHETHERED_RIGHT_BATTERY);
        }
        if (publicMeta.unthethered_case_battery != null) {
            list.add(BluetoothDevice.METADATA_UNTHETHERED_CASE_BATTERY);
        }
        if (publicMeta.unthethered_left_charging != null) {
            list.add(BluetoothDevice.METADATA_UNTHETHERED_LEFT_CHARGING);
        }
        if (publicMeta.unthethered_right_charging != null) {
            list.add(BluetoothDevice.METADATA_UNTHETHERED_RIGHT_CHARGING);
        }
        if (publicMeta.unthethered_case_charging != null) {
            list.add(BluetoothDevice.METADATA_UNTHETHERED_CASE_CHARGING);
        }
        if (publicMeta.enhanced_settings_ui_uri != null) {
            list.add(BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI);
        }
        return list;
    }
}
+124 −2
Original line number Diff line number Diff line
@@ -68,10 +68,10 @@ public final class DatabaseManagerTest {
                MetadataDatabase.class).build();

        mDatabaseManager = new DatabaseManager(mAdapterService);
        //mDatabaseManager.doNotMigrateSettingGlobal();

        BluetoothDevice[] bondedDevices = {};
        doReturn(bondedDevices).when(mAdapterService).getBondedDevices();
        doNothing().when(mAdapterService).metadataChanged(anyString(), anyInt(), anyString());

        mDatabaseManager.start(mDatabase);
        // Wait for handler thread finish its task.
@@ -182,11 +182,13 @@ public final class DatabaseManagerTest {

    @Test
    public void testRemoveUnusedMetadata() {
        // Insert two devices to database and cache, only mTestDevice is
        // Insert three devices to database and cache, only mTestDevice is
        // in the bonded list
        BluetoothDevice otherDevice = BluetoothAdapter.getDefaultAdapter()
                .getRemoteDevice(OTHER_BT_ADDR);
        Metadata otherData = new Metadata(OTHER_BT_ADDR);
        // Add metadata for otherDevice
        otherData.setCustomizedMeta(0, "value");
        mDatabaseManager.mMetadataCache.put(OTHER_BT_ADDR, otherData);
        mDatabase.insert(otherData);

@@ -201,6 +203,9 @@ public final class DatabaseManagerTest {
        // Wait for database update
        TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper());

        // Check removed device report metadata changed to null
        verify(mAdapterService).metadataChanged(OTHER_BT_ADDR, 0, null);

        List<Metadata> list = mDatabase.load();

        // Check number of metadata in the database
@@ -216,6 +221,85 @@ public final class DatabaseManagerTest {
        mDatabaseManager.mMetadataCache.clear();
    }

    @Test
    public void testSetGetCustomMeta() {
        int badKey = 100;
        String value = "input value";

        // Device is not in database
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MANUFACTURER_NAME,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MODEL_NAME,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_SOFTWARE_VERSION,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_HARDWARE_VERSION,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_COMPANION_APP,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_MAIN_ICON,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTHETHERED_LEFT_ICON,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTHETHERED_RIGHT_ICON,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTHETHERED_CASE_ICON,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTHETHERED_LEFT_BATTERY,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTHETHERED_RIGHT_BATTERY,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTHETHERED_CASE_BATTERY,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTHETHERED_LEFT_CHARGING,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTHETHERED_RIGHT_CHARGING,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_UNTHETHERED_CASE_CHARGING,
                value, true);
        testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI,
                value, true);
        testSetGetCustomMetaCase(false, badKey, value, false);

        // Device is in database
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MANUFACTURER_NAME,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MODEL_NAME,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_SOFTWARE_VERSION,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_HARDWARE_VERSION,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_COMPANION_APP,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MAIN_ICON,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTHETHERED_LEFT_ICON,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTHETHERED_RIGHT_ICON,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTHETHERED_CASE_ICON,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTHETHERED_LEFT_BATTERY,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTHETHERED_RIGHT_BATTERY,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTHETHERED_CASE_BATTERY,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTHETHERED_LEFT_CHARGING,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTHETHERED_RIGHT_CHARGING,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_UNTHETHERED_CASE_CHARGING,
                value, true);
        testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI,
                value, true);
    }

    void testSetGetProfilePriorityCase(boolean stored, int priority, int expectedPriority,
            boolean expectedSetResult) {
        if (stored) {
@@ -298,4 +382,42 @@ public final class DatabaseManagerTest {
        TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper());
        mDatabaseManager.mMetadataCache.clear();
    }

    void testSetGetCustomMetaCase(boolean stored, int key, String value, boolean expectedResult) {
        String testValue = "test value";
        int verifyTime = 1;
        if (stored) {
            Metadata data = new Metadata(TEST_BT_ADDR);
            mDatabaseManager.mMetadataCache.put(TEST_BT_ADDR, data);
            mDatabase.insert(data);
            Assert.assertEquals(expectedResult,
                    mDatabaseManager.setCustomMeta(mTestDevice, key, testValue));
            verify(mAdapterService).metadataChanged(TEST_BT_ADDR, key, testValue);
            verifyTime++;
        }
        Assert.assertEquals(expectedResult,
                mDatabaseManager.setCustomMeta(mTestDevice, key, value));
        if (expectedResult) {
            // Check for callback and get value
            verify(mAdapterService, times(verifyTime)).metadataChanged(TEST_BT_ADDR, key, value);
            Assert.assertEquals(value,
                    mDatabaseManager.getCustomMeta(mTestDevice, key));
        } else {
            Assert.assertNull(mDatabaseManager.getCustomMeta(mTestDevice, key));
            return;
        }
        // Wait for database update
        TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper());

        // Check whether the value is saved in database
        List<Metadata> list = mDatabase.load();
        Metadata data = list.get(0);
        Assert.assertEquals(TEST_BT_ADDR, data.getAddress());
        Assert.assertEquals(value, data.getCustomizedMeta(key));

        mDatabase.deleteAll();
        // Wait for clear database
        TestUtils.waitForLooperToFinishScheduledTask(mDatabaseManager.getHandlerLooper());
        mDatabaseManager.mMetadataCache.clear();
    }
}