diff --git a/res/xml/modes_rule_settings.xml b/res/xml/modes_rule_settings.xml
index 7551905f7bc..d2f573c56cf 100644
--- a/res/xml/modes_rule_settings.xml
+++ b/res/xml/modes_rule_settings.xml
@@ -51,8 +51,7 @@
+ android:icon="@drawable/ic_add_24dp" />
{
+ ZenModeScheduleChooserDialog.show(mFragment, mOnScheduleOptionListener);
+ return true;
+ });
+ }
+
+ @VisibleForTesting
+ final ZenModeScheduleChooserDialog.OnScheduleOptionListener mOnScheduleOptionListener =
+ conditionId -> saveMode(mode -> {
+ mode.setCustomModeConditionId(mContext, conditionId);
+ return mode;
+ // TODO: b/342156843 - Maybe jump to the corresponding schedule editing screen?
+ });
+}
diff --git a/src/com/android/settings/notification/modes/ZenModeTriggerCategoryPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeTriggerCategoryPreferenceController.java
new file mode 100644
index 00000000000..5fc3fda80ca
--- /dev/null
+++ b/src/com/android/settings/notification/modes/ZenModeTriggerCategoryPreferenceController.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 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.notification.modes;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.preference.Preference;
+
+import com.android.settingslib.notification.modes.ZenMode;
+
+/**
+ * Preference controller for the "Turn on automatically" category
+ */
+class ZenModeTriggerCategoryPreferenceController extends AbstractZenModePreferenceController {
+
+ ZenModeTriggerCategoryPreferenceController(Context context, String key) {
+ super(context, key);
+ }
+
+ @Override
+ public boolean isAvailable(@NonNull ZenMode zenMode) {
+ return !zenMode.isManualDnd();
+ }
+
+ @Override
+ public void updateState(Preference preference, @NonNull ZenMode zenMode) {
+ // Nothing to update here (except visibility via isAvailable()).
+ }
+}
diff --git a/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceController.java
similarity index 74%
rename from src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceController.java
rename to src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceController.java
index 24df931a43b..043a38c1cf8 100644
--- a/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceController.java
@@ -22,8 +22,6 @@ import static android.app.AutomaticZenRule.TYPE_SCHEDULE_CALENDAR;
import static android.app.AutomaticZenRule.TYPE_SCHEDULE_TIME;
import static android.service.notification.ZenModeConfig.tryParseScheduleConditionId;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
@@ -39,46 +37,36 @@ import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
-import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.PrimarySwitchPreference;
import com.android.settingslib.notification.modes.ZenMode;
import com.android.settingslib.notification.modes.ZenModesBackend;
import com.google.common.base.Strings;
-/**
- * Preference controller for the link to an individual mode's configuration page.
- */
-class ZenModeSetTriggerLinkPreferenceController extends AbstractZenModePreferenceController {
- private static final String TAG = "ZenModeSetTriggerLink";
+class ZenModeTriggerUpdatePreferenceController extends AbstractZenModePreferenceController {
- @VisibleForTesting
- static final String AUTOMATIC_TRIGGER_KEY = "zen_automatic_trigger_settings";
- static final String ADD_TRIGGER_KEY = "zen_add_automatic_trigger";
+ private static final String TAG = "ZenModeTriggerUpdate";
- private final DashboardFragment mFragment;
private final PackageManager mPackageManager;
private final ConfigurationActivityHelper mConfigurationActivityHelper;
private final ZenServiceListing mServiceListing;
- ZenModeSetTriggerLinkPreferenceController(Context context, String key,
- DashboardFragment fragment, ZenModesBackend backend) {
- this(context, key, fragment, backend, context.getPackageManager(),
+ ZenModeTriggerUpdatePreferenceController(Context context, String key,
+ ZenModesBackend backend) {
+ this(context, key, backend, context.getPackageManager(),
new ConfigurationActivityHelper(context.getPackageManager()),
new ZenServiceListing(context));
}
@VisibleForTesting
- ZenModeSetTriggerLinkPreferenceController(Context context, String key,
- DashboardFragment fragment, ZenModesBackend backend, PackageManager packageManager,
+ ZenModeTriggerUpdatePreferenceController(Context context, String key,
+ ZenModesBackend backend, PackageManager packageManager,
ConfigurationActivityHelper configurationActivityHelper,
ZenServiceListing serviceListing) {
super(context, key, backend);
- mFragment = fragment;
mPackageManager = packageManager;
mConfigurationActivityHelper = configurationActivityHelper;
mServiceListing = serviceListing;
@@ -86,7 +74,7 @@ class ZenModeSetTriggerLinkPreferenceController extends AbstractZenModePreferenc
@Override
public boolean isAvailable(@NonNull ZenMode zenMode) {
- return !zenMode.isManualDnd();
+ return !zenMode.isCustomManual() && !zenMode.isManualDnd();
}
@Override
@@ -97,39 +85,18 @@ class ZenModeSetTriggerLinkPreferenceController extends AbstractZenModePreferenc
}
@Override
- public void updateState(Preference preference, @NonNull ZenMode zenMode) {
- // This controller is expected to govern a preference category so that it controls the
- // availability of the entire preference category if the mode doesn't have a way to
- // automatically trigger (such as manual DND).
- if (zenMode.isManualDnd()) {
+ void updateState(Preference preference, @NonNull ZenMode zenMode) {
+ if (!isAvailable(zenMode)) {
return;
}
- PrimarySwitchPreference triggerPref = checkNotNull(
- ((PreferenceCategory) preference).findPreference(AUTOMATIC_TRIGGER_KEY));
- Preference addTriggerPref = checkNotNull(
- ((PreferenceCategory) preference).findPreference(ADD_TRIGGER_KEY));
- boolean isAddTrigger = zenMode.isSystemOwned() && zenMode.getType() != TYPE_SCHEDULE_TIME
- && zenMode.getType() != TYPE_SCHEDULE_CALENDAR;
-
- if (isAddTrigger) {
- triggerPref.setVisible(false);
- addTriggerPref.setVisible(true);
- addTriggerPref.setOnPreferenceClickListener(unused -> {
- ZenModeScheduleChooserDialog.show(mFragment, mOnScheduleOptionListener);
- return true;
- });
+ PrimarySwitchPreference triggerPref = (PrimarySwitchPreference) preference;
+ triggerPref.setChecked(zenMode.getRule().isEnabled());
+ triggerPref.setOnPreferenceChangeListener(mSwitchChangeListener);
+ if (zenMode.isSystemOwned()) {
+ setUpForSystemOwnedTrigger(triggerPref, zenMode);
} else {
- addTriggerPref.setVisible(false);
- triggerPref.setVisible(true);
- triggerPref.setChecked(zenMode.getRule().isEnabled());
- triggerPref.setOnPreferenceChangeListener(mSwitchChangeListener);
-
- if (zenMode.isSystemOwned()) {
- setUpForSystemOwnedTrigger(triggerPref, zenMode);
- } else {
- setUpForAppTrigger(triggerPref, zenMode);
- }
+ setUpForAppTrigger(triggerPref, zenMode);
}
}
@@ -223,14 +190,6 @@ class ZenModeSetTriggerLinkPreferenceController extends AbstractZenModePreferenc
preference.setIntent(configurationIntent);
}
- @VisibleForTesting
- final ZenModeScheduleChooserDialog.OnScheduleOptionListener mOnScheduleOptionListener =
- conditionId -> saveMode(mode -> {
- mode.setCustomModeConditionId(mContext, conditionId);
- return mode;
- // TODO: b/342156843 - Maybe jump to the corresponding schedule editing screen?
- });
-
private final Preference.OnPreferenceChangeListener mSwitchChangeListener = (p, newValue) -> {
confirmChangeEnabled(p, (boolean) newValue);
return true;
diff --git a/tests/robotests/src/com/android/settings/notification/modes/CharSequenceTruth.java b/tests/robotests/src/com/android/settings/notification/modes/CharSequenceTruth.java
new file mode 100644
index 00000000000..94b932fc2dd
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/modes/CharSequenceTruth.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 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.notification.modes;
+
+import androidx.annotation.Nullable;
+
+import com.google.common.truth.StringSubject;
+import com.google.common.truth.Truth;
+
+class CharSequenceTruth {
+ /**
+ * Shortcut version of {@link Truth#assertThat(String)} suitable for {@link CharSequence}.
+ * {@link CharSequence} doesn't necessarily provide a good {@code equals()} implementation;
+ * however we don't care about formatting in most cases, and we want to assert on the resulting
+ * string (without needing to worry that {@code assertThat(x.getText().toString())} can
+ * throw if the text is null).
+ */
+ static StringSubject assertThat(@Nullable CharSequence actual) {
+ return Truth.assertThat((String) (actual != null ? actual.toString() : null));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeTriggerAddPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeTriggerAddPreferenceControllerTest.java
new file mode 100644
index 00000000000..a56e7230bde
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeTriggerAddPreferenceControllerTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2024 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.notification.modes;
+
+import static android.app.AutomaticZenRule.TYPE_OTHER;
+import static android.app.AutomaticZenRule.TYPE_SCHEDULE_CALENDAR;
+import static android.app.AutomaticZenRule.TYPE_SCHEDULE_TIME;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
+import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
+
+import static com.android.settings.notification.modes.CharSequenceTruth.assertThat;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+
+import android.app.AutomaticZenRule;
+import android.app.Flags;
+import android.content.Context;
+import android.net.Uri;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.service.notification.SystemZenRules;
+import android.service.notification.ZenModeConfig;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settingslib.notification.modes.TestModeBuilder;
+import com.android.settingslib.notification.modes.ZenMode;
+import com.android.settingslib.notification.modes.ZenModesBackend;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.Calendar;
+
+@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
+public class ZenModeTriggerAddPreferenceControllerTest {
+
+ private static final ZenMode CUSTOM_MANUAL_MODE = new TestModeBuilder()
+ .setConditionId(ZenModeConfig.toCustomManualConditionId())
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
+ .setType(TYPE_OTHER)
+ .setTriggerDescription("Will not be shown")
+ .build();
+
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
+
+ private ZenModeTriggerAddPreferenceController mController;
+
+ private Context mContext;
+ private Preference mPreference;
+ @Mock private ZenModesBackend mBackend;
+ @Mock private DashboardFragment mFragment;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mContext = ApplicationProvider.getApplicationContext();
+
+ PreferenceManager preferenceManager = new PreferenceManager(mContext);
+ PreferenceScreen preferenceScreen = preferenceManager.inflateFromResource(mContext,
+ R.xml.modes_rule_settings, null);
+
+ mController = new ZenModeTriggerAddPreferenceController(mContext,
+ "zen_add_automatic_trigger", mFragment, mBackend);
+ mPreference = preferenceScreen.findPreference("zen_add_automatic_trigger");
+ }
+
+ @Test
+ public void isAvailable_customManualMode_true() {
+ mController.setZenMode(CUSTOM_MANUAL_MODE);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_systemMode_false() {
+ ZenMode mode = new TestModeBuilder()
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
+ .setType(TYPE_SCHEDULE_CALENDAR)
+ .build();
+ mController.setZenMode(mode);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_appProvidedMode_false() {
+ ZenMode mode = new TestModeBuilder()
+ .setPackage("com.some.package")
+ .setType(TYPE_OTHER)
+ .build();
+ mController.setZenMode(mode);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_manualDND_false() {
+ ZenMode manualMode = ZenMode.manualDndMode(new AutomaticZenRule.Builder("Do Not Disturb",
+ Uri.parse("manual"))
+ .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+ .build(), /* isActive= */ false);
+
+ mController.setZenMode(manualMode);
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void updateState_customManualRule() {
+ ZenMode mode = new TestModeBuilder()
+ .setConditionId(ZenModeConfig.toCustomManualConditionId())
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
+ .setType(TYPE_OTHER)
+ .setTriggerDescription("Will not be shown")
+ .build();
+
+ mController.updateState(mPreference, mode);
+
+ assertThat(mPreference.getTitle()).isEqualTo(
+ mContext.getString(R.string.zen_mode_select_schedule));
+ assertThat(mPreference.getSummary()).isNull();
+ // Sets up a click listener to open the dialog.
+ assertThat(mPreference.getOnPreferenceClickListener()).isNotNull();
+ }
+
+ @Test
+ public void onScheduleChosen_updatesMode() {
+ ZenMode originalMode = new TestModeBuilder()
+ .setConditionId(ZenModeConfig.toCustomManualConditionId())
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
+ .setType(TYPE_OTHER)
+ .setTriggerDescription("")
+ .build();
+ mController.updateZenMode(mPreference, originalMode);
+
+ ZenModeConfig.ScheduleInfo scheduleInfo = new ZenModeConfig.ScheduleInfo();
+ scheduleInfo.days = new int[] { Calendar.MONDAY };
+ scheduleInfo.startHour = 12;
+ scheduleInfo.endHour = 15;
+ Uri scheduleUri = ZenModeConfig.toScheduleConditionId(scheduleInfo);
+
+ mController.mOnScheduleOptionListener.onScheduleSelected(scheduleUri);
+
+ // verify the backend got asked to update the mode to be schedule-based.
+ ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class);
+ verify(mBackend).updateMode(captor.capture());
+ ZenMode updatedMode = captor.getValue();
+ assertThat(updatedMode.getType()).isEqualTo(TYPE_SCHEDULE_TIME);
+ assertThat(updatedMode.getRule().getConditionId()).isEqualTo(scheduleUri);
+ assertThat(updatedMode.getRule().getTriggerDescription()).isNotEmpty();
+ assertThat(updatedMode.getRule().getOwner()).isEqualTo(
+ ZenModeConfig.getScheduleConditionProvider());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeTriggerCategoryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeTriggerCategoryPreferenceControllerTest.java
new file mode 100644
index 00000000000..4510e2048f5
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeTriggerCategoryPreferenceControllerTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2024 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.notification.modes;
+
+import static android.app.AutomaticZenRule.TYPE_OTHER;
+import static android.app.AutomaticZenRule.TYPE_SCHEDULE_CALENDAR;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
+import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.AutomaticZenRule;
+import android.app.Flags;
+import android.content.Context;
+import android.net.Uri;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.service.notification.SystemZenRules;
+import android.service.notification.ZenModeConfig;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settingslib.notification.modes.TestModeBuilder;
+import com.android.settingslib.notification.modes.ZenMode;
+import com.android.settingslib.notification.modes.ZenModesBackend;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
+public class ZenModeTriggerCategoryPreferenceControllerTest {
+
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
+
+ private ZenModeTriggerCategoryPreferenceController mController;
+
+ private Context mContext;
+ private Preference mPreference;
+ @Mock private ZenModesBackend mBackend;
+ @Mock private DashboardFragment mFragment;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mContext = ApplicationProvider.getApplicationContext();
+
+ PreferenceManager preferenceManager = new PreferenceManager(mContext);
+ PreferenceScreen preferenceScreen = preferenceManager.inflateFromResource(mContext,
+ R.xml.modes_rule_settings, null);
+
+ mController = new ZenModeTriggerCategoryPreferenceController(mContext,
+ "zen_automatic_trigger_category");
+ mPreference = preferenceScreen.findPreference("zen_automatic_trigger_category");
+ }
+
+ @Test
+ public void isAvailable_customManualMode_true() {
+ ZenMode mode = new TestModeBuilder()
+ .setConditionId(ZenModeConfig.toCustomManualConditionId())
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
+ .setType(TYPE_OTHER)
+ .setTriggerDescription("Will not be shown")
+ .build();
+ mController.setZenMode(mode);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_systemMode_true() {
+ ZenMode mode = new TestModeBuilder()
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
+ .setType(TYPE_SCHEDULE_CALENDAR)
+ .build();
+ mController.setZenMode(mode);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_appProvidedMode_true() {
+ ZenMode mode = new TestModeBuilder()
+ .setPackage("com.some.package")
+ .setType(TYPE_OTHER)
+ .build();
+ mController.setZenMode(mode);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_manualDND_false() {
+ ZenMode manualMode = ZenMode.manualDndMode(new AutomaticZenRule.Builder("Do Not Disturb",
+ Uri.parse("manual"))
+ .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+ .build(), /* isActive= */ false);
+
+ mController.setZenMode(manualMode);
+ assertThat(mController.isAvailable()).isFalse();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceControllerTest.java
similarity index 60%
rename from tests/robotests/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceControllerTest.java
rename to tests/robotests/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceControllerTest.java
index 93db4bea617..a3fe57e02f5 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeTriggerUpdatePreferenceControllerTest.java
@@ -22,11 +22,8 @@ import static android.app.AutomaticZenRule.TYPE_SCHEDULE_TIME;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
-import static com.android.settings.notification.modes.ZenModeSetTriggerLinkPreferenceController.ADD_TRIGGER_KEY;
-import static com.android.settings.notification.modes.ZenModeSetTriggerLinkPreferenceController.AUTOMATIC_TRIGGER_KEY;
-import static com.android.settings.notification.modes.ZenModeSetTriggerLinkPreferenceControllerTest.CharSequenceTruth.assertThat;
+import static com.android.settings.notification.modes.CharSequenceTruth.assertThat;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -51,24 +48,17 @@ import android.platform.test.flag.junit.SetFlagsRule;
import android.service.notification.SystemZenRules;
import android.service.notification.ZenModeConfig;
-import androidx.annotation.Nullable;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
-import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.PrimarySwitchPreference;
import com.android.settingslib.notification.modes.TestModeBuilder;
import com.android.settingslib.notification.modes.ZenMode;
import com.android.settingslib.notification.modes.ZenModesBackend;
-import com.google.common.truth.StringSubject;
-import com.google.common.truth.Truth;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -84,44 +74,31 @@ import java.util.Calendar;
@RunWith(RobolectricTestRunner.class)
@EnableFlags(Flags.FLAG_MODES_UI)
-public class ZenModeSetTriggerLinkPreferenceControllerTest {
+public class ZenModeTriggerUpdatePreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
- @Mock
- private ZenModesBackend mBackend;
- private Context mContext;
+ private ZenModeTriggerUpdatePreferenceController mController;
- @Mock
- private PackageManager mPm;
- @Mock
- private ConfigurationActivityHelper mConfigurationActivityHelper;
-
- private PreferenceCategory mPrefCategory;
- private PrimarySwitchPreference mConfigPreference;
- private Preference mAddPreference;
-
- @Mock
- private DashboardFragment mFragment;
-
- private ZenModeSetTriggerLinkPreferenceController mController;
+ private PrimarySwitchPreference mPreference;
+ @Mock private ZenModesBackend mBackend;
+ @Mock private PackageManager mPm;
+ @Mock private ConfigurationActivityHelper mConfigurationActivityHelper;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mContext = ApplicationProvider.getApplicationContext();
+ Context context = ApplicationProvider.getApplicationContext();
- PreferenceManager preferenceManager = new PreferenceManager(mContext);
- PreferenceScreen preferenceScreen = preferenceManager.inflateFromResource(mContext,
+ PreferenceManager preferenceManager = new PreferenceManager(context);
+ PreferenceScreen preferenceScreen = preferenceManager.inflateFromResource(context,
R.xml.modes_rule_settings, null);
- mController = new ZenModeSetTriggerLinkPreferenceController(mContext,
- "zen_automatic_trigger_category", mFragment, mBackend, mPm,
+ mController = new ZenModeTriggerUpdatePreferenceController(context,
+ "zen_automatic_trigger_settings", mBackend, mPm,
mConfigurationActivityHelper, mock(ZenServiceListing.class));
- mPrefCategory = preferenceScreen.findPreference("zen_automatic_trigger_category");
- mConfigPreference = checkNotNull(mPrefCategory).findPreference(AUTOMATIC_TRIGGER_KEY);
- mAddPreference = checkNotNull(mPrefCategory).findPreference(ADD_TRIGGER_KEY);
+ mPreference = preferenceScreen.findPreference("zen_automatic_trigger_settings");
when(mPm.getApplicationInfo(any(), anyInt())).then(
(Answer) invocationOnMock -> {
@@ -136,19 +113,48 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
}
@Test
- public void testIsAvailable() {
- // should not be available for manual DND
+ public void isAvailable_systemModeNotCustomManual_true() {
+ ZenMode mode = new TestModeBuilder()
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
+ .setType(TYPE_SCHEDULE_CALENDAR)
+ .build();
+ mController.setZenMode(mode);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_appProvidedMode_true() {
+ ZenMode mode = new TestModeBuilder()
+ .setPackage("com.some.package")
+ .setType(TYPE_OTHER)
+ .build();
+ mController.setZenMode(mode);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_customManualMode_false() {
+ ZenMode mode = new TestModeBuilder()
+ .setConditionId(ZenModeConfig.toCustomManualConditionId())
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
+ .setType(TYPE_OTHER)
+ .build();
+ mController.setZenMode(mode);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_manualDND_false() {
ZenMode manualMode = ZenMode.manualDndMode(new AutomaticZenRule.Builder("Do Not Disturb",
Uri.parse("manual"))
.setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
- .build(), true);
+ .build(), /* isActive= */ false);
- mController.updateZenMode(mPrefCategory, manualMode);
+ mController.setZenMode(manualMode);
assertThat(mController.isAvailable()).isFalse();
-
- // should be available for other modes
- mController.updateZenMode(mPrefCategory, TestModeBuilder.EXAMPLE);
- assertThat(mController.isAvailable()).isTrue();
}
@Test
@@ -156,23 +162,23 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
ZenMode zenMode = new TestModeBuilder().setEnabled(false).build();
// Update preference controller with a zen mode that is not enabled
- mController.updateZenMode(mPrefCategory, zenMode);
- assertThat(mConfigPreference.getCheckedState()).isFalse();
+ mController.updateZenMode(mPreference, zenMode);
+ assertThat(mPreference.getCheckedState()).isFalse();
// Now with the rule enabled
zenMode.getRule().setEnabled(true);
- mController.updateZenMode(mPrefCategory, zenMode);
- assertThat(mConfigPreference.getCheckedState()).isTrue();
+ mController.updateZenMode(mPreference, zenMode);
+ assertThat(mPreference.getCheckedState()).isTrue();
}
@Test
public void onPreferenceChange_toggleOn_enablesModeAfterConfirmation() {
// Start with a disabled mode
ZenMode zenMode = new TestModeBuilder().setEnabled(false).build();
- mController.updateZenMode(mPrefCategory, zenMode);
+ mController.updateZenMode(mPreference, zenMode);
// Flip the switch
- mConfigPreference.callChangeListener(true);
+ mPreference.callChangeListener(true);
verify(mBackend, never()).updateMode(any());
// Oh wait, I forgot to confirm! Let's do that
@@ -193,10 +199,10 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
public void onPreferenceChange_toggleOff_disablesModeAfterConfirmation() {
// Start with an enabled mode
ZenMode zenMode = new TestModeBuilder().setEnabled(true).build();
- mController.updateZenMode(mPrefCategory, zenMode);
+ mController.updateZenMode(mPreference, zenMode);
// Flip the switch
- mConfigPreference.callChangeListener(false);
+ mPreference.callChangeListener(false);
verify(mBackend, never()).updateMode(any());
// Oh wait, I forgot to confirm! Let's do that
@@ -217,17 +223,17 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
public void onPreferenceChange_ifPressCancelButton_doesNotUpdateMode() {
// Start with a disabled mode
ZenMode zenMode = new TestModeBuilder().setEnabled(false).build();
- mController.updateZenMode(mPrefCategory, zenMode);
+ mController.updateZenMode(mPreference, zenMode);
// Flip the switch, then have second thoughts about it
- mConfigPreference.callChangeListener(true);
+ mPreference.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(mPreference.isChecked()).isFalse();
assertThat(ShadowAlertDialog.getLatestAlertDialog().isShowing()).isFalse();
}
@@ -235,16 +241,16 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
public void onPreferenceChange_ifExitingDialog_doesNotUpdateMode() {
// Start with a disabled mode
ZenMode zenMode = new TestModeBuilder().setEnabled(false).build();
- mController.updateZenMode(mPrefCategory, zenMode);
+ mController.updateZenMode(mPreference, zenMode);
// Flip the switch, but close the dialog without selecting either button.
- mConfigPreference.callChangeListener(true);
+ mPreference.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(mPreference.isChecked()).isFalse();
assertThat(ShadowAlertDialog.getLatestAlertDialog().isShowing()).isFalse();
}
@@ -260,15 +266,14 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
.setTriggerDescription("My events")
.build();
- mController.updateState(mPrefCategory, mode);
+ mController.updateState(mPreference, mode);
- assertThat(mAddPreference.isVisible()).isFalse();
- assertThat(mConfigPreference.isVisible()).isTrue();
- assertThat(mConfigPreference.getTitle()).isEqualTo("Calendar events");
- assertThat(mConfigPreference.getSummary()).isEqualTo("My events");
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getTitle()).isEqualTo("Calendar events");
+ assertThat(mPreference.getSummary()).isEqualTo("My events");
// Destination as written into the intent by SubSettingLauncher
assertThat(
- mConfigPreference.getIntent().getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
+ mPreference.getIntent().getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
.isEqualTo(ZenModeSetCalendarFragment.class.getName());
}
@@ -285,38 +290,17 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
.setTriggerDescription("some schedule")
.build();
- mController.updateState(mPrefCategory, mode);
+ mController.updateState(mPreference, mode);
- assertThat(mAddPreference.isVisible()).isFalse();
- assertThat(mConfigPreference.isVisible()).isTrue();
- assertThat(mConfigPreference.getTitle()).isEqualTo("1:00 AM - 3:00 PM");
- assertThat(mConfigPreference.getSummary()).isEqualTo("Mon - Tue, Thu");
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getTitle()).isEqualTo("1:00 AM - 3:00 PM");
+ assertThat(mPreference.getSummary()).isEqualTo("Mon - Tue, Thu");
// Destination as written into the intent by SubSettingLauncher
assertThat(
- mConfigPreference.getIntent().getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
+ mPreference.getIntent().getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
.isEqualTo(ZenModeSetScheduleFragment.class.getName());
}
- @Test
- public void updateState_customManualRule() {
- ZenMode mode = new TestModeBuilder()
- .setConditionId(ZenModeConfig.toCustomManualConditionId())
- .setPackage(SystemZenRules.PACKAGE_ANDROID)
- .setType(TYPE_OTHER)
- .setTriggerDescription("Will not be shown")
- .build();
-
- mController.updateState(mPrefCategory, mode);
-
- assertThat(mConfigPreference.isVisible()).isFalse();
- assertThat(mAddPreference.isVisible()).isTrue();
- assertThat(mAddPreference.getTitle()).isEqualTo(
- mContext.getString(R.string.zen_mode_select_schedule));
- assertThat(mAddPreference.getSummary()).isNull();
- // Sets up a click listener to open the dialog.
- assertThat(mAddPreference.getOnPreferenceClickListener()).isNotNull();
- }
-
@Test
public void updateState_appWithConfigActivity_showsLinkToConfigActivity() {
ZenMode mode = new TestModeBuilder()
@@ -327,12 +311,12 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
when(mConfigurationActivityHelper.getConfigurationActivityIntentForMode(any(), any()))
.thenReturn(configurationIntent);
- mController.updateState(mPrefCategory, mode);
+ mController.updateState(mPreference, mode);
- assertThat(mConfigPreference.isVisible()).isTrue();
- assertThat(mConfigPreference.getTitle()).isEqualTo("Linked to app");
- assertThat(mConfigPreference.getSummary()).isEqualTo("When The Music's Over");
- assertThat(mConfigPreference.getIntent()).isEqualTo(configurationIntent);
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getTitle()).isEqualTo("Linked to app");
+ assertThat(mPreference.getSummary()).isEqualTo("When The Music's Over");
+ assertThat(mPreference.getIntent()).isEqualTo(configurationIntent);
}
@Test
@@ -344,12 +328,12 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
when(mConfigurationActivityHelper.getConfigurationActivityIntentForMode(any(), any()))
.thenReturn(null);
- mController.updateState(mPrefCategory, mode);
+ mController.updateState(mPreference, mode);
- assertThat(mConfigPreference.isVisible()).isTrue();
- assertThat(mConfigPreference.getTitle()).isEqualTo("Linked to app");
- assertThat(mConfigPreference.getSummary()).isEqualTo("When the saints go marching in");
- assertThat(mConfigPreference.getIntent()).isNull();
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getTitle()).isEqualTo("Linked to app");
+ assertThat(mPreference.getSummary()).isEqualTo("When the saints go marching in");
+ assertThat(mPreference.getIntent()).isNull();
}
@Test
@@ -362,11 +346,11 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
.thenReturn(configurationIntent);
when(mPm.getText(any(), anyInt(), any())).thenReturn("The App Name");
- mController.updateState(mPrefCategory, mode);
+ mController.updateState(mPreference, mode);
- assertThat(mConfigPreference.isVisible()).isTrue();
- assertThat(mConfigPreference.getTitle()).isEqualTo("Linked to app");
- assertThat(mConfigPreference.getSummary()).isEqualTo("Info and settings in The App Name");
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getTitle()).isEqualTo("Linked to app");
+ assertThat(mPreference.getSummary()).isEqualTo("Info and settings in The App Name");
}
@Test
@@ -378,52 +362,10 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
.thenReturn(null);
when(mPm.getText(any(), anyInt(), any())).thenReturn("The App Name");
- mController.updateState(mPrefCategory, mode);
+ mController.updateState(mPreference, mode);
- assertThat(mConfigPreference.isVisible()).isTrue();
- assertThat(mConfigPreference.getTitle()).isEqualTo("Linked to app");
- assertThat(mConfigPreference.getSummary()).isEqualTo("Managed by The App Name");
- }
-
- @Test
- public void onScheduleChosen_updatesMode() {
- ZenMode originalMode = new TestModeBuilder()
- .setConditionId(ZenModeConfig.toCustomManualConditionId())
- .setPackage(SystemZenRules.PACKAGE_ANDROID)
- .setType(TYPE_OTHER)
- .setTriggerDescription("")
- .build();
- mController.updateZenMode(mPrefCategory, originalMode);
-
- ZenModeConfig.ScheduleInfo scheduleInfo = new ZenModeConfig.ScheduleInfo();
- scheduleInfo.days = new int[] { Calendar.MONDAY };
- scheduleInfo.startHour = 12;
- scheduleInfo.endHour = 15;
- Uri scheduleUri = ZenModeConfig.toScheduleConditionId(scheduleInfo);
-
- mController.mOnScheduleOptionListener.onScheduleSelected(scheduleUri);
-
- // verify the backend got asked to update the mode to be schedule-based.
- ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class);
- verify(mBackend).updateMode(captor.capture());
- ZenMode updatedMode = captor.getValue();
- assertThat(updatedMode.getType()).isEqualTo(TYPE_SCHEDULE_TIME);
- assertThat(updatedMode.getRule().getConditionId()).isEqualTo(scheduleUri);
- assertThat(updatedMode.getRule().getTriggerDescription()).isNotEmpty();
- assertThat(updatedMode.getRule().getOwner()).isEqualTo(
- ZenModeConfig.getScheduleConditionProvider());
- }
-
- static class CharSequenceTruth {
- /**
- * Shortcut version of {@link Truth#assertThat(String)} suitable for {@link CharSequence}.
- * {@link CharSequence} doesn't necessarily provide a good {@code equals()} implementation;
- * however we don't care about formatting here, so we want to assert on the resulting
- * string (without needing to worry that {@code assertThat(x.getText().toString())} can
- * throw if the text is null).
- */
- static StringSubject assertThat(@Nullable CharSequence actual) {
- return Truth.assertThat((String) (actual != null ? actual.toString() : null));
- }
+ assertThat(mPreference.isVisible()).isTrue();
+ assertThat(mPreference.getTitle()).isEqualTo("Linked to app");
+ assertThat(mPreference.getSummary()).isEqualTo("Managed by The App Name");
}
}