Fix default app notification locking on new devices
- 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
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 9fc30eb..e2033c6 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -46,6 +46,7 @@
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.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 @@
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 @@
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 @@
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 @@
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 @@
}
for (String nowApproved : roleHolders) {
if (!previouslyApproved.contains(nowApproved)) {
- toAdd.add(nowApproved);
+ toAdd.add(new Pair(nowApproved,
+ getUidForPackage(nowApproved, user.getIdentifier())));
}
}
@@ -8304,6 +8314,15 @@
// 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 {
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 9e16632..627b65c 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -38,6 +38,7 @@
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 @@
} else {
channel.populateFromXml(parser);
}
+ channel.setImportanceLockedByCriticalDeviceFunction(
+ r.defaultAppLockedImportance);
r.channels.put(id, channel);
}
}
@@ -882,7 +885,8 @@
}
}
- 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 @@
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 @@
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);