Loading services/core/java/com/android/server/media/MediaRoute2Provider.java +56 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } } services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +23 −62 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -247,7 +252,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { if (Flags.enableBuiltInSpeakerRouteSuitabilityStatuses()) { synchronized (mTransferLock) { mPendingTransferRequest = new SessionCreationRequest( new SessionCreationOrTransferRequest( requestId, routeId, transferReason, Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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); } } } Loading @@ -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; } } Loading Loading @@ -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); Loading Loading
services/core/java/com/android/server/media/MediaRoute2Provider.java +56 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } }
services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +23 −62 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -247,7 +252,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { if (Flags.enableBuiltInSpeakerRouteSuitabilityStatuses()) { synchronized (mTransferLock) { mPendingTransferRequest = new SessionCreationRequest( new SessionCreationOrTransferRequest( requestId, routeId, transferReason, Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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); } } } Loading @@ -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; } } Loading Loading @@ -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); Loading