diff --git a/res/values/strings.xml b/res/values/strings.xml
index bbc1f70d7e5..154218a47da 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9498,6 +9498,19 @@
Managed by %1$s
+
+ Disable Mode
+
+ If you disable this feature, the mode will no longer work as intended and its settings will be hidden.
+
+ Disable
+
+ Enable Mode
+
+ If you enable this feature, the mode will activate automatically according to its schedule.
+
+ Enable
+
Warning
diff --git a/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceController.java
index 1f979022670..24df931a43b 100644
--- a/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceController.java
@@ -25,6 +25,7 @@ import static android.service.notification.ZenModeConfig.tryParseScheduleConditi
import static com.google.common.base.Preconditions.checkNotNull;
import android.annotation.SuppressLint;
+import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -231,12 +232,40 @@ class ZenModeSetTriggerLinkPreferenceController extends AbstractZenModePreferenc
});
private final Preference.OnPreferenceChangeListener mSwitchChangeListener = (p, newValue) -> {
- final boolean newEnabled = (Boolean) newValue;
- return saveMode((zenMode) -> {
- if (newEnabled != zenMode.getRule().isEnabled()) {
- zenMode.getRule().setEnabled(newEnabled);
+ confirmChangeEnabled(p, (boolean) newValue);
+ return true;
+ };
+
+ private void confirmChangeEnabled(Preference preference, boolean enabled) {
+ @StringRes int title = enabled ? R.string.zen_mode_confirm_enable_title
+ : R.string.zen_mode_confirm_disable_title;
+ @StringRes int message = enabled ? R.string.zen_mode_confirm_enable_message
+ : R.string.zen_mode_confirm_disable_message;
+ @StringRes int confirmButton = enabled ? R.string.zen_mode_action_enable
+ : R.string.zen_mode_action_disable;
+
+ new AlertDialog.Builder(mContext)
+ .setTitle(title)
+ .setMessage(message)
+ .setPositiveButton(confirmButton,
+ (dialog, which) -> setModeEnabled(enabled))
+ .setNegativeButton(R.string.cancel,
+ (dialog, which) -> undoToggleSwitch(preference, enabled))
+ .setOnCancelListener(dialog -> undoToggleSwitch(preference, enabled))
+ .show();
+ }
+
+ private void setModeEnabled(boolean enabled) {
+ saveMode((zenMode) -> {
+ if (enabled != zenMode.getRule().isEnabled()) {
+ zenMode.getRule().setEnabled(enabled);
}
return zenMode;
});
- };
+ }
+
+ private void undoToggleSwitch(Preference preference, boolean wasSwitchedTo) {
+ PrimarySwitchPreference switchPreference = (PrimarySwitchPreference) preference;
+ switchPreference.setChecked(!wasSwitchedTo);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceControllerTest.java
index 61ca4d84662..93db4bea617 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceControllerTest.java
@@ -32,9 +32,12 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
+import android.app.AlertDialog;
import android.app.AutomaticZenRule;
import android.app.Flags;
import android.content.Context;
@@ -42,6 +45,7 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
+import android.os.Looper;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.service.notification.SystemZenRules;
@@ -74,6 +78,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.shadows.ShadowAlertDialog;
import java.util.Calendar;
@@ -161,19 +166,86 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
}
@Test
- public void onPreferenceChange_updatesMode() {
+ public void onPreferenceChange_toggleOn_enablesModeAfterConfirmation() {
+ // Start with a disabled mode
ZenMode zenMode = new TestModeBuilder().setEnabled(false).build();
-
- // start with disabled rule
mController.updateZenMode(mPrefCategory, zenMode);
- // then flip the switch
+ // Flip the switch
mConfigPreference.callChangeListener(true);
+ verify(mBackend, never()).updateMode(any());
- // verify the backend got asked to update the mode to be enabled
+ // Oh wait, I forgot to confirm! Let's do that
+ assertThat(ShadowAlertDialog.getLatestAlertDialog()).isNotNull();
+ assertThat(ShadowAlertDialog.getLatestAlertDialog().isShowing()).isTrue();
+ ShadowAlertDialog.getLatestAlertDialog()
+ .getButton(AlertDialog.BUTTON_POSITIVE).performClick();
+ shadowOf(Looper.getMainLooper()).idle();
+
+ // Verify the backend got asked to update the mode to be enabled
ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class);
verify(mBackend).updateMode(captor.capture());
assertThat(captor.getValue().getRule().isEnabled()).isTrue();
+ assertThat(ShadowAlertDialog.getLatestAlertDialog().isShowing()).isFalse();
+ }
+
+ @Test
+ public void onPreferenceChange_toggleOff_disablesModeAfterConfirmation() {
+ // Start with an enabled mode
+ ZenMode zenMode = new TestModeBuilder().setEnabled(true).build();
+ mController.updateZenMode(mPrefCategory, zenMode);
+
+ // Flip the switch
+ mConfigPreference.callChangeListener(false);
+ verify(mBackend, never()).updateMode(any());
+
+ // Oh wait, I forgot to confirm! Let's do that
+ assertThat(ShadowAlertDialog.getLatestAlertDialog()).isNotNull();
+ assertThat(ShadowAlertDialog.getLatestAlertDialog().isShowing()).isTrue();
+ ShadowAlertDialog.getLatestAlertDialog()
+ .getButton(AlertDialog.BUTTON_POSITIVE).performClick();
+ shadowOf(Looper.getMainLooper()).idle();
+
+ // Verify the backend got asked to update the mode to be disabled
+ ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class);
+ verify(mBackend).updateMode(captor.capture());
+ assertThat(captor.getValue().getRule().isEnabled()).isFalse();
+ assertThat(ShadowAlertDialog.getLatestAlertDialog().isShowing()).isFalse();
+ }
+
+ @Test
+ public void onPreferenceChange_ifPressCancelButton_doesNotUpdateMode() {
+ // Start with a disabled mode
+ ZenMode zenMode = new TestModeBuilder().setEnabled(false).build();
+ mController.updateZenMode(mPrefCategory, zenMode);
+
+ // Flip the switch, then have second thoughts about it
+ mConfigPreference.callChangeListener(true);
+ ShadowAlertDialog.getLatestAlertDialog()
+ .getButton(AlertDialog.BUTTON_NEGATIVE).performClick();
+ shadowOf(Looper.getMainLooper()).idle();
+
+ // Verify nothing changed, and the switch shows the correct (pre-change) value.
+ verify(mBackend, never()).updateMode(any());
+ assertThat(mConfigPreference.isChecked()).isFalse();
+ assertThat(ShadowAlertDialog.getLatestAlertDialog().isShowing()).isFalse();
+ }
+
+ @Test
+ public void onPreferenceChange_ifExitingDialog_doesNotUpdateMode() {
+ // Start with a disabled mode
+ ZenMode zenMode = new TestModeBuilder().setEnabled(false).build();
+ mController.updateZenMode(mPrefCategory, zenMode);
+
+ // Flip the switch, but close the dialog without selecting either button.
+ mConfigPreference.callChangeListener(true);
+ ShadowAlertDialog.getLatestAlertDialog().dismiss();
+ shadowOf(Looper.getMainLooper()).idle();
+
+ // Verify nothing changed, and the switch shows the correct (pre-change) value.
+ verify(mBackend, never()).updateMode(any());
+ assertThat(mConfigPreference.isChecked()).isFalse();
+ assertThat(ShadowAlertDialog.getLatestAlertDialog().isShowing()).isFalse();
}
@Test