diff --git a/res/drawable/ic_modes_event.xml b/res/drawable/ic_modes_event.xml
new file mode 100644
index 00000000000..40004899ad8
--- /dev/null
+++ b/res/drawable/ic_modes_event.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/res/drawable/ic_modes_time.xml b/res/drawable/ic_modes_time.xml
new file mode 100644
index 00000000000..dff3c43933d
--- /dev/null
+++ b/res/drawable/ic_modes_time.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/xml/modes_rule_settings.xml b/res/xml/modes_rule_settings.xml
index d7e26946829..1b79153cf7b 100644
--- a/res/xml/modes_rule_settings.xml
+++ b/res/xml/modes_rule_settings.xml
@@ -18,8 +18,8 @@
-
-
+
\ No newline at end of file
diff --git a/src/com/android/settings/notification/modes/ZenMode.java b/src/com/android/settings/notification/modes/ZenMode.java
index 66d68c5c7cd..51c92e6eae5 100644
--- a/src/com/android/settings/notification/modes/ZenMode.java
+++ b/src/com/android/settings/notification/modes/ZenMode.java
@@ -155,8 +155,8 @@ class ZenMode {
int iconResIdFromType = switch (mRule.getType()) {
case AutomaticZenRule.TYPE_UNKNOWN -> R.drawable.ic_do_not_disturb_on_24dp;
case AutomaticZenRule.TYPE_OTHER -> R.drawable.ic_do_not_disturb_on_24dp;
- case AutomaticZenRule.TYPE_SCHEDULE_TIME -> R.drawable.ic_do_not_disturb_on_24dp;
- case AutomaticZenRule.TYPE_SCHEDULE_CALENDAR -> R.drawable.ic_do_not_disturb_on_24dp;
+ case AutomaticZenRule.TYPE_SCHEDULE_TIME -> R.drawable.ic_modes_time;
+ case AutomaticZenRule.TYPE_SCHEDULE_CALENDAR -> R.drawable.ic_modes_event;
case AutomaticZenRule.TYPE_BEDTIME -> R.drawable.ic_do_not_disturb_on_24dp;
case AutomaticZenRule.TYPE_DRIVING -> R.drawable.ic_do_not_disturb_on_24dp;
case AutomaticZenRule.TYPE_IMMERSIVE -> R.drawable.ic_do_not_disturb_on_24dp;
diff --git a/src/com/android/settings/notification/modes/ZenModeFragment.java b/src/com/android/settings/notification/modes/ZenModeFragment.java
index 616332e0d1f..d2126810358 100644
--- a/src/com/android/settings/notification/modes/ZenModeFragment.java
+++ b/src/com/android/settings/notification/modes/ZenModeFragment.java
@@ -41,6 +41,7 @@ public class ZenModeFragment extends ZenModeFragmentBase {
// TODO: fill in with all the elements of this page. Each should be an instance of
// {@link AbstractZenModePreferenceController}.
List prefControllers = new ArrayList<>();
+ prefControllers.add(new ZenModeHeaderController(context, "header", this, mBackend));
return prefControllers;
}
@@ -55,19 +56,6 @@ public class ZenModeFragment extends ZenModeFragmentBase {
return;
}
getActivity().setTitle(azr.getName());
-
- // TODO: b/308819292 - implement the real screen!
- final PreferenceScreen screen = getPreferenceScreen();
- if (screen == null) {
- return;
- }
-
- Preference tmpPref = screen.findPreference("zen_mode_test");
- if (tmpPref == null) {
- return;
- }
- tmpPref.setTitle(azr.getTriggerDescription());
- tmpPref.setSummary("active?: " + mode.isActive());
}
@Override
diff --git a/src/com/android/settings/notification/modes/ZenModeHeaderController.java b/src/com/android/settings/notification/modes/ZenModeHeaderController.java
new file mode 100644
index 00000000000..246eee85d77
--- /dev/null
+++ b/src/com/android/settings/notification/modes/ZenModeHeaderController.java
@@ -0,0 +1,75 @@
+/*
+ * 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.app.Flags;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.widget.LayoutPreference;
+
+import java.util.concurrent.TimeUnit;
+
+public class ZenModeHeaderController extends AbstractZenModePreferenceController {
+
+ private final DashboardFragment mFragment;
+ private EntityHeaderController mHeaderController;
+
+ ZenModeHeaderController(
+ @NonNull Context context,
+ @NonNull String key,
+ @NonNull DashboardFragment fragment,
+ @Nullable ZenModesBackend backend) {
+ super(context, key, backend);
+ mFragment = fragment;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return Flags.modesApi();
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ if (getAZR() == null || mFragment == null) {
+ return;
+ }
+
+ if (mHeaderController == null) {
+ final LayoutPreference pref = (LayoutPreference) preference;
+ mHeaderController = EntityHeaderController.newInstance(
+ mFragment.getActivity(),
+ mFragment,
+ pref.findViewById(R.id.entity_header));
+ }
+ Drawable icon = null;
+ try {
+ icon = getMode().getIcon(mContext).get(200, TimeUnit.MILLISECONDS);
+ } catch (Exception e) {
+ // no icon
+ }
+ mHeaderController.setIcon(icon)
+ .setLabel(getAZR().getName())
+ .done(false /* rebindActions */);
+ }
+}
diff --git a/src/com/android/settings/notification/modes/ZenModeListPreference.java b/src/com/android/settings/notification/modes/ZenModeListPreference.java
index cb0456140bf..2a95dffc5e0 100644
--- a/src/com/android/settings/notification/modes/ZenModeListPreference.java
+++ b/src/com/android/settings/notification/modes/ZenModeListPreference.java
@@ -25,6 +25,10 @@ import com.android.settings.core.SubSettingLauncher;
import com.android.settings.notification.zen.ZenModeSettings;
import com.android.settingslib.RestrictedPreference;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
/**
* Preference representing a single mode item on the modes aggregator page. Clicking on this
* preference leads to an individual mode's configuration page.
@@ -36,10 +40,8 @@ public class ZenModeListPreference extends RestrictedPreference {
ZenModeListPreference(Context context, ZenMode zenMode) {
super(context);
mContext = context;
- mZenMode = zenMode;
- setTitle(mZenMode.getRule().getName());
- setSummary((mZenMode.isActive() ? "ACTIVE" : "inactive") + ": "
- + mZenMode.getRule().getTriggerDescription());
+ setZenMode(zenMode);
+ setKey(zenMode.getId());
}
@Override
@@ -60,6 +62,16 @@ public class ZenModeListPreference extends RestrictedPreference {
.setSourceMetricsCategory(SettingsEnums.NOTIFICATION_ZEN_MODE_AUTOMATION)
.launch();
}
+ }
+ public void setZenMode(ZenMode zenMode) {
+ mZenMode = zenMode;
+ setTitle(mZenMode.getRule().getName());
+ setSummary(mZenMode.getRule().getTriggerDescription());
+ try {
+ setIcon(mZenMode.getIcon(mContext).get(200, TimeUnit.MILLISECONDS));
+ } catch (Exception e) {
+ // no icon
+ }
}
}
diff --git a/src/com/android/settings/notification/modes/ZenModesBackend.java b/src/com/android/settings/notification/modes/ZenModesBackend.java
index 373d6540acc..e019ea27940 100644
--- a/src/com/android/settings/notification/modes/ZenModesBackend.java
+++ b/src/com/android/settings/notification/modes/ZenModesBackend.java
@@ -33,6 +33,7 @@ import com.android.settings.R;
import java.time.Duration;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
@@ -77,7 +78,15 @@ class ZenModesBackend {
isRuleActive(ruleId, currentConfig)));
}
- // TODO: b/331429435 - Sort modes.
+ modes.sort((l, r) -> {
+ if (l.isManualDnd()) {
+ return -1;
+ } else if (r.isManualDnd()) {
+ return 1;
+ }
+ return l.getRule().getName().compareTo(r.getRule().getName());
+ });
+
return modes;
}
@@ -105,10 +114,10 @@ class ZenModesBackend {
.setZenPolicy(ZenAdapters.notificationPolicyToZenPolicy(
mNotificationManager.getNotificationPolicy()))
.setDeviceEffects(null)
- .setTriggerDescription(mContext.getString(R.string.zen_mode_settings_summary))
.setManualInvocationAllowed(true)
.setConfigurationActivity(null) // No further settings
.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY)
+ .setIconResId(com.android.internal.R.drawable.ic_zen_24dp)
.build();
return ZenMode.manualDndMode(manualDndRule,
diff --git a/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java b/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java
index 53336c84be3..dbeaa2cceca 100644
--- a/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java
@@ -15,6 +15,7 @@
*/
package com.android.settings.notification.modes;
+import android.app.AutomaticZenRule;
import android.app.Flags;
import android.content.Context;
@@ -26,6 +27,9 @@ import androidx.preference.PreferenceCategory;
import com.android.settingslib.core.AbstractPreferenceController;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* Controller for the PreferenceCategory on the modes aggregator page ({@link ZenModesListFragment})
* containing links to each individual mode. This is a central controller that populates and updates
@@ -65,16 +69,30 @@ public class ZenModesListPreferenceController extends AbstractPreferenceControll
// category for each rule that exists.
PreferenceCategory category = (PreferenceCategory) preference;
- // TODO: b/322373473 - This is not the right way to replace these preferences; we should
- // follow something similar to what
- // ZenModeAutomaticRulesPreferenceController does to change rules
- // only as necessary and update them.
- category.removeAll();
+ Map originalPreferences = new HashMap<>();
+ for (int i = 0; i < category.getPreferenceCount(); i++) {
+ ZenModeListPreference pref = (ZenModeListPreference) category.getPreference(i);
+ originalPreferences.put(pref.getKey(), pref);
+ }
+ // Loop through each rule, either updating the existing rule or creating the rule's
+ // preference
for (ZenMode mode : mBackend.getModes()) {
- Preference pref = new ZenModeListPreference(mContext, mode);
- category.addPreference(pref);
+ if (originalPreferences.containsKey(mode.getId())) {
+ // existing rule; update its info if it's changed since the last display
+ AutomaticZenRule rule = mode.getRule();
+ originalPreferences.get(mode.getId()).setZenMode(mode);
+ } else {
+ // new rule; create a new ZenRulePreference & add it to the preference category
+ Preference pref = new ZenModeListPreference(mContext, mode);
+ category.addPreference(pref);
+ }
+
+ originalPreferences.remove(mode.getId());
+ }
+ // Remove preferences that no longer have a rule
+ for (String key : originalPreferences.keySet()) {
+ category.removePreferenceRecursively(key);
}
}
-
}