Merge "Show just disconnected device on previously connected" into rvc-qpr-dev
diff --git a/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java b/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java
index 3d4dd29..78791d4 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.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.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<Preference> mDevicesList = new ArrayList<>();
+
     private PreferenceGroup mPreferenceGroup;
     private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
     private DockUpdater mSavedDockUpdater;
@@ -116,16 +127,56 @@
     @Override
     public void onDeviceAdded(Preference preference) {
         mPreferenceSize++;
+        final List<BluetoothDevice> 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 e8b88f5..3363ff5 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 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.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.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 @@
     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 @@
         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<BluetoothDevice> 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 @@
 
     @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 f657293..9de5c7f 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 @@
 
     private int mState;
     private List<Integer> mSupportedProfiles = new ArrayList<>();
+    private List<BluetoothDevice> mMostRecentlyConnectedDevices = new ArrayList<>();
 
     @Implementation
     protected List<Integer> getSupportedProfiles() {
@@ -56,4 +58,13 @@
     protected boolean factoryReset() {
         return true;
     }
+
+    @Implementation
+    protected List<BluetoothDevice> getMostRecentlyConnectedDevices() {
+        return mMostRecentlyConnectedDevices;
+    }
+
+    public void setMostRecentlyConnectedDevices(List<BluetoothDevice> list) {
+        mMostRecentlyConnectedDevices = list;
+    }
 }