Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9481b2b3 authored by Julia Reynolds's avatar Julia Reynolds Committed by Android (Google) Code Review
Browse files

Merge "Add new state to AutomaticZenRule" into main

parents 2f0a4a53 2cd67d44
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -5315,11 +5315,15 @@ package android.app {
    method public android.net.Uri getConditionId();
    method @Nullable public android.content.ComponentName getConfigurationActivity();
    method public long getCreationTime();
    method @FlaggedApi("android.app.modes_api") @DrawableRes public int getIconResId();
    method public int getInterruptionFilter();
    method public String getName();
    method public android.content.ComponentName getOwner();
    method @FlaggedApi("android.app.modes_api") @Nullable public String getTriggerDescription();
    method @FlaggedApi("android.app.modes_api") public int getType();
    method public android.service.notification.ZenPolicy getZenPolicy();
    method public boolean isEnabled();
    method @FlaggedApi("android.app.modes_api") public boolean isManualInvocationAllowed();
    method public void setConditionId(android.net.Uri);
    method public void setConfigurationActivity(@Nullable android.content.ComponentName);
    method public void setEnabled(boolean);
@@ -5328,6 +5332,32 @@ package android.app {
    method public void setZenPolicy(android.service.notification.ZenPolicy);
    method public void writeToParcel(android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.AutomaticZenRule> CREATOR;
    field @FlaggedApi("android.app.modes_api") public static final int TYPE_BEDTIME = 3; // 0x3
    field @FlaggedApi("android.app.modes_api") public static final int TYPE_DRIVING = 4; // 0x4
    field @FlaggedApi("android.app.modes_api") public static final int TYPE_IMMERSIVE = 5; // 0x5
    field @FlaggedApi("android.app.modes_api") public static final int TYPE_MANAGED = 7; // 0x7
    field @FlaggedApi("android.app.modes_api") public static final int TYPE_OTHER = 0; // 0x0
    field @FlaggedApi("android.app.modes_api") public static final int TYPE_SCHEDULE_CALENDAR = 2; // 0x2
    field @FlaggedApi("android.app.modes_api") public static final int TYPE_SCHEDULE_TIME = 1; // 0x1
    field @FlaggedApi("android.app.modes_api") public static final int TYPE_THEATER = 6; // 0x6
    field @FlaggedApi("android.app.modes_api") public static final int TYPE_UNKNOWN = -1; // 0xffffffff
  }
  @FlaggedApi("android.app.modes_api") public static final class AutomaticZenRule.Builder {
    ctor public AutomaticZenRule.Builder(@NonNull android.app.AutomaticZenRule);
    ctor public AutomaticZenRule.Builder(@NonNull String, @NonNull android.net.Uri);
    method @NonNull public android.app.AutomaticZenRule build();
    method @NonNull public android.app.AutomaticZenRule.Builder setConditionId(@NonNull android.net.Uri);
    method @NonNull public android.app.AutomaticZenRule.Builder setConfigurationActivity(@Nullable android.content.ComponentName);
    method @NonNull public android.app.AutomaticZenRule.Builder setEnabled(boolean);
    method @NonNull public android.app.AutomaticZenRule.Builder setIconResId(@DrawableRes int);
    method @NonNull public android.app.AutomaticZenRule.Builder setInterruptionFilter(int);
    method @NonNull public android.app.AutomaticZenRule.Builder setManualInvocationAllowed(boolean);
    method @NonNull public android.app.AutomaticZenRule.Builder setName(@NonNull String);
    method @NonNull public android.app.AutomaticZenRule.Builder setOwner(@Nullable android.content.ComponentName);
    method @NonNull public android.app.AutomaticZenRule.Builder setTriggerDescription(@Nullable String);
    method @NonNull public android.app.AutomaticZenRule.Builder setType(int);
    method @NonNull public android.app.AutomaticZenRule.Builder setZenPolicy(@Nullable android.service.notification.ZenPolicy);
  }
  public final class BackgroundServiceStartNotAllowedException extends android.app.ServiceStartNotAllowedException implements android.os.Parcelable {
+331 −7
Original line number Diff line number Diff line
@@ -16,16 +16,23 @@

package android.app;

import android.annotation.DrawableRes;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.NotificationManager.InterruptionFilter;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.notification.Condition;
import android.service.notification.ZenPolicy;
import android.view.WindowInsetsController;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

/**
@@ -36,7 +43,67 @@ public final class AutomaticZenRule implements Parcelable {
    private static final int ENABLED = 1;
    /* @hide */
    private static final int DISABLED = 0;
    private boolean enabled = false;

    /**
     * Rule is of an unknown type. This is the default value if not provided by the owning app.
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public static final int TYPE_UNKNOWN = -1;
    /**
     * Rule is of a known type, but not one of the specific types.
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public static final int TYPE_OTHER = 0;
    /**
     * The type for rules triggered according to a time-based schedule.
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public static final int TYPE_SCHEDULE_TIME = 1;
    /**
     * The type for rules triggered by calendar events.
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public static final int TYPE_SCHEDULE_CALENDAR = 2;
    /**
     * The type for rules triggered by bedtime/sleeping, like time of day, or snore detection.
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public static final int TYPE_BEDTIME = 3;
    /**
     * The type for rules triggered by driving detection, like Bluetooth connections or vehicle
     * sounds.
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public static final int TYPE_DRIVING = 4;
    /**
     * The type for rules triggered by the user entering an immersive activity, like opening an app
     * using {@link WindowInsetsController#hide(int)}.
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public static final int TYPE_IMMERSIVE = 5;
    /**
     * The type for rules that have a {@link ZenPolicy} that implies that the
     * device should not make sound and potentially hide some visual effects; may be triggered
     * when entering a location where silence is requested, like a theater.
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public static final int TYPE_THEATER = 6;
    /**
     * The type for rules created and managed by a device owner. These rules may not be fully
     * editable by the device user.
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public static final int TYPE_MANAGED = 7;

    /** @hide */
    @IntDef(prefix = { "TYPE_" }, value = {
            TYPE_UNKNOWN, TYPE_OTHER, TYPE_SCHEDULE_TIME, TYPE_SCHEDULE_CALENDAR, TYPE_BEDTIME,
            TYPE_DRIVING, TYPE_IMMERSIVE, TYPE_THEATER, TYPE_MANAGED
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Type {}

    private boolean enabled;
    private String name;
    private @InterruptionFilter int interruptionFilter;
    private Uri conditionId;
@@ -46,6 +113,10 @@ public final class AutomaticZenRule implements Parcelable {
    private ZenPolicy mZenPolicy;
    private boolean mModified = false;
    private String mPkg;
    private int mType = TYPE_UNKNOWN;
    private int mIconResId;
    private String mTriggerDescription;
    private boolean mAllowManualInvocation;

    /**
     * The maximum string length for any string contained in this automatic zen rule. This pertains
@@ -54,6 +125,12 @@ public final class AutomaticZenRule implements Parcelable {
     */
    public static final int MAX_STRING_LENGTH = 1000;

    /**
     * The maximum string length for the trigger description rule, given UI constraints.
     * @hide
     */
    public static final int MAX_DESC_LENGTH = 150;

    /**
     * Creates an automatic zen rule.
     *
@@ -97,6 +174,7 @@ public final class AutomaticZenRule implements Parcelable {
     *               action ({@link Condition#STATE_TRUE}).
     * @param enabled Whether the rule is enabled.
     */
    // TODO (b/309088420): deprecate this constructor in favor of the builder
    public AutomaticZenRule(@NonNull String name, @Nullable ComponentName owner,
            @Nullable ComponentName configurationActivity, @NonNull Uri conditionId,
            @Nullable ZenPolicy policy, int interruptionFilter, boolean enabled) {
@@ -134,6 +212,12 @@ public final class AutomaticZenRule implements Parcelable {
        mZenPolicy = source.readParcelable(null, android.service.notification.ZenPolicy.class);
        mModified = source.readInt() == ENABLED;
        mPkg = source.readString();
        if (Flags.modesApi()) {
            mAllowManualInvocation = source.readBoolean();
            mIconResId = source.readInt();
            mTriggerDescription = getTrimmedString(source.readString(), MAX_DESC_LENGTH);
            mType = source.readInt();
        }
    }

    /**
@@ -269,6 +353,81 @@ public final class AutomaticZenRule implements Parcelable {
        return mPkg;
    }

    /**
     * Gets the type of the rule.
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public int getType() {
        return mType;
    }

    /**
     * Sets the type of the rule.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public void setType(@Type int type) {
        mType = type;
    }

    /**
     * Gets the user visible description of when this rule is active
     * (see {@link Condition#STATE_TRUE}).
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public @Nullable String getTriggerDescription() {
        return mTriggerDescription;
    }

    /**
     * Sets a user visible description of when this rule will be active
     * (see {@link Condition#STATE_TRUE}).
     *
     * A description should be a (localized) string like "Mon-Fri, 9pm-7am" or
     * "When connected to [Car Name]".
     * @hide
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public void setTriggerDescription(@Nullable String triggerDescription) {
        mTriggerDescription = triggerDescription;
    }

    /**
     * Gets the resource id of the drawable icon for this rule.
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public @DrawableRes int getIconResId() {
        return mIconResId;
    }

    /**
     * Sets a resource id of a tintable vector drawable representing the rule in image form.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public void setIconResId(int iconResId) {
        mIconResId = iconResId;
    }

    /**
     * Gets whether this rule can be manually activated by the user even when the triggering
     * condition for the rule is not met.
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public boolean isManualInvocationAllowed() {
        return mAllowManualInvocation;
    }

    /**
     * Sets whether this rule can be manually activated by the user even when the triggering
     * condition for the rule is not met.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public void setManualInvocationAllowed(boolean allowManualInvocation) {
        mAllowManualInvocation = allowManualInvocation;
    }

    @Override
    public int describeContents() {
        return 0;
@@ -291,11 +450,17 @@ public final class AutomaticZenRule implements Parcelable {
        dest.writeParcelable(mZenPolicy, 0);
        dest.writeInt(mModified ? ENABLED : DISABLED);
        dest.writeString(mPkg);
        if (Flags.modesApi()) {
            dest.writeBoolean(mAllowManualInvocation);
            dest.writeInt(mIconResId);
            dest.writeString(mTriggerDescription);
            dest.writeInt(mType);
        }
    }

    @Override
    public String toString() {
        return new StringBuilder(AutomaticZenRule.class.getSimpleName()).append('[')
        StringBuilder sb = new StringBuilder(AutomaticZenRule.class.getSimpleName()).append('[')
                .append("enabled=").append(enabled)
                .append(",name=").append(name)
                .append(",interruptionFilter=").append(interruptionFilter)
@@ -304,8 +469,16 @@ public final class AutomaticZenRule implements Parcelable {
                .append(",owner=").append(owner)
                .append(",configActivity=").append(configurationActivity)
                .append(",creationTime=").append(creationTime)
                .append(",mZenPolicy=").append(mZenPolicy)
                .append(']').toString();
                .append(",mZenPolicy=").append(mZenPolicy);

        if (Flags.modesApi()) {
            sb.append(",allowManualInvocation=").append(mAllowManualInvocation)
                    .append(",iconResId=").append(mIconResId)
                    .append(",triggerDescription=").append(mTriggerDescription)
                    .append(",type=").append(mType);
        }

        return sb.append(']').toString();
    }

    @Override
@@ -313,7 +486,7 @@ public final class AutomaticZenRule implements Parcelable {
        if (!(o instanceof AutomaticZenRule)) return false;
        if (o == this) return true;
        final AutomaticZenRule other = (AutomaticZenRule) o;
        return other.enabled == enabled
        boolean finalEquals = other.enabled == enabled
                && other.mModified == mModified
                && Objects.equals(other.name, name)
                && other.interruptionFilter == interruptionFilter
@@ -323,10 +496,23 @@ public final class AutomaticZenRule implements Parcelable {
                && Objects.equals(other.configurationActivity, configurationActivity)
                && Objects.equals(other.mPkg, mPkg)
                && other.creationTime == creationTime;
        if (Flags.modesApi()) {
            return finalEquals
                    && other.mAllowManualInvocation == mAllowManualInvocation
                    && other.mIconResId == mIconResId
                    && Objects.equals(other.mTriggerDescription, mTriggerDescription)
                    && other.mType == mType;
        }
        return finalEquals;
    }

    @Override
    public int hashCode() {
        if (Flags.modesApi()) {
            return Objects.hash(enabled, name, interruptionFilter, conditionId, owner,
                    configurationActivity, mZenPolicy, mModified, creationTime, mPkg,
                    mAllowManualInvocation, mIconResId, mTriggerDescription, mType);
        }
        return Objects.hash(enabled, name, interruptionFilter, conditionId, owner,
                configurationActivity, mZenPolicy, mModified, creationTime, mPkg);
    }
@@ -357,8 +543,12 @@ public final class AutomaticZenRule implements Parcelable {
     * Returns a truncated copy of the string if the string is longer than MAX_STRING_LENGTH.
     */
    private static String getTrimmedString(String input) {
        if (input != null && input.length() > MAX_STRING_LENGTH) {
            return input.substring(0, MAX_STRING_LENGTH);
        return getTrimmedString(input, MAX_STRING_LENGTH);
    }

    private static String getTrimmedString(String input, int length) {
        if (input != null && input.length() > length) {
            return input.substring(0, length);
        }
        return input;
    }
@@ -373,4 +563,138 @@ public final class AutomaticZenRule implements Parcelable {
        }
        return input;
    }

    @FlaggedApi(Flags.FLAG_MODES_API)
    public static final class Builder {
        private String mName;
        private ComponentName mOwner;
        private Uri mConditionId;
        private int mInterruptionFilter;
        private boolean mEnabled;
        private ComponentName mConfigurationActivity = null;
        private ZenPolicy mPolicy = null;
        private int mType;
        private String mDescription;
        private int mIconResId;
        private boolean mAllowManualInvocation;
        private long mCreationTime;
        private String mPkg;

        public Builder(@NonNull AutomaticZenRule rule) {
            mName = rule.getName();
            mOwner = rule.getOwner();
            mConditionId = rule.getConditionId();
            mInterruptionFilter = rule.getInterruptionFilter();
            mEnabled = rule.isEnabled();
            mConfigurationActivity = rule.getConfigurationActivity();
            mPolicy = rule.getZenPolicy();
            mType = rule.getType();
            mDescription = rule.getTriggerDescription();
            mIconResId = rule.getIconResId();
            mAllowManualInvocation = rule.isManualInvocationAllowed();
            mCreationTime = rule.getCreationTime();
            mPkg = rule.getPackageName();
        }

        public Builder(@NonNull String name, @NonNull Uri conditionId) {
            mName = name;
            mConditionId = conditionId;
        }

        public @NonNull Builder setName(@NonNull String name) {
            mName = name;
            return this;
        }

        public @NonNull Builder setOwner(@Nullable ComponentName owner) {
            mOwner = owner;
            return this;
        }

        public @NonNull Builder setConditionId(@NonNull Uri conditionId) {
            mConditionId = conditionId;
            return this;
        }

        public @NonNull Builder setInterruptionFilter(
                @InterruptionFilter int interruptionFilter) {
            mInterruptionFilter = interruptionFilter;
            return this;
        }

        public @NonNull Builder setEnabled(boolean enabled) {
            mEnabled = enabled;
            return this;
        }

        public @NonNull Builder setConfigurationActivity(
                @Nullable ComponentName configurationActivity) {
            mConfigurationActivity = configurationActivity;
            return this;
        }

        public @NonNull Builder setZenPolicy(@Nullable ZenPolicy policy) {
            mPolicy = policy;
            return this;
        }

        /**
         * Sets the type of the rule
         */
        public @NonNull Builder setType(@Type int type) {
            mType = type;
            return this;
        }

        /**
         * Sets a user visible description of when this rule will be active
         * (see {@link Condition#STATE_TRUE}).
         *
         * A description should be a (localized) string like "Mon-Fri, 9pm-7am" or
         * "When connected to [Car Name]".
         */
        public @NonNull Builder setTriggerDescription(@Nullable String description) {
            mDescription = description;
            return this;
        }

        /**
         * Sets a resource id of a tintable vector drawable representing the rule in image form.
         */
        public @NonNull Builder setIconResId(@DrawableRes int iconResId) {
            mIconResId = iconResId;
            return this;
        }

        /**
         * Sets whether this rule can be manually activated by the user even when the triggering
         * condition for the rule is not met.
         */
        public @NonNull Builder setManualInvocationAllowed(boolean allowManualInvocation) {
            mAllowManualInvocation = allowManualInvocation;
            return this;
        }

        /**
         * Sets the time at which this rule was created, in milliseconds since epoch
         * @hide
         */
        public @NonNull Builder setCreationTime(long creationTime) {
            mCreationTime = creationTime;
            return this;
        }

        public @NonNull AutomaticZenRule build() {
            AutomaticZenRule rule = new AutomaticZenRule(mName, mOwner, mConfigurationActivity,
                    mConditionId, mPolicy, mInterruptionFilter, mEnabled);
            rule.creationTime = mCreationTime;
            rule.mType = mType;
            rule.mTriggerDescription = mDescription;
            rule.mIconResId = mIconResId;
            rule.mAllowManualInvocation = mAllowManualInvocation;
            rule.setPackageName(mPkg);

            return rule;
        }
    }
}
+65 −5

File changed.

Preview size limit exceeded, changes collapsed.

+19 −0
Original line number Diff line number Diff line
@@ -454,6 +454,11 @@ public class ZenModeDiff {
        public static final String FIELD_ZEN_POLICY = "zenPolicy";
        public static final String FIELD_MODIFIED = "modified";
        public static final String FIELD_PKG = "pkg";
        public static final String FIELD_ALLOW_MANUAL = "allowManualInvocation";
        public static final String FIELD_ICON_RES = "iconResId";
        public static final String FIELD_TRIGGER = "triggerDescription";
        public static final String FIELD_TYPE = "type";
        // NOTE: new field strings must match the variable names in ZenModeConfig.ZenRule

        // Special field to track whether this rule became active or inactive
        FieldDiff<Boolean> mActiveDiff;
@@ -529,6 +534,20 @@ public class ZenModeDiff {
            if (!Objects.equals(from.pkg, to.pkg)) {
                addField(FIELD_PKG, new FieldDiff<>(from.pkg, to.pkg));
            }
            if (!Objects.equals(from.triggerDescription, to.triggerDescription)) {
                addField(FIELD_TRIGGER,
                        new FieldDiff<>(from.triggerDescription, to.triggerDescription));
            }
            if (from.type != to.type) {
                addField(FIELD_TYPE, new FieldDiff<>(from.type, to.type));
            }
            if (from.allowManualInvocation != to.allowManualInvocation) {
                addField(FIELD_ALLOW_MANUAL,
                        new FieldDiff<>(from.allowManualInvocation, to.allowManualInvocation));
            }
            if (!Objects.equals(from.iconResId, to.iconResId)) {
                addField(FIELD_ICON_RES, new FieldDiff(from.iconResId, to.iconResId));
            }
        }

        /**
+4 −0
Original line number Diff line number Diff line
@@ -125,6 +125,9 @@ public class AutomaticZenRuleTest {
            Field configActivity = Class.forName(CLASS).getDeclaredField("configurationActivity");
            configActivity.setAccessible(true);
            configActivity.set(rule, new ComponentName(longString, longString));
            Field trigger = Class.forName(CLASS).getDeclaredField("mTriggerDescription");
            trigger.setAccessible(true);
            trigger.set(rule, longString);
        } catch (NoSuchFieldException e) {
            fail(e.toString());
        } catch (ClassNotFoundException e) {
@@ -149,5 +152,6 @@ public class AutomaticZenRuleTest {
                fromParcel.getOwner().getPackageName().length());
        assertEquals(AutomaticZenRule.MAX_STRING_LENGTH,
                fromParcel.getOwner().getClassName().length());
        assertEquals(AutomaticZenRule.MAX_DESC_LENGTH, rule.getTriggerDescription().length());
    }
}
Loading