Grant URI permissions to NotificationListenerServices when added.

Bug: 162233630
Test: android.app.cts.NotificationManagerTest
Change-Id: I54b8aa8cf99e0713ee903bee00f5b6361b276608
(cherry picked from commit 41fe38a9e5d995a72f434dfcd9da7430799f92c5)
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 8dc7b93..2172aa5 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -9191,6 +9191,7 @@
             final NotificationRankingUpdate update;
             synchronized (mNotificationLock) {
                 update = makeRankingUpdateLocked(info);
+                grantUriPermissionsForActiveNotificationsLocked(info);
             }
             try {
                 listener.onListenerConnected(update);
@@ -9293,13 +9294,8 @@
                     // This notification became invisible -> remove the old one.
                     if (oldSbnVisible && !sbnVisible) {
                         final StatusBarNotification oldSbnLightClone = oldSbn.cloneLight();
-                        mHandler.post(new Runnable() {
-                            @Override
-                            public void run() {
-                                notifyRemoved(
-                                        info, oldSbnLightClone, update, null, REASON_USER_STOPPED);
-                            }
-                        });
+                        mHandler.post(() -> notifyRemoved(
+                                info, oldSbnLightClone, update, null, REASON_USER_STOPPED));
                         continue;
                     }
 
@@ -9309,12 +9305,7 @@
                     updateUriPermissions(r, old, info.component.getPackageName(), targetUserId);
 
                     final StatusBarNotification sbnToPost = trimCache.ForListener(info);
-                    mHandler.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            notifyPosted(info, sbnToPost, update);
-                        }
-                    });
+                    mHandler.post(() -> notifyPosted(info, sbnToPost, update));
                 }
             } catch (Exception e) {
                 Slog.e(TAG, "Could not notify listeners for " + r.getKey(), e);
@@ -9322,6 +9313,32 @@
         }
 
         /**
+         * Synchronously grant permissions to Uris for all active and visible notifications to the
+         * NotificationListenerService provided.
+         */
+        @GuardedBy("mNotificationLock")
+        private void grantUriPermissionsForActiveNotificationsLocked(ManagedServiceInfo info) {
+            try {
+                for (final NotificationRecord r : mNotificationList) {
+                    // This notification isn't visible -> ignore.
+                    if (!isVisibleToListener(r.getSbn(), info)) {
+                        continue;
+                    }
+                    // If the notification is hidden, permissions are not required by the listener.
+                    if (r.isHidden() && info.targetSdkVersion < Build.VERSION_CODES.P) {
+                        continue;
+                    }
+                    // Grant access before listener is initialized
+                    final int targetUserId = (info.userid == UserHandle.USER_ALL)
+                            ? UserHandle.USER_SYSTEM : info.userid;
+                    updateUriPermissions(r, null, info.component.getPackageName(), targetUserId);
+                }
+            } catch (Exception e) {
+                Slog.e(TAG, "Could not grant Uri permissions to " + info.component, e);
+            }
+        }
+
+        /**
          * asynchronously notify all listeners about a removed notification
          */
         @GuardedBy("mNotificationLock")