MediaRouter: save sessions in media router service

Each MediaRoute2Provider instance saves session infos
published by MediaRoute2ProviderService.

For that, MediaRouter2ProviderService notifies provider info and session
infos simultaneously and to minimize the number of binder calls,
schedulePublishState is added into MediaRoute2ProviderService.

The saved sessions can be obtained by calling MRM.getActiveSessions().

Test: atest mediaroutertest
 && manually call MRM.getActiveSessions()

Change-Id: I6938105f8d154ad9542f7e7c6210a451ee4ae90d
diff --git a/services/core/java/com/android/server/media/MediaRoute2Provider.java b/services/core/java/com/android/server/media/MediaRoute2Provider.java
index a30dd98..3cc18b6 100644
--- a/services/core/java/com/android/server/media/MediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/MediaRoute2Provider.java
@@ -24,6 +24,9 @@
 import android.media.MediaRoute2ProviderInfo;
 import android.media.RouteSessionInfo;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
 
 abstract class MediaRoute2Provider {
@@ -31,7 +34,8 @@
     final String mUniqueId;
 
     Callback mCallback;
-    private MediaRoute2ProviderInfo mProviderInfo;
+    private volatile MediaRoute2ProviderInfo mProviderInfo;
+    private volatile List<RouteSessionInfo> mSessionInfos = Collections.emptyList();
 
     MediaRoute2Provider(@NonNull ComponentName componentName) {
         mComponentName = Objects.requireNonNull(componentName, "Component name must not be null.");
@@ -64,15 +68,29 @@
         return mProviderInfo;
     }
 
-    void setAndNotifyProviderInfo(MediaRoute2ProviderInfo info) {
-        //TODO: check if info is not updated
-        if (info == null) {
+    @NonNull
+    public List<RouteSessionInfo> getSessionInfos() {
+        return mSessionInfos;
+    }
+
+    void setAndNotifyProviderState(MediaRoute2ProviderInfo providerInfo,
+            List<RouteSessionInfo> sessionInfos) {
+        if (providerInfo == null) {
             mProviderInfo = null;
         } else {
-            mProviderInfo = new MediaRoute2ProviderInfo.Builder(info)
+            mProviderInfo = new MediaRoute2ProviderInfo.Builder(providerInfo)
                     .setUniqueId(mUniqueId)
                     .build();
         }
+        List<RouteSessionInfo> sessionInfoWithProviderId = new ArrayList<RouteSessionInfo>();
+        for (RouteSessionInfo sessionInfo : sessionInfos) {
+            sessionInfoWithProviderId.add(
+                    new RouteSessionInfo.Builder(sessionInfo)
+                            .setProviderId(mUniqueId)
+                            .build());
+        }
+        mSessionInfos = sessionInfoWithProviderId;
+
         if (mCallback != null) {
             mCallback.onProviderStateChanged(this);
         }