Merge "Fix race condition using notification pipeline" into main
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 6d34a0f..04a413a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -303,7 +303,12 @@
         // TODO(b/169655907): get the semi-filtered notifications for current user
         Collection<NotificationEntry> allNotifications = mNotifPipeline.getAllNotifs();
         if (notificationMediaManagerBackgroundExecution()) {
-            mBackgroundExecutor.execute(() -> findPlayingMediaNotification(allNotifications));
+            // Create new sbn list to be accessed in background thread.
+            List<StatusBarNotification> statusBarNotifications = new ArrayList<>();
+            for (NotificationEntry entry: allNotifications) {
+                statusBarNotifications.add(entry.getSbn());
+            }
+            mBackgroundExecutor.execute(() -> findPlayingMediaNotification(statusBarNotifications));
         } else {
             findPlayingMediaNotification(allNotifications);
         }
@@ -341,6 +346,51 @@
             }
         }
 
+        StatusBarNotification statusBarNotification = null;
+        if (mediaNotification != null) {
+            statusBarNotification = mediaNotification.getSbn();
+        }
+        setUpControllerAndKey(controller, statusBarNotification);
+    }
+
+    /**
+     * Find a notification and media controller associated with the playing media session, and
+     * update this manager's internal state.
+     * This method must be called in background.
+     * TODO(b/273443374) check this method
+     */
+    void findPlayingMediaNotification(@NonNull List<StatusBarNotification> allNotifications) {
+        // Promote the media notification with a controller in 'playing' state, if any.
+        StatusBarNotification statusBarNotification = null;
+        MediaController controller = null;
+        for (StatusBarNotification sbn : allNotifications) {
+            Notification notif = sbn.getNotification();
+            if (notif.isMediaNotification()) {
+                final MediaSession.Token token =
+                        sbn.getNotification().extras.getParcelable(
+                                Notification.EXTRA_MEDIA_SESSION, MediaSession.Token.class);
+                if (token != null) {
+                    MediaController aController = new MediaController(mContext, token);
+                    if (PlaybackState.STATE_PLAYING
+                            == getMediaControllerPlaybackState(aController)) {
+                        if (DEBUG_MEDIA) {
+                            Log.v(TAG, "DEBUG_MEDIA: found mediastyle controller matching "
+                                    + sbn.getKey());
+                        }
+                        statusBarNotification = sbn;
+                        controller = aController;
+                        break;
+                    }
+                }
+            }
+        }
+
+        setUpControllerAndKey(controller, statusBarNotification);
+    }
+
+    private void setUpControllerAndKey(
+            MediaController controller,
+            StatusBarNotification mediaNotification) {
         if (controller != null && !sameSessions(mMediaController, controller)) {
             // We have a new media session
             clearCurrentMediaNotificationSession();
@@ -354,8 +404,8 @@
         }
 
         if (mediaNotification != null
-                && !mediaNotification.getSbn().getKey().equals(mMediaNotificationKey)) {
-            mMediaNotificationKey = mediaNotification.getSbn().getKey();
+                && !mediaNotification.getKey().equals(mMediaNotificationKey)) {
+            mMediaNotificationKey = mediaNotification.getKey();
             if (DEBUG_MEDIA) {
                 Log.v(TAG, "DEBUG_MEDIA: Found new media notification: key="
                         + mMediaNotificationKey);