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

Commit 044600fe authored by Matías Hernández's avatar Matías Hernández
Browse files

Add ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED broadcast

Also include the updated Policy as an extra (for both this broadcast and ACTION_NOTIFICATION_POLICY_CHANGED) so that apps don't need to do an extra call to retrieve them.

Fixes: 311679701
Test: atest ZenModeHelperTest NotificationManagerZenTest
Change-Id: Ie74027c577477f032531a7c653f678673c52db7e
parent 08dd4252
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -6988,6 +6988,7 @@ package android.app {
    field public static final String ACTION_APP_BLOCK_STATE_CHANGED = "android.app.action.APP_BLOCK_STATE_CHANGED";
    field public static final String ACTION_AUTOMATIC_ZEN_RULE = "android.app.action.AUTOMATIC_ZEN_RULE";
    field public static final String ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED = "android.app.action.AUTOMATIC_ZEN_RULE_STATUS_CHANGED";
    field @FlaggedApi("android.app.modes_api") public static final String ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED = "android.app.action.CONSOLIDATED_NOTIFICATION_POLICY_CHANGED";
    field public static final String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
    field public static final String ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED = "android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED";
    field public static final String ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED = "android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED";
@@ -7008,6 +7009,7 @@ package android.app {
    field public static final String EXTRA_BLOCKED_STATE = "android.app.extra.BLOCKED_STATE";
    field public static final String EXTRA_NOTIFICATION_CHANNEL_GROUP_ID = "android.app.extra.NOTIFICATION_CHANNEL_GROUP_ID";
    field public static final String EXTRA_NOTIFICATION_CHANNEL_ID = "android.app.extra.NOTIFICATION_CHANNEL_ID";
    field @FlaggedApi("android.app.modes_api") public static final String EXTRA_NOTIFICATION_POLICY = "android.app.extra.NOTIFICATION_POLICY";
    field public static final int IMPORTANCE_DEFAULT = 3; // 0x3
    field public static final int IMPORTANCE_HIGH = 4; // 0x4
    field public static final int IMPORTANCE_LOW = 2; // 0x2
+21 −0
Original line number Diff line number Diff line
@@ -378,6 +378,27 @@ public class NotificationManager {
    public static final String ACTION_NOTIFICATION_POLICY_CHANGED
            = "android.app.action.NOTIFICATION_POLICY_CHANGED";

    /**
     * Intent that is broadcast when the state of {@link #getConsolidatedNotificationPolicy()}
     * changes.
     *
     * <p>This broadcast is only sent to registered receivers and receivers in packages that have
     * been granted Do Not Disturb access (see {@link #isNotificationPolicyAccessGranted()}).
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED =
            "android.app.action.CONSOLIDATED_NOTIFICATION_POLICY_CHANGED";

    /**
     * Extra for {@link #ACTION_NOTIFICATION_POLICY_CHANGED} and
     * {@link #ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED} containing the new
     * {@link Policy} value.
     */
    @FlaggedApi(Flags.FLAG_MODES_API)
    public static final String EXTRA_NOTIFICATION_POLICY =
            "android.app.extra.NOTIFICATION_POLICY";

    /**
     * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
     *
+21 −6
Original line number Diff line number Diff line
@@ -44,15 +44,18 @@ import static android.app.Notification.FLAG_USER_INITIATED_JOB;
import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT;
import static android.app.NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED;
import static android.app.NotificationManager.ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED;
import static android.app.NotificationManager.ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED;
import static android.app.NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED;
import static android.app.NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL;
import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED;
import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED;
import static android.app.NotificationManager.ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED;
import static android.app.NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED;
import static android.app.NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
import static android.app.NotificationManager.EXTRA_AUTOMATIC_ZEN_RULE_ID;
import static android.app.NotificationManager.EXTRA_AUTOMATIC_ZEN_RULE_STATUS;
import static android.app.NotificationManager.EXTRA_NOTIFICATION_POLICY;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_MIN;
@@ -2506,17 +2509,25 @@ public class NotificationManagerService extends SystemService {
            }
            @Override
            void onPolicyChanged() {
            void onPolicyChanged(Policy newPolicy) {
                Binder.withCleanCallingIdentity(() -> {
                    sendRegisteredOnlyBroadcast(
                            NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED);
                    Intent intent = new Intent(ACTION_NOTIFICATION_POLICY_CHANGED);
                    if (android.app.Flags.modesApi()) {
                        intent.putExtra(EXTRA_NOTIFICATION_POLICY, newPolicy);
                    }
                    sendRegisteredOnlyBroadcast(intent);
                    mRankingHandler.requestSort();
                });
            }
            @Override
            void onConsolidatedPolicyChanged() {
            void onConsolidatedPolicyChanged(Policy newConsolidatedPolicy) {
                Binder.withCleanCallingIdentity(() -> {
                    if (android.app.Flags.modesApi()) {
                        Intent intent = new Intent(ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED);
                        intent.putExtra(EXTRA_NOTIFICATION_POLICY, newConsolidatedPolicy);
                        sendRegisteredOnlyBroadcast(intent);
                    }
                    mRankingHandler.requestSort();
                });
            }
@@ -2934,15 +2945,19 @@ public class NotificationManagerService extends SystemService {
    }
    private void sendRegisteredOnlyBroadcast(String action) {
        sendRegisteredOnlyBroadcast(new Intent(action));
    }
    private void sendRegisteredOnlyBroadcast(Intent baseIntent) {
        int[] userIds = mUmInternal.getProfileIds(mAmi.getCurrentUserId(), true);
        Intent intent = new Intent(action).addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
        Intent intent = new Intent(baseIntent).addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
        for (int userId : userIds) {
            getContext().sendBroadcastAsUser(intent, UserHandle.of(userId), null);
        }
        // explicitly send the broadcast to all DND packages, even if they aren't currently running
        for (int userId : userIds) {
            for (String pkg : mConditionProviders.getAllowedPackages(userId)) {
                Intent pkgIntent = new Intent(action).setPackage(pkg).setFlags(
                Intent pkgIntent = new Intent(baseIntent).setPackage(pkg).setFlags(
                        Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                getContext().sendBroadcastAsUser(pkgIntent, UserHandle.of(userId));
            }
+10 −10
Original line number Diff line number Diff line
@@ -1716,10 +1716,10 @@ public class ZenModeHelper {
            ZenLog.traceConfig(reason, mConfig, config);

            // send some broadcasts
            final boolean policyChanged = !Objects.equals(getNotificationPolicy(mConfig),
                    getNotificationPolicy(config));
            Policy newPolicy = getNotificationPolicy(config);
            boolean policyChanged = !Objects.equals(getNotificationPolicy(mConfig), newPolicy);
            if (policyChanged) {
                dispatchOnPolicyChanged();
                dispatchOnPolicyChanged(newPolicy);
            }
            updateConfigAndZenModeLocked(config, origin, reason, setRingerMode, callingUid);
            mConditions.evaluateConfig(config, triggeringComponent, true /*processSubscriptions*/);
@@ -1929,7 +1929,7 @@ public class ZenModeHelper {
            Policy newPolicy = mConfig.toNotificationPolicy(policy);
            if (!Objects.equals(mConsolidatedPolicy, newPolicy)) {
                mConsolidatedPolicy = newPolicy;
                dispatchOnConsolidatedPolicyChanged();
                dispatchOnConsolidatedPolicyChanged(newPolicy);
                ZenLog.traceSetConsolidatedZenPolicy(mConsolidatedPolicy, reason);
            }

@@ -2097,15 +2097,15 @@ public class ZenModeHelper {
        }
    }

    private void dispatchOnPolicyChanged() {
    private void dispatchOnPolicyChanged(Policy newPolicy) {
        for (Callback callback : mCallbacks) {
            callback.onPolicyChanged();
            callback.onPolicyChanged(newPolicy);
        }
    }

    private void dispatchOnConsolidatedPolicyChanged() {
    private void dispatchOnConsolidatedPolicyChanged(Policy newConsolidatedPolicy) {
        for (Callback callback : mCallbacks) {
            callback.onConsolidatedPolicyChanged();
            callback.onConsolidatedPolicyChanged(newConsolidatedPolicy);
        }
    }

@@ -2631,8 +2631,8 @@ public class ZenModeHelper {
    public static class Callback {
        void onConfigChanged() {}
        void onZenModeChanged() {}
        void onPolicyChanged() {}
        void onConsolidatedPolicyChanged() {}
        void onPolicyChanged(Policy newPolicy) {}
        void onConsolidatedPolicyChanged(Policy newConsolidatedPolicy) {}
        void onAutomaticRuleStatusChanged(int userId, String pkg, String id, int status) {}
    }
}
+48 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_DISABLED;
import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_ENABLED;
import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS;
import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL;
import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
@@ -161,6 +162,7 @@ import com.android.server.notification.ManagedServices.UserProfiles;

import com.google.common.collect.ImmutableList;
import com.google.common.truth.Correspondence;
import com.google.common.util.concurrent.SettableFuture;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
@@ -5221,6 +5223,52 @@ public class ZenModeHelperTest extends UiServiceTestCase {
        return rule;
    }

    @Test
    @EnableFlags(android.app.Flags.FLAG_MODES_API)
    public void testCallbacks_policy() throws Exception {
        setupZenConfig();
        assertThat(mZenModeHelper.getNotificationPolicy().allowReminders()).isTrue();
        SettableFuture<Policy> futurePolicy = SettableFuture.create();
        mZenModeHelper.addCallback(new ZenModeHelper.Callback() {
            @Override
            void onPolicyChanged(Policy newPolicy) {
                futurePolicy.set(newPolicy);
            }
        });

        Policy totalSilencePolicy = new Policy(0, 0, 0);
        mZenModeHelper.setNotificationPolicy(totalSilencePolicy, UPDATE_ORIGIN_APP, CUSTOM_PKG_UID);

        Policy callbackPolicy = futurePolicy.get(1, TimeUnit.SECONDS);
        assertThat(callbackPolicy.allowReminders()).isFalse();
    }

    @Test
    @EnableFlags(android.app.Flags.FLAG_MODES_API)
    public void testCallbacks_consolidatedPolicy() throws Exception {
        setupZenConfig();
        assertThat(mZenModeHelper.getConsolidatedNotificationPolicy().allowAlarms()).isTrue();
        SettableFuture<Policy> futureConsolidatedPolicy = SettableFuture.create();
        mZenModeHelper.addCallback(new ZenModeHelper.Callback() {
            @Override
            void onConsolidatedPolicyChanged(Policy newConsolidatedPolicy) {
                futureConsolidatedPolicy.set(newConsolidatedPolicy);
            }
        });

        String totalSilenceRuleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(),
                new AutomaticZenRule.Builder("Rule", CONDITION_ID)
                        .setOwner(OWNER)
                        .setInterruptionFilter(INTERRUPTION_FILTER_NONE)
                        .build(),
                UPDATE_ORIGIN_APP, "reasons", 0);
        mZenModeHelper.setAutomaticZenRuleState(totalSilenceRuleId,
                new Condition(CONDITION_ID, "", STATE_TRUE), UPDATE_ORIGIN_APP, CUSTOM_PKG_UID);

        Policy callbackPolicy = futureConsolidatedPolicy.get(1, TimeUnit.SECONDS);
        assertThat(callbackPolicy.allowAlarms()).isFalse();
    }

    @Test
    public void applyGlobalZenModeAsImplicitZenRule_createsImplicitRuleAndActivatesIt() {
        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API);