Settings: Add SMS Mirroring.
Bug: 37546615
Test: Updated Robolectric suite with new unit tests.
Change-Id: I02e1723e1b125b004ff679d6242df14bca4f08ce
diff --git a/res/drawable/ic_compare_arrows_24dp.xml b/res/drawable/ic_compare_arrows_24dp.xml
new file mode 100644
index 0000000..361a930
--- /dev/null
+++ b/res/drawable/ic_compare_arrows_24dp.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/colorControlNormal">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M9.01,14L2,14v2h7.01v3L13,15l-3.99,-4v3zM14.99,13v-3L22,10L22,8h-7.01L14.99,5L11,9l3.99,4z"/>
+</vector>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 95e6e18..835b7b4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7747,6 +7747,9 @@
<!-- Settings item summary for USB preference when set to entering MIDI mode [CHAR LIMIT=NONE] -->
<string name="usb_summary_MIDI">Using device as MIDI</string>
+ <!-- Settings item title for SMS Mirroring preference [CHAR LIMIT=35] -->
+ <string name="sms_mirroring_pref">SMS Mirroring</string>
+
<!-- Settings item title for background check prefs [CHAR LIMIT=35] -->
<string name="background_check_pref">Background check</string>
diff --git a/res/xml/connected_devices.xml b/res/xml/connected_devices.xml
index ecbcbd1..abbeda6 100644
--- a/res/xml/connected_devices.xml
+++ b/res/xml/connected_devices.xml
@@ -39,10 +39,16 @@
android:order="-4"/>
<Preference
+ android:key="sms_mirroring"
+ android:title="@string/sms_mirroring_pref"
+ android:icon="@drawable/ic_compare_arrows_24dp"
+ android:order="-3"/>
+
+ <Preference
android:key="usb_mode"
android:title="@string/usb_pref"
android:icon="@drawable/ic_usb"
- android:order="-3">
+ android:order="-2">
<intent android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.deviceinfo.UsbModeChooserActivity"/>
@@ -52,4 +58,4 @@
android:key="dashboard_tile_placeholder"
android:order="50"/>
-</PreferenceScreen>
\ No newline at end of file
+</PreferenceScreen>
diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
index e73da62..483b00c 100644
--- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
@@ -30,6 +30,7 @@
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.deviceinfo.UsbBackend;
import com.android.settings.nfc.NfcPreferenceController;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -81,6 +82,12 @@
(SettingsActivity) getActivity());
lifecycle.addObserver(bluetoothPreferenceController);
controllers.add(bluetoothPreferenceController);
+
+ SmsMirroringFeatureProvider smsMirroringFeatureProvider =
+ FeatureFactory.getFactory(context).getSmsMirroringFeatureProvider();
+ AbstractPreferenceController smsMirroringController =
+ smsMirroringFeatureProvider.getController(context);
+ controllers.add(smsMirroringController);
return controllers;
}
@@ -143,6 +150,13 @@
keys.add(NfcPreferenceController.KEY_ANDROID_BEAM_SETTINGS);
}
keys.add(BluetoothMasterSwitchPreferenceController.KEY_TOGGLE_BLUETOOTH);
+
+ SmsMirroringFeatureProvider smsMirroringFeatureProvider =
+ FeatureFactory.getFactory(context).getSmsMirroringFeatureProvider();
+ SmsMirroringPreferenceController smsMirroringController =
+ smsMirroringFeatureProvider.getController(context);
+ smsMirroringController.updateNonIndexableKeys(keys);
+
return keys;
}
};
diff --git a/src/com/android/settings/connecteddevice/SmsMirroringFeatureProvider.java b/src/com/android/settings/connecteddevice/SmsMirroringFeatureProvider.java
new file mode 100644
index 0000000..9064c81
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/SmsMirroringFeatureProvider.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 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;
+
+public interface SmsMirroringFeatureProvider {
+
+ /** Returns whether to show SMS mirroring. */
+ boolean shouldShowSmsMirroring(Context context);
+
+ /** Returns a preference controller for SMS mirroring. */
+ SmsMirroringPreferenceController getController(Context context);
+}
diff --git a/src/com/android/settings/connecteddevice/SmsMirroringFeatureProviderImpl.java b/src/com/android/settings/connecteddevice/SmsMirroringFeatureProviderImpl.java
new file mode 100644
index 0000000..c41d8f5
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/SmsMirroringFeatureProviderImpl.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 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;
+
+public class SmsMirroringFeatureProviderImpl implements SmsMirroringFeatureProvider {
+ @Override
+ public boolean shouldShowSmsMirroring(Context context) {
+ return false;
+ }
+
+ @Override
+ public SmsMirroringPreferenceController getController(Context context) {
+ return new SmsMirroringPreferenceController(context);
+ }
+}
+
diff --git a/src/com/android/settings/connecteddevice/SmsMirroringPreferenceController.java b/src/com/android/settings/connecteddevice/SmsMirroringPreferenceController.java
new file mode 100644
index 0000000..c293481
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/SmsMirroringPreferenceController.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2017 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 com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+public class SmsMirroringPreferenceController extends AbstractPreferenceController
+ implements PreferenceControllerMixin {
+
+ static final String KEY_SMS_MIRRORING = "sms_mirroring";
+
+ private SmsMirroringFeatureProvider mFeatureProvider;
+
+ public SmsMirroringPreferenceController(Context context) {
+ super(context);
+ mFeatureProvider = FeatureFactory.getFactory(context).getSmsMirroringFeatureProvider();
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return mFeatureProvider.shouldShowSmsMirroring(mContext);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_SMS_MIRRORING;
+ }
+}
diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java
index c426b58..1d0f24f 100644
--- a/src/com/android/settings/overlay/FeatureFactory.java
+++ b/src/com/android/settings/overlay/FeatureFactory.java
@@ -23,6 +23,7 @@
import com.android.settings.R;
import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.bluetooth.BluetoothFeatureProvider;
+import com.android.settings.connecteddevice.SmsMirroringFeatureProvider;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
@@ -103,6 +104,8 @@
public abstract DataPlanFeatureProvider getDataPlanFeatureProvider();
+ public abstract SmsMirroringFeatureProvider getSmsMirroringFeatureProvider();
+
public static final class FactoryNotFoundException extends RuntimeException {
public FactoryNotFoundException(Throwable throwable) {
super("Unable to create factory. Did you misconfigure Proguard?", throwable);
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java
index 38cd635..36c3bc9 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.java
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java
@@ -29,6 +29,8 @@
import com.android.settings.applications.PackageManagerWrapperImpl;
import com.android.settings.bluetooth.BluetoothFeatureProvider;
import com.android.settings.bluetooth.BluetoothFeatureProviderImpl;
+import com.android.settings.connecteddevice.SmsMirroringFeatureProvider;
+import com.android.settings.connecteddevice.SmsMirroringFeatureProviderImpl;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProviderImpl;
@@ -72,6 +74,7 @@
private UserFeatureProvider mUserFeatureProvider;
private BluetoothFeatureProvider mBluetoothFeatureProvider;
private DataPlanFeatureProvider mDataPlanFeatureProvider;
+ private SmsMirroringFeatureProvider mSmsMirroringFeatureProvider;
@Override
public SupportFeatureProvider getSupportFeatureProvider(Context context) {
@@ -197,4 +200,12 @@
}
return mAssistGestureFeatureProvider;
}
+
+ @Override
+ public SmsMirroringFeatureProvider getSmsMirroringFeatureProvider() {
+ if (mSmsMirroringFeatureProvider == null) {
+ mSmsMirroringFeatureProvider = new SmsMirroringFeatureProviderImpl();
+ }
+ return mSmsMirroringFeatureProvider;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java
index dbeecaa..4cb853e 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragmentTest.java
@@ -22,16 +22,19 @@
import android.provider.SearchIndexableResource;
import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.nfc.NfcPreferenceController;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.dashboard.SummaryLoader;
+import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settingslib.drawer.CategoryKey;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
@@ -50,19 +53,45 @@
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class ConnectedDeviceDashboardFragmentTest {
- @Mock
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
Context mContext;
@Mock
private PackageManager mManager;
+ private FakeFeatureFactory mFeatureFactory;
+ private SmsMirroringFeatureProvider mFeatureProvider;
private ConnectedDeviceDashboardFragment mFragment;
+ private TestSmsMirroringPreferenceController mSmsMirroringPreferenceController;
+
+ private static final class TestSmsMirroringPreferenceController
+ extends SmsMirroringPreferenceController implements PreferenceControllerMixin {
+
+ private boolean mIsAvailable;
+
+ public TestSmsMirroringPreferenceController(Context context) {
+ super(context);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return mIsAvailable;
+ }
+ }
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ FakeFeatureFactory.setupForTest(mContext);
+ mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
+ mFeatureProvider = mFeatureFactory.smsMirroringFeatureProvider;
+
mFragment = new ConnectedDeviceDashboardFragment();
when(mContext.getPackageManager()).thenReturn(mManager);
+
+ mSmsMirroringPreferenceController = new TestSmsMirroringPreferenceController(mContext);
+ when(mFeatureProvider.getController(mContext)).thenReturn(
+ mSmsMirroringPreferenceController);
}
@Test
@@ -103,11 +132,35 @@
}
@Test
+ public void testSearchIndexProvider_NoSmsMirroring_KeyAdded() {
+ when(mFeatureProvider.shouldShowSmsMirroring(mContext)).thenReturn(false);
+ mSmsMirroringPreferenceController.mIsAvailable = false;
+
+ final List<String> keys = mFragment.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(
+ mContext);
+
+ assertThat(keys).isNotNull();
+ assertThat(keys).contains(mSmsMirroringPreferenceController.getPreferenceKey());
+ }
+
+ @Test
+ public void testSearchIndexProvider_SmsMirroring_KeyNotAdded() {
+ when(mFeatureProvider.shouldShowSmsMirroring(mContext)).thenReturn(true);
+ mSmsMirroringPreferenceController.mIsAvailable = true;
+
+ final List<String> keys = mFragment.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(
+ mContext);
+
+ assertThat(keys).isNotNull();
+ assertThat(keys).doesNotContain(mSmsMirroringPreferenceController.getPreferenceKey());
+ }
+
+ @Test
public void testNonIndexableKeys_existInXmlLayout() {
final Context context = RuntimeEnvironment.application;
when(mManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(false);
final List<String> niks = ConnectedDeviceDashboardFragment.SEARCH_INDEX_DATA_PROVIDER
- .getNonIndexableKeys(context);
+ .getNonIndexableKeys(mContext);
final int xmlId = (new ConnectedDeviceDashboardFragment()).getPreferenceScreenResId();
final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId);
@@ -141,6 +194,7 @@
final SummaryLoader summaryLoader = mock(SummaryLoader.class);
when(mContext.getApplicationContext()).thenReturn(mContext);
+ when(mContext.getSystemService(NFC_SERVICE)).thenReturn(null);
SummaryLoader.SummaryProvider provider =
new ConnectedDeviceDashboardFragment.SummaryProvider(mContext, summaryLoader);
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index fe7ccbe..6da7a66 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -19,6 +19,7 @@
import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.bluetooth.BluetoothFeatureProvider;
+import com.android.settings.connecteddevice.SmsMirroringFeatureProvider;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
@@ -59,6 +60,7 @@
public final AssistGestureFeatureProvider assistGestureFeatureProvider;
public final BluetoothFeatureProvider bluetoothFeatureProvider;
public final DataPlanFeatureProvider dataPlanFeatureProvider;
+ public final SmsMirroringFeatureProvider smsMirroringFeatureProvider;
/**
* Call this in {@code @Before} method of the test class to use fake factory.
@@ -97,6 +99,7 @@
assistGestureFeatureProvider = mock(AssistGestureFeatureProvider.class);
bluetoothFeatureProvider = mock(BluetoothFeatureProvider.class);
dataPlanFeatureProvider = mock(DataPlanFeatureProvider.class);
+ smsMirroringFeatureProvider = mock(SmsMirroringFeatureProvider.class);
}
@Override
@@ -173,4 +176,9 @@
public AssistGestureFeatureProvider getAssistGestureFeatureProvider() {
return assistGestureFeatureProvider;
}
+
+ @Override
+ public SmsMirroringFeatureProvider getSmsMirroringFeatureProvider() {
+ return smsMirroringFeatureProvider;
+ }
}