diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 90aa55ff1a7..829425cfb91 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2991,7 +2991,7 @@ android:label="@string/settings_panel_title" android:theme="@style/Theme.BottomDialog" android:excludeFromRecents="true" - android:launchMode="singleTask" + android:launchMode="singleTop" android:exported="true"> diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java index 7bf01531f85..f678e08032a 100644 --- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java +++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java @@ -119,6 +119,14 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon && mSubId == SubscriptionManager.getDefaultDataSubscriptionId(); } + public static Uri getObservableUri(int subId) { + Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA); + if (TelephonyManager.getDefault().getSimCount() != 1) { + uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + subId); + } + return uri; + } + public void init(FragmentManager fragmentManager, int subId) { mFragmentManager = fragmentManager; mSubId = subId; @@ -169,10 +177,7 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon } public void register(Context context, int subId) { - Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA); - if (TelephonyManager.getDefault().getSimCount() != 1) { - uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + subId); - } + final Uri uri = getObservableUri(subId); context.getContentResolver().registerContentObserver(uri, false, this); } diff --git a/src/com/android/settings/network/telephony/MobileDataSlice.java b/src/com/android/settings/network/telephony/MobileDataSlice.java new file mode 100644 index 00000000000..6efd8c3aed6 --- /dev/null +++ b/src/com/android/settings/network/telephony/MobileDataSlice.java @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2019 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.network.telephony; + +import static android.app.slice.Slice.EXTRA_TOGGLE_STATE; + +import android.annotation.ColorInt; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Handler; +import android.os.Looper; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; + +import androidx.core.graphics.drawable.IconCompat; +import androidx.slice.Slice; +import androidx.slice.builders.ListBuilder; +import androidx.slice.builders.SliceAction; + +import com.android.settings.R; +import com.android.settings.Utils; +import com.android.settings.network.AirplaneModePreferenceController; +import com.android.settings.slices.CustomSliceRegistry; +import com.android.settings.slices.CustomSliceable; +import com.android.settings.slices.SliceBackgroundWorker; + +import com.google.common.annotations.VisibleForTesting; + +import java.io.IOException; + +/** + * Custom {@link Slice} for Mobile Data. + *

+ * We make a custom slice instead of using {@link MobileDataPreferenceController} because the + * pref controller is generalized across any carrier, and thus does not control a specific + * subscription. We attempt to reuse any telephony-specific code from the preference controller. + * + *

+ * + */ +public class MobileDataSlice implements CustomSliceable { + + private final Context mContext; + private final SubscriptionManager mSubscriptionManager; + private final TelephonyManager mTelephonyManager; + + public MobileDataSlice(Context context) { + mContext = context; + mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class); + mTelephonyManager = mContext.getSystemService(TelephonyManager.class); + } + + @Override + public Slice getSlice() { + final IconCompat icon = IconCompat.createWithResource(mContext, + R.drawable.ic_network_cell); + final String title = mContext.getText(R.string.mobile_data_settings_title).toString(); + final CharSequence summary = getSummary(); + @ColorInt final int color = Utils.getColorAccentDefaultColor(mContext); + final PendingIntent toggleAction = getBroadcastIntent(mContext); + final PendingIntent primaryAction = getPrimaryAction(); + final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryAction, icon, + ListBuilder.ICON_IMAGE, title); + final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction, + null /* actionTitle */, isMobileDataEnabled()); + + final ListBuilder listBuilder = new ListBuilder(mContext, getUri(), + ListBuilder.INFINITY) + .setAccentColor(color) + .addRow(new ListBuilder.RowBuilder() + .setTitle(title) + .setSubtitle(summary) + .addEndItem(toggleSliceAction) + .setPrimaryAction(primarySliceAction)); + return listBuilder.build(); + } + + @Override + public Uri getUri() { + return CustomSliceRegistry.MOBILE_DATA_SLICE_URI; + } + + @Override + public void onNotifyChange(Intent intent) { + // Don't make a change if we are in Airplane Mode. + if (isAirplaneModeEnabled()) { + return; + } + + final boolean newState = intent.getBooleanExtra(EXTRA_TOGGLE_STATE, + isMobileDataEnabled()); + + final int defaultSubId = getDefaultSubscriptionId(mSubscriptionManager); + if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + return; // No subscription - do nothing. + } + + MobileNetworkUtils.setMobileDataEnabled(mContext, defaultSubId, newState, + false /* disableOtherSubscriptions */); + // Do not notifyChange on Uri. The service takes longer to update the current value than it + // does for the Slice to check the current value again. Let {@link WifiScanWorker} + // handle it. + } + + @Override + public IntentFilter getIntentFilter() { + final IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); + return filter; + } + + @Override + public Intent getIntent() { + return new Intent(mContext, MobileNetworkActivity.class); + } + + @Override + public Class getBackgroundWorkerClass() { + return MobileDataWorker.class; + } + + protected static int getDefaultSubscriptionId(SubscriptionManager subscriptionManager) { + final SubscriptionInfo defaultSubscription = + subscriptionManager.getDefaultDataSubscriptionInfo(); + if (defaultSubscription == null) { + return SubscriptionManager.INVALID_SUBSCRIPTION_ID; // No default subscription + } + + return defaultSubscription.getSubscriptionId(); + } + + private CharSequence getSummary() { + final SubscriptionInfo defaultSubscription = + mSubscriptionManager.getDefaultDataSubscriptionInfo(); + if (defaultSubscription == null) { + return null; // no summary text + } + + return defaultSubscription.getDisplayName(); + } + + private PendingIntent getPrimaryAction() { + final Intent intent = getIntent(); + return PendingIntent.getActivity(mContext, 0 /* requestCode */, + intent, 0 /* flags */); + } + + @VisibleForTesting + boolean isAirplaneModeEnabled() { + // Generic key since we only want the method check - no UI. + AirplaneModePreferenceController controller = new AirplaneModePreferenceController(mContext, + "key" /* Key */); + return controller.isChecked(); + } + + @VisibleForTesting + boolean isMobileDataEnabled() { + if (mTelephonyManager == null) { + return false; + } + + return mTelephonyManager.isDataEnabled(); + } + + /** + * Listener for mobile data state changes. + * + *

+ * Listen to individual subscription changes since there is no framework broadcast. + * + * This worker registers a ContentObserver in the background and updates the MobileData + * Slice when the value changes. + */ + public static class MobileDataWorker extends SliceBackgroundWorker { + + DataContentObserver mMobileDataObserver; + + public MobileDataWorker(Context context, Uri uri) { + super(context, uri); + final Handler handler = new Handler(Looper.getMainLooper()); + mMobileDataObserver = new DataContentObserver(handler, this); + } + + @Override + protected void onSlicePinned() { + final SubscriptionManager subscriptionManager = + getContext().getSystemService(SubscriptionManager.class); + mMobileDataObserver.register(getContext(), + getDefaultSubscriptionId(subscriptionManager)); + } + + @Override + protected void onSliceUnpinned() { + mMobileDataObserver.unRegister(getContext()); + } + + @Override + public void close() throws IOException { + mMobileDataObserver = null; + } + + public void updateSlice() { + notifySliceChange(); + } + + public class DataContentObserver extends ContentObserver { + + private final MobileDataWorker mSliceBackgroundWorker; + + public DataContentObserver(Handler handler, MobileDataWorker backgroundWorker) { + super(handler); + mSliceBackgroundWorker = backgroundWorker; + } + + @Override + public void onChange(boolean selfChange) { + mSliceBackgroundWorker.updateSlice(); + } + + public void register(Context context, int subId) { + final Uri uri = MobileDataPreferenceController.getObservableUri(subId); + context.getContentResolver().registerContentObserver(uri, false, this); + } + + public void unRegister(Context context) { + context.getContentResolver().unregisterContentObserver(this); + } + } + } +} diff --git a/src/com/android/settings/panel/InternetConnectivityPanel.java b/src/com/android/settings/panel/InternetConnectivityPanel.java index aae42f87e94..d20b75afce4 100644 --- a/src/com/android/settings/panel/InternetConnectivityPanel.java +++ b/src/com/android/settings/panel/InternetConnectivityPanel.java @@ -55,6 +55,7 @@ public class InternetConnectivityPanel implements PanelContent { public List getSlices() { final List uris = new ArrayList<>(); uris.add(CustomSliceRegistry.WIFI_SLICE_URI); + uris.add(CustomSliceRegistry.MOBILE_DATA_SLICE_URI); uris.add(CustomSliceRegistry.AIRPLANE_URI); return uris; } diff --git a/src/com/android/settings/slices/CustomSliceManager.java b/src/com/android/settings/slices/CustomSliceManager.java index 3786c5c2ed9..c9e473a9c20 100644 --- a/src/com/android/settings/slices/CustomSliceManager.java +++ b/src/com/android/settings/slices/CustomSliceManager.java @@ -18,7 +18,6 @@ package com.android.settings.slices; import android.content.Context; import android.net.Uri; -import android.text.TextUtils; import android.util.ArrayMap; import androidx.annotation.VisibleForTesting; @@ -35,6 +34,7 @@ import com.android.settings.homepage.contextualcards.slices.LowStorageSlice; import com.android.settings.homepage.contextualcards.slices.NotificationChannelSlice; import com.android.settings.location.LocationSlice; import com.android.settings.media.MediaOutputSlice; +import com.android.settings.network.telephony.MobileDataSlice; import com.android.settings.wifi.slice.ContextualWifiSlice; import com.android.settings.wifi.slice.WifiSlice; @@ -123,6 +123,7 @@ public class CustomSliceManager { mUriMap.put(CustomSliceRegistry.FLASHLIGHT_SLICE_URI, FlashlightSlice.class); mUriMap.put(CustomSliceRegistry.LOCATION_SLICE_URI, LocationSlice.class); mUriMap.put(CustomSliceRegistry.LOW_STORAGE_SLICE_URI, LowStorageSlice.class); + mUriMap.put(CustomSliceRegistry.MOBILE_DATA_SLICE_URI, MobileDataSlice.class); mUriMap.put(CustomSliceRegistry.NOTIFICATION_CHANNEL_SLICE_URI, NotificationChannelSlice.class); mUriMap.put(CustomSliceRegistry.STORAGE_SLICE_URI, StorageSlice.class); diff --git a/src/com/android/settings/slices/CustomSliceRegistry.java b/src/com/android/settings/slices/CustomSliceRegistry.java index 66e85c0612d..ab1b2484828 100644 --- a/src/com/android/settings/slices/CustomSliceRegistry.java +++ b/src/com/android/settings/slices/CustomSliceRegistry.java @@ -164,6 +164,16 @@ public class CustomSliceRegistry { .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath("toggle_nfc") .build(); + + /** + * Backing Uri for Mobile Data Slice. + */ + public static final Uri MOBILE_DATA_SLICE_URI = new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSliceProvider.SLICE_AUTHORITY) + .appendEncodedPath(SettingsSlicesContract.PATH_SETTING_ACTION) + .appendPath("mobile_data") + .build(); /** * Backing Uri for Notification channel Slice. */ diff --git a/src/com/android/settings/slices/CustomSliceable.java b/src/com/android/settings/slices/CustomSliceable.java index b538b898252..220cdc80dbf 100644 --- a/src/com/android/settings/slices/CustomSliceable.java +++ b/src/com/android/settings/slices/CustomSliceable.java @@ -71,7 +71,7 @@ public interface CustomSliceable { * * @param intent which has the action taken on a {@link Slice}. */ - void onNotifyChange(Intent intent); + default void onNotifyChange(Intent intent) {} /** * @return an {@link Intent} to the source of the Slice data. @@ -90,11 +90,12 @@ public interface CustomSliceable { } /** - * Settings Slices which can represent component lists that are updatable by the - * {@link SliceBackgroundWorker} class returned here. + * Settings Slices which require background work, such as updating lists should implement a + * {@link SliceBackgroundWorker} and return it here. An example of background work is updating + * a list of Wifi networks available in the area. * - * @return a {@link SliceBackgroundWorker} class for fetching the list of results in the - * background. + * @return a {@link Class} to perform background work for the + * slice. */ default Class getBackgroundWorkerClass() { return null; diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java index 80b71335646..7b9acee6cf7 100644 --- a/src/com/android/settings/slices/SettingsSliceProvider.java +++ b/src/com/android/settings/slices/SettingsSliceProvider.java @@ -464,8 +464,9 @@ public class SettingsSliceProvider extends SliceProvider { private List getSpecialCaseOemUris() { return Arrays.asList( - CustomSliceRegistry.ZEN_MODE_SLICE_URI, - CustomSliceRegistry.FLASHLIGHT_SLICE_URI + CustomSliceRegistry.FLASHLIGHT_SLICE_URI, + CustomSliceRegistry.MOBILE_DATA_SLICE_URI, + CustomSliceRegistry.ZEN_MODE_SLICE_URI ); } diff --git a/src/com/android/settings/slices/SliceBackgroundWorker.java b/src/com/android/settings/slices/SliceBackgroundWorker.java index 6df45ba93e3..995394e7d41 100644 --- a/src/com/android/settings/slices/SliceBackgroundWorker.java +++ b/src/com/android/settings/slices/SliceBackgroundWorker.java @@ -59,6 +59,14 @@ public abstract class SliceBackgroundWorker implements Closeable { mUri = uri; } + protected Uri getUri() { + return mUri; + } + + protected Context getContext() { + return mContext; + } + /** * Returns the singleton instance of the {@link SliceBackgroundWorker} for specified {@link Uri} * if exists @@ -151,7 +159,7 @@ public abstract class SliceBackgroundWorker implements Closeable { /** * Notify that data was updated and attempt to sync changes to the Slice. */ - protected void notifySliceChange() { + protected final void notifySliceChange() { mContext.getContentResolver().notifyChange(mUri, null); } } \ No newline at end of file diff --git a/src/com/android/settings/wifi/slice/WifiSlice.java b/src/com/android/settings/wifi/slice/WifiSlice.java index 1a0ed0ce90e..bee643df363 100644 --- a/src/com/android/settings/wifi/slice/WifiSlice.java +++ b/src/com/android/settings/wifi/slice/WifiSlice.java @@ -142,7 +142,7 @@ public class WifiSlice implements CustomSliceable { .setTitle(title) .setSubtitle(!TextUtils.isEmpty(apSummary) ? apSummary - : mContext.getText(R.string.summary_placeholder)) + : null) .setPrimaryAction(SliceAction.create( getAccessPointAction(accessPoint), levelIcon, ListBuilder.ICON_IMAGE, title)); @@ -247,7 +247,7 @@ public class WifiSlice implements CustomSliceable { return mContext.getText(R.string.switch_off_text); case WifiManager.WIFI_STATE_UNKNOWN: default: - return ""; + return null; } } diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileDataSliceTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileDataSliceTest.java new file mode 100644 index 00000000000..c497cf82665 --- /dev/null +++ b/tests/robotests/src/com/android/settings/network/telephony/MobileDataSliceTest.java @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2019 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.network.telephony; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.content.Context; +import android.content.Intent; +import android.provider.Settings; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; + +import androidx.core.graphics.drawable.IconCompat; +import androidx.slice.Slice; +import androidx.slice.SliceMetadata; +import androidx.slice.SliceProvider; +import androidx.slice.core.SliceAction; +import androidx.slice.widget.SliceLiveData; + +import com.android.settings.R; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +import java.util.List; + +@RunWith(RobolectricTestRunner.class) +public class MobileDataSliceTest { + + private static final int SUB_ID = 2; + + @Mock + private TelephonyManager mTelephonyManager; + @Mock + private SubscriptionManager mSubscriptionManager; + @Mock + private SubscriptionInfo mSubscriptionInfo; + + private Context mContext; + private MobileDataSlice mMobileDataSlice; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application); + + doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE); + doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class); + doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID); + doReturn(mSubscriptionInfo).when(mSubscriptionManager).getDefaultDataSubscriptionInfo(); + doReturn(SUB_ID).when(mSubscriptionInfo).getSubscriptionId(); + + // Set-up specs for SliceMetadata. + SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); + + mMobileDataSlice = spy(new MobileDataSlice(mContext)); + } + + @Test + public void getSlice_shouldHaveTitleAndToggle() { + final Slice mobileData = mMobileDataSlice.getSlice(); + + final SliceMetadata metadata = SliceMetadata.from(mContext, mobileData); + assertThat(metadata.getTitle()) + .isEqualTo(mContext.getString(R.string.mobile_data_settings_title)); + + final List toggles = metadata.getToggles(); + assertThat(toggles).hasSize(1); + + final SliceAction primaryAction = metadata.getPrimaryAction(); + final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext, + R.drawable.ic_network_cell); + assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString()); + } + + @Test + public void handleUriChange_turnedOn_updatesMobileData() { + doReturn(false).when(mMobileDataSlice).isAirplaneModeEnabled(); + doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID); + final Intent intent = mMobileDataSlice.getIntent(); + intent.putExtra(android.app.slice.Slice.EXTRA_TOGGLE_STATE, true); + + mMobileDataSlice.onNotifyChange(intent); + + verify(mTelephonyManager).setDataEnabled(true); + } + + @Test + public void handleUriChange_turnedOff_updatesMobileData() { + doReturn(false).when(mMobileDataSlice).isAirplaneModeEnabled(); + doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID); + final Intent intent = mMobileDataSlice.getIntent(); + intent.putExtra(android.app.slice.Slice.EXTRA_TOGGLE_STATE, false); + + mMobileDataSlice.onNotifyChange(intent); + + verify(mTelephonyManager).setDataEnabled(false); + } + + @Test + public void handleUriChange_turnedOff_airplaneModeOn_mobileDataDoesNotUpdate() { + doReturn(true).when(mMobileDataSlice).isAirplaneModeEnabled(); + doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID); + final Intent intent = mMobileDataSlice.getIntent(); + intent.putExtra(android.app.slice.Slice.EXTRA_TOGGLE_STATE, false); + + mMobileDataSlice.onNotifyChange(intent); + + verify(mTelephonyManager, times(0)).setDataEnabled(true); + } + + @Test + public void isAirplaneModeEnabled_correctlyReturnsTrue() { + Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1); + + final boolean isAirplaneModeEnabled = mMobileDataSlice.isAirplaneModeEnabled(); + + assertThat(isAirplaneModeEnabled).isTrue(); + } + + @Test + public void isAirplaneModeEnabled_correctlyReturnsFalse() { + Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0); + + final boolean isAirplaneModeEnabled = mMobileDataSlice.isAirplaneModeEnabled(); + + assertThat(isAirplaneModeEnabled).isFalse(); + } + + @Test + public void isMobileDataEnabled_mobileDataEnabled() { + final boolean seed = true; + doReturn(seed).when(mTelephonyManager).isDataEnabled(); + + final boolean isMobileDataEnabled = mMobileDataSlice.isMobileDataEnabled(); + + assertThat(isMobileDataEnabled).isEqualTo(seed); + } +} diff --git a/tests/robotests/src/com/android/settings/panel/InternetConnectivityPanelTest.java b/tests/robotests/src/com/android/settings/panel/InternetConnectivityPanelTest.java index 3a4cf7b0ba6..42867fb6ca4 100644 --- a/tests/robotests/src/com/android/settings/panel/InternetConnectivityPanelTest.java +++ b/tests/robotests/src/com/android/settings/panel/InternetConnectivityPanelTest.java @@ -46,8 +46,10 @@ public class InternetConnectivityPanelTest { public void getSlices_containsNecessarySlices() { final List uris = mPanel.getSlices(); - assertThat(uris).containsExactly(CustomSliceRegistry.WIFI_SLICE_URI, - CustomSliceRegistry.AIRPLANE_URI); + assertThat(uris).containsExactly( + CustomSliceRegistry.AIRPLANE_URI, + CustomSliceRegistry.MOBILE_DATA_SLICE_URI, + CustomSliceRegistry.WIFI_SLICE_URI); } @Test diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java index 7eae3e4ad1a..efdcc264ec0 100644 --- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java @@ -116,7 +116,8 @@ public class SettingsSliceProviderTest { private static final List SPECIAL_CASE_OEM_URIS = Arrays.asList( CustomSliceRegistry.ZEN_MODE_SLICE_URI, - CustomSliceRegistry.FLASHLIGHT_SLICE_URI + CustomSliceRegistry.FLASHLIGHT_SLICE_URI, + CustomSliceRegistry.MOBILE_DATA_SLICE_URI ); @Before