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

Commit b786da2e authored by Yuri Lin's avatar Yuri Lin
Browse files

Include allowChannels info in DNDPolicyProto output.

This applies only when modes_api is on and will cause the policy proto included in both DNDModeProto and DNDStateChanged to reflect the new setting.

Bug: 308673342
Test: ZenModeHelperTest, statsd_testdrive

Change-Id: Icc619a08490e71df4fedc58933a1b2ab1390d24a
parent fde7a7db
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -1241,7 +1241,7 @@ public final class ZenPolicy implements Parcelable {
     * @hide
     */
    public byte[] toProto() {
        // TODO: b/308672510 - log new ZenPolicy fields to DNDPolicyProto.
        // TODO: b/308672510 - log user-customized ZenPolicy fields to DNDPolicyProto.
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        ProtoOutputStream proto = new ProtoOutputStream(bytes);

@@ -1267,6 +1267,10 @@ public final class ZenPolicy implements Parcelable {
        proto.write(DNDPolicyProto.ALLOW_MESSAGES_FROM, getPriorityMessageSenders());
        proto.write(DNDPolicyProto.ALLOW_CONVERSATIONS_FROM, getPriorityConversationSenders());

        if (Flags.modesApi()) {
            proto.write(DNDPolicyProto.ALLOW_CHANNELS, getAllowedChannels());
        }

        proto.flush();
        return bytes.toByteArray();
    }
+10 −0
Original line number Diff line number Diff line
@@ -359,6 +359,8 @@ message DNDPolicyProto {
    optional PeopleType allow_messages_from = 18;

    optional ConversationType allow_conversations_from = 19;

    optional ChannelType allow_channels = 20;
}

// Enum identifying the type of rule that changed; values set to match ones used in the
@@ -368,3 +370,11 @@ enum RuleType {
    RULE_TYPE_MANUAL = 1;
    RULE_TYPE_AUTOMATIC = 2;
}

// Enum used in DNDPolicyProto to indicate the type of channels permitted to
// break through DND. Mirrors values in ZenPolicy.
enum ChannelType {
    CHANNEL_TYPE_UNSET = 0;
    CHANNEL_TYPE_PRIORITY = 1;
    CHANNEL_TYPE_NONE = 2;
}
+8 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static android.service.notification.NotificationServiceProto.RULE_TYPE_MA
import static android.service.notification.NotificationServiceProto.RULE_TYPE_UNKNOWN;

import android.annotation.NonNull;
import android.app.Flags;
import android.app.NotificationManager;
import android.content.pm.PackageManager;
import android.os.Process;
@@ -502,6 +503,13 @@ class ZenModeEventLogger {
                        ZenModeConfig.getZenPolicySenders(mNewPolicy.allowMessagesFrom()));
                proto.write(DNDPolicyProto.ALLOW_CONVERSATIONS_FROM,
                        mNewPolicy.allowConversationsFrom());

                if (Flags.modesApi()) {
                    proto.write(DNDPolicyProto.ALLOW_CHANNELS,
                            mNewPolicy.allowPriorityChannels()
                                    ? ZenPolicy.CHANNEL_TYPE_PRIORITY
                                    : ZenPolicy.CHANNEL_TYPE_NONE);
                }
            } else {
                Log.wtf(TAG, "attempted to write zen mode log event with null policy");
            }
+132 −0
Original line number Diff line number Diff line
@@ -1051,6 +1051,88 @@ public class ZenModeHelperTest extends UiServiceTestCase {
        assertEquals("default ID(s) not found", 0, ids.size());
    }

    @Test
    public void testProtoWithAutoRuleCustomPolicy_classic() throws Exception {
        setupZenConfig();
        // clear any automatic rules just to make sure
        mZenModeHelper.mConfig.automaticRules = new ArrayMap<>();

        // Add an automatic rule with a custom policy
        ZenRule rule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS, CUSTOM_RULE_ID);
        rule.zenPolicy = new ZenPolicy.Builder()
                .allowAlarms(true)
                .allowRepeatCallers(false)
                .allowCalls(PEOPLE_TYPE_STARRED)
                .build();
        mZenModeHelper.mConfig.automaticRules.put(rule.id, rule);
        List<StatsEvent> events = new LinkedList<>();
        mZenModeHelper.pullRules(events);

        boolean foundCustomEvent = false;
        for (StatsEvent ev : events) {
            AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev);
            assertTrue(atom.hasDndModeRule());
            DNDModeProto cfg = atom.getDndModeRule();
            if (cfg.getUid() == CUSTOM_PKG_UID) {
                foundCustomEvent = true;
                // Check that the pieces of the policy are applied.
                assertThat(cfg.hasPolicy()).isTrue();
                DNDPolicyProto policy = cfg.getPolicy();
                assertThat(policy.getAlarms().getNumber()).isEqualTo(DNDProtoEnums.STATE_ALLOW);
                assertThat(policy.getRepeatCallers().getNumber())
                        .isEqualTo(DNDProtoEnums.STATE_DISALLOW);
                assertThat(policy.getCalls().getNumber()).isEqualTo(DNDProtoEnums.STATE_ALLOW);
                assertThat(policy.getAllowCallsFrom().getNumber())
                        .isEqualTo(DNDProtoEnums.PEOPLE_STARRED);
            }
        }
        assertTrue("couldn't find custom rule", foundCustomEvent);
    }

    @Test
    public void testProtoWithAutoRuleCustomPolicy() throws Exception {
        // allowChannels is only valid under modes_api.
        mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API);

        setupZenConfig();
        // clear any automatic rules just to make sure
        mZenModeHelper.mConfig.automaticRules = new ArrayMap<>();

        // Add an automatic rule with a custom policy
        ZenRule rule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS, CUSTOM_RULE_ID);
        rule.zenPolicy = new ZenPolicy.Builder()
                .allowAlarms(true)
                .allowRepeatCallers(false)
                .allowCalls(PEOPLE_TYPE_STARRED)
                .allowChannels(ZenPolicy.CHANNEL_TYPE_NONE)
                .build();
        mZenModeHelper.mConfig.automaticRules.put(rule.id, rule);
        List<StatsEvent> events = new LinkedList<>();
        mZenModeHelper.pullRules(events);

        boolean foundCustomEvent = false;
        for (StatsEvent ev : events) {
            AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev);
            assertTrue(atom.hasDndModeRule());
            DNDModeProto cfg = atom.getDndModeRule();
            if (cfg.getUid() == CUSTOM_PKG_UID) {
                foundCustomEvent = true;
                // Check that the pieces of the policy are applied.
                assertThat(cfg.hasPolicy()).isTrue();
                DNDPolicyProto policy = cfg.getPolicy();
                assertThat(policy.getAlarms().getNumber()).isEqualTo(DNDProtoEnums.STATE_ALLOW);
                assertThat(policy.getRepeatCallers().getNumber())
                        .isEqualTo(DNDProtoEnums.STATE_DISALLOW);
                assertThat(policy.getCalls().getNumber()).isEqualTo(DNDProtoEnums.STATE_ALLOW);
                assertThat(policy.getAllowCallsFrom().getNumber())
                        .isEqualTo(DNDProtoEnums.PEOPLE_STARRED);
                assertThat(policy.getAllowChannels().getNumber())
                        .isEqualTo(DNDProtoEnums.CHANNEL_TYPE_NONE);
            }
        }
        assertTrue("couldn't find custom rule", foundCustomEvent);
    }

    @Test
    public void ruleUidsCached() throws Exception {
        setupZenConfig();
@@ -2721,6 +2803,55 @@ public class ZenModeHelperTest extends UiServiceTestCase {
        assertEquals(12345, mZenModeEventLogger.getPackageUid(4));
    }

    @Test
    public void testZenModeEventLog_policyAllowChannels() {
        // when modes_api flag is on, ensure that any change in allow_channels gets logged,
        // even when there are no other changes.
        mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
        mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API);

        // Default zen config has allow channels = priority (aka on)
        setupZenConfig();

        // First just turn zen mode on
        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
                Process.SYSTEM_UID, true);

        // Now change only the channels part of the policy; want to confirm that this'll be
        // reflected in the logs
        ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
        newConfig.allowPriorityChannels = false;
        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
                true);

        // Total events: one for turning on, one for changing policy
        assertThat(mZenModeEventLogger.numLoggedChanges()).isEqualTo(2);

        // The first event is just turning DND on; make sure the policy is what we expect there
        // before it changes in the next stage
        assertThat(mZenModeEventLogger.getEventId(0))
                .isEqualTo(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId());
        DNDPolicyProto origDndProto = mZenModeEventLogger.getPolicyProto(0);
        checkDndProtoMatchesSetupZenConfig(origDndProto);
        assertThat(origDndProto.getAllowChannels().getNumber())
                .isEqualTo(DNDProtoEnums.CHANNEL_TYPE_PRIORITY);

        // Second message where we change the policy:
        //   - DND_POLICY_CHANGED (indicates only the policy changed and nothing else)
        //   - rule type: unknown (it's a policy change, not a rule change)
        //   - user action (because it comes from a "system" uid)
        //   - change is in allow channels, and final policy
        assertThat(mZenModeEventLogger.getEventId(1))
                .isEqualTo(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId());
        assertThat(mZenModeEventLogger.getChangedRuleType(1))
                .isEqualTo(DNDProtoEnums.UNKNOWN_RULE);
        assertThat(mZenModeEventLogger.getIsUserAction(1)).isTrue();
        assertThat(mZenModeEventLogger.getPackageUid(1)).isEqualTo(Process.SYSTEM_UID);
        DNDPolicyProto dndProto = mZenModeEventLogger.getPolicyProto(1);
        assertThat(dndProto.getAllowChannels().getNumber())
                .isEqualTo(DNDProtoEnums.CHANNEL_TYPE_NONE);
    }

    @Test
    public void testUpdateConsolidatedPolicy_defaultRulesOnly() {
        setupZenConfig();
@@ -3416,6 +3547,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
        return rule;
    }

    // TODO: b/310620812 - Update setup methods to include allowChannels() when MODES_API is inlined
    private void setupZenConfig() {
        mZenModeHelper.mZenMode = ZEN_MODE_OFF;
        mZenModeHelper.mConfig.allowAlarms = false;