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

Commit 1872151b authored by SongFerngWang's avatar SongFerngWang Committed by SongFerng Wang
Browse files

The BluetoothDevicePreference register the MetadataChanged

The bluetooth device preference needs to refresh UI after MetadataChanged
Fix: 282877247
Test: make RunSettingsRoboTests ROBOTEST_FILTER=BluetoothDevicePreferenceTest

Change-Id: I02cb07a6b255242e4877089ce2f3b7559ce02362
parent 128036a0
Loading
Loading
Loading
Loading
+53 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.settings.bluetooth;
import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;

import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.DialogInterface;
@@ -48,6 +49,8 @@ import com.android.settingslib.utils.ThreadUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.RejectedExecutionException;

/**
@@ -71,6 +74,10 @@ public final class BluetoothDevicePreference extends GearPreference {

    private final CachedBluetoothDevice mCachedDevice;
    private final UserManager mUserManager;

    private Set<BluetoothDevice> mBluetoothDevices;
    @VisibleForTesting
    BluetoothAdapter mBluetoothAdapter;
    private final boolean mShowDevicesWithoutNames;
    private final long mCurrentTime;
    private final int mType;
@@ -78,12 +85,23 @@ public final class BluetoothDevicePreference extends GearPreference {
    private AlertDialog mDisconnectDialog;
    private String contentDescription = null;
    private boolean mHideSecondTarget = false;
    private boolean mIsCallbackRemoved = false;
    private boolean mIsCallbackRemoved = true;
    @VisibleForTesting
    boolean mNeedNotifyHierarchyChanged = false;
    /* Talk-back descriptions for various BT icons */
    Resources mResources;
    final BluetoothDevicePreferenceCallback mCallback;
    @VisibleForTesting
    final BluetoothAdapter.OnMetadataChangedListener mMetadataListener =
            new BluetoothAdapter.OnMetadataChangedListener() {
                @Override
                public void onMetadataChanged(BluetoothDevice device, int key, byte[] value) {
                    Log.d(TAG, String.format("Metadata updated in Device %s: %d = %s.",
                            device.getAnonymizedAddress(),
                            key, value == null ? null : new String(value)));
                    onPreferenceAttributesChanged();
                }
            };

    private class BluetoothDevicePreferenceCallback implements CachedBluetoothDevice.Callback {

@@ -98,6 +116,7 @@ public final class BluetoothDevicePreference extends GearPreference {
        super(context, null);
        mResources = getContext().getResources();
        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        mShowDevicesWithoutNames = showDeviceWithoutNames;

        if (sDimAlpha == Integer.MIN_VALUE) {
@@ -108,7 +127,6 @@ public final class BluetoothDevicePreference extends GearPreference {

        mCachedDevice = cachedDevice;
        mCallback = new BluetoothDevicePreferenceCallback();
        mCachedDevice.registerCallback(mCallback);
        mCurrentTime = System.currentTimeMillis();
        mType = type;

@@ -141,6 +159,7 @@ public final class BluetoothDevicePreference extends GearPreference {
        super.onPrepareForRemoval();
        if (!mIsCallbackRemoved) {
            mCachedDevice.unregisterCallback(mCallback);
            unregisterMetadataChangedListener();
            mIsCallbackRemoved = true;
        }
        if (mDisconnectDialog != null) {
@@ -154,6 +173,7 @@ public final class BluetoothDevicePreference extends GearPreference {
        super.onAttached();
        if (mIsCallbackRemoved) {
            mCachedDevice.registerCallback(mCallback);
            registerMetadataChangedListener();
            mIsCallbackRemoved = false;
        }
        onPreferenceAttributesChanged();
@@ -164,10 +184,41 @@ public final class BluetoothDevicePreference extends GearPreference {
        super.onDetached();
        if (!mIsCallbackRemoved) {
            mCachedDevice.unregisterCallback(mCallback);
            unregisterMetadataChangedListener();
            mIsCallbackRemoved = true;
        }
    }

    private void registerMetadataChangedListener() {
        if (mBluetoothDevices == null) {
            mBluetoothDevices = new HashSet<>();
        }
        mBluetoothDevices.clear();
        if (mCachedDevice.getDevice() != null) {
            mBluetoothDevices.add(mCachedDevice.getDevice());
        }
        for (CachedBluetoothDevice cbd : mCachedDevice.getMemberDevice()) {
            mBluetoothDevices.add(cbd.getDevice());
        }
        if (mBluetoothDevices.isEmpty()) {
            Log.d(TAG, "No BT device to register.");
            return;
        }
        mBluetoothDevices.forEach(bd ->
                mBluetoothAdapter.addOnMetadataChangedListener(bd,
                        getContext().getMainExecutor(), mMetadataListener));
    }

    private void unregisterMetadataChangedListener() {
        if (mBluetoothDevices == null || mBluetoothDevices.isEmpty()) {
            Log.d(TAG, "No BT device to unregister.");
            return;
        }
        mBluetoothDevices.forEach(
                bd -> mBluetoothAdapter.removeOnMetadataChangedListener(bd, mMetadataListener));
        mBluetoothDevices.clear();
    }

    public CachedBluetoothDevice getBluetoothDevice() {
        return mCachedDevice;
    }
+27 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.graphics.drawable.Drawable;
@@ -77,7 +78,17 @@ public class BluetoothDevicePreferenceTest {
    @Mock
    private CachedBluetoothDevice mCachedDevice3;
    @Mock
    private BluetoothDevice mBluetoothDevice;
    @Mock
    private BluetoothDevice mBluetoothDevice1;
    @Mock
    private BluetoothDevice mBluetoothDevice2;
    @Mock
    private BluetoothDevice mBluetoothDevice3;
    @Mock
    private Drawable mDrawable;
    @Mock
    private BluetoothAdapter mBluetoothAdapter;

    private FakeFeatureFactory mFakeFeatureFactory;
    private MetricsFeatureProvider mMetricsFeatureProvider;
@@ -94,17 +105,22 @@ public class BluetoothDevicePreferenceTest {
        when(mCachedBluetoothDevice.getAddress()).thenReturn(MAC_ADDRESS);
        when(mCachedBluetoothDevice.getDrawableWithDescription())
                .thenReturn(new Pair<>(mDrawable, FAKE_DESCRIPTION));
        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
        when(mCachedDevice1.getAddress()).thenReturn(MAC_ADDRESS_2);
        when(mCachedDevice1.getDrawableWithDescription())
                .thenReturn(new Pair<>(mDrawable, FAKE_DESCRIPTION));
        when(mCachedDevice1.getDevice()).thenReturn(mBluetoothDevice1);
        when(mCachedDevice2.getAddress()).thenReturn(MAC_ADDRESS_3);
        when(mCachedDevice2.getDrawableWithDescription())
                .thenReturn(new Pair<>(mDrawable, FAKE_DESCRIPTION));
        when(mCachedDevice2.getDevice()).thenReturn(mBluetoothDevice2);
        when(mCachedDevice3.getAddress()).thenReturn(MAC_ADDRESS_4);
        when(mCachedDevice3.getDrawableWithDescription())
                .thenReturn(new Pair<>(mDrawable, FAKE_DESCRIPTION));
        when(mCachedDevice3.getDevice()).thenReturn(mBluetoothDevice3);
        mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice,
                SHOW_DEVICES_WITHOUT_NAMES, BluetoothDevicePreference.SortType.TYPE_DEFAULT);
        mPreference.mBluetoothAdapter = mBluetoothAdapter;
    }

    @Test
@@ -279,15 +295,25 @@ public class BluetoothDevicePreferenceTest {
    @Test
    public void onAttached_callbackNotRemoved_doNotRegisterCallback() {
        mPreference.onAttached();
        // After the onAttached(), the callback is registered.

        verify(mCachedBluetoothDevice, never()).unregisterCallback(any());
        // If it goes to the onAttached() again, then it do not register again, since the
        // callback is not removed.
        mPreference.onAttached();

        verify(mCachedBluetoothDevice, times(1)).registerCallback(any());
        verify(mBluetoothAdapter, times(1)).addOnMetadataChangedListener(any(), any(), any());
    }

    @Test
    public void onAttached_callbackRemoved_registerCallback() {
        mPreference.onAttached();

        mPreference.onPrepareForRemoval();
        mPreference.onAttached();

        verify(mCachedBluetoothDevice, times(1)).unregisterCallback(any());
        verify(mCachedBluetoothDevice, times(2)).registerCallback(any());
        verify(mBluetoothAdapter, times(2)).addOnMetadataChangedListener(any(), any(), any());
    }
}