Add support for rules with filter=ALL in ZenModesBackend
This is represented as an extra, special value for the AllowChannels field in ZenPolicy, with special treatment. Bug: 327419222 Bug: 331267485 Test: atest ZenModeTest Flag: android.app.modes_ui Change-Id: I44440e40e729d295150b36beda824ddbfa1f170d
This commit is contained in:
@@ -16,10 +16,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 java.util.Objects.requireNonNull;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AutomaticZenRule;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
@@ -50,11 +52,25 @@ class ZenMode {
|
||||
|
||||
private static final String TAG = "ZenMode";
|
||||
|
||||
/**
|
||||
* Additional value for the {@code @ZenPolicy.ChannelType} enumeration that indicates that all
|
||||
* channels can bypass DND when this policy is active.
|
||||
*
|
||||
* <p>This value shouldn't be used on "real" ZenPolicy objects sent to or returned from
|
||||
* {@link android.app.NotificationManager}; it's a way of representing rules with interruption
|
||||
* filter = {@link NotificationManager#INTERRUPTION_FILTER_ALL} in the UI.
|
||||
*/
|
||||
public static final int CHANNEL_POLICY_ALL = -1;
|
||||
|
||||
static final String MANUAL_DND_MODE_ID = "manual_dnd";
|
||||
|
||||
@SuppressLint("WrongConstant")
|
||||
private static final ZenPolicy POLICY_INTERRUPTION_FILTER_ALL =
|
||||
// TODO: b/331267485 - Support "allow all channels"!
|
||||
new ZenPolicy.Builder().allowAllSounds().showAllVisualEffects().build();
|
||||
new ZenPolicy.Builder()
|
||||
.allowChannels(CHANNEL_POLICY_ALL)
|
||||
.allowAllSounds()
|
||||
.showAllVisualEffects()
|
||||
.build();
|
||||
|
||||
// Must match com.android.server.notification.ZenModeHelper#applyCustomPolicy.
|
||||
private static final ZenPolicy POLICY_INTERRUPTION_FILTER_ALARMS =
|
||||
@@ -75,9 +91,11 @@ class ZenMode {
|
||||
|
||||
private final String mId;
|
||||
private final AutomaticZenRule mRule;
|
||||
private boolean mIsActive;
|
||||
private final boolean mIsActive;
|
||||
private final boolean mIsManualDnd;
|
||||
|
||||
// private ZenPolicy mPreviousPolicy;
|
||||
|
||||
ZenMode(String id, AutomaticZenRule rule, boolean isActive) {
|
||||
this(id, rule, isActive, false);
|
||||
}
|
||||
@@ -172,14 +190,48 @@ class ZenMode {
|
||||
}
|
||||
}
|
||||
|
||||
public void setZenPolicy(@NonNull ZenPolicy policy) {
|
||||
// TODO: b/331267485 - A policy with apps=ALL should be mapped to INTERRUPTION_FILTER_ALL.
|
||||
if (mRule.getInterruptionFilter() != INTERRUPTION_FILTER_PRIORITY) {
|
||||
/**
|
||||
* Updates the {@link ZenPolicy} of the associated {@link AutomaticZenRule} based on the
|
||||
* supplied policy. In some cases this involves conversions, so that the following call
|
||||
* to {@link #getPolicy} might return a different policy from the one supplied here.
|
||||
*/
|
||||
@SuppressLint("WrongConstant")
|
||||
public void setPolicy(@NonNull ZenPolicy policy) {
|
||||
ZenPolicy currentPolicy = getPolicy();
|
||||
if (!currentPolicy.equals(policy)) {
|
||||
// If policy is customized from any of the "special" ones, make the rule PRIORITY.
|
||||
mRule.setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY);
|
||||
if (currentPolicy.equals(policy)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// A policy with CHANNEL_POLICY_ALL is only a UI representation of the
|
||||
// INTERRUPTION_FILTER_ALL filter. Thus, switching to or away to this value only updates
|
||||
// the filter, discarding the rest of the supplied policy.
|
||||
if (policy.getAllowedChannels() == CHANNEL_POLICY_ALL
|
||||
&& currentPolicy.getAllowedChannels() != CHANNEL_POLICY_ALL) {
|
||||
if (mIsManualDnd) {
|
||||
throw new IllegalArgumentException("Manual DND cannot have CHANNEL_POLICY_ALL");
|
||||
}
|
||||
mRule.setInterruptionFilter(INTERRUPTION_FILTER_ALL);
|
||||
// Preserve the existing policy, e.g. if the user goes PRIORITY -> ALL -> PRIORITY that
|
||||
// shouldn't discard all other policy customizations. The existing policy will be a
|
||||
// synthetic one if the rule originally had filter NONE or ALARMS_ONLY and that's fine.
|
||||
if (mRule.getZenPolicy() == null) {
|
||||
mRule.setZenPolicy(currentPolicy);
|
||||
}
|
||||
return;
|
||||
} else if (policy.getAllowedChannels() != CHANNEL_POLICY_ALL
|
||||
&& currentPolicy.getAllowedChannels() == CHANNEL_POLICY_ALL) {
|
||||
mRule.setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY);
|
||||
// Go back to whatever policy the rule had before, unless the rule never had one, in
|
||||
// which case we use the supplied policy (which we know has a valid allowedChannels).
|
||||
if (mRule.getZenPolicy() == null) {
|
||||
mRule.setZenPolicy(policy);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If policy is customized from any of the "special" ones, make the rule PRIORITY.
|
||||
if (mRule.getInterruptionFilter() != INTERRUPTION_FILTER_PRIORITY) {
|
||||
mRule.setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY);
|
||||
}
|
||||
mRule.setZenPolicy(policy);
|
||||
}
|
||||
@@ -206,7 +258,7 @@ class ZenMode {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mId, mRule);
|
||||
return Objects.hash(mId, mRule, mIsActive);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -61,7 +61,7 @@ public class ZenModeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getZenPolicy_interruptionFilterPriority_returnsZenPolicy() {
|
||||
public void getPolicy_interruptionFilterPriority_returnsZenPolicy() {
|
||||
ZenMode zenMode = new ZenMode("id", new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
|
||||
.setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
|
||||
.setZenPolicy(ZEN_POLICY)
|
||||
@@ -71,18 +71,19 @@ public class ZenModeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getZenPolicy_interruptionFilterAll_returnsPolicyAllowingAll() {
|
||||
public void getPolicy_interruptionFilterAll_returnsPolicyAllowingAll() {
|
||||
ZenMode zenMode = new ZenMode("id", new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
|
||||
.setInterruptionFilter(INTERRUPTION_FILTER_ALL)
|
||||
.setZenPolicy(ZEN_POLICY) // should be ignored
|
||||
.build(), false);
|
||||
|
||||
assertThat(zenMode.getPolicy()).isEqualTo(
|
||||
new ZenPolicy.Builder().allowAllSounds().showAllVisualEffects().build());
|
||||
new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL)
|
||||
.allowAllSounds().showAllVisualEffects().build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getZenPolicy_interruptionFilterAlarms_returnsPolicyAllowingAlarms() {
|
||||
public void getPolicy_interruptionFilterAlarms_returnsPolicyAllowingAlarms() {
|
||||
ZenMode zenMode = new ZenMode("id", new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
|
||||
.setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
|
||||
.setZenPolicy(ZEN_POLICY) // should be ignored
|
||||
@@ -98,7 +99,7 @@ public class ZenModeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getZenPolicy_interruptionFilterNone_returnsPolicyAllowingNothing() {
|
||||
public void getPolicy_interruptionFilterNone_returnsPolicyAllowingNothing() {
|
||||
ZenMode zenMode = new ZenMode("id", new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
|
||||
.setInterruptionFilter(INTERRUPTION_FILTER_NONE)
|
||||
.setZenPolicy(ZEN_POLICY) // should be ignored
|
||||
@@ -111,4 +112,83 @@ public class ZenModeTest {
|
||||
.allowPriorityChannels(false)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setPolicy_setsInterruptionFilterPriority() {
|
||||
ZenMode zenMode = new ZenMode("id", new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
|
||||
.setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
|
||||
.build(), false);
|
||||
|
||||
zenMode.setPolicy(ZEN_POLICY);
|
||||
|
||||
assertThat(zenMode.getRule().getInterruptionFilter()).isEqualTo(
|
||||
INTERRUPTION_FILTER_PRIORITY);
|
||||
assertThat(zenMode.getPolicy()).isEqualTo(ZEN_POLICY);
|
||||
assertThat(zenMode.getRule().getZenPolicy()).isEqualTo(ZEN_POLICY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setPolicy_withAllChannelsAllowed_setsInterruptionFilterAll() {
|
||||
ZenMode zenMode = new ZenMode("id", new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
|
||||
.setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
|
||||
.setZenPolicy(ZEN_POLICY)
|
||||
.build(), false);
|
||||
|
||||
zenMode.setPolicy(
|
||||
new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL).build());
|
||||
|
||||
assertThat(zenMode.getRule().getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_ALL);
|
||||
assertThat(zenMode.getPolicy()).isEqualTo(
|
||||
new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL)
|
||||
.allowAllSounds().showAllVisualEffects().build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setPolicy_priorityToAllChannelsAndBack_restoresOldPolicy() {
|
||||
ZenMode zenMode = new ZenMode("id", new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
|
||||
.setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
|
||||
.setZenPolicy(ZEN_POLICY)
|
||||
.build(), false);
|
||||
|
||||
zenMode.setPolicy(
|
||||
new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL).build());
|
||||
assertThat(zenMode.getRule().getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_ALL);
|
||||
assertThat(zenMode.getPolicy()).isEqualTo(
|
||||
new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL)
|
||||
.allowAllSounds().showAllVisualEffects().build());
|
||||
|
||||
zenMode.setPolicy(
|
||||
new ZenPolicy.Builder().allowChannels(ZenPolicy.CHANNEL_POLICY_PRIORITY).build());
|
||||
|
||||
assertThat(zenMode.getRule().getInterruptionFilter()).isEqualTo(
|
||||
INTERRUPTION_FILTER_PRIORITY);
|
||||
assertThat(zenMode.getPolicy()).isEqualTo(ZEN_POLICY);
|
||||
assertThat(zenMode.getRule().getZenPolicy()).isEqualTo(ZEN_POLICY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setPolicy_alarmsOnlyToAllChannelsAndBack_restoresPolicySimilarToAlarmsOnly() {
|
||||
ZenMode zenMode = new ZenMode("id", new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
|
||||
.setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
|
||||
.build(), false);
|
||||
|
||||
zenMode.setPolicy(
|
||||
new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL).build());
|
||||
assertThat(zenMode.getRule().getInterruptionFilter()).isEqualTo(INTERRUPTION_FILTER_ALL);
|
||||
assertThat(zenMode.getPolicy()).isEqualTo(
|
||||
new ZenPolicy.Builder().allowChannels(ZenMode.CHANNEL_POLICY_ALL)
|
||||
.allowAllSounds().showAllVisualEffects().build());
|
||||
|
||||
zenMode.setPolicy(
|
||||
new ZenPolicy.Builder().allowChannels(ZenPolicy.CHANNEL_POLICY_PRIORITY).build());
|
||||
|
||||
// We don't go back to ALARMS, but the policy must be the one the user was seeing before.
|
||||
ZenPolicy alarmsOnlyLikePolicy = new ZenPolicy.Builder().disallowAllSounds()
|
||||
.allowAlarms(true).allowMedia(true).allowPriorityChannels(false)
|
||||
.build();
|
||||
assertThat(zenMode.getRule().getInterruptionFilter()).isEqualTo(
|
||||
INTERRUPTION_FILTER_PRIORITY);
|
||||
assertThat(zenMode.getPolicy()).isEqualTo(alarmsOnlyLikePolicy);
|
||||
assertThat(zenMode.getRule().getZenPolicy()).isEqualTo(alarmsOnlyLikePolicy);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user