diff --git a/res/layout/zen_mode_type_item.xml b/res/layout/zen_mode_type_item.xml
new file mode 100644
index 00000000000..841ca0066f8
--- /dev/null
+++ b/res/layout/zen_mode_type_item.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f92fd2aca84..386ece3caf4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7927,6 +7927,19 @@
Only get notified by important people and apps
+
+ Select activation type
+
+
+ Time
+
+ Ex. \"9:30 – 5:00 PM\"
+
+
+ Calendar
+
+ Ex. \"Personal calendar\"
+
Limit interruptions
diff --git a/src/com/android/settings/notification/modes/ZenMode.java b/src/com/android/settings/notification/modes/ZenMode.java
index cbe915b5bab..1040d1e0021 100644
--- a/src/com/android/settings/notification/modes/ZenMode.java
+++ b/src/com/android/settings/notification/modes/ZenMode.java
@@ -18,6 +18,12 @@ package com.android.settings.notification.modes;
import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
+import static android.service.notification.SystemZenRules.getTriggerDescriptionForScheduleEvent;
+import static android.service.notification.SystemZenRules.getTriggerDescriptionForScheduleTime;
+import static android.service.notification.ZenModeConfig.tryParseEventConditionId;
+import static android.service.notification.ZenModeConfig.tryParseScheduleConditionId;
+
+import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
@@ -26,7 +32,10 @@ import android.app.AutomaticZenRule;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.service.notification.SystemZenRules;
import android.service.notification.ZenDeviceEffects;
+import android.service.notification.ZenModeConfig;
import android.service.notification.ZenPolicy;
import android.util.Log;
@@ -204,6 +213,44 @@ class ZenMode {
: new ZenDeviceEffects.Builder().build();
}
+ public void setCustomModeConditionId(Context context, Uri conditionId) {
+ checkState(SystemZenRules.PACKAGE_ANDROID.equals(mRule.getPackageName()),
+ "Trying to change condition of non-system-owned rule %s (to %s)",
+ mRule, conditionId);
+
+ Uri oldCondition = mRule.getConditionId();
+ mRule.setConditionId(conditionId);
+
+ ZenModeConfig.ScheduleInfo scheduleInfo = tryParseScheduleConditionId(conditionId);
+ if (scheduleInfo != null) {
+ mRule.setType(AutomaticZenRule.TYPE_SCHEDULE_TIME);
+ mRule.setOwner(ZenModeConfig.getScheduleConditionProvider());
+ mRule.setTriggerDescription(
+ getTriggerDescriptionForScheduleTime(context, scheduleInfo));
+ return;
+ }
+
+ ZenModeConfig.EventInfo eventInfo = tryParseEventConditionId(conditionId);
+ if (eventInfo != null) {
+ mRule.setType(AutomaticZenRule.TYPE_SCHEDULE_CALENDAR);
+ mRule.setOwner(ZenModeConfig.getEventConditionProvider());
+ mRule.setTriggerDescription(getTriggerDescriptionForScheduleEvent(context, eventInfo));
+ return;
+ }
+
+ if (ZenModeConfig.isValidCustomManualConditionId(conditionId)) {
+ mRule.setType(AutomaticZenRule.TYPE_OTHER);
+ mRule.setOwner(ZenModeConfig.getCustomManualConditionProvider());
+ mRule.setTriggerDescription("");
+ return;
+ }
+
+ Log.wtf(TAG, String.format(
+ "Changed condition of rule %s (%s -> %s) but cannot recognize which kind of "
+ + "condition it was!",
+ mRule, oldCondition, conditionId));
+ }
+
public boolean canEditName() {
return !isManualDnd();
}
@@ -224,6 +271,15 @@ class ZenMode {
return mIsActive;
}
+ public boolean isSystemOwned() {
+ return SystemZenRules.PACKAGE_ANDROID.equals(mRule.getPackageName());
+ }
+
+ @AutomaticZenRule.Type
+ public int getType() {
+ return mRule.getType();
+ }
+
@Override
public boolean equals(@Nullable Object obj) {
return obj instanceof ZenMode other
diff --git a/src/com/android/settings/notification/modes/ZenModeFragment.java b/src/com/android/settings/notification/modes/ZenModeFragment.java
index 6bda5e13c97..ee497ae74df 100644
--- a/src/com/android/settings/notification/modes/ZenModeFragment.java
+++ b/src/com/android/settings/notification/modes/ZenModeFragment.java
@@ -52,7 +52,7 @@ public class ZenModeFragment extends ZenModeFragmentBase {
prefControllers.add(new ZenModeDisplayLinkPreferenceController(
context, "mode_display_settings", mBackend, mHelperBackend));
prefControllers.add(new ZenModeSetTriggerLinkPreferenceController(context,
- "zen_automatic_trigger_category", mBackend));
+ "zen_automatic_trigger_category", this, mBackend));
return prefControllers;
}
diff --git a/src/com/android/settings/notification/modes/ZenModeScheduleChooserDialog.java b/src/com/android/settings/notification/modes/ZenModeScheduleChooserDialog.java
new file mode 100644
index 00000000000..14264b7a844
--- /dev/null
+++ b/src/com/android/settings/notification/modes/ZenModeScheduleChooserDialog.java
@@ -0,0 +1,149 @@
+/*
+ * 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 com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.service.notification.ZenModeConfig;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.dashboard.DashboardFragment;
+
+import com.google.common.collect.ImmutableList;
+
+public class ZenModeScheduleChooserDialog extends InstrumentedDialogFragment {
+
+ private static final String TAG = "ZenModeScheduleChooserDialog";
+
+ static final int OPTION_TIME = 0;
+ static final int OPTION_CALENDAR = 1;
+
+ private record ScheduleOption(@StringRes int nameResId, @StringRes int exampleResId,
+ @DrawableRes int iconResId) {}
+
+ private static final ImmutableList SCHEDULE_OPTIONS = ImmutableList.of(
+ new ScheduleOption(R.string.zen_mode_select_schedule_time,
+ R.string.zen_mode_select_schedule_time_example,
+ com.android.internal.R.drawable.ic_zen_mode_type_schedule_time),
+ new ScheduleOption(R.string.zen_mode_select_schedule_calendar,
+ R.string.zen_mode_select_schedule_calendar_example,
+ com.android.internal.R.drawable.ic_zen_mode_type_schedule_calendar));
+
+ private OnScheduleOptionListener mOptionListener;
+
+ interface OnScheduleOptionListener {
+ void onScheduleSelected(Uri conditionId);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ // TODO: b/332937635 - Update metrics category
+ return 0;
+ }
+
+ static void show(DashboardFragment parent, OnScheduleOptionListener optionListener) {
+ ZenModeScheduleChooserDialog dialog = new ZenModeScheduleChooserDialog();
+ dialog.mOptionListener = optionListener;
+ dialog.setTargetFragment(parent, 0);
+ dialog.show(parent.getParentFragmentManager(), TAG);
+ }
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+ checkState(getContext() != null);
+ return new AlertDialog.Builder(getContext())
+ .setTitle(R.string.zen_mode_choose_rule_type)
+ .setAdapter(new OptionsAdapter(getContext()),
+ (dialog, which) -> onScheduleTypeSelected(which))
+ .setNegativeButton(R.string.cancel, null)
+ .create();
+ }
+
+ private static class OptionsAdapter extends ArrayAdapter {
+
+ private final LayoutInflater mInflater;
+
+ OptionsAdapter(@NonNull Context context) {
+ super(context, R.layout.zen_mode_type_item, SCHEDULE_OPTIONS);
+ mInflater = LayoutInflater.from(context);
+ }
+
+ @NonNull
+ @Override
+ public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
+ if (convertView == null) {
+ convertView = mInflater.inflate(R.layout.zen_mode_type_item, parent, false);
+ }
+ // No need for holder pattern since we have only 2 items.
+ ImageView imageView = checkNotNull(convertView.findViewById(R.id.icon));
+ TextView title = checkNotNull(convertView.findViewById(R.id.title));
+ TextView subtitle = checkNotNull(convertView.findViewById(R.id.subtitle));
+
+ ScheduleOption option = checkNotNull(getItem(position));
+ imageView.setImageResource(option.iconResId());
+ title.setText(option.nameResId());
+ subtitle.setText(option.exampleResId());
+
+ return convertView;
+ }
+ }
+
+ private void onScheduleTypeSelected(int whichOption) {
+ Uri conditionId = switch (whichOption) {
+ case OPTION_TIME -> getDefaultScheduleTimeCondition();
+ case OPTION_CALENDAR -> getDefaultScheduleCalendarCondition();
+ default -> ZenModeConfig.toCustomManualConditionId();
+ };
+
+ mOptionListener.onScheduleSelected(conditionId);
+ }
+
+ private static Uri getDefaultScheduleTimeCondition() {
+ ZenModeConfig.ScheduleInfo schedule = new ZenModeConfig.ScheduleInfo();
+ schedule.days = ZenModeConfig.ALL_DAYS;
+ schedule.startHour = 9;
+ schedule.startMinute = 30;
+ schedule.endHour = 17;
+ return ZenModeConfig.toScheduleConditionId(schedule);
+ }
+
+ private static Uri getDefaultScheduleCalendarCondition() {
+ ZenModeConfig.EventInfo eventInfo = new ZenModeConfig.EventInfo();
+ eventInfo.calendarId = null; // All calendars of the current user.
+ eventInfo.reply = ZenModeConfig.EventInfo.REPLY_ANY_EXCEPT_NO;
+ return ZenModeConfig.toEventConditionId(eventInfo);
+ }
+}
diff --git a/src/com/android/settings/notification/modes/ZenModeSetCalendarPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeSetCalendarPreferenceController.java
index 28413091a37..e87907647db 100644
--- a/src/com/android/settings/notification/modes/ZenModeSetCalendarPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeSetCalendarPreferenceController.java
@@ -16,14 +16,12 @@
package com.android.settings.notification.modes;
-import android.app.Flags;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.CalendarContract;
-import android.service.notification.SystemZenRules;
import android.service.notification.ZenModeConfig;
import androidx.annotation.NonNull;
@@ -42,7 +40,7 @@ import java.util.List;
import java.util.Objects;
import java.util.function.Function;
-public class ZenModeSetCalendarPreferenceController extends AbstractZenModePreferenceController {
+class ZenModeSetCalendarPreferenceController extends AbstractZenModePreferenceController {
@VisibleForTesting
protected static final String KEY_CALENDAR = "calendar";
@VisibleForTesting
@@ -122,11 +120,7 @@ public class ZenModeSetCalendarPreferenceController extends AbstractZenModePrefe
@VisibleForTesting
protected Function updateEventMode(ZenModeConfig.EventInfo event) {
return (zenMode) -> {
- zenMode.getRule().setConditionId(ZenModeConfig.toEventConditionId(event));
- if (Flags.modesApi() && Flags.modesUi()) {
- zenMode.getRule().setTriggerDescription(
- SystemZenRules.getTriggerDescriptionForScheduleEvent(mContext, event));
- }
+ zenMode.setCustomModeConditionId(mContext, ZenModeConfig.toEventConditionId(event));
return zenMode;
};
}
diff --git a/src/com/android/settings/notification/modes/ZenModeSetSchedulePreferenceController.java b/src/com/android/settings/notification/modes/ZenModeSetSchedulePreferenceController.java
index a6008ccd768..3432ed5154f 100644
--- a/src/com/android/settings/notification/modes/ZenModeSetSchedulePreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeSetSchedulePreferenceController.java
@@ -16,9 +16,7 @@
package com.android.settings.notification.modes;
-import android.app.Flags;
import android.content.Context;
-import android.service.notification.SystemZenRules;
import android.service.notification.ZenModeConfig;
import android.text.format.DateFormat;
import android.util.ArraySet;
@@ -116,16 +114,13 @@ class ZenModeSetSchedulePreferenceController extends AbstractZenModePreferenceCo
@VisibleForTesting
protected Function updateScheduleMode(ZenModeConfig.ScheduleInfo schedule) {
return (zenMode) -> {
- zenMode.getRule().setConditionId(ZenModeConfig.toScheduleConditionId(schedule));
- if (Flags.modesApi() && Flags.modesUi()) {
- zenMode.getRule().setTriggerDescription(
- SystemZenRules.getTriggerDescriptionForScheduleTime(mContext, schedule));
- }
+ zenMode.setCustomModeConditionId(mContext,
+ ZenModeConfig.toScheduleConditionId(schedule));
return zenMode;
};
}
- private ZenModeTimePickerFragment.TimeSetter mStartSetter = (hour, minute) -> {
+ private final ZenModeTimePickerFragment.TimeSetter mStartSetter = (hour, minute) -> {
if (!isValidTime(hour, minute)) {
return;
}
@@ -137,7 +132,7 @@ class ZenModeSetSchedulePreferenceController extends AbstractZenModePreferenceCo
saveMode(updateScheduleMode(mSchedule));
};
- private ZenModeTimePickerFragment.TimeSetter mEndSetter = (hour, minute) -> {
+ private final ZenModeTimePickerFragment.TimeSetter mEndSetter = (hour, minute) -> {
if (!isValidTime(hour, minute)) {
return;
}
diff --git a/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceController.java
index 14d5d59a19d..fd27958db95 100644
--- a/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceController.java
@@ -13,15 +13,13 @@
* 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_SCHEDULE_CALENDAR;
import static android.app.AutomaticZenRule.TYPE_SCHEDULE_TIME;
-import static com.android.settings.notification.modes.ZenModeFragmentBase.MODE_ID;
-
import android.content.Context;
-import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -29,7 +27,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import com.android.settings.R;
-import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.PrimarySwitchPreference;
/**
@@ -39,9 +37,13 @@ class ZenModeSetTriggerLinkPreferenceController extends AbstractZenModePreferenc
@VisibleForTesting
protected static final String AUTOMATIC_TRIGGER_PREF_KEY = "zen_automatic_trigger_settings";
+ private final DashboardFragment mFragment;
+
ZenModeSetTriggerLinkPreferenceController(Context context, String key,
+ DashboardFragment fragment,
ZenModesBackend backend) {
super(context, key, backend);
+ mFragment = fragment;
}
@Override
@@ -54,46 +56,52 @@ class ZenModeSetTriggerLinkPreferenceController extends AbstractZenModePreferenc
// 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).
- Preference switchPref = ((PreferenceCategory) preference).findPreference(
+ PrimarySwitchPreference switchPref = ((PreferenceCategory) preference).findPreference(
AUTOMATIC_TRIGGER_PREF_KEY);
if (switchPref == null) {
return;
}
- ((PrimarySwitchPreference) switchPref).setChecked(zenMode.getRule().isEnabled());
+ switchPref.setChecked(zenMode.getRule().isEnabled());
switchPref.setOnPreferenceChangeListener(mSwitchChangeListener);
- Bundle bundle = new Bundle();
- bundle.putString(MODE_ID, zenMode.getId());
+ switchPref.setSummary(zenMode.getRule().getTriggerDescription());
+ switchPref.setIcon(null);
+ switchPref.setOnPreferenceClickListener(null);
+ switchPref.setIntent(null);
- // TODO: b/341961712 - direct preference to app-owned intent if available
- switch (zenMode.getRule().getType()) {
- case TYPE_SCHEDULE_TIME:
- switchPref.setTitle(R.string.zen_mode_set_schedule_link);
- switchPref.setSummary(zenMode.getRule().getTriggerDescription());
- switchPref.setIntent(new SubSettingLauncher(mContext)
- .setDestination(ZenModeSetScheduleFragment.class.getName())
- // TODO: b/332937635 - set correct metrics category
- .setSourceMetricsCategory(0)
- .setArguments(bundle)
- .toIntent());
- break;
- case TYPE_SCHEDULE_CALENDAR:
- switchPref.setTitle(R.string.zen_mode_set_calendar_link);
- switchPref.setSummary(zenMode.getRule().getTriggerDescription());
- switchPref.setIntent(new SubSettingLauncher(mContext)
- .setDestination(ZenModeSetCalendarFragment.class.getName())
- // TODO: b/332937635 - set correct metrics category
- .setSourceMetricsCategory(0)
- .setArguments(bundle)
- .toIntent());
- break;
- default:
- // TODO: b/342156843 - change this to allow adding a trigger condition for system
- // rules that don't yet have a type selected
- switchPref.setTitle("not implemented");
+ if (zenMode.isSystemOwned() && zenMode.getType() == TYPE_SCHEDULE_TIME) {
+ switchPref.setTitle(R.string.zen_mode_set_schedule_link);
+ // TODO: b/332937635 - set correct metrics category
+ switchPref.setIntent(ZenSubSettingLauncher.forModeFragment(mContext,
+ ZenModeSetScheduleFragment.class, zenMode.getId(), 0).toIntent());
+ } else if (zenMode.isSystemOwned() && zenMode.getType() == TYPE_SCHEDULE_CALENDAR) {
+ switchPref.setTitle(R.string.zen_mode_set_calendar_link);
+ switchPref.setIcon(null);
+ // TODO: b/332937635 - set correct metrics category
+ switchPref.setIntent(ZenSubSettingLauncher.forModeFragment(mContext,
+ ZenModeSetCalendarFragment.class, zenMode.getId(), 0).toIntent());
+ } else if (zenMode.isSystemOwned()) {
+ switchPref.setTitle(R.string.zen_mode_select_schedule);
+ switchPref.setIcon(R.drawable.ic_add_24dp);
+ switchPref.setSummary("");
+ // TODO: b/342156843 - Hide the switch (needs support in SettingsLib).
+ switchPref.setOnPreferenceClickListener(clickedPreference -> {
+ ZenModeScheduleChooserDialog.show(mFragment, mOnScheduleOptionListener);
+ return true;
+ });
+ } else {
+ // TODO: b/341961712 - direct preference to app-owned intent if available
+ switchPref.setTitle("not implemented");
}
}
+ @VisibleForTesting
+ final ZenModeScheduleChooserDialog.OnScheduleOptionListener mOnScheduleOptionListener =
+ conditionId -> saveMode(mode -> {
+ mode.setCustomModeConditionId(mContext, conditionId);
+ return mode;
+ });
+
@VisibleForTesting
protected Preference.OnPreferenceChangeListener mSwitchChangeListener = (p, newValue) -> {
final boolean newEnabled = (Boolean) newValue;
@@ -103,5 +111,6 @@ class ZenModeSetTriggerLinkPreferenceController extends AbstractZenModePreferenc
}
return zenMode;
});
+ // TODO: b/342156843 - Do we want to jump to the corresponding schedule editing screen?
};
}
diff --git a/src/com/android/settings/notification/modes/ZenModesBackend.java b/src/com/android/settings/notification/modes/ZenModesBackend.java
index b58e3107934..4f86778cf63 100644
--- a/src/com/android/settings/notification/modes/ZenModesBackend.java
+++ b/src/com/android/settings/notification/modes/ZenModesBackend.java
@@ -24,7 +24,6 @@ import android.content.Context;
import android.net.Uri;
import android.provider.Settings;
import android.service.notification.Condition;
-import android.service.notification.SystemZenRules;
import android.service.notification.ZenModeConfig;
import android.util.Log;
@@ -194,19 +193,11 @@ class ZenModesBackend {
*/
@Nullable
ZenMode addCustomMode(String name) {
- ZenModeConfig.ScheduleInfo schedule = new ZenModeConfig.ScheduleInfo();
- schedule.days = ZenModeConfig.ALL_DAYS;
- schedule.startHour = 22;
- schedule.endHour = 7;
-
- // TODO: b/326442408 - Create as "manual" (i.e. no trigger) instead of schedule-time.
AutomaticZenRule rule = new AutomaticZenRule.Builder(name,
- ZenModeConfig.toScheduleConditionId(schedule))
- .setPackage(ZenModeConfig.getScheduleConditionProvider().getPackageName())
- .setType(AutomaticZenRule.TYPE_SCHEDULE_CALENDAR)
- .setOwner(ZenModeConfig.getScheduleConditionProvider())
- .setTriggerDescription(SystemZenRules.getTriggerDescriptionForScheduleTime(
- mContext, schedule))
+ ZenModeConfig.toCustomManualConditionId())
+ .setPackage(ZenModeConfig.getCustomManualConditionProvider().getPackageName())
+ .setType(AutomaticZenRule.TYPE_OTHER)
+ .setOwner(ZenModeConfig.getCustomManualConditionProvider())
.setManualInvocationAllowed(true)
.build();
diff --git a/src/com/android/settings/notification/modes/ZenSubSettingLauncher.java b/src/com/android/settings/notification/modes/ZenSubSettingLauncher.java
index 11f3492f36d..aa66e6c5186 100644
--- a/src/com/android/settings/notification/modes/ZenSubSettingLauncher.java
+++ b/src/com/android/settings/notification/modes/ZenSubSettingLauncher.java
@@ -29,7 +29,7 @@ class ZenSubSettingLauncher {
SettingsEnums.NOTIFICATION_ZEN_MODE_AUTOMATION);
}
- private static SubSettingLauncher forModeFragment(Context context,
+ static SubSettingLauncher forModeFragment(Context context,
Class extends ZenModeFragmentBase> fragmentClass, String modeId,
int sourceMetricsCategory) {
Bundle bundle = new Bundle();
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetCalendarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetCalendarPreferenceControllerTest.java
index 6b24fa21832..0ede058aed7 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetCalendarPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetCalendarPreferenceControllerTest.java
@@ -34,6 +34,7 @@ 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.DropDownPreference;
@@ -85,7 +86,9 @@ public class ZenModeSetCalendarPreferenceControllerTest {
@EnableFlags({Flags.FLAG_MODES_API, Flags.FLAG_MODES_UI})
public void updateEventMode_updatesConditionAndTriggerDescription() {
ZenMode mode = new ZenMode("id",
- new AutomaticZenRule.Builder("name", Uri.parse("condition")).build(),
+ new AutomaticZenRule.Builder("name", Uri.parse("condition"))
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
+ .build(),
true); // is active
// Explicitly update preference controller with mode info first, which will also call
@@ -99,6 +102,7 @@ public class ZenModeSetCalendarPreferenceControllerTest {
// apply event mode updater to existing mode
ZenMode out = mPrefController.updateEventMode(eventInfo).apply(mode);
+ assertThat(out.getRule().getOwner()).isEqualTo(ZenModeConfig.getEventConditionProvider());
assertThat(out.getRule().getConditionId()).isEqualTo(
ZenModeConfig.toEventConditionId(eventInfo));
assertThat(out.getRule().getTriggerDescription()).isEqualTo("My events");
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetSchedulePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetSchedulePreferenceControllerTest.java
index 7cf327c983e..5f492b971a8 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetSchedulePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetSchedulePreferenceControllerTest.java
@@ -29,6 +29,7 @@ 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 android.view.ViewGroup;
import android.widget.ToggleButton;
@@ -81,7 +82,9 @@ public class ZenModeSetSchedulePreferenceControllerTest {
@EnableFlags({Flags.FLAG_MODES_API, Flags.FLAG_MODES_UI})
public void updateScheduleRule_updatesConditionAndTriggerDescription() {
ZenMode mode = new ZenMode("id",
- new AutomaticZenRule.Builder("name", Uri.parse("condition")).build(),
+ new AutomaticZenRule.Builder("name", Uri.parse("condition"))
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
+ .build(),
true); // is active
ZenModeConfig.ScheduleInfo scheduleInfo = new ZenModeConfig.ScheduleInfo();
@@ -93,6 +96,8 @@ public class ZenModeSetSchedulePreferenceControllerTest {
assertThat(out.getRule().getConditionId())
.isEqualTo(ZenModeConfig.toScheduleConditionId(scheduleInfo));
assertThat(out.getRule().getTriggerDescription()).isNotEmpty();
+ assertThat(out.getRule().getOwner()).isEqualTo(
+ ZenModeConfig.getScheduleConditionProvider());
}
@Test
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 91de4ea8348..ff4d4a3c94c 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeSetTriggerLinkPreferenceControllerTest.java
@@ -16,6 +16,7 @@
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;
@@ -31,10 +32,10 @@ import static org.mockito.Mockito.when;
import android.app.AutomaticZenRule;
import android.app.Flags;
import android.content.Context;
-import android.content.Intent;
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 android.service.notification.ZenPolicy;
@@ -43,6 +44,7 @@ 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 org.junit.Before;
@@ -57,6 +59,7 @@ import org.robolectric.RobolectricTestRunner;
import java.util.Calendar;
@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
public class ZenModeSetTriggerLinkPreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
@@ -65,10 +68,13 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
private ZenModesBackend mBackend;
private Context mContext;
+ private PrimarySwitchPreference mPreference;
+
@Mock
private PreferenceCategory mPrefCategory;
@Mock
- private PrimarySwitchPreference mPreference;
+ private DashboardFragment mFragment;
+
private ZenModeSetTriggerLinkPreferenceController mPrefController;
@Before
@@ -77,12 +83,12 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
mContext = ApplicationProvider.getApplicationContext();
mPrefController = new ZenModeSetTriggerLinkPreferenceController(mContext,
- "zen_automatic_trigger_category", mBackend);
+ "zen_automatic_trigger_category", mFragment, mBackend);
+ mPreference = new PrimarySwitchPreference(mContext);
when(mPrefCategory.findPreference(AUTOMATIC_TRIGGER_PREF_KEY)).thenReturn(mPreference);
}
@Test
- @EnableFlags(Flags.FLAG_MODES_UI)
public void testIsAvailable() {
// should not be available for manual DND
ZenMode manualMode = ZenMode.manualDndMode(new AutomaticZenRule.Builder("Do Not Disturb",
@@ -117,12 +123,12 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
// Update preference controller with a zen mode that is not enabled
mPrefController.updateZenMode(mPrefCategory, zenMode);
- verify(mPreference).setChecked(false);
+ assertThat(mPreference.getCheckedState()).isFalse();
// Now with the rule enabled
zenMode.getRule().setEnabled(true);
mPrefController.updateZenMode(mPrefCategory, zenMode);
- verify(mPreference).setChecked(true);
+ assertThat(mPreference.getCheckedState()).isTrue();
}
@Test
@@ -154,21 +160,24 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
eventInfo.calName = "My events";
ZenMode mode = new ZenMode("id", new AutomaticZenRule.Builder("name",
ZenModeConfig.toEventConditionId(eventInfo))
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
.setType(TYPE_SCHEDULE_CALENDAR)
.setTriggerDescription("My events")
.build(),
true); // is active
mPrefController.updateZenMode(mPrefCategory, mode);
- verify(mPreference).setTitle(R.string.zen_mode_set_calendar_link);
- verify(mPreference).setSummary(mode.getRule().getTriggerDescription());
+ assertThat(mPreference.getTitle()).isNotNull();
+ assertThat(mPreference.getTitle().toString()).isEqualTo(
+ mContext.getString(R.string.zen_mode_set_calendar_link));
+ assertThat(mPreference.getSummary()).isNotNull();
+ assertThat(mPreference.getSummary().toString()).isEqualTo(
+ mode.getRule().getTriggerDescription());
+ assertThat(mPreference.getIcon()).isNull();
- ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class);
- verify(mPreference).setIntent(captor.capture());
// Destination as written into the intent by SubSettingLauncher
- assertThat(
- captor.getValue().getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo(
- ZenModeSetCalendarFragment.class.getName());
+ assertThat(mPreference.getIntent().getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
+ .isEqualTo(ZenModeSetCalendarFragment.class.getName());
}
@Test
@@ -179,20 +188,75 @@ public class ZenModeSetTriggerLinkPreferenceControllerTest {
scheduleInfo.endHour = 15;
ZenMode mode = new ZenMode("id", new AutomaticZenRule.Builder("name",
ZenModeConfig.toScheduleConditionId(scheduleInfo))
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
.setType(TYPE_SCHEDULE_TIME)
.setTriggerDescription("some schedule")
.build(),
true); // is active
mPrefController.updateZenMode(mPrefCategory, mode);
- verify(mPreference).setTitle(R.string.zen_mode_set_schedule_link);
- verify(mPreference).setSummary(mode.getRule().getTriggerDescription());
+ assertThat(mPreference.getTitle()).isNotNull();
+ assertThat(mPreference.getTitle().toString()).isEqualTo(
+ mContext.getString(R.string.zen_mode_set_schedule_link));
+ assertThat(mPreference.getSummary()).isNotNull();
+ assertThat(mPreference.getSummary().toString()).isEqualTo(
+ mode.getRule().getTriggerDescription());
+ assertThat(mPreference.getIcon()).isNull();
- ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class);
- verify(mPreference).setIntent(captor.capture());
// Destination as written into the intent by SubSettingLauncher
- assertThat(
- captor.getValue().getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo(
- ZenModeSetScheduleFragment.class.getName());
+ assertThat(mPreference.getIntent().getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
+ .isEqualTo(ZenModeSetScheduleFragment.class.getName());
+ }
+
+ @Test
+ public void testRuleLink_manual() {
+ ZenMode mode = new ZenMode("id", new AutomaticZenRule.Builder("name",
+ ZenModeConfig.toCustomManualConditionId())
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
+ .setType(TYPE_OTHER)
+ .setTriggerDescription("Will not be shown")
+ .build(),
+ true); // is active
+ mPrefController.updateZenMode(mPrefCategory, mode);
+
+ assertThat(mPreference.getTitle()).isNotNull();
+ assertThat(mPreference.getTitle().toString()).isEqualTo(
+ mContext.getString(R.string.zen_mode_select_schedule));
+ assertThat(mPreference.getIcon()).isNotNull();
+ assertThat(mPreference.getSummary()).isNotNull();
+ assertThat(mPreference.getSummary().toString()).isEqualTo("");
+
+ // Set up a click listener to open the dialog.
+ assertThat(mPreference.getOnPreferenceClickListener()).isNotNull();
+ }
+
+ @Test
+ public void onScheduleChosen_updatesMode() {
+ ZenMode originalMode = new ZenMode("id",
+ new AutomaticZenRule.Builder("name", ZenModeConfig.toCustomManualConditionId())
+ .setPackage(SystemZenRules.PACKAGE_ANDROID)
+ .setType(TYPE_OTHER)
+ .setTriggerDescription("")
+ .build(),
+ false);
+ mPrefController.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);
+
+ mPrefController.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());
}
}