Merge "Make RouteSessionInfo#getId() return String rather than primitive int"

This commit is contained in:
Hyundo Moon
2020-01-10 00:28:43 +00:00
committed by Android (Google) Code Review
14 changed files with 354 additions and 231 deletions

View File

@@ -24,13 +24,12 @@ import android.media.IMediaRoute2ProviderClient;
*/
oneway interface IMediaRoute2Provider {
void setClient(IMediaRoute2ProviderClient client);
void requestCreateSession(String packageName, String routeId,
String routeType, long requestId);
void releaseSession(int sessionId);
void requestCreateSession(String packageName, String routeId, String routeType, long requestId);
void releaseSession(String sessionId);
void selectRoute(int sessionId, String routeId);
void deselectRoute(int sessionId, String routeId);
void transferToRoute(int sessionId, String routeId);
void selectRoute(String sessionId, String routeId);
void deselectRoute(String sessionId, String routeId);
void transferToRoute(String sessionId, String routeId);
void notifyControlRequestSent(String id, in Intent request);
void requestSetVolume(String id, int volume);

View File

@@ -16,6 +16,8 @@
package android.media;
import static android.media.MediaRouter2Utils.toUniqueId;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -190,13 +192,6 @@ public final class MediaRoute2Info implements Parcelable {
mExtras = in.readBundle();
}
/**
* @hide
*/
public static String toUniqueId(String providerId, String routeId) {
return providerId + ":" + routeId;
}
/**
* Returns true if the route info has all of the required field.
* A route info only obtained from {@link com.android.server.media.MediaRouterService}

View File

@@ -29,6 +29,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
@@ -55,7 +56,7 @@ public abstract class MediaRoute2ProviderService extends Service {
private MediaRoute2ProviderInfo mProviderInfo;
@GuardedBy("mSessionLock")
private ArrayMap<Integer, RouteSessionInfo> mSessionInfo = new ArrayMap<>();
private ArrayMap<String, RouteSessionInfo> mSessionInfo = new ArrayMap<>();
public MediaRoute2ProviderService() {
mHandler = new Handler(Looper.getMainLooper());
@@ -106,7 +107,10 @@ public abstract class MediaRoute2ProviderService extends Service {
* null if the session is destroyed or id is not valid.
*/
@Nullable
public final RouteSessionInfo getSessionInfo(int sessionId) {
public final RouteSessionInfo getSessionInfo(@NonNull String sessionId) {
if (TextUtils.isEmpty(sessionId)) {
throw new IllegalArgumentException("sessionId must not be empty");
}
synchronized (mSessionLock) {
return mSessionInfo.get(sessionId);
}
@@ -134,7 +138,7 @@ public abstract class MediaRoute2ProviderService extends Service {
*/
public final void updateSessionInfo(@NonNull RouteSessionInfo sessionInfo) {
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
int sessionId = sessionInfo.getSessionId();
String sessionId = sessionInfo.getId();
if (sessionInfo.getSelectedRoutes().isEmpty()) {
releaseSession(sessionId);
return;
@@ -160,7 +164,7 @@ public abstract class MediaRoute2ProviderService extends Service {
public final void notifySessionInfoChanged(@NonNull RouteSessionInfo sessionInfo) {
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
int sessionId = sessionInfo.getSessionId();
String sessionId = sessionInfo.getId();
synchronized (mSessionLock) {
if (mSessionInfo.containsKey(sessionId)) {
mSessionInfo.put(sessionId, sessionInfo);
@@ -185,7 +189,7 @@ public abstract class MediaRoute2ProviderService extends Service {
* controlled, pass a {@link Bundle} that contains how to control it.
*
* @param sessionInfo information of the new session.
* The {@link RouteSessionInfo#getSessionId() id} of the session must be
* The {@link RouteSessionInfo#getId() id} of the session must be
* unique. Pass {@code null} to reject the request or inform clients that
* session creation is failed.
* @param requestId id of the previous request to create this session
@@ -194,13 +198,13 @@ public abstract class MediaRoute2ProviderService extends Service {
// TODO: Maybe better to create notifySessionCreationFailed?
public final void notifySessionCreated(@Nullable RouteSessionInfo sessionInfo, long requestId) {
if (sessionInfo != null) {
int sessionId = sessionInfo.getSessionId();
String sessionId = sessionInfo.getId();
synchronized (mSessionLock) {
if (mSessionInfo.containsKey(sessionId)) {
Log.w(TAG, "Ignoring duplicate session id.");
return;
}
mSessionInfo.put(sessionInfo.getSessionId(), sessionInfo);
mSessionInfo.put(sessionInfo.getId(), sessionInfo);
}
schedulePublishState();
}
@@ -220,9 +224,12 @@ public abstract class MediaRoute2ProviderService extends Service {
* {@link #onDestroySession} is called if the session is released.
*
* @param sessionId id of the session to be released
* @see #onDestroySession(int, RouteSessionInfo)
* @see #onDestroySession(String, RouteSessionInfo)
*/
public final void releaseSession(int sessionId) {
public final void releaseSession(@NonNull String sessionId) {
if (TextUtils.isEmpty(sessionId)) {
throw new IllegalArgumentException("sessionId must not be empty");
}
//TODO: notify media router service of release.
RouteSessionInfo sessionInfo;
synchronized (mSessionLock) {
@@ -259,9 +266,10 @@ public abstract class MediaRoute2ProviderService extends Service {
*
* @param sessionId id of the session being destroyed.
* @param lastSessionInfo information of the session being destroyed.
* @see #releaseSession(int)
* @see #releaseSession(String)
*/
public abstract void onDestroySession(int sessionId, @NonNull RouteSessionInfo lastSessionInfo);
public abstract void onDestroySession(@NonNull String sessionId,
@NonNull RouteSessionInfo lastSessionInfo);
//TODO: make a way to reject the request
/**
@@ -274,7 +282,7 @@ public abstract class MediaRoute2ProviderService extends Service {
* @param routeId id of the route
* @see #updateSessionInfo(RouteSessionInfo)
*/
public abstract void onSelectRoute(int sessionId, @NonNull String routeId);
public abstract void onSelectRoute(@NonNull String sessionId, @NonNull String routeId);
//TODO: make a way to reject the request
/**
@@ -286,7 +294,7 @@ public abstract class MediaRoute2ProviderService extends Service {
* @param sessionId id of the session
* @param routeId id of the route
*/
public abstract void onDeselectRoute(int sessionId, @NonNull String routeId);
public abstract void onDeselectRoute(@NonNull String sessionId, @NonNull String routeId);
//TODO: make a way to reject the request
/**
@@ -298,7 +306,7 @@ public abstract class MediaRoute2ProviderService extends Service {
* @param sessionId id of the session
* @param routeId id of the route
*/
public abstract void onTransferToRoute(int sessionId, @NonNull String routeId);
public abstract void onTransferToRoute(@NonNull String sessionId, @NonNull String routeId);
/**
* Called when the {@link RouteDiscoveryRequest discovery request} has changed.
@@ -385,37 +393,53 @@ public abstract class MediaRoute2ProviderService extends Service {
requestId));
}
@Override
public void releaseSession(int sessionId) {
public void releaseSession(@NonNull String sessionId) {
if (!checkCallerisSystem()) {
return;
}
if (TextUtils.isEmpty(sessionId)) {
Log.w(TAG, "releaseSession: Ignoring empty sessionId from system service.");
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::releaseSession,
MediaRoute2ProviderService.this, sessionId));
}
@Override
public void selectRoute(int sessionId, String routeId) {
public void selectRoute(@NonNull String sessionId, String routeId) {
if (!checkCallerisSystem()) {
return;
}
if (TextUtils.isEmpty(sessionId)) {
Log.w(TAG, "selectRoute: Ignoring empty sessionId from system service.");
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelectRoute,
MediaRoute2ProviderService.this, sessionId, routeId));
}
@Override
public void deselectRoute(int sessionId, String routeId) {
public void deselectRoute(@NonNull String sessionId, String routeId) {
if (!checkCallerisSystem()) {
return;
}
if (TextUtils.isEmpty(sessionId)) {
Log.w(TAG, "deselectRoute: Ignoring empty sessionId from system service.");
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onDeselectRoute,
MediaRoute2ProviderService.this, sessionId, routeId));
}
@Override
public void transferToRoute(int sessionId, String routeId) {
public void transferToRoute(@NonNull String sessionId, String routeId) {
if (!checkCallerisSystem()) {
return;
}
if (TextUtils.isEmpty(sessionId)) {
Log.w(TAG, "transferToRoute: Ignoring empty sessionId from system service.");
return;
}
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onTransferToRoute,
MediaRoute2ProviderService.this, sessionId, routeId));
}

View File

@@ -342,8 +342,7 @@ public class MediaRouter2 {
final int requestId;
requestId = mSessionCreationRequestCnt.getAndIncrement();
SessionCreationRequest request = new SessionCreationRequest(
requestId, route, routeType);
SessionCreationRequest request = new SessionCreationRequest(requestId, route, routeType);
mSessionCreationRequests.add(request);
Client2 client;
@@ -352,8 +351,7 @@ public class MediaRouter2 {
}
if (client != null) {
try {
mMediaRouterService.requestCreateSession(
client, route, routeType, requestId);
mMediaRouterService.requestCreateSession(client, route, routeType, requestId);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to request to create session.", ex);
mHandler.sendMessage(obtainMessage(MediaRouter2::createControllerOnHandler,
@@ -542,7 +540,7 @@ public class MediaRouter2 {
if (sessionInfo != null) {
RouteSessionController controller = new RouteSessionController(sessionInfo);
synchronized (sRouterLock) {
mSessionControllers.put(controller.getUniqueSessionId(), controller);
mSessionControllers.put(controller.getSessionId(), controller);
}
notifySessionCreated(controller);
}
@@ -556,12 +554,12 @@ public class MediaRouter2 {
RouteSessionController matchingController;
synchronized (sRouterLock) {
matchingController = mSessionControllers.get(sessionInfo.getUniqueSessionId());
matchingController = mSessionControllers.get(sessionInfo.getId());
}
if (matchingController == null) {
Log.w(TAG, "changeSessionInfoOnHandler: Matching controller not found. uniqueSessionId="
+ sessionInfo.getUniqueSessionId());
+ sessionInfo.getId());
return;
}
@@ -582,7 +580,7 @@ public class MediaRouter2 {
return;
}
final String uniqueSessionId = sessionInfo.getUniqueSessionId();
final String uniqueSessionId = sessionInfo.getId();
RouteSessionController matchingController;
synchronized (sRouterLock) {
matchingController = mSessionControllers.get(uniqueSessionId);
@@ -591,7 +589,7 @@ public class MediaRouter2 {
if (matchingController == null) {
if (DEBUG) {
Log.d(TAG, "releaseControllerOnHandler: Matching controller not found. "
+ "uniqueSessionId=" + sessionInfo.getUniqueSessionId());
+ "uniqueSessionId=" + sessionInfo.getId());
}
return;
}
@@ -783,20 +781,9 @@ public class MediaRouter2 {
/**
* @return the ID of the session
*/
public int getSessionId() {
public String getSessionId() {
synchronized (mControllerLock) {
return mSessionInfo.getSessionId();
}
}
/**
* @return the unique ID of the session
* @hide
*/
@NonNull
public String getUniqueSessionId() {
synchronized (mControllerLock) {
return mSessionInfo.getUniqueSessionId();
return mSessionInfo.getId();
}
}
@@ -913,7 +900,7 @@ public class MediaRouter2 {
}
if (client != null) {
try {
mMediaRouterService.selectRoute(client, getUniqueSessionId(), route);
mMediaRouterService.selectRoute(client, getSessionId(), route);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to select route for session.", ex);
}
@@ -960,7 +947,7 @@ public class MediaRouter2 {
}
if (client != null) {
try {
mMediaRouterService.deselectRoute(client, getUniqueSessionId(), route);
mMediaRouterService.deselectRoute(client, getSessionId(), route);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to remove route from session.", ex);
}
@@ -1008,7 +995,7 @@ public class MediaRouter2 {
}
if (client != null) {
try {
mMediaRouterService.transferToRoute(client, getUniqueSessionId(), route);
mMediaRouterService.transferToRoute(client, getSessionId(), route);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to transfer to route for session.", ex);
}
@@ -1033,12 +1020,12 @@ public class MediaRouter2 {
Client2 client;
synchronized (sRouterLock) {
mSessionControllers.remove(getUniqueSessionId(), this);
mSessionControllers.remove(getSessionId(), this);
client = mClient;
}
if (client != null) {
try {
mMediaRouterService.releaseSession(client, getUniqueSessionId());
mMediaRouterService.releaseSession(client, getSessionId());
} catch (RemoteException ex) {
Log.e(TAG, "Unable to notify of controller release", ex);
}
@@ -1068,6 +1055,7 @@ public class MediaRouter2 {
List<MediaRoute2Info> routes = new ArrayList<>();
synchronized (sRouterLock) {
// TODO: Maybe able to change using Collection.stream()?
for (String routeId : routeIds) {
MediaRoute2Info route = mRoutes.get(routeId);
if (route != null) {

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.media;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
/**
* @hide
*/
public class MediaRouter2Utils {
static final String TAG = "MR2Utils";
static final String SEPARATOR = ":";
/**
* @hide
*/
@NonNull
public static String toUniqueId(@NonNull String providerId, @NonNull String id) {
if (TextUtils.isEmpty(providerId)) {
Log.w(TAG, "toUniqueId: providerId shouldn't be empty");
return null;
}
if (TextUtils.isEmpty(id)) {
Log.w(TAG, "toUniqueId: id shouldn't be null");
return null;
}
return providerId + SEPARATOR + id;
}
/**
* Gets provider ID from unique ID.
* If the corresponding provider ID could not be generated, it will return null.
*
* @hide
*/
@Nullable
public static String getProviderId(@NonNull String uniqueId) {
if (TextUtils.isEmpty(uniqueId)) {
Log.w(TAG, "getProviderId: uniqueId shouldn't be empty");
return null;
}
int firstIndexOfSeparator = uniqueId.indexOf(SEPARATOR);
if (firstIndexOfSeparator == -1) {
return null;
}
String providerId = uniqueId.substring(0, firstIndexOfSeparator);
if (TextUtils.isEmpty(providerId)) {
return null;
}
return providerId;
}
/**
* Gets the original ID (i.e. non-unique route/session ID) from unique ID.
* If the corresponding ID could not be generated, it will return null.
*
* @hide
*/
@Nullable
public static String getOriginalId(@NonNull String uniqueId) {
if (TextUtils.isEmpty(uniqueId)) {
Log.w(TAG, "getOriginalId: uniqueId shouldn't be empty");
return null;
}
int firstIndexOfSeparator = uniqueId.indexOf(SEPARATOR);
if (firstIndexOfSeparator == -1 || firstIndexOfSeparator + 1 >= uniqueId.length()) {
return null;
}
String providerId = uniqueId.substring(firstIndexOfSeparator + 1);
if (TextUtils.isEmpty(providerId)) {
return null;
}
return providerId;
}
}

View File

@@ -22,6 +22,7 @@ import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
import java.util.Collections;
@@ -33,6 +34,7 @@ import java.util.Objects;
* @hide
*/
public class RouteSessionInfo implements Parcelable {
@NonNull
public static final Creator<RouteSessionInfo> CREATOR =
new Creator<RouteSessionInfo>() {
@@ -46,8 +48,10 @@ public class RouteSessionInfo implements Parcelable {
}
};
final int mSessionId;
final String mPackageName;
public static final String TAG = "RouteSessionInfo";
final String mId;
final String mClientPackageName;
final String mRouteType;
@Nullable
final String mProviderId;
@@ -61,15 +65,19 @@ public class RouteSessionInfo implements Parcelable {
RouteSessionInfo(@NonNull Builder builder) {
Objects.requireNonNull(builder, "builder must not be null.");
mSessionId = builder.mSessionId;
mPackageName = builder.mPackageName;
mId = builder.mId;
mClientPackageName = builder.mClientPackageName;
mRouteType = builder.mRouteType;
mProviderId = builder.mProviderId;
mSelectedRoutes = Collections.unmodifiableList(builder.mSelectedRoutes);
mSelectableRoutes = Collections.unmodifiableList(builder.mSelectableRoutes);
mDeselectableRoutes = Collections.unmodifiableList(builder.mDeselectableRoutes);
mTransferrableRoutes = Collections.unmodifiableList(builder.mTransferrableRoutes);
mSelectedRoutes = Collections.unmodifiableList(
convertToUniqueRouteIds(builder.mSelectedRoutes));
mSelectableRoutes = Collections.unmodifiableList(
convertToUniqueRouteIds(builder.mSelectableRoutes));
mDeselectableRoutes = Collections.unmodifiableList(
convertToUniqueRouteIds(builder.mDeselectableRoutes));
mTransferrableRoutes = Collections.unmodifiableList(
convertToUniqueRouteIds(builder.mTransferrableRoutes));
mControlHints = builder.mControlHints;
}
@@ -77,8 +85,8 @@ public class RouteSessionInfo implements Parcelable {
RouteSessionInfo(@NonNull Parcel src) {
Objects.requireNonNull(src, "src must not be null.");
mSessionId = src.readInt();
mPackageName = ensureString(src.readString());
mId = ensureString(src.readString());
mClientPackageName = ensureString(src.readString());
mRouteType = ensureString(src.readString());
mProviderId = src.readString();
@@ -104,74 +112,51 @@ public class RouteSessionInfo implements Parcelable {
return Collections.emptyList();
}
/**
* Gets non-unique session id (int) from unique session id (string).
* If the corresponding session id could not be generated, it will return null.
* @hide
*/
@Nullable
public static Integer getSessionId(@NonNull String uniqueSessionId) {
int lastIndexOfSeparator = uniqueSessionId.lastIndexOf("/");
if (lastIndexOfSeparator == -1 || lastIndexOfSeparator + 1 >= uniqueSessionId.length()) {
return null;
}
String integerString = uniqueSessionId.substring(lastIndexOfSeparator + 1);
if (TextUtils.isEmpty(integerString)) {
return null;
}
try {
return Integer.parseInt(integerString);
} catch (NumberFormatException ex) {
return null;
}
}
/**
* Gets provider ID (string) from unique session id (string).
* If the corresponding provider ID could not be generated, it will return null.
* @hide
*
* TODO: This logic seems error-prone. Consider to use long uniqueId.
*/
@Nullable
public static String getProviderId(@NonNull String uniqueSessionId) {
int lastIndexOfSeparator = uniqueSessionId.lastIndexOf("/");
if (lastIndexOfSeparator == -1) {
return null;
}
String result = uniqueSessionId.substring(0, lastIndexOfSeparator);
if (TextUtils.isEmpty(result)) {
return null;
}
return result;
}
/**
* Returns whether the session info is valid or not
*
* TODO in this CL: Remove this method.
*/
public boolean isValid() {
return !TextUtils.isEmpty(mPackageName)
return !TextUtils.isEmpty(mId)
&& !TextUtils.isEmpty(mClientPackageName)
&& !TextUtils.isEmpty(mRouteType)
&& mSelectedRoutes.size() > 0;
}
/**
* Gets the id of the session
* Gets the id of the session. The sessions which are given by {@link MediaRouter2} will have
* unique IDs.
* <p>
* In order to ensure uniqueness in {@link MediaRouter2} side, the value of this method
* can be different from what was set in {@link MediaRoute2ProviderService}.
*
* @see Builder#Builder(String, String, String)
*/
@NonNull
public int getSessionId() {
return mSessionId;
public String getId() {
if (mProviderId != null) {
return MediaRouter2Utils.toUniqueId(mProviderId, mId);
} else {
return mId;
}
}
/**
* Gets the original id set by {@link Builder#Builder(String, String, String)}.
* @hide
*/
@NonNull
public String getOriginalId() {
return mId;
}
/**
* Gets the client package name of the session
*/
@NonNull
public String getPackageName() {
return mPackageName;
public String getClientPackageName() {
return mClientPackageName;
}
/**
@@ -192,19 +177,6 @@ public class RouteSessionInfo implements Parcelable {
return mProviderId;
}
/**
* Gets the unique id of the session.
* @hide
*/
@NonNull
public String getUniqueSessionId() {
StringBuilder sessionIdBuilder = new StringBuilder()
.append(mProviderId)
.append("/")
.append(mSessionId);
return sessionIdBuilder.toString();
}
/**
* Gets the list of ids of selected routes for the session. It shouldn't be empty.
*/
@@ -252,8 +224,8 @@ public class RouteSessionInfo implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mSessionId);
dest.writeString(mPackageName);
dest.writeString(mId);
dest.writeString(mClientPackageName);
dest.writeString(mRouteType);
dest.writeString(mProviderId);
dest.writeStringList(mSelectedRoutes);
@@ -267,7 +239,7 @@ public class RouteSessionInfo implements Parcelable {
public String toString() {
StringBuilder result = new StringBuilder()
.append("RouteSessionInfo{ ")
.append("sessionId=").append(mSessionId)
.append("sessionId=").append(mId)
.append(", routeType=").append(mRouteType)
.append(", selectedRoutes={")
.append(String.join(",", mSelectedRoutes))
@@ -285,12 +257,30 @@ public class RouteSessionInfo implements Parcelable {
return result.toString();
}
private List<String> convertToUniqueRouteIds(@NonNull List<String> routeIds) {
if (routeIds == null) {
Log.w(TAG, "routeIds is null. Returning an empty list");
return Collections.emptyList();
}
// mProviderId can be null if not set. Return the original list for this case.
if (mProviderId == null) {
return routeIds;
}
List<String> result = new ArrayList<>();
for (String routeId : routeIds) {
result.add(MediaRouter2Utils.toUniqueId(mProviderId, routeId));
}
return result;
}
/**
* Builder class for {@link RouteSessionInfo}.
*/
public static final class Builder {
final String mPackageName;
final int mSessionId;
final String mId;
final String mClientPackageName;
final String mRouteType;
String mProviderId;
final List<String> mSelectedRoutes;
@@ -299,22 +289,42 @@ public class RouteSessionInfo implements Parcelable {
final List<String> mTransferrableRoutes;
Bundle mControlHints;
public Builder(int sessionId, @NonNull String packageName,
/**
* Constructor for builder to create {@link RouteSessionInfo}.
* <p>
* In order to ensure ID uniqueness in {@link MediaRouter2} side, the value of
* {@link RouteSessionInfo#getId()} can be different from what was set in
* {@link MediaRoute2ProviderService}.
* </p>
*
* @see MediaRoute2Info#getId()
*/
public Builder(@NonNull String id, @NonNull String clientPackageName,
@NonNull String routeType) {
mSessionId = sessionId;
mPackageName = Objects.requireNonNull(packageName, "packageName must not be null");
mRouteType = Objects.requireNonNull(routeType,
"routeType must not be null");
if (TextUtils.isEmpty(id)) {
throw new IllegalArgumentException("id must not be empty");
}
mId = id;
mClientPackageName = Objects.requireNonNull(
clientPackageName, "clientPackageName must not be null");
mRouteType = Objects.requireNonNull(routeType, "routeType must not be null");
mSelectedRoutes = new ArrayList<>();
mSelectableRoutes = new ArrayList<>();
mDeselectableRoutes = new ArrayList<>();
mTransferrableRoutes = new ArrayList<>();
}
public Builder(RouteSessionInfo sessionInfo) {
mSessionId = sessionInfo.mSessionId;
mPackageName = sessionInfo.mPackageName;
/**
* Constructor for builder to create {@link RouteSessionInfo} with
* existing {@link RouteSessionInfo} instance.
*
* @param sessionInfo the existing instance to copy data from.
*/
public Builder(@NonNull RouteSessionInfo sessionInfo) {
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
mId = sessionInfo.mId;
mClientPackageName = sessionInfo.mClientPackageName;
mRouteType = sessionInfo.mRouteType;
mProviderId = sessionInfo.mProviderId;
@@ -334,21 +344,12 @@ public class RouteSessionInfo implements Parcelable {
* @hide
*/
@NonNull
public Builder setProviderId(String providerId) {
mProviderId = providerId;
convertToUniqueRouteIds(providerId, mSelectedRoutes);
convertToUniqueRouteIds(providerId, mSelectableRoutes);
convertToUniqueRouteIds(providerId, mDeselectableRoutes);
convertToUniqueRouteIds(providerId, mTransferrableRoutes);
return this;
}
private void convertToUniqueRouteIds(@NonNull String providerId,
@NonNull List<String> routeIds) {
for (int i = 0; i < routeIds.size(); i++) {
String routeId = routeIds.get(i);
routeIds.set(i, MediaRoute2Info.toUniqueId(providerId, routeId));
public Builder setProviderId(@NonNull String providerId) {
if (TextUtils.isEmpty(providerId)) {
throw new IllegalArgumentException("providerId must not be empty");
}
mProviderId = providerId;
return this;
}
/**

View File

@@ -64,7 +64,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
"com.android.mediarouteprovider.TYPE_SPECIAL";
Map<String, MediaRoute2Info> mRoutes = new HashMap<>();
Map<String, Integer> mRouteSessionMap = new HashMap<>();
Map<String, String> mRouteSessionMap = new HashMap<>();
private int mNextSessionId = 1000;
private void initializeRoutes() {
@@ -177,7 +177,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
maybeDeselectRoute(routeId);
final int sessionId = mNextSessionId;
final String sessionId = String.valueOf(mNextSessionId);
mNextSessionId++;
mRoutes.put(routeId, new MediaRoute2Info.Builder(route)
@@ -196,7 +196,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
@Override
public void onDestroySession(int sessionId, RouteSessionInfo lastSessionInfo) {
public void onDestroySession(String sessionId, RouteSessionInfo lastSessionInfo) {
for (String routeId : lastSessionInfo.getSelectedRoutes()) {
mRouteSessionMap.remove(routeId);
MediaRoute2Info route = mRoutes.get(routeId);
@@ -209,7 +209,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
@Override
public void onSelectRoute(int sessionId, String routeId) {
public void onSelectRoute(String sessionId, String routeId) {
RouteSessionInfo sessionInfo = getSessionInfo(sessionId);
MediaRoute2Info route = mRoutes.get(routeId);
if (route == null || sessionInfo == null) {
@@ -218,7 +218,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
maybeDeselectRoute(routeId);
mRoutes.put(routeId, new MediaRoute2Info.Builder(route)
.setClientPackageName(sessionInfo.getPackageName())
.setClientPackageName(sessionInfo.getClientPackageName())
.build());
mRouteSessionMap.put(routeId, sessionId);
@@ -232,7 +232,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
@Override
public void onDeselectRoute(int sessionId, String routeId) {
public void onDeselectRoute(String sessionId, String routeId) {
RouteSessionInfo sessionInfo = getSessionInfo(sessionId);
MediaRoute2Info route = mRoutes.get(routeId);
@@ -254,7 +254,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
}
@Override
public void onTransferToRoute(int sessionId, String routeId) {
public void onTransferToRoute(String sessionId, String routeId) {
RouteSessionInfo sessionInfo = getSessionInfo(sessionId);
RouteSessionInfo newSessionInfo = new RouteSessionInfo.Builder(sessionInfo)
.clearSelectedRoutes()
@@ -271,7 +271,7 @@ public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService
return;
}
int sessionId = mRouteSessionMap.get(routeId);
String sessionId = mRouteSessionMap.get(routeId);
onDeselectRoute(sessionId, routeId);
}

View File

@@ -400,6 +400,7 @@ public class MediaRouter2Test {
assertTrue(createRouteMap(controller2.getSelectedRoutes()).containsKey(ROUTE_ID2));
assertTrue(TextUtils.equals(TYPE_SAMPLE, controller1.getRouteType()));
assertTrue(TextUtils.equals(TYPE_SAMPLE, controller2.getRouteType()));
} finally {
releaseControllers(createdControllers);
mRouter2.unregisterRouteCallback(routeCallback);
@@ -486,20 +487,21 @@ public class MediaRouter2Test {
public void onSessionInfoChanged(RouteSessionController controller,
RouteSessionInfo oldInfo, RouteSessionInfo newInfo) {
if (onSessionCreatedLatch.getCount() != 0
|| controllers.get(0).getSessionId() != controller.getSessionId()) {
|| !TextUtils.equals(
controllers.get(0).getSessionId(), controller.getSessionId())) {
return;
}
if (onSessionInfoChangedLatchForSelect.getCount() != 0) {
// Check oldInfo
assertEquals(controller.getSessionId(), oldInfo.getSessionId());
assertEquals(controller.getSessionId(), oldInfo.getId());
assertEquals(1, oldInfo.getSelectedRoutes().size());
assertTrue(oldInfo.getSelectedRoutes().contains(ROUTE_ID1));
assertTrue(oldInfo.getSelectableRoutes().contains(
ROUTE_ID4_TO_SELECT_AND_DESELECT));
// Check newInfo
assertEquals(controller.getSessionId(), newInfo.getSessionId());
assertEquals(controller.getSessionId(), newInfo.getId());
assertEquals(2, newInfo.getSelectedRoutes().size());
assertTrue(newInfo.getSelectedRoutes().contains(ROUTE_ID1));
assertTrue(newInfo.getSelectedRoutes().contains(
@@ -510,7 +512,7 @@ public class MediaRouter2Test {
onSessionInfoChangedLatchForSelect.countDown();
} else {
// Check newInfo
assertEquals(controller.getSessionId(), newInfo.getSessionId());
assertEquals(controller.getSessionId(), newInfo.getId());
assertEquals(1, newInfo.getSelectedRoutes().size());
assertTrue(newInfo.getSelectedRoutes().contains(ROUTE_ID1));
assertFalse(newInfo.getSelectedRoutes().contains(
@@ -587,18 +589,19 @@ public class MediaRouter2Test {
public void onSessionInfoChanged(RouteSessionController controller,
RouteSessionInfo oldInfo, RouteSessionInfo newInfo) {
if (onSessionCreatedLatch.getCount() != 0
|| controllers.get(0).getSessionId() != controller.getSessionId()) {
|| !TextUtils.equals(
controllers.get(0).getSessionId(), controller.getSessionId())) {
return;
}
// Check oldInfo
assertEquals(controller.getSessionId(), oldInfo.getSessionId());
assertEquals(controller.getSessionId(), oldInfo.getId());
assertEquals(1, oldInfo.getSelectedRoutes().size());
assertTrue(oldInfo.getSelectedRoutes().contains(ROUTE_ID1));
assertTrue(oldInfo.getTransferrableRoutes().contains(ROUTE_ID5_TO_TRANSFER_TO));
// Check newInfo
assertEquals(controller.getSessionId(), newInfo.getSessionId());
assertEquals(controller.getSessionId(), newInfo.getId());
assertEquals(1, newInfo.getSelectedRoutes().size());
assertFalse(newInfo.getSelectedRoutes().contains(ROUTE_ID1));
assertTrue(newInfo.getSelectedRoutes().contains(ROUTE_ID5_TO_TRANSFER_TO));
@@ -665,7 +668,8 @@ public class MediaRouter2Test {
public void onSessionInfoChanged(RouteSessionController controller,
RouteSessionInfo oldInfo, RouteSessionInfo newInfo) {
if (onSessionCreatedLatch.getCount() != 0
|| controllers.get(0).getSessionId() != controller.getSessionId()) {
|| !TextUtils.equals(
controllers.get(0).getSessionId(), controller.getSessionId())) {
return;
}
onSessionInfoChangedLatch.countDown();

View File

@@ -99,7 +99,7 @@ public class MediaRouterManagerTest {
public static final String TYPE_SPECIAL =
"com.android.mediarouteprovider.TYPE_SPECIAL";
private static final String TYPE_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO";
private static final String TYPE_LIVE_AUDIO = "android.media.intent.route.TYPE_LIVE_AUDIO";
private static final int TIMEOUT_MS = 5000;

View File

@@ -29,6 +29,7 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class RouteSessionTest {
private static final String TEST_SESSION_ID = "test_session_id";
private static final String TEST_PACKAGE_NAME = "com.android.mediaroutertest";
private static final String TEST_CONTROL_CATEGORY = "com.android.mediaroutertest.category";
@@ -36,17 +37,17 @@ public class RouteSessionTest {
@Test
public void testValidity() {
RouteSessionInfo emptyPackageSession = new RouteSessionInfo.Builder(1,
RouteSessionInfo emptyPackageSession = new RouteSessionInfo.Builder(TEST_SESSION_ID,
"",
TEST_CONTROL_CATEGORY)
.addSelectedRoute(TEST_ROUTE_ID1)
.build();
RouteSessionInfo emptyCategorySession = new RouteSessionInfo.Builder(1,
RouteSessionInfo emptyCategorySession = new RouteSessionInfo.Builder(TEST_SESSION_ID,
TEST_PACKAGE_NAME, "")
.addSelectedRoute(TEST_ROUTE_ID1)
.build();
RouteSessionInfo emptySelectedRouteSession = new RouteSessionInfo.Builder(1,
RouteSessionInfo emptySelectedRouteSession = new RouteSessionInfo.Builder(TEST_SESSION_ID,
TEST_PACKAGE_NAME, TEST_CONTROL_CATEGORY)
.build();
@@ -54,9 +55,9 @@ public class RouteSessionTest {
.addSelectedRoute(TEST_ROUTE_ID1)
.build();
assertFalse(emptySelectedRouteSession.isValid());
assertFalse(emptyPackageSession.isValid());
assertFalse(emptyCategorySession.isValid());
assertFalse(emptySelectedRouteSession.isValid());
assertTrue(validSession.isValid());
}
}

View File

@@ -47,11 +47,11 @@ abstract class MediaRoute2Provider {
public abstract void requestCreateSession(String packageName, String routeId,
String routeType, long requestId);
public abstract void releaseSession(int sessionId);
public abstract void releaseSession(String sessionId);
public abstract void selectRoute(int sessionId, String routeId);
public abstract void deselectRoute(int sessionId, String routeId);
public abstract void transferToRoute(int sessionId, String routeId);
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 sendControlRequest(String routeId, Intent request);
public abstract void requestSetVolume(String routeId, int volume);

View File

@@ -86,7 +86,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
}
@Override
public void releaseSession(int sessionId) {
public void releaseSession(String sessionId) {
if (mConnectionReady) {
mActiveConnection.releaseSession(sessionId);
updateBinding();
@@ -94,21 +94,21 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
}
@Override
public void selectRoute(int sessionId, String routeId) {
public void selectRoute(String sessionId, String routeId) {
if (mConnectionReady) {
mActiveConnection.selectRoute(sessionId, routeId);
}
}
@Override
public void deselectRoute(int sessionId, String routeId) {
public void deselectRoute(String sessionId, String routeId) {
if (mConnectionReady) {
mActiveConnection.deselectRoute(sessionId, routeId);
}
}
@Override
public void transferToRoute(int sessionId, String routeId) {
public void transferToRoute(String sessionId, String routeId) {
if (mConnectionReady) {
mActiveConnection.transferToRoute(sessionId, routeId);
}
@@ -302,6 +302,11 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
+ mComponentName);
return;
}
sessionInfo = new RouteSessionInfo.Builder(sessionInfo)
.setProviderId(getUniqueId())
.build();
mCallback.onSessionInfoChanged(this, sessionInfo);
}
@@ -355,7 +360,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
}
}
public void releaseSession(int sessionId) {
public void releaseSession(String sessionId) {
try {
mProvider.releaseSession(sessionId);
} catch (RemoteException ex) {
@@ -363,7 +368,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
}
}
public void selectRoute(int sessionId, String routeId) {
public void selectRoute(String sessionId, String routeId) {
try {
mProvider.selectRoute(sessionId, routeId);
} catch (RemoteException ex) {
@@ -371,7 +376,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
}
}
public void deselectRoute(int sessionId, String routeId) {
public void deselectRoute(String sessionId, String routeId) {
try {
mProvider.deselectRoute(sessionId, routeId);
} catch (RemoteException ex) {
@@ -379,7 +384,7 @@ final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements Serv
}
}
public void transferToRoute(int sessionId, String routeId) {
public void transferToRoute(String sessionId, String routeId) {
try {
mProvider.transferToRoute(sessionId, routeId);
} catch (RemoteException ex) {

View File

@@ -16,6 +16,9 @@
package com.android.server.media;
import static android.media.MediaRouter2Utils.getOriginalId;
import static android.media.MediaRouter2Utils.getProviderId;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import android.annotation.NonNull;
@@ -197,6 +200,9 @@ class MediaRouter2ServiceImpl {
MediaRoute2Info route) {
Objects.requireNonNull(client, "client must not be null");
Objects.requireNonNull(route, "route must not be null");
if (TextUtils.isEmpty(uniqueSessionId)) {
throw new IllegalArgumentException("uniqueSessionId must not be empty");
}
final long token = Binder.clearCallingIdentity();
try {
@@ -213,6 +219,9 @@ class MediaRouter2ServiceImpl {
MediaRoute2Info route) {
Objects.requireNonNull(client, "client must not be null");
Objects.requireNonNull(route, "route must not be null");
if (TextUtils.isEmpty(uniqueSessionId)) {
throw new IllegalArgumentException("uniqueSessionId must not be empty");
}
final long token = Binder.clearCallingIdentity();
try {
@@ -228,6 +237,9 @@ class MediaRouter2ServiceImpl {
MediaRoute2Info route) {
Objects.requireNonNull(client, "client must not be null");
Objects.requireNonNull(route, "route must not be null");
if (TextUtils.isEmpty(uniqueSessionId)) {
throw new IllegalArgumentException("uniqueSessionId must not be empty");
}
final long token = Binder.clearCallingIdentity();
try {
@@ -241,6 +253,9 @@ class MediaRouter2ServiceImpl {
public void releaseSession(IMediaRouter2Client client, String uniqueSessionId) {
Objects.requireNonNull(client, "client must not be null");
if (TextUtils.isEmpty(uniqueSessionId)) {
throw new IllegalArgumentException("uniqueSessionId must not be empty");
}
final long token = Binder.clearCallingIdentity();
try {
@@ -607,7 +622,7 @@ class MediaRouter2ServiceImpl {
}
long uniqueRequestId = toUniqueRequestId(managerRecord.mClientId, requestId);
if (clientRecord != null && managerRecord.mTrusted) {
//TODO: select category properly
//TODO: select route type properly
requestCreateSessionLocked(clientRecord.mClient, route,
route.getRouteTypes().get(0), uniqueRequestId);
}
@@ -1002,8 +1017,7 @@ class MediaRouter2ServiceImpl {
if (provider == null) {
return;
}
provider.selectRoute(RouteSessionInfo.getSessionId(uniqueSessionId),
route.getOriginalId());
provider.selectRoute(getOriginalId(uniqueSessionId), route.getOriginalId());
}
private void deselectRouteOnHandler(@NonNull Client2Record clientRecord,
@@ -1019,8 +1033,7 @@ class MediaRouter2ServiceImpl {
if (provider == null) {
return;
}
provider.deselectRoute(RouteSessionInfo.getSessionId(uniqueSessionId),
route.getOriginalId());
provider.deselectRoute(getOriginalId(uniqueSessionId), route.getOriginalId());
}
private void transferToRouteOnHandler(@NonNull Client2Record clientRecord,
@@ -1036,7 +1049,7 @@ class MediaRouter2ServiceImpl {
if (provider == null) {
return;
}
provider.transferToRoute(RouteSessionInfo.getSessionId(uniqueSessionId),
provider.transferToRoute(getOriginalId(uniqueSessionId),
route.getOriginalId());
}
@@ -1068,9 +1081,9 @@ class MediaRouter2ServiceImpl {
return false;
}
final Integer sessionId = RouteSessionInfo.getSessionId(uniqueSessionId);
final String sessionId = getOriginalId(uniqueSessionId);
if (sessionId == null) {
Slog.w(TAG, "Failed to get int session id from unique session id. "
Slog.w(TAG, "Failed to get original session id from unique session id. "
+ "uniqueSessionId=" + uniqueSessionId);
return false;
}
@@ -1093,14 +1106,14 @@ class MediaRouter2ServiceImpl {
return;
}
final String providerId = RouteSessionInfo.getProviderId(uniqueSessionId);
final String providerId = getProviderId(uniqueSessionId);
if (providerId == null) {
Slog.w(TAG, "Ignoring releasing session with invalid unique session ID. "
+ "uniqueSessionId=" + uniqueSessionId);
return;
}
final Integer sessionId = RouteSessionInfo.getSessionId(uniqueSessionId);
final String sessionId = getOriginalId(uniqueSessionId);
if (sessionId == null) {
Slog.w(TAG, "Ignoring releasing session with invalid unique session ID. "
+ "uniqueSessionId=" + uniqueSessionId + " providerId=" + providerId);
@@ -1146,15 +1159,15 @@ class MediaRouter2ServiceImpl {
}
String originalRouteId = matchingRequest.mRoute.getId();
String originalCategory = matchingRequest.mRouteType;
String originalRouteType = matchingRequest.mRouteType;
Client2Record client2Record = matchingRequest.mClientRecord;
if (!sessionInfo.getSelectedRoutes().contains(originalRouteId)
|| !TextUtils.equals(originalCategory,
|| !TextUtils.equals(originalRouteType,
sessionInfo.getRouteType())) {
Slog.w(TAG, "Created session doesn't match the original request."
+ " originalRouteId=" + originalRouteId
+ ", originalCategory=" + originalCategory + ", requestId=" + requestId
+ ", originalRouteType=" + originalRouteType + ", requestId=" + requestId
+ ", sessionInfo=" + sessionInfo);
notifySessionCreationFailed(matchingRequest.mClientRecord,
toClientRequestId(requestId));
@@ -1164,41 +1177,34 @@ class MediaRouter2ServiceImpl {
// Succeeded
notifySessionCreated(matchingRequest.mClientRecord,
sessionInfo, toClientRequestId(requestId));
mSessionToClientMap.put(sessionInfo.getUniqueSessionId(), client2Record);
mSessionToClientMap.put(sessionInfo.getId(), client2Record);
// TODO: Tell managers for the session creation
}
private void onSessionInfoChangedOnHandler(@NonNull MediaRoute2Provider provider,
@NonNull RouteSessionInfo sessionInfo) {
RouteSessionInfo sessionInfoWithProviderId = new RouteSessionInfo.Builder(sessionInfo)
.setProviderId(provider.getUniqueId())
.build();
Client2Record client2Record = mSessionToClientMap.get(
sessionInfoWithProviderId.getUniqueSessionId());
sessionInfo.getId());
if (client2Record == null) {
Slog.w(TAG, "No matching client found for session=" + sessionInfoWithProviderId);
Slog.w(TAG, "No matching client found for session=" + sessionInfo);
// TODO: Tell managers for the session update
return;
}
notifySessionInfoChanged(client2Record, sessionInfoWithProviderId);
notifySessionInfoChanged(client2Record, sessionInfo);
// TODO: Tell managers for the session update
}
private void onSessionReleasedOnHandler(@NonNull MediaRoute2Provider provider,
@NonNull RouteSessionInfo sessionInfo) {
RouteSessionInfo sessionInfoWithProviderId = new RouteSessionInfo.Builder(sessionInfo)
.setProviderId(provider.getUniqueId())
.build();
Client2Record client2Record = mSessionToClientMap.get(
sessionInfoWithProviderId.getUniqueSessionId());
Client2Record client2Record = mSessionToClientMap.get(sessionInfo.getId());
if (client2Record == null) {
Slog.w(TAG, "No matching client found for session=" + sessionInfoWithProviderId);
Slog.w(TAG, "No matching client found for session=" + sessionInfo);
// TODO: Tell managers for the session release
return;
}
notifySessionReleased(client2Record, sessionInfoWithProviderId);
notifySessionReleased(client2Record, sessionInfo);
// TODO: Tell managers for the session release
}

View File

@@ -48,8 +48,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
static final String BLUETOOTH_ROUTE_ID = "BLUETOOTH_ROUTE";
// TODO: Move these to a proper place
public static final String CATEGORY_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO";
public static final String CATEGORY_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO";
public static final String TYPE_LIVE_AUDIO = "android.media.intent.route.TYPE_LIVE_AUDIO";
public static final String TYPE_LIVE_VIDEO = "android.media.intent.route.TYPE_LIVE_VIDEO";
private final AudioManager mAudioManager;
private final IAudioService mAudioService;
@@ -97,22 +97,22 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
}
@Override
public void releaseSession(int sessionId) {
public void releaseSession(String sessionId) {
// Do nothing
}
@Override
public void selectRoute(int sessionId, String routeId) {
public void selectRoute(String sessionId, String routeId) {
//TODO: implement method
}
@Override
public void deselectRoute(int sessionId, String routeId) {
public void deselectRoute(String sessionId, String routeId) {
//TODO: implement method
}
@Override
public void transferToRoute(int sessionId, String routeId) {
public void transferToRoute(String sessionId, String routeId) {
//TODO: implement method
}
@@ -141,8 +141,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
: MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
.setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
.setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
.addRouteType(CATEGORY_LIVE_AUDIO)
.addRouteType(CATEGORY_LIVE_VIDEO)
.addRouteType(TYPE_LIVE_AUDIO)
.addRouteType(TYPE_LIVE_VIDEO)
.build();
AudioRoutesInfo newAudioRoutes = null;
@@ -181,8 +181,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
: MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
.setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
.setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
.addRouteType(CATEGORY_LIVE_AUDIO)
.addRouteType(CATEGORY_LIVE_VIDEO)
.addRouteType(TYPE_LIVE_AUDIO)
.addRouteType(TYPE_LIVE_VIDEO)
.build();
if (!TextUtils.equals(newRoutes.bluetoothName, mCurAudioRoutesInfo.bluetoothName)) {
@@ -193,7 +193,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
mCurAudioRoutesInfo.bluetoothName)
.setDescription(mContext.getResources().getText(
R.string.bluetooth_a2dp_audio_route_name).toString())
.addRouteType(CATEGORY_LIVE_AUDIO)
.addRouteType(TYPE_LIVE_AUDIO)
.build();
} else {
mBluetoothA2dpRoute = null;