Loading core/java/android/app/INotificationManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.app.NotificationChannel; import android.app.NotificationChannelGroup; import android.app.NotificationHistory; import android.app.NotificationManager; import android.content.AttributionSource; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ParceledListSlice; Loading Loading @@ -225,6 +226,7 @@ interface INotificationManager void setNotificationDelegate(String callingPkg, String delegate); String getNotificationDelegate(String callingPkg); boolean canNotifyAsPackage(String callingPkg, String targetPkg, int userId); boolean canUseFullScreenIntent(in AttributionSource attributionSource); void setPrivateNotificationsAllowed(boolean allow); boolean getPrivateNotificationsAllowed(); Loading core/java/android/app/NotificationManager.java +5 −14 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.PermissionChecker; import android.content.pm.ParceledListSlice; import android.content.pm.ShortcutInfo; import android.graphics.drawable.Icon; Loading Loading @@ -877,19 +876,11 @@ public class NotificationManager { * {@link android.provider.Settings#ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT}. */ public boolean canUseFullScreenIntent() { final int result = PermissionChecker.checkPermissionForPreflight(mContext, android.Manifest.permission.USE_FULL_SCREEN_INTENT, mContext.getAttributionSource()); switch (result) { case PermissionChecker.PERMISSION_GRANTED: return true; case PermissionChecker.PERMISSION_SOFT_DENIED: case PermissionChecker.PERMISSION_HARD_DENIED: return false; default: if (localLOGV) Log.v(TAG, "Unknown PermissionChecker result: " + result); return false; INotificationManager service = getService(); try { return service.canUseFullScreenIntent(mContext.getAttributionSource()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } Loading services/core/java/com/android/server/notification/NotificationManagerService.java +63 −25 Original line number Diff line number Diff line Loading @@ -3814,6 +3814,28 @@ public class NotificationManagerService extends SystemService { return false; } @Override public boolean canUseFullScreenIntent(@NonNull AttributionSource attributionSource) { final String packageName = attributionSource.getPackageName(); final int uid = attributionSource.getUid(); final int userId = UserHandle.getUserId(uid); checkCallerIsSameApp(packageName, uid, userId); final ApplicationInfo applicationInfo; try { applicationInfo = mPackageManagerClient.getApplicationInfoAsUser( packageName, PackageManager.MATCH_DIRECT_BOOT_AUTO, userId); } catch (NameNotFoundException e) { Slog.e(TAG, "Failed to getApplicationInfo() in canUseFullScreenIntent()", e); return false; } final boolean showStickyHunIfDenied = mFlagResolver.isEnabled( SystemUiSystemPropertiesFlags.NotificationFlags .SHOW_STICKY_HUN_FOR_DENIED_FSI); return checkUseFullScreenIntentPermission(attributionSource, applicationInfo, showStickyHunIfDenied /* isAppOpPermission */, false /* forDataDelivery */); } @Override public void updateNotificationChannelGroupForPackage(String pkg, int uid, NotificationChannelGroup group) throws RemoteException { Loading Loading @@ -6826,39 +6848,31 @@ public class NotificationManagerService extends SystemService { notification.flags &= ~FLAG_FSI_REQUESTED_BUT_DENIED; if (notification.fullScreenIntent != null && ai.targetSdkVersion >= Build.VERSION_CODES.Q) { if (notification.fullScreenIntent != null) { final boolean forceDemoteFsiToStickyHun = mFlagResolver.isEnabled( SystemUiSystemPropertiesFlags.NotificationFlags.FSI_FORCE_DEMOTE); final boolean showStickyHunIfDenied = mFlagResolver.isEnabled( SystemUiSystemPropertiesFlags.NotificationFlags.SHOW_STICKY_HUN_FOR_DENIED_FSI); if (forceDemoteFsiToStickyHun) { makeStickyHun(notification, pkg, userId); } else if (showStickyHunIfDenied) { final AttributionSource source = new AttributionSource.Builder(notificationUid) .setPackageName(pkg) .build(); final int permissionResult = mPermissionManager.checkPermissionForDataDelivery( Manifest.permission.USE_FULL_SCREEN_INTENT, source, /* message= */ null); if (permissionResult != PermissionManager.PERMISSION_GRANTED) { } else { final AttributionSource attributionSource = new AttributionSource.Builder(notificationUid).setPackageName(pkg).build(); final boolean showStickyHunIfDenied = mFlagResolver.isEnabled( SystemUiSystemPropertiesFlags.NotificationFlags .SHOW_STICKY_HUN_FOR_DENIED_FSI); final boolean canUseFullScreenIntent = checkUseFullScreenIntentPermission( attributionSource, ai, showStickyHunIfDenied /* isAppOpPermission */, true /* forDataDelivery */); if (!canUseFullScreenIntent) { if (showStickyHunIfDenied) { makeStickyHun(notification, pkg, userId); } } else { int fullscreenIntentPermission = getContext().checkPermission( android.Manifest.permission.USE_FULL_SCREEN_INTENT, -1, notificationUid); if (fullscreenIntentPermission != PERMISSION_GRANTED) { notification.fullScreenIntent = null; Slog.w(TAG, "Package " + pkg + ": Use of fullScreenIntent requires the" + "USE_FULL_SCREEN_INTENT permission"); } } } } // Ensure all actions are present if (notification.actions != null) { Loading Loading @@ -6951,6 +6965,30 @@ public class NotificationManagerService extends SystemService { ai.packageName) == AppOpsManager.MODE_ALLOWED; } private boolean checkUseFullScreenIntentPermission(@NonNull AttributionSource attributionSource, @NonNull ApplicationInfo applicationInfo, boolean isAppOpPermission, boolean forDataDelivery) { if (applicationInfo.targetSdkVersion < Build.VERSION_CODES.Q) { return true; } if (isAppOpPermission) { final int permissionResult; if (forDataDelivery) { permissionResult = mPermissionManager.checkPermissionForDataDelivery( permission.USE_FULL_SCREEN_INTENT, attributionSource, /* message= */ null); } else { permissionResult = mPermissionManager.checkPermissionForPreflight( permission.USE_FULL_SCREEN_INTENT, attributionSource); } return permissionResult == PermissionManager.PERMISSION_GRANTED; } else { final int permissionResult = getContext().checkPermission( permission.USE_FULL_SCREEN_INTENT, attributionSource.getPid(), attributionSource.getUid()); return permissionResult == PERMISSION_GRANTED; } } private void checkRemoteViews(String pkg, String tag, int id, Notification notification) { if (removeRemoteView(pkg, tag, id, notification.contentView)) { notification.contentView = null; Loading Loading
core/java/android/app/INotificationManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.app.NotificationChannel; import android.app.NotificationChannelGroup; import android.app.NotificationHistory; import android.app.NotificationManager; import android.content.AttributionSource; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ParceledListSlice; Loading Loading @@ -225,6 +226,7 @@ interface INotificationManager void setNotificationDelegate(String callingPkg, String delegate); String getNotificationDelegate(String callingPkg); boolean canNotifyAsPackage(String callingPkg, String targetPkg, int userId); boolean canUseFullScreenIntent(in AttributionSource attributionSource); void setPrivateNotificationsAllowed(boolean allow); boolean getPrivateNotificationsAllowed(); Loading
core/java/android/app/NotificationManager.java +5 −14 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.PermissionChecker; import android.content.pm.ParceledListSlice; import android.content.pm.ShortcutInfo; import android.graphics.drawable.Icon; Loading Loading @@ -877,19 +876,11 @@ public class NotificationManager { * {@link android.provider.Settings#ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT}. */ public boolean canUseFullScreenIntent() { final int result = PermissionChecker.checkPermissionForPreflight(mContext, android.Manifest.permission.USE_FULL_SCREEN_INTENT, mContext.getAttributionSource()); switch (result) { case PermissionChecker.PERMISSION_GRANTED: return true; case PermissionChecker.PERMISSION_SOFT_DENIED: case PermissionChecker.PERMISSION_HARD_DENIED: return false; default: if (localLOGV) Log.v(TAG, "Unknown PermissionChecker result: " + result); return false; INotificationManager service = getService(); try { return service.canUseFullScreenIntent(mContext.getAttributionSource()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +63 −25 Original line number Diff line number Diff line Loading @@ -3814,6 +3814,28 @@ public class NotificationManagerService extends SystemService { return false; } @Override public boolean canUseFullScreenIntent(@NonNull AttributionSource attributionSource) { final String packageName = attributionSource.getPackageName(); final int uid = attributionSource.getUid(); final int userId = UserHandle.getUserId(uid); checkCallerIsSameApp(packageName, uid, userId); final ApplicationInfo applicationInfo; try { applicationInfo = mPackageManagerClient.getApplicationInfoAsUser( packageName, PackageManager.MATCH_DIRECT_BOOT_AUTO, userId); } catch (NameNotFoundException e) { Slog.e(TAG, "Failed to getApplicationInfo() in canUseFullScreenIntent()", e); return false; } final boolean showStickyHunIfDenied = mFlagResolver.isEnabled( SystemUiSystemPropertiesFlags.NotificationFlags .SHOW_STICKY_HUN_FOR_DENIED_FSI); return checkUseFullScreenIntentPermission(attributionSource, applicationInfo, showStickyHunIfDenied /* isAppOpPermission */, false /* forDataDelivery */); } @Override public void updateNotificationChannelGroupForPackage(String pkg, int uid, NotificationChannelGroup group) throws RemoteException { Loading Loading @@ -6826,39 +6848,31 @@ public class NotificationManagerService extends SystemService { notification.flags &= ~FLAG_FSI_REQUESTED_BUT_DENIED; if (notification.fullScreenIntent != null && ai.targetSdkVersion >= Build.VERSION_CODES.Q) { if (notification.fullScreenIntent != null) { final boolean forceDemoteFsiToStickyHun = mFlagResolver.isEnabled( SystemUiSystemPropertiesFlags.NotificationFlags.FSI_FORCE_DEMOTE); final boolean showStickyHunIfDenied = mFlagResolver.isEnabled( SystemUiSystemPropertiesFlags.NotificationFlags.SHOW_STICKY_HUN_FOR_DENIED_FSI); if (forceDemoteFsiToStickyHun) { makeStickyHun(notification, pkg, userId); } else if (showStickyHunIfDenied) { final AttributionSource source = new AttributionSource.Builder(notificationUid) .setPackageName(pkg) .build(); final int permissionResult = mPermissionManager.checkPermissionForDataDelivery( Manifest.permission.USE_FULL_SCREEN_INTENT, source, /* message= */ null); if (permissionResult != PermissionManager.PERMISSION_GRANTED) { } else { final AttributionSource attributionSource = new AttributionSource.Builder(notificationUid).setPackageName(pkg).build(); final boolean showStickyHunIfDenied = mFlagResolver.isEnabled( SystemUiSystemPropertiesFlags.NotificationFlags .SHOW_STICKY_HUN_FOR_DENIED_FSI); final boolean canUseFullScreenIntent = checkUseFullScreenIntentPermission( attributionSource, ai, showStickyHunIfDenied /* isAppOpPermission */, true /* forDataDelivery */); if (!canUseFullScreenIntent) { if (showStickyHunIfDenied) { makeStickyHun(notification, pkg, userId); } } else { int fullscreenIntentPermission = getContext().checkPermission( android.Manifest.permission.USE_FULL_SCREEN_INTENT, -1, notificationUid); if (fullscreenIntentPermission != PERMISSION_GRANTED) { notification.fullScreenIntent = null; Slog.w(TAG, "Package " + pkg + ": Use of fullScreenIntent requires the" + "USE_FULL_SCREEN_INTENT permission"); } } } } // Ensure all actions are present if (notification.actions != null) { Loading Loading @@ -6951,6 +6965,30 @@ public class NotificationManagerService extends SystemService { ai.packageName) == AppOpsManager.MODE_ALLOWED; } private boolean checkUseFullScreenIntentPermission(@NonNull AttributionSource attributionSource, @NonNull ApplicationInfo applicationInfo, boolean isAppOpPermission, boolean forDataDelivery) { if (applicationInfo.targetSdkVersion < Build.VERSION_CODES.Q) { return true; } if (isAppOpPermission) { final int permissionResult; if (forDataDelivery) { permissionResult = mPermissionManager.checkPermissionForDataDelivery( permission.USE_FULL_SCREEN_INTENT, attributionSource, /* message= */ null); } else { permissionResult = mPermissionManager.checkPermissionForPreflight( permission.USE_FULL_SCREEN_INTENT, attributionSource); } return permissionResult == PermissionManager.PERMISSION_GRANTED; } else { final int permissionResult = getContext().checkPermission( permission.USE_FULL_SCREEN_INTENT, attributionSource.getPid(), attributionSource.getUid()); return permissionResult == PERMISSION_GRANTED; } } private void checkRemoteViews(String pkg, String tag, int id, Notification notification) { if (removeRemoteView(pkg, tag, id, notification.contentView)) { notification.contentView = null; Loading