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

Commit 9cf627f9 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Enable specific bundles to be enabled/disabled

Test: NotificationAssistantsTest
Test: NotificationAssistantServiceTest
Bug: 376476949
Flag: android.service.notification.notification_classification

Change-Id: Ia798f212e1c70afb2a829c49e4a7079b5122ff74
parent d9b1b338
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -401,6 +401,7 @@ package android.app {
    method @FlaggedApi("android.service.notification.notification_classification") @NonNull public java.util.Set<java.lang.String> getUnsupportedAdjustmentTypes();
    method public boolean isNotificationPolicyAccessGrantedForPackage(@NonNull String);
    method @FlaggedApi("android.app.modes_api") public boolean removeAutomaticZenRule(@NonNull String, boolean);
    method @FlaggedApi("android.service.notification.notification_classification") public void setAssistantAdjustmentKeyTypeState(int, boolean);
    method @FlaggedApi("android.app.api_rich_ongoing") public void setCanPostPromotedNotifications(@NonNull String, int, boolean);
    method @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS) public void setNotificationListenerAccessGranted(@NonNull android.content.ComponentName, boolean, boolean);
    method @RequiresPermission(android.Manifest.permission.MANAGE_TOAST_RATE_LIMITING) public void setToastRateLimitingEnabled(boolean);
+3 −0
Original line number Diff line number Diff line
@@ -266,4 +266,7 @@ interface INotificationManager

    void setAdjustmentTypeSupportedState(in INotificationListener token, String key, boolean supported);
    List<String> getUnsupportedAdjustmentTypes();

    int[] getAllowedAdjustmentKeyTypes();
    void setAssistantAdjustmentKeyTypeState(int type, boolean enabled);
}
+14 −0
Original line number Diff line number Diff line
@@ -1845,6 +1845,20 @@ public class NotificationManager {
        }
    }

    /**
     * @hide
     */
    @TestApi
    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
    public void setAssistantAdjustmentKeyTypeState(@Adjustment.Types int type, boolean enabled) {
        INotificationManager service = getService();
        try {
            service.setAssistantAdjustmentKeyTypeState(type, enabled);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * @hide
     */
+91 −6
Original line number Diff line number Diff line
@@ -473,6 +473,10 @@ public class NotificationManagerService extends SystemService {
            Adjustment.KEY_TYPE
    };
    static final Integer[] DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES = new Integer[] {
            TYPE_PROMOTION
    };
    static final String[] NON_BLOCKABLE_DEFAULT_ROLES = new String[] {
            RoleManager.ROLE_DIALER,
            RoleManager.ROLE_EMERGENCY
@@ -4187,6 +4191,22 @@ public class NotificationManagerService extends SystemService {
            }
        }
        @Override
        @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
        public @NonNull int[] getAllowedAdjustmentKeyTypes() {
            checkCallerIsSystemOrSystemUiOrShell();
            return mAssistants.getAllowedAdjustmentKeyTypes();
        }
        @Override
        @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
        public void setAssistantAdjustmentKeyTypeState(int type, boolean enabled) {
            checkCallerIsSystemOrSystemUiOrShell();
            mAssistants.setAssistantAdjustmentKeyTypeState(type, enabled);
            handleSavePolicyFile();
        }
        @Override
        @FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
        public boolean appCanBePromoted(String pkg, int uid) {
@@ -6949,12 +6969,16 @@ public class NotificationManagerService extends SystemService {
                if (!mAssistants.isAdjustmentAllowed(potentialKey)) {
                    toRemove.add(potentialKey);
                }
                if (notificationClassification() && adjustments.containsKey(KEY_TYPE)) {
                    if (!mAssistants.isAdjustmentKeyTypeAllowed(adjustments.getInt(KEY_TYPE))) {
                        toRemove.add(potentialKey);
                    }
                }
            }
            for (String removeKey : toRemove) {
                adjustments.remove(removeKey);
            }
            if (android.service.notification.Flags.notificationClassification()
                    && adjustments.containsKey(KEY_TYPE)) {
            if (notificationClassification() && adjustments.containsKey(KEY_TYPE)) {
                final NotificationChannel newChannel = getClassificationChannelLocked(r,
                        adjustments);
                if (newChannel == null || newChannel.getId().equals(r.getChannel().getId())) {
@@ -11514,10 +11538,14 @@ public class NotificationManagerService extends SystemService {
        private static final String ATT_TYPES = "types";
        private static final String ATT_DENIED = "denied_adjustments";
        private static final String ATT_ENABLED_TYPES = "enabled_key_types";
        private static final String ATT_NAS_UNSUPPORTED = "unsupported_adjustments";
        private final Object mLock = new Object();
        @GuardedBy("mLock")
        private Set<Integer> mAllowedAdjustmentKeyTypes = new ArraySet<>();
        @GuardedBy("mLock")
        private Set<String> mAllowedAdjustments = new ArraySet<>();
@@ -11601,6 +11629,8 @@ public class NotificationManagerService extends SystemService {
                for (int i = 0; i < DEFAULT_ALLOWED_ADJUSTMENTS.length; i++) {
                    mAllowedAdjustments.add(DEFAULT_ALLOWED_ADJUSTMENTS[i]);
                }
            } else {
                mAllowedAdjustmentKeyTypes.addAll(List.of(DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES));
            }
        }
@@ -11688,6 +11718,42 @@ public class NotificationManagerService extends SystemService {
            }
        }
        @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
        protected @NonNull boolean isAdjustmentKeyTypeAllowed(@Adjustment.Types int type) {
            synchronized (mLock) {
                if (notificationClassification()) {
                    return mAllowedAdjustmentKeyTypes.contains(type);
                }
            }
            return false;
        }
        @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
        protected @NonNull int[] getAllowedAdjustmentKeyTypes() {
            synchronized (mLock) {
                if (notificationClassification()) {
                    return mAllowedAdjustmentKeyTypes.stream()
                            .mapToInt(Integer::intValue).toArray();
                }
            }
            return new int[]{};
        }
        @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
        public void setAssistantAdjustmentKeyTypeState(@Adjustment.Types int type,
                boolean enabled) {
            if (!android.service.notification.Flags.notificationClassification()) {
                return;
            }
            synchronized (mLock) {
                if (enabled) {
                    mAllowedAdjustmentKeyTypes.add(type);
                } else {
                    mAllowedAdjustmentKeyTypes.remove(type);
                }
            }
        }
        protected void onNotificationsSeenLocked(ArrayList<NotificationRecord> records) {
            for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) {
                ArrayList<String> keys = new ArrayList<>(records.size());
@@ -12127,27 +12193,46 @@ public class NotificationManagerService extends SystemService {
        @Override
        protected void writeExtraXmlTags(TypedXmlSerializer out) throws IOException {
            if (!android.service.notification.Flags.notificationClassification()) {
            if (!notificationClassification()) {
                return;
            }
            synchronized (mLock) {
                out.startTag(null, ATT_DENIED);
                out.attribute(null, ATT_TYPES, TextUtils.join(",", mDeniedAdjustments));
                out.endTag(null, ATT_DENIED);
                out.startTag(null, ATT_ENABLED_TYPES);
                out.attribute(null, ATT_TYPES,
                        TextUtils.join(",", mAllowedAdjustmentKeyTypes));
                out.endTag(null, ATT_ENABLED_TYPES);
            }
        }
        @Override
        protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException {
            if (!android.service.notification.Flags.notificationClassification()) {
            if (!notificationClassification()) {
                return;
            }
            if (ATT_DENIED.equals(tag)) {
                final String types = XmlUtils.readStringAttribute(parser, ATT_TYPES);
                final String keys = XmlUtils.readStringAttribute(parser, ATT_TYPES);
                synchronized (mLock) {
                    mDeniedAdjustments.clear();
                    if (!TextUtils.isEmpty(keys)) {
                        mDeniedAdjustments.addAll(Arrays.asList(keys.split(",")));
                    }
                }
            } else if (ATT_ENABLED_TYPES.equals(tag)) {
                final String types = XmlUtils.readStringAttribute(parser, ATT_TYPES);
                synchronized (mLock) {
                    mAllowedAdjustmentKeyTypes.clear();
                    if (!TextUtils.isEmpty(types)) {
                        mDeniedAdjustments.addAll(Arrays.asList(types.split(",")));
                        List<String> typeList = Arrays.asList(types.split(","));
                        for (String type : typeList) {
                            try {
                                mAllowedAdjustmentKeyTypes.add(Integer.parseInt(type));
                            } catch (NumberFormatException e) {
                                Slog.wtf(TAG, "Bad type specified", e);
                            }
                        }
                    }
                }
            }
+48 −0
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@ package com.android.server.notification;

import static android.os.UserHandle.USER_ALL;
import static android.service.notification.Adjustment.KEY_IMPORTANCE;
import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION;
import static android.service.notification.Adjustment.TYPE_NEWS;
import static android.service.notification.Adjustment.TYPE_PROMOTION;

import static com.android.server.notification.NotificationManagerService.DEFAULT_ALLOWED_ADJUSTMENTS;

@@ -58,6 +61,8 @@ import android.testing.TestableContext;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IntArray;
import android.util.Log;
import android.util.Slog;
import android.util.Xml;

import androidx.test.runner.AndroidJUnit4;
@@ -690,4 +695,47 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
        assertThat(mAssistants.getAllowedAssistantAdjustments())
                .containsExactlyElementsIn(DEFAULT_ALLOWED_ADJUSTMENTS);
    }

    @Test
    @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
    public void testSetAssistantAdjustmentKeyTypeState_allow() {
        assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList()
                .containsExactly(TYPE_PROMOTION);

        mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, true);

        assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList()
                .containsExactlyElementsIn(List.of(TYPE_PROMOTION, TYPE_CONTENT_RECOMMENDATION));
    }

    @Test
    @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
    public void testSetAssistantAdjustmentKeyTypeState_disallow() {
        mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_PROMOTION, false);
        assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).isEmpty();
    }

    @Test
    @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
    public void testDisallowAdjustmentKeyType_readWriteXml() throws Exception {
        mAssistants.loadDefaultsFromConfig(true);
        mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_PROMOTION, false);
        mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, true);
        mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, true);

        writeXmlAndReload(USER_ALL);

        assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList()
                .containsExactlyElementsIn(List.of(TYPE_NEWS, TYPE_CONTENT_RECOMMENDATION));
    }

    @Test
    public void testDefaultAllowedKeyAdjustments_readWriteXml() throws Exception {
        mAssistants.loadDefaultsFromConfig(true);

        writeXmlAndReload(USER_ALL);

        assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList()
                .containsExactly(TYPE_PROMOTION);
    }
}
 No newline at end of file
Loading