Files
frameworks_base/media/java/android/media/MediaRoute2ProviderInfo.java
Kyunglyul Hyun 96d36cee93 MediaRouter: Add MediaRoute2Info#isSystemRoute
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
2020-01-31 17:11:27 +09:00

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);
}
}
}