Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 777fb8ee authored by Santiago Seifert's avatar Santiago Seifert Committed by Android (Google) Code Review
Browse files

Merge "Push session creation request to provider superclass" into main

parents 9a9a9cb8 3db562b8
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
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 @@ abstract class MediaRoute2Provider {
                @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);
        }
    }
}
+23 −62
Original line number Diff line number Diff line
@@ -79,12 +79,15 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
            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 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {

        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 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
        if (Flags.enableBuiltInSpeakerRouteSuitabilityStatuses()) {
            synchronized (mTransferLock) {
                mPendingTransferRequest =
                        new SessionCreationRequest(
                        new SessionCreationOrTransferRequest(
                                requestId,
                                routeId,
                                transferReason,
@@ -438,7 +443,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
                        boolean isTransferringToTheSelectedRoute =
                                mPendingTransferRequest.isTargetRoute(selectedRoute);
                        boolean canBePotentiallyTransferred =
                                mPendingTransferRequest.isInsideOfRoutesList(transferableRoutes);
                                mPendingTransferRequest.isTargetRouteIdInList(transferableRoutes);

                        if (isTransferringToTheSelectedRoute) {
                            transferReason = mPendingTransferRequest.mTransferReason;
@@ -492,20 +497,20 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
    @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 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
                    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 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
        // 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 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
                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);