OSDN Git Service

Merge "Grant notification Uri permissions as sending app." into pi-dev
authorJeff Sharkey <jsharkey@google.com>
Wed, 18 Apr 2018 18:18:48 +0000 (18:18 +0000)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Wed, 18 Apr 2018 18:18:48 +0000 (18:18 +0000)
1  2 
services/core/java/com/android/server/notification/NotificationManagerService.java
services/core/java/com/android/server/notification/NotificationRecord.java
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java

@@@ -5406,39 -5384,119 +5392,125 @@@ public class NotificationManagerServic
          mArchive.record(r.sbn);
  
          final long now = System.currentTimeMillis();
 -        MetricsLogger.action(r.getLogMaker(now)
 +        final LogMaker logMaker = r.getLogMaker(now)
                  .setCategory(MetricsEvent.NOTIFICATION_ITEM)
                  .setType(MetricsEvent.TYPE_DISMISS)
 -                .setSubtype(reason));
 +                .setSubtype(reason);
 +        if (rank != -1 && count != -1) {
 +            logMaker.addTaggedData(MetricsEvent.NOTIFICATION_SHADE_INDEX, rank)
 +                    .addTaggedData(MetricsEvent.NOTIFICATION_SHADE_COUNT, count);
 +        }
 +        MetricsLogger.action(logMaker);
          EventLogTags.writeNotificationCanceled(canceledKey, reason,
 -                r.getLifespanMs(now), r.getFreshnessMs(now), r.getExposureMs(now), listenerName);
 +                r.getLifespanMs(now), r.getFreshnessMs(now), r.getExposureMs(now),
 +                rank, count, listenerName);
      }
  
-     void revokeUriPermissions(NotificationRecord newRecord, NotificationRecord oldRecord) {
-         Set<Uri> oldUris = oldRecord.getNotificationUris();
-         Set<Uri> newUris = newRecord == null ? new HashSet<>() : newRecord.getNotificationUris();
-         oldUris.removeAll(newUris);
+     @VisibleForTesting
+     void updateUriPermissions(@Nullable NotificationRecord newRecord,
+             @Nullable NotificationRecord oldRecord, String targetPkg, int targetUserId) {
+         final String key = (newRecord != null) ? newRecord.getKey() : oldRecord.getKey();
+         if (DBG) Slog.d(TAG, key + ": updating permissions");
+         final ArraySet<Uri> newUris = (newRecord != null) ? newRecord.getGrantableUris() : null;
+         final ArraySet<Uri> oldUris = (oldRecord != null) ? oldRecord.getGrantableUris() : null;
  
-         long ident = Binder.clearCallingIdentity();
-         try {
-             for (Uri uri : oldUris) {
-                 if (uri != null) {
-                     int notiUserId = oldRecord.getUserId();
-                     int sourceUserId = notiUserId == USER_ALL ? USER_SYSTEM
-                             : ContentProvider.getUserIdFromUri(uri, notiUserId);
-                     uri = ContentProvider.getUriWithoutUserId(uri);
-                     mAm.revokeUriPermissionFromOwner(mPermissionOwner,
-                             uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, sourceUserId);
+         // Shortcut when no Uris involved
+         if (newUris == null && oldUris == null) {
+             return;
+         }
+         // Inherit any existing owner
+         IBinder permissionOwner = null;
+         if (newRecord != null && permissionOwner == null) {
+             permissionOwner = newRecord.permissionOwner;
+         }
+         if (oldRecord != null && permissionOwner == null) {
+             permissionOwner = oldRecord.permissionOwner;
+         }
+         // If we have Uris to grant, but no owner yet, go create one
+         if (newUris != null && permissionOwner == null) {
+             try {
+                 if (DBG) Slog.d(TAG, key + ": creating owner");
+                 permissionOwner = mAm.newUriPermissionOwner("NOTIF:" + key);
+             } catch (RemoteException ignored) {
+                 // Ignored because we're in same process
+             }
+         }
+         // If we have no Uris to grant, but an existing owner, go destroy it
+         if (newUris == null && permissionOwner != null) {
+             final long ident = Binder.clearCallingIdentity();
+             try {
+                 if (DBG) Slog.d(TAG, key + ": destroying owner");
+                 mAm.revokeUriPermissionFromOwner(permissionOwner, null, ~0,
+                         UserHandle.getUserId(oldRecord.getUid()));
+                 permissionOwner = null;
+             } catch (RemoteException ignored) {
+                 // Ignored because we're in same process
+             } finally {
+                 Binder.restoreCallingIdentity(ident);
+             }
+         }
+         // Grant access to new Uris
+         if (newUris != null && permissionOwner != null) {
+             for (int i = 0; i < newUris.size(); i++) {
+                 final Uri uri = newUris.valueAt(i);
+                 if (oldUris == null || !oldUris.contains(uri)) {
+                     if (DBG) Slog.d(TAG, key + ": granting " + uri);
+                     grantUriPermission(permissionOwner, uri, newRecord.getUid(), targetPkg,
+                             targetUserId);
                  }
              }
-         } catch (RemoteException e) {
-             Log.e(TAG, "Count not revoke uri permissions", e);
+         }
+         // Revoke access to old Uris
+         if (oldUris != null && permissionOwner != null) {
+             for (int i = 0; i < oldUris.size(); i++) {
+                 final Uri uri = oldUris.valueAt(i);
+                 if (newUris == null || !newUris.contains(uri)) {
+                     if (DBG) Slog.d(TAG, key + ": revoking " + uri);
+                     revokeUriPermission(permissionOwner, uri, oldRecord.getUid());
+                 }
+             }
+         }
+         if (newRecord != null) {
+             newRecord.permissionOwner = permissionOwner;
+         }
+     }
+     private void grantUriPermission(IBinder owner, Uri uri, int sourceUid, String targetPkg,
+             int targetUserId) {
+         if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return;
+         final long ident = Binder.clearCallingIdentity();
+         try {
+             mAm.grantUriPermissionFromOwner(owner, sourceUid, targetPkg,
+                     ContentProvider.getUriWithoutUserId(uri),
+                     Intent.FLAG_GRANT_READ_URI_PERMISSION,
+                     ContentProvider.getUserIdFromUri(uri, UserHandle.getUserId(sourceUid)),
+                     targetUserId);
+         } catch (RemoteException ignored) {
+             // Ignored because we're in same process
+         } finally {
+             Binder.restoreCallingIdentity(ident);
+         }
+     }
+     private void revokeUriPermission(IBinder owner, Uri uri, int sourceUid) {
+         if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return;
+         final long ident = Binder.clearCallingIdentity();
+         try {
+             mAm.revokeUriPermissionFromOwner(owner,
+                     ContentProvider.getUriWithoutUserId(uri),
+                     Intent.FLAG_GRANT_READ_URI_PERMISSION,
+                     ContentProvider.getUserIdFromUri(uri, UserHandle.getUserId(sourceUid)));
+         } catch (RemoteException ignored) {
+             // Ignored because we're in same process
          } finally {
              Binder.restoreCallingIdentity(ident);
          }