diff --git a/res/drawable/ic_compare_arrows_24dp.xml b/res/drawable/ic_compare_arrows_24dp.xml
new file mode 100644
index 00000000000..361a930ea4b
--- /dev/null
+++ b/res/drawable/ic_compare_arrows_24dp.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f68fe68cd22..03a70e0aa3f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7762,6 +7762,9 @@
Using device as MIDI
+
+ SMS Mirroring
+
Background check
diff --git a/res/xml/connected_devices.xml b/res/xml/connected_devices.xml
index ecbcbd1119a..abbeda67384 100644
--- a/res/xml/connected_devices.xml
+++ b/res/xml/connected_devices.xml
@@ -38,11 +38,17 @@
android:icon="@drawable/ic_android"
android:order="-4"/>
+
+
+ android:order="-2">
@@ -52,4 +58,4 @@
android:key="dashboard_tile_placeholder"
android:order="50"/>
-
\ 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 e73da62cb11..483b00c3e44 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.DashboardFragment;
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 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment {
(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 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment {
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 00000000000..9064c816cc8
--- /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 00000000000..c41d8f554ea
--- /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 00000000000..c293481c88b
--- /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 c426b582b74..1d0f24f0bae 100644
--- a/src/com/android/settings/overlay/FeatureFactory.java
+++ b/src/com/android/settings/overlay/FeatureFactory.java
@@ -23,6 +23,7 @@ import android.util.Log;
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 class FeatureFactory {
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 38cd6353eeb..36c3bc943e6 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.IPackageManagerWrapperImpl;
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 @@ public class FeatureFactoryImpl extends FeatureFactory {
private UserFeatureProvider mUserFeatureProvider;
private BluetoothFeatureProvider mBluetoothFeatureProvider;
private DataPlanFeatureProvider mDataPlanFeatureProvider;
+ private SmsMirroringFeatureProvider mSmsMirroringFeatureProvider;
@Override
public SupportFeatureProvider getSupportFeatureProvider(Context context) {
@@ -197,4 +200,12 @@ public class FeatureFactoryImpl extends FeatureFactory {
}
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 dbeecaa2b93..4cb853eb820 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.nfc.NfcManager;
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 @@ import static org.mockito.Mockito.when;
@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
@@ -102,12 +131,36 @@ public class ConnectedDeviceDashboardFragmentTest {
assertThat(keys).doesNotContain(NfcPreferenceController.KEY_ANDROID_BEAM_SETTINGS);
}
+ @Test
+ public void testSearchIndexProvider_NoSmsMirroring_KeyAdded() {
+ when(mFeatureProvider.shouldShowSmsMirroring(mContext)).thenReturn(false);
+ mSmsMirroringPreferenceController.mIsAvailable = false;
+
+ final List 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 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 niks = ConnectedDeviceDashboardFragment.SEARCH_INDEX_DATA_PROVIDER
- .getNonIndexableKeys(context);
+ .getNonIndexableKeys(mContext);
final int xmlId = (new ConnectedDeviceDashboardFragment()).getPreferenceScreenResId();
final List keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId);
@@ -141,6 +194,7 @@ public class ConnectedDeviceDashboardFragmentTest {
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 fe7ccbe8920..6da7a6655c5 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 android.content.Context;
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 class FakeFeatureFactory extends FeatureFactory {
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 @@ public class FakeFeatureFactory extends FeatureFactory {
assistGestureFeatureProvider = mock(AssistGestureFeatureProvider.class);
bluetoothFeatureProvider = mock(BluetoothFeatureProvider.class);
dataPlanFeatureProvider = mock(DataPlanFeatureProvider.class);
+ smsMirroringFeatureProvider = mock(SmsMirroringFeatureProvider.class);
}
@Override
@@ -173,4 +176,9 @@ public class FakeFeatureFactory extends FeatureFactory {
public AssistGestureFeatureProvider getAssistGestureFeatureProvider() {
return assistGestureFeatureProvider;
}
+
+ @Override
+ public SmsMirroringFeatureProvider getSmsMirroringFeatureProvider() {
+ return smsMirroringFeatureProvider;
+ }
}