Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc90e8c1 authored by Santiago Seifert's avatar Santiago Seifert
Browse files

Add routing type flags

Allow providers to indicate the types of routing it supports.

Bug: b/362507305
Test: atest CtsMediaBetterTogetherTestCases CtsMediaHostTestCasts
Flag: com.android.media.flags.enable_mirroring_in_media_router_2
Change-Id: I825b11cb3da20ed4398d81613e5e6bf5f2d3221e
parent 66e33150
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -24854,6 +24854,7 @@ package android.media {
    method @NonNull public String getId();
    method @NonNull public CharSequence getName();
    method @FlaggedApi("com.android.media.flags.enable_built_in_speaker_route_suitability_statuses") public int getSuitabilityStatus();
    method @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public int getSupportedRoutingTypes();
    method public int getType();
    method public int getVolume();
    method public int getVolumeHandling();
@@ -24869,6 +24870,8 @@ package android.media {
    field public static final String FEATURE_REMOTE_AUDIO_PLAYBACK = "android.media.route.feature.REMOTE_AUDIO_PLAYBACK";
    field public static final String FEATURE_REMOTE_PLAYBACK = "android.media.route.feature.REMOTE_PLAYBACK";
    field public static final String FEATURE_REMOTE_VIDEO_PLAYBACK = "android.media.route.feature.REMOTE_VIDEO_PLAYBACK";
    field @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public static final int FLAG_ROUTING_TYPE_REMOTE = 4; // 0x4
    field @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public static final int FLAG_ROUTING_TYPE_SYSTEM_AUDIO = 1; // 0x1
    field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
    field public static final int PLAYBACK_VOLUME_VARIABLE = 1; // 0x1
    field @FlaggedApi("com.android.media.flags.enable_built_in_speaker_route_suitability_statuses") public static final int SUITABILITY_STATUS_NOT_SUITABLE_FOR_TRANSFER = 2; // 0x2
@@ -24919,6 +24922,7 @@ package android.media {
    method @NonNull public android.media.MediaRoute2Info.Builder setExtras(@Nullable android.os.Bundle);
    method @NonNull public android.media.MediaRoute2Info.Builder setIconUri(@Nullable android.net.Uri);
    method @FlaggedApi("com.android.media.flags.enable_built_in_speaker_route_suitability_statuses") @NonNull public android.media.MediaRoute2Info.Builder setSuitabilityStatus(int);
    method @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") @NonNull public android.media.MediaRoute2Info.Builder setSupportedRoutingTypes(int);
    method @NonNull public android.media.MediaRoute2Info.Builder setType(int);
    method @NonNull public android.media.MediaRoute2Info.Builder setVisibilityPublic();
    method @NonNull public android.media.MediaRoute2Info.Builder setVisibilityRestricted(@NonNull java.util.Set<java.lang.String>);
+104 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.media.audio.Flags.FLAG_ENABLE_MULTICHANNEL_GROUP_DEVICE;

import static com.android.media.flags.Flags.FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER;
import static com.android.media.flags.Flags.FLAG_ENABLE_BUILT_IN_SPEAKER_ROUTE_SUITABILITY_STATUSES;
import static com.android.media.flags.Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2;
import static com.android.media.flags.Flags.FLAG_ENABLE_NEW_MEDIA_ROUTE_2_INFO_TYPES;
import static com.android.media.flags.Flags.FLAG_ENABLE_NEW_WIRED_MEDIA_ROUTE_2_INFO_TYPES;

@@ -421,6 +422,51 @@ public final class MediaRoute2Info implements Parcelable {
     */
    public static final int TYPE_GROUP = 2000;

    /** @hide */
    @IntDef(
            prefix = {"ROUTING_TYPE_"},
            value = {
                FLAG_ROUTING_TYPE_SYSTEM_AUDIO,
                FLAG_ROUTING_TYPE_SYSTEM_VIDEO,
                FLAG_ROUTING_TYPE_REMOTE
            },
            flag = true)
    @Retention(RetentionPolicy.SOURCE)
    public @interface RoutingType {}

    /**
     * Indicates that a route supports routing of the system audio.
     *
     * <p>Providers that support this type of routing require the {@link
     * android.Manifest.permission#MODIFY_AUDIO_ROUTING} permission.
     */
    @FlaggedApi(FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
    public static final int FLAG_ROUTING_TYPE_SYSTEM_AUDIO = 1;

    /**
     * Indicates that a route supports routing of the system video.
     *
     * @hide
     */
    // TODO: b/380431086 - Enable this API once we add support for system video routing.
    @FlaggedApi(FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
    public static final int FLAG_ROUTING_TYPE_SYSTEM_VIDEO = 1 << 1;

    /**
     * Indicates that a route supports routing playback to remote routes through control commands.
     *
     * <p>This type of routing does not affect affect this system's audio or video, but instead
     * relies on the device that corresponds to this route to fetch and play the media. It also
     * requires the media app to take care of initializing and controlling playback.
     */
    @FlaggedApi(FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
    public static final int FLAG_ROUTING_TYPE_REMOTE = 1 << 2;

    private static final int FLAG_ROUTING_TYPE_ALL =
            FLAG_ROUTING_TYPE_SYSTEM_AUDIO
                    | FLAG_ROUTING_TYPE_SYSTEM_VIDEO
                    | FLAG_ROUTING_TYPE_REMOTE;

    /**
     * Route feature: Live audio.
     * <p>
@@ -553,6 +599,7 @@ public final class MediaRoute2Info implements Parcelable {
    private final List<String> mFeatures;
    @Type
    private final int mType;
    @RoutingType private final int mRoutingTypeFlags;
    private final boolean mIsSystem;
    private final Uri mIconUri;
    private final CharSequence mDescription;
@@ -576,6 +623,7 @@ public final class MediaRoute2Info implements Parcelable {
        mName = builder.mName;
        mFeatures = builder.mFeatures;
        mType = builder.mType;
        mRoutingTypeFlags = builder.mRoutingTypeFlags;
        mIsSystem = builder.mIsSystem;
        mIconUri = builder.mIconUri;
        mDescription = builder.mDescription;
@@ -600,6 +648,7 @@ public final class MediaRoute2Info implements Parcelable {
        mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
        mFeatures = in.createStringArrayList();
        mType = in.readInt();
        mRoutingTypeFlags = validateRoutingTypeFlags(in.readInt());
        mIsSystem = in.readBoolean();
        mIconUri = in.readParcelable(null, android.net.Uri.class);
        mDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
@@ -660,6 +709,13 @@ public final class MediaRoute2Info implements Parcelable {
        return mType;
    }

    /** Returns the flags that indicate the routing types supported by this route. */
    @RoutingType
    @FlaggedApi(FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
    public int getSupportedRoutingTypes() {
        return mRoutingTypeFlags;
    }

    /**
     * Returns whether the route is a system route or not.
     * <p>
@@ -904,6 +960,7 @@ public final class MediaRoute2Info implements Parcelable {
        pw.println(indent + "mName=" + mName);
        pw.println(indent + "mFeatures=" + mFeatures);
        pw.println(indent + "mType=" + getDeviceTypeString(mType));
        pw.println(indent + "mRoutingTypeFlags=" + getRoutingTypeFlagsString(mRoutingTypeFlags));
        pw.println(indent + "mIsSystem=" + mIsSystem);
        pw.println(indent + "mIconUri=" + mIconUri);
        pw.println(indent + "mDescription=" + mDescription);
@@ -941,6 +998,7 @@ public final class MediaRoute2Info implements Parcelable {
                && Objects.equals(mName, other.mName)
                && Objects.equals(mFeatures, other.mFeatures)
                && (mType == other.mType)
                && (mRoutingTypeFlags == other.mRoutingTypeFlags)
                && (mIsSystem == other.mIsSystem)
                && Objects.equals(mIconUri, other.mIconUri)
                && Objects.equals(mDescription, other.mDescription)
@@ -966,6 +1024,7 @@ public final class MediaRoute2Info implements Parcelable {
                mName,
                mFeatures,
                mType,
                mRoutingTypeFlags,
                mIsSystem,
                mIconUri,
                mDescription,
@@ -994,6 +1053,8 @@ public final class MediaRoute2Info implements Parcelable {
                .append(getName())
                .append(", type=")
                .append(getDeviceTypeString(getType()))
                .append(", routingTypes=")
                .append(getRoutingTypeFlagsString(getSupportedRoutingTypes()))
                .append(", isSystem=")
                .append(isSystemRoute())
                .append(", features=")
@@ -1035,6 +1096,7 @@ public final class MediaRoute2Info implements Parcelable {
        TextUtils.writeToParcel(mName, dest, flags);
        dest.writeStringList(mFeatures);
        dest.writeInt(mType);
        dest.writeInt(mRoutingTypeFlags);
        dest.writeBoolean(mIsSystem);
        dest.writeParcelable(mIconUri, flags);
        TextUtils.writeToParcel(mDescription, dest, flags);
@@ -1143,6 +1205,34 @@ public final class MediaRoute2Info implements Parcelable {
        }
    }

    /** Returns a human-readable representation of the given {@code routingTypeFlags}. */
    private static String getRoutingTypeFlagsString(@RoutingType int routingTypeFlags) {
        List<String> typeStrings = new ArrayList<>();
        if ((routingTypeFlags & FLAG_ROUTING_TYPE_SYSTEM_AUDIO) != 0) {
            typeStrings.add("SYSTEM_AUDIO");
        }
        if ((routingTypeFlags & FLAG_ROUTING_TYPE_SYSTEM_VIDEO) != 0) {
            typeStrings.add("SYSTEM_VIDEO");
        }
        if ((routingTypeFlags & FLAG_ROUTING_TYPE_REMOTE) != 0) {
            typeStrings.add("REMOTE");
        }
        return String.join(/* delimiter= */ "|", typeStrings);
    }

    /**
     * Throws an {@link IllegalArgumentException} if the provided {@code routingTypeFlags} are not
     * valid. Otherwise, returns the provided value.
     */
    private static int validateRoutingTypeFlags(@RoutingType int routingTypeFlags) {
        if (routingTypeFlags == 0 || (routingTypeFlags & ~FLAG_ROUTING_TYPE_ALL) != 0) {
            throw new IllegalArgumentException(
                    "Invalid routing type flags: " + Integer.toHexString(routingTypeFlags));
        } else {
            return routingTypeFlags;
        }
    }

    /**
     * Builder for {@link MediaRoute2Info media route info}.
     */
@@ -1153,6 +1243,7 @@ public final class MediaRoute2Info implements Parcelable {

        @Type
        private int mType = TYPE_UNKNOWN;
        @RoutingType private int mRoutingTypeFlags = FLAG_ROUTING_TYPE_REMOTE;
        private boolean mIsSystem;
        private Uri mIconUri;
        private CharSequence mDescription;
@@ -1224,6 +1315,7 @@ public final class MediaRoute2Info implements Parcelable {
            mName = routeInfo.mName;
            mFeatures = new ArrayList<>(routeInfo.mFeatures);
            mType = routeInfo.mType;
            mRoutingTypeFlags = routeInfo.mRoutingTypeFlags;
            mIsSystem = routeInfo.mIsSystem;
            mIconUri = routeInfo.mIconUri;
            mDescription = routeInfo.mDescription;
@@ -1300,6 +1392,18 @@ public final class MediaRoute2Info implements Parcelable {
            return this;
        }

        /**
         * Sets the routing types that this route supports.
         *
         * @see MediaRoute2Info#getSupportedRoutingTypes()
         */
        @NonNull
        @FlaggedApi(FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
        public Builder setSupportedRoutingTypes(@RoutingType int routingTypeFlags) {
            mRoutingTypeFlags = validateRoutingTypeFlags(routingTypeFlags);
            return this;
        }

        /**
         * Sets whether the route is a system route or not.
         * @hide