MediaRouter2: Refactor internal classes

This CL introduces following changes:
 - Remove ambiguous 'client' word usages
 - Clarify AIDL file names and related classes/methods/fields
 - Reorder AIDL methods

Bug: 149642195
Test: CTS and atest mediaroutertest
Change-Id: I53656c3be52ab8deb3fbf96bf7caf9a3476d7af6
This commit is contained in:
Hyundo Moon
2020-02-16 16:19:54 +09:00
parent 0a3c802e02
commit 56337496f9
12 changed files with 584 additions and 571 deletions

View File

@@ -17,24 +17,25 @@
package android.media;
import android.content.Intent;
import android.media.IMediaRoute2ProviderClient;
import android.media.IMediaRoute2ProviderServiceCallback;
import android.media.RouteDiscoveryPreference;
import android.os.Bundle;
/**
* {@hide}
*/
oneway interface IMediaRoute2Provider {
void setClient(IMediaRoute2ProviderClient client);
oneway interface IMediaRoute2ProviderService {
// Note: When changing this file, match the order of methods below with
// MediaRoute2ProviderService#MediaRoute2ProviderServiceStub for readability.
void setCallback(IMediaRoute2ProviderServiceCallback callback);
void updateDiscoveryPreference(in RouteDiscoveryPreference discoveryPreference);
void setRouteVolume(String routeId, int volume);
void requestCreateSession(String packageName, String routeId, long requestId,
in @nullable Bundle sessionHints);
void releaseSession(String sessionId);
void updateDiscoveryPreference(in RouteDiscoveryPreference discoveryPreference);
void selectRoute(String sessionId, String routeId);
void deselectRoute(String sessionId, String routeId);
void transferToRoute(String sessionId, String routeId);
void setRouteVolume(String routeId, int volume);
void setSessionVolume(String sessionId, int volume);
void releaseSession(String sessionId);
}

View File

@@ -24,7 +24,7 @@ import android.os.Bundle;
/**
* @hide
*/
oneway interface IMediaRoute2ProviderClient {
oneway interface IMediaRoute2ProviderServiceCallback {
// TODO: Change it to updateRoutes?
void updateState(in MediaRoute2ProviderInfo providerInfo);
void notifySessionCreated(in RoutingSessionInfo sessionInfo, long requestId);

View File

@@ -23,7 +23,7 @@ import android.os.Bundle;
/**
* @hide
*/
oneway interface IMediaRouter2Client {
oneway interface IMediaRouter2 {
void notifyRestoreRoute();
void notifyRoutesAdded(in List<MediaRoute2Info> routes);
void notifyRoutesRemoved(in List<MediaRoute2Info> routes);

View File

@@ -17,7 +17,7 @@
package android.media;
import android.content.Intent;
import android.media.IMediaRouter2Client;
import android.media.IMediaRouter2;
import android.media.IMediaRouter2Manager;
import android.media.IMediaRouterClient;
import android.media.MediaRoute2Info;
@@ -44,40 +44,43 @@ interface IMediaRouterService {
void requestSetVolume(IMediaRouterClient client, String routeId, int volume);
void requestUpdateVolume(IMediaRouterClient client, String routeId, int direction);
// Methods for media router 2
// Note: When changing this file, match the order of methods below with
// MediaRouterService.java for readability.
// Methods for MediaRouter2
List<MediaRoute2Info> getSystemRoutes();
RoutingSessionInfo getSystemSessionInfo();
void registerClient2(IMediaRouter2Client client, String packageName);
void unregisterClient2(IMediaRouter2Client client);
void setRouteVolume2(IMediaRouter2Client client, in MediaRoute2Info route, int volume);
void setSessionVolume2(IMediaRouter2Client client, String sessionId, int volume);
void requestCreateSession(IMediaRouter2Client client, in MediaRoute2Info route, int requestId,
in @nullable Bundle sessionHints);
void setDiscoveryRequest2(IMediaRouter2Client client, in RouteDiscoveryPreference preference);
void selectRoute(IMediaRouter2Client client, String sessionId, in MediaRoute2Info route);
void deselectRoute(IMediaRouter2Client client, String sessionId, in MediaRoute2Info route);
void transferToRoute(IMediaRouter2Client client, String sessionId, in MediaRoute2Info route);
void releaseSession(IMediaRouter2Client client, String sessionId);
void registerRouter2(IMediaRouter2 router, String packageName);
void unregisterRouter2(IMediaRouter2 router);
void setDiscoveryRequestWithRouter2(IMediaRouter2 router,
in RouteDiscoveryPreference preference);
void setRouteVolumeWithRouter2(IMediaRouter2 router, in MediaRoute2Info route, int volume);
void requestCreateSessionWithRouter2(IMediaRouter2 router, in MediaRoute2Info route,
int requestId, in @nullable Bundle sessionHints);
void selectRouteWithRouter2(IMediaRouter2 router, String sessionId, in MediaRoute2Info route);
void deselectRouteWithRouter2(IMediaRouter2 router, String sessionId, in MediaRoute2Info route);
void transferToRouteWithRouter2(IMediaRouter2 router, String sessionId,
in MediaRoute2Info route);
void setSessionVolumeWithRouter2(IMediaRouter2 router, String sessionId, int volume);
void releaseSessionWithRouter2(IMediaRouter2 router, String sessionId);
// Methods for MediaRouter2Manager
List<RoutingSessionInfo> getActiveSessions(IMediaRouter2Manager manager);
void registerManager(IMediaRouter2Manager manager, String packageName);
void unregisterManager(IMediaRouter2Manager manager);
void setRouteVolumeWithManager(IMediaRouter2Manager manager, in MediaRoute2Info route,
int volume);
void requestCreateClientSession(IMediaRouter2Manager manager, String packageName,
in @nullable MediaRoute2Info route, int requestId);
void setRouteVolume2Manager(IMediaRouter2Manager manager,
in MediaRoute2Info route, int volume);
void setSessionVolume2Manager(IMediaRouter2Manager manager,
String sessionId, int volume);
List<RoutingSessionInfo> getActiveSessions(IMediaRouter2Manager manager);
void selectClientRoute(IMediaRouter2Manager manager,
String sessionId, in MediaRoute2Info route);
void deselectClientRoute(IMediaRouter2Manager manager,
String sessionId, in MediaRoute2Info route);
void transferToClientRoute(IMediaRouter2Manager manager,
String sessionId, in MediaRoute2Info route);
void releaseClientSession(IMediaRouter2Manager manager, String sessionId);
void requestCreateSessionWithManager(IMediaRouter2Manager manager, String packageName,
in @nullable MediaRoute2Info route, int requestId);
void selectRouteWithManager(IMediaRouter2Manager manager, String sessionId,
in MediaRoute2Info route);
void deselectRouteWithManager(IMediaRouter2Manager manager, String sessionId,
in MediaRoute2Info route);
void transferToRouteWithManager(IMediaRouter2Manager manager, String sessionId,
in MediaRoute2Info route);
void setSessionVolumeWithManager(IMediaRouter2Manager manager, String sessionId, int volume);
void releaseSessionWithManager(IMediaRouter2Manager manager, String sessionId);
}

View File

@@ -84,8 +84,8 @@ public abstract class MediaRoute2ProviderService extends Service {
private final Handler mHandler;
private final Object mSessionLock = new Object();
private final AtomicBoolean mStatePublishScheduled = new AtomicBoolean(false);
private ProviderStub mStub;
private IMediaRoute2ProviderClient mClient;
private MediaRoute2ProviderServiceStub mStub;
private IMediaRoute2ProviderServiceCallback mRemoteCallback;
private MediaRoute2ProviderInfo mProviderInfo;
@GuardedBy("mSessionLock")
@@ -107,7 +107,7 @@ public abstract class MediaRoute2ProviderService extends Service {
//TODO: Allow binding from media router service only?
if (SERVICE_INTERFACE.equals(intent.getAction())) {
if (mStub == null) {
mStub = new ProviderStub();
mStub = new MediaRoute2ProviderServiceStub();
}
return mStub;
}
@@ -185,14 +185,14 @@ public abstract class MediaRoute2ProviderService extends Service {
mSessionInfo.put(sessionInfo.getId(), sessionInfo);
}
if (mClient == null) {
if (mRemoteCallback == null) {
return;
}
try {
// TODO: 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.
mClient.notifySessionCreated(sessionInfo, requestId);
mRemoteCallback.notifySessionCreated(sessionInfo, requestId);
} catch (RemoteException ex) {
Log.w(TAG, "Failed to notify session created.");
}
@@ -206,11 +206,11 @@ public abstract class MediaRoute2ProviderService extends Service {
* @see #onCreateSession(String, String, long, Bundle)
*/
public final void notifySessionCreationFailed(long requestId) {
if (mClient == null) {
if (mRemoteCallback == null) {
return;
}
try {
mClient.notifySessionCreationFailed(requestId);
mRemoteCallback.notifySessionCreationFailed(requestId);
} catch (RemoteException ex) {
Log.w(TAG, "Failed to notify session creation failed.");
}
@@ -233,11 +233,11 @@ public abstract class MediaRoute2ProviderService extends Service {
}
}
if (mClient == null) {
if (mRemoteCallback == null) {
return;
}
try {
mClient.notifySessionUpdated(sessionInfo);
mRemoteCallback.notifySessionUpdated(sessionInfo);
} catch (RemoteException ex) {
Log.w(TAG, "Failed to notify session info changed.");
}
@@ -263,11 +263,11 @@ public abstract class MediaRoute2ProviderService extends Service {
return;
}
if (mClient == null) {
if (mRemoteCallback == null) {
return;
}
try {
mClient.notifySessionReleased(sessionInfo);
mRemoteCallback.notifySessionReleased(sessionInfo);
} catch (RemoteException ex) {
Log.w(TAG, "Failed to notify session info changed.");
}
@@ -382,8 +382,8 @@ public abstract class MediaRoute2ProviderService extends Service {
schedulePublishState();
}
void setClient(IMediaRoute2ProviderClient client) {
mClient = client;
void setCallback(IMediaRoute2ProviderServiceCallback callback) {
mRemoteCallback = callback;
schedulePublishState();
}
@@ -398,7 +398,7 @@ public abstract class MediaRoute2ProviderService extends Service {
return;
}
if (mClient == null) {
if (mRemoteCallback == null) {
return;
}
@@ -407,26 +407,45 @@ public abstract class MediaRoute2ProviderService extends Service {
sessionInfos = new ArrayList<>(mSessionInfo.values());
}
try {
mClient.updateState(mProviderInfo);
mRemoteCallback.updateState(mProviderInfo);
} catch (RemoteException ex) {
Log.w(TAG, "Failed to send onProviderInfoUpdated");
}
}
final class ProviderStub extends IMediaRoute2Provider.Stub {
ProviderStub() { }
final class MediaRoute2ProviderServiceStub extends IMediaRoute2ProviderService.Stub {
MediaRoute2ProviderServiceStub() { }
boolean checkCallerisSystem() {
return Binder.getCallingUid() == Process.SYSTEM_UID;
}
@Override
public void setClient(IMediaRoute2ProviderClient client) {
public void setCallback(IMediaRoute2ProviderServiceCallback callback) {
if (!checkCallerisSystem()) {
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::setClient,
MediaRoute2ProviderService.this, client));
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::setCallback,
MediaRoute2ProviderService.this, callback));
}
@Override
public void updateDiscoveryPreference(RouteDiscoveryPreference discoveryPreference) {
if (!checkCallerisSystem()) {
return;
}
mHandler.sendMessage(obtainMessage(
MediaRoute2ProviderService::onDiscoveryPreferenceChanged,
MediaRoute2ProviderService.this, discoveryPreference));
}
@Override
public void setRouteVolume(String routeId, int volume) {
if (!checkCallerisSystem()) {
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetRouteVolume,
MediaRoute2ProviderService.this, routeId, volume));
}
@Override
@@ -440,29 +459,6 @@ public abstract class MediaRoute2ProviderService extends Service {
requestCreateSession));
}
@Override
public void releaseSession(@NonNull String sessionId) {
if (!checkCallerisSystem()) {
return;
}
if (TextUtils.isEmpty(sessionId)) {
Log.w(TAG, "releaseSession: Ignoring empty sessionId from system service.");
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onReleaseSession,
MediaRoute2ProviderService.this, sessionId));
}
@Override
public void updateDiscoveryPreference(RouteDiscoveryPreference discoveryPreference) {
if (!checkCallerisSystem()) {
return;
}
mHandler.sendMessage(obtainMessage(
MediaRoute2ProviderService::onDiscoveryPreferenceChanged,
MediaRoute2ProviderService.this, discoveryPreference));
}
@Override
public void selectRoute(@NonNull String sessionId, String routeId) {
if (!checkCallerisSystem()) {
@@ -502,15 +498,6 @@ public abstract class MediaRoute2ProviderService extends Service {
MediaRoute2ProviderService.this, sessionId, routeId));
}
@Override
public void setRouteVolume(String routeId, int volume) {
if (!checkCallerisSystem()) {
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetRouteVolume,
MediaRoute2ProviderService.this, routeId, volume));
}
@Override
public void setSessionVolume(String sessionId, int volume) {
if (!checkCallerisSystem()) {
@@ -519,5 +506,18 @@ public abstract class MediaRoute2ProviderService extends Service {
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetSessionVolume,
MediaRoute2ProviderService.this, sessionId, volume));
}
@Override
public void releaseSession(@NonNull String sessionId) {
if (!checkCallerisSystem()) {
return;
}
if (TextUtils.isEmpty(sessionId)) {
Log.w(TAG, "releaseSession: Ignoring empty sessionId from system service.");
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onReleaseSession,
MediaRoute2ProviderService.this, sessionId));
}
}
}

View File

@@ -83,7 +83,7 @@ public class MediaRouter2 {
// TODO: Make MediaRouter2 is always connected to the MediaRouterService.
@GuardedBy("sRouterLock")
Client2 mClient;
MediaRouter2Stub mStub;
@GuardedBy("sRouterLock")
private Map<String, RoutingController> mRoutingControllers = new ArrayMap<>();
@@ -177,18 +177,18 @@ public class MediaRouter2 {
mRouteCallbackRecords.addIfAbsent(record);
synchronized (sRouterLock) {
if (mClient == null) {
Client2 client = new Client2();
if (mStub == null) {
MediaRouter2Stub stub = new MediaRouter2Stub();
try {
mMediaRouterService.registerClient2(client, mPackageName);
mClient = client;
mMediaRouterService.registerRouter2(stub, mPackageName);
mStub = stub;
} catch (RemoteException ex) {
Log.e(TAG, "registerRouteCallback: Unable to register client.", ex);
Log.e(TAG, "registerRouteCallback: Unable to register MediaRouter2.", ex);
}
}
if (mClient != null && updateDiscoveryPreferenceIfNeededLocked()) {
if (mStub != null && updateDiscoveryPreferenceIfNeededLocked()) {
try {
mMediaRouterService.setDiscoveryRequest2(mClient, mDiscoveryPreference);
mMediaRouterService.setDiscoveryRequestWithRouter2(mStub, mDiscoveryPreference);
} catch (RemoteException ex) {
Log.e(TAG, "registerRouteCallback: Unable to set discovery request.");
}
@@ -213,24 +213,26 @@ public class MediaRouter2 {
}
synchronized (sRouterLock) {
if (mClient != null) {
if (updateDiscoveryPreferenceIfNeededLocked()) {
try {
mMediaRouterService.setDiscoveryRequest2(mClient, mDiscoveryPreference);
} catch (RemoteException ex) {
Log.e(TAG, "unregisterRouteCallback: Unable to set discovery request.");
}
}
if (mRouteCallbackRecords.size() == 0) {
try {
mMediaRouterService.unregisterClient2(mClient);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to unregister media router.", ex);
}
}
mShouldUpdateRoutes = true;
mClient = null;
if (mStub == null) {
return;
}
if (updateDiscoveryPreferenceIfNeededLocked()) {
try {
mMediaRouterService.setDiscoveryRequestWithRouter2(
mStub, mDiscoveryPreference);
} catch (RemoteException ex) {
Log.e(TAG, "unregisterRouteCallback: Unable to set discovery request.");
}
}
if (mRouteCallbackRecords.size() == 0) {
try {
mMediaRouterService.unregisterRouter2(mStub);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to unregister media router.", ex);
}
}
mShouldUpdateRoutes = true;
mStub = null;
}
}
@@ -360,13 +362,14 @@ public class MediaRouter2 {
}
}
Client2 client;
MediaRouter2Stub stub;
synchronized (sRouterLock) {
client = mClient;
stub = mStub;
}
if (client != null) {
if (stub != null) {
try {
mMediaRouterService.requestCreateSession(client, route, requestId, controllerHints);
mMediaRouterService.requestCreateSessionWithRouter2(
stub, route, requestId, controllerHints);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to request to create controller.", ex);
mHandler.sendMessage(obtainMessage(MediaRouter2::createControllerOnHandler,
@@ -422,13 +425,13 @@ public class MediaRouter2 {
public void setRouteVolume(@NonNull MediaRoute2Info route, int volume) {
Objects.requireNonNull(route, "route must not be null");
Client2 client;
MediaRouter2Stub stub;
synchronized (sRouterLock) {
client = mClient;
stub = mStub;
}
if (client != null) {
if (stub != null) {
try {
mMediaRouterService.setRouteVolume2(client, route, volume);
mMediaRouterService.setRouteVolumeWithRouter2(stub, route, volume);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to send control request.", ex);
}
@@ -941,13 +944,13 @@ public class MediaRouter2 {
return;
}
Client2 client;
MediaRouter2Stub stub;
synchronized (sRouterLock) {
client = mClient;
stub = mStub;
}
if (client != null) {
if (stub != null) {
try {
mMediaRouterService.selectRoute(client, getId(), route);
mMediaRouterService.selectRouteWithRouter2(stub, getId(), route);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to select route for session.", ex);
}
@@ -988,13 +991,13 @@ public class MediaRouter2 {
return;
}
Client2 client;
MediaRouter2Stub stub;
synchronized (sRouterLock) {
client = mClient;
stub = mStub;
}
if (client != null) {
if (stub != null) {
try {
mMediaRouterService.deselectRoute(client, getId(), route);
mMediaRouterService.deselectRouteWithRouter2(stub, getId(), route);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to remove route from session.", ex);
}
@@ -1036,13 +1039,13 @@ public class MediaRouter2 {
return;
}
Client2 client;
MediaRouter2Stub stub;
synchronized (sRouterLock) {
client = mClient;
stub = mStub;
}
if (client != null) {
if (stub != null) {
try {
mMediaRouterService.transferToRoute(client, getId(), route);
mMediaRouterService.transferToRouteWithRouter2(stub, getId(), route);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to transfer to route for session.", ex);
}
@@ -1072,13 +1075,13 @@ public class MediaRouter2 {
return;
}
}
Client2 client;
MediaRouter2Stub stub;
synchronized (sRouterLock) {
client = mClient;
stub = mStub;
}
if (client != null) {
if (stub != null) {
try {
mMediaRouterService.setSessionVolume2(client, getId(), volume);
mMediaRouterService.setSessionVolumeWithRouter2(stub, getId(), volume);
} catch (RemoteException ex) {
Log.e(TAG, "setVolume: Failed to deliver request.", ex);
}
@@ -1100,20 +1103,20 @@ public class MediaRouter2 {
mIsReleased = true;
}
Client2 client;
MediaRouter2Stub stub;
boolean removed;
synchronized (sRouterLock) {
removed = mRoutingControllers.remove(getId(), this);
client = mClient;
stub = mStub;
}
if (removed) {
mHandler.post(() -> notifyControllerReleased(RoutingController.this));
}
if (client != null) {
if (stub != null) {
try {
mMediaRouterService.releaseSession(client, getId());
mMediaRouterService.releaseSessionWithRouter2(stub, getId());
} catch (RemoteException ex) {
Log.e(TAG, "Unable to notify of controller release", ex);
}
@@ -1269,7 +1272,7 @@ public class MediaRouter2 {
}
}
class Client2 extends IMediaRouter2Client.Stub {
class MediaRouter2Stub extends IMediaRouter2.Stub {
@Override
public void notifyRestoreRoute() throws RemoteException {}

View File

@@ -293,7 +293,7 @@ public class MediaRouter2Manager {
if (client != null) {
try {
int requestId = mNextRequestId.getAndIncrement();
mMediaRouterService.requestCreateClientSession(
mMediaRouterService.requestCreateSessionWithManager(
client, packageName, route, requestId);
//TODO: release the previous session?
} catch (RemoteException ex) {
@@ -337,7 +337,7 @@ public class MediaRouter2Manager {
}
if (client != null) {
try {
mMediaRouterService.setRouteVolume2Manager(client, route, volume);
mMediaRouterService.setRouteVolumeWithManager(client, route, volume);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to send control request.", ex);
}
@@ -368,7 +368,7 @@ public class MediaRouter2Manager {
}
if (client != null) {
try {
mMediaRouterService.setSessionVolume2Manager(
mMediaRouterService.setSessionVolumeWithManager(
client, sessionInfo.getId(), volume);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to send control request.", ex);
@@ -589,7 +589,7 @@ public class MediaRouter2Manager {
}
if (client != null) {
try {
mMediaRouterService.selectClientRoute(mClient, getSessionId(), route);
mMediaRouterService.selectRouteWithManager(mClient, getSessionId(), route);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to select route for session.", ex);
}
@@ -631,7 +631,7 @@ public class MediaRouter2Manager {
}
if (client != null) {
try {
mMediaRouterService.deselectClientRoute(mClient, getSessionId(), route);
mMediaRouterService.deselectRouteWithManager(mClient, getSessionId(), route);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to remove route from session.", ex);
}
@@ -674,7 +674,7 @@ public class MediaRouter2Manager {
}
if (client != null) {
try {
mMediaRouterService.transferToClientRoute(mClient, getSessionId(), route);
mMediaRouterService.transferToRouteWithManager(mClient, getSessionId(), route);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to transfer to route for session.", ex);
}
@@ -692,7 +692,7 @@ public class MediaRouter2Manager {
}
if (client != null) {
try {
mMediaRouterService.releaseClientSession(mClient, getSessionId());
mMediaRouterService.releaseSessionWithManager(mClient, getSessionId());
} catch (RemoteException ex) {
Log.e(TAG, "Unable to notify of controller release", ex);
}

View File

@@ -47,7 +47,7 @@ abstract class MediaRoute2Provider {
mUniqueId = componentName.flattenToShortString();
}
public void setCallback(MediaRoute2ProviderProxy.Callback callback) {
public void setCallback(MediaRoute2ProviderServiceProxy.Callback callback) {
mCallback = callback;
}

View File

@@ -21,8 +21,8 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.media.IMediaRoute2Provider;
import android.media.IMediaRoute2ProviderClient;
import android.media.IMediaRoute2ProviderService;
import android.media.IMediaRoute2ProviderServiceCallback;
import android.media.MediaRoute2ProviderInfo;
import android.media.MediaRoute2ProviderService;
import android.media.RouteDiscoveryPreference;
@@ -31,6 +31,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
@@ -41,11 +42,12 @@ import java.lang.ref.WeakReference;
import java.util.Objects;
/**
* Maintains a connection to a particular media route provider service.
* Maintains a connection to a particular {@link MediaRoute2ProviderService}.
*/
// TODO: Need to revisit the bind/unbind/connect/disconnect logic in this class.
final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements ServiceConnection {
private static final String TAG = "MR2ProviderProxy";
final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
implements ServiceConnection {
private static final String TAG = "MR2ProviderSvcProxy";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final Context mContext;
@@ -58,12 +60,12 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
private Connection mActiveConnection;
private boolean mConnectionReady;
MediaRoute2ProviderProxy(@NonNull Context context, @NonNull ComponentName componentName,
MediaRoute2ProviderServiceProxy(@NonNull Context context, @NonNull ComponentName componentName,
int userId) {
super(componentName);
mContext = Objects.requireNonNull(context, "Context must not be null.");
mUserId = userId;
mHandler = new Handler();
mHandler = new Handler(Looper.myLooper());
}
public void dump(PrintWriter pw, String prefix) {
@@ -79,8 +81,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
public void requestCreateSession(String packageName, String routeId, long requestId,
Bundle sessionHints) {
if (mConnectionReady) {
mActiveConnection.requestCreateSession(
packageName, routeId, requestId, sessionHints);
mActiveConnection.requestCreateSession(packageName, routeId, requestId, sessionHints);
updateBinding();
}
}
@@ -229,10 +230,10 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
if (mBound) {
disconnect();
IMediaRoute2Provider provider = IMediaRoute2Provider.Stub.asInterface(service);
if (provider != null) {
Connection connection = new Connection(provider);
IMediaRoute2ProviderService serviceBinder =
IMediaRoute2ProviderService.Stub.asInterface(service);
if (serviceBinder != null) {
Connection connection = new Connection(serviceBinder);
if (connection.register()) {
mActiveConnection = connection;
} else {
@@ -241,7 +242,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
}
}
} else {
Slog.e(TAG, this + ": Service returned invalid remote display provider binder");
Slog.e(TAG, this + ": Service returned invalid binder");
}
}
}
@@ -426,18 +427,18 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
}
private final class Connection implements DeathRecipient {
private final IMediaRoute2Provider mProvider;
private final ProviderClient mClient;
private final IMediaRoute2ProviderService mService;
private final ServiceCallbackStub mCallbackStub;
Connection(IMediaRoute2Provider provider) {
mProvider = provider;
mClient = new ProviderClient(this);
Connection(IMediaRoute2ProviderService serviceBinder) {
mService = serviceBinder;
mCallbackStub = new ServiceCallbackStub(this);
}
public boolean register() {
try {
mProvider.asBinder().linkToDeath(this, 0);
mProvider.setClient(mClient);
mService.asBinder().linkToDeath(this, 0);
mService.setCallback(mCallbackStub);
mHandler.post(() -> onConnectionReady(Connection.this));
return true;
} catch (RemoteException ex) {
@@ -447,14 +448,14 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
}
public void dispose() {
mProvider.asBinder().unlinkToDeath(this, 0);
mClient.dispose();
mService.asBinder().unlinkToDeath(this, 0);
mCallbackStub.dispose();
}
public void requestCreateSession(String packageName, String routeId, long requestId,
Bundle sessionHints) {
try {
mProvider.requestCreateSession(packageName, routeId, requestId, sessionHints);
mService.requestCreateSession(packageName, routeId, requestId, sessionHints);
} catch (RemoteException ex) {
Slog.e(TAG, "requestCreateSession: Failed to deliver request.");
}
@@ -462,7 +463,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
public void releaseSession(String sessionId) {
try {
mProvider.releaseSession(sessionId);
mService.releaseSession(sessionId);
} catch (RemoteException ex) {
Slog.e(TAG, "releaseSession: Failed to deliver request.");
}
@@ -470,7 +471,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
public void updateDiscoveryPreference(RouteDiscoveryPreference discoveryPreference) {
try {
mProvider.updateDiscoveryPreference(discoveryPreference);
mService.updateDiscoveryPreference(discoveryPreference);
} catch (RemoteException ex) {
Slog.e(TAG, "updateDiscoveryPreference: Failed to deliver request.");
}
@@ -478,7 +479,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
public void selectRoute(String sessionId, String routeId) {
try {
mProvider.selectRoute(sessionId, routeId);
mService.selectRoute(sessionId, routeId);
} catch (RemoteException ex) {
Slog.e(TAG, "selectRoute: Failed to deliver request.", ex);
}
@@ -486,7 +487,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
public void deselectRoute(String sessionId, String routeId) {
try {
mProvider.deselectRoute(sessionId, routeId);
mService.deselectRoute(sessionId, routeId);
} catch (RemoteException ex) {
Slog.e(TAG, "deselectRoute: Failed to deliver request.", ex);
}
@@ -494,7 +495,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
public void transferToRoute(String sessionId, String routeId) {
try {
mProvider.transferToRoute(sessionId, routeId);
mService.transferToRoute(sessionId, routeId);
} catch (RemoteException ex) {
Slog.e(TAG, "transferToRoute: Failed to deliver request.", ex);
}
@@ -502,7 +503,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
public void setRouteVolume(String routeId, int volume) {
try {
mProvider.setRouteVolume(routeId, volume);
mService.setRouteVolume(routeId, volume);
} catch (RemoteException ex) {
Slog.e(TAG, "setRouteVolume: Failed to deliver request.", ex);
}
@@ -510,7 +511,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
public void setSessionVolume(String sessionId, int volume) {
try {
mProvider.setSessionVolume(sessionId, volume);
mService.setSessionVolume(sessionId, volume);
} catch (RemoteException ex) {
Slog.e(TAG, "setSessionVolume: Failed to deliver request.", ex);
}
@@ -542,10 +543,11 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
}
}
private static final class ProviderClient extends IMediaRoute2ProviderClient.Stub {
private static final class ServiceCallbackStub extends
IMediaRoute2ProviderServiceCallback.Stub {
private final WeakReference<Connection> mConnectionRef;
ProviderClient(Connection connection) {
ServiceCallbackStub(Connection connection) {
mConnectionRef = new WeakReference<>(connection);
}

View File

@@ -47,7 +47,7 @@ final class MediaRoute2ProviderWatcher {
private final int mUserId;
private final PackageManager mPackageManager;
private final ArrayList<MediaRoute2ProviderProxy> mProviders = new ArrayList<>();
private final ArrayList<MediaRoute2ProviderServiceProxy> mProxies = new ArrayList<>();
private boolean mRunning;
MediaRoute2ProviderWatcher(Context context,
@@ -63,7 +63,7 @@ final class MediaRoute2ProviderWatcher {
pw.println(prefix + "Watcher");
pw.println(prefix + " mUserId=" + mUserId);
pw.println(prefix + " mRunning=" + mRunning);
pw.println(prefix + " mProviders.size()=" + mProviders.size());
pw.println(prefix + " mProxies.size()=" + mProxies.size());
}
public void start() {
@@ -94,8 +94,8 @@ final class MediaRoute2ProviderWatcher {
mHandler.removeCallbacks(mScanPackagesRunnable);
// Stop all providers.
for (int i = mProviders.size() - 1; i >= 0; i--) {
mProviders.get(i).stop();
for (int i = mProxies.size() - 1; i >= 0; i--) {
mProxies.get(i).stop();
}
}
}
@@ -115,38 +115,38 @@ final class MediaRoute2ProviderWatcher {
if (serviceInfo != null) {
int sourceIndex = findProvider(serviceInfo.packageName, serviceInfo.name);
if (sourceIndex < 0) {
MediaRoute2ProviderProxy provider =
new MediaRoute2ProviderProxy(mContext,
MediaRoute2ProviderServiceProxy proxy =
new MediaRoute2ProviderServiceProxy(mContext,
new ComponentName(serviceInfo.packageName, serviceInfo.name),
mUserId);
provider.start();
mProviders.add(targetIndex++, provider);
mCallback.onAddProvider(provider);
proxy.start();
mProxies.add(targetIndex++, proxy);
mCallback.onAddProviderService(proxy);
} else if (sourceIndex >= targetIndex) {
MediaRoute2ProviderProxy provider = mProviders.get(sourceIndex);
provider.start(); // restart the provider if needed
provider.rebindIfDisconnected();
Collections.swap(mProviders, sourceIndex, targetIndex++);
MediaRoute2ProviderServiceProxy proxy = mProxies.get(sourceIndex);
proxy.start(); // restart the proxy if needed
proxy.rebindIfDisconnected();
Collections.swap(mProxies, sourceIndex, targetIndex++);
}
}
}
// Remove providers for missing services.
if (targetIndex < mProviders.size()) {
for (int i = mProviders.size() - 1; i >= targetIndex; i--) {
MediaRoute2ProviderProxy provider = mProviders.get(i);
mCallback.onRemoveProvider(provider);
mProviders.remove(provider);
provider.stop();
if (targetIndex < mProxies.size()) {
for (int i = mProxies.size() - 1; i >= targetIndex; i--) {
MediaRoute2ProviderServiceProxy proxy = mProxies.get(i);
mCallback.onRemoveProviderService(proxy);
mProxies.remove(proxy);
proxy.stop();
}
}
}
private int findProvider(String packageName, String className) {
int count = mProviders.size();
int count = mProxies.size();
for (int i = 0; i < count; i++) {
MediaRoute2ProviderProxy provider = mProviders.get(i);
if (provider.hasComponentName(packageName, className)) {
MediaRoute2ProviderServiceProxy proxy = mProxies.get(i);
if (proxy.hasComponentName(packageName, className)) {
return i;
}
}
@@ -171,7 +171,7 @@ final class MediaRoute2ProviderWatcher {
};
public interface Callback {
void onAddProvider(MediaRoute2ProviderProxy provider);
void onRemoveProvider(MediaRoute2ProviderProxy provider);
void onAddProviderService(MediaRoute2ProviderServiceProxy proxy);
void onRemoveProviderService(MediaRoute2ProviderServiceProxy proxy);
}
}

View File

@@ -30,7 +30,7 @@ import android.media.AudioRoutesInfo;
import android.media.AudioSystem;
import android.media.IAudioRoutesObserver;
import android.media.IAudioService;
import android.media.IMediaRouter2Client;
import android.media.IMediaRouter2;
import android.media.IMediaRouter2Manager;
import android.media.IMediaRouterClient;
import android.media.IMediaRouterService;
@@ -450,50 +450,78 @@ public final class MediaRouterService extends IMediaRouterService.Stub
// Binder call
@Override
public void registerClient2(IMediaRouter2Client client, String packageName) {
public void registerRouter2(IMediaRouter2 router, String packageName) {
final int uid = Binder.getCallingUid();
if (!validatePackageName(uid, packageName)) {
throw new SecurityException("packageName must match the calling uid");
}
mService2.registerClient(client, packageName);
mService2.registerRouter2(router, packageName);
}
// Binder call
@Override
public void unregisterClient2(IMediaRouter2Client client) {
mService2.unregisterClient(client);
public void unregisterRouter2(IMediaRouter2 router) {
mService2.unregisterRouter2(router);
}
// Binder call
@Override
public void requestCreateSession(IMediaRouter2Client client, MediaRoute2Info route,
public void setDiscoveryRequestWithRouter2(IMediaRouter2 router,
RouteDiscoveryPreference request) {
mService2.setDiscoveryRequestWithRouter2(router, request);
}
// Binder call
@Override
public void setRouteVolumeWithRouter2(IMediaRouter2 router,
MediaRoute2Info route, int volume) {
mService2.setRouteVolumeWithRouter2(router, route, volume);
}
// Binder call
@Override
public void requestCreateSessionWithRouter2(IMediaRouter2 router, MediaRoute2Info route,
int requestId, Bundle sessionHints) {
mService2.requestCreateSession(client, route, requestId, sessionHints);
mService2.requestCreateSessionWithRouter2(router, route, requestId, sessionHints);
}
// Binder call
@Override
public void selectRoute(IMediaRouter2Client client, String sessionId, MediaRoute2Info route) {
mService2.selectRoute(client, sessionId, route);
}
// Binder call
@Override
public void deselectRoute(IMediaRouter2Client client, String sessionId, MediaRoute2Info route) {
mService2.deselectRoute(client, sessionId, route);
}
// Binder call
@Override
public void transferToRoute(IMediaRouter2Client client, String sessionId,
public void selectRouteWithRouter2(IMediaRouter2 router, String sessionId,
MediaRoute2Info route) {
mService2.transferToRoute(client, sessionId, route);
mService2.selectRouteWithRouter2(router, sessionId, route);
}
// Binder call
@Override
public void releaseSession(IMediaRouter2Client client, String sessionId) {
mService2.releaseSession(client, sessionId);
public void deselectRouteWithRouter2(IMediaRouter2 router, String sessionId,
MediaRoute2Info route) {
mService2.deselectRouteWithRouter2(router, sessionId, route);
}
// Binder call
@Override
public void transferToRouteWithRouter2(IMediaRouter2 router, String sessionId,
MediaRoute2Info route) {
mService2.transferToRouteWithRouter2(router, sessionId, route);
}
// Binder call
@Override
public void setSessionVolumeWithRouter2(IMediaRouter2 router, String sessionId, int volume) {
mService2.setSessionVolumeWithRouter2(router, sessionId, volume);
}
// Binder call
@Override
public void releaseSessionWithRouter2(IMediaRouter2 router, String sessionId) {
mService2.releaseSessionWithRouter2(router, sessionId);
}
// Binder call
@Override
public List<RoutingSessionInfo> getActiveSessions(IMediaRouter2Manager manager) {
return mService2.getActiveSessions(manager);
}
// Binder call
@@ -514,74 +542,50 @@ public final class MediaRouterService extends IMediaRouterService.Stub
// Binder call
@Override
public void requestCreateClientSession(IMediaRouter2Manager manager, String packageName,
public void setRouteVolumeWithManager(IMediaRouter2Manager manager,
MediaRoute2Info route, int volume) {
mService2.setRouteVolumeWithManager(manager, route, volume);
}
// Binder call
@Override
public void requestCreateSessionWithManager(IMediaRouter2Manager manager, String packageName,
MediaRoute2Info route, int requestId) {
mService2.requestCreateClientSession(manager, packageName, route, requestId);
}
// Binder call
@Override
public void setDiscoveryRequest2(IMediaRouter2Client client, RouteDiscoveryPreference request) {
mService2.setDiscoveryRequest2(client, request);
mService2.requestCreateSessionWithManager(manager, packageName, route, requestId);
}
// Binder call
@Override
public void setRouteVolume2(IMediaRouter2Client client,
MediaRoute2Info route, int volume) {
mService2.setRouteVolume2(client, route, volume);
public void selectRouteWithManager(IMediaRouter2Manager manager, String sessionId,
MediaRoute2Info route) {
mService2.selectRouteWithManager(manager, sessionId, route);
}
// Binder call
@Override
public void setSessionVolume2(IMediaRouter2Client client, String sessionId, int volume) {
mService2.setSessionVolume2(client, sessionId, volume);
public void deselectRouteWithManager(IMediaRouter2Manager manager, String sessionId,
MediaRoute2Info route) {
mService2.deselectRouteWithManager(manager, sessionId, route);
}
// Binder call
@Override
public void setRouteVolume2Manager(IMediaRouter2Manager manager,
MediaRoute2Info route, int volume) {
mService2.setRouteVolume2Manager(manager, route, volume);
public void transferToRouteWithManager(IMediaRouter2Manager manager, String sessionId,
MediaRoute2Info route) {
mService2.transferToRouteWithManager(manager, sessionId, route);
}
// Binder call
@Override
public void setSessionVolume2Manager(IMediaRouter2Manager manager,
public void setSessionVolumeWithManager(IMediaRouter2Manager manager,
String sessionId, int volume) {
mService2.setSessionVolume2Manager(manager, sessionId, volume);
mService2.setSessionVolumeWithManager(manager, sessionId, volume);
}
// Binder call
@Override
public List<RoutingSessionInfo> getActiveSessions(IMediaRouter2Manager manager) {
return mService2.getActiveSessions(manager);
}
// Binder call
@Override
public void selectClientRoute(IMediaRouter2Manager manager, String sessionId,
MediaRoute2Info route) {
mService2.selectClientRoute(manager, sessionId, route);
}
// Binder call
@Override
public void deselectClientRoute(IMediaRouter2Manager manager, String sessionId,
MediaRoute2Info route) {
mService2.deselectClientRoute(manager, sessionId, route);
}
// Binder call
@Override
public void transferToClientRoute(IMediaRouter2Manager manager, String sessionId,
MediaRoute2Info route) {
mService2.transferToClientRoute(manager, sessionId, route);
}
// Binder call
@Override
public void releaseClientSession(IMediaRouter2Manager manager, String sessionId) {
mService2.releaseClientSession(manager, sessionId);
public void releaseSessionWithManager(IMediaRouter2Manager manager, String sessionId) {
mService2.releaseSessionWithManager(manager, sessionId);
}
void restoreBluetoothA2dp() {