Merge "MediaRouter: Cleanup MediaRouter2Manager APIs" into rvc-dev am: f8ac47cdae
Change-Id: I0584908395b8c30b1c1d9363ae33e908ac5dfbdd
This commit is contained in:
@@ -1071,7 +1071,7 @@ public class MediaRouter2 {
|
|||||||
try {
|
try {
|
||||||
mMediaRouterService.deselectRouteWithRouter2(stub, getId(), route);
|
mMediaRouterService.deselectRouteWithRouter2(stub, getId(), route);
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
Log.e(TAG, "Unable to remove route from session.", ex);
|
Log.e(TAG, "Unable to deselect route from session.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,8 +44,10 @@ import java.util.concurrent.ConcurrentMap;
|
|||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* A class that monitors and controls media routing of other apps.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class MediaRouter2Manager {
|
public class MediaRouter2Manager {
|
||||||
@@ -200,11 +202,25 @@ public class MediaRouter2Manager {
|
|||||||
return routes;
|
return routes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the system routing session associated with no specific application.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public RoutingSessionInfo getSystemRoutingSession() {
|
||||||
|
for (RoutingSessionInfo sessionInfo : getActiveSessions()) {
|
||||||
|
if (sessionInfo.isSystemSession()) {
|
||||||
|
return sessionInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("No system routing session");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets routing sessions of an application with the given package name.
|
* Gets routing sessions of an application with the given package name.
|
||||||
* The first element of the returned list is the system routing controller.
|
* The first element of the returned list is the system routing session.
|
||||||
*
|
*
|
||||||
* @see MediaRouter2#getSystemController()
|
* @param packageName the package name of the application that is routing.
|
||||||
|
* @see #getSystemRoutingSession()
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public List<RoutingSessionInfo> getRoutingSessions(@NonNull String packageName) {
|
public List<RoutingSessionInfo> getRoutingSessions(@NonNull String packageName) {
|
||||||
@@ -213,8 +229,11 @@ public class MediaRouter2Manager {
|
|||||||
List<RoutingSessionInfo> sessions = new ArrayList<>();
|
List<RoutingSessionInfo> sessions = new ArrayList<>();
|
||||||
|
|
||||||
for (RoutingSessionInfo sessionInfo : getActiveSessions()) {
|
for (RoutingSessionInfo sessionInfo : getActiveSessions()) {
|
||||||
if (sessionInfo.isSystemSession()
|
if (sessionInfo.isSystemSession()) {
|
||||||
|| TextUtils.equals(sessionInfo.getClientPackageName(), packageName)) {
|
sessions.add(new RoutingSessionInfo.Builder(sessionInfo)
|
||||||
|
.setClientPackageName(packageName)
|
||||||
|
.build());
|
||||||
|
} else if (TextUtils.equals(sessionInfo.getClientPackageName(), packageName)) {
|
||||||
sessions.add(sessionInfo);
|
sessions.add(sessionInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,10 +242,15 @@ public class MediaRouter2Manager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of all active routing sessions.
|
* Gets the list of all active routing sessions.
|
||||||
|
* <p>
|
||||||
* The first element of the list is the system routing session containing
|
* The first element of the list is the system routing session containing
|
||||||
* phone speakers, wired headset, Bluetooth devices.
|
* phone speakers, wired headset, Bluetooth devices.
|
||||||
* The system routing session is shared by apps such that controlling it will affect
|
* The system routing session is shared by apps such that controlling it will affect
|
||||||
* all apps.
|
* all apps.
|
||||||
|
* If you want to transfer media of an application, use {@link #getRoutingSessions(String)}.
|
||||||
|
*
|
||||||
|
* @see #getRoutingSessions(String)
|
||||||
|
* @see #getSystemRoutingSession()
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public List<RoutingSessionInfo> getActiveSessions() {
|
public List<RoutingSessionInfo> getActiveSessions() {
|
||||||
@@ -258,31 +282,46 @@ public class MediaRouter2Manager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects media route for the specified package name.
|
* Selects media route for the specified package name.
|
||||||
*
|
|
||||||
* If the given route is {@link RoutingController#getTransferableRoutes() a transferable
|
|
||||||
* route} of a routing session of the application, the session will be transferred to
|
|
||||||
* the route. If not, a new routing session will be created.
|
|
||||||
*
|
|
||||||
* @param packageName the package name of the application that should change it's media route
|
|
||||||
* @param route the route to be selected.
|
|
||||||
*/
|
*/
|
||||||
public void selectRoute(@NonNull String packageName, @NonNull MediaRoute2Info route) {
|
public void selectRoute(@NonNull String packageName, @NonNull MediaRoute2Info route) {
|
||||||
Objects.requireNonNull(packageName, "packageName must not be null");
|
Objects.requireNonNull(packageName, "packageName must not be null");
|
||||||
Objects.requireNonNull(route, "route must not be null");
|
Objects.requireNonNull(route, "route must not be null");
|
||||||
|
|
||||||
boolean transferred = false;
|
List<RoutingSessionInfo> sessionInfos = getRoutingSessions(packageName);
|
||||||
//TODO: instead of release all controllers, add an API to specify controllers that
|
RoutingSessionInfo targetSession = sessionInfos.get(sessionInfos.size() - 1);
|
||||||
// should be released (or is the system controller).
|
transfer(targetSession, route);
|
||||||
for (RoutingSessionInfo sessionInfo : getRoutingSessions(packageName)) {
|
|
||||||
if (!transferred && sessionInfo.getTransferableRoutes().contains(route.getId())) {
|
|
||||||
new RoutingController(sessionInfo).transferToRoute(route);
|
|
||||||
transferred = true;
|
|
||||||
} else if (!sessionInfo.isSystemSession()) {
|
|
||||||
new RoutingController(sessionInfo).release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transferred) {
|
/**
|
||||||
|
* Transfers a routing session to a media route.
|
||||||
|
* <p>{@link Callback#onTransferred} or {@link Callback#onTransferFailed} will be called
|
||||||
|
* depending on the result.
|
||||||
|
*
|
||||||
|
* @param sessionInfo the routing session info to transfer
|
||||||
|
* @param route the route transfer to
|
||||||
|
*
|
||||||
|
* @see Callback#onTransferred(RoutingSessionInfo, RoutingSessionInfo)
|
||||||
|
* @see Callback#onTransferFailed(RoutingSessionInfo, MediaRoute2Info)
|
||||||
|
*/
|
||||||
|
public void transfer(@NonNull RoutingSessionInfo sessionInfo,
|
||||||
|
@Nullable MediaRoute2Info route) {
|
||||||
|
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
|
||||||
|
|
||||||
|
if (route == null) {
|
||||||
|
releaseSession(sessionInfo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Ignore unknown route.
|
||||||
|
if (sessionInfo.getTransferableRoutes().contains(route.getId())) {
|
||||||
|
//TODO: callbacks must be called after this.
|
||||||
|
transferToRoute(sessionInfo, route);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(sessionInfo.getClientPackageName())) {
|
||||||
|
Log.w(TAG, "transfer: Ignoring transfer without package name.");
|
||||||
|
notifyTransferFailed(sessionInfo, route);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,7 +333,7 @@ public class MediaRouter2Manager {
|
|||||||
try {
|
try {
|
||||||
int requestId = mNextRequestId.getAndIncrement();
|
int requestId = mNextRequestId.getAndIncrement();
|
||||||
mMediaRouterService.requestCreateSessionWithManager(
|
mMediaRouterService.requestCreateSessionWithManager(
|
||||||
client, packageName, route, requestId);
|
client, sessionInfo.getClientPackageName(), route, requestId);
|
||||||
//TODO: release the previous session?
|
//TODO: release the previous session?
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
Log.e(TAG, "Unable to select media route", ex);
|
Log.e(TAG, "Unable to select media route", ex);
|
||||||
@@ -451,6 +490,18 @@ public class MediaRouter2Manager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void notifyTransferred(RoutingSessionInfo oldSession, RoutingSessionInfo newSession) {
|
||||||
|
for (CallbackRecord record : mCallbackRecords) {
|
||||||
|
record.mExecutor.execute(() -> record.mCallback.onTransferred(oldSession, newSession));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void notifyTransferFailed(RoutingSessionInfo sessionInfo, MediaRoute2Info route) {
|
||||||
|
for (CallbackRecord record : mCallbackRecords) {
|
||||||
|
record.mExecutor.execute(() -> record.mCallback.onTransferFailed(sessionInfo, route));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void updatePreferredFeatures(String packageName, List<String> preferredFeatures) {
|
void updatePreferredFeatures(String packageName, List<String> preferredFeatures) {
|
||||||
List<String> prevFeatures = mPreferredFeaturesMap.put(packageName, preferredFeatures);
|
List<String> prevFeatures = mPreferredFeaturesMap.put(packageName, preferredFeatures);
|
||||||
if ((prevFeatures == null && preferredFeatures.size() == 0)
|
if ((prevFeatures == null && preferredFeatures.size() == 0)
|
||||||
@@ -474,6 +525,204 @@ public class MediaRouter2Manager {
|
|||||||
return new RoutingController(sessionInfo);
|
return new RoutingController(sessionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the unmodifiable list of selected routes for the session.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public List<MediaRoute2Info> getSelectedRoutes(@NonNull RoutingSessionInfo sessionInfo) {
|
||||||
|
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
|
||||||
|
|
||||||
|
List<String> routeIds = sessionInfo.getSelectedRoutes();
|
||||||
|
return getRoutesWithIds(routeIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the unmodifiable list of selectable routes for the session.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public List<MediaRoute2Info> getSelectableRoutes(@NonNull RoutingSessionInfo sessionInfo) {
|
||||||
|
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
|
||||||
|
|
||||||
|
List<String> routeIds = sessionInfo.getSelectableRoutes();
|
||||||
|
return getRoutesWithIds(routeIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the unmodifiable list of deselectable routes for the session.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public List<MediaRoute2Info> getDeselectableRoutes(@NonNull RoutingSessionInfo sessionInfo) {
|
||||||
|
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
|
||||||
|
|
||||||
|
List<String> routeIds = sessionInfo.getDeselectableRoutes();
|
||||||
|
return getRoutesWithIds(routeIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects a route for the remote session. After a route is selected, the media is expected
|
||||||
|
* to be played to the all the selected routes. This is different from {@link
|
||||||
|
* #transfer(RoutingSessionInfo, MediaRoute2Info)} transferring to a route},
|
||||||
|
* where the media is expected to 'move' from one route to another.
|
||||||
|
* <p>
|
||||||
|
* The given route must satisfy all of the following conditions:
|
||||||
|
* <ul>
|
||||||
|
* <li>it should not be included in {@link #getSelectedRoutes(RoutingSessionInfo)}</li>
|
||||||
|
* <li>it should be included in {@link #getSelectableRoutes(RoutingSessionInfo)}</li>
|
||||||
|
* </ul>
|
||||||
|
* If the route doesn't meet any of above conditions, it will be ignored.
|
||||||
|
*
|
||||||
|
* @see #getSelectedRoutes(RoutingSessionInfo)
|
||||||
|
* @see #getSelectableRoutes(RoutingSessionInfo)
|
||||||
|
* @see Callback#onSessionsUpdated()
|
||||||
|
*/
|
||||||
|
public void selectRoute(@NonNull RoutingSessionInfo sessionInfo,
|
||||||
|
@NonNull MediaRoute2Info route) {
|
||||||
|
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
|
||||||
|
Objects.requireNonNull(route, "route must not be null");
|
||||||
|
|
||||||
|
if (sessionInfo.getSelectedRoutes().contains(route.getId())) {
|
||||||
|
Log.w(TAG, "Ignoring selecting a route that is already selected. route=" + route);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sessionInfo.getSelectableRoutes().contains(route.getId())) {
|
||||||
|
Log.w(TAG, "Ignoring selecting a non-selectable route=" + route);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Client client;
|
||||||
|
synchronized (sLock) {
|
||||||
|
client = mClient;
|
||||||
|
}
|
||||||
|
if (client != null) {
|
||||||
|
try {
|
||||||
|
int requestId = mNextRequestId.getAndIncrement();
|
||||||
|
mMediaRouterService.selectRouteWithManager(
|
||||||
|
mClient, sessionInfo.getId(), route, requestId);
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
Log.e(TAG, "selectRoute: Failed to send a request.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deselects a route from the remote session. After a route is deselected, the media is
|
||||||
|
* expected to be stopped on the deselected routes.
|
||||||
|
* <p>
|
||||||
|
* The given route must satisfy all of the following conditions:
|
||||||
|
* <ul>
|
||||||
|
* <li>it should be included in {@link #getSelectedRoutes(RoutingSessionInfo)}</li>
|
||||||
|
* <li>it should be included in {@link #getDeselectableRoutes(RoutingSessionInfo)}</li>
|
||||||
|
* </ul>
|
||||||
|
* If the route doesn't meet any of above conditions, it will be ignored.
|
||||||
|
*
|
||||||
|
* @see #getSelectedRoutes(RoutingSessionInfo)
|
||||||
|
* @see #getDeselectableRoutes(RoutingSessionInfo)
|
||||||
|
* @see Callback#onSessionsUpdated()
|
||||||
|
*/
|
||||||
|
public void deselectRoute(@NonNull RoutingSessionInfo sessionInfo,
|
||||||
|
@NonNull MediaRoute2Info route) {
|
||||||
|
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
|
||||||
|
Objects.requireNonNull(route, "route must not be null");
|
||||||
|
|
||||||
|
if (!sessionInfo.getSelectedRoutes().contains(route.getId())) {
|
||||||
|
Log.w(TAG, "Ignoring deselecting a route that is not selected. route=" + route);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sessionInfo.getDeselectableRoutes().contains(route.getId())) {
|
||||||
|
Log.w(TAG, "Ignoring deselecting a non-deselectable route=" + route);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Client client;
|
||||||
|
synchronized (sLock) {
|
||||||
|
client = mClient;
|
||||||
|
}
|
||||||
|
if (client != null) {
|
||||||
|
try {
|
||||||
|
int requestId = mNextRequestId.getAndIncrement();
|
||||||
|
mMediaRouterService.deselectRouteWithManager(
|
||||||
|
mClient, sessionInfo.getId(), route, requestId);
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
Log.e(TAG, "deselectRoute: Failed to send a request.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfers to a given route for the remote session.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
void transferToRoute(@NonNull RoutingSessionInfo sessionInfo,
|
||||||
|
@NonNull MediaRoute2Info route) {
|
||||||
|
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
|
||||||
|
Objects.requireNonNull(route, "route must not be null");
|
||||||
|
|
||||||
|
if (sessionInfo.getSelectedRoutes().contains(route.getId())) {
|
||||||
|
Log.w(TAG, "Ignoring transferring to a route that is already added. route="
|
||||||
|
+ route);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sessionInfo.getTransferableRoutes().contains(route.getId())) {
|
||||||
|
Log.w(TAG, "Ignoring transferring to a non-transferable route=" + route);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Client client;
|
||||||
|
synchronized (sLock) {
|
||||||
|
client = mClient;
|
||||||
|
}
|
||||||
|
if (client != null) {
|
||||||
|
try {
|
||||||
|
int requestId = mNextRequestId.getAndIncrement();
|
||||||
|
mMediaRouterService.transferToRouteWithManager(
|
||||||
|
mClient, sessionInfo.getId(), route, requestId);
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
Log.e(TAG, "transferToRoute: Failed to send a request.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests releasing a session.
|
||||||
|
* <p>
|
||||||
|
* If a session is released, any operation on the session will be ignored.
|
||||||
|
* {@link Callback#onTransferred(RoutingSessionInfo, RoutingSessionInfo)} with {@code null}
|
||||||
|
* session will be called when the session is released.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @see Callback#onTransferred(RoutingSessionInfo, RoutingSessionInfo)
|
||||||
|
*/
|
||||||
|
public void releaseSession(@NonNull RoutingSessionInfo sessionInfo) {
|
||||||
|
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
|
||||||
|
|
||||||
|
Client client;
|
||||||
|
synchronized (sLock) {
|
||||||
|
client = mClient;
|
||||||
|
}
|
||||||
|
if (client != null) {
|
||||||
|
try {
|
||||||
|
int requestId = mNextRequestId.getAndIncrement();
|
||||||
|
mMediaRouterService.releaseSessionWithManager(
|
||||||
|
mClient, sessionInfo.getId(), requestId);
|
||||||
|
} catch (RemoteException ex) {
|
||||||
|
Log.e(TAG, "releaseSession: Failed to send a request", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MediaRoute2Info> getRoutesWithIds(List<String> routeIds) {
|
||||||
|
synchronized (sLock) {
|
||||||
|
return routeIds.stream().map(mRoutes::get)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Remove this.
|
||||||
/**
|
/**
|
||||||
* A class to control media routing session in media route provider.
|
* A class to control media routing session in media route provider.
|
||||||
* With routing controller, an application can select a route into the session or deselect
|
* With routing controller, an application can select a route into the session or deselect
|
||||||
@@ -488,6 +737,15 @@ public class MediaRouter2Manager {
|
|||||||
mSessionInfo = sessionInfo;
|
mSessionInfo = sessionInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases the session
|
||||||
|
*/
|
||||||
|
public void release() {
|
||||||
|
synchronized (mControllerLock) {
|
||||||
|
releaseSession(mSessionInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the ID of the session
|
* Gets the ID of the session
|
||||||
*/
|
*/
|
||||||
@@ -523,11 +781,7 @@ public class MediaRouter2Manager {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public List<MediaRoute2Info> getSelectedRoutes() {
|
public List<MediaRoute2Info> getSelectedRoutes() {
|
||||||
List<String> routeIds;
|
return MediaRouter2Manager.this.getSelectedRoutes(mSessionInfo);
|
||||||
synchronized (mControllerLock) {
|
|
||||||
routeIds = mSessionInfo.getSelectedRoutes();
|
|
||||||
}
|
|
||||||
return getRoutesWithIds(routeIds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -535,11 +789,7 @@ public class MediaRouter2Manager {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public List<MediaRoute2Info> getSelectableRoutes() {
|
public List<MediaRoute2Info> getSelectableRoutes() {
|
||||||
List<String> routeIds;
|
return MediaRouter2Manager.this.getSelectableRoutes(mSessionInfo);
|
||||||
synchronized (mControllerLock) {
|
|
||||||
routeIds = mSessionInfo.getSelectableRoutes();
|
|
||||||
}
|
|
||||||
return getRoutesWithIds(routeIds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -547,11 +797,7 @@ public class MediaRouter2Manager {
|
|||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public List<MediaRoute2Info> getDeselectableRoutes() {
|
public List<MediaRoute2Info> getDeselectableRoutes() {
|
||||||
List<String> routeIds;
|
return MediaRouter2Manager.this.getDeselectableRoutes(mSessionInfo);
|
||||||
synchronized (mControllerLock) {
|
|
||||||
routeIds = mSessionInfo.getDeselectableRoutes();
|
|
||||||
}
|
|
||||||
return getRoutesWithIds(routeIds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -579,35 +825,7 @@ public class MediaRouter2Manager {
|
|||||||
* @see #getSelectableRoutes()
|
* @see #getSelectableRoutes()
|
||||||
*/
|
*/
|
||||||
public void selectRoute(@NonNull MediaRoute2Info route) {
|
public void selectRoute(@NonNull MediaRoute2Info route) {
|
||||||
Objects.requireNonNull(route, "route must not be null");
|
MediaRouter2Manager.this.selectRoute(mSessionInfo, route);
|
||||||
|
|
||||||
RoutingSessionInfo sessionInfo;
|
|
||||||
synchronized (mControllerLock) {
|
|
||||||
sessionInfo = mSessionInfo;
|
|
||||||
}
|
|
||||||
if (sessionInfo.getSelectedRoutes().contains(route.getId())) {
|
|
||||||
Log.w(TAG, "Ignoring selecting a route that is already selected. route=" + route);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sessionInfo.getSelectableRoutes().contains(route.getId())) {
|
|
||||||
Log.w(TAG, "Ignoring selecting a non-selectable route=" + route);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Client client;
|
|
||||||
synchronized (sLock) {
|
|
||||||
client = mClient;
|
|
||||||
}
|
|
||||||
if (client != null) {
|
|
||||||
try {
|
|
||||||
int requestId = mNextRequestId.getAndIncrement();
|
|
||||||
mMediaRouterService.selectRouteWithManager(
|
|
||||||
mClient, getSessionId(), route, requestId);
|
|
||||||
} catch (RemoteException ex) {
|
|
||||||
Log.e(TAG, "Unable to select route for session.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -623,104 +841,19 @@ public class MediaRouter2Manager {
|
|||||||
* @see #getDeselectableRoutes()
|
* @see #getDeselectableRoutes()
|
||||||
*/
|
*/
|
||||||
public void deselectRoute(@NonNull MediaRoute2Info route) {
|
public void deselectRoute(@NonNull MediaRoute2Info route) {
|
||||||
Objects.requireNonNull(route, "route must not be null");
|
MediaRouter2Manager.this.deselectRoute(mSessionInfo, route);
|
||||||
RoutingSessionInfo sessionInfo;
|
|
||||||
synchronized (mControllerLock) {
|
|
||||||
sessionInfo = mSessionInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sessionInfo.getSelectedRoutes().contains(route.getId())) {
|
|
||||||
Log.w(TAG, "Ignoring deselecting a route that is not selected. route=" + route);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sessionInfo.getDeselectableRoutes().contains(route.getId())) {
|
|
||||||
Log.w(TAG, "Ignoring deselecting a non-deselectable route=" + route);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Client client;
|
|
||||||
synchronized (sLock) {
|
|
||||||
client = mClient;
|
|
||||||
}
|
|
||||||
if (client != null) {
|
|
||||||
try {
|
|
||||||
int requestId = mNextRequestId.getAndIncrement();
|
|
||||||
mMediaRouterService.deselectRouteWithManager(
|
|
||||||
mClient, getSessionId(), route, requestId);
|
|
||||||
} catch (RemoteException ex) {
|
|
||||||
Log.e(TAG, "Unable to remove route from session.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transfers to a given route for the remote session. The given route must satisfy
|
* Transfers session to the given rotue.
|
||||||
* all of the following conditions:
|
|
||||||
* <ul>
|
|
||||||
* <li>ID should not be included in {@link #getSelectedRoutes()}</li>
|
|
||||||
* <li>ID should be included in {@link #getTransferableRoutes()}</li>
|
|
||||||
* </ul>
|
|
||||||
* If the route doesn't meet any of above conditions, it will be ignored.
|
|
||||||
*
|
|
||||||
* @see #getSelectedRoutes()
|
|
||||||
* @see #getTransferableRoutes()
|
|
||||||
*/
|
*/
|
||||||
public void transferToRoute(@NonNull MediaRoute2Info route) {
|
public void transferToRoute(@NonNull MediaRoute2Info route) {
|
||||||
Objects.requireNonNull(route, "route must not be null");
|
MediaRouter2Manager.this.transferToRoute(mSessionInfo, route);
|
||||||
RoutingSessionInfo sessionInfo;
|
|
||||||
synchronized (mControllerLock) {
|
|
||||||
sessionInfo = mSessionInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sessionInfo.getSelectedRoutes().contains(route.getId())) {
|
|
||||||
Log.w(TAG, "Ignoring transferring to a route that is already added. route="
|
|
||||||
+ route);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sessionInfo.getTransferableRoutes().contains(route.getId())) {
|
|
||||||
Log.w(TAG, "Ignoring transferring to a non-transferable route=" + route);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Client client;
|
|
||||||
synchronized (sLock) {
|
|
||||||
client = mClient;
|
|
||||||
}
|
|
||||||
if (client != null) {
|
|
||||||
try {
|
|
||||||
int requestId = mNextRequestId.getAndIncrement();
|
|
||||||
mMediaRouterService.transferToRouteWithManager(
|
|
||||||
mClient, getSessionId(), route, requestId);
|
|
||||||
} catch (RemoteException ex) {
|
|
||||||
Log.e(TAG, "Unable to transfer to route for session.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Release this session.
|
|
||||||
* Any operation on this session after calling this method will be ignored.
|
|
||||||
*/
|
|
||||||
public void release() {
|
|
||||||
Client client;
|
|
||||||
synchronized (sLock) {
|
|
||||||
client = mClient;
|
|
||||||
}
|
|
||||||
if (client != null) {
|
|
||||||
try {
|
|
||||||
int requestId = mNextRequestId.getAndIncrement();
|
|
||||||
mMediaRouterService.releaseSessionWithManager(
|
|
||||||
mClient, getSessionId(), requestId);
|
|
||||||
} catch (RemoteException ex) {
|
|
||||||
Log.e(TAG, "Unable to notify of controller release", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the session info of the session
|
* Gets the session info of the session
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -729,19 +862,6 @@ public class MediaRouter2Manager {
|
|||||||
return mSessionInfo;
|
return mSessionInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MediaRoute2Info> getRoutesWithIds(List<String> routeIds) {
|
|
||||||
List<MediaRoute2Info> routes = new ArrayList<>();
|
|
||||||
synchronized (mRoutesLock) {
|
|
||||||
for (String routeId : routeIds) {
|
|
||||||
MediaRoute2Info route = mRoutes.get(routeId);
|
|
||||||
if (route != null) {
|
|
||||||
routes.add(route);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Collections.unmodifiableList(routes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -780,7 +900,24 @@ public class MediaRouter2Manager {
|
|||||||
*/
|
*/
|
||||||
public void onSessionsUpdated() {}
|
public void onSessionsUpdated() {}
|
||||||
|
|
||||||
//TODO: remove this
|
//TODO: Call this.
|
||||||
|
/**
|
||||||
|
* Called when media is transferred.
|
||||||
|
*
|
||||||
|
* @param oldSession the previous session
|
||||||
|
* @param newSession the new session or {@code null} if the session is released.
|
||||||
|
*/
|
||||||
|
public void onTransferred(@NonNull RoutingSessionInfo oldSession,
|
||||||
|
@Nullable RoutingSessionInfo newSession) { }
|
||||||
|
|
||||||
|
//TODO: Call this.
|
||||||
|
/**
|
||||||
|
* Called when {@link #transfer(RoutingSessionInfo, MediaRoute2Info)} fails.
|
||||||
|
*/
|
||||||
|
public void onTransferFailed(@NonNull RoutingSessionInfo session,
|
||||||
|
@NonNull MediaRoute2Info route) { }
|
||||||
|
|
||||||
|
//TODO: Remove this.
|
||||||
/**
|
/**
|
||||||
* Called when the preferred route features of an app is changed.
|
* Called when the preferred route features of an app is changed.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -357,7 +357,7 @@ public final class RoutingSessionInfo implements Parcelable {
|
|||||||
// TODO: Reorder these (important ones first)
|
// TODO: Reorder these (important ones first)
|
||||||
final String mId;
|
final String mId;
|
||||||
CharSequence mName;
|
CharSequence mName;
|
||||||
final String mClientPackageName;
|
String mClientPackageName;
|
||||||
String mProviderId;
|
String mProviderId;
|
||||||
final List<String> mSelectedRoutes;
|
final List<String> mSelectedRoutes;
|
||||||
final List<String> mSelectableRoutes;
|
final List<String> mSelectableRoutes;
|
||||||
@@ -433,6 +433,17 @@ public final class RoutingSessionInfo implements Parcelable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the client package name of the session.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public Builder setClientPackageName(@Nullable String packageName) {
|
||||||
|
mClientPackageName = packageName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the provider ID of the session.
|
* Sets the provider ID of the session.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -248,10 +248,9 @@ public class MediaRouter2ManagerTest {
|
|||||||
|
|
||||||
assertEquals(2, sessions.size());
|
assertEquals(2, sessions.size());
|
||||||
|
|
||||||
MediaRouter2Manager.RoutingController routingController =
|
RoutingSessionInfo sessionInfo = sessions.get(1);
|
||||||
mManager.getControllerForSession(sessions.get(1));
|
|
||||||
awaitOnRouteChangedManager(
|
awaitOnRouteChangedManager(
|
||||||
() -> routingController.release(),
|
() -> mManager.releaseSession(sessionInfo),
|
||||||
ROUTE_ID1,
|
ROUTE_ID1,
|
||||||
route -> TextUtils.equals(route.getClientPackageName(), null));
|
route -> TextUtils.equals(route.getClientPackageName(), null));
|
||||||
assertEquals(1, mManager.getRoutingSessions(mPackageName).size());
|
assertEquals(1, mManager.getRoutingSessions(mPackageName).size());
|
||||||
@@ -283,8 +282,7 @@ public class MediaRouter2ManagerTest {
|
|||||||
List<RoutingSessionInfo> sessions = mManager.getRoutingSessions(mPackageName);
|
List<RoutingSessionInfo> sessions = mManager.getRoutingSessions(mPackageName);
|
||||||
|
|
||||||
assertEquals(2, sessions.size());
|
assertEquals(2, sessions.size());
|
||||||
MediaRouter2Manager.RoutingController routingController =
|
RoutingSessionInfo sessionInfo = sessions.get(1);
|
||||||
mManager.getControllerForSession(sessions.get(1));
|
|
||||||
|
|
||||||
awaitOnRouteChangedManager(
|
awaitOnRouteChangedManager(
|
||||||
() -> mManager.selectRoute(mPackageName, routes.get(ROUTE_ID5_TO_TRANSFER_TO)),
|
() -> mManager.selectRoute(mPackageName, routes.get(ROUTE_ID5_TO_TRANSFER_TO)),
|
||||||
@@ -292,7 +290,7 @@ public class MediaRouter2ManagerTest {
|
|||||||
route -> TextUtils.equals(route.getClientPackageName(), mPackageName));
|
route -> TextUtils.equals(route.getClientPackageName(), mPackageName));
|
||||||
|
|
||||||
awaitOnRouteChangedManager(
|
awaitOnRouteChangedManager(
|
||||||
() -> routingController.release(),
|
() -> mManager.releaseSession(sessionInfo),
|
||||||
ROUTE_ID5_TO_TRANSFER_TO,
|
ROUTE_ID5_TO_TRANSFER_TO,
|
||||||
route -> TextUtils.equals(route.getClientPackageName(), null));
|
route -> TextUtils.equals(route.getClientPackageName(), null));
|
||||||
}
|
}
|
||||||
@@ -573,7 +571,7 @@ public class MediaRouter2ManagerTest {
|
|||||||
addManagerCallback(new MediaRouter2Manager.Callback());
|
addManagerCallback(new MediaRouter2Manager.Callback());
|
||||||
|
|
||||||
for (RoutingSessionInfo session : mManager.getActiveSessions()) {
|
for (RoutingSessionInfo session : mManager.getActiveSessions()) {
|
||||||
mManager.getControllerForSession(session).release();
|
mManager.releaseSession(session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user