diff --git a/res/xml/connected_devices_advanced.xml b/res/xml/connected_devices_advanced.xml index dda5655f083..fd4e5b480e2 100644 --- a/res/xml/connected_devices_advanced.xml +++ b/res/xml/connected_devices_advanced.xml @@ -17,7 +17,7 @@ createPreferenceControllers(Context context) { - final List controllers = new ArrayList<>(); - final Lifecycle lifecycle = getLifecycle(); + return buildPreferenceControllers(context, getLifecycle(), this); + } - controllers.add(new ConnectedDeviceGroupController(this, lifecycle)); - controllers.add(new SavedDeviceGroupController(this, lifecycle)); + private static List buildPreferenceControllers(Context context, + Lifecycle lifecycle, DashboardFragment dashboardFragment) { + final List controllers = new ArrayList<>(); + controllers.add(new ConnectedDeviceGroupController(context, dashboardFragment, lifecycle)); + controllers.add(new SavedDeviceGroupController(context, dashboardFragment, lifecycle)); return controllers; } @@ -108,18 +116,30 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment { /** * For Search. */ - //TODO(b/69333961): update the index for this new fragment - public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider() { @Override public List getXmlResourcesToIndex( Context context, boolean enabled) { - return new ArrayList<>(); + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = R.xml.connected_devices; + return Arrays.asList(sir); + } + + @Override + public List createPreferenceControllers(Context + context) { + return buildPreferenceControllers(context, null /* lifecycle */, + null /* dashboardFragment */); } @Override public List getNonIndexableKeys(Context context) { - return new ArrayList<>(); + List keys = super.getNonIndexableKeys(context); + // Disable because they show dynamic data + keys.add(KEY_CONNECTED_DEVICES); + keys.add(KEY_SAVED_DEVICES); + return keys; } }; } diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java b/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java index c77a7358d60..731acae663f 100644 --- a/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java +++ b/src/com/android/settings/connecteddevice/ConnectedDeviceGroupController.java @@ -16,6 +16,7 @@ package com.android.settings.connecteddevice; import android.content.pm.PackageManager; +import android.content.Context; import android.support.annotation.VisibleForTesting; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceGroup; @@ -26,8 +27,6 @@ import com.android.settings.core.BasePreferenceController; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.bluetooth.BluetoothDeviceUpdater; import com.android.settings.bluetooth.ConnectedBluetoothDeviceUpdater; -import com.android.settings.search.ResultPayload; -import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settings.dashboard.DashboardFragment; @@ -49,10 +48,11 @@ public class ConnectedDeviceGroupController extends BasePreferenceController private BluetoothDeviceUpdater mBluetoothDeviceUpdater; private ConnectedUsbDeviceUpdater mConnectedUsbDeviceUpdater; - public ConnectedDeviceGroupController(DashboardFragment fragment, Lifecycle lifecycle) { - super(fragment.getContext(), KEY); - init(lifecycle, new ConnectedBluetoothDeviceUpdater(fragment, this), - new ConnectedUsbDeviceUpdater(fragment, this)); + public ConnectedDeviceGroupController(Context context, DashboardFragment fragment, + Lifecycle lifecycle) { + super(context, KEY); + init(lifecycle, new ConnectedBluetoothDeviceUpdater(context, fragment, this), + new ConnectedUsbDeviceUpdater(context, fragment, this)); } @VisibleForTesting diff --git a/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java b/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java index da38d9fddbc..ff21bff0dd0 100644 --- a/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java +++ b/src/com/android/settings/connecteddevice/SavedDeviceGroupController.java @@ -16,6 +16,7 @@ package com.android.settings.connecteddevice; import android.content.pm.PackageManager; +import android.content.Context; import android.support.annotation.VisibleForTesting; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceGroup; @@ -26,7 +27,6 @@ import com.android.settings.bluetooth.SavedBluetoothDeviceUpdater; import com.android.settings.core.BasePreferenceController; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.dashboard.DashboardFragment; -import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; @@ -46,9 +46,11 @@ public class SavedDeviceGroupController extends BasePreferenceController PreferenceGroup mPreferenceGroup; private BluetoothDeviceUpdater mBluetoothDeviceUpdater; - public SavedDeviceGroupController(DashboardFragment fragment, Lifecycle lifecycle) { - super(fragment.getContext(), KEY); - init(lifecycle, new SavedBluetoothDeviceUpdater(fragment, SavedDeviceGroupController.this)); + public SavedDeviceGroupController(Context context, DashboardFragment fragment, + Lifecycle lifecycle) { + super(context, KEY); + init(lifecycle, new SavedBluetoothDeviceUpdater(context, fragment, + SavedDeviceGroupController.this)); } @VisibleForTesting diff --git a/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdater.java b/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdater.java index 31910980db6..b570204fba4 100644 --- a/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdater.java +++ b/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdater.java @@ -50,18 +50,18 @@ public class ConnectedUsbDeviceUpdater { } }; - public ConnectedUsbDeviceUpdater(DashboardFragment fragment, + public ConnectedUsbDeviceUpdater(Context context, DashboardFragment fragment, DevicePreferenceCallback devicePreferenceCallback) { - this(fragment, devicePreferenceCallback, new UsbBackend(fragment.getContext())); + this(context, fragment, devicePreferenceCallback, new UsbBackend(context)); } @VisibleForTesting - ConnectedUsbDeviceUpdater(DashboardFragment fragment, + ConnectedUsbDeviceUpdater(Context context, DashboardFragment fragment, DevicePreferenceCallback devicePreferenceCallback, UsbBackend usbBackend) { mFragment = fragment; mDevicePreferenceCallback = devicePreferenceCallback; mUsbBackend = usbBackend; - mUsbReceiver = new UsbConnectionBroadcastReceiver(fragment.getContext(), + mUsbReceiver = new UsbConnectionBroadcastReceiver(context, mUsbConnectionListener, mUsbBackend); } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java index a628d40048b..982de54cd93 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java @@ -20,8 +20,12 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.provider.SearchIndexableResource; +import com.android.settings.bluetooth.BluetoothMasterSwitchPreferenceController; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.XmlTestUtils; +import com.android.settings.testutils.shadow.ShadowBluetoothPan; +import com.android.settings.testutils.shadow.ShadowConnectivityManager; +import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settingslib.drawer.CategoryKey; import org.junit.Before; @@ -29,10 +33,13 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; import java.util.List; @RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = {ShadowBluetoothPan.class, ShadowUserManager.class, + ShadowConnectivityManager.class}) public class AdvancedConnectedDeviceDashboardFragmentTest { private AdvancedConnectedDeviceDashboardFragment mFragment; @@ -67,12 +74,10 @@ public class AdvancedConnectedDeviceDashboardFragmentTest { @Test public void testNonIndexableKeys_existInXmlLayout() { final Context context = RuntimeEnvironment.application; - final List niks = ConnectedDeviceDashboardFragment.SEARCH_INDEX_DATA_PROVIDER - .getNonIndexableKeys(context); - final int xmlId = new ConnectedDeviceDashboardFragment().getPreferenceScreenResId(); + final List niks = + AdvancedConnectedDeviceDashboardFragment.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(context); - final List keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId); - - assertThat(keys).containsAllIn(niks); + assertThat(niks).contains(BluetoothMasterSwitchPreferenceController.KEY_TOGGLE_BLUETOOTH); } } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java new file mode 100644 index 00000000000..c68771c2fdf --- /dev/null +++ b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 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 static com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment + .KEY_CONNECTED_DEVICES; +import static com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment + .KEY_SAVED_DEVICES; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.provider.SearchIndexableResource; + +import com.android.settings.R; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.ShadowBluetoothPan; +import com.android.settings.testutils.shadow.ShadowConnectivityManager; +import com.android.settings.testutils.shadow.ShadowUserManager; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.util.List; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = {ShadowBluetoothPan.class, ShadowUserManager.class, + ShadowConnectivityManager.class}) +public class ConnectedDeviceDashboardFragmentTest { + @Mock + private PackageManager mPackageManager; + private Context mContext; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mContext = spy(RuntimeEnvironment.application); + doReturn(mPackageManager).when(mContext).getPackageManager(); + doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); + } + + @Test + public void testSearchIndexProvider_shouldIndexResource() { + final List indexRes = + ConnectedDeviceDashboardFragment.SEARCH_INDEX_DATA_PROVIDER + .getXmlResourcesToIndex(mContext, true /* enabled */); + + assertThat(indexRes).isNotNull(); + assertThat(indexRes.get(0).xmlResId).isEqualTo(R.xml.connected_devices); + } + + @Test + public void testNonIndexableKeys_existInXmlLayout() { + final List niks = ConnectedDeviceDashboardFragment.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(mContext); + + assertThat(niks).containsExactly(KEY_CONNECTED_DEVICES, KEY_SAVED_DEVICES); + } +} diff --git a/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java index 46a5da93ca1..928e1c68094 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/usb/ConnectedUsbDeviceUpdaterTest.java @@ -58,7 +58,8 @@ public class ConnectedUsbDeviceUpdaterTest { mContext = RuntimeEnvironment.application; when(mFragment.getContext()).thenReturn(mContext); mDeviceUpdater = - new ConnectedUsbDeviceUpdater(mFragment, mDevicePreferenceCallback, mUsbBackend); + new ConnectedUsbDeviceUpdater(mContext, mFragment, mDevicePreferenceCallback, + mUsbBackend); mDeviceUpdater.mUsbReceiver = mUsbReceiver; } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothPan.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothPan.java new file mode 100644 index 00000000000..2724d98d703 --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowBluetoothPan.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 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.testutils.shadow; + +import android.bluetooth.BluetoothPan; +import android.bluetooth.BluetoothProfile; +import android.content.Context; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +@Implements(BluetoothPan.class) +public class ShadowBluetoothPan { + @Implementation + public void __constructor__(Context context, BluetoothProfile.ServiceListener l) { + // Do nothing, implement it to avoid null pointer error inside BluetoothPan + } +}