Loading media/java/android/media/MediaRoute2ProviderService.java +16 −9 Original line number Diff line number Diff line Loading @@ -358,7 +358,9 @@ public abstract class MediaRoute2ProviderService extends Service { * @return a {@link MediaStreams} instance that holds the media streams to route as part of the * newly created routing session. May be null if system media capture failed, in which case * you can ignore the return value, as you will receive a call to {@link #onReleaseSession} * where you can clean up this session * where you can clean up this session. {@link AudioRecord#startRecording()} must be called * immediately on {@link MediaStreams#getAudioRecord()} after calling this method, in order * to start streaming audio to the receiver. * @hide */ // TODO: b/362507305 - Unhide once the implementation and CTS are in place. Loading Loading @@ -458,7 +460,6 @@ public abstract class MediaRoute2ProviderService extends Service { if (uid != Process.INVALID_UID) { audioMixingRuleBuilder.addMixRule(AudioMixingRule.RULE_MATCH_UID, uid); } AudioMix mix = new AudioMix.Builder(audioMixingRuleBuilder.build()) .setFormat(audioFormat) Loading @@ -471,7 +472,11 @@ public abstract class MediaRoute2ProviderService extends Service { Log.e(TAG, "Couldn't fetch the audio manager."); return; } audioManager.registerAudioPolicy(audioPolicy); int audioPolicyResult = audioManager.registerAudioPolicy(audioPolicy); if (audioPolicyResult != AudioManager.SUCCESS) { Log.e(TAG, "Failed to register the audio policy."); return; } var audioRecord = audioPolicy.createAudioRecordSink(mix); if (audioRecord == null) { Log.e(TAG, "Audio record creation failed."); Loading Loading @@ -540,17 +545,19 @@ public abstract class MediaRoute2ProviderService extends Service { } /** Releases any system media routing resources associated with the given {@code sessionId}. */ private void maybeReleaseMediaStreams(String sessionId) { private boolean maybeReleaseMediaStreams(String sessionId) { if (!Flags.enableMirroringInMediaRouter2()) { return; return false; } synchronized (mSessionLock) { var streams = mOngoingMediaStreams.remove(sessionId); if (streams != null) { releaseAudioStream(streams.mAudioPolicy, streams.mAudioRecord); // TODO: b/380431086: Release the video stream once implemented. return true; } } return false; } // We cannot reach the code that requires MODIFY_AUDIO_ROUTING without holding it. Loading Loading @@ -1019,12 +1026,12 @@ public abstract class MediaRoute2ProviderService extends Service { if (!checkCallerIsSystem()) { return; } if (!checkSessionIdIsValid(sessionId, "releaseSession")) { return; } // We proactively release the system media routing once the system requests it, to // ensure it happens immediately. maybeReleaseMediaStreams(sessionId); if (!maybeReleaseMediaStreams(sessionId) && !checkSessionIdIsValid(sessionId, "releaseSession")) { return; } addRequestId(requestId); mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onReleaseSession, Loading services/core/java/com/android/server/media/MediaRoute2Provider.java +11 −1 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.MediaRoute2ProviderService.Reason; import android.media.MediaRouter2; import android.media.MediaRouter2Utils; import android.media.RouteDiscoveryPreference; Loading Loading @@ -123,6 +124,13 @@ abstract class MediaRoute2Provider { } } /** Calls {@link Callback#onRequestFailed} with the given id and reason. */ protected void notifyRequestFailed(long requestId, @Reason int reason) { if (mCallback != null) { mCallback.onRequestFailed(/* provider= */ this, requestId, reason); } } void setAndNotifyProviderState(MediaRoute2ProviderInfo providerInfo) { setProviderState(providerInfo); notifyProviderState(); Loading Loading @@ -175,7 +183,9 @@ abstract class MediaRoute2Provider { @NonNull RoutingSessionInfo sessionInfo); void onSessionReleased(@NonNull MediaRoute2Provider provider, @NonNull RoutingSessionInfo sessionInfo); void onRequestFailed(@NonNull MediaRoute2Provider provider, long requestId, int reason); void onRequestFailed( @NonNull MediaRoute2Provider provider, long requestId, @Reason int reason); } /** Loading services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java +114 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.media.IMediaRoute2ProviderServiceCallback; import android.media.MediaRoute2Info; import android.media.MediaRoute2ProviderInfo; import android.media.MediaRoute2ProviderService; import android.media.MediaRoute2ProviderService.Reason; import android.media.RouteDiscoveryPreference; import android.media.RoutingSessionInfo; import android.os.Bundle; Loading @@ -41,6 +42,7 @@ import android.os.Looper; import android.os.RemoteException; import android.os.UserHandle; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; import android.util.LongSparseArray; import android.util.Slog; Loading Loading @@ -88,6 +90,12 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { private final LongSparseArray<SessionCreationOrTransferRequest> mRequestIdToSessionCreationRequest; @GuardedBy("mLock") private final Map<String, SystemMediaSessionCallback> mSystemSessionCallbacks; @GuardedBy("mLock") private final LongSparseArray<SystemMediaSessionCallback> mRequestIdToSystemSessionRequest; @GuardedBy("mLock") private final Map<String, SessionCreationOrTransferRequest> mSessionOriginalIdToTransferRequest; Loading @@ -102,6 +110,8 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { mContext = Objects.requireNonNull(context, "Context must not be null."); mRequestIdToSessionCreationRequest = new LongSparseArray<>(); mSessionOriginalIdToTransferRequest = new HashMap<>(); mRequestIdToSystemSessionRequest = new LongSparseArray<>(); mSystemSessionCallbacks = new ArrayMap<>(); mIsSelfScanOnlyProvider = isSelfScanOnlyProvider; mSupportsSystemMediaRouting = supportsSystemMediaRouting; mUserId = userId; Loading Loading @@ -236,6 +246,48 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { } } /** * Requests the creation of a system media routing session. * * @param requestId The id of the request. * @param uid The uid of the package whose media to route, or {@link * android.os.Process#INVALID_UID} if not applicable (for example, if all the system's media * must be routed). * @param packageName The package name to populate {@link * RoutingSessionInfo#getClientPackageName()}. * @param routeId The id of the route to be initially {@link * RoutingSessionInfo#getSelectedRoutes()}. * @param sessionHints An optional bundle with paramets. * @param callback A {@link SystemMediaSessionCallback} to notify of session events. * @see MediaRoute2ProviderService#onCreateSystemRoutingSession */ public void requestCreateSystemMediaSession( long requestId, int uid, String packageName, String routeId, @Nullable Bundle sessionHints, @NonNull SystemMediaSessionCallback callback) { if (!Flags.enableMirroringInMediaRouter2()) { throw new IllegalStateException( "Unexpected call to requestCreateSystemMediaSession. Governing flag is" + " disabled."); } if (mConnectionReady) { boolean binderRequestSucceeded = mActiveConnection.requestCreateSystemMediaSession( requestId, uid, packageName, routeId, sessionHints); if (!binderRequestSucceeded) { // notify failure. return; } updateBinding(); synchronized (mLock) { mRequestIdToSystemSessionRequest.put(requestId, callback); } } } public boolean hasComponentName(String packageName, String className) { return mComponentName.getPackageName().equals(packageName) && mComponentName.getClassName().equals(className); Loading Loading @@ -292,7 +344,14 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { mLastDiscoveryPreference != null && mLastDiscoveryPreference.shouldPerformActiveScan() && mSupportsSystemMediaRouting; boolean bindDueToOngoingSystemMediaRoutingSessions = false; if (Flags.enableMirroringInMediaRouter2()) { synchronized (mLock) { bindDueToOngoingSystemMediaRoutingSessions = !mSystemSessionCallbacks.isEmpty(); } } if (!getSessionInfos().isEmpty() || bindDueToOngoingSystemMediaRoutingSessions || bindDueToManagerScan || bindDueToSystemMediaRoutingSupport) { return true; Loading Loading @@ -438,6 +497,13 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { String newSessionId = newSession.getId(); synchronized (mLock) { var systemMediaSessionCallback = mRequestIdToSystemSessionRequest.get(requestId); if (systemMediaSessionCallback != null) { mSystemSessionCallbacks.put(newSession.getOriginalId(), systemMediaSessionCallback); systemMediaSessionCallback.onSessionUpdate(newSession); return; } if (Flags.enableBuiltInSpeakerRouteSuitabilityStatuses()) { newSession = createSessionWithPopulatedTransferInitiationDataLocked( Loading Loading @@ -569,6 +635,12 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { boolean found = false; synchronized (mLock) { var sessionCallback = mSystemSessionCallbacks.get(releasedSession.getOriginalId()); if (sessionCallback != null) { sessionCallback.onSessionReleased(); return; } mSessionOriginalIdToTransferRequest.remove(releasedSession.getId()); for (RoutingSessionInfo session : mSessionInfos) { if (TextUtils.equals(session.getId(), releasedSession.getId())) { Loading Loading @@ -673,6 +745,26 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { pendingTransferCount); } /** * Callback for events related to system media sessions. * * @see MediaRoute2ProviderService#onCreateSystemRoutingSession */ public interface SystemMediaSessionCallback { /** * Called when the corresponding session's {@link RoutingSessionInfo}, or upon the creation * of the given session info. */ void onSessionUpdate(@NonNull RoutingSessionInfo sessionInfo); /** Called when the request with the given id fails for the given reason. */ void onRequestFailed(long requestId, @Reason int reason); /** Called when the corresponding session is released. */ void onSessionReleased(); } // All methods in this class are called on the main thread. private final class ServiceConnectionImpl implements ServiceConnection { Loading Loading @@ -739,6 +831,28 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { } } /** * Sends a system media session creation request to the provider service, and returns * whether the request transaction succeeded. * * <p>The transaction might fail, for example, if the recipient process has died. */ public boolean requestCreateSystemMediaSession( long requestId, int uid, String packageName, String routeId, @Nullable Bundle sessionHints) { try { mService.requestCreateSystemMediaSession( requestId, uid, packageName, routeId, sessionHints); return true; } catch (RemoteException ex) { Slog.e(TAG, "requestCreateSystemMediaSession: Failed to deliver request."); } return false; } public void releaseSession(long requestId, String sessionId) { try { mService.releaseSession(requestId, sessionId); Loading services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +10 −14 Original line number Diff line number Diff line Loading @@ -846,33 +846,29 @@ class MediaRouter2ServiceImpl { try { synchronized (mLock) { UserRecord userRecord = getOrCreateUserRecordLocked(userId); List<RoutingSessionInfo> sessionInfos; SystemMediaRoute2Provider systemProvider = userRecord.mHandler.getSystemProvider(); if (hasSystemRoutingPermissions) { if (setDeviceRouteSelected && !Flags.enableMirroringInMediaRouter2()) { if (!Flags.enableMirroringInMediaRouter2() && setDeviceRouteSelected) { // Return a fake system session that shows the device route as selected and // available bluetooth routes as transferable. return userRecord.mHandler.getSystemProvider() .generateDeviceRouteSelectedSessionInfo(targetPackageName); return systemProvider.generateDeviceRouteSelectedSessionInfo( targetPackageName); } else { sessionInfos = userRecord.mHandler.getSystemProvider().getSessionInfos(); if (!sessionInfos.isEmpty()) { // Return a copy of the current system session with no modification, // except setting the client package name. return new RoutingSessionInfo.Builder(sessionInfos.get(0)) .setClientPackageName(targetPackageName) .build(); RoutingSessionInfo session = systemProvider.getSessionForPackage(targetPackageName); if (session != null) { return session; } else { Slog.w(TAG, "System provider does not have any session info."); return null; } } } else { return new RoutingSessionInfo.Builder( userRecord.mHandler.getSystemProvider().getDefaultSessionInfo()) return new RoutingSessionInfo.Builder(systemProvider.getDefaultSessionInfo()) .setClientPackageName(targetPackageName) .build(); } } return null; } finally { Binder.restoreCallingIdentity(token); } Loading services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +19 −2 Original line number Diff line number Diff line Loading @@ -326,6 +326,23 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { return mDefaultSessionInfo; } /** * Returns the {@link RoutingSessionInfo} that corresponds to the package with the given name. */ public RoutingSessionInfo getSessionForPackage(String targetPackageName) { synchronized (mLock) { if (!mSessionInfos.isEmpty()) { // Return a copy of the current system session with no modification, // except setting the client package name. return new RoutingSessionInfo.Builder(mSessionInfos.get(0)) .setClientPackageName(targetPackageName) .build(); } else { return null; } } } /** * Builds a system {@link RoutingSessionInfo} with the selected route set to the currently * selected <b>device</b> route (wired or built-in, but not bluetooth) and transferable routes Loading Loading @@ -633,10 +650,10 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { RoutingSessionInfo sessionInfo; synchronized (mLock) { sessionInfo = mSessionInfos.get(0); if (sessionInfo == null) { if (mSessionInfos.isEmpty()) { return; } sessionInfo = mSessionInfos.get(0); } mCallback.onSessionUpdated(this, sessionInfo); Loading Loading
media/java/android/media/MediaRoute2ProviderService.java +16 −9 Original line number Diff line number Diff line Loading @@ -358,7 +358,9 @@ public abstract class MediaRoute2ProviderService extends Service { * @return a {@link MediaStreams} instance that holds the media streams to route as part of the * newly created routing session. May be null if system media capture failed, in which case * you can ignore the return value, as you will receive a call to {@link #onReleaseSession} * where you can clean up this session * where you can clean up this session. {@link AudioRecord#startRecording()} must be called * immediately on {@link MediaStreams#getAudioRecord()} after calling this method, in order * to start streaming audio to the receiver. * @hide */ // TODO: b/362507305 - Unhide once the implementation and CTS are in place. Loading Loading @@ -458,7 +460,6 @@ public abstract class MediaRoute2ProviderService extends Service { if (uid != Process.INVALID_UID) { audioMixingRuleBuilder.addMixRule(AudioMixingRule.RULE_MATCH_UID, uid); } AudioMix mix = new AudioMix.Builder(audioMixingRuleBuilder.build()) .setFormat(audioFormat) Loading @@ -471,7 +472,11 @@ public abstract class MediaRoute2ProviderService extends Service { Log.e(TAG, "Couldn't fetch the audio manager."); return; } audioManager.registerAudioPolicy(audioPolicy); int audioPolicyResult = audioManager.registerAudioPolicy(audioPolicy); if (audioPolicyResult != AudioManager.SUCCESS) { Log.e(TAG, "Failed to register the audio policy."); return; } var audioRecord = audioPolicy.createAudioRecordSink(mix); if (audioRecord == null) { Log.e(TAG, "Audio record creation failed."); Loading Loading @@ -540,17 +545,19 @@ public abstract class MediaRoute2ProviderService extends Service { } /** Releases any system media routing resources associated with the given {@code sessionId}. */ private void maybeReleaseMediaStreams(String sessionId) { private boolean maybeReleaseMediaStreams(String sessionId) { if (!Flags.enableMirroringInMediaRouter2()) { return; return false; } synchronized (mSessionLock) { var streams = mOngoingMediaStreams.remove(sessionId); if (streams != null) { releaseAudioStream(streams.mAudioPolicy, streams.mAudioRecord); // TODO: b/380431086: Release the video stream once implemented. return true; } } return false; } // We cannot reach the code that requires MODIFY_AUDIO_ROUTING without holding it. Loading Loading @@ -1019,12 +1026,12 @@ public abstract class MediaRoute2ProviderService extends Service { if (!checkCallerIsSystem()) { return; } if (!checkSessionIdIsValid(sessionId, "releaseSession")) { return; } // We proactively release the system media routing once the system requests it, to // ensure it happens immediately. maybeReleaseMediaStreams(sessionId); if (!maybeReleaseMediaStreams(sessionId) && !checkSessionIdIsValid(sessionId, "releaseSession")) { return; } addRequestId(requestId); mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onReleaseSession, Loading
services/core/java/com/android/server/media/MediaRoute2Provider.java +11 −1 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.MediaRoute2ProviderService.Reason; import android.media.MediaRouter2; import android.media.MediaRouter2Utils; import android.media.RouteDiscoveryPreference; Loading Loading @@ -123,6 +124,13 @@ abstract class MediaRoute2Provider { } } /** Calls {@link Callback#onRequestFailed} with the given id and reason. */ protected void notifyRequestFailed(long requestId, @Reason int reason) { if (mCallback != null) { mCallback.onRequestFailed(/* provider= */ this, requestId, reason); } } void setAndNotifyProviderState(MediaRoute2ProviderInfo providerInfo) { setProviderState(providerInfo); notifyProviderState(); Loading Loading @@ -175,7 +183,9 @@ abstract class MediaRoute2Provider { @NonNull RoutingSessionInfo sessionInfo); void onSessionReleased(@NonNull MediaRoute2Provider provider, @NonNull RoutingSessionInfo sessionInfo); void onRequestFailed(@NonNull MediaRoute2Provider provider, long requestId, int reason); void onRequestFailed( @NonNull MediaRoute2Provider provider, long requestId, @Reason int reason); } /** Loading
services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java +114 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.media.IMediaRoute2ProviderServiceCallback; import android.media.MediaRoute2Info; import android.media.MediaRoute2ProviderInfo; import android.media.MediaRoute2ProviderService; import android.media.MediaRoute2ProviderService.Reason; import android.media.RouteDiscoveryPreference; import android.media.RoutingSessionInfo; import android.os.Bundle; Loading @@ -41,6 +42,7 @@ import android.os.Looper; import android.os.RemoteException; import android.os.UserHandle; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; import android.util.LongSparseArray; import android.util.Slog; Loading Loading @@ -88,6 +90,12 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { private final LongSparseArray<SessionCreationOrTransferRequest> mRequestIdToSessionCreationRequest; @GuardedBy("mLock") private final Map<String, SystemMediaSessionCallback> mSystemSessionCallbacks; @GuardedBy("mLock") private final LongSparseArray<SystemMediaSessionCallback> mRequestIdToSystemSessionRequest; @GuardedBy("mLock") private final Map<String, SessionCreationOrTransferRequest> mSessionOriginalIdToTransferRequest; Loading @@ -102,6 +110,8 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { mContext = Objects.requireNonNull(context, "Context must not be null."); mRequestIdToSessionCreationRequest = new LongSparseArray<>(); mSessionOriginalIdToTransferRequest = new HashMap<>(); mRequestIdToSystemSessionRequest = new LongSparseArray<>(); mSystemSessionCallbacks = new ArrayMap<>(); mIsSelfScanOnlyProvider = isSelfScanOnlyProvider; mSupportsSystemMediaRouting = supportsSystemMediaRouting; mUserId = userId; Loading Loading @@ -236,6 +246,48 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { } } /** * Requests the creation of a system media routing session. * * @param requestId The id of the request. * @param uid The uid of the package whose media to route, or {@link * android.os.Process#INVALID_UID} if not applicable (for example, if all the system's media * must be routed). * @param packageName The package name to populate {@link * RoutingSessionInfo#getClientPackageName()}. * @param routeId The id of the route to be initially {@link * RoutingSessionInfo#getSelectedRoutes()}. * @param sessionHints An optional bundle with paramets. * @param callback A {@link SystemMediaSessionCallback} to notify of session events. * @see MediaRoute2ProviderService#onCreateSystemRoutingSession */ public void requestCreateSystemMediaSession( long requestId, int uid, String packageName, String routeId, @Nullable Bundle sessionHints, @NonNull SystemMediaSessionCallback callback) { if (!Flags.enableMirroringInMediaRouter2()) { throw new IllegalStateException( "Unexpected call to requestCreateSystemMediaSession. Governing flag is" + " disabled."); } if (mConnectionReady) { boolean binderRequestSucceeded = mActiveConnection.requestCreateSystemMediaSession( requestId, uid, packageName, routeId, sessionHints); if (!binderRequestSucceeded) { // notify failure. return; } updateBinding(); synchronized (mLock) { mRequestIdToSystemSessionRequest.put(requestId, callback); } } } public boolean hasComponentName(String packageName, String className) { return mComponentName.getPackageName().equals(packageName) && mComponentName.getClassName().equals(className); Loading Loading @@ -292,7 +344,14 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { mLastDiscoveryPreference != null && mLastDiscoveryPreference.shouldPerformActiveScan() && mSupportsSystemMediaRouting; boolean bindDueToOngoingSystemMediaRoutingSessions = false; if (Flags.enableMirroringInMediaRouter2()) { synchronized (mLock) { bindDueToOngoingSystemMediaRoutingSessions = !mSystemSessionCallbacks.isEmpty(); } } if (!getSessionInfos().isEmpty() || bindDueToOngoingSystemMediaRoutingSessions || bindDueToManagerScan || bindDueToSystemMediaRoutingSupport) { return true; Loading Loading @@ -438,6 +497,13 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { String newSessionId = newSession.getId(); synchronized (mLock) { var systemMediaSessionCallback = mRequestIdToSystemSessionRequest.get(requestId); if (systemMediaSessionCallback != null) { mSystemSessionCallbacks.put(newSession.getOriginalId(), systemMediaSessionCallback); systemMediaSessionCallback.onSessionUpdate(newSession); return; } if (Flags.enableBuiltInSpeakerRouteSuitabilityStatuses()) { newSession = createSessionWithPopulatedTransferInitiationDataLocked( Loading Loading @@ -569,6 +635,12 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { boolean found = false; synchronized (mLock) { var sessionCallback = mSystemSessionCallbacks.get(releasedSession.getOriginalId()); if (sessionCallback != null) { sessionCallback.onSessionReleased(); return; } mSessionOriginalIdToTransferRequest.remove(releasedSession.getId()); for (RoutingSessionInfo session : mSessionInfos) { if (TextUtils.equals(session.getId(), releasedSession.getId())) { Loading Loading @@ -673,6 +745,26 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { pendingTransferCount); } /** * Callback for events related to system media sessions. * * @see MediaRoute2ProviderService#onCreateSystemRoutingSession */ public interface SystemMediaSessionCallback { /** * Called when the corresponding session's {@link RoutingSessionInfo}, or upon the creation * of the given session info. */ void onSessionUpdate(@NonNull RoutingSessionInfo sessionInfo); /** Called when the request with the given id fails for the given reason. */ void onRequestFailed(long requestId, @Reason int reason); /** Called when the corresponding session is released. */ void onSessionReleased(); } // All methods in this class are called on the main thread. private final class ServiceConnectionImpl implements ServiceConnection { Loading Loading @@ -739,6 +831,28 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { } } /** * Sends a system media session creation request to the provider service, and returns * whether the request transaction succeeded. * * <p>The transaction might fail, for example, if the recipient process has died. */ public boolean requestCreateSystemMediaSession( long requestId, int uid, String packageName, String routeId, @Nullable Bundle sessionHints) { try { mService.requestCreateSystemMediaSession( requestId, uid, packageName, routeId, sessionHints); return true; } catch (RemoteException ex) { Slog.e(TAG, "requestCreateSystemMediaSession: Failed to deliver request."); } return false; } public void releaseSession(long requestId, String sessionId) { try { mService.releaseSession(requestId, sessionId); Loading
services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +10 −14 Original line number Diff line number Diff line Loading @@ -846,33 +846,29 @@ class MediaRouter2ServiceImpl { try { synchronized (mLock) { UserRecord userRecord = getOrCreateUserRecordLocked(userId); List<RoutingSessionInfo> sessionInfos; SystemMediaRoute2Provider systemProvider = userRecord.mHandler.getSystemProvider(); if (hasSystemRoutingPermissions) { if (setDeviceRouteSelected && !Flags.enableMirroringInMediaRouter2()) { if (!Flags.enableMirroringInMediaRouter2() && setDeviceRouteSelected) { // Return a fake system session that shows the device route as selected and // available bluetooth routes as transferable. return userRecord.mHandler.getSystemProvider() .generateDeviceRouteSelectedSessionInfo(targetPackageName); return systemProvider.generateDeviceRouteSelectedSessionInfo( targetPackageName); } else { sessionInfos = userRecord.mHandler.getSystemProvider().getSessionInfos(); if (!sessionInfos.isEmpty()) { // Return a copy of the current system session with no modification, // except setting the client package name. return new RoutingSessionInfo.Builder(sessionInfos.get(0)) .setClientPackageName(targetPackageName) .build(); RoutingSessionInfo session = systemProvider.getSessionForPackage(targetPackageName); if (session != null) { return session; } else { Slog.w(TAG, "System provider does not have any session info."); return null; } } } else { return new RoutingSessionInfo.Builder( userRecord.mHandler.getSystemProvider().getDefaultSessionInfo()) return new RoutingSessionInfo.Builder(systemProvider.getDefaultSessionInfo()) .setClientPackageName(targetPackageName) .build(); } } return null; } finally { Binder.restoreCallingIdentity(token); } Loading
services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +19 −2 Original line number Diff line number Diff line Loading @@ -326,6 +326,23 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { return mDefaultSessionInfo; } /** * Returns the {@link RoutingSessionInfo} that corresponds to the package with the given name. */ public RoutingSessionInfo getSessionForPackage(String targetPackageName) { synchronized (mLock) { if (!mSessionInfos.isEmpty()) { // Return a copy of the current system session with no modification, // except setting the client package name. return new RoutingSessionInfo.Builder(mSessionInfos.get(0)) .setClientPackageName(targetPackageName) .build(); } else { return null; } } } /** * Builds a system {@link RoutingSessionInfo} with the selected route set to the currently * selected <b>device</b> route (wired or built-in, but not bluetooth) and transferable routes Loading Loading @@ -633,10 +650,10 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { RoutingSessionInfo sessionInfo; synchronized (mLock) { sessionInfo = mSessionInfos.get(0); if (sessionInfo == null) { if (mSessionInfos.isEmpty()) { return; } sessionInfo = mSessionInfos.get(0); } mCallback.onSessionUpdated(this, sessionInfo); Loading