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

Commit c888d516 authored by Mady Mellor's avatar Mady Mellor
Browse files

Apps that hold SAW perm on restore get bubble all by default

Test: atest PreferenceHelperTest
Test: manual - flash this to a phone with  an app that
               holds SAW perm, check that that app has
               "bubble all" by default in settings
Bug: 138116133
Change-Id: I044634b3feb02b71d6c6b73a1ea268a523944122
parent 02c8566b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1959,7 +1959,8 @@ public class NotificationManagerService extends SystemService {
                mPackageManagerClient,
                mRankingHandler,
                mZenModeHelper,
                new NotificationChannelLoggerImpl());
                new NotificationChannelLoggerImpl(),
                mAppOps);
        mRankingHelper = new RankingHelper(getContext(),
                mRankingHandler,
                mPreferencesHelper,
+30 −4
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@

package com.android.server.notification;

import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
@@ -30,6 +32,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
@@ -79,7 +82,9 @@ import java.util.concurrent.ConcurrentHashMap;

public class PreferencesHelper implements RankingConfig {
    private static final String TAG = "NotificationPrefHelper";
    private static final int XML_VERSION = 1;
    private static final int XML_VERSION = 2;
    /** What version to check to do the upgrade for bubbles. */
    private static final int XML_VERSION_BUBBLES_UPGRADE = 1;
    private static final int UNKNOWN_UID = UserHandle.USER_NULL;
    private static final String NON_BLOCKABLE_CHANNEL_DELIM = ":";

@@ -151,6 +156,7 @@ public class PreferencesHelper implements RankingConfig {
    private final RankingHandler mRankingHandler;
    private final ZenModeHelper mZenModeHelper;
    private final NotificationChannelLogger mNotificationChannelLogger;
    private final AppOpsManager mAppOps;

    private SparseBooleanArray mBadgingEnabled;
    private boolean mBubblesEnabledGlobally = DEFAULT_GLOBAL_ALLOW_BUBBLE;
@@ -167,12 +173,14 @@ public class PreferencesHelper implements RankingConfig {
    }

    public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
            ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger) {
            ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger,
            AppOpsManager appOpsManager) {
        mContext = context;
        mZenModeHelper = zenHelper;
        mRankingHandler = rankingHandler;
        mPm = pm;
        mNotificationChannelLogger = notificationChannelLogger;
        mAppOps = appOpsManager;

        // STOPSHIP (b/142218092) this should be removed before ship
        if (!wasBadgingForcedTrue(context)) {
@@ -195,6 +203,15 @@ public class PreferencesHelper implements RankingConfig {
        if (type != XmlPullParser.START_TAG) return;
        String tag = parser.getName();
        if (!TAG_RANKING.equals(tag)) return;

        boolean upgradeForBubbles = false;
        if (parser.getAttributeCount() > 0) {
            String attribute = parser.getAttributeName(0);
            if (ATT_VERSION.equals(attribute)) {
                int xmlVersion = Integer.parseInt(parser.getAttributeValue(0));
                upgradeForBubbles = xmlVersion == XML_VERSION_BUBBLES_UPGRADE;
            }
        }
        synchronized (mPackagePreferences) {
            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
                tag = parser.getName();
@@ -220,6 +237,16 @@ public class PreferencesHelper implements RankingConfig {
                                }
                            }
                            boolean skipWarningLogged = false;
                            boolean hasSAWPermission = false;
                            if (upgradeForBubbles) {
                                hasSAWPermission = mAppOps.noteOpNoThrow(
                                        OP_SYSTEM_ALERT_WINDOW, uid, name, null,
                                        "check-notif-bubble") == AppOpsManager.MODE_ALLOWED;
                            }
                            int bubblePref = hasSAWPermission
                                    ? BUBBLE_PREFERENCE_ALL
                                    : XmlUtils.readIntAttribute(parser, ATT_ALLOW_BUBBLE,
                                            DEFAULT_BUBBLE_PREFERENCE);

                            PackagePreferences r = getOrCreatePackagePreferencesLocked(
                                    name, userId, uid,
@@ -231,8 +258,7 @@ public class PreferencesHelper implements RankingConfig {
                                            parser, ATT_VISIBILITY, DEFAULT_VISIBILITY),
                                    XmlUtils.readBooleanAttribute(
                                            parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE),
                                    XmlUtils.readIntAttribute(
                                            parser, ATT_ALLOW_BUBBLE, DEFAULT_BUBBLE_PREFERENCE));
                                    bubblePref);
                            r.importance = XmlUtils.readIntAttribute(
                                    parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
                            r.priority = XmlUtils.readIntAttribute(
+97 −18
Original line number Diff line number Diff line
@@ -15,6 +15,9 @@
 */
package com.android.server.notification;

import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_DEFAULT;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
@@ -50,6 +53,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
@@ -132,6 +136,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
    @Spy IContentProvider mTestIContentProvider = new MockIContentProvider();
    @Mock Context mContext;
    @Mock ZenModeHelper mMockZenModeHelper;
    @Mock AppOpsManager mAppOpsManager;

    private NotificationManager.Policy mTestNotificationPolicy;

@@ -187,7 +192,10 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
                NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
        when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(),
                anyString(), eq(null), anyString())).thenReturn(MODE_DEFAULT);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);
        resetZenModeHelper();

        mAudioAttributes = new AudioAttributes.Builder()
@@ -1464,7 +1472,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
                NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
        when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);
        assertFalse(mHelper.areChannelsBypassingDnd());
        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
        resetZenModeHelper();
@@ -1475,7 +1484,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        // start notification policy off with mAreChannelsBypassingDnd = false
        mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0, 0);
        when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);
        assertFalse(mHelper.areChannelsBypassingDnd());
        verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
        resetZenModeHelper();
@@ -2241,7 +2251,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
                + "</package>\n"
                + "</ranking>\n";
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);
        loadByteArrayXml(preQXml.getBytes(), true, UserHandle.USER_SYSTEM);

        assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
@@ -2253,7 +2264,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        mHelper.setHideSilentStatusIcons(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);

        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);
        loadStreamXml(baos, false, UserHandle.USER_ALL);

        assertEquals(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
@@ -2349,7 +2361,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);

        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);
        loadStreamXml(baos, false, UserHandle.USER_ALL);

        assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2360,7 +2373,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);

        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);
        loadStreamXml(baos, false, UserHandle.USER_ALL);

        assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2372,7 +2386,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        mHelper.revokeNotificationDelegate(PKG_O, UID_O);

        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);
        loadStreamXml(baos, false, UserHandle.USER_ALL);

        assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2384,7 +2399,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);

        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);
        loadStreamXml(baos, false, UserHandle.USER_ALL);

        // appears disabled
@@ -2402,7 +2418,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        mHelper.revokeNotificationDelegate(PKG_O, UID_O);

        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);
        loadStreamXml(baos, false, UserHandle.USER_ALL);

        // appears disabled
@@ -2417,14 +2434,71 @@ public class PreferencesHelperTest extends UiServiceTestCase {

    @Test
    public void testBubblePreference_defaults() throws Exception {
        assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
        assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O));

        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);
        loadStreamXml(baos, false, UserHandle.USER_ALL);

        assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
        assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O));
        assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
    }

    @Test
    public void testBubblePreference_upgradeWithSAWPermission() throws Exception {
        when(mAppOpsManager.noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(),
                anyString(), eq(null), anyString())).thenReturn(MODE_ALLOWED);

        final String xml = "<ranking version=\"1\">\n"
                + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\">\n"
                + "<channel id=\"someId\" name=\"hi\""
                + " importance=\"3\"/>"
                + "</package>"
                + "</ranking>";
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
                null);
        parser.nextTag();
        mHelper.readXml(parser, false, UserHandle.USER_ALL);

        assertEquals(BUBBLE_PREFERENCE_ALL, mHelper.getBubblePreference(PKG_O, UID_O));
        assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
    }

    @Test
    public void testBubblePreference_upgradeWithSAWThenUserOverride() throws Exception {
        when(mAppOpsManager.noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(),
                anyString(), eq(null), anyString())).thenReturn(MODE_ALLOWED);

        final String xml = "<ranking version=\"1\">\n"
                + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\">\n"
                + "<channel id=\"someId\" name=\"hi\""
                + " importance=\"3\"/>"
                + "</package>"
                + "</ranking>";
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
                null);
        parser.nextTag();
        mHelper.readXml(parser, false, UserHandle.USER_ALL);

        assertEquals(BUBBLE_PREFERENCE_ALL, mHelper.getBubblePreference(PKG_O, UID_O));
        assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));

        mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_SELECTED);
        assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O));
        assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
                mHelper.getAppLockedFields(PKG_O, UID_O));

        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);
        loadStreamXml(baos, false, UserHandle.USER_ALL);

        assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O));
        assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
                mHelper.getAppLockedFields(PKG_O, UID_O));
    }

    @Test
@@ -2435,7 +2509,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
                mHelper.getAppLockedFields(PKG_O, UID_O));

        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);
        loadStreamXml(baos, false, UserHandle.USER_ALL);

        assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
@@ -2949,7 +3024,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0);

        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);

        final String xml = "<ranking version=\"1\">\n"
                + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
@@ -2969,7 +3045,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
    public void testPlaceholderConversationId_shortcutRequired() throws Exception {
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);

        final String xml = "<ranking version=\"1\">\n"
                + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
@@ -2989,7 +3066,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
    public void testNormalConversationId_shortcutRequired() throws Exception {
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);

        final String xml = "<ranking version=\"1\">\n"
                + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
@@ -3009,7 +3087,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
    public void testNoConversationId_shortcutRequired() throws Exception {
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
        mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
                mAppOpsManager);

        final String xml = "<ranking version=\"1\">\n"
                + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"