Loading services/core/java/com/android/server/notification/NotificationManagerService.java +7 −2 Original line number Diff line number Diff line Loading @@ -2342,7 +2342,6 @@ public class NotificationManagerService extends SystemService { mPermissionManager, mNotificationChannelLogger, mAppOps, mUgmInternal, new SysUiStatsEvent.BuilderFactory(), mShowReviewPermissionsNotification); mRankingHelper = new RankingHelper(getContext(), Loading Loading @@ -5882,7 +5881,13 @@ public class NotificationManagerService extends SystemService { final Uri originalSoundUri = (originalChannel != null) ? originalChannel.getSound() : null; if (soundUri != null && !Objects.equals(originalSoundUri, soundUri)) { PermissionHelper.grantUriPermission(mUgmInternal, soundUri, sourceUid); Binder.withCleanCallingIdentity(() -> { mUgmInternal.checkGrantUriPermission(sourceUid, null, ContentProvider.getUriWithoutUserId(soundUri), Intent.FLAG_GRANT_READ_URI_PERMISSION, ContentProvider.getUserIdFromUri(soundUri, UserHandle.getUserId(sourceUid))); }); } } Loading services/core/java/com/android/server/notification/NotificationRecord.java +10 −1 Original line number Diff line number Diff line Loading @@ -1417,13 +1417,20 @@ public final class NotificationRecord { * {@link SecurityException} depending on target SDK of enqueuing app. */ private void visitGrantableUri(Uri uri, boolean userOverriddenUri, boolean isSound) { if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return; if (mGrantableUris != null && mGrantableUris.contains(uri)) { return; // already verified this URI } final int sourceUid = getSbn().getUid(); final long ident = Binder.clearCallingIdentity(); try { PermissionHelper.grantUriPermission(mUgmInternal, uri, sourceUid); // This will throw a SecurityException if the caller can't grant. mUgmInternal.checkGrantUriPermission(sourceUid, null, ContentProvider.getUriWithoutUserId(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION, ContentProvider.getUserIdFromUri(uri, UserHandle.getUserId(sourceUid))); if (mGrantableUris == null) { mGrantableUris = new ArraySet<>(); Loading @@ -1443,6 +1450,8 @@ public final class NotificationRecord { } } } } finally { Binder.restoreCallingIdentity(ident); } } Loading services/core/java/com/android/server/notification/PermissionHelper.java +1 −20 Original line number Diff line number Diff line Loading @@ -25,25 +25,19 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.Manifest; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.net.Uri; import android.os.Binder; import android.os.RemoteException; import android.os.UserHandle; import android.permission.IPermissionManager; import android.util.ArrayMap; import android.util.Pair; import android.util.Slog; import com.android.internal.util.ArrayUtils; import com.android.server.uri.UriGrantsManagerInternal; import java.util.Collections; import java.util.HashSet; Loading Loading @@ -302,19 +296,6 @@ public final class PermissionHelper { return false; } static void grantUriPermission(final UriGrantsManagerInternal ugmInternal, Uri uri, int sourceUid) { if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return; Binder.withCleanCallingIdentity(() -> { // This will throw a SecurityException if the caller can't grant. ugmInternal.checkGrantUriPermission(sourceUid, null, ContentProvider.getUriWithoutUserId(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION, ContentProvider.getUserIdFromUri(uri, UserHandle.getUserId(sourceUid))); }); } public static class PackagePermission { public final String packageName; public final @UserIdInt int userId; Loading services/core/java/com/android/server/notification/PreferencesHelper.java +0 −9 Original line number Diff line number Diff line Loading @@ -85,7 +85,6 @@ import com.android.internal.util.XmlUtils; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import com.android.server.notification.PermissionHelper.PackagePermission; import com.android.server.uri.UriGrantsManagerInternal; import org.json.JSONArray; import org.json.JSONException; Loading Loading @@ -197,7 +196,6 @@ public class PreferencesHelper implements RankingConfig { private final PermissionManager mPermissionManager; private final NotificationChannelLogger mNotificationChannelLogger; private final AppOpsManager mAppOps; private final UriGrantsManagerInternal mUgmInternal; private SparseBooleanArray mBadgingEnabled; private SparseBooleanArray mBubblesEnabled; Loading @@ -214,7 +212,6 @@ public class PreferencesHelper implements RankingConfig { ZenModeHelper zenHelper, PermissionHelper permHelper, PermissionManager permManager, NotificationChannelLogger notificationChannelLogger, AppOpsManager appOpsManager, UriGrantsManagerInternal ugmInternal, SysUiStatsEvent.BuilderFactory statsEventBuilderFactory, boolean showReviewPermissionsNotification) { mContext = context; Loading @@ -226,7 +223,6 @@ public class PreferencesHelper implements RankingConfig { mNotificationChannelLogger = notificationChannelLogger; mAppOps = appOpsManager; mStatsEventBuilderFactory = statsEventBuilderFactory; mUgmInternal = ugmInternal; mShowReviewPermissionsNotification = showReviewPermissionsNotification; XML_VERSION = 4; Loading Loading @@ -1014,11 +1010,6 @@ public class PreferencesHelper implements RankingConfig { } clearLockedFieldsLocked(channel); // Verify that the app has permission to read the sound Uri // Only check for new channels, as regular apps can only set sound // before creating. See: {@link NotificationChannel#setSound} PermissionHelper.grantUriPermission(mUgmInternal, channel.getSound(), uid); channel.setImportanceLockedByCriticalDeviceFunction( r.defaultAppLockedImportance || r.fixedImportance); Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +1 −36 Original line number Diff line number Diff line Loading @@ -3775,41 +3775,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .checkGrantUriPermission(eq(Process.myUid()), any(), eq(soundUri), anyInt(), eq(Process.myUserHandle().getIdentifier())); mBinderService.updateNotificationChannelFromPrivilegedListener( null, mPkg, Process.myUserHandle(), updatedNotificationChannel); verify(mPreferencesHelper, times(1)).updateNotificationChannel( anyString(), anyInt(), any(), anyBoolean(), anyInt(), anyBoolean()); verify(mListeners, never()).notifyNotificationChannelChanged(eq(mPkg), eq(Process.myUserHandle()), eq(mTestNotificationChannel), eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); } @Test public void testUpdateNotificationChannelFromPrivilegedListener_oldSoundNoUriPerm_newSoundHasUriPerm() throws Exception { mService.setPreferencesHelper(mPreferencesHelper); when(mCompanionMgr.getAssociations(mPkg, mUserId)) .thenReturn(singletonList(mock(AssociationInfo.class))); when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(), eq(mTestNotificationChannel.getId()), anyBoolean())) .thenReturn(mTestNotificationChannel); // Missing Uri permissions for the old channel sound final Uri oldSoundUri = Settings.System.DEFAULT_NOTIFICATION_URI; doThrow(new SecurityException("no access")).when(mUgmInternal) .checkGrantUriPermission(eq(Process.myUid()), any(), eq(oldSoundUri), anyInt(), eq(Process.myUserHandle().getIdentifier())); // Has Uri permissions for the old channel sound final Uri newSoundUri = Uri.parse("content://media/test/sound/uri"); final NotificationChannel updatedNotificationChannel = new NotificationChannel( TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT); updatedNotificationChannel.setSound(newSoundUri, updatedNotificationChannel.getAudioAttributes()); mBinderService.updateNotificationChannelFromPrivilegedListener( null, PKG, Process.myUserHandle(), updatedNotificationChannel); Loading Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +7 −2 Original line number Diff line number Diff line Loading @@ -2342,7 +2342,6 @@ public class NotificationManagerService extends SystemService { mPermissionManager, mNotificationChannelLogger, mAppOps, mUgmInternal, new SysUiStatsEvent.BuilderFactory(), mShowReviewPermissionsNotification); mRankingHelper = new RankingHelper(getContext(), Loading Loading @@ -5882,7 +5881,13 @@ public class NotificationManagerService extends SystemService { final Uri originalSoundUri = (originalChannel != null) ? originalChannel.getSound() : null; if (soundUri != null && !Objects.equals(originalSoundUri, soundUri)) { PermissionHelper.grantUriPermission(mUgmInternal, soundUri, sourceUid); Binder.withCleanCallingIdentity(() -> { mUgmInternal.checkGrantUriPermission(sourceUid, null, ContentProvider.getUriWithoutUserId(soundUri), Intent.FLAG_GRANT_READ_URI_PERMISSION, ContentProvider.getUserIdFromUri(soundUri, UserHandle.getUserId(sourceUid))); }); } } Loading
services/core/java/com/android/server/notification/NotificationRecord.java +10 −1 Original line number Diff line number Diff line Loading @@ -1417,13 +1417,20 @@ public final class NotificationRecord { * {@link SecurityException} depending on target SDK of enqueuing app. */ private void visitGrantableUri(Uri uri, boolean userOverriddenUri, boolean isSound) { if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return; if (mGrantableUris != null && mGrantableUris.contains(uri)) { return; // already verified this URI } final int sourceUid = getSbn().getUid(); final long ident = Binder.clearCallingIdentity(); try { PermissionHelper.grantUriPermission(mUgmInternal, uri, sourceUid); // This will throw a SecurityException if the caller can't grant. mUgmInternal.checkGrantUriPermission(sourceUid, null, ContentProvider.getUriWithoutUserId(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION, ContentProvider.getUserIdFromUri(uri, UserHandle.getUserId(sourceUid))); if (mGrantableUris == null) { mGrantableUris = new ArraySet<>(); Loading @@ -1443,6 +1450,8 @@ public final class NotificationRecord { } } } } finally { Binder.restoreCallingIdentity(ident); } } Loading
services/core/java/com/android/server/notification/PermissionHelper.java +1 −20 Original line number Diff line number Diff line Loading @@ -25,25 +25,19 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.Manifest; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.net.Uri; import android.os.Binder; import android.os.RemoteException; import android.os.UserHandle; import android.permission.IPermissionManager; import android.util.ArrayMap; import android.util.Pair; import android.util.Slog; import com.android.internal.util.ArrayUtils; import com.android.server.uri.UriGrantsManagerInternal; import java.util.Collections; import java.util.HashSet; Loading Loading @@ -302,19 +296,6 @@ public final class PermissionHelper { return false; } static void grantUriPermission(final UriGrantsManagerInternal ugmInternal, Uri uri, int sourceUid) { if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return; Binder.withCleanCallingIdentity(() -> { // This will throw a SecurityException if the caller can't grant. ugmInternal.checkGrantUriPermission(sourceUid, null, ContentProvider.getUriWithoutUserId(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION, ContentProvider.getUserIdFromUri(uri, UserHandle.getUserId(sourceUid))); }); } public static class PackagePermission { public final String packageName; public final @UserIdInt int userId; Loading
services/core/java/com/android/server/notification/PreferencesHelper.java +0 −9 Original line number Diff line number Diff line Loading @@ -85,7 +85,6 @@ import com.android.internal.util.XmlUtils; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import com.android.server.notification.PermissionHelper.PackagePermission; import com.android.server.uri.UriGrantsManagerInternal; import org.json.JSONArray; import org.json.JSONException; Loading Loading @@ -197,7 +196,6 @@ public class PreferencesHelper implements RankingConfig { private final PermissionManager mPermissionManager; private final NotificationChannelLogger mNotificationChannelLogger; private final AppOpsManager mAppOps; private final UriGrantsManagerInternal mUgmInternal; private SparseBooleanArray mBadgingEnabled; private SparseBooleanArray mBubblesEnabled; Loading @@ -214,7 +212,6 @@ public class PreferencesHelper implements RankingConfig { ZenModeHelper zenHelper, PermissionHelper permHelper, PermissionManager permManager, NotificationChannelLogger notificationChannelLogger, AppOpsManager appOpsManager, UriGrantsManagerInternal ugmInternal, SysUiStatsEvent.BuilderFactory statsEventBuilderFactory, boolean showReviewPermissionsNotification) { mContext = context; Loading @@ -226,7 +223,6 @@ public class PreferencesHelper implements RankingConfig { mNotificationChannelLogger = notificationChannelLogger; mAppOps = appOpsManager; mStatsEventBuilderFactory = statsEventBuilderFactory; mUgmInternal = ugmInternal; mShowReviewPermissionsNotification = showReviewPermissionsNotification; XML_VERSION = 4; Loading Loading @@ -1014,11 +1010,6 @@ public class PreferencesHelper implements RankingConfig { } clearLockedFieldsLocked(channel); // Verify that the app has permission to read the sound Uri // Only check for new channels, as regular apps can only set sound // before creating. See: {@link NotificationChannel#setSound} PermissionHelper.grantUriPermission(mUgmInternal, channel.getSound(), uid); channel.setImportanceLockedByCriticalDeviceFunction( r.defaultAppLockedImportance || r.fixedImportance); Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +1 −36 Original line number Diff line number Diff line Loading @@ -3775,41 +3775,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .checkGrantUriPermission(eq(Process.myUid()), any(), eq(soundUri), anyInt(), eq(Process.myUserHandle().getIdentifier())); mBinderService.updateNotificationChannelFromPrivilegedListener( null, mPkg, Process.myUserHandle(), updatedNotificationChannel); verify(mPreferencesHelper, times(1)).updateNotificationChannel( anyString(), anyInt(), any(), anyBoolean(), anyInt(), anyBoolean()); verify(mListeners, never()).notifyNotificationChannelChanged(eq(mPkg), eq(Process.myUserHandle()), eq(mTestNotificationChannel), eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); } @Test public void testUpdateNotificationChannelFromPrivilegedListener_oldSoundNoUriPerm_newSoundHasUriPerm() throws Exception { mService.setPreferencesHelper(mPreferencesHelper); when(mCompanionMgr.getAssociations(mPkg, mUserId)) .thenReturn(singletonList(mock(AssociationInfo.class))); when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(), eq(mTestNotificationChannel.getId()), anyBoolean())) .thenReturn(mTestNotificationChannel); // Missing Uri permissions for the old channel sound final Uri oldSoundUri = Settings.System.DEFAULT_NOTIFICATION_URI; doThrow(new SecurityException("no access")).when(mUgmInternal) .checkGrantUriPermission(eq(Process.myUid()), any(), eq(oldSoundUri), anyInt(), eq(Process.myUserHandle().getIdentifier())); // Has Uri permissions for the old channel sound final Uri newSoundUri = Uri.parse("content://media/test/sound/uri"); final NotificationChannel updatedNotificationChannel = new NotificationChannel( TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT); updatedNotificationChannel.setSound(newSoundUri, updatedNotificationChannel.getAudioAttributes()); mBinderService.updateNotificationChannelFromPrivilegedListener( null, PKG, Process.myUserHandle(), updatedNotificationChannel); Loading