diff --git a/api/current.txt b/api/current.txt index 255128ca8e350..1ef08e3be24dc 100644 --- a/api/current.txt +++ b/api/current.txt @@ -26899,7 +26899,6 @@ package android.media { method public final void notifyRequestFailed(long, int); method public final void notifyRoutes(@NonNull java.util.Collection); method public final void notifySessionCreated(@NonNull android.media.RoutingSessionInfo, long); - method public final void notifySessionCreationFailed(long); method public final void notifySessionReleased(@NonNull String); method public final void notifySessionUpdated(@NonNull android.media.RoutingSessionInfo); method @CallSuper @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent); diff --git a/media/java/android/media/IMediaRoute2ProviderServiceCallback.aidl b/media/java/android/media/IMediaRoute2ProviderServiceCallback.aidl index ab42d75bf14fd..882caad0f49b5 100644 --- a/media/java/android/media/IMediaRoute2ProviderServiceCallback.aidl +++ b/media/java/android/media/IMediaRoute2ProviderServiceCallback.aidl @@ -28,7 +28,6 @@ oneway interface IMediaRoute2ProviderServiceCallback { // TODO: Change it to updateRoutes? void updateState(in MediaRoute2ProviderInfo providerInfo); void notifySessionCreated(in RoutingSessionInfo sessionInfo, long requestId); - void notifySessionCreationFailed(long requestId); void notifySessionUpdated(in RoutingSessionInfo sessionInfo); void notifySessionReleased(in RoutingSessionInfo sessionInfo); void notifyRequestFailed(long requestId, int reason); diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java index aa0eda1fdbb17..51696a4de2d42 100644 --- a/media/java/android/media/MediaRoute2ProviderService.java +++ b/media/java/android/media/MediaRoute2ProviderService.java @@ -233,6 +233,7 @@ public abstract class MediaRoute2ProviderService extends Service { String sessionId = sessionInfo.getId(); synchronized (mSessionLock) { if (mSessionInfo.containsKey(sessionId)) { + // TODO: Notify failure to the requester, and throw exception if needed. Log.w(TAG, "Ignoring duplicate session id."); return; } @@ -252,24 +253,6 @@ public abstract class MediaRoute2ProviderService extends Service { } } - /** - * Notifies clients of that the session could not be created. - * - * @param requestId id of the previous request to create the session provided in - * {@link #onCreateSession(long, String, String, Bundle)}. - * @see #onCreateSession(long, String, String, Bundle) - */ - public final void notifySessionCreationFailed(long requestId) { - if (mRemoteCallback == null) { - return; - } - try { - mRemoteCallback.notifySessionCreationFailed(requestId); - } catch (RemoteException ex) { - Log.w(TAG, "Failed to notify session creation failed."); - } - } - /** * Notifies the existing session is updated. For example, when * {@link RoutingSessionInfo#getSelectedRoutes() selected routes} are changed. @@ -364,7 +347,7 @@ public abstract class MediaRoute2ProviderService extends Service { * {@link Bundle} which contains how to control the session. *

* If you can't create the session or want to reject the request, call - * {@link #notifySessionCreationFailed(long)} with the given {@code requestId}. + * {@link #notifyRequestFailed(long, int)} with the given {@code requestId}. * * @param requestId the id of this request * @param packageName the package name of the application that selected the route diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java index 0e7c7fc499b4a..22c5bce5b3817 100644 --- a/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java +++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java @@ -216,8 +216,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService @Nullable Bundle sessionHints) { MediaRoute2Info route = mRoutes.get(routeId); if (route == null || TextUtils.equals(ROUTE_ID3_SESSION_CREATION_FAILED, routeId)) { - // Tell the router that session cannot be created by passing null as sessionInfo. - notifySessionCreationFailed(requestId); + notifyRequestFailed(requestId, REASON_UNKNOWN_ERROR); return; } maybeDeselectRoute(routeId); diff --git a/services/core/java/com/android/server/media/MediaRoute2Provider.java b/services/core/java/com/android/server/media/MediaRoute2Provider.java index f144405436f95..4cb1ed9a0f9ea 100644 --- a/services/core/java/com/android/server/media/MediaRoute2Provider.java +++ b/services/core/java/com/android/server/media/MediaRoute2Provider.java @@ -111,7 +111,6 @@ abstract class MediaRoute2Provider { void onProviderStateChanged(@Nullable MediaRoute2Provider provider); void onSessionCreated(@NonNull MediaRoute2Provider provider, @Nullable RoutingSessionInfo sessionInfo, long requestId); - void onSessionCreationFailed(@NonNull MediaRoute2Provider provider, long requestId); void onSessionUpdated(@NonNull MediaRoute2Provider provider, @NonNull RoutingSessionInfo sessionInfo); void onSessionReleased(@NonNull MediaRoute2Provider provider, diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java index e64776cc6e35d..36a7bd983a293 100644 --- a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java +++ b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java @@ -328,19 +328,6 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider mCallback.onSessionCreated(this, sessionInfo, requestId); } - private void onSessionCreationFailed(Connection connection, long requestId) { - if (mActiveConnection != connection) { - return; - } - - if (requestId == MediaRoute2ProviderService.REQUEST_ID_NONE) { - Slog.w(TAG, "onSessionCreationFailed: Ignoring requestId REQUEST_ID_NONE"); - return; - } - - mCallback.onSessionCreationFailed(this, requestId); - } - private void onSessionUpdated(Connection connection, RoutingSessionInfo sessionInfo) { if (mActiveConnection != connection) { return; @@ -543,10 +530,6 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider mHandler.post(() -> onSessionCreated(Connection.this, sessionInfo, requestId)); } - void postSessionCreationFailed(long requestId) { - mHandler.post(() -> onSessionCreationFailed(Connection.this, requestId)); - } - void postSessionUpdated(RoutingSessionInfo sessionInfo) { mHandler.post(() -> onSessionUpdated(Connection.this, sessionInfo)); } @@ -555,7 +538,7 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider mHandler.post(() -> onSessionReleased(Connection.this, sessionInfo)); } - void postSessionReleased(long requestId, int reason) { + void postRequestFailed(long requestId, int reason) { mHandler.post(() -> onRequestFailed(Connection.this, requestId, reason)); } } @@ -588,14 +571,6 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider } } - @Override - public void notifySessionCreationFailed(long requestId) { - Connection connection = mConnectionRef.get(); - if (connection != null) { - connection.postSessionCreationFailed(requestId); - } - } - @Override public void notifySessionUpdated(RoutingSessionInfo sessionInfo) { Connection connection = mConnectionRef.get(); @@ -616,7 +591,7 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider public void notifyRequestFailed(long requestId, int reason) { Connection connection = mConnectionRef.get(); if (connection != null) { - connection.postSessionReleased(requestId, reason); + connection.postRequestFailed(requestId, reason); } } } diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index e78a35cd88a4b..16f2addcb8397 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -608,7 +608,8 @@ class MediaRouter2ServiceImpl { routerRecord.mUserRecord.mHandler.sendMessage( obtainMessage(UserHandler::requestCreateSessionOnHandler, routerRecord.mUserRecord.mHandler, - routerRecord, route, uniqueRequestId, sessionHints)); + routerRecord, /* managerRecord= */ null, route, uniqueRequestId, + sessionHints)); } private void selectRouteWithRouter2Locked(@NonNull IMediaRouter2 router, @@ -788,7 +789,8 @@ class MediaRouter2ServiceImpl { routerRecord.mUserRecord.mHandler.sendMessage( obtainMessage(UserHandler::requestCreateSessionOnHandler, routerRecord.mUserRecord.mHandler, - routerRecord, route, uniqueRequestId, null /* sessionHints */)); + routerRecord, managerRecord, route, uniqueRequestId, + /* sessionHints= */ null)); } private void selectRouteWithManagerLocked(@NonNull IMediaRouter2Manager manager, @@ -927,7 +929,7 @@ class MediaRouter2ServiceImpl { return ((long) routerOrManagerId << 32) | originalRequestId; } - static int toRouterOrManagerId(long uniqueRequestId) { + static int toRequesterId(long uniqueRequestId) { return (int) (uniqueRequestId >> 32); } @@ -1107,11 +1109,6 @@ class MediaRouter2ServiceImpl { this, provider, sessionInfo, requestId)); } - @Override - public void onSessionCreationFailed(@NonNull MediaRoute2Provider provider, long requestId) { - sendMessage(PooledLambda.obtainMessage(UserHandler::onSessionCreationFailedOnHandler, - this, provider, requestId)); - } @Override public void onSessionUpdated(@NonNull MediaRoute2Provider provider, @@ -1223,7 +1220,8 @@ class MediaRouter2ServiceImpl { } private void requestCreateSessionOnHandler(@NonNull RouterRecord routerRecord, - @NonNull MediaRoute2Info route, long requestId, @Nullable Bundle sessionHints) { + @Nullable ManagerRecord managerRecord, @NonNull MediaRoute2Info route, + long requestId, @Nullable Bundle sessionHints) { final MediaRoute2Provider provider = findProvider(route.getProviderId()); if (provider == null) { @@ -1235,7 +1233,7 @@ class MediaRouter2ServiceImpl { // TODO: Apply timeout for each request (How many seconds should we wait?) SessionCreationRequest request = - new SessionCreationRequest(routerRecord, route, requestId); + new SessionCreationRequest(routerRecord, managerRecord, route, requestId); mSessionCreationRequests.add(request); provider.requestCreateSession(routerRecord.mPackageName, route.getOriginalId(), @@ -1421,30 +1419,6 @@ class MediaRouter2ServiceImpl { mSessionToRouterMap.put(sessionInfo.getId(), routerRecord); } - private void onSessionCreationFailedOnHandler(@NonNull MediaRoute2Provider provider, - long requestId) { - SessionCreationRequest matchingRequest = null; - - for (SessionCreationRequest request : mSessionCreationRequests) { - if (request.mRequestId == requestId - && TextUtils.equals( - request.mRoute.getProviderId(), provider.getUniqueId())) { - matchingRequest = request; - break; - } - } - - if (matchingRequest == null) { - Slog.w(TAG, "Ignoring session creation failed result for unknown request. " - + "requestId=" + requestId); - return; - } - - mSessionCreationRequests.remove(matchingRequest); - notifySessionCreationFailedToRouter(matchingRequest.mRouterRecord, - toOriginalRequestId(requestId)); - } - private void onSessionInfoChangedOnHandler(@NonNull MediaRoute2Provider provider, @NonNull RoutingSessionInfo sessionInfo) { List managers = getManagers(); @@ -1483,30 +1457,56 @@ class MediaRouter2ServiceImpl { private void onRequestFailedOnHandler(@NonNull MediaRoute2Provider provider, long requestId, int reason) { - final int managerId = toRouterOrManagerId(requestId); - - MediaRouter2ServiceImpl service = mServiceRef.get(); - if (service == null) { + if (handleSessionCreationRequestFailed(provider, requestId, reason)) { return; } - ManagerRecord managerToNotifyFailure = null; - synchronized (service.mLock) { - for (ManagerRecord manager : mUserRecord.mManagerRecords) { - if (manager.mManagerId == managerId) { - managerToNotifyFailure = manager; - break; - } + final int requesterId = toRequesterId(requestId); + for (ManagerRecord manager : getManagerRecords()) { + if (manager.mManagerId == requesterId) { + notifyRequestFailedToManager( + manager.mManager, toOriginalRequestId(requestId), reason); + return; } } - if (managerToNotifyFailure == null) { - Slog.w(TAG, "No matching managerRecord found for managerId=" + managerId); - return; + // Currently, only the manager can get notified of failures. + // TODO: Notify router too when the related callback is introduced. + } + + // TODO: Find a way to prevent providers from notifying error on random requestId. + // Solutions can be: + // 1) Record the other type of requests too (not only session creation request) + // 2) Throw exception on providers when they try to notify error on random requestId. + private boolean handleSessionCreationRequestFailed(@NonNull MediaRoute2Provider provider, + long requestId, int reason) { + // Check whether the failure is about creating a session + SessionCreationRequest matchingRequest = null; + for (SessionCreationRequest request : mSessionCreationRequests) { + if (request.mRequestId == requestId && TextUtils.equals( + request.mRoute.getProviderId(), provider.getUniqueId())) { + matchingRequest = request; + break; + } } - notifyRequestFailedToManager( - managerToNotifyFailure.mManager, toOriginalRequestId(requestId), reason); + if (matchingRequest == null) { + // The failure is not about creating a session. + return false; + } + + mSessionCreationRequests.remove(matchingRequest); + + // Notify the requester about the failure. + // The call should be made by either MediaRouter2 or MediaRouter2Manager. + if (matchingRequest.mRequestedManagerRecord == null) { + notifySessionCreationFailedToRouter( + matchingRequest.mRouterRecord, toOriginalRequestId(requestId)); + } else { + notifyRequestFailedToManager(matchingRequest.mRequestedManagerRecord.mManager, + toOriginalRequestId(requestId), reason); + } + return true; } private void notifySessionCreatedToRouter(@NonNull RouterRecord routerRecord, @@ -1596,6 +1596,16 @@ class MediaRouter2ServiceImpl { return managers; } + private List getManagerRecords() { + MediaRouter2ServiceImpl service = mServiceRef.get(); + if (service == null) { + return new ArrayList<>(); + } + synchronized (service.mLock) { + return new ArrayList<>(mUserRecord.mManagerRecords); + } + } + private void notifyRoutesToRouter(@NonNull IMediaRouter2 router) { List routes = new ArrayList<>(); for (MediaRoute2ProviderInfo providerInfo : mLastProviderInfos) { @@ -1789,12 +1799,16 @@ class MediaRouter2ServiceImpl { final class SessionCreationRequest { public final RouterRecord mRouterRecord; + public final ManagerRecord mRequestedManagerRecord; public final MediaRoute2Info mRoute; public final long mRequestId; + // requestedManagerRecord is not null only when the request is made by manager. SessionCreationRequest(@NonNull RouterRecord routerRecord, + @Nullable ManagerRecord requestedManagerRecord, @NonNull MediaRoute2Info route, long requestId) { mRouterRecord = routerRecord; + mRequestedManagerRecord = requestedManagerRecord; mRoute = route; mRequestId = requestId; }