[go: nahoru, domu]

blob: e053d4f43cce248df35da25e338a65ef9f0303a1 [file] [log] [blame]
/*
* Copyright (C) 2013 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 androidx.mediarouter.media;
import static androidx.annotation.RestrictTo.Scope.LIBRARY;
import android.annotation.SuppressLint;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.media.RouteDiscoveryPreference;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Describes the properties of a route.
* <p>
* Each route is uniquely identified by an opaque id string. This token
* may take any form as long as it is unique within the media route provider.
* </p><p>
* This object is immutable once created using a {@link Builder} instance.
* </p>
*/
public final class MediaRouteDescriptor {
static final String KEY_ID = "id";
static final String KEY_GROUP_MEMBER_IDS = "groupMemberIds";
static final String KEY_NAME = "name";
static final String KEY_DESCRIPTION = "status";
static final String KEY_ICON_URI = "iconUri";
static final String KEY_ENABLED = "enabled";
static final String IS_DYNAMIC_GROUP_ROUTE = "isDynamicGroupRoute";
static final String KEY_CONNECTING = "connecting";
static final String KEY_CONNECTION_STATE = "connectionState";
static final String KEY_CONTROL_FILTERS = "controlFilters";
static final String KEY_PLAYBACK_TYPE = "playbackType";
static final String KEY_PLAYBACK_STREAM = "playbackStream";
static final String KEY_DEVICE_TYPE = "deviceType";
static final String KEY_VOLUME = "volume";
static final String KEY_VOLUME_MAX = "volumeMax";
static final String KEY_VOLUME_HANDLING = "volumeHandling";
static final String KEY_PRESENTATION_DISPLAY_ID = "presentationDisplayId";
static final String KEY_EXTRAS = "extras";
static final String KEY_CAN_DISCONNECT = "canDisconnect";
static final String KEY_SETTINGS_INTENT = "settingsIntent";
static final String KEY_MIN_CLIENT_VERSION = "minClientVersion";
static final String KEY_MAX_CLIENT_VERSION = "maxClientVersion";
static final String KEY_DEDUPLICATION_IDS = "deduplicationIds";
static final String KEY_IS_VISIBILITY_PUBLIC = "isVisibilityPublic";
static final String KEY_ALLOWED_PACKAGES = "allowedPackages";
final Bundle mBundle;
MediaRouteDescriptor(Bundle bundle) {
mBundle = bundle;
}
/**
* Gets the unique id of the route.
* <p>
* The route id associated with a route descriptor functions as a stable
* identifier for the route and must be unique among all routes offered
* by the provider.
* </p>
*/
@NonNull
public String getId() {
return mBundle.getString(KEY_ID);
}
/**
* Gets the group member ids of the route.
* <p>
* A route descriptor that has one or more group member route ids
* represents a route group. A member route may belong to another group.
* </p>
*/
@RestrictTo(LIBRARY)
@NonNull
public List<String> getGroupMemberIds() {
if (!mBundle.containsKey(KEY_GROUP_MEMBER_IDS)) {
return new ArrayList<>();
}
return new ArrayList<>(mBundle.getStringArrayList(KEY_GROUP_MEMBER_IDS));
}
/**
* Gets the user-visible name of the route.
* <p>
* The route name identifies the destination represented by the route.
* It may be a user-supplied name, an alias, or device serial number.
* </p>
*/
@NonNull
public String getName() {
return mBundle.getString(KEY_NAME);
}
/**
* Gets the user-visible description of the route.
* <p>
* The route description describes the kind of destination represented by the route.
* It may be a user-supplied string, a model number or brand of device.
* </p>
*/
@Nullable
public String getDescription() {
return mBundle.getString(KEY_DESCRIPTION);
}
/**
* Gets the URI of the icon representing this route.
* <p>
* This icon will be used in picker UIs if available.
* </p>
*/
@Nullable
public Uri getIconUri() {
String iconUri = mBundle.getString(KEY_ICON_URI);
return iconUri == null ? null : Uri.parse(iconUri);
}
/**
* Gets whether the route is enabled.
*/
public boolean isEnabled() {
return mBundle.getBoolean(KEY_ENABLED, true);
}
/**
* Returns if this route is a dynamic group route.
* <p>
* {@link MediaRouteProvider} creates a dynamic group route when
* {@link MediaRouteProvider#onCreateDynamicGroupRouteController(String)} is called.
* It happens when a single route or a single static group is selected.
* </p>
* <p>
* If a single device or a static group is selected, the associated dynamic group route
* should not be seen by any client app because there is already one for the device.
* After user added more devices into the session, it should be seen by the client app.
* The provider can treat this by not setting the media intent for the dynamic group route
* if it contains only one member.
* </p>>
* @return {@code true} if this route is a dynamic group route.
*/
public boolean isDynamicGroupRoute() {
return mBundle.getBoolean(IS_DYNAMIC_GROUP_ROUTE, false);
}
/**
* Gets whether the route is connecting.
* @deprecated Use {@link #getConnectionState} instead
*/
@Deprecated
public boolean isConnecting() {
return mBundle.getBoolean(KEY_CONNECTING, false);
}
/**
* Gets the connection state of the route.
*
* @return The connection state of this route:
* {@link MediaRouter.RouteInfo#CONNECTION_STATE_DISCONNECTED},
* {@link MediaRouter.RouteInfo#CONNECTION_STATE_CONNECTING}, or
* {@link MediaRouter.RouteInfo#CONNECTION_STATE_CONNECTED}.
*/
public int getConnectionState() {
return mBundle.getInt(KEY_CONNECTION_STATE,
MediaRouter.RouteInfo.CONNECTION_STATE_DISCONNECTED);
}
/**
* Gets whether the route can be disconnected without stopping playback.
* <p>
* The route can normally be disconnected without stopping playback when
* the destination device on the route is connected to two or more source
* devices. The route provider should update the route immediately when the
* number of connected devices changes.
* </p><p>
* To specify that the route should disconnect without stopping use
* {@link MediaRouter#unselect(int)} with
* {@link MediaRouter#UNSELECT_REASON_DISCONNECTED}.
* </p>
*/
public boolean canDisconnectAndKeepPlaying() {
return mBundle.getBoolean(KEY_CAN_DISCONNECT, false);
}
/**
* Gets an {@link IntentSender} for starting a settings activity for this
* route. The activity may have specific route settings or general settings
* for the connected device or route provider.
*
* @return An {@link IntentSender} to start a settings activity.
*/
@Nullable
public IntentSender getSettingsActivity() {
return mBundle.getParcelable(KEY_SETTINGS_INTENT);
}
/**
* Gets the route's {@link MediaControlIntent media control intent} filters.
*/
@NonNull
public List<IntentFilter> getControlFilters() {
if (!mBundle.containsKey(KEY_CONTROL_FILTERS)) {
return new ArrayList<>();
}
return new ArrayList<>(mBundle.getParcelableArrayList(KEY_CONTROL_FILTERS));
}
/**
* Gets the type of playback associated with this route.
*
* @return The type of playback associated with this route:
* {@link MediaRouter.RouteInfo#PLAYBACK_TYPE_LOCAL} or
* {@link MediaRouter.RouteInfo#PLAYBACK_TYPE_REMOTE}.
*/
public int getPlaybackType() {
return mBundle.getInt(KEY_PLAYBACK_TYPE, MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE);
}
/**
* Gets the route's playback stream.
*/
public int getPlaybackStream() {
return mBundle.getInt(KEY_PLAYBACK_STREAM, -1);
}
/**
* Gets the type of the receiver device associated with this route.
*
* @return The type of the receiver device associated with this route.
*/
@MediaRouter.RouteInfo.DeviceType
public int getDeviceType() {
return mBundle.getInt(KEY_DEVICE_TYPE);
}
/**
* Gets the route's current volume, or 0 if unknown.
*/
public int getVolume() {
return mBundle.getInt(KEY_VOLUME);
}
/**
* Gets the route's maximum volume, or 0 if unknown.
*/
public int getVolumeMax() {
return mBundle.getInt(KEY_VOLUME_MAX);
}
/**
* Gets information about how volume is handled on the route.
*
* @return How volume is handled on the route:
* {@link MediaRouter.RouteInfo#PLAYBACK_VOLUME_FIXED} or
* {@link MediaRouter.RouteInfo#PLAYBACK_VOLUME_VARIABLE}.
*/
public int getVolumeHandling() {
return mBundle.getInt(KEY_VOLUME_HANDLING,
MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED);
}
/**
* Gets the route's deduplication ids.
*
* <p>Two routes are considered to come from the same receiver device if any of their respective
* deduplication ids match.
*/
@NonNull
public Set<String> getDeduplicationIds() {
ArrayList<String> deduplicationIds = mBundle.getStringArrayList(KEY_DEDUPLICATION_IDS);
return deduplicationIds != null
? Collections.unmodifiableSet(new HashSet<>(deduplicationIds))
: Collections.emptySet();
}
/**
* Gets the route's presentation display id, or -1 if none.
*/
public int getPresentationDisplayId() {
return mBundle.getInt(
KEY_PRESENTATION_DISPLAY_ID, MediaRouter.RouteInfo.PRESENTATION_DISPLAY_ID_NONE);
}
/**
* Gets a bundle of extras for this route descriptor.
* The extras will be ignored by the media router but they may be used
* by applications.
*/
@Nullable
public Bundle getExtras() {
return mBundle.getBundle(KEY_EXTRAS);
}
/**
* Gets the minimum client version required for this route.
*/
@RestrictTo(LIBRARY)
public int getMinClientVersion() {
return mBundle.getInt(KEY_MIN_CLIENT_VERSION,
MediaRouteProviderProtocol.CLIENT_VERSION_START);
}
/**
* Gets the maximum client version required for this route.
*/
@RestrictTo(LIBRARY)
public int getMaxClientVersion() {
return mBundle.getInt(KEY_MAX_CLIENT_VERSION, Integer.MAX_VALUE);
}
/**
* Gets whether the route visibility is public or not.
*/
public boolean isVisibilityPublic() {
return mBundle.getBoolean(KEY_IS_VISIBILITY_PUBLIC, /* defaultValue= */ true);
}
/**
* Gets the set of allowed packages which are able to see the route or an empty set if only
* the route provider's package is allowed to see this route. This applies only when
* {@link #isVisibilityPublic} returns {@code false}.
*/
@NonNull
public Set<String> getAllowedPackages() {
if (!mBundle.containsKey(KEY_ALLOWED_PACKAGES)) {
return new HashSet<>();
}
return new HashSet<>(mBundle.getStringArrayList(KEY_ALLOWED_PACKAGES));
}
/**
* Returns true if the route descriptor has all of the required fields.
*/
public boolean isValid() {
if (TextUtils.isEmpty(getId())
|| TextUtils.isEmpty(getName())
|| getControlFilters().contains(null)) {
return false;
}
return true;
}
@NonNull
@Override
public String toString() {
return "MediaRouteDescriptor{ "
+ "id=" + getId()
+ ", groupMemberIds=" + getGroupMemberIds()
+ ", name=" + getName()
+ ", description=" + getDescription()
+ ", iconUri=" + getIconUri()
+ ", isEnabled=" + isEnabled()
+ ", connectionState=" + getConnectionState()
+ ", controlFilters=" + Arrays.toString(getControlFilters().toArray())
+ ", playbackType=" + getPlaybackType()
+ ", playbackStream=" + getPlaybackStream()
+ ", deviceType=" + getDeviceType()
+ ", volume=" + getVolume()
+ ", volumeMax=" + getVolumeMax()
+ ", volumeHandling=" + getVolumeHandling()
+ ", presentationDisplayId=" + getPresentationDisplayId()
+ ", extras=" + getExtras()
+ ", isValid=" + isValid()
+ ", minClientVersion=" + getMinClientVersion()
+ ", maxClientVersion=" + getMaxClientVersion()
+ ", isVisibilityPublic=" + isVisibilityPublic()
+ ", allowedPackages=" + Arrays.toString(getAllowedPackages().toArray())
+ " }";
}
/**
* Converts this object to a bundle for serialization.
*
* @return The contents of the object represented as a bundle.
*/
@NonNull
public Bundle asBundle() {
return mBundle;
}
/**
* Creates an instance from a bundle.
*
* @param bundle The bundle, or null if none.
* @return The new instance, or null if the bundle was null.
*/
@Nullable
public static MediaRouteDescriptor fromBundle(@Nullable Bundle bundle) {
return bundle != null ? new MediaRouteDescriptor(bundle) : null;
}
/**
* Builder for {@link MediaRouteDescriptor media route descriptors}.
*/
public static final class Builder {
private final Bundle mBundle;
private List<String> mGroupMemberIds = new ArrayList<>();
private List<IntentFilter> mControlFilters = new ArrayList<>();
private Set<String> mAllowedPackages = new HashSet<>();
/**
* Creates a media route descriptor builder.
*
* @param id The unique id of the route.
* @param name The user-visible name of the route.
*/
public Builder(@NonNull String id, @NonNull String name) {
mBundle = new Bundle();
setId(id);
setName(name);
}
/**
* Creates a media route descriptor builder whose initial contents are
* copied from an existing descriptor.
*/
public Builder(@NonNull MediaRouteDescriptor descriptor) {
if (descriptor == null) {
throw new IllegalArgumentException("descriptor must not be null");
}
mBundle = new Bundle(descriptor.mBundle);
mGroupMemberIds = descriptor.getGroupMemberIds();
mControlFilters = descriptor.getControlFilters();
mAllowedPackages = descriptor.getAllowedPackages();
}
/**
* Sets the unique id of the route.
* <p>
* The route id associated with a route descriptor functions as a stable
* identifier for the route and must be unique among all routes offered
* by the provider.
* </p>
*/
@NonNull
public Builder setId(@NonNull String id) {
if (id == null) {
throw new NullPointerException("id must not be null");
}
mBundle.putString(KEY_ID, id);
return this;
}
/**
* Clears the group member IDs of the route.
*/
@RestrictTo(LIBRARY)
@NonNull
public Builder clearGroupMemberIds() {
mGroupMemberIds.clear();
return this;
}
/**
* Adds a group member id of the route.
* <p>
* A route descriptor that has one or more group member route ids
* represents a route group. A member route may belong to another group.
* </p>
*/
@RestrictTo(LIBRARY)
@NonNull
public Builder addGroupMemberId(@NonNull String groupMemberId) {
if (TextUtils.isEmpty(groupMemberId)) {
throw new IllegalArgumentException("groupMemberId must not be empty");
}
if (!mGroupMemberIds.contains(groupMemberId)) {
mGroupMemberIds.add(groupMemberId);
}
return this;
}
/**
* Adds a list of group member ids of the route.
* <p>
* A route descriptor that has one or more group member route ids
* represents a route group. A member route may belong to another group.
* </p>
*/
@RestrictTo(LIBRARY)
@NonNull
public Builder addGroupMemberIds(@NonNull Collection<String> groupMemberIds) {
if (groupMemberIds == null) {
throw new IllegalArgumentException("groupMemberIds must not be null");
}
if (!groupMemberIds.isEmpty()) {
for (String groupMemberId : groupMemberIds) {
addGroupMemberId(groupMemberId);
}
}
return this;
}
/**
* Removes a group member id from the route's member list.
* <p>
* A route descriptor that has one or more group member route ids
* represents a route group. A member route may belong to another group.
* </p>
*/
@RestrictTo(LIBRARY)
@NonNull
public Builder removeGroupMemberId(@NonNull String memberRouteId) {
if (TextUtils.isEmpty(memberRouteId)) {
throw new IllegalArgumentException("memberRouteId must not be empty");
}
mGroupMemberIds.remove(memberRouteId);
return this;
}
/**
* Sets the user-visible name of the route.
* <p>
* The route name identifies the destination represented by the route.
* It may be a user-supplied name, an alias, or device serial number.
* </p>
*/
@NonNull
public Builder setName(@NonNull String name) {
if (name == null) {
throw new NullPointerException("name must not be null");
}
mBundle.putString(KEY_NAME, name);
return this;
}
/**
* Sets the user-visible description of the route.
* <p>
* The route description describes the kind of destination represented by the route.
* It may be a user-supplied string, a model number or brand of device.
* </p>
*/
@NonNull
public Builder setDescription(@Nullable String description) {
mBundle.putString(KEY_DESCRIPTION, description);
return this;
}
/**
* Sets the URI of the icon representing this route.
* <p>
* This icon will be used in picker UIs if available.
* </p><p>
* The URI must be one of the following formats:
* <ul>
* <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
* <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
* </li>
* <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
* </ul>
* </p>
*/
@NonNull
public Builder setIconUri(@NonNull Uri iconUri) {
if (iconUri == null) {
throw new IllegalArgumentException("iconUri must not be null");
}
mBundle.putString(KEY_ICON_URI, iconUri.toString());
return this;
}
/**
* Sets whether the route is enabled.
* <p>
* Disabled routes represent routes that a route provider knows about, such as paired
* Wifi Display receivers, but that are not currently available for use.
* </p>
*/
@NonNull
public Builder setEnabled(boolean enabled) {
mBundle.putBoolean(KEY_ENABLED, enabled);
return this;
}
/**
* Sets whether the route is a dynamic group route.
* @see #isDynamicGroupRoute()
*/
@NonNull
public Builder setIsDynamicGroupRoute(boolean isDynamicGroupRoute) {
mBundle.putBoolean(IS_DYNAMIC_GROUP_ROUTE, isDynamicGroupRoute);
return this;
}
/**
* Sets whether the route is in the process of connecting and is not yet
* ready for use.
* @deprecated Use {@link #setConnectionState} instead.
*/
@Deprecated
@NonNull
public Builder setConnecting(boolean connecting) {
mBundle.putBoolean(KEY_CONNECTING, connecting);
return this;
}
/**
* Sets the route's connection state.
*
* @param connectionState The connection state of the route:
* {@link MediaRouter.RouteInfo#CONNECTION_STATE_DISCONNECTED},
* {@link MediaRouter.RouteInfo#CONNECTION_STATE_CONNECTING}, or
* {@link MediaRouter.RouteInfo#CONNECTION_STATE_CONNECTED}.
*/
@NonNull
public Builder setConnectionState(int connectionState) {
mBundle.putInt(KEY_CONNECTION_STATE, connectionState);
return this;
}
/**
* Sets whether the route can be disconnected without stopping playback.
*/
@NonNull
public Builder setCanDisconnect(boolean canDisconnect) {
mBundle.putBoolean(KEY_CAN_DISCONNECT, canDisconnect);
return this;
}
/**
* Sets an intent sender for launching the settings activity for this
* route.
*/
@NonNull
public Builder setSettingsActivity(@Nullable IntentSender is) {
mBundle.putParcelable(KEY_SETTINGS_INTENT, is);
return this;
}
/**
* Clears {@link MediaControlIntent media control intent} filters for the route.
*/
@NonNull
public Builder clearControlFilters() {
mControlFilters.clear();
return this;
}
/**
* Adds a {@link MediaControlIntent media control intent} filter for the route.
*/
@NonNull
public Builder addControlFilter(@NonNull IntentFilter filter) {
if (filter == null) {
throw new IllegalArgumentException("filter must not be null");
}
if (!mControlFilters.contains(filter)) {
mControlFilters.add(filter);
}
return this;
}
/**
* Adds a list of {@link MediaControlIntent media control intent} filters for the route.
*/
@NonNull
public Builder addControlFilters(@NonNull Collection<IntentFilter> filters) {
if (filters == null) {
throw new IllegalArgumentException("filters must not be null");
}
if (!filters.isEmpty()) {
for (IntentFilter filter : filters) {
if (filter != null) {
addControlFilter(filter);
}
}
}
return this;
}
/**
* Sets the route's playback type.
*
* @param playbackType The playback type of the route:
* {@link MediaRouter.RouteInfo#PLAYBACK_TYPE_LOCAL} or
* {@link MediaRouter.RouteInfo#PLAYBACK_TYPE_REMOTE}.
*/
@NonNull
public Builder setPlaybackType(int playbackType) {
mBundle.putInt(KEY_PLAYBACK_TYPE, playbackType);
return this;
}
/**
* Sets the route's playback stream.
*/
@NonNull
public Builder setPlaybackStream(int playbackStream) {
mBundle.putInt(KEY_PLAYBACK_STREAM, playbackStream);
return this;
}
/**
* Sets the route's receiver device type.
*
* @param deviceType The type of the receiver device.
*/
@NonNull
public Builder setDeviceType(@MediaRouter.RouteInfo.DeviceType int deviceType) {
mBundle.putInt(KEY_DEVICE_TYPE, deviceType);
return this;
}
/**
* Sets the route's current volume, or 0 if unknown.
*/
@NonNull
public Builder setVolume(int volume) {
mBundle.putInt(KEY_VOLUME, volume);
return this;
}
/**
* Sets the route's maximum volume, or 0 if unknown.
*/
@NonNull
public Builder setVolumeMax(int volumeMax) {
mBundle.putInt(KEY_VOLUME_MAX, volumeMax);
return this;
}
/**
* Sets the route's volume handling.
*
* @param volumeHandling how volume is handled on the route:
* {@link MediaRouter.RouteInfo#PLAYBACK_VOLUME_FIXED} or
* {@link MediaRouter.RouteInfo#PLAYBACK_VOLUME_VARIABLE}.
*/
@NonNull
public Builder setVolumeHandling(int volumeHandling) {
mBundle.putInt(KEY_VOLUME_HANDLING, volumeHandling);
return this;
}
/**
* Sets the route's deduplication ids.
*
* <p>Two routes are considered to come from the same receiver device if any of their
* respective deduplication ids match.
*
* @param deduplicationIds A set of strings that uniquely identify the receiver device that
* backs this route.
*/
@NonNull
public Builder setDeduplicationIds(@NonNull Set<String> deduplicationIds) {
mBundle.putStringArrayList(KEY_DEDUPLICATION_IDS, new ArrayList<>(deduplicationIds));
return this;
}
/**
* Sets the route's presentation display id, or -1 if none.
*/
@NonNull
public Builder setPresentationDisplayId(int presentationDisplayId) {
mBundle.putInt(KEY_PRESENTATION_DISPLAY_ID, presentationDisplayId);
return this;
}
/**
* Sets a bundle of extras for this route descriptor.
* The extras will be ignored by the media router but they may be used
* by applications.
*/
@NonNull
public Builder setExtras(@Nullable Bundle extras) {
if (extras == null) {
mBundle.putBundle(KEY_EXTRAS, null);
} else {
mBundle.putBundle(KEY_EXTRAS, new Bundle(extras));
}
return this;
}
/**
* Sets the route's minimum client version.
* A router whose version is lower than this will not be able to connect to this route.
*/
@RestrictTo(LIBRARY)
@NonNull
public Builder setMinClientVersion(int minVersion) {
mBundle.putInt(KEY_MIN_CLIENT_VERSION, minVersion);
return this;
}
/**
* Sets the route's maximum client version.
* A router whose version is higher than this will not be able to connect to this route.
*/
@RestrictTo(LIBRARY)
@NonNull
public Builder setMaxClientVersion(int maxVersion) {
mBundle.putInt(KEY_MAX_CLIENT_VERSION, maxVersion);
return this;
}
/**
* Sets the visibility of this route to public.
*
* <p>By default, unless you call {@link #setVisibilityRestricted}, the new route will be
* public.
*
* <p>Public routes are visible to any application with a matching {@link
* RouteDiscoveryPreference#getPreferredFeatures feature}.
*
* <p>Calls to this method override previous calls to {@link #setVisibilityPublic} and
* {@link #setVisibilityRestricted}.
*/
@NonNull
@SuppressLint({"MissingGetterMatchingBuilder"})
public Builder setVisibilityPublic() {
mBundle.putBoolean(KEY_IS_VISIBILITY_PUBLIC, true);
mAllowedPackages.clear();
return this;
}
/**
* Sets the visibility of this route to restricted.
*
* <p>Routes with restricted visibility are only visible to its publisher application and
* applications whose package name is included in the provided {@code allowedPackages} set
* with a matching {@link RouteDiscoveryPreference#getPreferredFeatures feature}.
*
* <p>Calls to this method override previous calls to {@link #setVisibilityPublic} and
* {@link #setVisibilityRestricted}.
*
* @see #setVisibilityPublic
* @param allowedPackages set of package names which are allowed to see this route.
*/
@NonNull
@SuppressLint({"MissingGetterMatchingBuilder"})
public Builder setVisibilityRestricted(@NonNull Set<String> allowedPackages) {
mBundle.putBoolean(KEY_IS_VISIBILITY_PUBLIC, false);
mAllowedPackages = new HashSet<>(allowedPackages);
return this;
}
/**
* Builds the {@link MediaRouteDescriptor media route descriptor}.
*/
@NonNull
public MediaRouteDescriptor build() {
mBundle.putParcelableArrayList(KEY_CONTROL_FILTERS, new ArrayList<>(mControlFilters));
mBundle.putStringArrayList(KEY_GROUP_MEMBER_IDS, new ArrayList<>(mGroupMemberIds));
mBundle.putStringArrayList(KEY_ALLOWED_PACKAGES, new ArrayList<>(mAllowedPackages));
return new MediaRouteDescriptor(mBundle);
}
}
}