Disable all preferences (except toggle) when a mode is disabled
Also set some alpha on the circles so that they look more or less disabled as well.
Fixes: 354867828
Test: atest com.android.settings.notification.modes
Flag: android.app.modes_ui
Change-Id: I53ef5e381d37afa20b0532f3c7ddb3f106b2e85e
diff --git a/src/com/android/settings/notification/modes/CircularIconsPreference.java b/src/com/android/settings/notification/modes/CircularIconsPreference.java
index 1ce3476..e3cd948 100644
--- a/src/com/android/settings/notification/modes/CircularIconsPreference.java
+++ b/src/com/android/settings/notification/modes/CircularIconsPreference.java
@@ -51,6 +51,8 @@
public class CircularIconsPreference extends RestrictedPreference {
+ private static final float DISABLED_ITEM_ALPHA = 0.3f;
+
private Executor mUiExecutor;
@Nullable private LinearLayout mIconContainer;
@@ -98,6 +100,14 @@
displayIconsIfPending();
}
+ @Override
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled);
+ if (mIconContainer != null) {
+ applyEnabledToIcons(mIconContainer, enabled);
+ }
+ }
+
private void displayIconsIfPending() {
CircularIconSet<?> pendingIconSet = mPendingDisplayIconSet;
if (pendingIconSet != null) {
@@ -211,6 +221,8 @@
textView.setText(getContext().getString(R.string.zen_mode_plus_n_items, extraItems));
}
+ applyEnabledToIcons(mIconContainer, isEnabled());
+
// Display icons when all are ready (more consistent than randomly loading).
mPendingLoadIconsFuture = Futures.allAsList(iconFutures);
FutureUtil.whenDone(
@@ -224,6 +236,13 @@
mUiExecutor);
}
+ private void applyEnabledToIcons(ViewGroup container, boolean enabled) {
+ for (int i = 0; i < container.getChildCount(); i++) {
+ View child = container.getChildAt(i);
+ child.setAlpha(enabled ? 1.0f : DISABLED_ITEM_ALPHA);
+ }
+ }
+
private static Drawable getPlaceholderImage(Context context) {
ShapeDrawable placeholder = new ShapeDrawable(new OvalShape());
placeholder.setTintList(Utils.getColorAttr(context,
@@ -250,6 +269,18 @@
}
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
+ List<View> getViews() {
+ if (mIconContainer == null) {
+ return List.of();
+ }
+ ArrayList<View> views = new ArrayList<>();
+ for (int i = 0; i < mIconContainer.getChildCount(); i++) {
+ views.add(mIconContainer.getChildAt(i));
+ }
+ return views;
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.NONE)
List<Drawable> getIcons() {
if (mIconContainer == null) {
return List.of();
diff --git a/src/com/android/settings/notification/modes/InterruptionFilterPreferenceController.java b/src/com/android/settings/notification/modes/InterruptionFilterPreferenceController.java
index 8bdeea4..9d4a172 100644
--- a/src/com/android/settings/notification/modes/InterruptionFilterPreferenceController.java
+++ b/src/com/android/settings/notification/modes/InterruptionFilterPreferenceController.java
@@ -44,6 +44,7 @@
@Override
public void updateState(Preference preference, @NonNull ZenMode zenMode) {
+ preference.setEnabled(zenMode.isEnabled());
boolean filteringNotifications = zenMode.getRule().getInterruptionFilter()
!= INTERRUPTION_FILTER_ALL;
((TwoStatePreference) preference).setChecked(filteringNotifications);
diff --git a/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java
index 962e016..1521a8b 100644
--- a/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java
@@ -34,7 +34,6 @@
import com.android.settings.R;
import com.android.settings.Utils;
-import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.notification.modes.ZenMode;
@@ -95,11 +94,11 @@
Bundle bundle = new Bundle();
bundle.putString(EXTRA_AUTOMATIC_ZEN_RULE_ID, zenMode.getId());
// TODO(b/332937635): Update metrics category
- preference.setIntent(new SubSettingLauncher(mContext)
- .setDestination(ZenModeAppsFragment.class.getName())
- .setSourceMetricsCategory(0)
- .setArguments(bundle)
- .toIntent());
+ preference.setIntent(
+ ZenSubSettingLauncher.forModeFragment(mContext, ZenModeAppsFragment.class,
+ zenMode.getId(), 0).toIntent());
+ preference.setEnabled(zenMode.isEnabled());
+
mZenMode = zenMode;
mPreference = (CircularIconsPreference) preference;
diff --git a/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceController.java
index d3559f1..bba5e34 100644
--- a/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceController.java
@@ -24,7 +24,6 @@
import androidx.annotation.NonNull;
import androidx.preference.Preference;
-import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.notification.modes.ZenMode;
import com.android.settingslib.notification.modes.ZenModesBackend;
@@ -43,11 +42,10 @@
Bundle bundle = new Bundle();
bundle.putString(EXTRA_AUTOMATIC_ZEN_RULE_ID, zenMode.getId());
// TODO(b/332937635): Update metrics category
- preference.setIntent(new SubSettingLauncher(mContext)
- .setDestination(ZenModeDisplayFragment.class.getName())
- .setSourceMetricsCategory(0)
- .setArguments(bundle)
- .toIntent());
+ preference.setIntent(
+ ZenSubSettingLauncher.forModeFragment(mContext, ZenModeDisplayFragment.class,
+ zenMode.getId(), 0).toIntent());
+ preference.setEnabled(zenMode.isEnabled());
}
@Override
diff --git a/src/com/android/settings/notification/modes/ZenModeFragment.java b/src/com/android/settings/notification/modes/ZenModeFragment.java
index 7d7631b..0661284 100644
--- a/src/com/android/settings/notification/modes/ZenModeFragment.java
+++ b/src/com/android/settings/notification/modes/ZenModeFragment.java
@@ -53,12 +53,15 @@
prefControllers.add(new ZenModeHeaderController(context, "header", this));
prefControllers.add(
new ZenModeButtonPreferenceController(context, "activate", this, mBackend));
+ prefControllers.add(new ZenModePreferenceCategoryController(context, "modes_filters"));
prefControllers.add(new ZenModePeopleLinkPreferenceController(
context, "zen_mode_people", mHelperBackend));
prefControllers.add(new ZenModeAppsLinkPreferenceController(
context, "zen_mode_apps", this, mBackend, mHelperBackend));
prefControllers.add(new ZenModeOtherLinkPreferenceController(
context, "zen_other_settings", mHelperBackend));
+ prefControllers.add(
+ new ZenModePreferenceCategoryController(context, "modes_additional_actions"));
prefControllers.add(new ZenModeDisplayLinkPreferenceController(
context, "mode_display_settings", mBackend, mHelperBackend));
prefControllers.add(new ZenModeSetTriggerLinkPreferenceController(context,
diff --git a/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java
index d7bd517..15e0edc 100644
--- a/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java
@@ -70,6 +70,7 @@
ZenSubSettingLauncher.forModeFragment(mContext, ZenModeOtherFragment.class,
zenMode.getId(), 0).toIntent());
+ preference.setEnabled(zenMode.isEnabled());
preference.setSummary(mSummaryHelper.getOtherSoundCategoriesSummary(zenMode));
((CircularIconsPreference) preference).displayIcons(getSoundIcons(zenMode.getPolicy()));
}
diff --git a/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java
index 762cdd5..b5938c6 100644
--- a/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceController.java
@@ -92,6 +92,7 @@
ZenSubSettingLauncher.forModeFragment(mContext, ZenModePeopleFragment.class,
zenMode.getId(), 0).toIntent());
+ preference.setEnabled(zenMode.isEnabled());
preference.setSummary(mSummaryHelper.getPeopleSummary(zenMode.getPolicy()));
((CircularIconsPreference) preference).displayIcons(getPeopleIcons(zenMode.getPolicy()));
}
diff --git a/src/com/android/settings/notification/modes/ZenModePreferenceCategoryController.java b/src/com/android/settings/notification/modes/ZenModePreferenceCategoryController.java
new file mode 100644
index 0000000..6ebcb1f
--- /dev/null
+++ b/src/com/android/settings/notification/modes/ZenModePreferenceCategoryController.java
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+/**
+ * Simple {@link AbstractZenModePreferenceController} used for all {@code PreferenceCategory}
+ * entries in {@link ZenModeFragment} that should be disabled when the mode is disabled.
+ */
+class ZenModePreferenceCategoryController extends AbstractZenModePreferenceController {
+ ZenModePreferenceCategoryController(@NonNull Context context, @NonNull String key) {
+ super(context, key);
+ }
+
+ @Override
+ void updateState(Preference preference, @NonNull ZenMode zenMode) {
+ preference.setEnabled(zenMode.isEnabled());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/modes/CircularIconsPreferenceTest.java b/tests/robotests/src/com/android/settings/notification/modes/CircularIconsPreferenceTest.java
index 73754df..ce23fc4 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/CircularIconsPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/CircularIconsPreferenceTest.java
@@ -226,4 +226,32 @@
mPreference.displayIcons(one);
mPreference.displayIcons(same); // if no exception, wasn't called.
}
+
+ @Test
+ public void setEnabled_afterDisplayIcons_showsEnabledOrDisabledImages() {
+ CircularIconSet<Integer> iconSet = new CircularIconSet<>(ImmutableList.of(1, 2),
+ ColorDrawable::new);
+ bindAndMeasureViewHolder(VIEW_WIDTH);
+ mPreference.displayIcons(iconSet);
+ assertThat(mPreference.getViews()).hasSize(2);
+
+ mPreference.setEnabled(false);
+ assertThat(mPreference.getViews().get(0).getAlpha()).isLessThan(1f);
+
+ mPreference.setEnabled(true);
+ assertThat(mPreference.getViews().get(0).getAlpha()).isEqualTo(1f);
+ }
+
+ @Test
+ public void setEnabled_beforeDisplayIcons_showsEnabledOrDisabledImages() {
+ CircularIconSet<Integer> iconSet = new CircularIconSet<>(ImmutableList.of(1, 2),
+ ColorDrawable::new);
+
+ mPreference.setEnabled(false);
+ bindAndMeasureViewHolder(VIEW_WIDTH);
+ mPreference.displayIcons(iconSet);
+
+ assertThat(mPreference.getViews()).hasSize(2);
+ assertThat(mPreference.getViews().get(0).getAlpha()).isLessThan(1f);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/notification/modes/InterruptionFilterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/InterruptionFilterPreferenceControllerTest.java
index 61d3192..0c3f8e1 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/InterruptionFilterPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/InterruptionFilterPreferenceControllerTest.java
@@ -68,6 +68,18 @@
}
@Test
+ public void testUpdateState_disabled() {
+ TwoStatePreference preference = mock(TwoStatePreference.class);
+ ZenMode zenMode = new TestModeBuilder()
+ .setEnabled(false)
+ .build();
+
+ mController.updateZenMode(preference, zenMode);
+
+ verify(preference).setEnabled(false);
+ }
+
+ @Test
public void testUpdateState_all() {
TwoStatePreference preference = mock(TwoStatePreference.class);
ZenMode zenMode = new TestModeBuilder()
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java
index cc4d306..301ff90 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java
@@ -142,6 +142,17 @@
}
@Test
+ public void testUpdateState_disabled() {
+ ZenMode zenMode = new TestModeBuilder()
+ .setEnabled(false)
+ .build();
+
+ mController.updateState(mPreference, zenMode);
+
+ assertThat(mPreference.isEnabled()).isFalse();
+ }
+
+ @Test
public void testUpdateSetsIntent() {
// Create a zen mode that allows priority channels to breakthrough.
ZenMode zenMode = createPriorityChannelsZenMode();
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceControllerTest.java
index 6c3d74f..29350f6 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeDisplayLinkPreferenceControllerTest.java
@@ -28,6 +28,7 @@
import androidx.preference.Preference;
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;
@@ -62,6 +63,18 @@
}
@Test
+ public void testUpdateState_disabled() {
+ Preference preference = mock(Preference.class);
+ ZenMode zenMode = new TestModeBuilder()
+ .setEnabled(false)
+ .build();
+
+ mController.updateState(preference, zenMode);
+
+ verify(preference).setEnabled(false);
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_MODES_UI)
public void testHasSummary() {
Preference pref = mock(Preference.class);
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceControllerTest.java
index 7fa4f9f..8aa87e6 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceControllerTest.java
@@ -62,6 +62,18 @@
}
@Test
+ public void updateState_disabled() {
+ CircularIconsPreference pref = mock(CircularIconsPreference.class);
+ ZenMode zenMode = new TestModeBuilder()
+ .setEnabled(false)
+ .build();
+
+ mController.updateZenMode(pref, zenMode);
+
+ verify(pref).setEnabled(false);
+ }
+
+ @Test
public void updateState_loadsSummary() {
CircularIconsPreference pref = mock(CircularIconsPreference.class);
mController.updateZenMode(pref, TestModeBuilder.EXAMPLE);
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceControllerTest.java
index 8ec980d..63068fa 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModePeopleLinkPreferenceControllerTest.java
@@ -112,6 +112,17 @@
}
@Test
+ public void updateState_disabled() {
+ ZenMode zenMode = new TestModeBuilder()
+ .setEnabled(false)
+ .build();
+
+ mController.updateState(mPreference, zenMode);
+
+ assertThat(mPreference.isEnabled()).isFalse();
+ }
+
+ @Test
public void updateState_setsSummary() {
mController.updateState(mPreference, TestModeBuilder.EXAMPLE);