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

Commit 8e4ed131 authored by Matías Hernández's avatar Matías Hernández Committed by Android (Google) Code Review
Browse files

Merge changes from topics "add-mode-dialog", "nicer-icon-header" into main

* changes:
  Provide a method to get the default icon for a type
  Support "in-memory" ZenMode
  Supply icon (in addition to name) for addCustomManualMode()
parents 87fc9576 4f338d31
Loading
Loading
Loading
Loading
+9 −2
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import static com.google.common.util.concurrent.Futures.immediateFuture;


import static java.util.Objects.requireNonNull;
import static java.util.Objects.requireNonNull;


import android.annotation.DrawableRes;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.AutomaticZenRule;
import android.app.AutomaticZenRule;
import android.content.Context;
import android.content.Context;
@@ -120,7 +121,14 @@ public class ZenIconLoader {
    }
    }


    private static Drawable getFallbackIcon(Context context, int ruleType) {
    private static Drawable getFallbackIcon(Context context, int ruleType) {
        int iconResIdFromType = switch (ruleType) {
        int iconResIdFromType = getIconResourceIdFromType(ruleType);
        return requireNonNull(context.getDrawable(iconResIdFromType));
    }

    /** Return the default icon resource associated to a {@link AutomaticZenRule.Type} */
    @DrawableRes
    public static int getIconResourceIdFromType(@AutomaticZenRule.Type int ruleType) {
        return switch (ruleType) {
            case AutomaticZenRule.TYPE_UNKNOWN ->
            case AutomaticZenRule.TYPE_UNKNOWN ->
                    com.android.internal.R.drawable.ic_zen_mode_type_unknown;
                    com.android.internal.R.drawable.ic_zen_mode_type_unknown;
            case AutomaticZenRule.TYPE_OTHER ->
            case AutomaticZenRule.TYPE_OTHER ->
@@ -141,7 +149,6 @@ public class ZenIconLoader {
                    com.android.internal.R.drawable.ic_zen_mode_type_managed;
                    com.android.internal.R.drawable.ic_zen_mode_type_managed;
            default -> com.android.internal.R.drawable.ic_zen_mode_type_unknown;
            default -> com.android.internal.R.drawable.ic_zen_mode_type_unknown;
        };
        };
        return requireNonNull(context.getDrawable(iconResIdFromType));
    }
    }


    private static Drawable getMonochromeIconIfPresent(Drawable icon) {
    private static Drawable getMonochromeIconIfPresent(Drawable icon) {
+55 −1
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@ import static android.service.notification.SystemZenRules.getTriggerDescriptionF
import static android.service.notification.ZenModeConfig.tryParseEventConditionId;
import static android.service.notification.ZenModeConfig.tryParseEventConditionId;
import static android.service.notification.ZenModeConfig.tryParseScheduleConditionId;
import static android.service.notification.ZenModeConfig.tryParseScheduleConditionId;


import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Preconditions.checkState;


import static java.util.Objects.requireNonNull;
import static java.util.Objects.requireNonNull;
@@ -33,12 +34,15 @@ import android.app.NotificationManager;
import android.content.Context;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.notification.SystemZenRules;
import android.service.notification.SystemZenRules;
import android.service.notification.ZenDeviceEffects;
import android.service.notification.ZenDeviceEffects;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenPolicy;
import android.service.notification.ZenPolicy;
import android.util.Log;
import android.util.Log;


import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Nullable;


@@ -56,11 +60,12 @@ import java.util.Objects;
 * <p>It also adapts other rule features that we don't want to expose in the UI, such as
 * <p>It also adapts other rule features that we don't want to expose in the UI, such as
 * interruption filters other than {@code PRIORITY}, rules without specific icons, etc.
 * interruption filters other than {@code PRIORITY}, rules without specific icons, etc.
 */
 */
public class ZenMode {
public class ZenMode implements Parcelable {


    private static final String TAG = "ZenMode";
    private static final String TAG = "ZenMode";


    static final String MANUAL_DND_MODE_ID = "manual_dnd";
    static final String MANUAL_DND_MODE_ID = "manual_dnd";
    static final String TEMP_NEW_MODE_ID = "temp_new_mode";


    // Must match com.android.server.notification.ZenModeHelper#applyCustomPolicy.
    // Must match com.android.server.notification.ZenModeHelper#applyCustomPolicy.
    private static final ZenPolicy POLICY_INTERRUPTION_FILTER_ALARMS =
    private static final ZenPolicy POLICY_INTERRUPTION_FILTER_ALARMS =
@@ -125,6 +130,25 @@ public class ZenMode {
                isActive ? Status.ENABLED_AND_ACTIVE : Status.ENABLED, true);
                isActive ? Status.ENABLED_AND_ACTIVE : Status.ENABLED, true);
    }
    }


    /**
     * Returns a new {@link ZenMode} instance that can represent a custom_manual mode that is in the
     * process of being created (and not yet saved).
     *
     * @param name mode name
     * @param iconResId resource id of the chosen icon, {code 0} if none.
     */
    public static ZenMode newCustomManual(String name, @DrawableRes int iconResId) {
        AutomaticZenRule rule = new AutomaticZenRule.Builder(name,
                ZenModeConfig.toCustomManualConditionId())
                .setPackage(ZenModeConfig.getCustomManualConditionProvider().getPackageName())
                .setType(AutomaticZenRule.TYPE_OTHER)
                .setOwner(ZenModeConfig.getCustomManualConditionProvider())
                .setIconResId(iconResId)
                .setManualInvocationAllowed(true)
                .build();
        return new ZenMode(TEMP_NEW_MODE_ID, rule, Status.ENABLED, false);
    }

    private ZenMode(String id, @NonNull AutomaticZenRule rule, Status status, boolean isManualDnd) {
    private ZenMode(String id, @NonNull AutomaticZenRule rule, Status status, boolean isManualDnd) {
        mId = id;
        mId = id;
        mRule = rule;
        mRule = rule;
@@ -304,4 +328,34 @@ public class ZenMode {
    public String toString() {
    public String toString() {
        return mId + " (" + mStatus + ") -> " + mRule;
        return mId + " (" + mStatus + ") -> " + mRule;
    }
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString(mId);
        dest.writeParcelable(mRule, 0);
        dest.writeString(mStatus.name());
        dest.writeBoolean(mIsManualDnd);
    }

    public static final Creator<ZenMode> CREATOR = new Creator<ZenMode>() {
        @Override
        public ZenMode createFromParcel(Parcel in) {
            return new ZenMode(
                    in.readString(),
                    checkNotNull(in.readParcelable(AutomaticZenRule.class.getClassLoader(),
                            AutomaticZenRule.class)),
                    Status.valueOf(in.readString()),
                    in.readBoolean());
        }

        @Override
        public ZenMode[] newArray(int size) {
            return new ZenMode[size];
        }
    };
}
}
+6 −9
Original line number Original line Diff line number Diff line
@@ -27,6 +27,8 @@ import android.service.notification.Condition;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig;
import android.util.Log;
import android.util.Log;


import androidx.annotation.DrawableRes;

import com.android.settingslib.R;
import com.android.settingslib.R;


import java.time.Duration;
import java.time.Duration;
@@ -184,18 +186,13 @@ public class ZenModesBackend {
     * Creates a new custom mode with the provided {@code name}. The mode will be "manual" (i.e.
     * Creates a new custom mode with the provided {@code name}. The mode will be "manual" (i.e.
     * not have a schedule), this can be later updated by the user in the mode settings page.
     * not have a schedule), this can be later updated by the user in the mode settings page.
     *
     *
     * @param name mode name
     * @param iconResId resource id of the chosen icon, {code 0} if none.
     * @return the created mode. Only {@code null} if creation failed due to an internal error
     * @return the created mode. Only {@code null} if creation failed due to an internal error
     */
     */
    @Nullable
    @Nullable
    public ZenMode addCustomMode(String name) {
    public ZenMode addCustomManualMode(String name, @DrawableRes int iconResId) {
        AutomaticZenRule rule = new AutomaticZenRule.Builder(name,
        AutomaticZenRule rule = ZenMode.newCustomManual(name, iconResId).getRule();
                ZenModeConfig.toCustomManualConditionId())
                .setPackage(ZenModeConfig.getCustomManualConditionProvider().getPackageName())
                .setType(AutomaticZenRule.TYPE_OTHER)
                .setOwner(ZenModeConfig.getCustomManualConditionProvider())
                .setManualInvocationAllowed(true)
                .build();

        String ruleId = mNotificationManager.addAutomaticZenRule(rule);
        String ruleId = mNotificationManager.addAutomaticZenRule(rule);
        return getMode(ruleId);
        return getMode(ruleId);
    }
    }
+28 −0
Original line number Original line Diff line number Diff line
@@ -21,13 +21,17 @@ import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;


import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;


import android.app.AutomaticZenRule;
import android.app.AutomaticZenRule;
import android.net.Uri;
import android.net.Uri;
import android.os.Parcel;
import android.service.notification.Condition;
import android.service.notification.Condition;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenPolicy;
import android.service.notification.ZenPolicy;


import com.android.internal.R;

import org.junit.Test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RobolectricTestRunner;
@@ -161,6 +165,30 @@ public class ZenModeTest {
        assertThat(zenMode.getRule().getZenPolicy()).isEqualTo(ZEN_POLICY);
        assertThat(zenMode.getRule().getZenPolicy()).isEqualTo(ZEN_POLICY);
    }
    }


    @Test
    public void writeToParcel_equals() {
        assertUnparceledIsEqualToOriginal("example",
                new ZenMode("id", ZEN_RULE, zenConfigRuleFor(ZEN_RULE, false)));

        assertUnparceledIsEqualToOriginal("dnd", ZenMode.manualDndMode(ZEN_RULE, true));

        assertUnparceledIsEqualToOriginal("custom_manual",
                ZenMode.newCustomManual("New mode", R.drawable.ic_zen_mode_type_immersive));
    }

    private static void assertUnparceledIsEqualToOriginal(String type, ZenMode original) {
        Parcel parcel = Parcel.obtain();
        try {
            original.writeToParcel(parcel, 0);
            parcel.setDataPosition(0);
            ZenMode unparceled = ZenMode.CREATOR.createFromParcel(parcel);

            assertWithMessage("Comparing " + type).that(unparceled).isEqualTo(original);
        } finally {
            parcel.recycle();
        }
    }

    private static ZenModeConfig.ZenRule zenConfigRuleFor(AutomaticZenRule azr, boolean isActive) {
    private static ZenModeConfig.ZenRule zenConfigRuleFor(AutomaticZenRule azr, boolean isActive) {
        ZenModeConfig.ZenRule zenRule = new ZenModeConfig.ZenRule();
        ZenModeConfig.ZenRule zenRule = new ZenModeConfig.ZenRule();
        zenRule.pkg = azr.getPackageName();
        zenRule.pkg = azr.getPackageName();