Merge "Disable all preferences (except toggle) when a mode is disabled" into main

This commit is contained in:
Matías Hernández
2024-07-24 22:56:40 +00:00
committed by Android (Google) Code Review
14 changed files with 172 additions and 12 deletions

View File

@@ -51,6 +51,8 @@ import java.util.concurrent.Executor;
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 @@ public class CircularIconsPreference extends RestrictedPreference {
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 @@ public class CircularIconsPreference extends RestrictedPreference {
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 @@ public class CircularIconsPreference extends RestrictedPreference {
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,
@@ -249,6 +268,18 @@ public class CircularIconsPreference extends RestrictedPreference {
return parent.getChildAt(parent.getChildCount() - 1);
}
@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) {

View File

@@ -44,6 +44,7 @@ class InterruptionFilterPreferenceController extends AbstractZenModePreferenceCo
@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);

View File

@@ -34,7 +34,6 @@ import androidx.preference.Preference;
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 @@ class ZenModeAppsLinkPreferenceController extends AbstractZenModePreferenceContr
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;

View File

@@ -24,7 +24,6 @@ import android.os.Bundle;
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 @@ class ZenModeDisplayLinkPreferenceController extends AbstractZenModePreferenceCo
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

View File

@@ -53,12 +53,15 @@ public class ZenModeFragment extends ZenModeFragmentBase {
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,

View File

@@ -70,6 +70,7 @@ class ZenModeOtherLinkPreferenceController extends AbstractZenModePreferenceCont
ZenSubSettingLauncher.forModeFragment(mContext, ZenModeOtherFragment.class,
zenMode.getId(), 0).toIntent());
preference.setEnabled(zenMode.isEnabled());
preference.setSummary(mSummaryHelper.getOtherSoundCategoriesSummary(zenMode));
((CircularIconsPreference) preference).displayIcons(getSoundIcons(zenMode.getPolicy()));
}

View File

@@ -92,6 +92,7 @@ class ZenModePeopleLinkPreferenceController extends AbstractZenModePreferenceCon
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()));
}

View File

@@ -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());
}
}

View File

@@ -226,4 +226,32 @@ public class CircularIconsPreferenceTest {
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);
}
}

View File

@@ -67,6 +67,18 @@ public final class InterruptionFilterPreferenceControllerTest {
mController = new InterruptionFilterPreferenceController(mContext, "something", mBackend);
}
@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);

View File

@@ -141,6 +141,17 @@ public final class ZenModeAppsLinkPreferenceControllerTest {
assertThat(mController.isAvailable()).isTrue();
}
@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.

View File

@@ -28,6 +28,7 @@ import android.platform.test.flag.junit.SetFlagsRule;
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;
@@ -61,6 +62,18 @@ public final class ZenModeDisplayLinkPreferenceControllerTest {
mContext, "something", mBackend, mHelperBackend);
}
@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() {

View File

@@ -61,6 +61,18 @@ public final class ZenModeOtherLinkPreferenceControllerTest {
mContext, "something", mHelperBackend);
}
@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);

View File

@@ -111,6 +111,17 @@ public final class ZenModePeopleLinkPreferenceControllerTest {
anyBoolean())).thenReturn(new ColorDrawable(Color.BLACK));
}
@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);