Loading aconfig/settings_connecteddevice_flag_declarations.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -27,3 +27,10 @@ flag { description: "Gates whether to require an auth challenge for changing USB preferences" bug: "317367746" } flag { name: "enable_saved_devices_order_by_recency" namespace: "pixel_cross_device_control" description: "Order the saved bluetooth devices by most recently connected." bug: "306160434" } No newline at end of file src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java +91 −17 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.settings.connecteddevice; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; Loading @@ -36,13 +37,16 @@ import com.android.settings.bluetooth.SavedBluetoothDeviceUpdater; import com.android.settings.connecteddevice.dock.DockUpdater; import com.android.settings.core.BasePreferenceController; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.flags.Flags; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class PreviouslyConnectedDevicePreferenceController extends BasePreferenceController implements LifecycleObserver, OnStart, OnStop, DevicePreferenceCallback { Loading @@ -56,11 +60,12 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc private final List<Preference> mDevicesList = new ArrayList<>(); private final List<Preference> mDockDevicesList = new ArrayList<>(); private final Map<BluetoothDevice, Preference> mDevicePreferenceMap = new HashMap<>(); private final BluetoothAdapter mBluetoothAdapter; private PreferenceGroup mPreferenceGroup; private BluetoothDeviceUpdater mBluetoothDeviceUpdater; private DockUpdater mSavedDockUpdater; private BluetoothAdapter mBluetoothAdapter; @VisibleForTesting Preference mSeeAllPreference; Loading @@ -81,8 +86,12 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc mSavedDockUpdater = FeatureFactory.getFeatureFactory().getDockUpdaterFeatureProvider() .getSavedDockUpdater(context, this); mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); if (Flags.enableSavedDevicesOrderByRecency()) { mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter(); } else { mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } } @Override public int getAvailabilityStatus() { Loading Loading @@ -114,6 +123,9 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc mContext.registerReceiver(mReceiver, mIntentFilter, Context.RECEIVER_EXPORTED_UNAUDITED); mBluetoothDeviceUpdater.refreshPreference(); if (Flags.enableSavedDevicesOrderByRecency()) { updatePreferenceGroup(); } } @Override Loading @@ -131,11 +143,28 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc @Override public void onDeviceAdded(Preference preference) { if (Flags.enableSavedDevicesOrderByRecency()) { if (preference instanceof BluetoothDevicePreference) { mDevicePreferenceMap.put( ((BluetoothDevicePreference) preference).getBluetoothDevice().getDevice(), preference); } else { mDockDevicesList.add(preference); } if (DEBUG) { Log.d(TAG, "onDeviceAdded() " + preference.getTitle()); } updatePreferenceGroup(); } else { final List<BluetoothDevice> bluetoothDevices = mBluetoothAdapter.getMostRecentlyConnectedDevices(); final int index = preference instanceof BluetoothDevicePreference ? bluetoothDevices.indexOf(((BluetoothDevicePreference) preference) .getBluetoothDevice().getDevice()) : DOCK_DEVICE_INDEX; 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) { Loading @@ -145,6 +174,7 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc addPreference(index, preference); updatePreferenceVisibility(); } } private void addPreference(int index, Preference preference) { if (preference instanceof BluetoothDevicePreference) { Loading Loading @@ -194,6 +224,19 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc @Override public void onDeviceRemoved(Preference preference) { if (Flags.enableSavedDevicesOrderByRecency()) { if (preference instanceof BluetoothDevicePreference) { mDevicePreferenceMap.remove( ((BluetoothDevicePreference) preference).getBluetoothDevice().getDevice(), preference); } else { mDockDevicesList.remove(preference); } if (DEBUG) { Log.d(TAG, "onDeviceRemoved() " + preference.getTitle()); } updatePreferenceGroup(); } else { if (preference instanceof BluetoothDevicePreference) { mDevicesList.remove(preference); } else { Loading @@ -203,6 +246,37 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc addPreference(); updatePreferenceVisibility(); } } /** Sort the preferenceGroup by most recently used. */ public void updatePreferenceGroup() { mPreferenceGroup.removeAll(); mPreferenceGroup.addPreference(mSeeAllPreference); if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) { // Bluetooth is supported int order = 0; for (BluetoothDevice device : mBluetoothAdapter.getMostRecentlyConnectedDevices()) { Preference preference = mDevicePreferenceMap.getOrDefault(device, null); if (preference != null) { preference.setOrder(order); mPreferenceGroup.addPreference(preference); order += 1; } if (order == MAX_DEVICE_NUM) { break; } } for (Preference preference : mDockDevicesList) { if (order == MAX_DEVICE_NUM) { break; } preference.setOrder(order); mPreferenceGroup.addPreference(preference); order += 1; } } updatePreferenceVisibility(); } @VisibleForTesting void setBluetoothDeviceUpdater(BluetoothDeviceUpdater bluetoothDeviceUpdater) { Loading src/com/android/settings/connecteddevice/SavedDeviceGroupController.java +74 −5 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.settings.connecteddevice; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.content.Context; import android.content.pm.PackageManager; Loading @@ -23,18 +26,25 @@ import androidx.preference.Preference; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; import com.android.settings.bluetooth.BluetoothDevicePreference; import com.android.settings.bluetooth.BluetoothDeviceUpdater; import com.android.settings.bluetooth.SavedBluetoothDeviceUpdater; import com.android.settings.connecteddevice.dock.DockUpdater; import com.android.settings.core.BasePreferenceController; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.flags.Flags; import com.android.settings.overlay.DockUpdaterFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Controller to maintain the {@link PreferenceGroup} for all * saved devices. It uses {@link DevicePreferenceCallback} to add/remove {@link Preference} Loading @@ -45,6 +55,10 @@ public class SavedDeviceGroupController extends BasePreferenceController private static final String KEY = "saved_device_list"; private final Map<BluetoothDevice, Preference> mDevicePreferenceMap = new HashMap<>(); private final List<Preference> mDockDevicesList = new ArrayList<>(); private final BluetoothAdapter mBluetoothAdapter; @VisibleForTesting PreferenceGroup mPreferenceGroup; private BluetoothDeviceUpdater mBluetoothDeviceUpdater; Loading @@ -57,6 +71,7 @@ public class SavedDeviceGroupController extends BasePreferenceController FeatureFactory.getFeatureFactory().getDockUpdaterFeatureProvider(); mSavedDockUpdater = dockUpdaterFeatureProvider.getSavedDockUpdater(context, this); mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter(); } @Override Loading @@ -64,6 +79,9 @@ public class SavedDeviceGroupController extends BasePreferenceController mBluetoothDeviceUpdater.registerCallback(); mSavedDockUpdater.registerCallback(); mBluetoothDeviceUpdater.refreshPreference(); if (Flags.enableSavedDevicesOrderByRecency()) { updatePreferenceGroup(); } } @Override Loading Loading @@ -101,19 +119,65 @@ public class SavedDeviceGroupController extends BasePreferenceController @Override public void onDeviceAdded(Preference preference) { if (Flags.enableSavedDevicesOrderByRecency()) { mPreferenceGroup.addPreference(preference); if (preference instanceof BluetoothDevicePreference) { mDevicePreferenceMap.put( ((BluetoothDevicePreference) preference).getBluetoothDevice().getDevice(), preference); } else { mDockDevicesList.add(preference); } updatePreferenceGroup(); } else { if (mPreferenceGroup.getPreferenceCount() == 0) { mPreferenceGroup.setVisible(true); } mPreferenceGroup.addPreference(preference); } } @Override public void onDeviceRemoved(Preference preference) { if (Flags.enableSavedDevicesOrderByRecency()) { mPreferenceGroup.removePreference(preference); if (preference instanceof BluetoothDevicePreference) { mDevicePreferenceMap.remove( ((BluetoothDevicePreference) preference).getBluetoothDevice().getDevice(), preference); } else { mDockDevicesList.remove(preference); } updatePreferenceGroup(); } else { mPreferenceGroup.removePreference(preference); if (mPreferenceGroup.getPreferenceCount() == 0) { mPreferenceGroup.setVisible(false); } } } /** Sort the preferenceGroup by most recently used. */ public void updatePreferenceGroup() { if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { // Bluetooth is unsupported or disabled mPreferenceGroup.setVisible(false); } else { mPreferenceGroup.setVisible(true); int order = 0; for (BluetoothDevice device : mBluetoothAdapter.getMostRecentlyConnectedDevices()) { Preference preference = mDevicePreferenceMap.getOrDefault(device, null); if (preference != null) { preference.setOrder(order); order += 1; } } for (Preference preference : mDockDevicesList) { preference.setOrder(order); order += 1; } } } public void init(DashboardFragment fragment) { mBluetoothDeviceUpdater = new SavedBluetoothDeviceUpdater(fragment.getContext(), Loading @@ -130,4 +194,9 @@ public class SavedDeviceGroupController extends BasePreferenceController public void setSavedDockUpdater(DockUpdater savedDockUpdater) { mSavedDockUpdater = savedDockUpdater; } @VisibleForTesting void setPreferenceGroup(PreferenceGroup preferenceGroup) { mPreferenceGroup = preferenceGroup; } } tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java +104 −4 Original line number Diff line number Diff line Loading @@ -27,9 +27,14 @@ import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.content.Context; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.util.Pair; import androidx.preference.Preference; Loading @@ -42,11 +47,13 @@ import com.android.settings.bluetooth.BluetoothDevicePreference; import com.android.settings.bluetooth.BluetoothDeviceUpdater; import com.android.settings.connecteddevice.dock.DockUpdater; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.flags.Flags; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.widget.SingleTargetGearPreference; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; Loading @@ -70,6 +77,9 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { private static final String FAKE_ADDRESS_4 = "AA:AA:AA:AA:AA:04"; private static final String FAKE_ADDRESS_5 = "AA:AA:AA:AA:AA:05"; @Rule public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); @Mock private DashboardFragment mDashboardFragment; @Mock Loading Loading @@ -105,6 +115,9 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { @Mock private Drawable mDrawable; @Mock private BluetoothManager mBluetoothManager; @Mock private BluetoothAdapter mBluetoothAdapter; private Context mContext; private PreviouslyConnectedDevicePreferenceController mPreConnectedDeviceController; private PreferenceGroup mPreferenceGroup; Loading @@ -117,10 +130,8 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { mContext = spy(RuntimeEnvironment.application); doReturn(mContext).when(mDashboardFragment).getContext(); doReturn(mPackageManager).when(mContext).getPackageManager(); mPreConnectedDeviceController = new PreviouslyConnectedDevicePreferenceController(mContext, KEY); mPreConnectedDeviceController.setBluetoothDeviceUpdater(mBluetoothDeviceUpdater); mPreConnectedDeviceController.setSavedDockUpdater(mDockUpdater); when(mContext.getSystemService(BluetoothManager.class)).thenReturn(mBluetoothManager); when(mBluetoothManager.getAdapter()).thenReturn(mBluetoothAdapter); mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); when(mCachedDevice1.getDevice()).thenReturn(mBluetoothDevice1); Loading @@ -145,7 +156,13 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { mMostRecentlyConnectedDevices.add(mBluetoothDevice4); mMostRecentlyConnectedDevices.add(mBluetoothDevice3); mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(mMostRecentlyConnectedDevices); when(mBluetoothAdapter.getMostRecentlyConnectedDevices()) .thenReturn(mMostRecentlyConnectedDevices); mPreConnectedDeviceController = new PreviouslyConnectedDevicePreferenceController(mContext, KEY); mPreConnectedDeviceController.setBluetoothDeviceUpdater(mBluetoothDeviceUpdater); mPreConnectedDeviceController.setSavedDockUpdater(mDockUpdater); mPreferenceGroup = spy(new PreferenceCategory(mContext)); doReturn(mPreferenceManager).when(mPreferenceGroup).getPreferenceManager(); mPreferenceGroup.setVisible(false); Loading Loading @@ -249,6 +266,7 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { } @Test @RequiresFlagsDisabled(Flags.FLAG_ENABLE_SAVED_DEVICES_ORDER_BY_RECENCY) public void onDeviceAdded_addPreferenceNotExistInRecentlyDevices_noCrash() { final BluetoothDevicePreference preference = new BluetoothDevicePreference( mContext, mCachedDevice5, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); Loading @@ -259,6 +277,18 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(2); } @Test @RequiresFlagsEnabled(Flags.FLAG_ENABLE_SAVED_DEVICES_ORDER_BY_RECENCY) public void onDeviceAdded_addPreferenceNotExistInRecentlyDevices_doNothing() { final BluetoothDevicePreference preference = new BluetoothDevicePreference( mContext, mCachedDevice5, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); mPreConnectedDeviceController.onDeviceAdded(preference); // 1 see all preference assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1); } @Test public void onDeviceRemoved_removeLastDevice_showSeeAllPreference() { final BluetoothDevicePreference preference1 = new BluetoothDevicePreference( Loading @@ -277,6 +307,7 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { @Test public void updatePreferenceVisibility_bluetoothIsEnable_shouldShowCorrectText() { mShadowBluetoothAdapter.setEnabled(true); when(mBluetoothAdapter.isEnabled()).thenReturn(true); mPreConnectedDeviceController.updatePreferenceVisibility(); verify(mSeeAllPreference).setSummary(""); Loading @@ -285,9 +316,78 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { @Test public void updatePreferenceVisibility_bluetoothIsDisable_shouldShowCorrectText() { mShadowBluetoothAdapter.setEnabled(false); when(mBluetoothAdapter.isEnabled()).thenReturn(false); mPreConnectedDeviceController.updatePreferenceVisibility(); verify(mSeeAllPreference).setSummary( mContext.getString(R.string.connected_device_see_all_summary)); } @Test @RequiresFlagsEnabled(Flags.FLAG_ENABLE_SAVED_DEVICES_ORDER_BY_RECENCY) public void updatePreferenceGroup_bluetoothIsEnable_shouldOrderByMostRecentlyConnected() { when(mBluetoothAdapter.isEnabled()).thenReturn(true); final BluetoothDevicePreference preference4 = new BluetoothDevicePreference( mContext, mCachedDevice4, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); final BluetoothDevicePreference preference3 = new BluetoothDevicePreference( mContext, mCachedDevice3, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); final BluetoothDevicePreference preference2 = new BluetoothDevicePreference( mContext, mCachedDevice2, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); mPreConnectedDeviceController.onDeviceAdded(preference4); mPreConnectedDeviceController.onDeviceAdded(preference3); mPreConnectedDeviceController.onDeviceAdded(preference2); mPreConnectedDeviceController.updatePreferenceGroup(); // Refer to the order of {@link #mMostRecentlyConnectedDevices}, the first one is see all // preference assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(4); assertThat(preference2.getOrder()).isEqualTo(0); assertThat(preference4.getOrder()).isEqualTo(1); assertThat(preference3.getOrder()).isEqualTo(2); } @Test @RequiresFlagsEnabled(Flags.FLAG_ENABLE_SAVED_DEVICES_ORDER_BY_RECENCY) public void updatePreferenceGroup_bluetoothIsDisable_shouldShowOnlySeeAllPreference() { when(mBluetoothAdapter.isEnabled()).thenReturn(false); final BluetoothDevicePreference preference4 = new BluetoothDevicePreference( mContext, mCachedDevice4, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); final BluetoothDevicePreference preference3 = new BluetoothDevicePreference( mContext, mCachedDevice3, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); final BluetoothDevicePreference preference2 = new BluetoothDevicePreference( mContext, mCachedDevice2, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); mPreConnectedDeviceController.onDeviceAdded(preference4); mPreConnectedDeviceController.onDeviceAdded(preference3); mPreConnectedDeviceController.onDeviceAdded(preference2); mPreConnectedDeviceController.updatePreferenceGroup(); // 1 see all preference assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1); } } tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java +125 −1 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
aconfig/settings_connecteddevice_flag_declarations.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -27,3 +27,10 @@ flag { description: "Gates whether to require an auth challenge for changing USB preferences" bug: "317367746" } flag { name: "enable_saved_devices_order_by_recency" namespace: "pixel_cross_device_control" description: "Order the saved bluetooth devices by most recently connected." bug: "306160434" } No newline at end of file
src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java +91 −17 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.settings.connecteddevice; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; Loading @@ -36,13 +37,16 @@ import com.android.settings.bluetooth.SavedBluetoothDeviceUpdater; import com.android.settings.connecteddevice.dock.DockUpdater; import com.android.settings.core.BasePreferenceController; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.flags.Flags; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class PreviouslyConnectedDevicePreferenceController extends BasePreferenceController implements LifecycleObserver, OnStart, OnStop, DevicePreferenceCallback { Loading @@ -56,11 +60,12 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc private final List<Preference> mDevicesList = new ArrayList<>(); private final List<Preference> mDockDevicesList = new ArrayList<>(); private final Map<BluetoothDevice, Preference> mDevicePreferenceMap = new HashMap<>(); private final BluetoothAdapter mBluetoothAdapter; private PreferenceGroup mPreferenceGroup; private BluetoothDeviceUpdater mBluetoothDeviceUpdater; private DockUpdater mSavedDockUpdater; private BluetoothAdapter mBluetoothAdapter; @VisibleForTesting Preference mSeeAllPreference; Loading @@ -81,8 +86,12 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc mSavedDockUpdater = FeatureFactory.getFeatureFactory().getDockUpdaterFeatureProvider() .getSavedDockUpdater(context, this); mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); if (Flags.enableSavedDevicesOrderByRecency()) { mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter(); } else { mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } } @Override public int getAvailabilityStatus() { Loading Loading @@ -114,6 +123,9 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc mContext.registerReceiver(mReceiver, mIntentFilter, Context.RECEIVER_EXPORTED_UNAUDITED); mBluetoothDeviceUpdater.refreshPreference(); if (Flags.enableSavedDevicesOrderByRecency()) { updatePreferenceGroup(); } } @Override Loading @@ -131,11 +143,28 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc @Override public void onDeviceAdded(Preference preference) { if (Flags.enableSavedDevicesOrderByRecency()) { if (preference instanceof BluetoothDevicePreference) { mDevicePreferenceMap.put( ((BluetoothDevicePreference) preference).getBluetoothDevice().getDevice(), preference); } else { mDockDevicesList.add(preference); } if (DEBUG) { Log.d(TAG, "onDeviceAdded() " + preference.getTitle()); } updatePreferenceGroup(); } else { final List<BluetoothDevice> bluetoothDevices = mBluetoothAdapter.getMostRecentlyConnectedDevices(); final int index = preference instanceof BluetoothDevicePreference ? bluetoothDevices.indexOf(((BluetoothDevicePreference) preference) .getBluetoothDevice().getDevice()) : DOCK_DEVICE_INDEX; 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) { Loading @@ -145,6 +174,7 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc addPreference(index, preference); updatePreferenceVisibility(); } } private void addPreference(int index, Preference preference) { if (preference instanceof BluetoothDevicePreference) { Loading Loading @@ -194,6 +224,19 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc @Override public void onDeviceRemoved(Preference preference) { if (Flags.enableSavedDevicesOrderByRecency()) { if (preference instanceof BluetoothDevicePreference) { mDevicePreferenceMap.remove( ((BluetoothDevicePreference) preference).getBluetoothDevice().getDevice(), preference); } else { mDockDevicesList.remove(preference); } if (DEBUG) { Log.d(TAG, "onDeviceRemoved() " + preference.getTitle()); } updatePreferenceGroup(); } else { if (preference instanceof BluetoothDevicePreference) { mDevicesList.remove(preference); } else { Loading @@ -203,6 +246,37 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc addPreference(); updatePreferenceVisibility(); } } /** Sort the preferenceGroup by most recently used. */ public void updatePreferenceGroup() { mPreferenceGroup.removeAll(); mPreferenceGroup.addPreference(mSeeAllPreference); if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) { // Bluetooth is supported int order = 0; for (BluetoothDevice device : mBluetoothAdapter.getMostRecentlyConnectedDevices()) { Preference preference = mDevicePreferenceMap.getOrDefault(device, null); if (preference != null) { preference.setOrder(order); mPreferenceGroup.addPreference(preference); order += 1; } if (order == MAX_DEVICE_NUM) { break; } } for (Preference preference : mDockDevicesList) { if (order == MAX_DEVICE_NUM) { break; } preference.setOrder(order); mPreferenceGroup.addPreference(preference); order += 1; } } updatePreferenceVisibility(); } @VisibleForTesting void setBluetoothDeviceUpdater(BluetoothDeviceUpdater bluetoothDeviceUpdater) { Loading
src/com/android/settings/connecteddevice/SavedDeviceGroupController.java +74 −5 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.settings.connecteddevice; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.content.Context; import android.content.pm.PackageManager; Loading @@ -23,18 +26,25 @@ import androidx.preference.Preference; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; import com.android.settings.bluetooth.BluetoothDevicePreference; import com.android.settings.bluetooth.BluetoothDeviceUpdater; import com.android.settings.bluetooth.SavedBluetoothDeviceUpdater; import com.android.settings.connecteddevice.dock.DockUpdater; import com.android.settings.core.BasePreferenceController; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.flags.Flags; import com.android.settings.overlay.DockUpdaterFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Controller to maintain the {@link PreferenceGroup} for all * saved devices. It uses {@link DevicePreferenceCallback} to add/remove {@link Preference} Loading @@ -45,6 +55,10 @@ public class SavedDeviceGroupController extends BasePreferenceController private static final String KEY = "saved_device_list"; private final Map<BluetoothDevice, Preference> mDevicePreferenceMap = new HashMap<>(); private final List<Preference> mDockDevicesList = new ArrayList<>(); private final BluetoothAdapter mBluetoothAdapter; @VisibleForTesting PreferenceGroup mPreferenceGroup; private BluetoothDeviceUpdater mBluetoothDeviceUpdater; Loading @@ -57,6 +71,7 @@ public class SavedDeviceGroupController extends BasePreferenceController FeatureFactory.getFeatureFactory().getDockUpdaterFeatureProvider(); mSavedDockUpdater = dockUpdaterFeatureProvider.getSavedDockUpdater(context, this); mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter(); } @Override Loading @@ -64,6 +79,9 @@ public class SavedDeviceGroupController extends BasePreferenceController mBluetoothDeviceUpdater.registerCallback(); mSavedDockUpdater.registerCallback(); mBluetoothDeviceUpdater.refreshPreference(); if (Flags.enableSavedDevicesOrderByRecency()) { updatePreferenceGroup(); } } @Override Loading Loading @@ -101,19 +119,65 @@ public class SavedDeviceGroupController extends BasePreferenceController @Override public void onDeviceAdded(Preference preference) { if (Flags.enableSavedDevicesOrderByRecency()) { mPreferenceGroup.addPreference(preference); if (preference instanceof BluetoothDevicePreference) { mDevicePreferenceMap.put( ((BluetoothDevicePreference) preference).getBluetoothDevice().getDevice(), preference); } else { mDockDevicesList.add(preference); } updatePreferenceGroup(); } else { if (mPreferenceGroup.getPreferenceCount() == 0) { mPreferenceGroup.setVisible(true); } mPreferenceGroup.addPreference(preference); } } @Override public void onDeviceRemoved(Preference preference) { if (Flags.enableSavedDevicesOrderByRecency()) { mPreferenceGroup.removePreference(preference); if (preference instanceof BluetoothDevicePreference) { mDevicePreferenceMap.remove( ((BluetoothDevicePreference) preference).getBluetoothDevice().getDevice(), preference); } else { mDockDevicesList.remove(preference); } updatePreferenceGroup(); } else { mPreferenceGroup.removePreference(preference); if (mPreferenceGroup.getPreferenceCount() == 0) { mPreferenceGroup.setVisible(false); } } } /** Sort the preferenceGroup by most recently used. */ public void updatePreferenceGroup() { if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { // Bluetooth is unsupported or disabled mPreferenceGroup.setVisible(false); } else { mPreferenceGroup.setVisible(true); int order = 0; for (BluetoothDevice device : mBluetoothAdapter.getMostRecentlyConnectedDevices()) { Preference preference = mDevicePreferenceMap.getOrDefault(device, null); if (preference != null) { preference.setOrder(order); order += 1; } } for (Preference preference : mDockDevicesList) { preference.setOrder(order); order += 1; } } } public void init(DashboardFragment fragment) { mBluetoothDeviceUpdater = new SavedBluetoothDeviceUpdater(fragment.getContext(), Loading @@ -130,4 +194,9 @@ public class SavedDeviceGroupController extends BasePreferenceController public void setSavedDockUpdater(DockUpdater savedDockUpdater) { mSavedDockUpdater = savedDockUpdater; } @VisibleForTesting void setPreferenceGroup(PreferenceGroup preferenceGroup) { mPreferenceGroup = preferenceGroup; } }
tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java +104 −4 Original line number Diff line number Diff line Loading @@ -27,9 +27,14 @@ import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.content.Context; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.util.Pair; import androidx.preference.Preference; Loading @@ -42,11 +47,13 @@ import com.android.settings.bluetooth.BluetoothDevicePreference; import com.android.settings.bluetooth.BluetoothDeviceUpdater; import com.android.settings.connecteddevice.dock.DockUpdater; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.flags.Flags; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.widget.SingleTargetGearPreference; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; Loading @@ -70,6 +77,9 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { private static final String FAKE_ADDRESS_4 = "AA:AA:AA:AA:AA:04"; private static final String FAKE_ADDRESS_5 = "AA:AA:AA:AA:AA:05"; @Rule public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); @Mock private DashboardFragment mDashboardFragment; @Mock Loading Loading @@ -105,6 +115,9 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { @Mock private Drawable mDrawable; @Mock private BluetoothManager mBluetoothManager; @Mock private BluetoothAdapter mBluetoothAdapter; private Context mContext; private PreviouslyConnectedDevicePreferenceController mPreConnectedDeviceController; private PreferenceGroup mPreferenceGroup; Loading @@ -117,10 +130,8 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { mContext = spy(RuntimeEnvironment.application); doReturn(mContext).when(mDashboardFragment).getContext(); doReturn(mPackageManager).when(mContext).getPackageManager(); mPreConnectedDeviceController = new PreviouslyConnectedDevicePreferenceController(mContext, KEY); mPreConnectedDeviceController.setBluetoothDeviceUpdater(mBluetoothDeviceUpdater); mPreConnectedDeviceController.setSavedDockUpdater(mDockUpdater); when(mContext.getSystemService(BluetoothManager.class)).thenReturn(mBluetoothManager); when(mBluetoothManager.getAdapter()).thenReturn(mBluetoothAdapter); mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); when(mCachedDevice1.getDevice()).thenReturn(mBluetoothDevice1); Loading @@ -145,7 +156,13 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { mMostRecentlyConnectedDevices.add(mBluetoothDevice4); mMostRecentlyConnectedDevices.add(mBluetoothDevice3); mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(mMostRecentlyConnectedDevices); when(mBluetoothAdapter.getMostRecentlyConnectedDevices()) .thenReturn(mMostRecentlyConnectedDevices); mPreConnectedDeviceController = new PreviouslyConnectedDevicePreferenceController(mContext, KEY); mPreConnectedDeviceController.setBluetoothDeviceUpdater(mBluetoothDeviceUpdater); mPreConnectedDeviceController.setSavedDockUpdater(mDockUpdater); mPreferenceGroup = spy(new PreferenceCategory(mContext)); doReturn(mPreferenceManager).when(mPreferenceGroup).getPreferenceManager(); mPreferenceGroup.setVisible(false); Loading Loading @@ -249,6 +266,7 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { } @Test @RequiresFlagsDisabled(Flags.FLAG_ENABLE_SAVED_DEVICES_ORDER_BY_RECENCY) public void onDeviceAdded_addPreferenceNotExistInRecentlyDevices_noCrash() { final BluetoothDevicePreference preference = new BluetoothDevicePreference( mContext, mCachedDevice5, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); Loading @@ -259,6 +277,18 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(2); } @Test @RequiresFlagsEnabled(Flags.FLAG_ENABLE_SAVED_DEVICES_ORDER_BY_RECENCY) public void onDeviceAdded_addPreferenceNotExistInRecentlyDevices_doNothing() { final BluetoothDevicePreference preference = new BluetoothDevicePreference( mContext, mCachedDevice5, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); mPreConnectedDeviceController.onDeviceAdded(preference); // 1 see all preference assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1); } @Test public void onDeviceRemoved_removeLastDevice_showSeeAllPreference() { final BluetoothDevicePreference preference1 = new BluetoothDevicePreference( Loading @@ -277,6 +307,7 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { @Test public void updatePreferenceVisibility_bluetoothIsEnable_shouldShowCorrectText() { mShadowBluetoothAdapter.setEnabled(true); when(mBluetoothAdapter.isEnabled()).thenReturn(true); mPreConnectedDeviceController.updatePreferenceVisibility(); verify(mSeeAllPreference).setSummary(""); Loading @@ -285,9 +316,78 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { @Test public void updatePreferenceVisibility_bluetoothIsDisable_shouldShowCorrectText() { mShadowBluetoothAdapter.setEnabled(false); when(mBluetoothAdapter.isEnabled()).thenReturn(false); mPreConnectedDeviceController.updatePreferenceVisibility(); verify(mSeeAllPreference).setSummary( mContext.getString(R.string.connected_device_see_all_summary)); } @Test @RequiresFlagsEnabled(Flags.FLAG_ENABLE_SAVED_DEVICES_ORDER_BY_RECENCY) public void updatePreferenceGroup_bluetoothIsEnable_shouldOrderByMostRecentlyConnected() { when(mBluetoothAdapter.isEnabled()).thenReturn(true); final BluetoothDevicePreference preference4 = new BluetoothDevicePreference( mContext, mCachedDevice4, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); final BluetoothDevicePreference preference3 = new BluetoothDevicePreference( mContext, mCachedDevice3, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); final BluetoothDevicePreference preference2 = new BluetoothDevicePreference( mContext, mCachedDevice2, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); mPreConnectedDeviceController.onDeviceAdded(preference4); mPreConnectedDeviceController.onDeviceAdded(preference3); mPreConnectedDeviceController.onDeviceAdded(preference2); mPreConnectedDeviceController.updatePreferenceGroup(); // Refer to the order of {@link #mMostRecentlyConnectedDevices}, the first one is see all // preference assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(4); assertThat(preference2.getOrder()).isEqualTo(0); assertThat(preference4.getOrder()).isEqualTo(1); assertThat(preference3.getOrder()).isEqualTo(2); } @Test @RequiresFlagsEnabled(Flags.FLAG_ENABLE_SAVED_DEVICES_ORDER_BY_RECENCY) public void updatePreferenceGroup_bluetoothIsDisable_shouldShowOnlySeeAllPreference() { when(mBluetoothAdapter.isEnabled()).thenReturn(false); final BluetoothDevicePreference preference4 = new BluetoothDevicePreference( mContext, mCachedDevice4, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); final BluetoothDevicePreference preference3 = new BluetoothDevicePreference( mContext, mCachedDevice3, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); final BluetoothDevicePreference preference2 = new BluetoothDevicePreference( mContext, mCachedDevice2, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); mPreConnectedDeviceController.onDeviceAdded(preference4); mPreConnectedDeviceController.onDeviceAdded(preference3); mPreConnectedDeviceController.onDeviceAdded(preference2); mPreConnectedDeviceController.updatePreferenceGroup(); // 1 see all preference assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1); } }
tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java +125 −1 File changed.Preview size limit exceeded, changes collapsed. Show changes