From a6aae425bc95d5fda5ec57147d5062f973dd73f0 Mon Sep 17 00:00:00 2001 From: Hugh Chen Date: Wed, 2 Sep 2020 17:00:13 +0800 Subject: [PATCH] Fix settings crash - This CL before, "Previously connected device" didn't handle dock device. If user have disconnected dock device will cause Settings crash. This CL add condition to handle dock device to avoid crash. - Update test case. Bug: 167054620 Test: make -j42 RunSettingsRoboTests Change-Id: I769cee3f589e14a993b00a0ae6ec3ddfba8ef281 --- .../bluetooth/BluetoothDevicePreference.java | 14 +++- ...lyConnectedDevicePreferenceController.java | 70 ++++++++++++------- ...nnectedDevicePreferenceControllerTest.java | 18 +++++ 3 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java index 86b72ec3f94..2e4654c3994 100644 --- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java +++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java @@ -96,7 +96,6 @@ public final class BluetoothDevicePreference extends GearPreference implements } mCachedDevice = cachedDevice; - mCachedDevice.registerCallback(this); mCurrentTime = System.currentTimeMillis(); mType = type; @@ -127,13 +126,24 @@ public final class BluetoothDevicePreference extends GearPreference implements @Override protected void onPrepareForRemoval() { super.onPrepareForRemoval(); - mCachedDevice.unregisterCallback(this); if (mDisconnectDialog != null) { mDisconnectDialog.dismiss(); mDisconnectDialog = null; } } + @Override + public void onAttached() { + super.onAttached(); + mCachedDevice.registerCallback(this); + } + + @Override + public void onDetached() { + super.onDetached(); + mCachedDevice.unregisterCallback(this); + } + public CachedBluetoothDevice getBluetoothDevice() { return mCachedDevice; } diff --git a/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java b/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java index 78791d4ebff..438a3815f9a 100644 --- a/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java +++ b/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java @@ -51,14 +51,15 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final int MAX_DEVICE_NUM = 3; + private static final int DOCK_DEVICE_INDEX = 9; private static final String KEY_SEE_ALL = "previously_connected_devices_see_all"; private final List mDevicesList = new ArrayList<>(); + private final List mDockDevicesList = new ArrayList<>(); private PreferenceGroup mPreferenceGroup; private BluetoothDeviceUpdater mBluetoothDeviceUpdater; private DockUpdater mSavedDockUpdater; - private int mPreferenceSize; private BluetoothAdapter mBluetoothAdapter; @VisibleForTesting @@ -126,33 +127,38 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc @Override public void onDeviceAdded(Preference preference) { - mPreferenceSize++; final List bluetoothDevices = mBluetoothAdapter.getMostRecentlyConnectedDevices(); - final int index = bluetoothDevices.indexOf(((BluetoothDevicePreference) preference) - .getBluetoothDevice().getDevice()); + final int index = preference instanceof BluetoothDevicePreference + ? bluetoothDevices.indexOf(((BluetoothDevicePreference) preference) + .getBluetoothDevice().getDevice()) : DOCK_DEVICE_INDEX; if (DEBUG) { Log.d(TAG, "onDeviceAdded() " + preference.getTitle() + ", index of : " + index); for (BluetoothDevice device : bluetoothDevices) { Log.d(TAG, "onDeviceAdded() most recently device : " + device.getName()); } } - if (mPreferenceSize <= MAX_DEVICE_NUM) { - addPreference(mPreferenceSize, index, preference); - } else { - addPreference(MAX_DEVICE_NUM, index, preference); - } + addPreference(index, preference); updatePreferenceVisibility(); } - private void addPreference(int size, int index, Preference preference) { - if (mDevicesList.size() >= index) { - mDevicesList.add(index, preference); + private void addPreference(int index, Preference preference) { + if (preference instanceof BluetoothDevicePreference) { + if (mDevicesList.size() >= index) { + mDevicesList.add(index, preference); + } else { + mDevicesList.add(preference); + } } else { - mDevicesList.add(preference); + mDockDevicesList.add(preference); } + addPreference(); + } + + private void addPreference() { mPreferenceGroup.removeAll(); mPreferenceGroup.addPreference(mSeeAllPreference); + final int size = getDeviceListSize(); for (int i = 0; i < size; i++) { if (DEBUG) { Log.d(TAG, "addPreference() add device : " + mDevicesList.get(i).getTitle()); @@ -160,23 +166,37 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc mDevicesList.get(i).setOrder(i); mPreferenceGroup.addPreference(mDevicesList.get(i)); } + if (mDockDevicesList.size() > 0) { + for (int i = 0; i < getDockDeviceListSize(MAX_DEVICE_NUM - size); i++) { + if (DEBUG) { + Log.d(TAG, "addPreference() add dock device : " + + mDockDevicesList.get(i).getTitle()); + } + mDockDevicesList.get(i).setOrder(DOCK_DEVICE_INDEX); + mPreferenceGroup.addPreference(mDockDevicesList.get(i)); + } + } + } + + private int getDeviceListSize() { + return mDevicesList.size() >= MAX_DEVICE_NUM + ? MAX_DEVICE_NUM : mDevicesList.size(); + } + + private int getDockDeviceListSize(int availableSize) { + return mDockDevicesList.size() >= availableSize + ? availableSize : mDockDevicesList.size(); } @Override public void onDeviceRemoved(Preference preference) { - mPreferenceSize--; - mDevicesList.remove(preference); - mPreferenceGroup.removeAll(); - mPreferenceGroup.addPreference(mSeeAllPreference); - final int size = mDevicesList.size() >= MAX_DEVICE_NUM - ? MAX_DEVICE_NUM : mDevicesList.size(); - for (int i = 0; i < size; i++) { - if (DEBUG) { - Log.d(TAG, "onDeviceRemoved() add device : " + mDevicesList.get(i).getTitle()); - } - mDevicesList.get(i).setOrder(i); - mPreferenceGroup.addPreference(mDevicesList.get(i)); + if (preference instanceof BluetoothDevicePreference) { + mDevicesList.remove(preference); + } else { + mDockDevicesList.remove(preference); } + + addPreference(); updatePreferenceVisibility(); } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java index 3363ff5346c..d73471f94ed 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java @@ -41,6 +41,7 @@ import com.android.settings.bluetooth.BluetoothDeviceUpdater; import com.android.settings.connecteddevice.dock.DockUpdater; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; +import com.android.settings.widget.SingleTargetGearPreference; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import org.junit.Before; @@ -187,6 +188,16 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(2); } + @Test + public void onDeviceAdded_addDockDevicePreference_displayIt() { + final SingleTargetGearPreference dockPreference = new SingleTargetGearPreference( + mContext, null /* AttributeSet */); + + mPreConnectedDeviceController.onDeviceAdded(dockPreference); + + assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(2); + } + @Test public void onDeviceAdded_addFourDevicePreference_onlyDisplayThree() { final BluetoothDevicePreference preference1 = new BluetoothDevicePreference( @@ -197,11 +208,14 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { mContext, mCachedDevice3, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); final BluetoothDevicePreference preference4 = new BluetoothDevicePreference( mContext, mCachedDevice4, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); + final SingleTargetGearPreference dockPreference = new SingleTargetGearPreference( + mContext, null /* AttributeSet */); mPreConnectedDeviceController.onDeviceAdded(preference1); mPreConnectedDeviceController.onDeviceAdded(preference2); mPreConnectedDeviceController.onDeviceAdded(preference3); mPreConnectedDeviceController.onDeviceAdded(preference4); + mPreConnectedDeviceController.onDeviceAdded(dockPreference); // 3 BluetoothDevicePreference and 1 see all preference assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(4); @@ -211,9 +225,13 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { public void onDeviceRemoved_removeLastDevice_showSeeAllPreference() { final BluetoothDevicePreference preference1 = new BluetoothDevicePreference( mContext, mCachedDevice1, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); + final SingleTargetGearPreference dockPreference = new SingleTargetGearPreference( + mContext, null /* AttributeSet */); mPreferenceGroup.addPreference(preference1); + mPreferenceGroup.addPreference(dockPreference); mPreConnectedDeviceController.onDeviceRemoved(preference1); + mPreConnectedDeviceController.onDeviceRemoved(dockPreference); assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1); }