Push session creation request to provider superclass

The goal being its reuse in provider service proxy. This CL also renames
the pending transfer initiation data holder to cover regular transfers.

Bug: b/319651986
Test: Presubmit (non-functional refactor)
Flag: EXEMPT refactor
Change-Id: I2b78f36447765853c02a94a926913c6e8e096bc7
diff --git a/services/core/java/com/android/server/media/MediaRoute2Provider.java b/services/core/java/com/android/server/media/MediaRoute2Provider.java
index 1bc2a5e..363684f 100644
--- a/services/core/java/com/android/server/media/MediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/MediaRoute2Provider.java
@@ -21,6 +21,7 @@
 import android.content.ComponentName;
 import android.media.MediaRoute2Info;
 import android.media.MediaRoute2ProviderInfo;
+import android.media.MediaRouter2;
 import android.media.RouteDiscoveryPreference;
 import android.media.RoutingSessionInfo;
 import android.os.Bundle;
@@ -172,4 +173,59 @@
                 @NonNull RoutingSessionInfo sessionInfo);
         void onRequestFailed(@NonNull MediaRoute2Provider provider, long requestId, int reason);
     }
+
+    /**
+     * Holds session creation or transfer initiation information for a transfer in flight.
+     *
+     * <p>The initiator app is typically also the {@link RoutingSessionInfo#getClientPackageName()
+     * client app}, with the exception of the {@link MediaRouter2#getSystemController() system
+     * routing session} which is exceptional in that it's shared among all apps.
+     *
+     * <p>For the system routing session, the initiator app is the one that programmatically
+     * triggered the transfer (for example, via {@link MediaRouter2#transferTo}), or the target app
+     * of the proxy router that did the transfer.
+     *
+     * @see MediaRouter2.RoutingController#wasTransferInitiatedBySelf()
+     * @see RoutingSessionInfo#getTransferInitiatorPackageName()
+     * @see RoutingSessionInfo#getTransferInitiatorUserHandle()
+     */
+    protected static class SessionCreationOrTransferRequest {
+
+        /**
+         * The id of the request, or {@link
+         * android.media.MediaRoute2ProviderService#REQUEST_ID_NONE} if unknown.
+         */
+        public final long mRequestId;
+
+        /** The {@link MediaRoute2Info#getId() id} of the target route. */
+        @NonNull public final String mTargetRouteId;
+
+        @RoutingSessionInfo.TransferReason public final int mTransferReason;
+
+        /** The {@link android.os.UserHandle} on which the initiator app is running. */
+        @NonNull public final UserHandle mTransferInitiatorUserHandle;
+
+        @NonNull public final String mTransferInitiatorPackageName;
+
+        SessionCreationOrTransferRequest(
+                long requestId,
+                @NonNull String routeId,
+                @RoutingSessionInfo.TransferReason int transferReason,
+                @NonNull UserHandle transferInitiatorUserHandle,
+                @NonNull String transferInitiatorPackageName) {
+            mRequestId = requestId;
+            mTargetRouteId = routeId;
+            mTransferReason = transferReason;
+            mTransferInitiatorUserHandle = transferInitiatorUserHandle;
+            mTransferInitiatorPackageName = transferInitiatorPackageName;
+        }
+
+        public boolean isTargetRoute(@Nullable MediaRoute2Info route2Info) {
+            return route2Info != null && mTargetRouteId.equals(route2Info.getId());
+        }
+
+        public boolean isTargetRouteIdInList(@NonNull List<String> routesList) {
+            return routesList.stream().anyMatch(mTargetRouteId::equals);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index 6ce3ab4..76930a0 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -79,12 +79,15 @@
             new AudioManagerBroadcastReceiver();
 
     private final Object mRequestLock = new Object();
+
     @GuardedBy("mRequestLock")
-    private volatile SessionCreationRequest mPendingSessionCreationRequest;
+    private volatile SessionCreationOrTransferRequest mPendingSessionCreationOrTransferRequest;
 
     private final Object mTransferLock = new Object();
+
     @GuardedBy("mTransferLock")
-    @Nullable private volatile SessionCreationRequest mPendingTransferRequest;
+    @Nullable
+    private volatile SessionCreationOrTransferRequest mPendingTransferRequest;
 
     SystemMediaRoute2Provider(Context context, UserHandle user, Looper looper) {
         super(COMPONENT_NAME);
@@ -180,12 +183,14 @@
 
         synchronized (mRequestLock) {
             // Handle the previous request as a failure if exists.
-            if (mPendingSessionCreationRequest != null) {
-                mCallback.onRequestFailed(this, mPendingSessionCreationRequest.mRequestId,
+            if (mPendingSessionCreationOrTransferRequest != null) {
+                mCallback.onRequestFailed(
+                        /* provider= */ this,
+                        mPendingSessionCreationOrTransferRequest.mRequestId,
                         MediaRoute2ProviderService.REASON_UNKNOWN_ERROR);
             }
-            mPendingSessionCreationRequest =
-                    new SessionCreationRequest(
+            mPendingSessionCreationOrTransferRequest =
+                    new SessionCreationOrTransferRequest(
                             requestId,
                             routeId,
                             RoutingSessionInfo.TRANSFER_REASON_FALLBACK,
@@ -247,7 +252,7 @@
         if (Flags.enableBuiltInSpeakerRouteSuitabilityStatuses()) {
             synchronized (mTransferLock) {
                 mPendingTransferRequest =
-                        new SessionCreationRequest(
+                        new SessionCreationOrTransferRequest(
                                 requestId,
                                 routeId,
                                 transferReason,
@@ -438,7 +443,7 @@
                         boolean isTransferringToTheSelectedRoute =
                                 mPendingTransferRequest.isTargetRoute(selectedRoute);
                         boolean canBePotentiallyTransferred =
-                                mPendingTransferRequest.isInsideOfRoutesList(transferableRoutes);
+                                mPendingTransferRequest.isTargetRouteIdInList(transferableRoutes);
 
                         if (isTransferringToTheSelectedRoute) {
                             transferReason = mPendingTransferRequest.mTransferReason;
@@ -492,20 +497,20 @@
     @GuardedBy("mRequestLock")
     private void reportPendingSessionRequestResultLockedIfNeeded(
             RoutingSessionInfo newSessionInfo) {
-        if (mPendingSessionCreationRequest == null) {
+        if (mPendingSessionCreationOrTransferRequest == null) {
             // No pending request, nothing to report.
             return;
         }
 
-        long pendingRequestId = mPendingSessionCreationRequest.mRequestId;
-        if (TextUtils.equals(mSelectedRouteId, mPendingSessionCreationRequest.mRouteId)) {
+        long pendingRequestId = mPendingSessionCreationOrTransferRequest.mRequestId;
+        if (mPendingSessionCreationOrTransferRequest.mTargetRouteId.equals(mSelectedRouteId)) {
             if (DEBUG) {
                 Slog.w(
                         TAG,
                         "Session creation success to route "
-                                + mPendingSessionCreationRequest.mRouteId);
+                                + mPendingSessionCreationOrTransferRequest.mTargetRouteId);
             }
-            mPendingSessionCreationRequest = null;
+            mPendingSessionCreationOrTransferRequest = null;
             mCallback.onSessionCreated(this, pendingRequestId, newSessionInfo);
         } else {
             boolean isRequestedRouteConnectedBtRoute = isRequestedRouteConnectedBtRoute();
@@ -515,16 +520,16 @@
                     Slog.w(
                             TAG,
                             "Session creation failed to route "
-                                    + mPendingSessionCreationRequest.mRouteId);
+                                    + mPendingSessionCreationOrTransferRequest.mTargetRouteId);
                 }
-                mPendingSessionCreationRequest = null;
+                mPendingSessionCreationOrTransferRequest = null;
                 mCallback.onRequestFailed(
                         this, pendingRequestId, MediaRoute2ProviderService.REASON_UNKNOWN_ERROR);
             } else if (DEBUG) {
                 Slog.w(
                         TAG,
                         "Session creation waiting state to route "
-                                + mPendingSessionCreationRequest.mRouteId);
+                                + mPendingSessionCreationOrTransferRequest.mTargetRouteId);
             }
         }
     }
@@ -535,7 +540,8 @@
         // where two BT routes are active so the transferable routes list is empty.
         // See b/307723189 for context
         for (MediaRoute2Info btRoute : mBluetoothRouteController.getAllBluetoothRoutes()) {
-            if (TextUtils.equals(btRoute.getId(), mPendingSessionCreationRequest.mRouteId)) {
+            if (TextUtils.equals(
+                    btRoute.getId(), mPendingSessionCreationOrTransferRequest.mTargetRouteId)) {
                 return true;
             }
         }
@@ -585,51 +591,6 @@
                 mBluetoothRouteController.getClass().getSimpleName());
     }
 
-    private static class SessionCreationRequest {
-        private final long mRequestId;
-        @NonNull private final String mRouteId;
-
-        @RoutingSessionInfo.TransferReason private final int mTransferReason;
-
-        @NonNull private final UserHandle mTransferInitiatorUserHandle;
-        @NonNull private final String mTransferInitiatorPackageName;
-
-        SessionCreationRequest(
-                long requestId,
-                @NonNull String routeId,
-                @RoutingSessionInfo.TransferReason int transferReason,
-                @NonNull UserHandle transferInitiatorUserHandle,
-                @NonNull String transferInitiatorPackageName) {
-            mRequestId = requestId;
-            mRouteId = routeId;
-            mTransferReason = transferReason;
-            mTransferInitiatorUserHandle = transferInitiatorUserHandle;
-            mTransferInitiatorPackageName = transferInitiatorPackageName;
-        }
-
-        private boolean isTargetRoute(@Nullable MediaRoute2Info route2Info) {
-            if (route2Info == null) {
-                return false;
-            }
-
-            return isTargetRoute(route2Info.getId());
-        }
-
-        private boolean isTargetRoute(@Nullable String routeId) {
-            return mRouteId.equals(routeId);
-        }
-
-        private boolean isInsideOfRoutesList(@NonNull List<String> routesList) {
-            for (String routeId : routesList) {
-                if (isTargetRoute(routeId)) {
-                    return true;
-                }
-            }
-
-            return false;
-        }
-    }
-
     void updateVolume() {
         int devices = mAudioManager.getDevicesForStream(AudioManager.STREAM_MUSIC);
         int volume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);