Loading media/java/android/media/IMediaRoute2Provider.aidl +8 −4 Original line number Diff line number Diff line Loading @@ -24,10 +24,14 @@ import android.media.IMediaRoute2ProviderClient; */ oneway interface IMediaRoute2Provider { void setClient(IMediaRoute2ProviderClient client); void requestCreateSession(String packageName, String routeId, String controlCategory, int requestId); void requestSelectRoute(String packageName, String id, int seq); void unselectRoute(String packageName, String id); void requestCreateSession(String packageName, String routeId, String controlCategory, int requestId); void releaseSession(int sessionId); void addRoute(int sessionId, String routeId); void removeRoute(int sessionId, String routeId); void transferRoute(int sessionId, String routeId); void notifyControlRequestSent(String id, in Intent request); void requestSetVolume(String id, int volume); void requestUpdateVolume(String id, int delta); Loading media/java/android/media/IMediaRoute2ProviderClient.aidl +0 −2 Original line number Diff line number Diff line Loading @@ -26,7 +26,5 @@ import android.os.Bundle; */ oneway interface IMediaRoute2ProviderClient { void updateProviderInfo(in MediaRoute2ProviderInfo info); void notifyRouteSelected(String packageName, String routeId, in @nullable Bundle controlHints, int seq); void notifySessionCreated(in @nullable RouteSessionInfo sessionInfo, int requestId); } media/java/android/media/IMediaRouterService.aidl +3 −9 Original line number Diff line number Diff line Loading @@ -55,15 +55,9 @@ interface IMediaRouterService { void registerManager(IMediaRouter2Manager manager, String packageName); void unregisterManager(IMediaRouter2Manager manager); /** * Changes the selected route of an application. * * @param manager the manager that calls the method * @param packageName the package name of the client that will change the selected route * @param route the route to be selected */ void selectClientRoute2(IMediaRouter2Manager manager, String packageName, in @nullable MediaRoute2Info route); void requestCreateClientSession(IMediaRouter2Manager manager, String packageName, in @nullable MediaRoute2Info route, int requestId); void requestSetVolume2Manager(IMediaRouter2Manager manager, in MediaRoute2Info route, int volume); Loading media/java/android/media/MediaRoute2ProviderService.java +66 −76 Original line number Diff line number Diff line Loading @@ -22,10 +22,12 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Process; import android.os.RemoteException; import android.util.ArrayMap; import android.util.Log; Loading @@ -47,7 +49,6 @@ public abstract class MediaRoute2ProviderService extends Service { private final Handler mHandler; private final Object mSessionLock = new Object(); private ProviderStub mStub; // TODO: Rename this to mService (and accordingly IMediaRoute2ProviderClient to something else) private IMediaRoute2ProviderClient mClient; private MediaRoute2ProviderInfo mProviderInfo; Loading @@ -70,28 +71,6 @@ public abstract class MediaRoute2ProviderService extends Service { return null; } /** * Called when selectRoute is called on a route of the provider. * Once the route is ready to be used , call {@link #notifyRouteSelected(SelectToken, Bundle)} * to notify that. * * @param packageName the package name of the application that selected the route * @param routeId the id of the route being selected * @param token token that contains select info * * @see #notifyRouteSelected */ public abstract void onSelectRoute(@NonNull String packageName, @NonNull String routeId, @NonNull SelectToken token); /** * Called when unselectRoute is called on a route of the provider. * * @param packageName the package name of the application that has selected the route. * @param routeId the id of the route being unselected */ public abstract void onUnselectRoute(@NonNull String packageName, @NonNull String routeId); /** * Called when sendControlRequest is called on a route of the provider * Loading Loading @@ -155,6 +134,8 @@ public abstract class MediaRoute2ProviderService extends Service { Objects.requireNonNull(sessionInfo, "sessionInfo must not be null"); int sessionId = sessionInfo.getSessionId(); //TODO: notify updated session info synchronized (mSessionLock) { if (mSessionInfo.containsKey(sessionId)) { mSessionInfo.put(sessionId, sessionInfo); Loading @@ -162,6 +143,9 @@ public abstract class MediaRoute2ProviderService extends Service { Log.w(TAG, "Ignoring unknown session info."); } } if (sessionInfo.getSelectedRoutes().isEmpty()) { releaseSession(sessionId); } } /** Loading @@ -169,15 +153,20 @@ public abstract class MediaRoute2ProviderService extends Service { * controlled, pass a {@link Bundle} that contains how to control it. * * @param sessionInfo information of the new session. * Pass {@code null} to reject the request or inform clients that * session creation has failed. * The {@link RouteSessionInfo#getSessionId() id} of the session must be * unique. Pass {@code null} to reject the request or inform clients that * session creation is failed. * @param requestId id of the previous request to create this session */ //TODO: fail reason? public final void notifySessionCreated(@Nullable RouteSessionInfo sessionInfo, int requestId) { //TODO: validate sessionInfo.getSessionId() (it must be in "waiting list") if (sessionInfo != null) { int sessionId = sessionInfo.getSessionId(); synchronized (mSessionLock) { if (mSessionInfo.containsKey(sessionId)) { Log.w(TAG, "Ignoring duplicate session id."); return; } mSessionInfo.put(sessionInfo.getSessionId(), sessionInfo); } } Loading @@ -200,6 +189,7 @@ public abstract class MediaRoute2ProviderService extends Service { * @see #onDestroySession(int, RouteSessionInfo) */ public final void releaseSession(int sessionId) { //TODO: notify media router service of release. RouteSessionInfo sessionInfo; synchronized (mSessionLock) { sessionInfo = mSessionInfo.put(sessionId, null); Loading Loading @@ -283,29 +273,6 @@ public abstract class MediaRoute2ProviderService extends Service { publishState(); } /** * Notifies the client of that the selected route is ready for use. If the selected route can be * controlled, pass a {@link Bundle} that contains how to control it. * * @param token token passed in {@link #onSelectRoute} * @param controlHints a {@link Bundle} that contains how to control the given route. * Pass {@code null} if the route is not available. */ public final void notifyRouteSelected(@NonNull SelectToken token, @Nullable Bundle controlHints) { Objects.requireNonNull(token, "token must not be null"); if (mClient == null) { return; } try { mClient.notifyRouteSelected(token.mPackageName, token.mRouteId, controlHints, token.mSeq); } catch (RemoteException ex) { Log.w(TAG, "Failed to notify route selected"); } } void setClient(IMediaRoute2ProviderClient client) { mClient = client; publishState(); Loading @@ -323,68 +290,91 @@ public abstract class MediaRoute2ProviderService extends Service { } } /** * Route selection information. * * @see #notifyRouteSelected */ public final class SelectToken { final String mPackageName; final String mRouteId; final int mSeq; SelectToken(String packageName, String routeId, int seq) { mPackageName = packageName; mRouteId = routeId; mSeq = seq; } } final class ProviderStub extends IMediaRoute2Provider.Stub { ProviderStub() { } boolean checkCallerisSystem() { return Binder.getCallingUid() == Process.SYSTEM_UID; } @Override public void setClient(IMediaRoute2ProviderClient client) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::setClient, MediaRoute2ProviderService.this, client)); } @Override public void requestCreateSession(String packageName, String routeId, String controlCategory, int requestId) { public void requestCreateSession(String packageName, String routeId, String controlCategory, int requestId) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onCreateSession, MediaRoute2ProviderService.this, packageName, routeId, controlCategory, requestId)); } @Override public void releaseSession(int sessionId) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::releaseSession, MediaRoute2ProviderService.this, sessionId)); } @Override public void requestSelectRoute(String packageName, String routeId, int seq) { //TODO: call onCreateSession instead mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelectRoute, MediaRoute2ProviderService.this, packageName, routeId, new SelectToken(packageName, routeId, seq))); public void addRoute(int sessionId, String routeId) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onAddRoute, MediaRoute2ProviderService.this, sessionId, routeId)); } @Override public void unselectRoute(String packageName, String routeId) { mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onUnselectRoute, MediaRoute2ProviderService.this, packageName, routeId)); public void removeRoute(int sessionId, String routeId) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onRemoveRoute, MediaRoute2ProviderService.this, sessionId, routeId)); } @Override public void transferRoute(int sessionId, String routeId) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onTransferRoute, MediaRoute2ProviderService.this, sessionId, routeId)); } @Override public void notifyControlRequestSent(String routeId, Intent request) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onControlRequest, MediaRoute2ProviderService.this, routeId, request)); } @Override public void requestSetVolume(String routeId, int volume) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetVolume, MediaRoute2ProviderService.this, routeId, volume)); } @Override public void requestUpdateVolume(String routeId, int delta) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onUpdateVolume, MediaRoute2ProviderService.this, routeId, delta)); } Loading media/java/android/media/MediaRouter2Manager.java +9 −21 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.os.Handler; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.text.TextUtils; Loading @@ -40,6 +41,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; /** * @hide Loading @@ -66,6 +68,8 @@ public class MediaRouter2Manager { @NonNull final ConcurrentMap<String, List<String>> mControlCategoryMap = new ConcurrentHashMap<>(); private AtomicInteger mNextRequestId = new AtomicInteger(1); /** * Gets an instance of media router manager that controls media route of other applications. * Loading Loading @@ -204,7 +208,7 @@ public class MediaRouter2Manager { * Selects media route for the specified package name. * * @param packageName the package name of the application that should change it's media route * @param route the route to be selected * @param route the route to be selected. */ public void selectRoute(@NonNull String packageName, @NonNull MediaRoute2Info route) { Objects.requireNonNull(packageName, "packageName must not be null"); Loading @@ -216,26 +220,10 @@ public class MediaRouter2Manager { } if (client != null) { try { mMediaRouterService.selectClientRoute2(client, packageName, route); } catch (RemoteException ex) { Log.e(TAG, "Unable to select media route", ex); } } } /** * Unselects media route for the specified package name. * * @param packageName the package name of the application that should stop routing */ public void unselectRoute(@NonNull String packageName) { Client client; synchronized (sLock) { client = mClient; } if (client != null) { try { mMediaRouterService.selectClientRoute2(client, packageName, null); //TODO: make request id globally unique int requestId = Process.myPid() * 10000 + mNextRequestId.getAndIncrement(); mMediaRouterService.requestCreateClientSession( client, packageName, route, requestId); } catch (RemoteException ex) { Log.e(TAG, "Unable to select media route", ex); } Loading Loading
media/java/android/media/IMediaRoute2Provider.aidl +8 −4 Original line number Diff line number Diff line Loading @@ -24,10 +24,14 @@ import android.media.IMediaRoute2ProviderClient; */ oneway interface IMediaRoute2Provider { void setClient(IMediaRoute2ProviderClient client); void requestCreateSession(String packageName, String routeId, String controlCategory, int requestId); void requestSelectRoute(String packageName, String id, int seq); void unselectRoute(String packageName, String id); void requestCreateSession(String packageName, String routeId, String controlCategory, int requestId); void releaseSession(int sessionId); void addRoute(int sessionId, String routeId); void removeRoute(int sessionId, String routeId); void transferRoute(int sessionId, String routeId); void notifyControlRequestSent(String id, in Intent request); void requestSetVolume(String id, int volume); void requestUpdateVolume(String id, int delta); Loading
media/java/android/media/IMediaRoute2ProviderClient.aidl +0 −2 Original line number Diff line number Diff line Loading @@ -26,7 +26,5 @@ import android.os.Bundle; */ oneway interface IMediaRoute2ProviderClient { void updateProviderInfo(in MediaRoute2ProviderInfo info); void notifyRouteSelected(String packageName, String routeId, in @nullable Bundle controlHints, int seq); void notifySessionCreated(in @nullable RouteSessionInfo sessionInfo, int requestId); }
media/java/android/media/IMediaRouterService.aidl +3 −9 Original line number Diff line number Diff line Loading @@ -55,15 +55,9 @@ interface IMediaRouterService { void registerManager(IMediaRouter2Manager manager, String packageName); void unregisterManager(IMediaRouter2Manager manager); /** * Changes the selected route of an application. * * @param manager the manager that calls the method * @param packageName the package name of the client that will change the selected route * @param route the route to be selected */ void selectClientRoute2(IMediaRouter2Manager manager, String packageName, in @nullable MediaRoute2Info route); void requestCreateClientSession(IMediaRouter2Manager manager, String packageName, in @nullable MediaRoute2Info route, int requestId); void requestSetVolume2Manager(IMediaRouter2Manager manager, in MediaRoute2Info route, int volume); Loading
media/java/android/media/MediaRoute2ProviderService.java +66 −76 Original line number Diff line number Diff line Loading @@ -22,10 +22,12 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Process; import android.os.RemoteException; import android.util.ArrayMap; import android.util.Log; Loading @@ -47,7 +49,6 @@ public abstract class MediaRoute2ProviderService extends Service { private final Handler mHandler; private final Object mSessionLock = new Object(); private ProviderStub mStub; // TODO: Rename this to mService (and accordingly IMediaRoute2ProviderClient to something else) private IMediaRoute2ProviderClient mClient; private MediaRoute2ProviderInfo mProviderInfo; Loading @@ -70,28 +71,6 @@ public abstract class MediaRoute2ProviderService extends Service { return null; } /** * Called when selectRoute is called on a route of the provider. * Once the route is ready to be used , call {@link #notifyRouteSelected(SelectToken, Bundle)} * to notify that. * * @param packageName the package name of the application that selected the route * @param routeId the id of the route being selected * @param token token that contains select info * * @see #notifyRouteSelected */ public abstract void onSelectRoute(@NonNull String packageName, @NonNull String routeId, @NonNull SelectToken token); /** * Called when unselectRoute is called on a route of the provider. * * @param packageName the package name of the application that has selected the route. * @param routeId the id of the route being unselected */ public abstract void onUnselectRoute(@NonNull String packageName, @NonNull String routeId); /** * Called when sendControlRequest is called on a route of the provider * Loading Loading @@ -155,6 +134,8 @@ public abstract class MediaRoute2ProviderService extends Service { Objects.requireNonNull(sessionInfo, "sessionInfo must not be null"); int sessionId = sessionInfo.getSessionId(); //TODO: notify updated session info synchronized (mSessionLock) { if (mSessionInfo.containsKey(sessionId)) { mSessionInfo.put(sessionId, sessionInfo); Loading @@ -162,6 +143,9 @@ public abstract class MediaRoute2ProviderService extends Service { Log.w(TAG, "Ignoring unknown session info."); } } if (sessionInfo.getSelectedRoutes().isEmpty()) { releaseSession(sessionId); } } /** Loading @@ -169,15 +153,20 @@ public abstract class MediaRoute2ProviderService extends Service { * controlled, pass a {@link Bundle} that contains how to control it. * * @param sessionInfo information of the new session. * Pass {@code null} to reject the request or inform clients that * session creation has failed. * The {@link RouteSessionInfo#getSessionId() id} of the session must be * unique. Pass {@code null} to reject the request or inform clients that * session creation is failed. * @param requestId id of the previous request to create this session */ //TODO: fail reason? public final void notifySessionCreated(@Nullable RouteSessionInfo sessionInfo, int requestId) { //TODO: validate sessionInfo.getSessionId() (it must be in "waiting list") if (sessionInfo != null) { int sessionId = sessionInfo.getSessionId(); synchronized (mSessionLock) { if (mSessionInfo.containsKey(sessionId)) { Log.w(TAG, "Ignoring duplicate session id."); return; } mSessionInfo.put(sessionInfo.getSessionId(), sessionInfo); } } Loading @@ -200,6 +189,7 @@ public abstract class MediaRoute2ProviderService extends Service { * @see #onDestroySession(int, RouteSessionInfo) */ public final void releaseSession(int sessionId) { //TODO: notify media router service of release. RouteSessionInfo sessionInfo; synchronized (mSessionLock) { sessionInfo = mSessionInfo.put(sessionId, null); Loading Loading @@ -283,29 +273,6 @@ public abstract class MediaRoute2ProviderService extends Service { publishState(); } /** * Notifies the client of that the selected route is ready for use. If the selected route can be * controlled, pass a {@link Bundle} that contains how to control it. * * @param token token passed in {@link #onSelectRoute} * @param controlHints a {@link Bundle} that contains how to control the given route. * Pass {@code null} if the route is not available. */ public final void notifyRouteSelected(@NonNull SelectToken token, @Nullable Bundle controlHints) { Objects.requireNonNull(token, "token must not be null"); if (mClient == null) { return; } try { mClient.notifyRouteSelected(token.mPackageName, token.mRouteId, controlHints, token.mSeq); } catch (RemoteException ex) { Log.w(TAG, "Failed to notify route selected"); } } void setClient(IMediaRoute2ProviderClient client) { mClient = client; publishState(); Loading @@ -323,68 +290,91 @@ public abstract class MediaRoute2ProviderService extends Service { } } /** * Route selection information. * * @see #notifyRouteSelected */ public final class SelectToken { final String mPackageName; final String mRouteId; final int mSeq; SelectToken(String packageName, String routeId, int seq) { mPackageName = packageName; mRouteId = routeId; mSeq = seq; } } final class ProviderStub extends IMediaRoute2Provider.Stub { ProviderStub() { } boolean checkCallerisSystem() { return Binder.getCallingUid() == Process.SYSTEM_UID; } @Override public void setClient(IMediaRoute2ProviderClient client) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::setClient, MediaRoute2ProviderService.this, client)); } @Override public void requestCreateSession(String packageName, String routeId, String controlCategory, int requestId) { public void requestCreateSession(String packageName, String routeId, String controlCategory, int requestId) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onCreateSession, MediaRoute2ProviderService.this, packageName, routeId, controlCategory, requestId)); } @Override public void releaseSession(int sessionId) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::releaseSession, MediaRoute2ProviderService.this, sessionId)); } @Override public void requestSelectRoute(String packageName, String routeId, int seq) { //TODO: call onCreateSession instead mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelectRoute, MediaRoute2ProviderService.this, packageName, routeId, new SelectToken(packageName, routeId, seq))); public void addRoute(int sessionId, String routeId) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onAddRoute, MediaRoute2ProviderService.this, sessionId, routeId)); } @Override public void unselectRoute(String packageName, String routeId) { mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onUnselectRoute, MediaRoute2ProviderService.this, packageName, routeId)); public void removeRoute(int sessionId, String routeId) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onRemoveRoute, MediaRoute2ProviderService.this, sessionId, routeId)); } @Override public void transferRoute(int sessionId, String routeId) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onTransferRoute, MediaRoute2ProviderService.this, sessionId, routeId)); } @Override public void notifyControlRequestSent(String routeId, Intent request) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onControlRequest, MediaRoute2ProviderService.this, routeId, request)); } @Override public void requestSetVolume(String routeId, int volume) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetVolume, MediaRoute2ProviderService.this, routeId, volume)); } @Override public void requestUpdateVolume(String routeId, int delta) { if (!checkCallerisSystem()) { return; } mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onUpdateVolume, MediaRoute2ProviderService.this, routeId, delta)); } Loading
media/java/android/media/MediaRouter2Manager.java +9 −21 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.os.Handler; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.text.TextUtils; Loading @@ -40,6 +41,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; /** * @hide Loading @@ -66,6 +68,8 @@ public class MediaRouter2Manager { @NonNull final ConcurrentMap<String, List<String>> mControlCategoryMap = new ConcurrentHashMap<>(); private AtomicInteger mNextRequestId = new AtomicInteger(1); /** * Gets an instance of media router manager that controls media route of other applications. * Loading Loading @@ -204,7 +208,7 @@ public class MediaRouter2Manager { * Selects media route for the specified package name. * * @param packageName the package name of the application that should change it's media route * @param route the route to be selected * @param route the route to be selected. */ public void selectRoute(@NonNull String packageName, @NonNull MediaRoute2Info route) { Objects.requireNonNull(packageName, "packageName must not be null"); Loading @@ -216,26 +220,10 @@ public class MediaRouter2Manager { } if (client != null) { try { mMediaRouterService.selectClientRoute2(client, packageName, route); } catch (RemoteException ex) { Log.e(TAG, "Unable to select media route", ex); } } } /** * Unselects media route for the specified package name. * * @param packageName the package name of the application that should stop routing */ public void unselectRoute(@NonNull String packageName) { Client client; synchronized (sLock) { client = mClient; } if (client != null) { try { mMediaRouterService.selectClientRoute2(client, packageName, null); //TODO: make request id globally unique int requestId = Process.myPid() * 10000 + mNextRequestId.getAndIncrement(); mMediaRouterService.requestCreateClientSession( client, packageName, route, requestId); } catch (RemoteException ex) { Log.e(TAG, "Unable to select media route", ex); } Loading