From aa31bd43a350b4dce5eb76bf7c47e0105fefdc44 Mon Sep 17 00:00:00 2001 From: hughchen Date: Tue, 3 Apr 2018 16:15:03 +0800 Subject: [PATCH] Implement previously connected device UI * Move save device group to "Previously connected devices" Bug: 74134939 Test: make -j60 RunSettingsRoboTests Change-Id: Iff7894033df402d42dcc0ccaea6db3106edb7013 Merged-In: Iff7894033df402d42dcc0ccaea6db3106edb7013 --- res/drawable/ic_devices_other_black.xml | 29 +++++++ res/values/strings.xml | 2 + res/xml/connected_devices.xml | 18 ++-- res/xml/previously_connected_devices.xml | 27 ++++++ .../ConnectedDeviceDashboardFragment.java | 1 - ...ouslyConnectedDeviceDashboardFragment.java | 85 +++++++++++++++++++ .../SavedDeviceGroupController.java | 17 ++-- .../core/gateway/SettingsGateway.java | 2 + .../search/SearchIndexableResourcesImpl.java | 2 + .../SavedBluetoothDeviceUpdaterTest.java | 9 +- .../SavedDeviceGroupControllerTest.java | 75 ++++++---------- 11 files changed, 196 insertions(+), 71 deletions(-) create mode 100644 res/drawable/ic_devices_other_black.xml create mode 100644 res/xml/previously_connected_devices.xml create mode 100644 src/com/android/settings/connecteddevice/PreviouslyConnectedDeviceDashboardFragment.java diff --git a/res/drawable/ic_devices_other_black.xml b/res/drawable/ic_devices_other_black.xml new file mode 100644 index 00000000000..9974eafa1e8 --- /dev/null +++ b/res/drawable/ic_devices_other_black.xml @@ -0,0 +1,29 @@ + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index a351bd877ac..323d0751886 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6660,6 +6660,8 @@ + + diff --git a/res/xml/connected_devices.xml b/res/xml/connected_devices.xml index 7428019fa75..030428f9fb6 100644 --- a/res/xml/connected_devices.xml +++ b/res/xml/connected_devices.xml @@ -24,27 +24,29 @@ android:key="connected_device_list" android:title="@string/connected_device_connected_title"/> - - + + @@ -56,7 +58,7 @@ android:summary="@string/nfc_quick_toggle_summary"/> + android:title="@string/connected_device_connections_title" + android:fragment="com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment"/> diff --git a/res/xml/previously_connected_devices.xml b/res/xml/previously_connected_devices.xml new file mode 100644 index 00000000000..b0578a725be --- /dev/null +++ b/res/xml/previously_connected_devices.xml @@ -0,0 +1,27 @@ + + + + + + + + \ No newline at end of file diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java index b3dd8acf763..942fd7bd0b4 100644 --- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java +++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java @@ -72,7 +72,6 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment { Lifecycle lifecycle, DashboardFragment dashboardFragment) { final List controllers = new ArrayList<>(); controllers.add(new ConnectedDeviceGroupController(context, dashboardFragment, lifecycle)); - controllers.add(new SavedDeviceGroupController(context, dashboardFragment, lifecycle)); final NfcPreferenceController nfcPreferenceController = new NfcPreferenceController(context); diff --git a/src/com/android/settings/connecteddevice/PreviouslyConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/PreviouslyConnectedDeviceDashboardFragment.java new file mode 100644 index 00000000000..195daf372ff --- /dev/null +++ b/src/com/android/settings/connecteddevice/PreviouslyConnectedDeviceDashboardFragment.java @@ -0,0 +1,85 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.settings.connecteddevice; + +import android.content.Context; +import android.content.res.Resources; +import com.android.internal.logging.nano.MetricsProto; +import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.SearchIndexableRaw; + +import java.util.ArrayList; +import java.util.List; + +/** + * This fragment contains previously connected device + */ +public class PreviouslyConnectedDeviceDashboardFragment extends DashboardFragment { + + private static final String TAG = "PreConnectedDeviceFrag"; + static final String KEY_PREVIOUSLY_CONNECTED_DEVICES = "saved_device_list"; + + @Override + public int getHelpResource() { + return R.string.help_url_previously_connected_devices; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.previously_connected_devices; + } + + @Override + protected String getLogTag() { + return TAG; + } + + @Override + public int getMetricsCategory() { + return MetricsProto.MetricsEvent.PREVIOUSLY_CONNECTED_DEVICES; + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + use(SavedDeviceGroupController.class).init(this); + } + + /** + * For Search. + */ + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List getRawDataToIndex( + Context context, boolean enabled) { + final List result = new ArrayList(); + final Resources res = context.getResources(); + + // Add fragment title + SearchIndexableRaw data = new SearchIndexableRaw(context); + data.key = KEY_PREVIOUSLY_CONNECTED_DEVICES; + data.title = res.getString( + R.string.connected_device_previously_connected_title); + data.screenTitle = res.getString( + R.string.connected_device_previously_connected_title); + result.add(data); + return result; + } + }; +} \ No newline at end of file diff --git a/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java b/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java index ff21bff0dd0..d045c9ec22d 100644 --- a/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java +++ b/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java @@ -46,18 +46,15 @@ public class SavedDeviceGroupController extends BasePreferenceController PreferenceGroup mPreferenceGroup; private BluetoothDeviceUpdater mBluetoothDeviceUpdater; - public SavedDeviceGroupController(Context context, DashboardFragment fragment, - Lifecycle lifecycle) { + public SavedDeviceGroupController(Context context) { super(context, KEY); - init(lifecycle, new SavedBluetoothDeviceUpdater(context, fragment, - SavedDeviceGroupController.this)); } @VisibleForTesting - SavedDeviceGroupController(DashboardFragment fragment, Lifecycle lifecycle, + SavedDeviceGroupController(DashboardFragment fragment, BluetoothDeviceUpdater bluetoothDeviceUpdater) { super(fragment.getContext(), KEY); - init(lifecycle, bluetoothDeviceUpdater); + mBluetoothDeviceUpdater = bluetoothDeviceUpdater; } @Override @@ -108,10 +105,8 @@ public class SavedDeviceGroupController extends BasePreferenceController } } - private void init(Lifecycle lifecycle, BluetoothDeviceUpdater bluetoothDeviceUpdater) { - if (lifecycle != null && isAvailable()) { - lifecycle.addObserver(this); - } - mBluetoothDeviceUpdater = bluetoothDeviceUpdater; + public void init(DashboardFragment fragment) { + mBluetoothDeviceUpdater = new SavedBluetoothDeviceUpdater(fragment.getContext(), + fragment, SavedDeviceGroupController.this); } } diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index afa5f5e0f03..ede23dc7677 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -55,6 +55,7 @@ import com.android.settings.backup.ToggleBackupSettingFragment; import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment; import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment; import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment; +import com.android.settings.connecteddevice.PreviouslyConnectedDeviceDashboardFragment; import com.android.settings.connecteddevice.usb.UsbDetailsFragment; import com.android.settings.datausage.DataUsageList; import com.android.settings.datausage.DataUsageSummary; @@ -257,6 +258,7 @@ public class SettingsGateway { DataUsageList.class.getName(), DirectoryAccessDetails.class.getName(), ToggleBackupSettingFragment.class.getName(), + PreviouslyConnectedDeviceDashboardFragment.class.getName(), }; public static final String[] SETTINGS_FOR_RESTRICTED = { diff --git a/src/com/android/settings/search/SearchIndexableResourcesImpl.java b/src/com/android/settings/search/SearchIndexableResourcesImpl.java index 3e4e0be6d30..33bc2e0eee8 100644 --- a/src/com/android/settings/search/SearchIndexableResourcesImpl.java +++ b/src/com/android/settings/search/SearchIndexableResourcesImpl.java @@ -22,6 +22,7 @@ import com.android.settings.DateTimeSettings; import com.android.settings.DisplaySettings; import com.android.settings.LegalSettings; import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment; +import com.android.settings.connecteddevice.PreviouslyConnectedDeviceDashboardFragment; import com.android.settings.datausage.DataUsageSummaryLegacy; import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment; import com.android.settings.accessibility.AccessibilitySettings; @@ -183,6 +184,7 @@ public class SearchIndexableResourcesImpl implements SearchIndexableResources { addIndex(MyDeviceInfoFragment.class); addIndex(VibrationSettings.class); addIndex(RecentLocationRequestSeeAllFragment.class); + addIndex(PreviouslyConnectedDeviceDashboardFragment.class); } @Override diff --git a/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java index ee76269564b..e0ba82916b3 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java @@ -30,6 +30,8 @@ import com.android.settings.connecteddevice.DevicePreferenceCallback; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settingslib.bluetooth.CachedBluetoothDevice; +import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import org.junit.Before; import org.junit.Test; @@ -49,6 +51,10 @@ public class SavedBluetoothDeviceUpdaterTest { private CachedBluetoothDevice mCachedBluetoothDevice; @Mock private BluetoothDevice mBluetoothDevice; + @Mock + private LocalBluetoothManager mLocalManager; + @Mock + private LocalBluetoothProfileManager mLocalBluetoothProfileManager; private Context mContext; private BluetoothDeviceUpdater mBluetoothDeviceUpdater; @@ -60,9 +66,10 @@ public class SavedBluetoothDeviceUpdaterTest { mContext = RuntimeEnvironment.application; doReturn(mContext).when(mDashboardFragment).getContext(); when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice); + when(mLocalManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager); mBluetoothDeviceUpdater = spy(new SavedBluetoothDeviceUpdater(mDashboardFragment, - mDevicePreferenceCallback, null)); + mDevicePreferenceCallback, mLocalManager)); mBluetoothDeviceUpdater.setPrefContext(mContext); doNothing().when(mBluetoothDeviceUpdater).addPreference(any()); doNothing().when(mBluetoothDeviceUpdater).removePreference(any()); diff --git a/tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java index 3d606ddc2f2..a0d3d7bc574 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/SavedDeviceGroupControllerTest.java @@ -14,32 +14,20 @@ * limitations under the License */ package com.android.settings.connecteddevice; - -import static android.arch.lifecycle.Lifecycle.Event.ON_START; - import static com.android.settings.core.BasePreferenceController.AVAILABLE; import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED; - import static com.google.common.truth.Truth.assertThat; - import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; - import android.arch.lifecycle.LifecycleOwner; import android.content.Context; import android.content.pm.PackageManager; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceGroup; import android.support.v7.preference.PreferenceManager; -import android.support.v7.preference.PreferenceScreen; - import com.android.settings.bluetooth.BluetoothDeviceUpdater; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settingslib.core.lifecycle.Lifecycle; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -47,68 +35,55 @@ import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; @RunWith(SettingsRobolectricTestRunner.class) public class SavedDeviceGroupControllerTest { private static final String PREFERENCE_KEY_1 = "pref_key_1"; - @Mock private DashboardFragment mDashboardFragment; @Mock private BluetoothDeviceUpdater mBluetoothDeviceUpdater; - @Mock - private PreferenceScreen mPreferenceScreen; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private PreferenceManager mPreferenceManager; @Mock private PackageManager mPackageManager; - - private PreferenceGroup mPreferenceGroup; private Context mContext; - private Preference mPreference; - private SavedDeviceGroupController mConnectedDeviceGroupController; + private SavedDeviceGroupController mSavedDeviceGroupController; private LifecycleOwner mLifecycleOwner; private Lifecycle mLifecycle; - @Before public void setUp() { MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); mLifecycleOwner = () -> mLifecycle; mLifecycle = new Lifecycle(mLifecycleOwner); - doReturn(mContext).when(mDashboardFragment).getContext(); doReturn(mPackageManager).when(mContext).getPackageManager(); + mSavedDeviceGroupController = new SavedDeviceGroupController(mDashboardFragment, + mBluetoothDeviceUpdater); } - @Test - public void constructor_noBluetoothFeature_shouldNotRegisterCallback() { - doReturn(false).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); - - mConnectedDeviceGroupController = new SavedDeviceGroupController(mDashboardFragment, - mLifecycle, mBluetoothDeviceUpdater); - - assertThat(mConnectedDeviceGroupController.getAvailabilityStatus()).isEqualTo( - DISABLED_UNSUPPORTED); - - mLifecycle.handleLifecycleEvent(ON_START); - verify(mBluetoothDeviceUpdater, never()).registerCallback(); - } - - - @Test - public void constructor_hasBluetoothFeature_shouldRegisterCallback() { - doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); - - mConnectedDeviceGroupController = new SavedDeviceGroupController(mDashboardFragment, - mLifecycle, mBluetoothDeviceUpdater); - - assertThat(mConnectedDeviceGroupController.getAvailabilityStatus()).isEqualTo( - AVAILABLE); - - mLifecycle.handleLifecycleEvent(ON_START); + public void testRegister() { + // register the callback in onStart() + mSavedDeviceGroupController.onStart(); verify(mBluetoothDeviceUpdater).registerCallback(); } -} + @Test + public void testUnregister() { + // unregister the callback in onStop() + mSavedDeviceGroupController.onStop(); + verify(mBluetoothDeviceUpdater).unregisterCallback(); + } + @Test + public void testGetAvailabilityStatus_noBluetoothFeature_returnUnSupported() { + doReturn(false).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); + assertThat(mSavedDeviceGroupController.getAvailabilityStatus()).isEqualTo( + DISABLED_UNSUPPORTED); + } + @Test + public void testGetAvailabilityStatus_BluetoothFeature_returnSupported() { + doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); + assertThat(mSavedDeviceGroupController.getAvailabilityStatus()).isEqualTo( + AVAILABLE); + } +} \ No newline at end of file