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

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

Merge "Hide ZenMode.getRule()" into main

parents 292a552a f32d9b83
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3131,6 +3131,7 @@ public class ZenModeConfig implements Parcelable {
     * @return null if DND is off or describeForeverCondition is false and
     * DND is on forever (until turned off)
     */
    // TODO: b/368247671 - Delete when inlining MODES_UI
    public static String getDescription(Context context, boolean zenOn, ZenModeConfig config,
            boolean describeForeverCondition) {
        if (!zenOn || config == null) {
+49 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import static java.util.Objects.requireNonNull;
import android.annotation.SuppressLint;
import android.app.AutomaticZenRule;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.net.Uri;
import android.os.Parcel;
@@ -117,6 +118,14 @@ public class ZenMode implements Parcelable {
        DISABLED_BY_OTHER
    }

    /**
     * Information about the owner of a {@link ZenMode}. {@link #packageName()} is
     * {@link SystemZenRules#PACKAGE_ANDROID} if the mode is system-owned; it may also be
     * {@code null}, but only as an artifact of very old modes.
     */
    public record Owner(@Nullable String packageName, @Nullable ComponentName configurationActivity,
                           @Nullable ComponentName conditionProvider) { }

    private final String mId;
    private final AutomaticZenRule mRule;
    private final Kind mKind;
@@ -198,7 +207,7 @@ public class ZenMode implements Parcelable {
    }

    @NonNull
    public AutomaticZenRule getRule() {
    AutomaticZenRule getRule() {
        return mRule;
    }

@@ -207,6 +216,10 @@ public class ZenMode implements Parcelable {
        return Strings.nullToEmpty(mRule.getName());
    }

    public void setName(@NonNull String name) {
        mRule.setName(name);
    }

    @NonNull
    public Kind getKind() {
        return mKind;
@@ -217,6 +230,17 @@ public class ZenMode implements Parcelable {
        return mStatus;
    }

    @NonNull
    public Owner getOwner() {
        return new Owner(mRule.getPackageName(), mRule.getConfigurationActivity(),
                mRule.getOwner());
    }

    @Nullable
    public String getOwnerPackage() {
        return getOwner().packageName();
    }

    @AutomaticZenRule.Type
    public int getType() {
        return mRule.getType();
@@ -257,6 +281,26 @@ public class ZenMode implements Parcelable {
        }
    }

    /**
     * Returns the resource id of the icon for this mode. Note that this is the <em>stored</em>
     * resource id, and thus can be different from the value in {@link #getIconKey()} -- in
     * particular, for modes without a custom icon set, this method returns {@code 0} whereas
     * {@link #getIconKey()} will return a default icon based on other mode properties.
     *
     * <p>Most callers are interested in {@link #getIconKey()}, unless they are editing the icon.
     */
    public int getIconResId() {
        return mRule.getIconResId();
    }

    /**
     * Sets the resource id of the icon for this mode.
     * @see #getIconResId()
     */
    public void setIconResId(@DrawableRes int iconResId) {
        mRule.setIconResId(iconResId);
    }

    /** Returns the interruption filter of the mode. */
    @NotificationManager.InterruptionFilter
    public int getInterruptionFilter() {
@@ -445,6 +489,10 @@ public class ZenMode implements Parcelable {
        return mStatus == Status.ENABLED_AND_ACTIVE;
    }

    public boolean isManualInvocationAllowed() {
        return mRule.isManualInvocationAllowed();
    }

    public boolean isSystemOwned() {
        return SystemZenRules.PACKAGE_ANDROID.equals(mRule.getPackageName());
    }
+1 −2
Original line number Diff line number Diff line
@@ -70,8 +70,7 @@ public final class ZenModeDescriptions {
    public String getTriggerDescriptionForAccessibility(@NonNull ZenMode mode) {
        // Only one special case: time-based schedules, where we want to use full day names.
        if (mode.isSystemOwned() && mode.getType() == TYPE_SCHEDULE_TIME) {
            ZenModeConfig.ScheduleInfo schedule = ZenModeConfig.tryParseScheduleConditionId(
                    mode.getRule().getConditionId());
            ZenModeConfig.ScheduleInfo schedule = ZenModeSchedules.getTimeSchedule(mode);
            if (schedule != null) {
                String fullDaysSummary = SystemZenRules.getDaysOfWeekFull(mContext, schedule);
                if (fullDaysSummary != null) {
+45 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.settingslib.notification.modes;

import android.service.notification.ZenModeConfig;

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

public class ZenModeSchedules {

    /**
     * Returns the {@link ZenModeConfig.ScheduleInfo} time schedule corresponding to the mode, or
     * {@code null} if the mode is not time-schedule-based.
     */
    @Nullable
    public static ZenModeConfig.ScheduleInfo getTimeSchedule(@NonNull ZenMode mode) {
        return ZenModeConfig.tryParseScheduleConditionId(mode.getRule().getConditionId());
    }

    /**
     * Returns the {@link ZenModeConfig.EventInfo} calendar schedule corresponding to the mode, or
     * {@code null} if the mode is not calendar-schedule-based.
     */
    @Nullable
    public static ZenModeConfig.EventInfo getCalendarSchedule(@NonNull ZenMode mode) {
        return ZenModeConfig.tryParseEventConditionId(mode.getRule().getConditionId());
    }

    private ZenModeSchedules() { }
}
+113 −4
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.app.AutomaticZenRule.TYPE_DRIVING;
import static android.app.AutomaticZenRule.TYPE_IMMERSIVE;
import static android.app.AutomaticZenRule.TYPE_OTHER;
import static android.app.AutomaticZenRule.TYPE_SCHEDULE_CALENDAR;
import static android.app.AutomaticZenRule.TYPE_SCHEDULE_TIME;
import static android.app.AutomaticZenRule.TYPE_THEATER;
import static android.app.AutomaticZenRule.TYPE_UNKNOWN;
import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS;
@@ -35,6 +36,8 @@ import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;

import android.app.AutomaticZenRule;
import android.content.ComponentName;
import android.content.Context;
import android.net.Uri;
import android.os.Parcel;
import android.service.notification.Condition;
@@ -43,13 +46,17 @@ import android.service.notification.ZenDeviceEffects;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenPolicy;

import androidx.test.core.app.ApplicationProvider;

import com.android.internal.R;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

@RunWith(RobolectricTestRunner.class)
@@ -72,6 +79,13 @@ public class ZenModeTest {
                    .setType(TYPE_OTHER)
                    .build();

    private Context mContext;

    @Before
    public void setUp() {
        mContext = ApplicationProvider.getApplicationContext();
    }

    @Test
    public void testBasicMethods_mode() {
        ZenMode zenMode = new ZenMode("id", ZEN_RULE, zenConfigRuleFor(ZEN_RULE, true));
@@ -95,7 +109,7 @@ public class ZenModeTest {
        assertThat(manualMode.canEditPolicy()).isTrue();
        assertThat(manualMode.canBeDeleted()).isFalse();
        assertThat(manualMode.isActive()).isFalse();
        assertThat(manualMode.getRule().getPackageName()).isEqualTo(PACKAGE_ANDROID);
        assertThat(manualMode.getOwnerPackage()).isEqualTo(PACKAGE_ANDROID);
    }

    @Test
@@ -153,7 +167,7 @@ public class ZenModeTest {
    public void isCustomManual_scheduleTime_false() {
        AutomaticZenRule rule = new AutomaticZenRule.Builder("Mode", Uri.parse("x"))
                .setPackage(SystemZenRules.PACKAGE_ANDROID)
                .setType(AutomaticZenRule.TYPE_SCHEDULE_TIME)
                .setType(TYPE_SCHEDULE_TIME)
                .build();
        ZenMode mode = new ZenMode("id", rule, zenConfigRuleFor(rule, false));

@@ -193,6 +207,23 @@ public class ZenModeTest {
        assertThat(mode.isCustomManual()).isFalse();
    }

    @Test
    public void getOwner_returnsOwnerDetails() {
        AutomaticZenRule azr = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
                .setPackage("package")
                .setConfigurationActivity(new ComponentName("package", "configActivity"))
                .setOwner(new ComponentName("package", "conditionService"))
                .build();
        ZenMode zenMode = new ZenMode("id", azr, zenConfigRuleFor(azr, false));

        ZenMode.Owner owner = zenMode.getOwner();
        assertThat(owner.packageName()).isEqualTo("package");
        assertThat(owner.configurationActivity()).isEqualTo(
                new ComponentName("package", "configActivity"));
        assertThat(owner.conditionProvider()).isEqualTo(
                new ComponentName("package", "conditionService"));
    }

    @Test
    public void getPolicy_interruptionFilterPriority_returnsZenPolicy() {
        AutomaticZenRule azr = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
@@ -245,7 +276,7 @@ public class ZenModeTest {

        zenMode.setPolicy(ZEN_POLICY);

        assertThat(zenMode.getRule().getInterruptionFilter()).isEqualTo(
        assertThat(zenMode.getInterruptionFilter()).isEqualTo(
                INTERRUPTION_FILTER_PRIORITY);
        assertThat(zenMode.getPolicy()).isEqualTo(ZEN_POLICY);
        assertThat(zenMode.getRule().getZenPolicy()).isEqualTo(ZEN_POLICY);
@@ -397,6 +428,7 @@ public class ZenModeTest {

        assertThat(iconKey.resPackage()).isEqualTo("some.package");
        assertThat(iconKey.resId()).isEqualTo(123);
        assertThat(mode.getIconResId()).isEqualTo(123);
    }

    @Test
@@ -411,6 +443,7 @@ public class ZenModeTest {

        assertThat(iconKey.resPackage()).isNull();
        assertThat(iconKey.resId()).isEqualTo(123);
        assertThat(mode.getIconResId()).isEqualTo(123);
    }

    @Test
@@ -425,15 +458,18 @@ public class ZenModeTest {

        assertThat(iconKey.resPackage()).isEqualTo("some.package");
        assertThat(iconKey.resId()).isEqualTo(123);
        assertThat(mode.getIconResId()).isEqualTo(123);
    }

    @Test
    public void getIconKey_manualDnd_isDndIcon() {
        ZenIcon.Key iconKey = TestModeBuilder.MANUAL_DND.getIconKey();
        ZenMode mode = TestModeBuilder.MANUAL_DND;
        ZenIcon.Key iconKey = mode.getIconKey();

        assertThat(iconKey.resPackage()).isNull();
        assertThat(iconKey.resId()).isEqualTo(
                com.android.internal.R.drawable.ic_zen_mode_type_special_dnd);
        assertThat(mode.getIconResId()).isEqualTo(0);
    }

    @Test
@@ -448,6 +484,7 @@ public class ZenModeTest {
        assertThat(iconKey.resPackage()).isNull();
        assertThat(iconKey.resId()).isEqualTo(
                com.android.internal.R.drawable.ic_zen_mode_type_bedtime);
        assertThat(mode.getIconResId()).isEqualTo(0);
    }

    @Test
@@ -462,6 +499,7 @@ public class ZenModeTest {
        assertThat(iconKey.resPackage()).isNull();
        assertThat(iconKey.resId()).isEqualTo(
                com.android.internal.R.drawable.ic_zen_mode_type_schedule_calendar);
        assertThat(mode.getIconResId()).isEqualTo(0);
    }

    @Test
@@ -477,6 +515,77 @@ public class ZenModeTest {
        assertThat(iconKey.resPackage()).isNull();
        assertThat(iconKey.resId()).isEqualTo(
                com.android.internal.R.drawable.ic_zen_mode_type_special_dnd);
        assertThat(mode.getIconResId()).isEqualTo(0);
    }

    @Test
    public void setCustomModeConditionId_timeSchedule() {
        ZenMode mode = new TestModeBuilder()
                .setPackage(PACKAGE_ANDROID)
                .build();
        ZenModeConfig.ScheduleInfo timeSchedule = new ZenModeConfig.ScheduleInfo();
        timeSchedule.startHour = 9;
        timeSchedule.endHour = 12;
        timeSchedule.days = new int[] {Calendar.SATURDAY, Calendar.SUNDAY};
        Uri scheduleUri = ZenModeConfig.toScheduleConditionId(timeSchedule);

        mode.setCustomModeConditionId(mContext, scheduleUri);

        assertThat(mode.getType()).isEqualTo(TYPE_SCHEDULE_TIME);
        assertThat(ZenModeSchedules.getTimeSchedule(mode)).isEqualTo(timeSchedule);
        assertThat(mode.getTriggerDescription()).isEqualTo("Sun, Sat, 9:00 AM - 12:00 PM");

        assertThat(mode.getRule().getConditionId()).isEqualTo(scheduleUri);
        assertThat(mode.getRule().getOwner()).isEqualTo(
                ZenModeConfig.getScheduleConditionProvider());
    }

    @Test
    public void setCustomModeConditionId_calendarSchedule() {
        ZenMode mode = new TestModeBuilder()
                .setPackage(PACKAGE_ANDROID)
                .build();
        ZenModeConfig.EventInfo calendarSchedule = new ZenModeConfig.EventInfo();
        calendarSchedule.calendarId = 1L;
        calendarSchedule.calName = "My events";
        Uri scheduleUri = ZenModeConfig.toEventConditionId(calendarSchedule);

        mode.setCustomModeConditionId(mContext, scheduleUri);

        assertThat(mode.getType()).isEqualTo(TYPE_SCHEDULE_CALENDAR);
        assertThat(ZenModeSchedules.getCalendarSchedule(mode)).isEqualTo(calendarSchedule);
        assertThat(mode.getTriggerDescription()).isEqualTo("My events");

        assertThat(mode.getRule().getConditionId()).isEqualTo(scheduleUri);
        assertThat(mode.getRule().getOwner()).isEqualTo(
                ZenModeConfig.getEventConditionProvider());
    }

    @Test
    public void setCustomModeConditionId_manualSchedule() {
        ZenMode mode = new TestModeBuilder()
                .setPackage(PACKAGE_ANDROID)
                .build();

        mode.setCustomModeConditionId(mContext, ZenModeConfig.toCustomManualConditionId());

        assertThat(mode.getType()).isEqualTo(TYPE_OTHER);
        assertThat(mode.getTriggerDescription()).isEqualTo("");

        assertThat(mode.getRule().getConditionId()).isEqualTo(
                ZenModeConfig.toCustomManualConditionId());
        assertThat(mode.getRule().getOwner()).isEqualTo(
                ZenModeConfig.getCustomManualConditionProvider());
    }

    @Test
    public void setCustomModeConditionId_nonSystemRule_throws() {
        ZenMode mode = new TestModeBuilder()
                .setPackage("some.other.package")
                .build();

        assertThrows(IllegalStateException.class,
                () -> mode.setCustomModeConditionId(mContext, Uri.parse("blah")));
    }

    private static void assertUnparceledIsEqualToOriginal(String type, ZenMode original) {
Loading