Fix the device on "Media devices" not updated issue
- This CL uses new CachedBluetoothDevice callback instance
in construct to avoid unregister wrong callback.
- This CL uses flag to make sure preference will register callback
on onAttached() when preference remove callback on
onPrepareForRemoval() or onDetached().
- Update test case
Bug: 168682778
Bug: 157653997
Test: make -j42 RunSettingsRoboTests
Change-Id: I7a0d9f5332153ee80634e191847b84cd7c380b7d
Merged-In: I7a0d9f5332153ee80634e191847b84cd7c380b7d
(cherry picked from commit cafeab28136320345e12ccfb8e9bf2def10635d8)
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index 2e4654c..d927121 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -52,8 +52,7 @@
* BluetoothDevicePreference is the preference type used to display each remote
* Bluetooth device in the Bluetooth Settings screen.
*/
-public final class BluetoothDevicePreference extends GearPreference implements
- CachedBluetoothDevice.Callback {
+public final class BluetoothDevicePreference extends GearPreference {
private static final String TAG = "BluetoothDevicePref";
private static int sDimAlpha = Integer.MIN_VALUE;
@@ -77,10 +76,20 @@
private AlertDialog mDisconnectDialog;
private String contentDescription = null;
private boolean mHideSecondTarget = false;
+ private boolean mIsCallbackRemoved = false;
@VisibleForTesting
boolean mNeedNotifyHierarchyChanged = false;
/* Talk-back descriptions for various BT icons */
Resources mResources;
+ final BluetoothDevicePreferenceCallback mCallback;
+
+ private class BluetoothDevicePreferenceCallback implements CachedBluetoothDevice.Callback {
+
+ @Override
+ public void onDeviceAttributesChanged() {
+ onPreferenceAttributesChanged();
+ }
+ }
public BluetoothDevicePreference(Context context, CachedBluetoothDevice cachedDevice,
boolean showDeviceWithoutNames, @SortType int type) {
@@ -96,10 +105,12 @@
}
mCachedDevice = cachedDevice;
+ mCallback = new BluetoothDevicePreferenceCallback();
+ mCachedDevice.registerCallback(mCallback);
mCurrentTime = System.currentTimeMillis();
mType = type;
- onDeviceAttributesChanged();
+ onPreferenceAttributesChanged();
}
public void setNeedNotifyHierarchyChanged(boolean needNotifyHierarchyChanged) {
@@ -126,6 +137,10 @@
@Override
protected void onPrepareForRemoval() {
super.onPrepareForRemoval();
+ if (!mIsCallbackRemoved) {
+ mCachedDevice.unregisterCallback(mCallback);
+ mIsCallbackRemoved = true;
+ }
if (mDisconnectDialog != null) {
mDisconnectDialog.dismiss();
mDisconnectDialog = null;
@@ -135,13 +150,20 @@
@Override
public void onAttached() {
super.onAttached();
- mCachedDevice.registerCallback(this);
+ if (mIsCallbackRemoved) {
+ mCachedDevice.registerCallback(mCallback);
+ mIsCallbackRemoved = false;
+ }
+ onPreferenceAttributesChanged();
}
@Override
public void onDetached() {
super.onDetached();
- mCachedDevice.unregisterCallback(this);
+ if (!mIsCallbackRemoved) {
+ mCachedDevice.unregisterCallback(mCallback);
+ mIsCallbackRemoved = true;
+ }
}
public CachedBluetoothDevice getBluetoothDevice() {
@@ -152,7 +174,7 @@
mHideSecondTarget = hideSecondTarget;
}
- public void onDeviceAttributesChanged() {
+ private void onPreferenceAttributesChanged() {
/*
* The preference framework takes care of making sure the value has
* changed before proceeding. It will also call notifyChanged() if
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
index f12e06e..c87cc25 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePreferenceTest.java
@@ -17,10 +17,12 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -35,7 +37,6 @@
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
-import com.android.settingslib.testutils.DrawableTestHelper;
import org.junit.Before;
import org.junit.Test;
@@ -261,4 +262,19 @@
assertThat(mPreferenceList.get(2).getCachedDevice().getAddress())
.isEqualTo(preference3.getCachedDevice().getAddress());
}
+
+ @Test
+ public void onAttached_callbackNotRemoved_doNotRegisterCallback() {
+ mPreference.onAttached();
+
+ verify(mCachedBluetoothDevice, never()).unregisterCallback(any());
+ }
+
+ @Test
+ public void onAttached_callbackRemoved_registerCallback() {
+ mPreference.onPrepareForRemoval();
+ mPreference.onAttached();
+
+ verify(mCachedBluetoothDevice, times(2)).registerCallback(any());
+ }
}