diff --git a/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java b/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java index 3d4dd29d38f..78791d4ebff 100644 --- a/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java +++ b/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java @@ -16,11 +16,13 @@ package com.android.settings.connecteddevice; import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; @@ -28,6 +30,7 @@ import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; import com.android.settings.R; +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; @@ -38,12 +41,20 @@ 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.List; + public class PreviouslyConnectedDevicePreferenceController extends BasePreferenceController implements LifecycleObserver, OnStart, OnStop, DevicePreferenceCallback { + private static final String TAG = "PreviouslyDevicePreController"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + private static final int MAX_DEVICE_NUM = 3; private static final String KEY_SEE_ALL = "previously_connected_devices_see_all"; + private final List mDevicesList = new ArrayList<>(); + private PreferenceGroup mPreferenceGroup; private BluetoothDeviceUpdater mBluetoothDeviceUpdater; private DockUpdater mSavedDockUpdater; @@ -116,16 +127,56 @@ 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()); + 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) { - mPreferenceGroup.addPreference(preference); + addPreference(mPreferenceSize, index, preference); + } else { + addPreference(MAX_DEVICE_NUM, index, preference); } updatePreferenceVisibility(); } + private void addPreference(int size, int index, Preference preference) { + if (mDevicesList.size() >= index) { + mDevicesList.add(index, preference); + } else { + mDevicesList.add(preference); + } + mPreferenceGroup.removeAll(); + mPreferenceGroup.addPreference(mSeeAllPreference); + for (int i = 0; i < size; i++) { + if (DEBUG) { + Log.d(TAG, "addPreference() add device : " + mDevicesList.get(i).getTitle()); + } + mDevicesList.get(i).setOrder(i); + mPreferenceGroup.addPreference(mDevicesList.get(i)); + } + } + @Override public void onDeviceRemoved(Preference preference) { mPreferenceSize--; - mPreferenceGroup.removePreference(preference); + 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)); + } updatePreferenceVisibility(); } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java index e8b88f50389..3363ff5346c 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java @@ -23,8 +23,10 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; 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.content.pm.PackageManager; @@ -34,10 +36,12 @@ import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceManager; import com.android.settings.R; +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.testutils.shadow.ShadowBluetoothAdapter; +import com.android.settingslib.bluetooth.CachedBluetoothDevice; import org.junit.Before; import org.junit.Test; @@ -49,11 +53,18 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; +import java.util.ArrayList; +import java.util.List; + @RunWith(RobolectricTestRunner.class) @Config(shadows = ShadowBluetoothAdapter.class) public class PreviouslyConnectedDevicePreferenceControllerTest { - private final String KEY = "test_key"; + private static final String KEY = "test_key"; + private static final String FAKE_ADDRESS_1 = "AA:AA:AA:AA:AA:01"; + private static final String FAKE_ADDRESS_2 = "AA:AA:AA:AA:AA:02"; + private static final String FAKE_ADDRESS_3 = "AA:AA:AA:AA:AA:03"; + private static final String FAKE_ADDRESS_4 = "AA:AA:AA:AA:AA:04"; @Mock private DashboardFragment mDashboardFragment; @@ -67,6 +78,22 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { private PreferenceManager mPreferenceManager; @Mock private Preference mSeeAllPreference; + @Mock + private CachedBluetoothDevice mCachedDevice1; + @Mock + private CachedBluetoothDevice mCachedDevice2; + @Mock + private CachedBluetoothDevice mCachedDevice3; + @Mock + private CachedBluetoothDevice mCachedDevice4; + @Mock + private BluetoothDevice mBluetoothDevice1; + @Mock + private BluetoothDevice mBluetoothDevice2; + @Mock + private BluetoothDevice mBluetoothDevice3; + @Mock + private BluetoothDevice mBluetoothDevice4; private Context mContext; private PreviouslyConnectedDevicePreferenceController mPreConnectedDeviceController; @@ -85,6 +112,22 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { mPreConnectedDeviceController.setSavedDockUpdater(mDockUpdater); mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); + when(mCachedDevice1.getDevice()).thenReturn(mBluetoothDevice1); + when(mCachedDevice1.getAddress()).thenReturn(FAKE_ADDRESS_1); + when(mCachedDevice2.getDevice()).thenReturn(mBluetoothDevice2); + when(mCachedDevice2.getAddress()).thenReturn(FAKE_ADDRESS_2); + when(mCachedDevice3.getDevice()).thenReturn(mBluetoothDevice3); + when(mCachedDevice3.getAddress()).thenReturn(FAKE_ADDRESS_3); + when(mCachedDevice4.getDevice()).thenReturn(mBluetoothDevice4); + when(mCachedDevice4.getAddress()).thenReturn(FAKE_ADDRESS_4); + + final List mMostRecentlyConnectedDevices = new ArrayList<>(); + mMostRecentlyConnectedDevices.add(mBluetoothDevice1); + mMostRecentlyConnectedDevices.add(mBluetoothDevice2); + mMostRecentlyConnectedDevices.add(mBluetoothDevice4); + mMostRecentlyConnectedDevices.add(mBluetoothDevice3); + mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(mMostRecentlyConnectedDevices); + mPreferenceGroup = spy(new PreferenceCategory(mContext)); doReturn(mPreferenceManager).when(mPreferenceGroup).getPreferenceManager(); mPreferenceGroup.setVisible(false); @@ -136,29 +179,43 @@ public class PreviouslyConnectedDevicePreferenceControllerTest { @Test public void onDeviceAdded_addDevicePreference_displayIt() { - mPreConnectedDeviceController.onDeviceAdded(new Preference(mContext)); + final BluetoothDevicePreference preference1 = new BluetoothDevicePreference( + mContext, mCachedDevice1, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); - assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1); + mPreConnectedDeviceController.onDeviceAdded(preference1); + + assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(2); } @Test public void onDeviceAdded_addFourDevicePreference_onlyDisplayThree() { - mPreConnectedDeviceController.onDeviceAdded(new Preference(mContext)); - mPreConnectedDeviceController.onDeviceAdded(new Preference(mContext)); - mPreConnectedDeviceController.onDeviceAdded(new Preference(mContext)); - mPreConnectedDeviceController.onDeviceAdded(new Preference(mContext)); + final BluetoothDevicePreference preference1 = new BluetoothDevicePreference( + mContext, mCachedDevice1, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); + final BluetoothDevicePreference preference2 = new BluetoothDevicePreference( + mContext, mCachedDevice2, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); + final BluetoothDevicePreference preference3 = new BluetoothDevicePreference( + mContext, mCachedDevice3, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); + final BluetoothDevicePreference preference4 = new BluetoothDevicePreference( + mContext, mCachedDevice4, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); - assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(3); + mPreConnectedDeviceController.onDeviceAdded(preference1); + mPreConnectedDeviceController.onDeviceAdded(preference2); + mPreConnectedDeviceController.onDeviceAdded(preference3); + mPreConnectedDeviceController.onDeviceAdded(preference4); + + // 3 BluetoothDevicePreference and 1 see all preference + assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(4); } @Test - public void onDeviceRemoved_removeLastDevice_setInvisible() { - final Preference preference = new Preference(mContext); - mPreferenceGroup.addPreference(preference); + public void onDeviceRemoved_removeLastDevice_showSeeAllPreference() { + final BluetoothDevicePreference preference1 = new BluetoothDevicePreference( + mContext, mCachedDevice1, true, BluetoothDevicePreference.SortType.TYPE_NO_SORT); + mPreferenceGroup.addPreference(preference1); - mPreConnectedDeviceController.onDeviceRemoved(preference); + mPreConnectedDeviceController.onDeviceRemoved(preference1); - assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(0); + assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1); } @Test diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java index f65729366cf..9de5c7fc2da 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothAdapter.java @@ -17,6 +17,7 @@ package com.android.settings.testutils.shadow; import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -29,6 +30,7 @@ public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBlueto private int mState; private List mSupportedProfiles = new ArrayList<>(); + private List mMostRecentlyConnectedDevices = new ArrayList<>(); @Implementation protected List getSupportedProfiles() { @@ -56,4 +58,13 @@ public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBlueto protected boolean factoryReset() { return true; } + + @Implementation + protected List getMostRecentlyConnectedDevices() { + return mMostRecentlyConnectedDevices; + } + + public void setMostRecentlyConnectedDevices(List list) { + mMostRecentlyConnectedDevices = list; + } }