MediaRoute2Info#isSystemRoute returns true only if it is generated by SystemMediaRoute2Provider. In addition, MediaRouter2 and MediaRouter2Manager always include system routes when getRoutes or getAvailableRoutes is called. This CL will change the behavior of MediaRouter2#getRoutes(), however, without this change, there doesn't seem to be a good way to get system routes. (e.g. how can we support multiple bt routes in xMR?) Bug: 145632124 Test: atest android.media.cts.MediaRoute2InfoTest && atest android.media.cts.MediaRouter2Test && atest android.media.cts.RouteDiscoveryPreferenceTest && atest android.media.cts.RoutingSessionInfoTest && atest mediaroutertest Change-Id: I18ea188b68e6e1335cb0e25c3cc3674910d4d645
242 lines
7.4 KiB
Java
242 lines
7.4 KiB
Java
/*
|
|
* Copyright 2019 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.os.Parcel;
|
|
import android.os.Parcelable;
|
|
import android.text.TextUtils;
|
|
import android.util.ArrayMap;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* Describes the state of a media router provider and the routes that it publishes.
|
|
* @hide
|
|
*/
|
|
public final class MediaRoute2ProviderInfo implements Parcelable {
|
|
@NonNull
|
|
public static final Creator<MediaRoute2ProviderInfo> CREATOR =
|
|
new Creator<MediaRoute2ProviderInfo>() {
|
|
@Override
|
|
public MediaRoute2ProviderInfo createFromParcel(Parcel in) {
|
|
return new MediaRoute2ProviderInfo(in);
|
|
}
|
|
@Override
|
|
public MediaRoute2ProviderInfo[] newArray(int size) {
|
|
return new MediaRoute2ProviderInfo[size];
|
|
}
|
|
};
|
|
|
|
@Nullable
|
|
final String mUniqueId;
|
|
@NonNull
|
|
final ArrayMap<String, MediaRoute2Info> mRoutes;
|
|
|
|
MediaRoute2ProviderInfo(@NonNull Builder builder) {
|
|
Objects.requireNonNull(builder, "builder must not be null.");
|
|
|
|
mUniqueId = builder.mUniqueId;
|
|
mRoutes = builder.mRoutes;
|
|
}
|
|
|
|
MediaRoute2ProviderInfo(@NonNull Parcel src) {
|
|
mUniqueId = src.readString();
|
|
ArrayMap<String, MediaRoute2Info> routes = src.createTypedArrayMap(MediaRoute2Info.CREATOR);
|
|
mRoutes = (routes == null) ? ArrayMap.EMPTY : routes;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the information of the provider and all of it's routes have all
|
|
* of the required fields.
|
|
* @hide
|
|
*/
|
|
public boolean isValid() {
|
|
if (mUniqueId == null) {
|
|
return false;
|
|
}
|
|
final int count = mRoutes.size();
|
|
for (int i = 0; i < count; i++) {
|
|
MediaRoute2Info route = mRoutes.valueAt(i);
|
|
if (route == null || !route.isValid()) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @hide
|
|
*/
|
|
@Nullable
|
|
public String getUniqueId() {
|
|
return mUniqueId;
|
|
}
|
|
|
|
/**
|
|
* Gets the route for the given route id or null if no matching route exists.
|
|
* Please note that id should be original id.
|
|
*
|
|
* @see MediaRoute2Info#getOriginalId()
|
|
*/
|
|
@Nullable
|
|
public MediaRoute2Info getRoute(@NonNull String routeId) {
|
|
return mRoutes.get(Objects.requireNonNull(routeId, "routeId must not be null"));
|
|
}
|
|
|
|
/**
|
|
* Gets the unmodifiable list of all routes that this provider has published.
|
|
*/
|
|
@NonNull
|
|
public Collection<MediaRoute2Info> getRoutes() {
|
|
return mRoutes.values();
|
|
}
|
|
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
|
dest.writeString(mUniqueId);
|
|
dest.writeTypedArrayMap(mRoutes, flags);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
StringBuilder result = new StringBuilder()
|
|
.append("MediaRouteProviderInfo { ")
|
|
.append("uniqueId=").append(mUniqueId)
|
|
.append(", routes=").append(Arrays.toString(getRoutes().toArray()))
|
|
.append(" }");
|
|
return result.toString();
|
|
}
|
|
|
|
/**
|
|
* Builder for {@link MediaRoute2ProviderInfo media route provider info}.
|
|
*/
|
|
public static final class Builder {
|
|
@NonNull
|
|
final ArrayMap<String, MediaRoute2Info> mRoutes;
|
|
String mUniqueId;
|
|
|
|
public Builder() {
|
|
mRoutes = new ArrayMap<>();
|
|
}
|
|
|
|
public Builder(@NonNull MediaRoute2ProviderInfo descriptor) {
|
|
Objects.requireNonNull(descriptor, "descriptor must not be null");
|
|
|
|
mUniqueId = descriptor.mUniqueId;
|
|
mRoutes = new ArrayMap<>(descriptor.mRoutes);
|
|
}
|
|
|
|
/**
|
|
* Sets the unique id of the provider info.
|
|
* <p>
|
|
* The unique id is automatically set by
|
|
* {@link com.android.server.media.MediaRouterService} and used to identify providers.
|
|
* The id set by {@link MediaRoute2ProviderService} will be ignored.
|
|
* </p>
|
|
* @hide
|
|
*/
|
|
@NonNull
|
|
public Builder setUniqueId(@Nullable String uniqueId) {
|
|
if (TextUtils.equals(mUniqueId, uniqueId)) {
|
|
return this;
|
|
}
|
|
mUniqueId = uniqueId;
|
|
|
|
final ArrayMap<String, MediaRoute2Info> newRoutes = new ArrayMap<>();
|
|
for (Map.Entry<String, MediaRoute2Info> entry : mRoutes.entrySet()) {
|
|
MediaRoute2Info routeWithProviderId = new MediaRoute2Info.Builder(entry.getValue())
|
|
.setProviderId(mUniqueId)
|
|
.build();
|
|
newRoutes.put(routeWithProviderId.getOriginalId(), routeWithProviderId);
|
|
}
|
|
|
|
mRoutes.clear();
|
|
mRoutes.putAll(newRoutes);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets whether the provider provides system routes or not
|
|
*/
|
|
@NonNull
|
|
public Builder setSystemRouteProvider(boolean isSystem) {
|
|
int count = mRoutes.size();
|
|
for (int i = 0; i < count; i++) {
|
|
MediaRoute2Info route = mRoutes.valueAt(i);
|
|
if (route.isSystemRoute() != isSystem) {
|
|
mRoutes.setValueAt(i, new MediaRoute2Info.Builder(route)
|
|
.setSystemRoute(isSystem)
|
|
.build());
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Adds a route to the provider
|
|
*/
|
|
@NonNull
|
|
public Builder addRoute(@NonNull MediaRoute2Info route) {
|
|
Objects.requireNonNull(route, "route must not be null");
|
|
|
|
if (mRoutes.containsKey(route.getOriginalId())) {
|
|
throw new IllegalArgumentException("A route with the same id is already added");
|
|
}
|
|
if (mUniqueId != null) {
|
|
mRoutes.put(route.getOriginalId(),
|
|
new MediaRoute2Info.Builder(route).setProviderId(mUniqueId).build());
|
|
} else {
|
|
mRoutes.put(route.getOriginalId(), route);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Adds a list of routes to the provider
|
|
*/
|
|
@NonNull
|
|
public Builder addRoutes(@NonNull Collection<MediaRoute2Info> routes) {
|
|
Objects.requireNonNull(routes, "routes must not be null");
|
|
|
|
if (!routes.isEmpty()) {
|
|
for (MediaRoute2Info route : routes) {
|
|
addRoute(route);
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Builds {@link MediaRoute2ProviderInfo media route provider info}.
|
|
*/
|
|
@NonNull
|
|
public MediaRoute2ProviderInfo build() {
|
|
return new MediaRoute2ProviderInfo(this);
|
|
}
|
|
}
|
|
}
|