Loading core/api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -3023,6 +3023,7 @@ package android.content.pm { method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, @android.content.pm.PackageManager.PermissionFlags int, @android.content.pm.PackageManager.PermissionFlags int, @NonNull android.os.UserHandle); method @Deprecated @RequiresPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT) public abstract void verifyIntentFilter(int, int, @NonNull java.util.List<java.lang.String>); field public static final String ACTION_REQUEST_PERMISSIONS = "android.content.pm.action.REQUEST_PERMISSIONS"; field public static final String ACTION_REQUEST_PERMISSIONS_FOR_OTHER = "android.content.pm.action.REQUEST_PERMISSIONS_FOR_OTHER"; field public static final String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES"; field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS"; field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio"; core/java/android/content/pm/PackageManager.java +14 −2 Original line number Diff line number Diff line Loading @@ -4220,6 +4220,17 @@ public abstract class PackageManager { public static final String ACTION_REQUEST_PERMISSIONS = "android.content.pm.action.REQUEST_PERMISSIONS"; /** * The action used to request that the user approve a permission request * from the application. Sent from an application other than the one whose permissions * will be granted. Can only be used by the system server. * * @hide */ @SystemApi public static final String ACTION_REQUEST_PERMISSIONS_FOR_OTHER = "android.content.pm.action.REQUEST_PERMISSIONS_FOR_OTHER"; /** * The names of the requested permissions. * <p> Loading Loading @@ -4328,8 +4339,9 @@ public abstract class PackageManager { public static final int FLAG_PERMISSION_GRANTED_BY_DEFAULT = 1 << 5; /** * Permission flag: The permission has to be reviewed before any of * the app components can run. * Permission flag: If app targetSDK < M, then the permission has to be reviewed before any of * the app components can run. If app targetSDK >= M, then the system might need to show a * request dialog for this permission on behalf of an app. * * @hide */ Loading core/java/android/provider/Settings.java +1 −0 Original line number Diff line number Diff line Loading @@ -9949,6 +9949,7 @@ public final class Settings { * * @hide */ @Readable public static final String NOTIFICATION_PERMISSION_ENABLED = "notification_permission_enabled"; Loading services/core/java/com/android/server/notification/NotificationManagerInternal.java +3 −0 Original line number Diff line number Diff line Loading @@ -36,4 +36,7 @@ public interface NotificationManagerInternal { void removeForegroundServiceFlagFromNotification(String pkg, int notificationId, int userId); void onConversationRemoved(String pkg, int uid, Set<String> shortcuts); /** Get the number of notification channels for a given package */ int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted); } services/core/java/com/android/server/notification/NotificationManagerService.java +101 −5 Original line number Diff line number Diff line Loading @@ -133,6 +133,7 @@ import android.annotation.WorkerThread; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ActivityManagerInternal.ServiceNotificationPolicy; import android.app.ActivityTaskManager; import android.app.AlarmManager; import android.app.AppGlobals; import android.app.AppOpsManager; Loading Loading @@ -296,6 +297,7 @@ import com.android.server.notification.toast.TextToastRecord; import com.android.server.notification.toast.ToastRecord; import com.android.server.pm.PackageManagerService; import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.UriGrantsManagerInternal; import com.android.server.utils.quota.MultiRateLimiter; Loading Loading @@ -480,6 +482,7 @@ public class NotificationManagerService extends SystemService { private IPackageManager mPackageManager; private PackageManager mPackageManagerClient; private PackageManagerInternal mPackageManagerInternal; private PermissionPolicyInternal mPermissionPolicyInternal; AudioManager mAudioManager; AudioManagerInternal mAudioManagerInternal; // Can be null for wear Loading Loading @@ -2106,6 +2109,7 @@ public class NotificationManagerService extends SystemService { mPackageManager = packageManager; mPackageManagerClient = packageManagerClient; mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class); mAppOps = appOps; mAppOpsService = iAppOps; try { Loading Loading @@ -3674,9 +3678,19 @@ public class NotificationManagerService extends SystemService { private void createNotificationChannelsImpl(String pkg, int uid, ParceledListSlice channelsList) { createNotificationChannelsImpl(pkg, uid, channelsList, ActivityTaskManager.INVALID_TASK_ID); } private void createNotificationChannelsImpl(String pkg, int uid, ParceledListSlice channelsList, int startingTaskId) { List<NotificationChannel> channels = channelsList.getList(); final int channelsSize = channels.size(); ParceledListSlice<NotificationChannel> oldChannels = mPreferencesHelper.getNotificationChannels(pkg, uid, true); final boolean hadChannel = oldChannels != null && !oldChannels.getList().isEmpty(); boolean needsPolicyFileChange = false; boolean hasRequestedNotificationPermission = false; for (int i = 0; i < channelsSize; i++) { final NotificationChannel channel = channels.get(i); Objects.requireNonNull(channel, "channel in list is null"); Loading @@ -3690,6 +3704,19 @@ public class NotificationManagerService extends SystemService { mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(), false), NOTIFICATION_CHANNEL_OR_GROUP_ADDED); boolean hasChannel = hadChannel || hasRequestedNotificationPermission; if (!hasChannel) { ParceledListSlice<NotificationChannel> currChannels = mPreferencesHelper.getNotificationChannels(pkg, uid, true); hasChannel = currChannels != null && !currChannels.getList().isEmpty(); } if (!hadChannel && hasChannel && !hasRequestedNotificationPermission && startingTaskId != ActivityTaskManager.INVALID_TASK_ID) { hasRequestedNotificationPermission = true; mHandler.post(new ShowNotificationPermissionPromptRunnable(pkg, UserHandle.getUserId(uid), startingTaskId, mPermissionPolicyInternal)); } } } if (needsPolicyFileChange) { Loading @@ -3698,10 +3725,29 @@ public class NotificationManagerService extends SystemService { } @Override public void createNotificationChannels(String pkg, ParceledListSlice channelsList) { public void createNotificationChannels(String pkg, ParceledListSlice channelsList) { checkCallerIsSystemOrSameApp(pkg); createNotificationChannelsImpl(pkg, Binder.getCallingUid(), channelsList); int taskId = ActivityTaskManager.INVALID_TASK_ID; try { int uid = mPackageManager.getPackageUid(pkg, 0, UserHandle.getUserId(Binder.getCallingUid())); List<ActivityManager.AppTask> tasks = mAtm.getAppTasks(pkg, uid); for (int i = 0; i < tasks.size(); i++) { ActivityManager.RecentTaskInfo task = tasks.get(i).getTaskInfo(); if (mPermissionPolicyInternal == null) { mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class); } if (mPermissionPolicyInternal != null && mPermissionPolicyInternal.canShowPermissionPromptForTask(task)) { taskId = task.taskId; break; } } } catch (RemoteException e) { // Do nothing } createNotificationChannelsImpl(pkg, Binder.getCallingUid(), channelsList, taskId); } @Override Loading Loading @@ -3885,8 +3931,8 @@ public class NotificationManagerService extends SystemService { public int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) { enforceSystemOrSystemUI("getNumNotificationChannelsForPackage"); return mPreferencesHelper.getNotificationChannels(pkg, uid, includeDeleted) .getList().size(); return NotificationManagerService.this .getNumNotificationChannelsForPackage(pkg, uid, includeDeleted); } @Override Loading Loading @@ -6151,8 +6197,20 @@ public class NotificationManagerService extends SystemService { // initially *and* force remove FLAG_FOREGROUND_SERVICE. sbn.getNotification().flags = (r.mOriginalFlags & ~FLAG_FOREGROUND_SERVICE); } @Override public int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) { return NotificationManagerService.this .getNumNotificationChannelsForPackage(pkg, uid, includeDeleted); } }; int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) { return mPreferencesHelper.getNotificationChannels(pkg, uid, includeDeleted).getList() .size(); } void cancelNotificationInternal(String pkg, String opPkg, int callingUid, int callingPid, String tag, int id, int userId) { userId = ActivityManager.handleIncomingUser(callingPid, Loading Loading @@ -6974,6 +7032,44 @@ public class NotificationManagerService extends SystemService { } } protected static class ShowNotificationPermissionPromptRunnable implements Runnable { private final String mPkgName; private final int mUserId; private final int mTaskId; private final PermissionPolicyInternal mPpi; ShowNotificationPermissionPromptRunnable(String pkg, int user, int task, PermissionPolicyInternal pPi) { mPkgName = pkg; mUserId = user; mTaskId = task; mPpi = pPi; } @Override public boolean equals(Object o) { if (!(o instanceof ShowNotificationPermissionPromptRunnable)) { return false; } ShowNotificationPermissionPromptRunnable other = (ShowNotificationPermissionPromptRunnable) o; return Objects.equals(mPkgName, other.mPkgName) && mUserId == other.mUserId && mTaskId == other.mTaskId; } @Override public int hashCode() { return Objects.hash(mPkgName, mUserId, mTaskId); } @Override public void run() { mPpi.showNotificationPromptIfNeeded(mPkgName, mUserId, mTaskId); } } protected class EnqueueNotificationRunnable implements Runnable { private final NotificationRecord r; private final int userId; Loading Loading
core/api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -3023,6 +3023,7 @@ package android.content.pm { method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, @android.content.pm.PackageManager.PermissionFlags int, @android.content.pm.PackageManager.PermissionFlags int, @NonNull android.os.UserHandle); method @Deprecated @RequiresPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT) public abstract void verifyIntentFilter(int, int, @NonNull java.util.List<java.lang.String>); field public static final String ACTION_REQUEST_PERMISSIONS = "android.content.pm.action.REQUEST_PERMISSIONS"; field public static final String ACTION_REQUEST_PERMISSIONS_FOR_OTHER = "android.content.pm.action.REQUEST_PERMISSIONS_FOR_OTHER"; field public static final String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES"; field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS"; field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio";
core/java/android/content/pm/PackageManager.java +14 −2 Original line number Diff line number Diff line Loading @@ -4220,6 +4220,17 @@ public abstract class PackageManager { public static final String ACTION_REQUEST_PERMISSIONS = "android.content.pm.action.REQUEST_PERMISSIONS"; /** * The action used to request that the user approve a permission request * from the application. Sent from an application other than the one whose permissions * will be granted. Can only be used by the system server. * * @hide */ @SystemApi public static final String ACTION_REQUEST_PERMISSIONS_FOR_OTHER = "android.content.pm.action.REQUEST_PERMISSIONS_FOR_OTHER"; /** * The names of the requested permissions. * <p> Loading Loading @@ -4328,8 +4339,9 @@ public abstract class PackageManager { public static final int FLAG_PERMISSION_GRANTED_BY_DEFAULT = 1 << 5; /** * Permission flag: The permission has to be reviewed before any of * the app components can run. * Permission flag: If app targetSDK < M, then the permission has to be reviewed before any of * the app components can run. If app targetSDK >= M, then the system might need to show a * request dialog for this permission on behalf of an app. * * @hide */ Loading
core/java/android/provider/Settings.java +1 −0 Original line number Diff line number Diff line Loading @@ -9949,6 +9949,7 @@ public final class Settings { * * @hide */ @Readable public static final String NOTIFICATION_PERMISSION_ENABLED = "notification_permission_enabled"; Loading
services/core/java/com/android/server/notification/NotificationManagerInternal.java +3 −0 Original line number Diff line number Diff line Loading @@ -36,4 +36,7 @@ public interface NotificationManagerInternal { void removeForegroundServiceFlagFromNotification(String pkg, int notificationId, int userId); void onConversationRemoved(String pkg, int uid, Set<String> shortcuts); /** Get the number of notification channels for a given package */ int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted); }
services/core/java/com/android/server/notification/NotificationManagerService.java +101 −5 Original line number Diff line number Diff line Loading @@ -133,6 +133,7 @@ import android.annotation.WorkerThread; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ActivityManagerInternal.ServiceNotificationPolicy; import android.app.ActivityTaskManager; import android.app.AlarmManager; import android.app.AppGlobals; import android.app.AppOpsManager; Loading Loading @@ -296,6 +297,7 @@ import com.android.server.notification.toast.TextToastRecord; import com.android.server.notification.toast.ToastRecord; import com.android.server.pm.PackageManagerService; import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.UriGrantsManagerInternal; import com.android.server.utils.quota.MultiRateLimiter; Loading Loading @@ -480,6 +482,7 @@ public class NotificationManagerService extends SystemService { private IPackageManager mPackageManager; private PackageManager mPackageManagerClient; private PackageManagerInternal mPackageManagerInternal; private PermissionPolicyInternal mPermissionPolicyInternal; AudioManager mAudioManager; AudioManagerInternal mAudioManagerInternal; // Can be null for wear Loading Loading @@ -2106,6 +2109,7 @@ public class NotificationManagerService extends SystemService { mPackageManager = packageManager; mPackageManagerClient = packageManagerClient; mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class); mAppOps = appOps; mAppOpsService = iAppOps; try { Loading Loading @@ -3674,9 +3678,19 @@ public class NotificationManagerService extends SystemService { private void createNotificationChannelsImpl(String pkg, int uid, ParceledListSlice channelsList) { createNotificationChannelsImpl(pkg, uid, channelsList, ActivityTaskManager.INVALID_TASK_ID); } private void createNotificationChannelsImpl(String pkg, int uid, ParceledListSlice channelsList, int startingTaskId) { List<NotificationChannel> channels = channelsList.getList(); final int channelsSize = channels.size(); ParceledListSlice<NotificationChannel> oldChannels = mPreferencesHelper.getNotificationChannels(pkg, uid, true); final boolean hadChannel = oldChannels != null && !oldChannels.getList().isEmpty(); boolean needsPolicyFileChange = false; boolean hasRequestedNotificationPermission = false; for (int i = 0; i < channelsSize; i++) { final NotificationChannel channel = channels.get(i); Objects.requireNonNull(channel, "channel in list is null"); Loading @@ -3690,6 +3704,19 @@ public class NotificationManagerService extends SystemService { mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(), false), NOTIFICATION_CHANNEL_OR_GROUP_ADDED); boolean hasChannel = hadChannel || hasRequestedNotificationPermission; if (!hasChannel) { ParceledListSlice<NotificationChannel> currChannels = mPreferencesHelper.getNotificationChannels(pkg, uid, true); hasChannel = currChannels != null && !currChannels.getList().isEmpty(); } if (!hadChannel && hasChannel && !hasRequestedNotificationPermission && startingTaskId != ActivityTaskManager.INVALID_TASK_ID) { hasRequestedNotificationPermission = true; mHandler.post(new ShowNotificationPermissionPromptRunnable(pkg, UserHandle.getUserId(uid), startingTaskId, mPermissionPolicyInternal)); } } } if (needsPolicyFileChange) { Loading @@ -3698,10 +3725,29 @@ public class NotificationManagerService extends SystemService { } @Override public void createNotificationChannels(String pkg, ParceledListSlice channelsList) { public void createNotificationChannels(String pkg, ParceledListSlice channelsList) { checkCallerIsSystemOrSameApp(pkg); createNotificationChannelsImpl(pkg, Binder.getCallingUid(), channelsList); int taskId = ActivityTaskManager.INVALID_TASK_ID; try { int uid = mPackageManager.getPackageUid(pkg, 0, UserHandle.getUserId(Binder.getCallingUid())); List<ActivityManager.AppTask> tasks = mAtm.getAppTasks(pkg, uid); for (int i = 0; i < tasks.size(); i++) { ActivityManager.RecentTaskInfo task = tasks.get(i).getTaskInfo(); if (mPermissionPolicyInternal == null) { mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class); } if (mPermissionPolicyInternal != null && mPermissionPolicyInternal.canShowPermissionPromptForTask(task)) { taskId = task.taskId; break; } } } catch (RemoteException e) { // Do nothing } createNotificationChannelsImpl(pkg, Binder.getCallingUid(), channelsList, taskId); } @Override Loading Loading @@ -3885,8 +3931,8 @@ public class NotificationManagerService extends SystemService { public int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) { enforceSystemOrSystemUI("getNumNotificationChannelsForPackage"); return mPreferencesHelper.getNotificationChannels(pkg, uid, includeDeleted) .getList().size(); return NotificationManagerService.this .getNumNotificationChannelsForPackage(pkg, uid, includeDeleted); } @Override Loading Loading @@ -6151,8 +6197,20 @@ public class NotificationManagerService extends SystemService { // initially *and* force remove FLAG_FOREGROUND_SERVICE. sbn.getNotification().flags = (r.mOriginalFlags & ~FLAG_FOREGROUND_SERVICE); } @Override public int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) { return NotificationManagerService.this .getNumNotificationChannelsForPackage(pkg, uid, includeDeleted); } }; int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) { return mPreferencesHelper.getNotificationChannels(pkg, uid, includeDeleted).getList() .size(); } void cancelNotificationInternal(String pkg, String opPkg, int callingUid, int callingPid, String tag, int id, int userId) { userId = ActivityManager.handleIncomingUser(callingPid, Loading Loading @@ -6974,6 +7032,44 @@ public class NotificationManagerService extends SystemService { } } protected static class ShowNotificationPermissionPromptRunnable implements Runnable { private final String mPkgName; private final int mUserId; private final int mTaskId; private final PermissionPolicyInternal mPpi; ShowNotificationPermissionPromptRunnable(String pkg, int user, int task, PermissionPolicyInternal pPi) { mPkgName = pkg; mUserId = user; mTaskId = task; mPpi = pPi; } @Override public boolean equals(Object o) { if (!(o instanceof ShowNotificationPermissionPromptRunnable)) { return false; } ShowNotificationPermissionPromptRunnable other = (ShowNotificationPermissionPromptRunnable) o; return Objects.equals(mPkgName, other.mPkgName) && mUserId == other.mUserId && mTaskId == other.mTaskId; } @Override public int hashCode() { return Objects.hash(mPkgName, mUserId, mTaskId); } @Override public void run() { mPpi.showNotificationPromptIfNeeded(mPkgName, mUserId, mTaskId); } } protected class EnqueueNotificationRunnable implements Runnable { private final NotificationRecord r; private final int userId; Loading