From f064dcae8e9ba64939824a1c996af4a82040667c Mon Sep 17 00:00:00 2001 From: Kyunglyul Hyun Date: Fri, 6 Mar 2020 22:59:14 +0900 Subject: [PATCH] Call MediaRouter2Manager#onTransferred Call MediaRouter2Manager#onTransferred to notify whether transfer is succeeded or failed. Bug: 151396145 Test: atest mediaroutertest Change-Id: I4331c80d03c61b5a722a8be404c979d3fcfa23f1 --- .../android/media/IMediaRouter2Manager.aidl | 4 +- .../android/media/MediaRouter2Manager.java | 140 +++++++++++++----- .../MediaRouter2ManagerTest.java | 24 +-- .../server/media/MediaRouter2ServiceImpl.java | 21 +-- 4 files changed, 134 insertions(+), 55 deletions(-) diff --git a/media/java/android/media/IMediaRouter2Manager.aidl b/media/java/android/media/IMediaRouter2Manager.aidl index a2f9ee906c032..5925d380115c0 100644 --- a/media/java/android/media/IMediaRouter2Manager.aidl +++ b/media/java/android/media/IMediaRouter2Manager.aidl @@ -24,8 +24,8 @@ import android.media.RoutingSessionInfo; * {@hide} */ oneway interface IMediaRouter2Manager { - void notifySessionCreated(in RoutingSessionInfo sessionInfo); - void notifySessionsUpdated(); + void notifySessionCreated(int requestId, in RoutingSessionInfo sessionInfo); + void notifySessionUpdated(in RoutingSessionInfo sessionInfo); void notifyPreferredFeaturesChanged(String packageName, in List preferredFeatures); void notifyRoutesAdded(in List routes); void notifyRoutesRemoved(in List routes); diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java index 88bcd6aaad951..b694fd059bfaf 100644 --- a/media/java/android/media/MediaRouter2Manager.java +++ b/media/java/android/media/MediaRouter2Manager.java @@ -75,6 +75,8 @@ public final class MediaRouter2Manager { final ConcurrentMap> mPreferredFeaturesMap = new ConcurrentHashMap<>(); private final AtomicInteger mNextRequestId = new AtomicInteger(1); + private final CopyOnWriteArrayList mTransferRequests = + new CopyOnWriteArrayList<>(); /** * Gets an instance of media router manager that controls media route of other applications. @@ -328,6 +330,9 @@ public final class MediaRouter2Manager { if (client != null) { try { int requestId = mNextRequestId.getAndIncrement(); + //TODO: Ensure that every request is eventually removed. + mTransferRequests.add(new TransferRequest(requestId, sessionInfo, route)); + mMediaRouterService.requestCreateSessionWithManager( client, requestId, sessionInfo.getClientPackageName(), route); } catch (RemoteException ex) { @@ -446,6 +451,77 @@ public final class MediaRouter2Manager { } } + void createSessionOnHandler(int requestId, RoutingSessionInfo sessionInfo) { + TransferRequest matchingRequest = null; + for (TransferRequest request : mTransferRequests) { + if (request.mRequestId == requestId) { + matchingRequest = request; + break; + } + } + + if (matchingRequest == null) { + return; + } + + mTransferRequests.remove(matchingRequest); + + MediaRoute2Info requestedRoute = matchingRequest.mTargetRoute; + + if (sessionInfo == null) { + notifyTransferFailed(matchingRequest.mOldSessionInfo, requestedRoute); + return; + } else if (!sessionInfo.getSelectedRoutes().contains(requestedRoute.getId())) { + Log.w(TAG, "The session does not contain the requested route. " + + "(requestedRouteId=" + requestedRoute.getId() + + ", actualRoutes=" + sessionInfo.getSelectedRoutes() + + ")"); + notifyTransferFailed(matchingRequest.mOldSessionInfo, requestedRoute); + return; + } else if (!TextUtils.equals(requestedRoute.getProviderId(), + sessionInfo.getProviderId())) { + Log.w(TAG, "The session's provider ID does not match the requested route's. " + + "(requested route's providerId=" + requestedRoute.getProviderId() + + ", actual providerId=" + sessionInfo.getProviderId() + + ")"); + notifyTransferFailed(matchingRequest.mOldSessionInfo, requestedRoute); + return; + } + notifyTransferred(matchingRequest.mOldSessionInfo, sessionInfo); + } + + void handleFailureOnHandler(int requestId, int reason) { + TransferRequest matchingRequest = null; + for (TransferRequest request : mTransferRequests) { + if (request.mRequestId == requestId) { + matchingRequest = request; + break; + } + } + + if (matchingRequest != null) { + mTransferRequests.remove(matchingRequest); + notifyTransferFailed(matchingRequest.mOldSessionInfo, matchingRequest.mTargetRoute); + return; + } + notifyRequestFailed(reason); + } + + void handleSessionsUpdated(RoutingSessionInfo sessionInfo) { + for (TransferRequest request : mTransferRequests) { + String sessionId = request.mOldSessionInfo.getId(); + if (!TextUtils.equals(sessionId, sessionInfo.getId())) { + continue; + } + if (sessionInfo.getSelectedRoutes().contains(request.mTargetRoute.getId())) { + notifyTransferred(request.mOldSessionInfo, sessionInfo); + mTransferRequests.remove(request); + break; + } + } + notifySessionUpdated(sessionInfo); + } + private void notifyRoutesAdded(List routes) { for (CallbackRecord record: mCallbackRecords) { record.mExecutor.execute( @@ -467,16 +543,9 @@ public final class MediaRouter2Manager { } } - void notifySessionCreated(RoutingSessionInfo sessionInfo) { + void notifySessionUpdated(RoutingSessionInfo sessionInfo) { for (CallbackRecord record : mCallbackRecords) { - record.mExecutor.execute(() -> record.mCallback.onSessionCreated( - new RoutingController(sessionInfo))); - } - } - - void notifySessionInfosChanged() { - for (CallbackRecord record : mCallbackRecords) { - record.mExecutor.execute(() -> record.mCallback.onSessionsUpdated()); + record.mExecutor.execute(() -> record.mCallback.onSessionUpdated(sessionInfo)); } } @@ -569,7 +638,7 @@ public final class MediaRouter2Manager { * * @see #getSelectedRoutes(RoutingSessionInfo) * @see #getSelectableRoutes(RoutingSessionInfo) - * @see Callback#onSessionsUpdated() + * @see Callback#onSessionUpdated(RoutingSessionInfo) */ public void selectRoute(@NonNull RoutingSessionInfo sessionInfo, @NonNull MediaRoute2Info route) { @@ -614,7 +683,7 @@ public final class MediaRouter2Manager { * * @see #getSelectedRoutes(RoutingSessionInfo) * @see #getDeselectableRoutes(RoutingSessionInfo) - * @see Callback#onSessionsUpdated() + * @see Callback#onSessionUpdated(RoutingSessionInfo) */ public void deselectRoute(@NonNull RoutingSessionInfo sessionInfo, @NonNull MediaRoute2Info route) { @@ -667,13 +736,15 @@ public final class MediaRouter2Manager { return; } + int requestId = mNextRequestId.getAndIncrement(); + mTransferRequests.add(new TransferRequest(requestId, sessionInfo, route)); + Client client; synchronized (sLock) { client = mClient; } if (client != null) { try { - int requestId = mNextRequestId.getAndIncrement(); mMediaRouterService.transferToRouteWithManager( mClient, requestId, sessionInfo.getId(), route); } catch (RemoteException ex) { @@ -884,19 +955,11 @@ public final class MediaRouter2Manager { public void onRoutesChanged(@NonNull List routes) {} /** - * Called when a routing session is created. - * - * @param controller the controller to control the created session + * Called when a session is changed. + * @param sessionInfo the updated session */ - public void onSessionCreated(@NonNull RoutingController controller) {} + public void onSessionUpdated(@NonNull RoutingSessionInfo sessionInfo) {} - /** - * Called when at least one session info is changed. - * Call {@link #getActiveSessions()} to get current active session info. - */ - public void onSessionsUpdated() {} - - //TODO: Call this. /** * Called when media is transferred. * @@ -906,7 +969,6 @@ public final class MediaRouter2Manager { public void onTransferred(@NonNull RoutingSessionInfo oldSession, @Nullable RoutingSessionInfo newSession) { } - //TODO: Call this. /** * Called when {@link #transfer(RoutingSessionInfo, MediaRoute2Info)} fails. */ @@ -971,25 +1033,37 @@ public final class MediaRouter2Manager { } } + static final class TransferRequest { + public final int mRequestId; + public final RoutingSessionInfo mOldSessionInfo; + public final MediaRoute2Info mTargetRoute; + + TransferRequest(int requestId, @NonNull RoutingSessionInfo oldSessionInfo, + @NonNull MediaRoute2Info targetRoute) { + mRequestId = requestId; + mOldSessionInfo = oldSessionInfo; + mTargetRoute = targetRoute; + } + } + class Client extends IMediaRouter2Manager.Stub { @Override - public void notifySessionCreated(RoutingSessionInfo sessionInfo) { - mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifySessionCreated, - MediaRouter2Manager.this, sessionInfo)); + public void notifySessionCreated(int requestId, RoutingSessionInfo sessionInfo) { + mHandler.sendMessage(obtainMessage(MediaRouter2Manager::createSessionOnHandler, + MediaRouter2Manager.this, requestId, sessionInfo)); } @Override - public void notifySessionsUpdated() { - mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifySessionInfosChanged, - MediaRouter2Manager.this)); - // do nothing + public void notifySessionUpdated(RoutingSessionInfo sessionInfo) { + mHandler.sendMessage(obtainMessage(MediaRouter2Manager::handleSessionsUpdated, + MediaRouter2Manager.this, sessionInfo)); } @Override public void notifyRequestFailed(int requestId, int reason) { // Note: requestId is not used. - mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyRequestFailed, - MediaRouter2Manager.this, reason)); + mHandler.sendMessage(obtainMessage(MediaRouter2Manager::handleFailureOnHandler, + MediaRouter2Manager.this, requestId, reason)); } @Override diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java index 77e8f97192941..6ca564fb34cc3 100644 --- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java +++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java @@ -231,9 +231,10 @@ public class MediaRouter2ManagerTest { addRouterCallback(new RouteCallback() {}); addManagerCallback(new MediaRouter2Manager.Callback() { @Override - public void onSessionCreated(MediaRouter2Manager.RoutingController controller) { - if (TextUtils.equals(mPackageName, controller.getClientPackageName()) - && createRouteMap(controller.getSelectedRoutes()).containsKey(ROUTE_ID1)) { + public void onTransferred(RoutingSessionInfo oldSessionInfo, + RoutingSessionInfo newSessionInfo) { + if (TextUtils.equals(mPackageName, newSessionInfo.getClientPackageName()) + && newSessionInfo.getSelectedRoutes().contains(ROUTE_ID1)) { latch.countDown(); } } @@ -268,8 +269,9 @@ public class MediaRouter2ManagerTest { addManagerCallback(new MediaRouter2Manager.Callback() { @Override - public void onSessionCreated(MediaRouter2Manager.RoutingController controller) { - assertNotNull(controller); + public void onTransferred(RoutingSessionInfo oldSessionInfo, + RoutingSessionInfo newSessionInfo) { + assertNotNull(newSessionInfo); onSessionCreatedLatch.countDown(); } }); @@ -352,8 +354,9 @@ public class MediaRouter2ManagerTest { // create a controller addManagerCallback(new MediaRouter2Manager.Callback() { @Override - public void onSessionCreated(MediaRouter2Manager.RoutingController controller) { - assertNotNull(controller); + public void onTransferred(RoutingSessionInfo oldSessionInfo, + RoutingSessionInfo newSessionInfo) { + assertNotNull(newSessionInfo); onSessionCreatedLatch.countDown(); } }); @@ -383,13 +386,12 @@ public class MediaRouter2ManagerTest { addManagerCallback(new MediaRouter2Manager.Callback() { @Override - public void onSessionsUpdated() { - List sessions = mManager.getRoutingSessions(mPackageName); - if (sessions.size() != 2) { + public void onSessionUpdated(RoutingSessionInfo updatedSessionInfo) { + if (!TextUtils.equals(sessionInfo.getId(), updatedSessionInfo.getId())) { return; } - if (sessions.get(1).getVolume() == targetVolume) { + if (updatedSessionInfo.getVolume() == targetVolume) { volumeChangedLatch.countDown(); } } diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index 0bba1723931d2..86aa34a1d86a8 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -1403,7 +1403,8 @@ class MediaRouter2ServiceImpl { private void onSessionCreatedOnHandler(@NonNull MediaRoute2Provider provider, long uniqueRequestId, @NonNull RoutingSessionInfo sessionInfo) { - notifySessionCreatedToManagers(getManagers(), sessionInfo); + notifySessionCreatedToManagers(getManagers(), + toOriginalRequestId(uniqueRequestId), sessionInfo); if (uniqueRequestId == REQUEST_ID_NONE) { // The session is created without any matching request. @@ -1457,7 +1458,7 @@ class MediaRouter2ServiceImpl { private void onSessionInfoChangedOnHandler(@NonNull MediaRoute2Provider provider, @NonNull RoutingSessionInfo sessionInfo) { List managers = getManagers(); - notifySessionInfosChangedToManagers(managers); + notifySessionInfoChangedToManagers(managers, sessionInfo); // For system provider, notify all routers. if (provider == mSystemProvider) { @@ -1480,7 +1481,7 @@ class MediaRouter2ServiceImpl { private void onSessionReleasedOnHandler(@NonNull MediaRoute2Provider provider, @NonNull RoutingSessionInfo sessionInfo) { List managers = getManagers(); - notifySessionInfosChangedToManagers(managers); + notifySessionInfoChangedToManagers(managers, sessionInfo); RouterRecord routerRecord = mSessionToRouterMap.get(sessionInfo.getId()); if (routerRecord == null) { @@ -1558,7 +1559,8 @@ class MediaRouter2ServiceImpl { private void notifySessionCreationFailedToRouter(@NonNull RouterRecord routerRecord, int requestId) { try { - routerRecord.mRouter.notifySessionCreated(requestId, /* sessionInfo= */ null); + routerRecord.mRouter.notifySessionCreated(requestId, + /* sessionInfo= */ null); } catch (RemoteException ex) { Slog.w(TAG, "Failed to notify router of the session creation failure." + " Router probably died.", ex); @@ -1731,10 +1733,10 @@ class MediaRouter2ServiceImpl { } private void notifySessionCreatedToManagers(@NonNull List managers, - @NonNull RoutingSessionInfo sessionInfo) { + int requestId, @NonNull RoutingSessionInfo sessionInfo) { for (IMediaRouter2Manager manager : managers) { try { - manager.notifySessionCreated(sessionInfo); + manager.notifySessionCreated(requestId, sessionInfo); } catch (RemoteException ex) { Slog.w(TAG, "notifySessionCreatedToManagers: " + "failed to notify. Manager probably died.", ex); @@ -1742,11 +1744,12 @@ class MediaRouter2ServiceImpl { } } - private void notifySessionInfosChangedToManagers( - @NonNull List managers) { + private void notifySessionInfoChangedToManagers( + @NonNull List managers, + @NonNull RoutingSessionInfo sessionInfo) { for (IMediaRouter2Manager manager : managers) { try { - manager.notifySessionsUpdated(); + manager.notifySessionUpdated(sessionInfo); } catch (RemoteException ex) { Slog.w(TAG, "notifySessionInfosChangedToManagers: " + "failed to notify. Manager probably died.", ex);