diff --git a/res/values/strings.xml b/res/values/strings.xml index 92a90cea302..fd49d15aa8c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -13315,6 +13315,12 @@ No other networks available No networks available + + Turn off mobile data? + + You won\’t have access to data or the internet through %s. Internet will only be available via Wi\u2011Fi. + + your carrier Unavailable because bedtime mode is on diff --git a/src/com/android/settings/network/ProviderModelSlice.java b/src/com/android/settings/network/ProviderModelSlice.java index 0ae270c64b8..aafe715c4a5 100644 --- a/src/com/android/settings/network/ProviderModelSlice.java +++ b/src/com/android/settings/network/ProviderModelSlice.java @@ -22,16 +22,20 @@ import static android.app.slice.Slice.EXTRA_TOGGLE_STATE; import static com.android.settings.slices.CustomSliceRegistry.PROVIDER_MODEL_SLICE_URI; import android.annotation.ColorInt; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; import android.app.PendingIntent; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.telephony.SubscriptionManager; import android.util.Log; +import android.view.WindowManager.LayoutParams; import androidx.annotation.VisibleForTesting; import androidx.core.graphics.drawable.IconCompat; @@ -64,12 +68,16 @@ import java.util.stream.Collectors; public class ProviderModelSlice extends WifiSlice { private static final String TAG = "ProviderModelSlice"; + protected static final String PREF_NAME = "ProviderModelSlice"; + protected static final String PREF_HAS_TURNED_OFF_MOBILE_DATA = "PrefHasTurnedOffMobileData"; private final ProviderModelSliceHelper mHelper; + private final SharedPreferences mSharedPref; public ProviderModelSlice(Context context) { super(context); mHelper = getHelper(); + mSharedPref = getSharedPreference(); } @Override @@ -194,10 +202,21 @@ public class ProviderModelSlice extends WifiSlice { boolean isToggleAction = intent.hasExtra(EXTRA_TOGGLE_STATE); boolean newState = intent.getBooleanExtra(EXTRA_TOGGLE_STATE, mHelper.isMobileDataEnabled()); + if (isToggleAction) { // The ToggleAction is used to set mobile data enabled. - MobileNetworkUtils.setMobileDataEnabled(mContext, defaultSubId, newState, - false /* disableOtherSubscriptions */); + if (!newState && mSharedPref != null + && mSharedPref.getBoolean(PREF_HAS_TURNED_OFF_MOBILE_DATA, true)) { + String carrierName = mHelper.getMobileTitle(); + if (carrierName.equals(mContext.getString(R.string.mobile_data_settings_title))) { + carrierName = mContext.getString( + R.string.mobile_data_disable_message_default_carrier); + } + showMobileDataDisableDialog(getMobileDataDisableDialog(defaultSubId, carrierName)); + } else { + MobileNetworkUtils.setMobileDataEnabled(mContext, defaultSubId, newState, + false /* disableOtherSubscriptions */); + } } final boolean isDataEnabled = @@ -205,6 +224,38 @@ public class ProviderModelSlice extends WifiSlice { doCarrierNetworkAction(isToggleAction, isDataEnabled, defaultSubId); } + @VisibleForTesting + AlertDialog getMobileDataDisableDialog(int defaultSubId, String carrierName) { + return new Builder(mContext) + .setTitle(R.string.mobile_data_disable_title) + .setMessage(mContext.getString(R.string.mobile_data_disable_message, + carrierName)) + .setNegativeButton(android.R.string.cancel, null) + .setPositiveButton( + com.android.internal.R.string.alert_windows_notification_turn_off_action, + (dialog, which) -> { + MobileNetworkUtils.setMobileDataEnabled(mContext, defaultSubId, + false /* enabled */, + false /* disableOtherSubscriptions */); + if (mSharedPref != null) { + SharedPreferences.Editor editor = mSharedPref.edit(); + editor.putBoolean(PREF_HAS_TURNED_OFF_MOBILE_DATA, false); + editor.apply(); + } + }) + .create(); + } + + private void showMobileDataDisableDialog(AlertDialog dialog) { + if (dialog == null) { + log("AlertDialog is null"); + return; + } + + dialog.getWindow().setType(LayoutParams.TYPE_KEYGUARD_DIALOG); + dialog.show(); + } + @VisibleForTesting void doCarrierNetworkAction(boolean isToggleAction, boolean isDataEnabled, int subId) { final NetworkProviderWorker worker = getWorker(); @@ -247,6 +298,11 @@ public class ProviderModelSlice extends WifiSlice { return SliceBackgroundWorker.getInstance(getUri()); } + @VisibleForTesting + SharedPreferences getSharedPreference() { + return mContext.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); + } + private @InternetUpdater.InternetType int getInternetType() { final NetworkProviderWorker worker = getWorker(); if (worker == null) { diff --git a/src/com/android/settings/network/ProviderModelSliceHelper.java b/src/com/android/settings/network/ProviderModelSliceHelper.java index 28f857464ae..16d5c924552 100644 --- a/src/com/android/settings/network/ProviderModelSliceHelper.java +++ b/src/com/android/settings/network/ProviderModelSliceHelper.java @@ -264,7 +264,7 @@ public class ProviderModelSliceHelper { return summary; } - private String getMobileTitle() { + protected String getMobileTitle() { String title = mContext.getText(R.string.mobile_data_settings_title).toString(); if (mSubscriptionManager == null) { return title; diff --git a/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java b/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java index 4e9ed762fb8..722e305197d 100644 --- a/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java +++ b/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java @@ -16,6 +16,10 @@ package com.android.settings.network; +import static android.app.slice.Slice.EXTRA_TOGGLE_STATE; + +import static com.android.settings.network.ProviderModelSlice.PREF_HAS_TURNED_OFF_MOBILE_DATA; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -28,9 +32,11 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.AlertDialog; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.net.ConnectivityManager; @@ -100,6 +106,7 @@ public class ProviderModelSliceTest { WifiPickerTracker mWifiPickerTracker; @Mock WifiSliceItem mWifiSliceItem; + AlertDialog mMockAlertDialog; private FakeFeatureFactory mFeatureFactory; @@ -128,6 +135,11 @@ public class ProviderModelSliceTest { PROVIDER_MODEL_SLICE_URI)); mMockProviderModelSlice = spy(new MockProviderModelSlice( mContext, mMockNetworkProviderWorker)); + mMockAlertDialog = new AlertDialog.Builder(mContext) + .setTitle("") + .create(); + mMockAlertDialog = spy(mMockAlertDialog); + mMockProviderModelSlice.setMobileDataDisableDialog(mMockAlertDialog); mListBuilder = spy(new ListBuilder(mContext, PROVIDER_MODEL_SLICE_URI, ListBuilder.INFINITY).setAccentColor(-1)); when(mProviderModelSliceHelper.createListBuilder(PROVIDER_MODEL_SLICE_URI)).thenReturn( @@ -350,6 +362,7 @@ public class ProviderModelSliceTest { private MockNetworkProviderWorker mNetworkProviderWorker; private boolean mHasCreateEthernetRow; private boolean mHasSeeAllRow; + private AlertDialog mAlertDialog; MockProviderModelSlice(Context context, MockNetworkProviderWorker networkProviderWorker) { super(context); @@ -366,6 +379,11 @@ public class ProviderModelSliceTest { return mNetworkProviderWorker; } + @Override + AlertDialog getMobileDataDisableDialog(int defaultSubId, String carrierName) { + return mAlertDialog; + } + @Override ListBuilder.RowBuilder createEthernetRow() { mHasCreateEthernetRow = true; @@ -385,6 +403,64 @@ public class ProviderModelSliceTest { public boolean hasSeeAllRow() { return mHasSeeAllRow; } + + public void setMobileDataDisableDialog(AlertDialog alertDialog) { + mAlertDialog = alertDialog; + } + } + + @Test + @UiThreadTest + public void onNotifyChange_FirstTimeDisableToggleState_showDialog() { + final Intent intent = new Intent(); + intent.putExtra(EXTRA_TOGGLE_STATE, false); + SharedPreferences sharedPref = mMockProviderModelSlice.getSharedPreference(); + when(mProviderModelSliceHelper.getMobileTitle()).thenReturn("mockRow"); + if (sharedPref != null) { + SharedPreferences.Editor editor = sharedPref.edit(); + editor.putBoolean(PREF_HAS_TURNED_OFF_MOBILE_DATA, true); + editor.apply(); + } + + mMockProviderModelSlice.onNotifyChange(intent); + + verify(mMockAlertDialog).show(); + } + + @Test + @UiThreadTest + public void onNotifyChange_EnableToggleState_doNotShowDialog() { + final Intent intent = new Intent(); + intent.putExtra(EXTRA_TOGGLE_STATE, true); + SharedPreferences sharedPref = mMockProviderModelSlice.getSharedPreference(); + when(mProviderModelSliceHelper.getMobileTitle()).thenReturn("mockRow"); + if (sharedPref != null) { + SharedPreferences.Editor editor = sharedPref.edit(); + editor.putBoolean(PREF_HAS_TURNED_OFF_MOBILE_DATA, true); + editor.apply(); + } + + mMockProviderModelSlice.onNotifyChange(intent); + + verify(mMockAlertDialog, never()).show(); + } + + @Test + @UiThreadTest + public void onNotifyChange_notFirstTimeDisableToggleState_doNotShowDialog() { + final Intent intent = new Intent(); + intent.putExtra(EXTRA_TOGGLE_STATE, false); + SharedPreferences sharedPref = mMockProviderModelSlice.getSharedPreference(); + when(mProviderModelSliceHelper.getMobileTitle()).thenReturn("mockRow"); + if (sharedPref != null) { + SharedPreferences.Editor editor = sharedPref.edit(); + editor.putBoolean(PREF_HAS_TURNED_OFF_MOBILE_DATA, false); + editor.apply(); + } + + mMockProviderModelSlice.onNotifyChange(intent); + + verify(mMockAlertDialog, never()).show(); } @Test