diff options
3 files changed, 63 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/notification/BubbleExtractor.java b/services/core/java/com/android/server/notification/BubbleExtractor.java index 536ea30d6a94..27802ffc013d 100644 --- a/services/core/java/com/android/server/notification/BubbleExtractor.java +++ b/services/core/java/com/android/server/notification/BubbleExtractor.java @@ -16,6 +16,7 @@ package com.android.server.notification; import static android.app.Notification.FLAG_BUBBLE; +import static android.app.Notification.FLAG_FOREGROUND_SERVICE; import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE; import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; @@ -89,9 +90,10 @@ public class BubbleExtractor implements NotificationSignalExtractor { record.setAllowBubble(recordChannel.canBubble()); } - final boolean fulfillsPolicy = record.isConversation() + final boolean fulfillsPolicy = record.canBubble() + && record.isConversation() && !mActivityManager.isLowRamDevice() - && record.canBubble(); + && (record.getNotification().flags & FLAG_FOREGROUND_SERVICE) == 0; final boolean applyFlag = fulfillsPolicy && canPresentAsBubble(record); if (applyFlag) { record.getNotification().flags |= FLAG_BUBBLE; diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index c11a80ddf352..54efe543a29f 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -3095,7 +3095,7 @@ public class NotificationManagerService extends SystemService { if (UserHandle.getCallingUserId() != UserHandle.getUserId(uid)) { getContext().enforceCallingPermission( android.Manifest.permission.INTERACT_ACROSS_USERS, - "canNotifyAsPackage for uid " + uid); + "getBubblePreferenceForPackage for uid " + uid); } return mPreferencesHelper.getBubblePreference(pkg, uid); @@ -3103,7 +3103,7 @@ public class NotificationManagerService extends SystemService { @Override public void setBubblesAllowed(String pkg, int uid, int bubblePreference) { - enforceSystemOrSystemUI("Caller not system or systemui"); + checkCallerIsSystemOrSystemUiOrShell("Caller not system or sysui or shell"); mPreferencesHelper.setBubblesAllowed(pkg, uid, bubblePreference); handleSavePolicyFile(); } @@ -3304,7 +3304,7 @@ public class NotificationManagerService extends SystemService { String targetPkg, String channelId, boolean returnParentIfNoConversationChannel, String conversationId) { if (canNotifyAsPackage(callingPkg, targetPkg, userId) - || isCallerIsSystemOrSystemUi()) { + || isCallerIsSystemOrSysemUiOrShell()) { int targetUid = -1; try { targetUid = mPackageManagerClient.getPackageUidAsUser(targetPkg, userId); @@ -3414,7 +3414,7 @@ public class NotificationManagerService extends SystemService { @Override public void updateNotificationChannelForPackage(String pkg, int uid, NotificationChannel channel) { - enforceSystemOrSystemUI("Caller not system or systemui"); + checkCallerIsSystemOrSystemUiOrShell("Caller not system or sysui or shell"); Objects.requireNonNull(channel); updateNotificationChannelInt(pkg, uid, channel, false); } @@ -5844,6 +5844,7 @@ public class NotificationManagerService extends SystemService { synchronized (mNotificationLock) { NotificationRecord r = mNotificationsByKey.get(key); if (r != null) { + r.setShortcutInfo(null); // Enqueue will trigger resort & flag is updated that way. r.getNotification().flags |= FLAG_ONLY_ALERT_ONCE; mHandler.post( @@ -8247,6 +8248,14 @@ public class NotificationManagerService extends SystemService { == PERMISSION_GRANTED; } + private boolean isCallerIsSystemOrSysemUiOrShell() { + int callingUid = Binder.getCallingUid(); + if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { + return true; + } + return isCallerIsSystemOrSystemUi(); + } + private void checkCallerIsSystemOrShell() { int callingUid = Binder.getCallingUid(); if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { @@ -8263,6 +8272,10 @@ public class NotificationManagerService extends SystemService { } private void checkCallerIsSystemOrSystemUiOrShell() { + checkCallerIsSystemOrSystemUiOrShell(null); + } + + private void checkCallerIsSystemOrSystemUiOrShell(String message) { int callingUid = Binder.getCallingUid(); if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { return; @@ -8270,7 +8283,8 @@ public class NotificationManagerService extends SystemService { if (isCallerSystemOrPhone()) { return; } - getContext().enforceCallingPermission(android.Manifest.permission.STATUS_BAR_SERVICE, null); + getContext().enforceCallingPermission(android.Manifest.permission.STATUS_BAR_SERVICE, + message); } private void checkCallerIsSystemOrSameApp(String pkg) { diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java index 2b5ba2528429..e4a17740b0b7 100644 --- a/services/core/java/com/android/server/notification/NotificationShellCmd.java +++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java @@ -38,7 +38,6 @@ import android.content.res.Resources; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; -import android.media.IRingtonePlayer; import android.net.Uri; import android.os.Binder; import android.os.Process; @@ -48,8 +47,6 @@ import android.os.UserHandle; import android.text.TextUtils; import android.util.Slog; -import com.android.internal.util.FunctionalUtils; - import java.io.PrintWriter; import java.net.URISyntaxException; import java.util.Collections; @@ -72,7 +69,11 @@ public class NotificationShellCmd extends ShellCommand { + " unsuspend_package PACKAGE\n" + " reset_assistant_user_set [user_id (current user if not specified)]\n" + " get_approved_assistant [user_id (current user if not specified)]\n" - + " post [--help | flags] TAG TEXT"; + + " post [--help | flags] TAG TEXT\n" + + " set_bubbles PACKAGE PREFERENCE (0=none 1=all 2=selected) " + + "[user_id (current user if not specified)]\n" + + " set_bubbles_channel PACKAGE CHANNEL_ID ALLOW " + + "[user_id (current user if not specified)]\n"; private static final String NOTIFY_USAGE = "usage: cmd notification post [flags] <tag> <text>\n\n" @@ -109,6 +110,7 @@ public class NotificationShellCmd extends ShellCommand { private final NotificationManagerService mDirectService; private final INotificationManager mBinderService; private final PackageManager mPm; + private NotificationChannel mChannel; public NotificationShellCmd(NotificationManagerService service) { mDirectService = service; @@ -276,6 +278,40 @@ public class NotificationShellCmd extends ShellCommand { } break; } + case "set_bubbles": { + // only use for testing + String packageName = getNextArgRequired(); + int preference = Integer.parseInt(getNextArgRequired()); + if (preference > 3 || preference < 0) { + pw.println("Invalid preference - must be between 0-3 " + + "(0=none 1=all 2=selected)"); + return -1; + } + int userId = ActivityManager.getCurrentUser(); + if (peekNextArg() != null) { + userId = Integer.parseInt(getNextArgRequired()); + } + int appUid = UserHandle.getUid(userId, mPm.getPackageUid(packageName, 0)); + mBinderService.setBubblesAllowed(packageName, appUid, preference); + break; + } + case "set_bubbles_channel": { + // only use for testing + String packageName = getNextArgRequired(); + String channelId = getNextArgRequired(); + boolean allow = Boolean.parseBoolean(getNextArgRequired()); + int userId = ActivityManager.getCurrentUser(); + if (peekNextArg() != null) { + userId = Integer.parseInt(getNextArgRequired()); + } + NotificationChannel channel = mBinderService.getNotificationChannel( + callingPackage, userId, packageName, channelId); + channel.setAllowBubbles(allow); + int appUid = UserHandle.getUid(userId, mPm.getPackageUid(packageName, 0)); + mBinderService.updateNotificationChannelForPackage(packageName, appUid, + channel); + break; + } case "post": case "notify": doNotify(pw, callingPackage, callingUid); |