Loading media/java/android/media/MediaRoute2ProviderService.java +101 −71 Original line number Diff line number Diff line Loading @@ -137,7 +137,7 @@ public abstract class MediaRoute2ProviderService extends Service { private final AtomicBoolean mStatePublishScheduled = new AtomicBoolean(false); private MediaRoute2ProviderServiceStub mStub; private IMediaRoute2ProviderServiceCallback mRemoteCallback; private MediaRoute2ProviderInfo mProviderInfo; private volatile MediaRoute2ProviderInfo mProviderInfo; @GuardedBy("mSessionLock") private ArrayMap<String, RoutingSessionInfo> mSessionInfo = new ArrayMap<>(); Loading Loading @@ -167,8 +167,8 @@ public abstract class MediaRoute2ProviderService extends Service { /** * Called when a volume setting is requested on a route of the provider * * @param requestId the id of this request * @param routeId the id of the route * @param requestId the ID of this request * @param routeId the ID of the route * @param volume the target volume * @see MediaRoute2Info.Builder#setVolume(int) */ Loading @@ -178,8 +178,8 @@ public abstract class MediaRoute2ProviderService extends Service { * Called when {@link MediaRouter2.RoutingController#setVolume(int)} is called on * a routing session of the provider * * @param requestId the id of this request * @param sessionId the id of the routing session * @param requestId the ID of this request * @param sessionId the ID of the routing session * @param volume the target volume * @see RoutingSessionInfo.Builder#setVolume(int) */ Loading @@ -188,7 +188,7 @@ public abstract class MediaRoute2ProviderService extends Service { /** * Gets information of the session with the given id. * * @param sessionId id of the session * @param sessionId the ID of the session * @return information of the session with the given id. * null if the session is released or ID is not valid. */ Loading Loading @@ -218,7 +218,7 @@ public abstract class MediaRoute2ProviderService extends Service { * If this session is created without any creation request, use {@link #REQUEST_ID_NONE} * as the request ID. * * @param requestId id of the previous request to create this session provided in * @param requestId the ID of the previous request to create this session provided in * {@link #onCreateSession(long, String, String, Bundle)}. Can be * {@link #REQUEST_ID_NONE} if this session is created without any request. * @param sessionInfo information of the new session. Loading @@ -237,20 +237,17 @@ public abstract class MediaRoute2ProviderService extends Service { return; } mSessionInfo.put(sessionInfo.getId(), sessionInfo); } if (mRemoteCallback == null) { return; } try { // TODO(b/157873487): Calling binder calls in multiple thread may cause timing issue. // Consider to change implementations to avoid the problems. // For example, post binder calls, always send all sessions at once, etc. mRemoteCallback.notifySessionCreated(requestId, sessionInfo); } catch (RemoteException ex) { Log.w(TAG, "Failed to notify session created."); } } } /** * Notifies the existing session is updated. For example, when Loading @@ -267,7 +264,6 @@ public abstract class MediaRoute2ProviderService extends Service { Log.w(TAG, "Ignoring unknown session info."); return; } } if (mRemoteCallback == null) { return; Loading @@ -278,11 +274,12 @@ public abstract class MediaRoute2ProviderService extends Service { Log.w(TAG, "Failed to notify session info changed."); } } } /** * Notifies that the session is released. * * @param sessionId id of the released session. * @param sessionId the ID of the released session. * @see #onReleaseSession(long, String) */ public final void notifySessionReleased(@NonNull String sessionId) { Loading @@ -292,7 +289,6 @@ public abstract class MediaRoute2ProviderService extends Service { RoutingSessionInfo sessionInfo; synchronized (mSessionLock) { sessionInfo = mSessionInfo.remove(sessionId); } if (sessionInfo == null) { Log.w(TAG, "Ignoring unknown session info."); Loading @@ -308,6 +304,7 @@ public abstract class MediaRoute2ProviderService extends Service { Log.w(TAG, "Failed to notify session info changed."); } } } /** * Notifies to the client that the request has failed. Loading Loading @@ -348,9 +345,9 @@ public abstract class MediaRoute2ProviderService extends Service { * If you can't create the session or want to reject the request, call * {@link #notifyRequestFailed(long, int)} with the given {@code requestId}. * * @param requestId the id of this request * @param requestId the ID of this request * @param packageName the package name of the application that selected the route * @param routeId the id of the route initially being connected * @param routeId the ID of the route initially being connected * @param sessionHints an optional bundle of app-specific arguments sent by * {@link MediaRouter2}, or null if none. The contents of this bundle * may affect the result of session creation. Loading @@ -372,8 +369,8 @@ public abstract class MediaRoute2ProviderService extends Service { * Note: Calling {@link #notifySessionReleased(String)} will <em>NOT</em> trigger * this method to be called. * * @param requestId the id of this request * @param sessionId id of the session being released. * @param requestId the ID of this request * @param sessionId the ID of the session being released. * @see #notifySessionReleased(String) * @see #getSessionInfo(String) */ Loading @@ -384,9 +381,9 @@ public abstract class MediaRoute2ProviderService extends Service { * After the route is selected, call {@link #notifySessionUpdated(RoutingSessionInfo)} * to update session info. * * @param requestId the id of this request * @param sessionId id of the session * @param routeId id of the route * @param requestId the ID of this request * @param sessionId the ID of the session * @param routeId the ID of the route */ public abstract void onSelectRoute(long requestId, @NonNull String sessionId, @NonNull String routeId); Loading @@ -396,9 +393,9 @@ public abstract class MediaRoute2ProviderService extends Service { * After the route is deselected, call {@link #notifySessionUpdated(RoutingSessionInfo)} * to update session info. * * @param requestId the id of this request * @param sessionId id of the session * @param routeId id of the route * @param requestId the ID of this request * @param sessionId the ID of the session * @param routeId the ID of the route */ public abstract void onDeselectRoute(long requestId, @NonNull String sessionId, @NonNull String routeId); Loading @@ -408,9 +405,9 @@ public abstract class MediaRoute2ProviderService extends Service { * After the transfer is finished, call {@link #notifySessionUpdated(RoutingSessionInfo)} * to update session info. * * @param requestId the id of this request * @param sessionId id of the session * @param routeId id of the route * @param requestId the ID of this request * @param sessionId the ID of the session * @param routeId the ID of the route */ public abstract void onTransferToRoute(long requestId, @NonNull String sessionId, @NonNull String routeId); Loading Loading @@ -475,13 +472,39 @@ public abstract class MediaRoute2ProviderService extends Service { final class MediaRoute2ProviderServiceStub extends IMediaRoute2ProviderService.Stub { MediaRoute2ProviderServiceStub() { } boolean checkCallerisSystem() { private boolean checkCallerIsSystem() { return Binder.getCallingUid() == Process.SYSTEM_UID; } private boolean checkSessionIdIsValid(String sessionId, String description) { if (TextUtils.isEmpty(sessionId)) { Log.w(TAG, description + ": Ignoring empty sessionId from system service."); return false; } if (getSessionInfo(sessionId) == null) { Log.w(TAG, description + ": Ignoring unknown session from system service. " + "sessionId=" + sessionId); return false; } return true; } private boolean checkRouteIdIsValid(String routeId, String description) { if (TextUtils.isEmpty(routeId)) { Log.w(TAG, description + ": Ignoring empty routeId from system service."); return false; } if (mProviderInfo == null || mProviderInfo.getRoute(routeId) == null) { Log.w(TAG, description + ": Ignoring unknown route from system service. " + "routeId=" + routeId); return false; } return true; } @Override public void setCallback(IMediaRoute2ProviderServiceCallback callback) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::setCallback, Loading @@ -490,7 +513,7 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void updateDiscoveryPreference(RouteDiscoveryPreference discoveryPreference) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } mHandler.sendMessage(obtainMessage( Loading @@ -500,7 +523,10 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void setRouteVolume(long requestId, String routeId, int volume) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (!checkRouteIdIsValid(routeId, "setRouteVolume")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetRouteVolume, Loading @@ -510,7 +536,10 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void requestCreateSession(long requestId, String packageName, String routeId, @Nullable Bundle requestCreateSession) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (!checkRouteIdIsValid(routeId, "requestCreateSession")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onCreateSession, Loading @@ -518,14 +547,13 @@ public abstract class MediaRoute2ProviderService extends Service { requestCreateSession)); } //TODO(b/157873546): Ignore requests with unknown session ID. -> For all similar commands. @Override public void selectRoute(long requestId, String sessionId, String routeId) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (TextUtils.isEmpty(sessionId)) { Log.w(TAG, "selectRoute: Ignoring empty sessionId from system service."); if (!checkSessionIdIsValid(sessionId, "selectRoute") || !checkRouteIdIsValid(routeId, "selectRoute")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelectRoute, Loading @@ -534,11 +562,11 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void deselectRoute(long requestId, String sessionId, String routeId) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (TextUtils.isEmpty(sessionId)) { Log.w(TAG, "deselectRoute: Ignoring empty sessionId from system service."); if (!checkSessionIdIsValid(sessionId, "deselectRoute") || !checkRouteIdIsValid(routeId, "deselectRoute")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onDeselectRoute, Loading @@ -547,11 +575,11 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void transferToRoute(long requestId, String sessionId, String routeId) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (TextUtils.isEmpty(sessionId)) { Log.w(TAG, "transferToRoute: Ignoring empty sessionId from system service."); if (!checkSessionIdIsValid(sessionId, "transferToRoute") || !checkRouteIdIsValid(routeId, "transferToRoute")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onTransferToRoute, Loading @@ -560,7 +588,10 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void setSessionVolume(long requestId, String sessionId, int volume) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (!checkSessionIdIsValid(sessionId, "setSessionVolume")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetSessionVolume, Loading @@ -569,11 +600,10 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void releaseSession(long requestId, String sessionId) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (TextUtils.isEmpty(sessionId)) { Log.w(TAG, "releaseSession: Ignoring empty sessionId from system service."); if (!checkSessionIdIsValid(sessionId, "releaseSession")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onReleaseSession, Loading Loading
media/java/android/media/MediaRoute2ProviderService.java +101 −71 Original line number Diff line number Diff line Loading @@ -137,7 +137,7 @@ public abstract class MediaRoute2ProviderService extends Service { private final AtomicBoolean mStatePublishScheduled = new AtomicBoolean(false); private MediaRoute2ProviderServiceStub mStub; private IMediaRoute2ProviderServiceCallback mRemoteCallback; private MediaRoute2ProviderInfo mProviderInfo; private volatile MediaRoute2ProviderInfo mProviderInfo; @GuardedBy("mSessionLock") private ArrayMap<String, RoutingSessionInfo> mSessionInfo = new ArrayMap<>(); Loading Loading @@ -167,8 +167,8 @@ public abstract class MediaRoute2ProviderService extends Service { /** * Called when a volume setting is requested on a route of the provider * * @param requestId the id of this request * @param routeId the id of the route * @param requestId the ID of this request * @param routeId the ID of the route * @param volume the target volume * @see MediaRoute2Info.Builder#setVolume(int) */ Loading @@ -178,8 +178,8 @@ public abstract class MediaRoute2ProviderService extends Service { * Called when {@link MediaRouter2.RoutingController#setVolume(int)} is called on * a routing session of the provider * * @param requestId the id of this request * @param sessionId the id of the routing session * @param requestId the ID of this request * @param sessionId the ID of the routing session * @param volume the target volume * @see RoutingSessionInfo.Builder#setVolume(int) */ Loading @@ -188,7 +188,7 @@ public abstract class MediaRoute2ProviderService extends Service { /** * Gets information of the session with the given id. * * @param sessionId id of the session * @param sessionId the ID of the session * @return information of the session with the given id. * null if the session is released or ID is not valid. */ Loading Loading @@ -218,7 +218,7 @@ public abstract class MediaRoute2ProviderService extends Service { * If this session is created without any creation request, use {@link #REQUEST_ID_NONE} * as the request ID. * * @param requestId id of the previous request to create this session provided in * @param requestId the ID of the previous request to create this session provided in * {@link #onCreateSession(long, String, String, Bundle)}. Can be * {@link #REQUEST_ID_NONE} if this session is created without any request. * @param sessionInfo information of the new session. Loading @@ -237,20 +237,17 @@ public abstract class MediaRoute2ProviderService extends Service { return; } mSessionInfo.put(sessionInfo.getId(), sessionInfo); } if (mRemoteCallback == null) { return; } try { // TODO(b/157873487): Calling binder calls in multiple thread may cause timing issue. // Consider to change implementations to avoid the problems. // For example, post binder calls, always send all sessions at once, etc. mRemoteCallback.notifySessionCreated(requestId, sessionInfo); } catch (RemoteException ex) { Log.w(TAG, "Failed to notify session created."); } } } /** * Notifies the existing session is updated. For example, when Loading @@ -267,7 +264,6 @@ public abstract class MediaRoute2ProviderService extends Service { Log.w(TAG, "Ignoring unknown session info."); return; } } if (mRemoteCallback == null) { return; Loading @@ -278,11 +274,12 @@ public abstract class MediaRoute2ProviderService extends Service { Log.w(TAG, "Failed to notify session info changed."); } } } /** * Notifies that the session is released. * * @param sessionId id of the released session. * @param sessionId the ID of the released session. * @see #onReleaseSession(long, String) */ public final void notifySessionReleased(@NonNull String sessionId) { Loading @@ -292,7 +289,6 @@ public abstract class MediaRoute2ProviderService extends Service { RoutingSessionInfo sessionInfo; synchronized (mSessionLock) { sessionInfo = mSessionInfo.remove(sessionId); } if (sessionInfo == null) { Log.w(TAG, "Ignoring unknown session info."); Loading @@ -308,6 +304,7 @@ public abstract class MediaRoute2ProviderService extends Service { Log.w(TAG, "Failed to notify session info changed."); } } } /** * Notifies to the client that the request has failed. Loading Loading @@ -348,9 +345,9 @@ public abstract class MediaRoute2ProviderService extends Service { * If you can't create the session or want to reject the request, call * {@link #notifyRequestFailed(long, int)} with the given {@code requestId}. * * @param requestId the id of this request * @param requestId the ID of this request * @param packageName the package name of the application that selected the route * @param routeId the id of the route initially being connected * @param routeId the ID of the route initially being connected * @param sessionHints an optional bundle of app-specific arguments sent by * {@link MediaRouter2}, or null if none. The contents of this bundle * may affect the result of session creation. Loading @@ -372,8 +369,8 @@ public abstract class MediaRoute2ProviderService extends Service { * Note: Calling {@link #notifySessionReleased(String)} will <em>NOT</em> trigger * this method to be called. * * @param requestId the id of this request * @param sessionId id of the session being released. * @param requestId the ID of this request * @param sessionId the ID of the session being released. * @see #notifySessionReleased(String) * @see #getSessionInfo(String) */ Loading @@ -384,9 +381,9 @@ public abstract class MediaRoute2ProviderService extends Service { * After the route is selected, call {@link #notifySessionUpdated(RoutingSessionInfo)} * to update session info. * * @param requestId the id of this request * @param sessionId id of the session * @param routeId id of the route * @param requestId the ID of this request * @param sessionId the ID of the session * @param routeId the ID of the route */ public abstract void onSelectRoute(long requestId, @NonNull String sessionId, @NonNull String routeId); Loading @@ -396,9 +393,9 @@ public abstract class MediaRoute2ProviderService extends Service { * After the route is deselected, call {@link #notifySessionUpdated(RoutingSessionInfo)} * to update session info. * * @param requestId the id of this request * @param sessionId id of the session * @param routeId id of the route * @param requestId the ID of this request * @param sessionId the ID of the session * @param routeId the ID of the route */ public abstract void onDeselectRoute(long requestId, @NonNull String sessionId, @NonNull String routeId); Loading @@ -408,9 +405,9 @@ public abstract class MediaRoute2ProviderService extends Service { * After the transfer is finished, call {@link #notifySessionUpdated(RoutingSessionInfo)} * to update session info. * * @param requestId the id of this request * @param sessionId id of the session * @param routeId id of the route * @param requestId the ID of this request * @param sessionId the ID of the session * @param routeId the ID of the route */ public abstract void onTransferToRoute(long requestId, @NonNull String sessionId, @NonNull String routeId); Loading Loading @@ -475,13 +472,39 @@ public abstract class MediaRoute2ProviderService extends Service { final class MediaRoute2ProviderServiceStub extends IMediaRoute2ProviderService.Stub { MediaRoute2ProviderServiceStub() { } boolean checkCallerisSystem() { private boolean checkCallerIsSystem() { return Binder.getCallingUid() == Process.SYSTEM_UID; } private boolean checkSessionIdIsValid(String sessionId, String description) { if (TextUtils.isEmpty(sessionId)) { Log.w(TAG, description + ": Ignoring empty sessionId from system service."); return false; } if (getSessionInfo(sessionId) == null) { Log.w(TAG, description + ": Ignoring unknown session from system service. " + "sessionId=" + sessionId); return false; } return true; } private boolean checkRouteIdIsValid(String routeId, String description) { if (TextUtils.isEmpty(routeId)) { Log.w(TAG, description + ": Ignoring empty routeId from system service."); return false; } if (mProviderInfo == null || mProviderInfo.getRoute(routeId) == null) { Log.w(TAG, description + ": Ignoring unknown route from system service. " + "routeId=" + routeId); return false; } return true; } @Override public void setCallback(IMediaRoute2ProviderServiceCallback callback) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::setCallback, Loading @@ -490,7 +513,7 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void updateDiscoveryPreference(RouteDiscoveryPreference discoveryPreference) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } mHandler.sendMessage(obtainMessage( Loading @@ -500,7 +523,10 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void setRouteVolume(long requestId, String routeId, int volume) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (!checkRouteIdIsValid(routeId, "setRouteVolume")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetRouteVolume, Loading @@ -510,7 +536,10 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void requestCreateSession(long requestId, String packageName, String routeId, @Nullable Bundle requestCreateSession) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (!checkRouteIdIsValid(routeId, "requestCreateSession")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onCreateSession, Loading @@ -518,14 +547,13 @@ public abstract class MediaRoute2ProviderService extends Service { requestCreateSession)); } //TODO(b/157873546): Ignore requests with unknown session ID. -> For all similar commands. @Override public void selectRoute(long requestId, String sessionId, String routeId) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (TextUtils.isEmpty(sessionId)) { Log.w(TAG, "selectRoute: Ignoring empty sessionId from system service."); if (!checkSessionIdIsValid(sessionId, "selectRoute") || !checkRouteIdIsValid(routeId, "selectRoute")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelectRoute, Loading @@ -534,11 +562,11 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void deselectRoute(long requestId, String sessionId, String routeId) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (TextUtils.isEmpty(sessionId)) { Log.w(TAG, "deselectRoute: Ignoring empty sessionId from system service."); if (!checkSessionIdIsValid(sessionId, "deselectRoute") || !checkRouteIdIsValid(routeId, "deselectRoute")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onDeselectRoute, Loading @@ -547,11 +575,11 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void transferToRoute(long requestId, String sessionId, String routeId) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (TextUtils.isEmpty(sessionId)) { Log.w(TAG, "transferToRoute: Ignoring empty sessionId from system service."); if (!checkSessionIdIsValid(sessionId, "transferToRoute") || !checkRouteIdIsValid(routeId, "transferToRoute")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onTransferToRoute, Loading @@ -560,7 +588,10 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void setSessionVolume(long requestId, String sessionId, int volume) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (!checkSessionIdIsValid(sessionId, "setSessionVolume")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetSessionVolume, Loading @@ -569,11 +600,10 @@ public abstract class MediaRoute2ProviderService extends Service { @Override public void releaseSession(long requestId, String sessionId) { if (!checkCallerisSystem()) { if (!checkCallerIsSystem()) { return; } if (TextUtils.isEmpty(sessionId)) { Log.w(TAG, "releaseSession: Ignoring empty sessionId from system service."); if (!checkSessionIdIsValid(sessionId, "releaseSession")) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onReleaseSession, Loading