/*
* 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 androidx.mediarouter.media;
import static androidx.annotation.RestrictTo.Scope.LIBRARY;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* MediaRouterParams are used in {@link MediaRouter} to denote routing functionality and UI types.
*/
public class MediaRouterParams {
/**
* A dialog type used for default if not set.
* {@link androidx.mediarouter.app.MediaRouteChooserDialog} and
* {@link androidx.mediarouter.app.MediaRouteControllerDialog} will be shown
*/
public static final int DIALOG_TYPE_DEFAULT = 1;
/**
* A dialog type supporting dynamic group.
* Users can dynamically group and ungroup route devices via this type of route dialog when the
* selected routes are from a {@link MediaRouteProvider} that supports dynamic group.
*/
public static final int DIALOG_TYPE_DYNAMIC_GROUP = 2;
/**
*/
@RestrictTo(LIBRARY)
@IntDef({DIALOG_TYPE_DEFAULT, DIALOG_TYPE_DYNAMIC_GROUP})
@Retention(RetentionPolicy.SOURCE)
public @interface DialogType {}
/**
* Bundle key used for enabling group volume UX. The default value is {@code true}.
* To disable the group volume UX, set the value {@code false}.
*
* <p>TYPE: boolean
*/
public static final String ENABLE_GROUP_VOLUME_UX =
"androidx.mediarouter.media.MediaRouterParams.ENABLE_GROUP_VOLUME_UX";
/**
* Bundle key used for setting the cast icon fixed regardless of its connection state.
*
* <p>TYPE: boolean
*/
@RestrictTo(RestrictTo.Scope.LIBRARY)
public static final String EXTRAS_KEY_FIXED_CAST_ICON =
"androidx.mediarouter.media.MediaRouterParams.FIXED_CAST_ICON";
@DialogType
final int mDialogType;
final boolean mMediaTransferReceiverEnabled;
final boolean mOutputSwitcherEnabled;
final boolean mTransferToLocalEnabled;
final Bundle mExtras;
MediaRouterParams(@NonNull Builder builder) {
mDialogType = builder.mDialogType;
mMediaTransferReceiverEnabled = builder.mMediaTransferEnabled;
mOutputSwitcherEnabled = builder.mOutputSwitcherEnabled;
mTransferToLocalEnabled = builder.mTransferToLocalEnabled;
Bundle extras = builder.mExtras;
mExtras = extras == null ? Bundle.EMPTY : new Bundle(extras);
}
/**
* Gets the media route controller dialog type.
*
* @see Builder#setDialogType(int)
*/
public @DialogType int getDialogType() {
return mDialogType;
}
/**
* Gets whether declared {@link MediaTransferReceiver} is enabled.
*
* @see Builder#setMediaTransferReceiverEnabled(boolean)
*/
public boolean isMediaTransferReceiverEnabled() {
return mMediaTransferReceiverEnabled;
}
/**
* Gets whether the output switcher dialog is enabled.
* <p>
* Note that it always returns {@code false} for Android versions earlier than Android R.
*
* @see Builder#setOutputSwitcherEnabled(boolean)
*/
public boolean isOutputSwitcherEnabled() {
return mOutputSwitcherEnabled;
}
/**
* Returns whether transferring media from remote to local is enabled.
* <p>
* Note that it always returns {@code false} for Android versions earlier than Android R.
*
* @see Builder#setTransferToLocalEnabled(boolean)
*/
public boolean isTransferToLocalEnabled() {
return mTransferToLocalEnabled;
}
/**
*/
@NonNull
@RestrictTo(RestrictTo.Scope.LIBRARY)
public Bundle getExtras() {
return mExtras;
}
/**
* Builder class for {@link MediaRouterParams}.
*/
public static final class Builder {
@DialogType
int mDialogType = DIALOG_TYPE_DEFAULT;
boolean mMediaTransferEnabled = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R;
boolean mOutputSwitcherEnabled;
boolean mTransferToLocalEnabled;
Bundle mExtras;
/**
* Constructor for builder to create {@link MediaRouterParams}.
*/
public Builder() {}
/**
* Constructor for builder to create {@link MediaRouterParams} with existing
* {@link MediaRouterParams} instance.
*
* @param params the existing instance to copy data from.
*/
public Builder(@NonNull MediaRouterParams params) {
if (params == null) {
throw new NullPointerException("params should not be null!");
}
mDialogType = params.mDialogType;
mOutputSwitcherEnabled = params.mOutputSwitcherEnabled;
mTransferToLocalEnabled = params.mTransferToLocalEnabled;
mMediaTransferEnabled = params.mMediaTransferReceiverEnabled;
mExtras = params.mExtras == null ? null : new Bundle(params.mExtras);
}
/**
* Sets the media route controller dialog type. Default value is
* {@link #DIALOG_TYPE_DEFAULT}.
* <p>
* Note that from Android R, output switcher will be used rather than the dialog type set by
* this method if both {@link #setOutputSwitcherEnabled(boolean)} output switcher} and
* {@link MediaTransferReceiver media transfer feature} are enabled.
*
* @param dialogType the dialog type
* @see #setOutputSwitcherEnabled(boolean)
* @see #DIALOG_TYPE_DEFAULT
* @see #DIALOG_TYPE_DYNAMIC_GROUP
*/
@NonNull
public Builder setDialogType(@DialogType int dialogType) {
mDialogType = dialogType;
return this;
}
/**
* Sets whether declared {@link MediaTransferReceiver} is enabled. The default value is
* {@code true}. This method will be no-op for Android versions earlier than Android R and
* it stays {@code false} on devices earlier than Android R.
* <p>
* It can be used to disable media transfer feature when {@link MediaTransferReceiver} is
* declared.
* If set to {@code false}, media transfer feature will be disabled
* even when {@link MediaTransferReceiver} is declared.
* <p>
* It is not recommended to change this value at runtime.
* It could result in getting invalid routes.
* @see MediaTransferReceiver
*/
@NonNull
public Builder setMediaTransferReceiverEnabled(boolean enabled) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
mMediaTransferEnabled = enabled;
}
return this;
}
/**
* Sets whether output switcher dialogs are enabled. This method will be no-op for Android
* versions earlier than Android R. Default value is {@code false}.
* <p>
* If set to {@code true}, and when {@link MediaTransferReceiver media transfer is enabled},
* {@link androidx.mediarouter.app.MediaRouteButton MediaRouteButton} will show output
* switcher when clicked, no matter what type of dialog is set by
* {@link #setDialogType(int)}.
* <p>
* If set to {@code false}, {@link androidx.mediarouter.app.MediaRouteButton
* MediaRouteButton} will show the dialog type which is set by {@link #setDialogType(int)}.
*/
@NonNull
public Builder setOutputSwitcherEnabled(boolean enabled) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
mOutputSwitcherEnabled = enabled;
}
return this;
}
/**
* Enables media can be transferred from remote (e.g. TV) to local (e.g. phone, Bluetooth).
* Apps that enabling this feature should handle the case in their {@link
* MediaRouter.Callback#onRouteSelected(MediaRouter, MediaRouter.RouteInfo, int) callback}
* properly. Default value is {@code false}.
* <p>
* When this is enabled, {@link MediaRouter.Callback#onRouteSelected(MediaRouter,
* MediaRouter.RouteInfo, int, MediaRouter.RouteInfo)} will be called whenever the
* 'remote to local' transfer happens, regardless of the selector provided in
* {@link MediaRouter#addCallback(MediaRouteSelector, MediaRouter.Callback)}.
* <p>
* Note: This method will be no-op for Android versions earlier than Android R. It has
* effect only when {@link MediaTransferReceiver media transfer is enabled}.
*/
@NonNull
public Builder setTransferToLocalEnabled(boolean enabled) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
mTransferToLocalEnabled = enabled;
}
return this;
}
/**
* Set extras. Default value is {@link Bundle#EMPTY} if not set.
*
*/
@RestrictTo(RestrictTo.Scope.LIBRARY)
@NonNull
public Builder setExtras(@Nullable Bundle extras) {
mExtras = (extras == null) ? null : new Bundle(extras);
return this;
}
/**
* Builds the {@link MediaRouterParams} instance.
*/
@NonNull
public MediaRouterParams build() {
return new MediaRouterParams(this);
}
}
}