Add MediaRoute2ProviderService#notifyRequestFailed

Bug: 146616547
Test: atest mediaroutertest and CTS
Change-Id: I2b2b95bf0fec070ab24f51bba0c58221e5495460
This commit is contained in:
Hyundo Moon
2020-02-14 11:44:45 +09:00
parent 81a661fb49
commit 0fa60e880b
15 changed files with 476 additions and 176 deletions

View File

@@ -26873,21 +26873,27 @@ package android.media {
ctor public MediaRoute2ProviderService();
method @NonNull public final java.util.List<android.media.RoutingSessionInfo> getAllSessionInfo();
method @Nullable public final android.media.RoutingSessionInfo getSessionInfo(@NonNull String);
method public final void notifyRequestFailed(long, int);
method public final void notifyRoutes(@NonNull java.util.Collection<android.media.MediaRoute2Info>);
method public final void notifySessionCreated(@NonNull android.media.RoutingSessionInfo, long);
method public final void notifySessionCreationFailed(long);
method public final void notifySessionReleased(@NonNull String);
method public final void notifySessionUpdated(@NonNull android.media.RoutingSessionInfo);
method @CallSuper @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent);
method public abstract void onCreateSession(@NonNull String, @NonNull String, long, @Nullable android.os.Bundle);
method public abstract void onDeselectRoute(@NonNull String, @NonNull String);
method public abstract void onCreateSession(long, @NonNull String, @NonNull String, @Nullable android.os.Bundle);
method public abstract void onDeselectRoute(long, @NonNull String, @NonNull String);
method public void onDiscoveryPreferenceChanged(@NonNull android.media.RouteDiscoveryPreference);
method public abstract void onReleaseSession(@NonNull String);
method public abstract void onSelectRoute(@NonNull String, @NonNull String);
method public abstract void onSetRouteVolume(@NonNull String, int);
method public abstract void onSetSessionVolume(@NonNull String, int);
method public abstract void onTransferToRoute(@NonNull String, @NonNull String);
field public static final long REQUEST_ID_UNKNOWN = 0L; // 0x0L
method public abstract void onReleaseSession(long, @NonNull String);
method public abstract void onSelectRoute(long, @NonNull String, @NonNull String);
method public abstract void onSetRouteVolume(long, @NonNull String, int);
method public abstract void onSetSessionVolume(long, @NonNull String, int);
method public abstract void onTransferToRoute(long, @NonNull String, @NonNull String);
field public static final int REASON_INVALID_COMMAND = 4; // 0x4
field public static final int REASON_NETWORK_ERROR = 2; // 0x2
field public static final int REASON_REJECTED = 1; // 0x1
field public static final int REASON_ROUTE_NOT_AVAILABLE = 3; // 0x3
field public static final int REASON_UNKNOWN_ERROR = 0; // 0x0
field public static final long REQUEST_ID_NONE = 0L; // 0x0L
field public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService";
}

View File

@@ -29,13 +29,13 @@ oneway interface IMediaRoute2ProviderService {
// MediaRoute2ProviderService#MediaRoute2ProviderServiceStub for readability.
void setCallback(IMediaRoute2ProviderServiceCallback callback);
void updateDiscoveryPreference(in RouteDiscoveryPreference discoveryPreference);
void setRouteVolume(String routeId, int volume);
void setRouteVolume(String routeId, int volume, long requestId);
void requestCreateSession(String packageName, String routeId, long requestId,
in @nullable Bundle sessionHints);
void selectRoute(String sessionId, String routeId);
void deselectRoute(String sessionId, String routeId);
void transferToRoute(String sessionId, String routeId);
void setSessionVolume(String sessionId, int volume);
void releaseSession(String sessionId);
void selectRoute(String sessionId, String routeId, long requestId);
void deselectRoute(String sessionId, String routeId, long requestId);
void transferToRoute(String sessionId, String routeId, long requestId);
void setSessionVolume(String sessionId, int volume, long requestId);
void releaseSession(String sessionId, long requestId);
}

View File

@@ -31,4 +31,5 @@ oneway interface IMediaRoute2ProviderServiceCallback {
void notifySessionCreationFailed(long requestId);
void notifySessionUpdated(in RoutingSessionInfo sessionInfo);
void notifySessionReleased(in RoutingSessionInfo sessionInfo);
void notifyRequestFailed(long requestId, int reason);
}

View File

@@ -30,4 +30,5 @@ oneway interface IMediaRouter2Manager {
void notifyRoutesAdded(in List<MediaRoute2Info> routes);
void notifyRoutesRemoved(in List<MediaRoute2Info> routes);
void notifyRoutesChanged(in List<MediaRoute2Info> routes);
void notifyRequestFailed(int requestId, int reason);
}

View File

@@ -71,16 +71,17 @@ interface IMediaRouterService {
void registerManager(IMediaRouter2Manager manager, String packageName);
void unregisterManager(IMediaRouter2Manager manager);
void setRouteVolumeWithManager(IMediaRouter2Manager manager, in MediaRoute2Info route,
int volume);
int volume, int requestId);
void requestCreateSessionWithManager(IMediaRouter2Manager manager, String packageName,
in @nullable MediaRoute2Info route, int requestId);
void selectRouteWithManager(IMediaRouter2Manager manager, String sessionId,
in MediaRoute2Info route);
in MediaRoute2Info route, int requestId);
void deselectRouteWithManager(IMediaRouter2Manager manager, String sessionId,
in MediaRoute2Info route);
in MediaRoute2Info route, int requestId);
void transferToRouteWithManager(IMediaRouter2Manager manager, String sessionId,
in MediaRoute2Info route);
void setSessionVolumeWithManager(IMediaRouter2Manager manager, String sessionId, int volume);
void releaseSessionWithManager(IMediaRouter2Manager manager, String sessionId);
in MediaRoute2Info route, int requestId);
void setSessionVolumeWithManager(IMediaRouter2Manager manager, String sessionId, int volume,
int requestId);
void releaseSessionWithManager(IMediaRouter2Manager manager, String sessionId, int requestId);
}

View File

@@ -19,6 +19,7 @@ package android.media;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import android.annotation.CallSuper;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
@@ -37,6 +38,8 @@ import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -51,7 +54,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
* Media apps which use {@link MediaRouter2} can request to play their media on the routes.
* </p><p>
* When {@link MediaRouter2 media router} wants to play media on a route,
* {@link #onCreateSession(String, String, long, Bundle)} will be called to handle the request.
* {@link #onCreateSession(long, String, String, Bundle)} will be called to handle the request.
* A session can be considered as a group of currently selected routes for each connection.
* Create and manage the sessions by yourself, and notify the {@link RoutingSessionInfo
* session infos} when there are any changes.
@@ -61,6 +64,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
* a {@link MediaRouter2 media router} by an application. See
* {@link #onDiscoveryPreferenceChanged(RouteDiscoveryPreference)} for the details.
* </p>
* Use {@link #notifyRequestFailed(long, int)} to notify the failure with previously received
* request ID.
*/
public abstract class MediaRoute2ProviderService extends Service {
private static final String TAG = "MR2ProviderService";
@@ -79,7 +84,53 @@ public abstract class MediaRoute2ProviderService extends Service {
*
* @see #notifySessionCreated(RoutingSessionInfo, long)
*/
public static final long REQUEST_ID_UNKNOWN = 0;
public static final long REQUEST_ID_NONE = 0;
/**
* The request has failed due to unknown reason.
*
* @see #notifyRequestFailed(long, int)
*/
public static final int REASON_UNKNOWN_ERROR = 0;
/**
* The request has failed since this service rejected the request.
*
* @see #notifyRequestFailed(long, int)
*/
public static final int REASON_REJECTED = 1;
/**
* The request has failed due to a network error.
*
* @see #notifyRequestFailed(long, int)
*/
public static final int REASON_NETWORK_ERROR = 2;
/**
* The request has failed since the requested route is no longer available.
*
* @see #notifyRequestFailed(long, int)
*/
public static final int REASON_ROUTE_NOT_AVAILABLE = 3;
/**
* The request has failed since the request is not valid. For example, selecting a route
* which is not selectable.
*
* @see #notifyRequestFailed(long, int)
*/
public static final int REASON_INVALID_COMMAND = 4;
/**
* @hide
*/
@IntDef(prefix = "REASON_", value = {
REASON_UNKNOWN_ERROR, REASON_REJECTED, REASON_NETWORK_ERROR, REASON_ROUTE_NOT_AVAILABLE,
REASON_INVALID_COMMAND
})
@Retention(RetentionPolicy.SOURCE)
public @interface Reason {}
private final Handler mHandler;
private final Object mSessionLock = new Object();
@@ -116,20 +167,23 @@ 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 volume the target volume
* @see MediaRoute2Info#getVolumeMax()
* @see MediaRoute2Info.Builder#setVolume(int)
*/
public abstract void onSetRouteVolume(@NonNull String routeId, int volume);
public abstract void onSetRouteVolume(long requestId, @NonNull String routeId, int volume);
/**
* 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 volume the target volume
* @see RoutingSessionInfo.Builder#setVolume(int)
*/
public abstract void onSetSessionVolume(@NonNull String sessionId, int volume);
public abstract void onSetSessionVolume(long requestId, @NonNull String sessionId, int volume);
/**
* Gets information of the session with the given id.
@@ -161,14 +215,15 @@ public abstract class MediaRoute2ProviderService extends Service {
/**
* Notifies clients of that the session is created and ready for use.
* <p>
* If this session is created without any creation request, use {@link #REQUEST_ID_UNKNOWN}
* If this session is created without any creation request, use {@link #REQUEST_ID_NONE}
* as the request ID.
*
* @param sessionInfo information of the new session.
* The {@link RoutingSessionInfo#getId() id} of the session must be unique.
* @param requestId id of the previous request to create this session provided in
* {@link #onCreateSession(String, String, long, Bundle)}
* @see #onCreateSession(String, String, long, Bundle)
* {@link #onCreateSession(long, String, String, Bundle)}. Can be
* {@link #REQUEST_ID_NONE} if this session is created without any request.
* @see #onCreateSession(long, String, String, Bundle)
* @see #getSessionInfo(String)
*/
public final void notifySessionCreated(@NonNull RoutingSessionInfo sessionInfo,
@@ -201,8 +256,8 @@ public abstract class MediaRoute2ProviderService extends Service {
* Notifies clients of that the session could not be created.
*
* @param requestId id of the previous request to create the session provided in
* {@link #onCreateSession(String, String, long, Bundle)}.
* @see #onCreateSession(String, String, long, Bundle)
* {@link #onCreateSession(long, String, String, Bundle)}.
* @see #onCreateSession(long, String, String, Bundle)
*/
public final void notifySessionCreationFailed(long requestId) {
if (mRemoteCallback == null) {
@@ -246,7 +301,7 @@ public abstract class MediaRoute2ProviderService extends Service {
* Notifies that the session is released.
*
* @param sessionId id of the released session.
* @see #onReleaseSession(String)
* @see #onReleaseSession(long, String)
*/
public final void notifySessionReleased(@NonNull String sessionId) {
if (TextUtils.isEmpty(sessionId)) {
@@ -272,6 +327,29 @@ public abstract class MediaRoute2ProviderService extends Service {
}
}
/**
* Notifies to the client that the request has failed.
*
* @param requestId the ID of the previous request
* @param reason the reason why the request has failed
*
* @see #REASON_UNKNOWN_ERROR
* @see #REASON_REJECTED
* @see #REASON_NETWORK_ERROR
* @see #REASON_ROUTE_NOT_AVAILABLE
* @see #REASON_INVALID_COMMAND
*/
public final void notifyRequestFailed(long requestId, @Reason int reason) {
if (mRemoteCallback == null) {
return;
}
try {
mRemoteCallback.notifyRequestFailed(requestId, reason);
} catch (RemoteException ex) {
Log.w(TAG, "Failed to notify that the request has failed.");
}
}
/**
* Called when the service receives a request to create a session.
* <p>
@@ -288,9 +366,9 @@ public abstract class MediaRoute2ProviderService extends Service {
* If you can't create the session or want to reject the request, call
* {@link #notifySessionCreationFailed(long)} with the given {@code requestId}.
*
* @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 requestId the id of this session creation request
* @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.
@@ -299,8 +377,8 @@ public abstract class MediaRoute2ProviderService extends Service {
* @see RoutingSessionInfo.Builder#addSelectedRoute(String)
* @see RoutingSessionInfo.Builder#setControlHints(Bundle)
*/
public abstract void onCreateSession(@NonNull String packageName, @NonNull String routeId,
long requestId, @Nullable Bundle sessionHints);
public abstract void onCreateSession(long requestId, @NonNull String packageName,
@NonNull String routeId, @Nullable Bundle sessionHints);
/**
* Called when the session should be released. A client of the session or system can request
@@ -312,44 +390,48 @@ 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.
* @see #notifySessionReleased(String)
* @see #getSessionInfo(String)
*/
public abstract void onReleaseSession(@NonNull String sessionId);
public abstract void onReleaseSession(long requestId, @NonNull String sessionId);
//TODO: make a way to reject the request
/**
* Called when a client requests selecting a route for the session.
* 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
*/
public abstract void onSelectRoute(@NonNull String sessionId, @NonNull String routeId);
public abstract void onSelectRoute(long requestId, @NonNull String sessionId,
@NonNull String routeId);
//TODO: make a way to reject the request
/**
* Called when a client requests deselecting a route from the session.
* 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
*/
public abstract void onDeselectRoute(@NonNull String sessionId, @NonNull String routeId);
public abstract void onDeselectRoute(long requestId, @NonNull String sessionId,
@NonNull String routeId);
//TODO: make a way to reject the request
/**
* Called when a client requests transferring a session to a route.
* 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
*/
public abstract void onTransferToRoute(@NonNull String sessionId, @NonNull String routeId);
public abstract void onTransferToRoute(long requestId, @NonNull String sessionId,
@NonNull String routeId);
/**
* Called when the {@link RouteDiscoveryPreference discovery preference} has changed.
@@ -439,12 +521,12 @@ public abstract class MediaRoute2ProviderService extends Service {
}
@Override
public void setRouteVolume(String routeId, int volume) {
public void setRouteVolume(String routeId, int volume, long requestId) {
if (!checkCallerisSystem()) {
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetRouteVolume,
MediaRoute2ProviderService.this, routeId, volume));
MediaRoute2ProviderService.this, requestId, routeId, volume));
}
@Override
@@ -454,12 +536,12 @@ public abstract class MediaRoute2ProviderService extends Service {
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onCreateSession,
MediaRoute2ProviderService.this, packageName, routeId, requestId,
MediaRoute2ProviderService.this, requestId, packageName, routeId,
requestCreateSession));
}
@Override
public void selectRoute(@NonNull String sessionId, String routeId) {
public void selectRoute(String sessionId, String routeId, long requestId) {
if (!checkCallerisSystem()) {
return;
}
@@ -468,11 +550,11 @@ public abstract class MediaRoute2ProviderService extends Service {
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelectRoute,
MediaRoute2ProviderService.this, sessionId, routeId));
MediaRoute2ProviderService.this, requestId, sessionId, routeId));
}
@Override
public void deselectRoute(@NonNull String sessionId, String routeId) {
public void deselectRoute(String sessionId, String routeId, long requestId) {
if (!checkCallerisSystem()) {
return;
}
@@ -481,11 +563,11 @@ public abstract class MediaRoute2ProviderService extends Service {
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onDeselectRoute,
MediaRoute2ProviderService.this, sessionId, routeId));
MediaRoute2ProviderService.this, requestId, sessionId, routeId));
}
@Override
public void transferToRoute(@NonNull String sessionId, String routeId) {
public void transferToRoute(String sessionId, String routeId, long requestId) {
if (!checkCallerisSystem()) {
return;
}
@@ -494,20 +576,20 @@ public abstract class MediaRoute2ProviderService extends Service {
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onTransferToRoute,
MediaRoute2ProviderService.this, sessionId, routeId));
MediaRoute2ProviderService.this, requestId, sessionId, routeId));
}
@Override
public void setSessionVolume(String sessionId, int volume) {
public void setSessionVolume(String sessionId, int volume, long requestId) {
if (!checkCallerisSystem()) {
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetSessionVolume,
MediaRoute2ProviderService.this, sessionId, volume));
MediaRoute2ProviderService.this, requestId, sessionId, volume));
}
@Override
public void releaseSession(@NonNull String sessionId) {
public void releaseSession(String sessionId, long requestId) {
if (!checkCallerisSystem()) {
return;
}
@@ -516,7 +598,7 @@ public abstract class MediaRoute2ProviderService extends Service {
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onReleaseSession,
MediaRoute2ProviderService.this, sessionId));
MediaRoute2ProviderService.this, requestId, sessionId));
}
}
}

View File

@@ -817,7 +817,7 @@ public class MediaRouter2 {
* @return An optional bundle of app-specific arguments to send to the provider,
* or null if none. The contents of this bundle may affect the result of
* controller creation.
* @see MediaRoute2ProviderService#onCreateSession(String, String, long, Bundle)
* @see MediaRoute2ProviderService#onCreateSession(long, String, String, Bundle)
*/
@Nullable
Bundle onGetControllerHints(@NonNull MediaRoute2Info route);

View File

@@ -337,7 +337,8 @@ public class MediaRouter2Manager {
}
if (client != null) {
try {
mMediaRouterService.setRouteVolumeWithManager(client, route, volume);
int requestId = mNextRequestId.getAndIncrement();
mMediaRouterService.setRouteVolumeWithManager(client, route, volume, requestId);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to send control request.", ex);
}
@@ -368,8 +369,9 @@ public class MediaRouter2Manager {
}
if (client != null) {
try {
int requestId = mNextRequestId.getAndIncrement();
mMediaRouterService.setSessionVolumeWithManager(
client, sessionInfo.getId(), volume);
client, sessionInfo.getId(), volume, requestId);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to send control request.", ex);
}
@@ -443,6 +445,12 @@ public class MediaRouter2Manager {
}
}
void notifyRequestFailed(int reason) {
for (CallbackRecord record : mCallbackRecords) {
record.mExecutor.execute(() -> record.mCallback.onRequestFailed(reason));
}
}
void updatePreferredFeatures(String packageName, List<String> preferredFeatures) {
List<String> prevFeatures = mPreferredFeaturesMap.put(packageName, preferredFeatures);
if ((prevFeatures == null && preferredFeatures.size() == 0)
@@ -593,7 +601,9 @@ public class MediaRouter2Manager {
}
if (client != null) {
try {
mMediaRouterService.selectRouteWithManager(mClient, getSessionId(), route);
int requestId = mNextRequestId.getAndIncrement();
mMediaRouterService.selectRouteWithManager(
mClient, getSessionId(), route, requestId);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to select route for session.", ex);
}
@@ -635,7 +645,9 @@ public class MediaRouter2Manager {
}
if (client != null) {
try {
mMediaRouterService.deselectRouteWithManager(mClient, getSessionId(), route);
int requestId = mNextRequestId.getAndIncrement();
mMediaRouterService.deselectRouteWithManager(
mClient, getSessionId(), route, requestId);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to remove route from session.", ex);
}
@@ -678,7 +690,9 @@ public class MediaRouter2Manager {
}
if (client != null) {
try {
mMediaRouterService.transferToRouteWithManager(mClient, getSessionId(), route);
int requestId = mNextRequestId.getAndIncrement();
mMediaRouterService.transferToRouteWithManager(
mClient, getSessionId(), route, requestId);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to transfer to route for session.", ex);
}
@@ -696,7 +710,9 @@ public class MediaRouter2Manager {
}
if (client != null) {
try {
mMediaRouterService.releaseSessionWithManager(mClient, getSessionId());
int requestId = mNextRequestId.getAndIncrement();
mMediaRouterService.releaseSessionWithManager(
mClient, getSessionId(), requestId);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to notify of controller release", ex);
}
@@ -783,6 +799,17 @@ public class MediaRouter2Manager {
public void onPreferredFeaturesChanged(@NonNull String packageName,
@NonNull List<String> preferredFeatures) {}
/**
* Called when a previous request has failed.
*
* @param reason the reason that the request has failed. Can be one of followings:
* {@link MediaRoute2ProviderService#REASON_UNKNOWN_ERROR},
* {@link MediaRoute2ProviderService#REASON_REJECTED},
* {@link MediaRoute2ProviderService#REASON_NETWORK_ERROR},
* {@link MediaRoute2ProviderService#REASON_ROUTE_NOT_AVAILABLE},
* {@link MediaRoute2ProviderService#REASON_INVALID_COMMAND},
*/
public void onRequestFailed(int reason) {}
}
final class CallbackRecord {
@@ -825,6 +852,13 @@ public class MediaRouter2Manager {
// do nothing
}
@Override
public void notifyRequestFailed(int requestId, int reason) {
// Note: requestId is not used.
mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyRequestFailed,
MediaRouter2Manager.this, reason));
}
@Override
public void notifyPreferredFeaturesChanged(String packageName, List<String> features) {
mHandler.sendMessage(obtainMessage(MediaRouter2Manager::updatePreferredFeatures,

View File

@@ -19,6 +19,8 @@ package com.android.mediaroutertest;
import static android.media.MediaRoute2Info.FEATURE_LIVE_AUDIO;
import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_FIXED;
import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;
import static android.media.MediaRoute2ProviderService.REASON_REJECTED;
import static android.media.MediaRoute2ProviderService.REQUEST_ID_NONE;
import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.FEATURE_SAMPLE;
import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.FEATURE_SPECIAL;
@@ -32,6 +34,7 @@ import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE
import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.VOLUME_MAX;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -69,6 +72,7 @@ import java.util.function.Predicate;
@SmallTest
public class MediaRouter2ManagerTest {
private static final String TAG = "MediaRouter2ManagerTest";
private static final int WAIT_TIME_MS = 2000;
private static final int TIMEOUT_MS = 5000;
private Context mContext;
@@ -111,6 +115,11 @@ public class MediaRouter2ManagerTest {
releaseAllSessions();
// unregister callbacks
clearCallbacks();
SampleMediaRoute2ProviderService instance = SampleMediaRoute2ProviderService.getInstance();
if (instance != null) {
instance.setProxy(null);
}
}
@Test
@@ -398,6 +407,53 @@ public class MediaRouter2ManagerTest {
}
}
/**
* Tests that {@link android.media.MediaRoute2ProviderService#notifyRequestFailed(long, int)}
* should invoke the callback only when the right requestId is used.
*/
@Test
public void testOnRequestFailedCalledForProperRequestId() throws Exception {
Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
MediaRoute2Info volRoute = routes.get(ROUTE_ID_VARIABLE_VOLUME);
SampleMediaRoute2ProviderService instance = SampleMediaRoute2ProviderService.getInstance();
assertNotNull(instance);
final List<Long> requestIds = new ArrayList<>();
final CountDownLatch onSetRouteVolumeLatch = new CountDownLatch(1);
instance.setProxy(new SampleMediaRoute2ProviderService.Proxy() {
@Override
public void onSetRouteVolume(String routeId, int volume, long requestId) {
requestIds.add(requestId);
onSetRouteVolumeLatch.countDown();
}
});
addManagerCallback(new MediaRouter2Manager.Callback() {});
mManager.setRouteVolume(volRoute, 0);
assertTrue(onSetRouteVolumeLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
assertFalse(requestIds.isEmpty());
final int failureReason = REASON_REJECTED;
final CountDownLatch onRequestFailedLatch = new CountDownLatch(1);
addManagerCallback(new MediaRouter2Manager.Callback() {
@Override
public void onRequestFailed(int reason) {
if (reason == failureReason) {
onRequestFailedLatch.countDown();
}
}
});
final long invalidRequestId = REQUEST_ID_NONE;
instance.notifyRequestFailed(invalidRequestId, failureReason);
assertFalse(onRequestFailedLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
final long validRequestId = requestIds.get(0);
instance.notifyRequestFailed(validRequestId, failureReason);
assertTrue(onRequestFailedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
}
@Test
public void testVolumeHandling() throws Exception {
Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);

View File

@@ -75,6 +75,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
@GuardedBy("sLock")
private static SampleMediaRoute2ProviderService sInstance;
private Proxy mProxy;
private void initializeRoutes() {
MediaRoute2Info route1 = new MediaRoute2Info.Builder(ROUTE_ID1, ROUTE_NAME1)
@@ -179,7 +180,13 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
@Override
public void onSetRouteVolume(String routeId, int volume) {
public void onSetRouteVolume(long requestId, String routeId, int volume) {
Proxy proxy = mProxy;
if (proxy != null) {
proxy.onSetRouteVolume(routeId, volume, requestId);
return;
}
MediaRoute2Info route = mRoutes.get(routeId);
if (route == null) {
return;
@@ -192,7 +199,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
@Override
public void onSetSessionVolume(String sessionId, int volume) {
public void onSetSessionVolume(long requestId, String sessionId, int volume) {
RoutingSessionInfo sessionInfo = getSessionInfo(sessionId);
if (sessionInfo == null) {
return;
@@ -205,7 +212,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
@Override
public void onCreateSession(String packageName, String routeId, long requestId,
public void onCreateSession(long requestId, String packageName, String routeId,
@Nullable Bundle sessionHints) {
MediaRoute2Info route = mRoutes.get(routeId);
if (route == null || TextUtils.equals(ROUTE_ID3_SESSION_CREATION_FAILED, routeId)) {
@@ -238,7 +245,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
@Override
public void onReleaseSession(String sessionId) {
public void onReleaseSession(long requestId, String sessionId) {
RoutingSessionInfo sessionInfo = getSessionInfo(sessionId);
if (sessionInfo == null) {
return;
@@ -258,7 +265,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
@Override
public void onSelectRoute(String sessionId, String routeId) {
public void onSelectRoute(long requestId, String sessionId, String routeId) {
RoutingSessionInfo sessionInfo = getSessionInfo(sessionId);
MediaRoute2Info route = mRoutes.get(routeId);
if (route == null || sessionInfo == null) {
@@ -280,7 +287,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
@Override
public void onDeselectRoute(String sessionId, String routeId) {
public void onDeselectRoute(long requestId, String sessionId, String routeId) {
RoutingSessionInfo sessionInfo = getSessionInfo(sessionId);
MediaRoute2Info route = mRoutes.get(routeId);
@@ -308,7 +315,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
@Override
public void onTransferToRoute(String sessionId, String routeId) {
public void onTransferToRoute(long requestId, String sessionId, String routeId) {
RoutingSessionInfo sessionInfo = getSessionInfo(sessionId);
MediaRoute2Info route = mRoutes.get(routeId);
@@ -347,10 +354,18 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
String sessionId = mRouteIdToSessionId.get(routeId);
onDeselectRoute(sessionId, routeId);
onDeselectRoute(REQUEST_ID_NONE, sessionId, routeId);
}
void publishRoutes() {
notifyRoutes(mRoutes.values());
}
public void setProxy(@Nullable Proxy proxy) {
mProxy = proxy;
}
public static class Proxy {
public void onSetRouteVolume(String routeId, int volume, long requestId) {}
}
}

View File

@@ -53,15 +53,15 @@ abstract class MediaRoute2Provider {
public abstract void requestCreateSession(String packageName, String routeId, long requestId,
@Nullable Bundle sessionHints);
public abstract void releaseSession(String sessionId);
public abstract void releaseSession(String sessionId, long requestId);
public abstract void updateDiscoveryPreference(RouteDiscoveryPreference discoveryPreference);
public abstract void selectRoute(String sessionId, String routeId);
public abstract void deselectRoute(String sessionId, String routeId);
public abstract void transferToRoute(String sessionId, String routeId);
public abstract void selectRoute(String sessionId, String routeId, long requestId);
public abstract void deselectRoute(String sessionId, String routeId, long requestId);
public abstract void transferToRoute(String sessionId, String routeId, long requestId);
public abstract void setRouteVolume(String routeId, int volume);
public abstract void setSessionVolume(String sessionId, int volume);
public abstract void setRouteVolume(String routeId, int volume, long requestId);
public abstract void setSessionVolume(String sessionId, int volume, long requestId);
@NonNull
public String getUniqueId() {
@@ -116,5 +116,6 @@ abstract class MediaRoute2Provider {
@NonNull RoutingSessionInfo sessionInfo);
void onSessionReleased(@NonNull MediaRoute2Provider provider,
@NonNull RoutingSessionInfo sessionInfo);
void onRequestFailed(@NonNull MediaRoute2Provider provider, long requestId, int reason);
}
}

View File

@@ -87,9 +87,9 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
}
@Override
public void releaseSession(String sessionId) {
public void releaseSession(String sessionId, long requestId) {
if (mConnectionReady) {
mActiveConnection.releaseSession(sessionId);
mActiveConnection.releaseSession(sessionId, requestId);
updateBinding();
}
}
@@ -103,38 +103,38 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
}
@Override
public void selectRoute(String sessionId, String routeId) {
public void selectRoute(String sessionId, String routeId, long requestId) {
if (mConnectionReady) {
mActiveConnection.selectRoute(sessionId, routeId);
mActiveConnection.selectRoute(sessionId, routeId, requestId);
}
}
@Override
public void deselectRoute(String sessionId, String routeId) {
public void deselectRoute(String sessionId, String routeId, long requestId) {
if (mConnectionReady) {
mActiveConnection.deselectRoute(sessionId, routeId);
mActiveConnection.deselectRoute(sessionId, routeId, requestId);
}
}
@Override
public void transferToRoute(String sessionId, String routeId) {
public void transferToRoute(String sessionId, String routeId, long requestId) {
if (mConnectionReady) {
mActiveConnection.transferToRoute(sessionId, routeId);
mActiveConnection.transferToRoute(sessionId, routeId, requestId);
}
}
@Override
public void setRouteVolume(String routeId, int volume) {
public void setRouteVolume(String routeId, int volume, long requestId) {
if (mConnectionReady) {
mActiveConnection.setRouteVolume(routeId, volume);
mActiveConnection.setRouteVolume(routeId, volume, requestId);
updateBinding();
}
}
@Override
public void setSessionVolume(String sessionId, int volume) {
public void setSessionVolume(String sessionId, int volume, long requestId) {
if (mConnectionReady) {
mActiveConnection.setSessionVolume(sessionId, volume);
mActiveConnection.setSessionVolume(sessionId, volume, requestId);
updateBinding();
}
}
@@ -333,8 +333,8 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
return;
}
if (requestId == MediaRoute2ProviderService.REQUEST_ID_UNKNOWN) {
Slog.w(TAG, "onSessionCreationFailed: Ignoring requestId REQUEST_ID_UNKNOWN");
if (requestId == MediaRoute2ProviderService.REQUEST_ID_NONE) {
Slog.w(TAG, "onSessionCreationFailed: Ignoring requestId REQUEST_ID_NONE");
return;
}
@@ -406,6 +406,19 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
mCallback.onSessionReleased(this, sessionInfo);
}
private void onRequestFailed(Connection connection, long requestId, int reason) {
if (mActiveConnection != connection) {
return;
}
if (requestId == MediaRoute2ProviderService.REQUEST_ID_NONE) {
Slog.w(TAG, "onRequestFailed: Ignoring requestId REQUEST_ID_NONE");
return;
}
mCallback.onRequestFailed(this, requestId, reason);
}
private void disconnect() {
if (mActiveConnection != null) {
mConnectionReady = false;
@@ -461,9 +474,9 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
}
}
public void releaseSession(String sessionId) {
public void releaseSession(String sessionId, long requestId) {
try {
mService.releaseSession(sessionId);
mService.releaseSession(sessionId, requestId);
} catch (RemoteException ex) {
Slog.e(TAG, "releaseSession: Failed to deliver request.");
}
@@ -477,41 +490,41 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
}
}
public void selectRoute(String sessionId, String routeId) {
public void selectRoute(String sessionId, String routeId, long requestId) {
try {
mService.selectRoute(sessionId, routeId);
mService.selectRoute(sessionId, routeId, requestId);
} catch (RemoteException ex) {
Slog.e(TAG, "selectRoute: Failed to deliver request.", ex);
}
}
public void deselectRoute(String sessionId, String routeId) {
public void deselectRoute(String sessionId, String routeId, long requestId) {
try {
mService.deselectRoute(sessionId, routeId);
mService.deselectRoute(sessionId, routeId, requestId);
} catch (RemoteException ex) {
Slog.e(TAG, "deselectRoute: Failed to deliver request.", ex);
}
}
public void transferToRoute(String sessionId, String routeId) {
public void transferToRoute(String sessionId, String routeId, long requestId) {
try {
mService.transferToRoute(sessionId, routeId);
mService.transferToRoute(sessionId, routeId, requestId);
} catch (RemoteException ex) {
Slog.e(TAG, "transferToRoute: Failed to deliver request.", ex);
}
}
public void setRouteVolume(String routeId, int volume) {
public void setRouteVolume(String routeId, int volume, long requestId) {
try {
mService.setRouteVolume(routeId, volume);
mService.setRouteVolume(routeId, volume, requestId);
} catch (RemoteException ex) {
Slog.e(TAG, "setRouteVolume: Failed to deliver request.", ex);
}
}
public void setSessionVolume(String sessionId, int volume) {
public void setSessionVolume(String sessionId, int volume, long requestId) {
try {
mService.setSessionVolume(sessionId, volume);
mService.setSessionVolume(sessionId, volume, requestId);
} catch (RemoteException ex) {
Slog.e(TAG, "setSessionVolume: Failed to deliver request.", ex);
}
@@ -541,6 +554,10 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
void postSessionReleased(RoutingSessionInfo sessionInfo) {
mHandler.post(() -> onSessionReleased(Connection.this, sessionInfo));
}
void postSessionReleased(long requestId, int reason) {
mHandler.post(() -> onRequestFailed(Connection.this, requestId, reason));
}
}
private static final class ServiceCallbackStub extends
@@ -594,5 +611,13 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
connection.postSessionReleased(sessionInfo);
}
}
@Override
public void notifyRequestFailed(long requestId, int reason) {
Connection connection = mConnectionRef.get();
if (connection != null) {
connection.postSessionReleased(requestId, reason);
}
}
}
}

View File

@@ -16,6 +16,7 @@
package com.android.server.media;
import static android.media.MediaRoute2ProviderService.REQUEST_ID_NONE;
import static android.media.MediaRouter2Utils.getOriginalId;
import static android.media.MediaRouter2Utils.getProviderId;
@@ -30,7 +31,6 @@ import android.media.IMediaRouter2;
import android.media.IMediaRouter2Manager;
import android.media.MediaRoute2Info;
import android.media.MediaRoute2ProviderInfo;
import android.media.MediaRoute2ProviderService;
import android.media.RouteDiscoveryPreference;
import android.media.RoutingSessionInfo;
import android.os.Binder;
@@ -70,6 +70,12 @@ class MediaRouter2ServiceImpl {
private static final String TAG = "MR2ServiceImpl";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
/**
* TODO: Change this with the real request ID from MediaRouter2 when
* MediaRouter2 needs to get notified for the failures.
*/
private static final long DUMMY_REQUEST_ID = -1;
private final Context mContext;
private final Object mLock = new Object();
final AtomicInteger mNextRouterOrManagerId = new AtomicInteger(1);
@@ -365,14 +371,14 @@ class MediaRouter2ServiceImpl {
}
public void setRouteVolumeWithManager(IMediaRouter2Manager manager,
MediaRoute2Info route, int volume) {
MediaRoute2Info route, int volume, int requestId) {
Objects.requireNonNull(manager, "manager must not be null");
Objects.requireNonNull(route, "route must not be null");
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
setRouteVolumeWithManagerLocked(manager, route, volume);
setRouteVolumeWithManagerLocked(manager, route, volume, requestId);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -397,7 +403,7 @@ class MediaRouter2ServiceImpl {
}
public void selectRouteWithManager(IMediaRouter2Manager manager, String uniqueSessionId,
MediaRoute2Info route) {
MediaRoute2Info route, int requestId) {
Objects.requireNonNull(manager, "manager must not be null");
if (TextUtils.isEmpty(uniqueSessionId)) {
throw new IllegalArgumentException("uniqueSessionId must not be empty");
@@ -407,7 +413,7 @@ class MediaRouter2ServiceImpl {
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
selectRouteWithManagerLocked(manager, uniqueSessionId, route);
selectRouteWithManagerLocked(manager, uniqueSessionId, route, requestId);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -415,7 +421,7 @@ class MediaRouter2ServiceImpl {
}
public void deselectRouteWithManager(IMediaRouter2Manager manager, String uniqueSessionId,
MediaRoute2Info route) {
MediaRoute2Info route, int requestId) {
Objects.requireNonNull(manager, "manager must not be null");
if (TextUtils.isEmpty(uniqueSessionId)) {
throw new IllegalArgumentException("uniqueSessionId must not be empty");
@@ -425,7 +431,7 @@ class MediaRouter2ServiceImpl {
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
deselectRouteWithManagerLocked(manager, uniqueSessionId, route);
deselectRouteWithManagerLocked(manager, uniqueSessionId, route, requestId);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -433,7 +439,7 @@ class MediaRouter2ServiceImpl {
}
public void transferToRouteWithManager(IMediaRouter2Manager manager, String uniqueSessionId,
MediaRoute2Info route) {
MediaRoute2Info route, int requestId) {
Objects.requireNonNull(manager, "manager must not be null");
if (TextUtils.isEmpty(uniqueSessionId)) {
throw new IllegalArgumentException("uniqueSessionId must not be empty");
@@ -443,7 +449,7 @@ class MediaRouter2ServiceImpl {
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
transferToRouteWithManagerLocked(manager, uniqueSessionId, route);
transferToRouteWithManagerLocked(manager, uniqueSessionId, route, requestId);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -451,7 +457,7 @@ class MediaRouter2ServiceImpl {
}
public void setSessionVolumeWithManager(IMediaRouter2Manager manager,
String uniqueSessionId, int volume) {
String uniqueSessionId, int volume, int requestId) {
Objects.requireNonNull(manager, "manager must not be null");
if (TextUtils.isEmpty(uniqueSessionId)) {
throw new IllegalArgumentException("uniqueSessionId must not be empty");
@@ -460,14 +466,15 @@ class MediaRouter2ServiceImpl {
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
setSessionVolumeWithManagerLocked(manager, uniqueSessionId, volume);
setSessionVolumeWithManagerLocked(manager, uniqueSessionId, volume, requestId);
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
public void releaseSessionWithManager(IMediaRouter2Manager manager, String uniqueSessionId) {
public void releaseSessionWithManager(IMediaRouter2Manager manager, String uniqueSessionId,
int requestId) {
Objects.requireNonNull(manager, "manager must not be null");
if (TextUtils.isEmpty(uniqueSessionId)) {
throw new IllegalArgumentException("uniqueSessionId must not be empty");
@@ -476,7 +483,7 @@ class MediaRouter2ServiceImpl {
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
releaseSessionWithManagerLocked(manager, uniqueSessionId);
releaseSessionWithManagerLocked(manager, uniqueSessionId, requestId);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -572,7 +579,7 @@ class MediaRouter2ServiceImpl {
obtainMessage(UserHandler::notifyPreferredFeaturesChangedToManagers,
routerRecord.mUserRecord.mHandler, routerRecord));
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::updateDiscoveryPreference,
obtainMessage(UserHandler::updateDiscoveryPreferenceOnHandler,
routerRecord.mUserRecord.mHandler));
}
@@ -584,7 +591,7 @@ class MediaRouter2ServiceImpl {
if (routerRecord != null) {
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::setRouteVolumeOnHandler,
routerRecord.mUserRecord.mHandler, route, volume));
routerRecord.mUserRecord.mHandler, route, volume, DUMMY_REQUEST_ID));
}
}
@@ -615,7 +622,8 @@ class MediaRouter2ServiceImpl {
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::selectRouteOnHandler,
routerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId, route));
routerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId, route,
DUMMY_REQUEST_ID));
}
private void deselectRouteWithRouter2Locked(@NonNull IMediaRouter2 router,
@@ -629,7 +637,8 @@ class MediaRouter2ServiceImpl {
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::deselectRouteOnHandler,
routerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId, route));
routerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId, route,
DUMMY_REQUEST_ID));
}
private void transferToRouteWithRouter2Locked(@NonNull IMediaRouter2 router,
@@ -643,7 +652,8 @@ class MediaRouter2ServiceImpl {
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::transferToRouteOnHandler,
routerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId, route));
routerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId, route,
DUMMY_REQUEST_ID));
}
private void setSessionVolumeWithRouter2Locked(@NonNull IMediaRouter2 router,
@@ -657,7 +667,8 @@ class MediaRouter2ServiceImpl {
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::setSessionVolumeOnHandler,
routerRecord.mUserRecord.mHandler, uniqueSessionId, volume));
routerRecord.mUserRecord.mHandler, uniqueSessionId, volume,
DUMMY_REQUEST_ID));
}
private void releaseSessionWithRouter2Locked(@NonNull IMediaRouter2 router,
@@ -671,7 +682,8 @@ class MediaRouter2ServiceImpl {
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::releaseSessionOnHandler,
routerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId));
routerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId,
DUMMY_REQUEST_ID));
}
////////////////////////////////////////////////////////////
@@ -744,16 +756,18 @@ class MediaRouter2ServiceImpl {
}
private void setRouteVolumeWithManagerLocked(@NonNull IMediaRouter2Manager manager,
@NonNull MediaRoute2Info route, int volume) {
@NonNull MediaRoute2Info route, int volume, int requestId) {
final IBinder binder = manager.asBinder();
ManagerRecord managerRecord = mAllManagerRecords.get(binder);
if (managerRecord == null) {
return;
}
long uniqueRequestId = toUniqueRequestId(managerRecord.mManagerId, requestId);
managerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::setRouteVolumeOnHandler,
managerRecord.mUserRecord.mHandler, route, volume));
managerRecord.mUserRecord.mHandler, route, volume, uniqueRequestId));
}
private void requestCreateSessionWithManagerLocked(@NonNull IMediaRouter2Manager manager,
@@ -778,7 +792,7 @@ class MediaRouter2ServiceImpl {
}
private void selectRouteWithManagerLocked(@NonNull IMediaRouter2Manager manager,
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route) {
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route, int requestId) {
final IBinder binder = manager.asBinder();
ManagerRecord managerRecord = mAllManagerRecords.get(binder);
@@ -790,13 +804,15 @@ class MediaRouter2ServiceImpl {
RouterRecord routerRecord = managerRecord.mUserRecord.mHandler
.findRouterforSessionLocked(uniqueSessionId);
long uniqueRequestId = toUniqueRequestId(managerRecord.mManagerId, requestId);
managerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::selectRouteOnHandler,
managerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId, route));
managerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId, route,
uniqueRequestId));
}
private void deselectRouteWithManagerLocked(@NonNull IMediaRouter2Manager manager,
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route) {
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route, int requestId) {
final IBinder binder = manager.asBinder();
ManagerRecord managerRecord = mAllManagerRecords.get(binder);
@@ -808,13 +824,15 @@ class MediaRouter2ServiceImpl {
RouterRecord routerRecord = managerRecord.mUserRecord.mHandler
.findRouterforSessionLocked(uniqueSessionId);
long uniqueRequestId = toUniqueRequestId(managerRecord.mManagerId, requestId);
managerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::deselectRouteOnHandler,
managerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId, route));
managerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId, route,
uniqueRequestId));
}
private void transferToRouteWithManagerLocked(@NonNull IMediaRouter2Manager manager,
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route) {
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route, int requestId) {
final IBinder binder = manager.asBinder();
ManagerRecord managerRecord = mAllManagerRecords.get(binder);
@@ -826,13 +844,15 @@ class MediaRouter2ServiceImpl {
RouterRecord routerRecord = managerRecord.mUserRecord.mHandler
.findRouterforSessionLocked(uniqueSessionId);
long uniqueRequestId = toUniqueRequestId(managerRecord.mManagerId, requestId);
managerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::transferToRouteOnHandler,
managerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId, route));
managerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId, route,
uniqueRequestId));
}
private void setSessionVolumeWithManagerLocked(@NonNull IMediaRouter2Manager manager,
@NonNull String uniqueSessionId, int volume) {
@NonNull String uniqueSessionId, int volume, int requestId) {
final IBinder binder = manager.asBinder();
ManagerRecord managerRecord = mAllManagerRecords.get(binder);
@@ -840,13 +860,15 @@ class MediaRouter2ServiceImpl {
return;
}
long uniqueRequestId = toUniqueRequestId(managerRecord.mManagerId, requestId);
managerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::setSessionVolumeOnHandler,
managerRecord.mUserRecord.mHandler, uniqueSessionId, volume));
managerRecord.mUserRecord.mHandler, uniqueSessionId, volume,
uniqueRequestId));
}
private void releaseSessionWithManagerLocked(@NonNull IMediaRouter2Manager manager,
@NonNull String uniqueSessionId) {
@NonNull String uniqueSessionId, int requestId) {
final IBinder binder = manager.asBinder();
ManagerRecord managerRecord = mAllManagerRecords.get(binder);
@@ -856,10 +878,15 @@ class MediaRouter2ServiceImpl {
RouterRecord routerRecord = managerRecord.mUserRecord.mHandler
.findRouterforSessionLocked(uniqueSessionId);
if (routerRecord == null) {
return;
}
long uniqueRequestId = toUniqueRequestId(managerRecord.mManagerId, requestId);
managerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::releaseSessionOnHandler,
managerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId));
managerRecord.mUserRecord.mHandler, routerRecord, uniqueSessionId,
uniqueRequestId));
}
////////////////////////////////////////////////////////////
@@ -1100,6 +1127,13 @@ class MediaRouter2ServiceImpl {
this, provider, sessionInfo));
}
@Override
public void onRequestFailed(@NonNull MediaRoute2Provider provider, long requestId,
int reason) {
sendMessage(PooledLambda.obtainMessage(UserHandler::onRequestFailedOnHandler,
this, provider, requestId, reason));
}
@Nullable
public RouterRecord findRouterforSessionLocked(@NonNull String uniqueSessionId) {
return mSessionToRouterMap.get(uniqueSessionId);
@@ -1195,7 +1229,7 @@ class MediaRouter2ServiceImpl {
if (provider == null) {
Slog.w(TAG, "Ignoring session creation request since no provider found for"
+ " given route=" + route);
notifySessionCreationFailed(routerRecord, toOriginalRequestId(requestId));
notifySessionCreationFailedToRouter(routerRecord, toOriginalRequestId(requestId));
return;
}
@@ -1210,7 +1244,7 @@ class MediaRouter2ServiceImpl {
// routerRecord can be null if the session is system's.
private void selectRouteOnHandler(@Nullable RouterRecord routerRecord,
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route) {
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route, long requestId) {
if (!checkArgumentsForSessionControl(routerRecord, uniqueSessionId, route,
"selecting")) {
return;
@@ -1222,12 +1256,12 @@ class MediaRouter2ServiceImpl {
if (provider == null) {
return;
}
provider.selectRoute(getOriginalId(uniqueSessionId), route.getOriginalId());
provider.selectRoute(getOriginalId(uniqueSessionId), route.getOriginalId(), requestId);
}
// routerRecord can be null if the session is system's.
private void deselectRouteOnHandler(@Nullable RouterRecord routerRecord,
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route) {
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route, long requestId) {
if (!checkArgumentsForSessionControl(routerRecord, uniqueSessionId, route,
"deselecting")) {
return;
@@ -1239,12 +1273,13 @@ class MediaRouter2ServiceImpl {
if (provider == null) {
return;
}
provider.deselectRoute(getOriginalId(uniqueSessionId), route.getOriginalId());
provider.deselectRoute(getOriginalId(uniqueSessionId), route.getOriginalId(),
requestId);
}
// routerRecord can be null if the session is system's.
private void transferToRouteOnHandler(@Nullable RouterRecord routerRecord,
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route) {
@NonNull String uniqueSessionId, @NonNull MediaRoute2Info route, long requestId) {
if (!checkArgumentsForSessionControl(routerRecord, uniqueSessionId, route,
"transferring to")) {
return;
@@ -1256,7 +1291,8 @@ class MediaRouter2ServiceImpl {
if (provider == null) {
return;
}
provider.transferToRoute(getOriginalId(uniqueSessionId), route.getOriginalId());
provider.transferToRoute(getOriginalId(uniqueSessionId), route.getOriginalId(),
requestId);
}
private boolean checkArgumentsForSessionControl(@Nullable RouterRecord routerRecord,
@@ -1299,7 +1335,7 @@ class MediaRouter2ServiceImpl {
}
private void releaseSessionOnHandler(@NonNull RouterRecord routerRecord,
@NonNull String uniqueSessionId) {
@NonNull String uniqueSessionId, long uniqueRequestId) {
final RouterRecord matchingRecord = mSessionToRouterMap.get(uniqueSessionId);
if (matchingRecord != routerRecord) {
Slog.w(TAG, "Ignoring releasing session from non-matching router."
@@ -1329,14 +1365,14 @@ class MediaRouter2ServiceImpl {
return;
}
provider.releaseSession(sessionId);
provider.releaseSession(sessionId, uniqueRequestId);
}
private void onSessionCreatedOnHandler(@NonNull MediaRoute2Provider provider,
@NonNull RoutingSessionInfo sessionInfo, long requestId) {
notifySessionCreatedToManagers(getManagers(), sessionInfo);
if (requestId == MediaRoute2ProviderService.REQUEST_ID_UNKNOWN) {
if (requestId == REQUEST_ID_NONE) {
// The session is created without any matching request.
return;
}
@@ -1362,7 +1398,7 @@ class MediaRouter2ServiceImpl {
if (sessionInfo == null) {
// Failed
notifySessionCreationFailed(matchingRequest.mRouterRecord,
notifySessionCreationFailedToRouter(matchingRequest.mRouterRecord,
toOriginalRequestId(requestId));
return;
}
@@ -1374,13 +1410,13 @@ class MediaRouter2ServiceImpl {
Slog.w(TAG, "Created session doesn't match the original request."
+ " originalRouteId=" + originalRouteId
+ ", requestId=" + requestId + ", sessionInfo=" + sessionInfo);
notifySessionCreationFailed(matchingRequest.mRouterRecord,
notifySessionCreationFailedToRouter(matchingRequest.mRouterRecord,
toOriginalRequestId(requestId));
return;
}
// Succeeded
notifySessionCreated(matchingRequest.mRouterRecord,
notifySessionCreatedToRouter(matchingRequest.mRouterRecord,
sessionInfo, toOriginalRequestId(requestId));
mSessionToRouterMap.put(sessionInfo.getId(), routerRecord);
}
@@ -1405,7 +1441,7 @@ class MediaRouter2ServiceImpl {
}
mSessionCreationRequests.remove(matchingRequest);
notifySessionCreationFailed(matchingRequest.mRouterRecord,
notifySessionCreationFailedToRouter(matchingRequest.mRouterRecord,
toOriginalRequestId(requestId));
}
@@ -1429,7 +1465,7 @@ class MediaRouter2ServiceImpl {
Slog.w(TAG, "No matching router found for session=" + sessionInfo);
return;
}
notifySessionInfoChanged(routerRecord, sessionInfo);
notifySessionInfoChangedToRouter(routerRecord, sessionInfo);
}
private void onSessionReleasedOnHandler(@NonNull MediaRoute2Provider provider,
@@ -1442,10 +1478,38 @@ class MediaRouter2ServiceImpl {
Slog.w(TAG, "No matching router found for session=" + sessionInfo);
return;
}
notifySessionReleased(routerRecord, sessionInfo);
notifySessionReleasedToRouter(routerRecord, sessionInfo);
}
private void notifySessionCreated(@NonNull RouterRecord routerRecord,
private void onRequestFailedOnHandler(@NonNull MediaRoute2Provider provider,
long requestId, int reason) {
final int managerId = toRouterOrManagerId(requestId);
MediaRouter2ServiceImpl service = mServiceRef.get();
if (service == null) {
return;
}
ManagerRecord managerToNotifyFailure = null;
synchronized (service.mLock) {
for (ManagerRecord manager : mUserRecord.mManagerRecords) {
if (manager.mManagerId == managerId) {
managerToNotifyFailure = manager;
break;
}
}
}
if (managerToNotifyFailure == null) {
Slog.w(TAG, "No matching managerRecord found for managerId=" + managerId);
return;
}
notifyRequestFailedToManager(
managerToNotifyFailure.mManager, toOriginalRequestId(requestId), reason);
}
private void notifySessionCreatedToRouter(@NonNull RouterRecord routerRecord,
@NonNull RoutingSessionInfo sessionInfo, int requestId) {
try {
routerRecord.mRouter.notifySessionCreated(sessionInfo, requestId);
@@ -1455,7 +1519,7 @@ class MediaRouter2ServiceImpl {
}
}
private void notifySessionCreationFailed(@NonNull RouterRecord routerRecord,
private void notifySessionCreationFailedToRouter(@NonNull RouterRecord routerRecord,
int requestId) {
try {
routerRecord.mRouter.notifySessionCreated(/* sessionInfo= */ null, requestId);
@@ -1465,7 +1529,7 @@ class MediaRouter2ServiceImpl {
}
}
private void notifySessionInfoChanged(@NonNull RouterRecord routerRecord,
private void notifySessionInfoChangedToRouter(@NonNull RouterRecord routerRecord,
@NonNull RoutingSessionInfo sessionInfo) {
try {
routerRecord.mRouter.notifySessionInfoChanged(sessionInfo);
@@ -1475,7 +1539,7 @@ class MediaRouter2ServiceImpl {
}
}
private void notifySessionReleased(@NonNull RouterRecord routerRecord,
private void notifySessionReleasedToRouter(@NonNull RouterRecord routerRecord,
@NonNull RoutingSessionInfo sessionInfo) {
try {
routerRecord.mRouter.notifySessionReleased(sessionInfo);
@@ -1485,21 +1549,23 @@ class MediaRouter2ServiceImpl {
}
}
private void setRouteVolumeOnHandler(@NonNull MediaRoute2Info route, int volume) {
private void setRouteVolumeOnHandler(@NonNull MediaRoute2Info route, int volume,
long requestId) {
final MediaRoute2Provider provider = findProvider(route.getProviderId());
if (provider != null) {
provider.setRouteVolume(route.getOriginalId(), volume);
provider.setRouteVolume(route.getOriginalId(), volume, requestId);
}
}
private void setSessionVolumeOnHandler(@NonNull String uniqueSessionId, int volume) {
private void setSessionVolumeOnHandler(@NonNull String uniqueSessionId, int volume,
long requestId) {
final MediaRoute2Provider provider = findProvider(getProviderId(uniqueSessionId));
if (provider == null) {
Slog.w(TAG, "setSessionVolume: couldn't find provider for session "
+ "id=" + uniqueSessionId);
return;
}
provider.setSessionVolume(getOriginalId(uniqueSessionId), volume);
provider.setSessionVolume(getOriginalId(uniqueSessionId), volume, requestId);
}
private List<IMediaRouter2> getRouters() {
@@ -1683,7 +1749,17 @@ class MediaRouter2ServiceImpl {
}
}
private void updateDiscoveryPreference() {
private void notifyRequestFailedToManager(@NonNull IMediaRouter2Manager manager,
int requestId, int reason) {
try {
manager.notifyRequestFailed(requestId, reason);
} catch (RemoteException ex) {
Slog.w(TAG, "Failed to notify manager of the request failure."
+ " Manager probably died.", ex);
}
}
private void updateDiscoveryPreferenceOnHandler() {
MediaRouter2ServiceImpl service = mServiceRef.get();
if (service == null) {
return;

View File

@@ -543,8 +543,8 @@ public final class MediaRouterService extends IMediaRouterService.Stub
// Binder call
@Override
public void setRouteVolumeWithManager(IMediaRouter2Manager manager,
MediaRoute2Info route, int volume) {
mService2.setRouteVolumeWithManager(manager, route, volume);
MediaRoute2Info route, int volume, int requestId) {
mService2.setRouteVolumeWithManager(manager, route, volume, requestId);
}
// Binder call
@@ -557,35 +557,36 @@ public final class MediaRouterService extends IMediaRouterService.Stub
// Binder call
@Override
public void selectRouteWithManager(IMediaRouter2Manager manager, String sessionId,
MediaRoute2Info route) {
mService2.selectRouteWithManager(manager, sessionId, route);
MediaRoute2Info route, int requestId) {
mService2.selectRouteWithManager(manager, sessionId, route, requestId);
}
// Binder call
@Override
public void deselectRouteWithManager(IMediaRouter2Manager manager, String sessionId,
MediaRoute2Info route) {
mService2.deselectRouteWithManager(manager, sessionId, route);
MediaRoute2Info route, int requestId) {
mService2.deselectRouteWithManager(manager, sessionId, route, requestId);
}
// Binder call
@Override
public void transferToRouteWithManager(IMediaRouter2Manager manager, String sessionId,
MediaRoute2Info route) {
mService2.transferToRouteWithManager(manager, sessionId, route);
MediaRoute2Info route, int requestId) {
mService2.transferToRouteWithManager(manager, sessionId, route, requestId);
}
// Binder call
@Override
public void setSessionVolumeWithManager(IMediaRouter2Manager manager,
String sessionId, int volume) {
mService2.setSessionVolumeWithManager(manager, sessionId, volume);
String sessionId, int volume, int requestId) {
mService2.setSessionVolumeWithManager(manager, sessionId, volume, requestId);
}
// Binder call
@Override
public void releaseSessionWithManager(IMediaRouter2Manager manager, String sessionId) {
mService2.releaseSessionWithManager(manager, sessionId);
public void releaseSessionWithManager(IMediaRouter2Manager manager, String sessionId,
int requestId) {
mService2.releaseSessionWithManager(manager, sessionId, requestId);
}
void restoreBluetoothA2dp() {

View File

@@ -130,26 +130,27 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
}
@Override
public void releaseSession(String sessionId) {
public void releaseSession(String sessionId, long requestId) {
// Do nothing
}
@Override
public void updateDiscoveryPreference(RouteDiscoveryPreference discoveryPreference) {
// Do nothing
}
@Override
public void selectRoute(String sessionId, String routeId) {
public void selectRoute(String sessionId, String routeId, long requestId) {
// Do nothing since we don't support multiple BT yet.
}
@Override
public void deselectRoute(String sessionId, String routeId) {
public void deselectRoute(String sessionId, String routeId, long requestId) {
// Do nothing since we don't support multiple BT yet.
}
@Override
public void transferToRoute(String sessionId, String routeId) {
public void transferToRoute(String sessionId, String routeId, long requestId) {
if (TextUtils.equals(routeId, mDefaultRoute.getId())) {
mBtRouteProvider.transferTo(null);
} else {
@@ -158,7 +159,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
}
@Override
public void setRouteVolume(String routeId, int volume) {
public void setRouteVolume(String routeId, int volume, long requestId) {
if (!TextUtils.equals(routeId, mSelectedRouteId)) {
return;
}
@@ -166,7 +167,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
}
@Override
public void setSessionVolume(String sessionId, int volume) {
public void setSessionVolume(String sessionId, int volume, long requestId) {
// Do nothing since we don't support grouping volume yet.
}