Loading core/api/test-current.txt +8 −0 Original line number Diff line number Diff line Loading @@ -3056,6 +3056,14 @@ package android.service.notification { method @Deprecated public boolean isBound(); } @FlaggedApi("android.app.modes_api") public final class ZenDeviceEffects implements android.os.Parcelable { method @NonNull public java.util.Set<java.lang.String> getExtraEffects(); } @FlaggedApi("android.app.modes_api") public static final class ZenDeviceEffects.Builder { method @NonNull public android.service.notification.ZenDeviceEffects.Builder setExtraEffects(@NonNull java.util.Set<java.lang.String>); } public final class ZenPolicy implements android.os.Parcelable { method @FlaggedApi("android.app.modes_api") @NonNull public android.service.notification.ZenPolicy overwrittenWith(@Nullable android.service.notification.ZenPolicy); } Loading core/java/android/app/AutomaticZenRule.java +3 −0 Original line number Diff line number Diff line Loading @@ -487,6 +487,9 @@ public final class AutomaticZenRule implements Parcelable { public void validate() { if (Flags.modesApi()) { checkValidType(mType); if (mDeviceEffects != null) { mDeviceEffects.validate(); } } } Loading core/java/android/service/notification/ZenDeviceEffects.java +109 −9 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; import android.app.Flags; import android.os.Parcel; import android.os.Parcelable; Loading @@ -27,7 +28,10 @@ import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Objects; import java.util.Set; /** * Represents the set of device effects (affecting display and device behavior in general) that Loading @@ -51,6 +55,7 @@ public final class ZenDeviceEffects implements Parcelable { FIELD_DISABLE_TOUCH, FIELD_MINIMIZE_RADIO_USAGE, FIELD_MAXIMIZE_DOZE, FIELD_EXTRA_EFFECTS }) @Retention(RetentionPolicy.SOURCE) public @interface ModifiableField {} Loading Loading @@ -95,6 +100,12 @@ public final class ZenDeviceEffects implements Parcelable { * @hide */ public static final int FIELD_MAXIMIZE_DOZE = 1 << 9; /** * @hide */ public static final int FIELD_EXTRA_EFFECTS = 1 << 10; private static final int MAX_EFFECTS_LENGTH = 2_000; // characters private final boolean mGrayscale; private final boolean mSuppressAmbientDisplay; Loading @@ -107,11 +118,12 @@ public final class ZenDeviceEffects implements Parcelable { private final boolean mDisableTouch; private final boolean mMinimizeRadioUsage; private final boolean mMaximizeDoze; private final Set<String> mExtraEffects; private ZenDeviceEffects(boolean grayscale, boolean suppressAmbientDisplay, boolean dimWallpaper, boolean nightMode, boolean disableAutoBrightness, boolean disableTapToWake, boolean disableTiltToWake, boolean disableTouch, boolean minimizeRadioUsage, boolean maximizeDoze) { boolean minimizeRadioUsage, boolean maximizeDoze, Set<String> extraEffects) { mGrayscale = grayscale; mSuppressAmbientDisplay = suppressAmbientDisplay; mDimWallpaper = dimWallpaper; Loading @@ -122,6 +134,21 @@ public final class ZenDeviceEffects implements Parcelable { mDisableTouch = disableTouch; mMinimizeRadioUsage = minimizeRadioUsage; mMaximizeDoze = maximizeDoze; mExtraEffects = Collections.unmodifiableSet(extraEffects); } /** @hide */ @FlaggedApi(Flags.FLAG_MODES_API) public void validate() { int extraEffectsLength = 0; for (String extraEffect : mExtraEffects) { extraEffectsLength += extraEffect.length(); } if (extraEffectsLength > MAX_EFFECTS_LENGTH) { throw new IllegalArgumentException( "Total size of extra effects must be at most " + MAX_EFFECTS_LENGTH + " characters"); } } @Override Loading @@ -138,19 +165,20 @@ public final class ZenDeviceEffects implements Parcelable { && this.mDisableTiltToWake == that.mDisableTiltToWake && this.mDisableTouch == that.mDisableTouch && this.mMinimizeRadioUsage == that.mMinimizeRadioUsage && this.mMaximizeDoze == that.mMaximizeDoze; && this.mMaximizeDoze == that.mMaximizeDoze && Objects.equals(this.mExtraEffects, that.mExtraEffects); } @Override public int hashCode() { return Objects.hash(mGrayscale, mSuppressAmbientDisplay, mDimWallpaper, mNightMode, mDisableAutoBrightness, mDisableTapToWake, mDisableTiltToWake, mDisableTouch, mMinimizeRadioUsage, mMaximizeDoze); mMinimizeRadioUsage, mMaximizeDoze, mExtraEffects); } @Override public String toString() { ArrayList<String> effects = new ArrayList<>(10); ArrayList<String> effects = new ArrayList<>(11); if (mGrayscale) effects.add("grayscale"); if (mSuppressAmbientDisplay) effects.add("suppressAmbientDisplay"); if (mDimWallpaper) effects.add("dimWallpaper"); Loading @@ -161,6 +189,9 @@ public final class ZenDeviceEffects implements Parcelable { if (mDisableTouch) effects.add("disableTouch"); if (mMinimizeRadioUsage) effects.add("minimizeRadioUsage"); if (mMaximizeDoze) effects.add("maximizeDoze"); if (mExtraEffects.size() > 0) { effects.add("extraEffects=[" + String.join(",", mExtraEffects) + "]"); } return "[" + String.join(", ", effects) + "]"; } Loading Loading @@ -197,6 +228,9 @@ public final class ZenDeviceEffects implements Parcelable { if ((bitmask & FIELD_MAXIMIZE_DOZE) != 0) { modified.add("FIELD_MAXIMIZE_DOZE"); } if ((bitmask & FIELD_EXTRA_EFFECTS) != 0) { modified.add("FIELD_EXTRA_EFFECTS"); } return "{" + String.join(",", modified) + "}"; } Loading Loading @@ -270,7 +304,7 @@ public final class ZenDeviceEffects implements Parcelable { } /** * Whether Doze should be enhanced (e.g. with more aggresive activation, or less frequent * Whether Doze should be enhanced (e.g. with more aggressive activation, or less frequent * maintenance windows) while the rule is active. * @hide */ Loading @@ -278,6 +312,18 @@ public final class ZenDeviceEffects implements Parcelable { return mMaximizeDoze; } /** * (Immutable) set of extra effects to be applied while the rule is active. Extra effects are * not used in AOSP, but OEMs may add support for them by providing a custom * {@link DeviceEffectsApplier}. * @hide */ @TestApi @NonNull public Set<String> getExtraEffects() { return mExtraEffects; } /** * Whether any of the effects are set up. * @hide Loading @@ -285,7 +331,8 @@ public final class ZenDeviceEffects implements Parcelable { public boolean hasEffects() { return mGrayscale || mSuppressAmbientDisplay || mDimWallpaper || mNightMode || mDisableAutoBrightness || mDisableTapToWake || mDisableTiltToWake || mDisableTouch || mMinimizeRadioUsage || mMaximizeDoze; || mDisableTouch || mMinimizeRadioUsage || mMaximizeDoze || mExtraEffects.size() > 0; } /** {@link Parcelable.Creator} that instantiates {@link ZenDeviceEffects} objects. */ Loading @@ -296,7 +343,8 @@ public final class ZenDeviceEffects implements Parcelable { return new ZenDeviceEffects(in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean()); in.readBoolean(), Set.of(in.readArray(String.class.getClassLoader(), String.class))); } @Override Loading @@ -322,6 +370,7 @@ public final class ZenDeviceEffects implements Parcelable { dest.writeBoolean(mDisableTouch); dest.writeBoolean(mMinimizeRadioUsage); dest.writeBoolean(mMaximizeDoze); dest.writeArray(mExtraEffects.toArray(new String[0])); } /** Builder class for {@link ZenDeviceEffects} objects. */ Loading @@ -338,6 +387,7 @@ public final class ZenDeviceEffects implements Parcelable { private boolean mDisableTouch; private boolean mMinimizeRadioUsage; private boolean mMaximizeDoze; private final HashSet<String> mExtraEffects = new HashSet<>(); /** * Instantiates a new {@link ZenPolicy.Builder} with all effects set to default (disabled). Loading @@ -360,6 +410,7 @@ public final class ZenDeviceEffects implements Parcelable { mDisableTouch = zenDeviceEffects.shouldDisableTouch(); mMinimizeRadioUsage = zenDeviceEffects.shouldMinimizeRadioUsage(); mMaximizeDoze = zenDeviceEffects.shouldMaximizeDoze(); mExtraEffects.addAll(zenDeviceEffects.getExtraEffects()); } /** Loading Loading @@ -450,7 +501,7 @@ public final class ZenDeviceEffects implements Parcelable { } /** * Sets whether Doze should be enhanced (e.g. with more aggresive activation, or less * Sets whether Doze should be enhanced (e.g. with more aggressive activation, or less * frequent maintenance windows) while the rule is active. * @hide */ Loading @@ -460,6 +511,54 @@ public final class ZenDeviceEffects implements Parcelable { return this; } /** * Sets the extra effects to be applied while the rule is active. Extra effects are not * used in AOSP, but OEMs may add support for them by providing a custom * {@link DeviceEffectsApplier}. * * @apiNote The total size of the extra effects (concatenation of strings) is limited. * * @hide */ @TestApi @NonNull public Builder setExtraEffects(@NonNull Set<String> extraEffects) { Objects.requireNonNull(extraEffects); mExtraEffects.clear(); mExtraEffects.addAll(extraEffects); return this; } /** * Adds the supplied extra effects to the set to be applied while the rule is active. * Extra effects are not used in AOSP, but OEMs may add support for them by providing a * custom {@link DeviceEffectsApplier}. * * @apiNote The total size of the extra effects (concatenation of strings) is limited. * * @hide */ @NonNull public Builder addExtraEffects(@NonNull Set<String> extraEffects) { mExtraEffects.addAll(Objects.requireNonNull(extraEffects)); return this; } /** * Adds the supplied extra effect to the set to be applied while the rule is active. * Extra effects are not used in AOSP, but OEMs may add support for them by providing a * custom {@link DeviceEffectsApplier}. * * @apiNote The total size of the extra effects (concatenation of strings) is limited. * * @hide */ @NonNull public Builder addExtraEffect(@NonNull String extraEffect) { mExtraEffects.add(Objects.requireNonNull(extraEffect)); return this; } /** * Applies the effects that are {@code true} on the supplied {@link ZenDeviceEffects} to * this builder (essentially logically-ORing the effect set). Loading @@ -478,6 +577,7 @@ public final class ZenDeviceEffects implements Parcelable { if (effects.shouldDisableTouch()) setShouldDisableTouch(true); if (effects.shouldMinimizeRadioUsage()) setShouldMinimizeRadioUsage(true); if (effects.shouldMaximizeDoze()) setShouldMaximizeDoze(true); addExtraEffects(effects.getExtraEffects()); return this; } Loading @@ -487,7 +587,7 @@ public final class ZenDeviceEffects implements Parcelable { return new ZenDeviceEffects(mGrayscale, mSuppressAmbientDisplay, mDimWallpaper, mNightMode, mDisableAutoBrightness, mDisableTapToWake, mDisableTiltToWake, mDisableTouch, mMinimizeRadioUsage, mMaximizeDoze); mMaximizeDoze, mExtraEffects); } } } core/java/android/service/notification/ZenModeConfig.java +52 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OF import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AlarmManager; Loading Loading @@ -65,17 +66,21 @@ import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.TimeZone; import java.util.UUID; import java.util.regex.Pattern; /** * Persisted configuration for zen mode. Loading Loading @@ -272,8 +277,13 @@ public class ZenModeConfig implements Parcelable { private static final String DEVICE_EFFECT_DISABLE_TOUCH = "zdeDisableTouch"; private static final String DEVICE_EFFECT_MINIMIZE_RADIO_USAGE = "zdeMinimizeRadioUsage"; private static final String DEVICE_EFFECT_MAXIMIZE_DOZE = "zdeMaximizeDoze"; private static final String DEVICE_EFFECT_EXTRAS = "zdeExtraEffects"; private static final String DEVICE_EFFECT_USER_MODIFIED_FIELDS = "zdeUserModifiedFields"; private static final String ITEM_SEPARATOR = ","; private static final String ITEM_SEPARATOR_ESCAPE = "\\"; private static final Pattern ITEM_SPLITTER_REGEX = Pattern.compile("(?<!\\\\),"); @UnsupportedAppUsage public boolean allowAlarms = DEFAULT_ALLOW_ALARMS; public boolean allowMedia = DEFAULT_ALLOW_MEDIA; Loading Loading @@ -1099,6 +1109,7 @@ public class ZenModeConfig implements Parcelable { .setShouldMinimizeRadioUsage( safeBoolean(parser, DEVICE_EFFECT_MINIMIZE_RADIO_USAGE, false)) .setShouldMaximizeDoze(safeBoolean(parser, DEVICE_EFFECT_MAXIMIZE_DOZE, false)) .setExtraEffects(safeStringSet(parser, DEVICE_EFFECT_EXTRAS)) .build(); return deviceEffects.hasEffects() ? deviceEffects : null; Loading @@ -1123,6 +1134,7 @@ public class ZenModeConfig implements Parcelable { writeBooleanIfTrue(out, DEVICE_EFFECT_MINIMIZE_RADIO_USAGE, deviceEffects.shouldMinimizeRadioUsage()); writeBooleanIfTrue(out, DEVICE_EFFECT_MAXIMIZE_DOZE, deviceEffects.shouldMaximizeDoze()); writeStringSet(out, DEVICE_EFFECT_EXTRAS, deviceEffects.getExtraEffects()); } private static void writeBooleanIfTrue(TypedXmlSerializer out, String att, boolean value) Loading @@ -1132,6 +1144,26 @@ public class ZenModeConfig implements Parcelable { } } private static void writeStringSet(TypedXmlSerializer out, String att, Set<String> values) throws IOException { if (values.isEmpty()) { return; } // We escape each item by replacing "\" by "\\" and "," by "\,". Then we concatenate with // "," as separator. Reading performs the same operations in the opposite order. List<String> escapedItems = new ArrayList<>(); for (String item : values) { escapedItems.add( item .replace(ITEM_SEPARATOR_ESCAPE, ITEM_SEPARATOR_ESCAPE + ITEM_SEPARATOR_ESCAPE) .replace(ITEM_SEPARATOR, ITEM_SEPARATOR_ESCAPE + ITEM_SEPARATOR)); } String serialized = String.join(ITEM_SEPARATOR, escapedItems); out.attribute(null, att, serialized); } public static boolean isValidHour(int val) { return val >= 0 && val < 24; } Loading Loading @@ -1182,6 +1214,26 @@ public class ZenModeConfig implements Parcelable { return tryParseLong(val, defValue); } @NonNull private static Set<String> safeStringSet(TypedXmlPullParser parser, String att) { Set<String> values = new HashSet<>(); String serialized = parser.getAttributeValue(null, att); if (!TextUtils.isEmpty(serialized)) { // We split on every "," that is *not preceded* by the escape character "\". // Then we reverse the escaping done on each individual item. String[] escapedItems = ITEM_SPLITTER_REGEX.split(serialized); for (String escapedItem : escapedItems) { values.add(escapedItem .replace(ITEM_SEPARATOR_ESCAPE + ITEM_SEPARATOR_ESCAPE, ITEM_SEPARATOR_ESCAPE) .replace(ITEM_SEPARATOR_ESCAPE + ITEM_SEPARATOR, ITEM_SEPARATOR)); } } return values; } @Override public int describeContents() { return 0; Loading services/core/java/com/android/server/notification/ZenModeHelper.java +5 −1 Original line number Diff line number Diff line Loading @@ -1264,7 +1264,7 @@ public class ZenModeHelper { : new ZenDeviceEffects.Builder().build(); if (isFromApp) { // Don't allow apps to toggle hidden effects. // Don't allow apps to toggle hidden (non-public-API) effects. newEffects = new ZenDeviceEffects.Builder(newEffects) .setShouldDisableAutoBrightness(oldEffects.shouldDisableAutoBrightness()) .setShouldDisableTapToWake(oldEffects.shouldDisableTapToWake()) Loading @@ -1272,6 +1272,7 @@ public class ZenModeHelper { .setShouldDisableTouch(oldEffects.shouldDisableTouch()) .setShouldMinimizeRadioUsage(oldEffects.shouldMinimizeRadioUsage()) .setShouldMaximizeDoze(oldEffects.shouldMaximizeDoze()) .setExtraEffects(oldEffects.getExtraEffects()) .build(); } Loading Loading @@ -1311,6 +1312,9 @@ public class ZenModeHelper { if (oldEffects.shouldMaximizeDoze() != newEffects.shouldMaximizeDoze()) { userModifiedFields |= ZenDeviceEffects.FIELD_MAXIMIZE_DOZE; } if (!Objects.equals(oldEffects.getExtraEffects(), newEffects.getExtraEffects())) { userModifiedFields |= ZenDeviceEffects.FIELD_EXTRA_EFFECTS; } zenRule.zenDeviceEffectsUserModifiedFields = userModifiedFields; } } Loading Loading
core/api/test-current.txt +8 −0 Original line number Diff line number Diff line Loading @@ -3056,6 +3056,14 @@ package android.service.notification { method @Deprecated public boolean isBound(); } @FlaggedApi("android.app.modes_api") public final class ZenDeviceEffects implements android.os.Parcelable { method @NonNull public java.util.Set<java.lang.String> getExtraEffects(); } @FlaggedApi("android.app.modes_api") public static final class ZenDeviceEffects.Builder { method @NonNull public android.service.notification.ZenDeviceEffects.Builder setExtraEffects(@NonNull java.util.Set<java.lang.String>); } public final class ZenPolicy implements android.os.Parcelable { method @FlaggedApi("android.app.modes_api") @NonNull public android.service.notification.ZenPolicy overwrittenWith(@Nullable android.service.notification.ZenPolicy); } Loading
core/java/android/app/AutomaticZenRule.java +3 −0 Original line number Diff line number Diff line Loading @@ -487,6 +487,9 @@ public final class AutomaticZenRule implements Parcelable { public void validate() { if (Flags.modesApi()) { checkValidType(mType); if (mDeviceEffects != null) { mDeviceEffects.validate(); } } } Loading
core/java/android/service/notification/ZenDeviceEffects.java +109 −9 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; import android.app.Flags; import android.os.Parcel; import android.os.Parcelable; Loading @@ -27,7 +28,10 @@ import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Objects; import java.util.Set; /** * Represents the set of device effects (affecting display and device behavior in general) that Loading @@ -51,6 +55,7 @@ public final class ZenDeviceEffects implements Parcelable { FIELD_DISABLE_TOUCH, FIELD_MINIMIZE_RADIO_USAGE, FIELD_MAXIMIZE_DOZE, FIELD_EXTRA_EFFECTS }) @Retention(RetentionPolicy.SOURCE) public @interface ModifiableField {} Loading Loading @@ -95,6 +100,12 @@ public final class ZenDeviceEffects implements Parcelable { * @hide */ public static final int FIELD_MAXIMIZE_DOZE = 1 << 9; /** * @hide */ public static final int FIELD_EXTRA_EFFECTS = 1 << 10; private static final int MAX_EFFECTS_LENGTH = 2_000; // characters private final boolean mGrayscale; private final boolean mSuppressAmbientDisplay; Loading @@ -107,11 +118,12 @@ public final class ZenDeviceEffects implements Parcelable { private final boolean mDisableTouch; private final boolean mMinimizeRadioUsage; private final boolean mMaximizeDoze; private final Set<String> mExtraEffects; private ZenDeviceEffects(boolean grayscale, boolean suppressAmbientDisplay, boolean dimWallpaper, boolean nightMode, boolean disableAutoBrightness, boolean disableTapToWake, boolean disableTiltToWake, boolean disableTouch, boolean minimizeRadioUsage, boolean maximizeDoze) { boolean minimizeRadioUsage, boolean maximizeDoze, Set<String> extraEffects) { mGrayscale = grayscale; mSuppressAmbientDisplay = suppressAmbientDisplay; mDimWallpaper = dimWallpaper; Loading @@ -122,6 +134,21 @@ public final class ZenDeviceEffects implements Parcelable { mDisableTouch = disableTouch; mMinimizeRadioUsage = minimizeRadioUsage; mMaximizeDoze = maximizeDoze; mExtraEffects = Collections.unmodifiableSet(extraEffects); } /** @hide */ @FlaggedApi(Flags.FLAG_MODES_API) public void validate() { int extraEffectsLength = 0; for (String extraEffect : mExtraEffects) { extraEffectsLength += extraEffect.length(); } if (extraEffectsLength > MAX_EFFECTS_LENGTH) { throw new IllegalArgumentException( "Total size of extra effects must be at most " + MAX_EFFECTS_LENGTH + " characters"); } } @Override Loading @@ -138,19 +165,20 @@ public final class ZenDeviceEffects implements Parcelable { && this.mDisableTiltToWake == that.mDisableTiltToWake && this.mDisableTouch == that.mDisableTouch && this.mMinimizeRadioUsage == that.mMinimizeRadioUsage && this.mMaximizeDoze == that.mMaximizeDoze; && this.mMaximizeDoze == that.mMaximizeDoze && Objects.equals(this.mExtraEffects, that.mExtraEffects); } @Override public int hashCode() { return Objects.hash(mGrayscale, mSuppressAmbientDisplay, mDimWallpaper, mNightMode, mDisableAutoBrightness, mDisableTapToWake, mDisableTiltToWake, mDisableTouch, mMinimizeRadioUsage, mMaximizeDoze); mMinimizeRadioUsage, mMaximizeDoze, mExtraEffects); } @Override public String toString() { ArrayList<String> effects = new ArrayList<>(10); ArrayList<String> effects = new ArrayList<>(11); if (mGrayscale) effects.add("grayscale"); if (mSuppressAmbientDisplay) effects.add("suppressAmbientDisplay"); if (mDimWallpaper) effects.add("dimWallpaper"); Loading @@ -161,6 +189,9 @@ public final class ZenDeviceEffects implements Parcelable { if (mDisableTouch) effects.add("disableTouch"); if (mMinimizeRadioUsage) effects.add("minimizeRadioUsage"); if (mMaximizeDoze) effects.add("maximizeDoze"); if (mExtraEffects.size() > 0) { effects.add("extraEffects=[" + String.join(",", mExtraEffects) + "]"); } return "[" + String.join(", ", effects) + "]"; } Loading Loading @@ -197,6 +228,9 @@ public final class ZenDeviceEffects implements Parcelable { if ((bitmask & FIELD_MAXIMIZE_DOZE) != 0) { modified.add("FIELD_MAXIMIZE_DOZE"); } if ((bitmask & FIELD_EXTRA_EFFECTS) != 0) { modified.add("FIELD_EXTRA_EFFECTS"); } return "{" + String.join(",", modified) + "}"; } Loading Loading @@ -270,7 +304,7 @@ public final class ZenDeviceEffects implements Parcelable { } /** * Whether Doze should be enhanced (e.g. with more aggresive activation, or less frequent * Whether Doze should be enhanced (e.g. with more aggressive activation, or less frequent * maintenance windows) while the rule is active. * @hide */ Loading @@ -278,6 +312,18 @@ public final class ZenDeviceEffects implements Parcelable { return mMaximizeDoze; } /** * (Immutable) set of extra effects to be applied while the rule is active. Extra effects are * not used in AOSP, but OEMs may add support for them by providing a custom * {@link DeviceEffectsApplier}. * @hide */ @TestApi @NonNull public Set<String> getExtraEffects() { return mExtraEffects; } /** * Whether any of the effects are set up. * @hide Loading @@ -285,7 +331,8 @@ public final class ZenDeviceEffects implements Parcelable { public boolean hasEffects() { return mGrayscale || mSuppressAmbientDisplay || mDimWallpaper || mNightMode || mDisableAutoBrightness || mDisableTapToWake || mDisableTiltToWake || mDisableTouch || mMinimizeRadioUsage || mMaximizeDoze; || mDisableTouch || mMinimizeRadioUsage || mMaximizeDoze || mExtraEffects.size() > 0; } /** {@link Parcelable.Creator} that instantiates {@link ZenDeviceEffects} objects. */ Loading @@ -296,7 +343,8 @@ public final class ZenDeviceEffects implements Parcelable { return new ZenDeviceEffects(in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean(), in.readBoolean()); in.readBoolean(), Set.of(in.readArray(String.class.getClassLoader(), String.class))); } @Override Loading @@ -322,6 +370,7 @@ public final class ZenDeviceEffects implements Parcelable { dest.writeBoolean(mDisableTouch); dest.writeBoolean(mMinimizeRadioUsage); dest.writeBoolean(mMaximizeDoze); dest.writeArray(mExtraEffects.toArray(new String[0])); } /** Builder class for {@link ZenDeviceEffects} objects. */ Loading @@ -338,6 +387,7 @@ public final class ZenDeviceEffects implements Parcelable { private boolean mDisableTouch; private boolean mMinimizeRadioUsage; private boolean mMaximizeDoze; private final HashSet<String> mExtraEffects = new HashSet<>(); /** * Instantiates a new {@link ZenPolicy.Builder} with all effects set to default (disabled). Loading @@ -360,6 +410,7 @@ public final class ZenDeviceEffects implements Parcelable { mDisableTouch = zenDeviceEffects.shouldDisableTouch(); mMinimizeRadioUsage = zenDeviceEffects.shouldMinimizeRadioUsage(); mMaximizeDoze = zenDeviceEffects.shouldMaximizeDoze(); mExtraEffects.addAll(zenDeviceEffects.getExtraEffects()); } /** Loading Loading @@ -450,7 +501,7 @@ public final class ZenDeviceEffects implements Parcelable { } /** * Sets whether Doze should be enhanced (e.g. with more aggresive activation, or less * Sets whether Doze should be enhanced (e.g. with more aggressive activation, or less * frequent maintenance windows) while the rule is active. * @hide */ Loading @@ -460,6 +511,54 @@ public final class ZenDeviceEffects implements Parcelable { return this; } /** * Sets the extra effects to be applied while the rule is active. Extra effects are not * used in AOSP, but OEMs may add support for them by providing a custom * {@link DeviceEffectsApplier}. * * @apiNote The total size of the extra effects (concatenation of strings) is limited. * * @hide */ @TestApi @NonNull public Builder setExtraEffects(@NonNull Set<String> extraEffects) { Objects.requireNonNull(extraEffects); mExtraEffects.clear(); mExtraEffects.addAll(extraEffects); return this; } /** * Adds the supplied extra effects to the set to be applied while the rule is active. * Extra effects are not used in AOSP, but OEMs may add support for them by providing a * custom {@link DeviceEffectsApplier}. * * @apiNote The total size of the extra effects (concatenation of strings) is limited. * * @hide */ @NonNull public Builder addExtraEffects(@NonNull Set<String> extraEffects) { mExtraEffects.addAll(Objects.requireNonNull(extraEffects)); return this; } /** * Adds the supplied extra effect to the set to be applied while the rule is active. * Extra effects are not used in AOSP, but OEMs may add support for them by providing a * custom {@link DeviceEffectsApplier}. * * @apiNote The total size of the extra effects (concatenation of strings) is limited. * * @hide */ @NonNull public Builder addExtraEffect(@NonNull String extraEffect) { mExtraEffects.add(Objects.requireNonNull(extraEffect)); return this; } /** * Applies the effects that are {@code true} on the supplied {@link ZenDeviceEffects} to * this builder (essentially logically-ORing the effect set). Loading @@ -478,6 +577,7 @@ public final class ZenDeviceEffects implements Parcelable { if (effects.shouldDisableTouch()) setShouldDisableTouch(true); if (effects.shouldMinimizeRadioUsage()) setShouldMinimizeRadioUsage(true); if (effects.shouldMaximizeDoze()) setShouldMaximizeDoze(true); addExtraEffects(effects.getExtraEffects()); return this; } Loading @@ -487,7 +587,7 @@ public final class ZenDeviceEffects implements Parcelable { return new ZenDeviceEffects(mGrayscale, mSuppressAmbientDisplay, mDimWallpaper, mNightMode, mDisableAutoBrightness, mDisableTapToWake, mDisableTiltToWake, mDisableTouch, mMinimizeRadioUsage, mMaximizeDoze); mMaximizeDoze, mExtraEffects); } } }
core/java/android/service/notification/ZenModeConfig.java +52 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OF import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AlarmManager; Loading Loading @@ -65,17 +66,21 @@ import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.TimeZone; import java.util.UUID; import java.util.regex.Pattern; /** * Persisted configuration for zen mode. Loading Loading @@ -272,8 +277,13 @@ public class ZenModeConfig implements Parcelable { private static final String DEVICE_EFFECT_DISABLE_TOUCH = "zdeDisableTouch"; private static final String DEVICE_EFFECT_MINIMIZE_RADIO_USAGE = "zdeMinimizeRadioUsage"; private static final String DEVICE_EFFECT_MAXIMIZE_DOZE = "zdeMaximizeDoze"; private static final String DEVICE_EFFECT_EXTRAS = "zdeExtraEffects"; private static final String DEVICE_EFFECT_USER_MODIFIED_FIELDS = "zdeUserModifiedFields"; private static final String ITEM_SEPARATOR = ","; private static final String ITEM_SEPARATOR_ESCAPE = "\\"; private static final Pattern ITEM_SPLITTER_REGEX = Pattern.compile("(?<!\\\\),"); @UnsupportedAppUsage public boolean allowAlarms = DEFAULT_ALLOW_ALARMS; public boolean allowMedia = DEFAULT_ALLOW_MEDIA; Loading Loading @@ -1099,6 +1109,7 @@ public class ZenModeConfig implements Parcelable { .setShouldMinimizeRadioUsage( safeBoolean(parser, DEVICE_EFFECT_MINIMIZE_RADIO_USAGE, false)) .setShouldMaximizeDoze(safeBoolean(parser, DEVICE_EFFECT_MAXIMIZE_DOZE, false)) .setExtraEffects(safeStringSet(parser, DEVICE_EFFECT_EXTRAS)) .build(); return deviceEffects.hasEffects() ? deviceEffects : null; Loading @@ -1123,6 +1134,7 @@ public class ZenModeConfig implements Parcelable { writeBooleanIfTrue(out, DEVICE_EFFECT_MINIMIZE_RADIO_USAGE, deviceEffects.shouldMinimizeRadioUsage()); writeBooleanIfTrue(out, DEVICE_EFFECT_MAXIMIZE_DOZE, deviceEffects.shouldMaximizeDoze()); writeStringSet(out, DEVICE_EFFECT_EXTRAS, deviceEffects.getExtraEffects()); } private static void writeBooleanIfTrue(TypedXmlSerializer out, String att, boolean value) Loading @@ -1132,6 +1144,26 @@ public class ZenModeConfig implements Parcelable { } } private static void writeStringSet(TypedXmlSerializer out, String att, Set<String> values) throws IOException { if (values.isEmpty()) { return; } // We escape each item by replacing "\" by "\\" and "," by "\,". Then we concatenate with // "," as separator. Reading performs the same operations in the opposite order. List<String> escapedItems = new ArrayList<>(); for (String item : values) { escapedItems.add( item .replace(ITEM_SEPARATOR_ESCAPE, ITEM_SEPARATOR_ESCAPE + ITEM_SEPARATOR_ESCAPE) .replace(ITEM_SEPARATOR, ITEM_SEPARATOR_ESCAPE + ITEM_SEPARATOR)); } String serialized = String.join(ITEM_SEPARATOR, escapedItems); out.attribute(null, att, serialized); } public static boolean isValidHour(int val) { return val >= 0 && val < 24; } Loading Loading @@ -1182,6 +1214,26 @@ public class ZenModeConfig implements Parcelable { return tryParseLong(val, defValue); } @NonNull private static Set<String> safeStringSet(TypedXmlPullParser parser, String att) { Set<String> values = new HashSet<>(); String serialized = parser.getAttributeValue(null, att); if (!TextUtils.isEmpty(serialized)) { // We split on every "," that is *not preceded* by the escape character "\". // Then we reverse the escaping done on each individual item. String[] escapedItems = ITEM_SPLITTER_REGEX.split(serialized); for (String escapedItem : escapedItems) { values.add(escapedItem .replace(ITEM_SEPARATOR_ESCAPE + ITEM_SEPARATOR_ESCAPE, ITEM_SEPARATOR_ESCAPE) .replace(ITEM_SEPARATOR_ESCAPE + ITEM_SEPARATOR, ITEM_SEPARATOR)); } } return values; } @Override public int describeContents() { return 0; Loading
services/core/java/com/android/server/notification/ZenModeHelper.java +5 −1 Original line number Diff line number Diff line Loading @@ -1264,7 +1264,7 @@ public class ZenModeHelper { : new ZenDeviceEffects.Builder().build(); if (isFromApp) { // Don't allow apps to toggle hidden effects. // Don't allow apps to toggle hidden (non-public-API) effects. newEffects = new ZenDeviceEffects.Builder(newEffects) .setShouldDisableAutoBrightness(oldEffects.shouldDisableAutoBrightness()) .setShouldDisableTapToWake(oldEffects.shouldDisableTapToWake()) Loading @@ -1272,6 +1272,7 @@ public class ZenModeHelper { .setShouldDisableTouch(oldEffects.shouldDisableTouch()) .setShouldMinimizeRadioUsage(oldEffects.shouldMinimizeRadioUsage()) .setShouldMaximizeDoze(oldEffects.shouldMaximizeDoze()) .setExtraEffects(oldEffects.getExtraEffects()) .build(); } Loading Loading @@ -1311,6 +1312,9 @@ public class ZenModeHelper { if (oldEffects.shouldMaximizeDoze() != newEffects.shouldMaximizeDoze()) { userModifiedFields |= ZenDeviceEffects.FIELD_MAXIMIZE_DOZE; } if (!Objects.equals(oldEffects.getExtraEffects(), newEffects.getExtraEffects())) { userModifiedFields |= ZenDeviceEffects.FIELD_EXTRA_EFFECTS; } zenRule.zenDeviceEffectsUserModifiedFields = userModifiedFields; } } Loading