| /* |
| * 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.net.Uri; |
| import android.os.Bundle; |
| import android.text.TextUtils; |
| |
| import androidx.annotation.RestrictTo; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.List; |
| |
| /** |
| * 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"; |
| |
| final Bundle mBundle; |
| List<String> mGroupMemberIds; |
| List<IntentFilter> mControlFilters; |
| |
| 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> |
| */ |
| 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> |
| * @hide |
| */ |
| @RestrictTo(LIBRARY) |
| public List<String> getGroupMemberIds() { |
| ensureGroupMemberIds(); |
| return mGroupMemberIds; |
| } |
| |
| void ensureGroupMemberIds() { |
| if (mGroupMemberIds == null) { |
| mGroupMemberIds = mBundle.getStringArrayList(KEY_GROUP_MEMBER_IDS); |
| if (mGroupMemberIds == null) { |
| mGroupMemberIds = Collections.emptyList(); |
| } |
| } |
| } |
| |
| /** |
| * 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> |
| */ |
| 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> |
| */ |
| 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> |
| */ |
| 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. |
| */ |
| public IntentSender getSettingsActivity() { |
| return mBundle.getParcelable(KEY_SETTINGS_INTENT); |
| } |
| |
| /** |
| * Gets the route's {@link MediaControlIntent media control intent} filters. |
| */ |
| public List<IntentFilter> getControlFilters() { |
| ensureControlFilters(); |
| return mControlFilters; |
| } |
| |
| void ensureControlFilters() { |
| if (mControlFilters == null) { |
| mControlFilters = mBundle.<IntentFilter>getParcelableArrayList(KEY_CONTROL_FILTERS); |
| if (mControlFilters == null) { |
| mControlFilters = Collections.<IntentFilter>emptyList(); |
| } |
| } |
| } |
| |
| /** |
| * 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: |
| * {@link MediaRouter.RouteInfo#DEVICE_TYPE_TV} or |
| * {@link MediaRouter.RouteInfo#DEVICE_TYPE_SPEAKER}. |
| */ |
| 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 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. |
| */ |
| public Bundle getExtras() { |
| return mBundle.getBundle(KEY_EXTRAS); |
| } |
| |
| /** |
| * Gets the minimum client version required for this route. |
| * @hide |
| */ |
| @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. |
| * @hide |
| */ |
| @RestrictTo(LIBRARY) |
| public int getMaxClientVersion() { |
| return mBundle.getInt(KEY_MAX_CLIENT_VERSION, Integer.MAX_VALUE); |
| } |
| |
| /** |
| * Returns true if the route descriptor has all of the required fields. |
| */ |
| public boolean isValid() { |
| ensureControlFilters(); |
| if (TextUtils.isEmpty(getId()) |
| || TextUtils.isEmpty(getName()) |
| || mControlFilters.contains(null)) { |
| return false; |
| } |
| return true; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder result = new StringBuilder(); |
| result.append("MediaRouteDescriptor{ "); |
| result.append("id=").append(getId()); |
| result.append(", groupMemberIds=").append(getGroupMemberIds()); |
| result.append(", name=").append(getName()); |
| result.append(", description=").append(getDescription()); |
| result.append(", iconUri=").append(getIconUri()); |
| result.append(", isEnabled=").append(isEnabled()); |
| result.append(", connectionState=").append(getConnectionState()); |
| result.append(", controlFilters=").append(Arrays.toString(getControlFilters().toArray())); |
| result.append(", playbackType=").append(getPlaybackType()); |
| result.append(", playbackStream=").append(getPlaybackStream()); |
| result.append(", deviceType=").append(getDeviceType()); |
| result.append(", volume=").append(getVolume()); |
| result.append(", volumeMax=").append(getVolumeMax()); |
| result.append(", volumeHandling=").append(getVolumeHandling()); |
| result.append(", presentationDisplayId=").append(getPresentationDisplayId()); |
| result.append(", extras=").append(getExtras()); |
| result.append(", isValid=").append(isValid()); |
| result.append(", minClientVersion=").append(getMinClientVersion()); |
| result.append(", maxClientVersion=").append(getMaxClientVersion()); |
| result.append(" }"); |
| return result.toString(); |
| } |
| |
| /** |
| * Converts this object to a bundle for serialization. |
| * |
| * @return The contents of the object represented as a bundle. |
| */ |
| 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. |
| */ |
| public static MediaRouteDescriptor fromBundle(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 ArrayList<String> mGroupMemberIds; |
| private ArrayList<IntentFilter> mControlFilters; |
| |
| /** |
| * 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(String id, 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(MediaRouteDescriptor descriptor) { |
| if (descriptor == null) { |
| throw new IllegalArgumentException("descriptor must not be null"); |
| } |
| |
| mBundle = new Bundle(descriptor.mBundle); |
| |
| if (!descriptor.getGroupMemberIds().isEmpty()) { |
| mGroupMemberIds = new ArrayList<String>(descriptor.getGroupMemberIds()); |
| } |
| |
| if (!descriptor.getControlFilters().isEmpty()) { |
| mControlFilters = new ArrayList<IntentFilter>(descriptor.mControlFilters); |
| } |
| } |
| |
| /** |
| * 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> |
| */ |
| public Builder setId(String id) { |
| mBundle.putString(KEY_ID, id); |
| return this; |
| } |
| |
| /** |
| * Clears the group member IDs of the route. |
| * @hide |
| */ |
| @RestrictTo(LIBRARY) |
| public Builder clearGroupMemberIds() { |
| if (mGroupMemberIds == null) { |
| mGroupMemberIds = new ArrayList<>(); |
| } else { |
| 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> |
| * @hide |
| */ |
| @RestrictTo(LIBRARY) |
| public Builder addGroupMemberId(String groupMemberId) { |
| if (TextUtils.isEmpty(groupMemberId)) { |
| throw new IllegalArgumentException("groupMemberId must not be empty"); |
| } |
| |
| if (mGroupMemberIds == null) { |
| mGroupMemberIds = new ArrayList<>(); |
| } |
| 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> |
| * @hide |
| */ |
| @RestrictTo(LIBRARY) |
| public Builder addGroupMemberIds(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> |
| * @hide |
| */ |
| @RestrictTo(LIBRARY) |
| public Builder removeGroupMemberId(String memberRouteId) { |
| if (TextUtils.isEmpty(memberRouteId)) { |
| throw new IllegalArgumentException("memberRouteId must not be empty"); |
| } |
| |
| if (mGroupMemberIds != null) { |
| 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> |
| */ |
| public Builder setName(String name) { |
| 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> |
| */ |
| public Builder setDescription(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> |
| */ |
| public Builder setIconUri(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> |
| */ |
| public Builder setEnabled(boolean enabled) { |
| mBundle.putBoolean(KEY_ENABLED, enabled); |
| return this; |
| } |
| |
| /** |
| * Sets whether the route is a dynamic group route. |
| * @see #isDynamicGroupRoute() |
| */ |
| 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 |
| 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}. |
| */ |
| public Builder setConnectionState(int connectionState) { |
| mBundle.putInt(KEY_CONNECTION_STATE, connectionState); |
| return this; |
| } |
| |
| /** |
| * Sets whether the route can be disconnected without stopping playback. |
| */ |
| 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. |
| */ |
| public Builder setSettingsActivity(IntentSender is) { |
| mBundle.putParcelable(KEY_SETTINGS_INTENT, is); |
| return this; |
| } |
| |
| /** |
| * Adds a {@link MediaControlIntent media control intent} filter for the route. |
| */ |
| public Builder addControlFilter(IntentFilter filter) { |
| if (filter == null) { |
| throw new IllegalArgumentException("filter must not be null"); |
| } |
| |
| if (mControlFilters == null) { |
| mControlFilters = new ArrayList<IntentFilter>(); |
| } |
| if (!mControlFilters.contains(filter)) { |
| mControlFilters.add(filter); |
| } |
| return this; |
| } |
| |
| /** |
| * Adds a list of {@link MediaControlIntent media control intent} filters for the route. |
| */ |
| public Builder addControlFilters(Collection<IntentFilter> filters) { |
| if (filters == null) { |
| throw new IllegalArgumentException("filters must not be null"); |
| } |
| |
| if (!filters.isEmpty()) { |
| for (IntentFilter filter : filters) { |
| 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}. |
| */ |
| public Builder setPlaybackType(int playbackType) { |
| mBundle.putInt(KEY_PLAYBACK_TYPE, playbackType); |
| return this; |
| } |
| |
| /** |
| * Sets the route's playback stream. |
| */ |
| public Builder setPlaybackStream(int playbackStream) { |
| mBundle.putInt(KEY_PLAYBACK_STREAM, playbackStream); |
| return this; |
| } |
| |
| /** |
| * Sets the route's receiver device type. |
| * |
| * @param deviceType The receive device type of the route: |
| * {@link MediaRouter.RouteInfo#DEVICE_TYPE_TV} or |
| * {@link MediaRouter.RouteInfo#DEVICE_TYPE_SPEAKER}. |
| */ |
| public Builder setDeviceType(int deviceType) { |
| mBundle.putInt(KEY_DEVICE_TYPE, deviceType); |
| return this; |
| } |
| |
| /** |
| * Sets the route's current volume, or 0 if unknown. |
| */ |
| public Builder setVolume(int volume) { |
| mBundle.putInt(KEY_VOLUME, volume); |
| return this; |
| } |
| |
| /** |
| * Sets the route's maximum volume, or 0 if unknown. |
| */ |
| 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}. |
| */ |
| public Builder setVolumeHandling(int volumeHandling) { |
| mBundle.putInt(KEY_VOLUME_HANDLING, volumeHandling); |
| return this; |
| } |
| |
| /** |
| * Sets the route's presentation display id, or -1 if none. |
| */ |
| 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. |
| */ |
| public Builder setExtras(Bundle extras) { |
| mBundle.putBundle(KEY_EXTRAS, 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. |
| * @hide |
| */ |
| @RestrictTo(LIBRARY) |
| 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. |
| * @hide |
| */ |
| @RestrictTo(LIBRARY) |
| public Builder setMaxClientVersion(int maxVersion) { |
| mBundle.putInt(KEY_MAX_CLIENT_VERSION, maxVersion); |
| return this; |
| } |
| |
| /** |
| * Builds the {@link MediaRouteDescriptor media route descriptor}. |
| */ |
| @SuppressLint("UnknownNullness") |
| public MediaRouteDescriptor build() { |
| if (mControlFilters != null) { |
| mBundle.putParcelableArrayList(KEY_CONTROL_FILTERS, mControlFilters); |
| } |
| if (mGroupMemberIds != null) { |
| mBundle.putStringArrayList(KEY_GROUP_MEMBER_IDS, mGroupMemberIds); |
| } |
| return new MediaRouteDescriptor(mBundle); |
| } |
| } |
| } |