OSDN Git Service

Fix default app notification locking on new devices
authorJulia Reynolds <juliacr@google.com>
Thu, 25 Apr 2019 19:41:47 +0000 (15:41 -0400)
committerJulia Reynolds <juliacr@google.com>
Thu, 25 Apr 2019 21:18:03 +0000 (21:18 +0000)
- Fresh devices, no restore, create app prefs if app hasn't done
it already
- Apply app level locking to channels created via readxml on restore

Test: atest, factory reset device and verify that default dialer app is
locked without requiring a reboot. restore backup and verify that it's
still locked
Fixes: 127855529

Change-Id: Ieca3e064eb5b5aa5877a4b575bf6223f62259668

services/core/java/com/android/server/notification/NotificationManagerService.java
services/core/java/com/android/server/notification/PreferencesHelper.java
services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java

index 9fc30eb..e2033c6 100644 (file)
@@ -46,6 +46,7 @@ import static android.content.Context.BIND_AUTO_CREATE;
 import static android.content.Context.BIND_FOREGROUND_SERVICE;
 import static android.content.pm.PackageManager.FEATURE_LEANBACK;
 import static android.content.pm.PackageManager.FEATURE_TELEVISION;
+import static android.content.pm.PackageManager.MATCH_ALL;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -191,6 +192,7 @@ import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.IntArray;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.Xml;
@@ -1880,7 +1882,7 @@ public class NotificationManagerService extends SystemService {
             mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
             mZenModeHelper.onSystemReady();
             mRoleObserver = new RoleObserver(getContext().getSystemService(RoleManager.class),
-                    getContext().getMainExecutor());
+                    mPackageManager, getContext().getMainExecutor());
             mRoleObserver.init();
         } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
             // This observer will force an update when observe is called, causing us to
@@ -8219,11 +8221,14 @@ public class NotificationManagerService extends SystemService {
         private ArrayMap<String, ArrayMap<Integer, ArraySet<String>>> mNonBlockableDefaultApps;
 
         private final RoleManager mRm;
+        private final IPackageManager mPm;
         private final Executor mExecutor;
 
         RoleObserver(@NonNull RoleManager roleManager,
+                @NonNull IPackageManager pkgMgr,
                 @NonNull @CallbackExecutor Executor executor) {
             mRm = roleManager;
+            mPm = pkgMgr;
             mExecutor = executor;
         }
 
@@ -8237,8 +8242,12 @@ public class NotificationManagerService extends SystemService {
                     Integer userId = users.get(j).getUserHandle().getIdentifier();
                     ArraySet<String> approvedForUserId = new ArraySet<>(mRm.getRoleHoldersAsUser(
                             NON_BLOCKABLE_DEFAULT_ROLES[i], UserHandle.of(userId)));
+                    ArraySet<Pair<String, Integer>> approvedAppUids = new ArraySet<>();
+                    for (String pkg : approvedForUserId) {
+                        approvedAppUids.add(new Pair(pkg, getUidForPackage(pkg, userId)));
+                    }
                     userToApprovedList.put(userId, approvedForUserId);
-                    mPreferencesHelper.updateDefaultApps(userId, null, approvedForUserId);
+                    mPreferencesHelper.updateDefaultApps(userId, null, approvedAppUids);
                 }
             }
 
@@ -8281,7 +8290,7 @@ public class NotificationManagerService extends SystemService {
                     prevApprovedForRole.getOrDefault(user.getIdentifier(), new ArraySet<>());
 
             ArraySet<String> toRemove = new ArraySet<>();
-            ArraySet<String> toAdd = new ArraySet<>();
+            ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
 
             for (String previous : previouslyApproved) {
                 if (!roleHolders.contains(previous)) {
@@ -8290,7 +8299,8 @@ public class NotificationManagerService extends SystemService {
             }
             for (String nowApproved : roleHolders) {
                 if (!previouslyApproved.contains(nowApproved)) {
-                    toAdd.add(nowApproved);
+                    toAdd.add(new Pair(nowApproved,
+                            getUidForPackage(nowApproved, user.getIdentifier())));
                 }
             }
 
@@ -8304,6 +8314,15 @@ public class NotificationManagerService extends SystemService {
             // RoleManager is the source of truth for this data so we don't need to trigger a
             // write of the notification policy xml for this change
         }
+
+        private int getUidForPackage(String pkg, int userId) {
+            try {
+                return mPm.getPackageUid(pkg, MATCH_ALL, userId);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "role manager has bad default " + pkg + " " + userId);
+            }
+            return -1;
+        }
     }
 
     public static final class DumpFilter {
index 9e16632..627b65c 100644 (file)
@@ -38,6 +38,7 @@ import android.service.notification.RankingHelperProto;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
 import android.util.proto.ProtoOutputStream;
@@ -236,6 +237,8 @@ public class PreferencesHelper implements RankingConfig {
                                         } else {
                                             channel.populateFromXml(parser);
                                         }
+                                        channel.setImportanceLockedByCriticalDeviceFunction(
+                                                r.defaultAppLockedImportance);
                                         r.channels.put(id, channel);
                                     }
                                 }
@@ -882,7 +885,8 @@ public class PreferencesHelper implements RankingConfig {
         }
     }
 
-    public void updateDefaultApps(int userId, ArraySet<String> toRemove, ArraySet<String> toAdd) {
+    public void updateDefaultApps(int userId, ArraySet<String> toRemove,
+            ArraySet<Pair<String, Integer>> toAdd) {
         synchronized (mPackagePreferences) {
             for (PackagePreferences p : mPackagePreferences.values()) {
                 if (userId == UserHandle.getUserId(p.uid)) {
@@ -891,11 +895,16 @@ public class PreferencesHelper implements RankingConfig {
                         for (NotificationChannel channel : p.channels.values()) {
                             channel.setImportanceLockedByCriticalDeviceFunction(false);
                         }
-                    } else if (toAdd != null && toAdd.contains(p.pkg)) {
-                        p.defaultAppLockedImportance = true;
-                        for (NotificationChannel channel : p.channels.values()) {
-                            channel.setImportanceLockedByCriticalDeviceFunction(true);
-                        }
+                    }
+                }
+            }
+            if (toAdd != null) {
+                for (Pair<String, Integer> approvedApp : toAdd) {
+                    PackagePreferences p = getOrCreatePackagePreferencesLocked(approvedApp.first,
+                            approvedApp.second);
+                    p.defaultAppLockedImportance = true;
+                    for (NotificationChannel channel : p.channels.values()) {
+                        channel.setImportanceLockedByCriticalDeviceFunction(true);
                     }
                 }
             }
@@ -1426,8 +1435,22 @@ public class PreferencesHelper implements RankingConfig {
                     pw.print(" visibility=");
                     pw.print(Notification.visibilityToString(r.visibility));
                 }
-                pw.print(" showBadge=");
-                pw.print(Boolean.toString(r.showBadge));
+                if (r.showBadge != DEFAULT_SHOW_BADGE) {
+                    pw.print(" showBadge=");
+                    pw.print(r.showBadge);
+                }
+                if (r.defaultAppLockedImportance != DEFAULT_APP_LOCKED_IMPORTANCE) {
+                    pw.print(" defaultAppLocked=");
+                    pw.print(r.defaultAppLockedImportance);
+                }
+                if (r.oemLockedImportance != DEFAULT_OEM_LOCKED_IMPORTANCE) {
+                    pw.print(" oemLocked=");
+                    pw.print(r.oemLockedImportance);
+                }
+                if (!r.futureOemLockedChannels.isEmpty()) {
+                    pw.print(" futureLockedChannels=");
+                    pw.print(r.futureOemLockedChannels);
+                }
                 pw.println();
                 for (NotificationChannel channel : r.channels.values()) {
                     pw.print(prefix);
index 1a06490..d1a3550 100644 (file)
@@ -63,6 +63,7 @@ import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.TestableContentResolver;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.Pair;
 import android.util.Xml;
 
 import com.android.internal.util.FastXmlSerializer;
@@ -1647,11 +1648,13 @@ public class PreferencesHelperTest extends UiServiceTestCase {
     public void testClearData() {
         ArraySet<String> pkg = new ArraySet<>();
         pkg.add(PKG_O);
+        ArraySet<Pair<String, Integer>> pkgPair = new ArraySet<>();
+        pkgPair.add(new Pair(PKG_O, UID_O));
         mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
         mHelper.createNotificationChannelGroup(
                 PKG_O, UID_O, new NotificationChannelGroup("1", "bye"), true);
         mHelper.lockChannelsForOEM(pkg.toArray(new String[]{}));
-        mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, pkg);
+        mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, pkgPair);
         mHelper.setNotificationDelegate(PKG_O, UID_O, "", 1);
         mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
         mHelper.setBubblesAllowed(PKG_O, UID_O, false);
@@ -2493,8 +2496,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
         mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
         mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true);
 
-        ArraySet<String> toAdd = new ArraySet<>();
-        toAdd.add(PKG_O);
+        ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
+        toAdd.add(new Pair(PKG_O, UID_O));
         mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
 
         assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
@@ -2513,8 +2516,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
         mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
 
-        ArraySet<String> toAdd = new ArraySet<>();
-        toAdd.add(PKG_O);
+        ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
+        toAdd.add(new Pair(PKG_O, UID_O));
         mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
 
 
@@ -2532,8 +2535,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
         mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
         mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
 
-        ArraySet<String> toAdd = new ArraySet<>();
-        toAdd.add(PKG_O);
+        ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
+        toAdd.add(new Pair(PKG_O, UID_O));
         mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
 
         assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
@@ -2558,8 +2561,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
         mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
 
-        ArraySet<String> toAdd = new ArraySet<>();
-        toAdd.add(PKG_O);
+        ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
+        toAdd.add(new Pair(PKG_O, UID_O));
         mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
 
 
@@ -2572,7 +2575,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
         ArraySet<String> toRemove = new ArraySet<>();
         toRemove.add(PKG_O);
         toAdd = new ArraySet<>();
-        toAdd.add(PKG_N_MR1);
+        toAdd.add(new Pair(PKG_N_MR1, UID_N_MR1));
         mHelper.updateDefaultApps(USER.getIdentifier(), toRemove, toAdd);
 
         assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
@@ -2583,8 +2586,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
 
     @Test
     public void testUpdateDefaultApps_appDoesNotExist_noCrash() {
-        ArraySet<String> toAdd = new ArraySet<>();
-        toAdd.add(PKG_O);
+        ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
+        toAdd.add(new Pair(PKG_O, UID_O));
         ArraySet<String> toRemove = new ArraySet<>();
         toRemove.add(PKG_N_MR1);
         mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, toAdd);
@@ -2596,8 +2599,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
         NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
         mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
 
-        ArraySet<String> toAdd = new ArraySet<>();
-        toAdd.add(PKG_O);
+        ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
+        toAdd.add(new Pair(PKG_O, UID_O));
         mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
 
         assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
@@ -2612,8 +2615,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
     public void testUpdateNotificationChannel_defaultAppLockedImportance() {
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
         mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
-        ArraySet<String> toAdd = new ArraySet<>();
-        toAdd.add(PKG_O);
+        ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
+        toAdd.add(new Pair(PKG_O, UID_O));
         mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
 
         NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
@@ -2631,4 +2634,43 @@ public class PreferencesHelperTest extends UiServiceTestCase {
         assertEquals(IMPORTANCE_HIGH,
                 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
     }
+
+    @Test
+    public void testDefaultApp_appHasNoSettingsYet() {
+        ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
+        toAdd.add(new Pair(PKG_O, UID_O));
+        mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
+
+        NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+
+        assertTrue(a.isImportanceLockedByCriticalDeviceFunction());
+    }
+
+    @Test
+    public void testChannelXml_backupDefaultApp() throws Exception {
+        NotificationChannel channel1 =
+                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
+
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel1, true, false);
+
+        // clear data
+        ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, true,
+                UserHandle.USER_SYSTEM, channel1.getId(), NotificationChannel.DEFAULT_CHANNEL_ID);
+        mHelper.onPackagesChanged(true, UserHandle.myUserId(), new String[]{PKG_O}, new int[]{
+                UID_O});
+
+        ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
+        toAdd.add(new Pair(PKG_O, UID_O));
+        mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
+
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
+                null);
+        parser.nextTag();
+        mHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
+
+        assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, channel1.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+    }
 }
index 7e3d4b4..20e3fe2 100644 (file)
 
 package com.android.server.notification;
 
-import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
-import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
-import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
-import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-import static android.app.NotificationManager.IMPORTANCE_LOW;
-import static android.app.NotificationManager.IMPORTANCE_MAX;
-import static android.app.NotificationManager.IMPORTANCE_NONE;
-import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
-import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
-import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
-import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
-import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
-import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
-import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
-import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
-import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
-import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
 import static android.app.role.RoleManager.ROLE_DIALER;
 import static android.app.role.RoleManager.ROLE_EMERGENCY;
 import static android.app.role.RoleManager.ROLE_SMS;
-import static android.content.pm.PackageManager.FEATURE_WATCH;
-import static android.content.pm.PackageManager.PERMISSION_DENIED;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.os.Build.VERSION_CODES.O_MR1;
-import static android.os.Build.VERSION_CODES.P;
-import static android.service.notification.Adjustment.KEY_IMPORTANCE;
-import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
-import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
-import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
-
-import static junit.framework.Assert.assertEquals;
+import static android.content.pm.PackageManager.MATCH_ALL;
+
 import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.fail;
 
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -74,94 +35,43 @@ import static org.mockito.Mockito.when;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
-import android.app.INotificationManager;
-import android.app.ITransientNotification;
 import android.app.IUriGrantsManager;
-import android.app.Notification;
-import android.app.Notification.MessagingStyle.Message;
-import android.app.NotificationChannel;
-import android.app.NotificationChannelGroup;
-import android.app.NotificationManager;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.app.role.RoleManager;
 import android.app.usage.UsageStatsManagerInternal;
 import android.companion.ICompanionDeviceManager;
-import android.content.ComponentName;
-import android.content.ContentUris;
 import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.pm.ParceledListSlice;
 import android.content.pm.UserInfo;
-import android.graphics.Color;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.IBinder;
 import android.os.Looper;
-import android.os.Process;
-import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.provider.DeviceConfig;
-import android.provider.MediaStore;
-import android.provider.Settings;
-import android.service.notification.Adjustment;
-import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationStats;
-import android.service.notification.NotifyingApp;
-import android.service.notification.StatusBarNotification;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableContext;
-import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
-import android.testing.TestablePermissions;
-import android.text.Html;
-import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
+import android.util.Pair;
 
-import com.android.internal.R;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
-import com.android.internal.statusbar.NotificationVisibility;
 import com.android.server.LocalServices;
 import com.android.server.UiServiceTestCase;
-import com.android.server.lights.Light;
 import com.android.server.lights.LightsManager;
 import com.android.server.notification.NotificationManagerService.NotificationAssistants;
 import com.android.server.notification.NotificationManagerService.NotificationListeners;
 import com.android.server.uri.UriGrantsManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.mockito.stubbing.Answer;
 
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.FileInputStream;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 import java.util.concurrent.Executor;
-import java.util.function.Consumer;
-
-import androidx.annotation.Nullable;
-import androidx.test.InstrumentationRegistry;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -175,6 +85,8 @@ public class RoleObserverTest extends UiServiceTestCase {
     @Mock
     private PreferencesHelper mPreferencesHelper;
     @Mock
+    private IPackageManager mPm;
+    @Mock
     private UserManager mUm;
     @Mock
     private Executor mExecutor;
@@ -214,7 +126,7 @@ public class RoleObserverTest extends UiServiceTestCase {
         when(mUm.getUsers()).thenReturn(mUsers);
 
         mService = new TestableNotificationManagerService(mContext);
-        mRoleObserver = mService.new RoleObserver(mRoleManager, mExecutor);
+        mRoleObserver = mService.new RoleObserver(mRoleManager, mPm, mExecutor);
 
         try {
             mService.init(mock(Looper.class),
@@ -238,13 +150,26 @@ public class RoleObserverTest extends UiServiceTestCase {
     }
 
     @Test
-    public void testInit() {
+    public void testInit() throws Exception {
         List<String> dialer0 = new ArrayList<>();
         dialer0.add("dialer");
         List<String> emer0 = new ArrayList<>();
         emer0.add("emergency");
         List<String> sms10 = new ArrayList<>();
         sms10.add("sms");
+
+        ArraySet<Pair<String, Integer>> dialer0Pair = new ArraySet<>();
+        dialer0Pair.add(new Pair("dialer", 30));
+        when(mPm.getPackageUid("dialer", MATCH_ALL, 0)).thenReturn(30);
+
+        ArraySet<Pair<String, Integer>> emer0Pair = new ArraySet<>();
+        emer0Pair.add(new Pair("emergency", 40));
+        when(mPm.getPackageUid("emergency", MATCH_ALL, 0)).thenReturn(40);
+
+        ArraySet<Pair<String, Integer>> sms10Pair = new ArraySet<>();
+        sms10Pair.add(new Pair("sms", 50));
+        when(mPm.getPackageUid("sms", MATCH_ALL, 10)).thenReturn(50);
+
         when(mRoleManager.getRoleHoldersAsUser(
                 ROLE_DIALER,
                 mUsers.get(0).getUserHandle())).
@@ -285,13 +210,13 @@ public class RoleObserverTest extends UiServiceTestCase {
                 eq(mExecutor), any(), eq(UserHandle.ALL));
 
         // make sure we told pref helper about the state of the world
-        verify(mPreferencesHelper, times(1)).updateDefaultApps(0, null, new ArraySet<>(dialer0));
-        verify(mPreferencesHelper, times(1)).updateDefaultApps(0, null, new ArraySet<>(emer0));
-        verify(mPreferencesHelper, times(1)).updateDefaultApps(10, null, new ArraySet<>(sms10));
+        verify(mPreferencesHelper, times(1)).updateDefaultApps(0, null, dialer0Pair);
+        verify(mPreferencesHelper, times(1)).updateDefaultApps(0, null, emer0Pair);
+        verify(mPreferencesHelper, times(1)).updateDefaultApps(10, null, sms10Pair);
     }
 
     @Test
-    public void testSwapDefault() {
+    public void testSwapDefault() throws Exception {
         List<String> dialer0 = new ArrayList<>();
         dialer0.add("dialer");
 
@@ -305,6 +230,10 @@ public class RoleObserverTest extends UiServiceTestCase {
         List<String> newDefault = new ArrayList<>();
         newDefault.add("phone");
 
+        ArraySet<Pair<String, Integer>> newDefaultPair = new ArraySet<>();
+        newDefaultPair.add(new Pair("phone", 30));
+        when(mPm.getPackageUid("phone", MATCH_ALL, 0)).thenReturn(30);
+
         when(mRoleManager.getRoleHoldersAsUser(
                 ROLE_DIALER,
                 mUsers.get(0).getUserHandle())).
@@ -313,11 +242,11 @@ public class RoleObserverTest extends UiServiceTestCase {
         mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(0));
 
         verify(mPreferencesHelper, times(1)).updateDefaultApps(
-                0, new ArraySet<>(dialer0), new ArraySet<>(newDefault));
+                0, new ArraySet<>(dialer0), newDefaultPair);
     }
 
     @Test
-    public void testSwapDefault_multipleOverlappingApps() {
+    public void testSwapDefault_multipleOverlappingApps() throws Exception {
         List<String> dialer0 = new ArrayList<>();
         dialer0.add("dialer");
         dialer0.add("phone");
@@ -342,15 +271,17 @@ public class RoleObserverTest extends UiServiceTestCase {
                 mUsers.get(0).getUserHandle())).
                 thenReturn(newDefault);
 
-        mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(0));
-
         ArraySet<String> expectedRemove = new ArraySet<>();
         expectedRemove.add("dialer");
-        ArraySet<String> expectedAdd = new ArraySet<>();
-        expectedAdd.add("emerPhone");
+
+        ArraySet<Pair<String, Integer>> expectedAddPair = new ArraySet<>();
+        expectedAddPair.add(new Pair("emerPhone", 30));
+        when(mPm.getPackageUid("emerPhone", MATCH_ALL, 0)).thenReturn(30);
+
+        mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(0));
 
         verify(mPreferencesHelper, times(1)).updateDefaultApps(
-                0, expectedRemove, expectedAdd);
+                0, expectedRemove, expectedAddPair);
 
         assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "phone", 0));
         assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "emerPhone", 0));
@@ -358,7 +289,7 @@ public class RoleObserverTest extends UiServiceTestCase {
     }
 
     @Test
-    public void testSwapDefault_newUser() {
+    public void testSwapDefault_newUser() throws Exception {
         List<String> dialer0 = new ArrayList<>();
         dialer0.add("dialer");
 
@@ -377,6 +308,10 @@ public class RoleObserverTest extends UiServiceTestCase {
                 mUsers.get(1).getUserHandle())).
                 thenReturn(dialer10);
 
+        ArraySet<Pair<String, Integer>> expectedAddPair = new ArraySet<>();
+        expectedAddPair.add(new Pair("phone", 30));
+        when(mPm.getPackageUid("phone", MATCH_ALL, 10)).thenReturn(30);
+
         mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(10));
 
         ArraySet<String> expectedRemove = new ArraySet<>();
@@ -384,7 +319,7 @@ public class RoleObserverTest extends UiServiceTestCase {
         expectedAdd.add("phone");
 
         verify(mPreferencesHelper, times(1)).updateDefaultApps(
-                10, expectedRemove, expectedAdd);
+                10, expectedRemove, expectedAddPair);
 
         assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "phone", 10));
         assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "dialer", 0));