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

Commit e5d16057 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Publish MR2 system media session APIs" into main

parents 8d6c0f57 a3172500
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -25039,8 +25039,10 @@ package android.media {
    method public final void notifySessionCreated(long, @NonNull android.media.RoutingSessionInfo);
    method public final void notifySessionReleased(@NonNull String);
    method public final void notifySessionUpdated(@NonNull android.media.RoutingSessionInfo);
    method @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") @Nullable @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public final android.media.MediaRoute2ProviderService.MediaStreams notifySystemRoutingSessionCreated(long, @NonNull android.media.RoutingSessionInfo, @NonNull android.media.MediaRoute2ProviderService.MediaStreamsFormats);
    method @CallSuper @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent);
    method public abstract void onCreateSession(long, @NonNull String, @NonNull String, @Nullable android.os.Bundle);
    method @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public void onCreateSystemRoutingSession(long, @NonNull String, @NonNull android.media.MediaRoute2ProviderService.SystemRoutingSessionParams);
    method public abstract void onDeselectRoute(long, @NonNull String, @NonNull String);
    method public void onDiscoveryPreferenceChanged(@NonNull android.media.RouteDiscoveryPreference);
    method public abstract void onReleaseSession(long, @NonNull String);
@@ -25048,15 +25050,44 @@ package android.media {
    method public abstract void onSetRouteVolume(long, @NonNull String, int);
    method public abstract void onSetSessionVolume(long, @NonNull String, int);
    method public abstract void onTransferToRoute(long, @NonNull String, @NonNull String);
    field @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public static final String CATEGORY_SYSTEM_MEDIA = "android.media.MediaRoute2ProviderService.SYSTEM_MEDIA";
    field @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public static final int REASON_FAILED_TO_REROUTE_SYSTEM_MEDIA = 6; // 0x6
    field public static final int REASON_INVALID_COMMAND = 4; // 0x4
    field public static final int REASON_NETWORK_ERROR = 2; // 0x2
    field public static final int REASON_REJECTED = 1; // 0x1
    field public static final int REASON_ROUTE_NOT_AVAILABLE = 3; // 0x3
    field @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public static final int REASON_UNIMPLEMENTED = 5; // 0x5
    field public static final int REASON_UNKNOWN_ERROR = 0; // 0x0
    field public static final long REQUEST_ID_NONE = 0L; // 0x0L
    field public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService";
  }
  @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public static final class MediaRoute2ProviderService.MediaStreams {
    method @Nullable public android.media.AudioRecord getAudioRecord();
  }
  @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public static final class MediaRoute2ProviderService.MediaStreamsFormats {
    method @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") @Nullable public android.media.AudioFormat getAudioFormat();
  }
  @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public static final class MediaRoute2ProviderService.MediaStreamsFormats.Builder {
    ctor public MediaRoute2ProviderService.MediaStreamsFormats.Builder();
    method @NonNull public android.media.MediaRoute2ProviderService.MediaStreamsFormats build();
    method @NonNull public android.media.MediaRoute2ProviderService.MediaStreamsFormats.Builder setAudioFormat(@NonNull android.media.AudioFormat);
  }
  @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public static final class MediaRoute2ProviderService.SystemRoutingSessionParams {
    method @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") @NonNull public android.os.Bundle getExtras();
    method @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") @NonNull public String getPackageName();
  }
  public static final class MediaRoute2ProviderService.SystemRoutingSessionParams.Builder {
    ctor public MediaRoute2ProviderService.SystemRoutingSessionParams.Builder();
    method @NonNull public android.media.MediaRoute2ProviderService.SystemRoutingSessionParams build();
    method @NonNull public android.media.MediaRoute2ProviderService.SystemRoutingSessionParams.Builder setExtras(@NonNull android.os.Bundle);
    method @NonNull public android.media.MediaRoute2ProviderService.SystemRoutingSessionParams.Builder setPackageName(@NonNull String);
  }
  public class MediaRouter {
    method public void addCallback(int, android.media.MediaRouter.Callback);
    method public void addCallback(int, android.media.MediaRouter.Callback, int);
+116 −51
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;

/**
@@ -96,12 +97,10 @@ public abstract class MediaRoute2ProviderService extends Service {
     * system media, as described by {@link MediaRoute2Info#getSupportedRoutingTypes()}.
     *
     * @see #onCreateSystemRoutingSession
     * @hide
     */
    // TODO: b/362507305 - Unhide once the implementation and CTS are in place.
    @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
    @SdkConstant(SdkConstant.SdkConstantType.INTENT_CATEGORY)
    public static final String SERVICE_INTERFACE_SYSTEM_MEDIA =
    public static final String CATEGORY_SYSTEM_MEDIA =
            "android.media.MediaRoute2ProviderService.SYSTEM_MEDIA";

    /**
@@ -165,9 +164,7 @@ public abstract class MediaRoute2ProviderService extends Service {
     * The request has failed because the requested operation is not implemented by the provider.
     *
     * @see #notifyRequestFailed
     * @hide
     */
    // TODO: b/362507305 - Unhide once the implementation and CTS are in place.
    @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
    public static final int REASON_UNIMPLEMENTED = 5;

@@ -175,9 +172,7 @@ public abstract class MediaRoute2ProviderService extends Service {
     * The request has failed because the provider has failed to route system media.
     *
     * @see #notifyRequestFailed
     * @hide
     */
    // TODO: b/362507305 - Unhide once the implementation and CTS are in place.
    @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
    public static final int REASON_FAILED_TO_REROUTE_SYSTEM_MEDIA = 6;

@@ -217,7 +212,7 @@ public abstract class MediaRoute2ProviderService extends Service {
     * package (for example, if they affect the entire system).
     */
    @GuardedBy("mRequestIdsLock")
    private final LongSparseArray<Integer> mSystemMediaSessionCreationRequests =
    private final LongSparseArray<Integer> mSystemRoutingSessionCreationRequests =
            new LongSparseArray<>();

    @GuardedBy("mSessionLock")
@@ -350,7 +345,7 @@ public abstract class MediaRoute2ProviderService extends Service {
    /**
     * Notifies the system of the successful creation of a system media routing session.
     *
     * <p>This method can only be called as the result of a prior call to {@link
     * <p>This method must only be called as the result of a prior call to {@link
     * #onCreateSystemRoutingSession}.
     *
     * @param requestId the ID of the {@link #onCreateSystemRoutingSession} request which this call
@@ -365,13 +360,13 @@ public abstract class MediaRoute2ProviderService extends Service {
     *     where you can clean up this session. {@link AudioRecord#startRecording()} must be called
     *     immediately on {@link MediaStreams#getAudioRecord()} after calling this method, in order
     *     to start streaming audio to the receiver.
     * @hide
     * @throws IllegalStateException If the provided {@code requestId} doesn't correspond to a
     *     previous call to {@link #onCreateSystemRoutingSession}.
     */
    // TODO: b/362507305 - Unhide once the implementation and CTS are in place.
    @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
    @RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
    @Nullable
    public final MediaStreams notifySystemMediaSessionCreated(
    public final MediaStreams notifySystemRoutingSessionCreated(
            long requestId,
            @NonNull RoutingSessionInfo sessionInfo,
            @NonNull MediaStreamsFormats formats) {
@@ -380,7 +375,7 @@ public abstract class MediaRoute2ProviderService extends Service {
        if (DEBUG) {
            Log.d(
                    TAG,
                    "notifySystemMediaSessionCreated: Creating a session. requestId="
                    "notifySystemRoutingSessionCreated: Creating a session. requestId="
                            + requestId
                            + ", sessionInfo="
                            + sessionInfo);
@@ -388,8 +383,8 @@ public abstract class MediaRoute2ProviderService extends Service {

        Integer uid;
        synchronized (mRequestIdsLock) {
            uid = mSystemMediaSessionCreationRequests.get(requestId);
            mSystemMediaSessionCreationRequests.remove(requestId);
            uid = mSystemRoutingSessionCreationRequests.get(requestId);
            mSystemRoutingSessionCreationRequests.remove(requestId);
        }

        if (uid == null) {
@@ -656,37 +651,34 @@ public abstract class MediaRoute2ProviderService extends Service {
    /**
     * Called when the service receives a request to create a system routing session.
     *
     * <p>This method will only be called for routes that support routing of the system media, as
     * described by {@link MediaRoute2Info#getSupportedRoutingTypes()}.
     * <p>This method must be overridden by subclasses that support routes that support routing
     * {@link MediaRoute2Info#getSupportedRoutingTypes() system media}. The provided {@code routeId}
     * will always correspond to a route that supports routing of the system media, as per {@link
     * MediaRoute2Info#getSupportedRoutingTypes()}.
     *
     * <p>Implementors of this method must call {@link #notifySystemMediaSessionCreated} with the
     * <p>Implementors of this method must call {@link #notifySystemRoutingSessionCreated} with the
     * given {@code requestId} to indicate a successful session creation. If the session creation
     * fails (for example, if the connection to the receiver device fails), the implementor must
     * call {@link #notifyRequestFailed}, passing the {@code requestId}.
     *
     * <p>Unlike {@link #onCreateSession}, system sessions route the system media (for example,
     * audio and/or video) which is to be retrieved by calling {@link
     * #notifySystemMediaSessionCreated}.
     * #notifySystemRoutingSessionCreated}.
     *
     * <p>Changes to the session can be notified by calling {@link #notifySessionUpdated}.
     *
     * @param requestId the ID of this request
     * @param packageName the package name of the application whose media to route.
     * @param routeId the ID of the route initially being {@link
     *     RoutingSessionInfo#getSelectedRoutes() selected}.
     * @param sessionHints an optional bundle of arguments sent by {@link MediaRouter2}, or null if
     *     none.
     * @param parameters {@link SystemRoutingSessionParams} for the session creation.
     * @see RoutingSessionInfo.Builder
     * @see #notifySystemMediaSessionCreated
     * @hide
     * @see #notifySystemRoutingSessionCreated
     */
    // TODO: b/362507305 - Unhide once the implementation and CTS are in place.
    @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
    public void onCreateSystemRoutingSession(
            long requestId,
            @NonNull String packageName,
            @NonNull String routeId,
            @Nullable Bundle sessionHints) {
            @NonNull SystemRoutingSessionParams parameters) {
        mHandler.post(() -> notifyRequestFailed(requestId, REASON_UNIMPLEMENTED));
    }

@@ -974,24 +966,29 @@ public abstract class MediaRoute2ProviderService extends Service {
                int uid,
                String packageName,
                String routeId,
                @Nullable Bundle sessionHints) {
            if (!checkCallerIsSystem()) {
                @Nullable Bundle extras) {
            if (!Flags.enableMirroringInMediaRouter2() || !checkCallerIsSystem()) {
                return;
            }
            if (!checkRouteIdIsValid(routeId, "requestCreateSession")) {
                return;
            }
            synchronized (mRequestIdsLock) {
                mSystemMediaSessionCreationRequests.put(requestId, uid);
                mSystemRoutingSessionCreationRequests.put(requestId, uid);
            }
            var sessionParamsBuilder =
                    new SystemRoutingSessionParams.Builder().setPackageName(packageName);
            if (extras != null) {
                sessionParamsBuilder.setExtras(extras);
            }
            var sessionParams = sessionParamsBuilder.build();
            mHandler.sendMessage(
                    obtainMessage(
                            MediaRoute2ProviderService::onCreateSystemRoutingSession,
                            MediaRoute2ProviderService.this,
                            requestId,
                            packageName,
                            routeId,
                            sessionHints));
                            sessionParams));
        }

        @Override
@@ -1072,14 +1069,12 @@ public abstract class MediaRoute2ProviderService extends Service {
    }

    /**
     * Holds the streams to be routed as part of a system media routing session.
     *
     * <p>The encoded data format matches the {@link MediaStreamsFormats} passed to {@link
     * #notifySystemMediaSessionCreated}.
     * Holds the streams to be routed as part of a {@link #onCreateSystemRoutingSession system media
     * routing session}.
     *
     * @hide
     * <p>The encoded data format will match the {@link MediaStreamsFormats} passed to {@link
     * #notifySystemRoutingSessionCreated}.
     */
    // TODO: b/362507305 - Unhide once the implementation and CTS are in place.
    @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
    public static final class MediaStreams {

@@ -1088,8 +1083,6 @@ public abstract class MediaRoute2ProviderService extends Service {

        /**
         * Holds the last {@link RoutingSessionInfo} associated with these streams.
         *
         * @hide
         */
        @NonNull
        // Access guarded by mSessionsLock, but it's not convenient to enforce through @GuardedBy.
@@ -1147,15 +1140,91 @@ public abstract class MediaRoute2ProviderService extends Service {
        }
    }

    /**
     * Holds parameters associated with a {@link #onCreateSystemRoutingSession session creation
     * request}.
     */
    @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
    public static final class SystemRoutingSessionParams {

        private final String mPackageName;
        private final Bundle mExtras;

        private SystemRoutingSessionParams(Builder builder) {
            this.mPackageName = builder.mPackageName;
            this.mExtras = builder.mExtras;
        }

        /**
         * Returns the name of the package associated with the session, or an empty string if not
         * applicable.
         *
         * <p>The package name is not applicable if the session is not associated with a specific
         * package, for example is the session affects the entire system.
         */
        @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
        @NonNull
        public String getPackageName() {
            return mPackageName;
        }

        /** Returns a bundle provided by the client that triggered the session creation request. */
        @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
        @NonNull
        public Bundle getExtras() {
            return mExtras;
        }

        /** A builder for {@link SystemRoutingSessionParams}. */
        public static final class Builder {
            private String mPackageName;
            private Bundle mExtras;

            /** Constructor. */
            public Builder() {
                mPackageName = "";
                mExtras = Bundle.EMPTY;
            }

            /**
             * Sets the {@link #getExtras() extras}.
             *
             * <p>The default value is an empty {@link Bundle}.
             *
             * <p>Note that this bundle is not copied, so avoiding mutating the given {@link Bundle}
             * after passing it to this method.
             */
            @NonNull
            public Builder setExtras(@NonNull Bundle extras) {
                mExtras = Objects.requireNonNull(extras);
                return this;
            }

            /**
             * Sets the {@link #getPackageName()}.
             *
             * <p>The default value is an empty string.
             */
            @NonNull
            public Builder setPackageName(@NonNull String packageName) {
                mPackageName = Objects.requireNonNull(packageName);
                return this;
            }

            /** Returns a new {@link SystemRoutingSessionParams} instance. */
            @NonNull
            public SystemRoutingSessionParams build() {
                return new SystemRoutingSessionParams(this);
            }
        }
    }

    /**
     * Holds the formats to encode media data to be read from {@link MediaStreams}.
     *
     * @see MediaStreams
     * @see #notifySystemMediaSessionCreated
     * @hide
     * @see #notifySystemRoutingSessionCreated
     */
    // TODO: b/362507305 - Unhide once the implementation and CTS are in place.
    @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
    public static final class MediaStreamsFormats {

@@ -1169,29 +1238,25 @@ public abstract class MediaRoute2ProviderService extends Service {

        /**
         * Returns the audio format to use for creating the {@link MediaStreams#getAudioRecord} to
         * return from {@link #notifySystemMediaSessionCreated}.
         *
         * @hide
         * return from {@link #notifySystemRoutingSessionCreated}. May be null if the session
         * doesn't support system audio.
         */
        // TODO: b/362507305 - Unhide once the implementation and CTS are in place.
        @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
        @Nullable
        public AudioFormat getAudioFormat() {
            return mAudioFormat;
        }

        /**
         * Builder for {@link MediaStreamsFormats}
         *
         * @hide
         */
        // TODO: b/362507305 - Unhide once the implementation and CTS are in place.
        @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
        public static final class Builder {
            private AudioFormat mAudioFormat;

            /**
             * Sets the audio format to use for creating the {@link MediaStreams#getAudioRecord} to
             * return from {@link #notifySystemMediaSessionCreated}.
             * return from {@link #notifySystemRoutingSessionCreated}.
             *
             * @param audioFormat the audio format
             * @return this builder
+1 −2
Original line number Diff line number Diff line
@@ -141,8 +141,7 @@ final class MediaRoute2ProviderWatcher {
                        isSelfScanOnlyProvider |=
                                MediaRoute2ProviderService.CATEGORY_SELF_SCAN_ONLY.equals(category);
                        supportsSystemMediaRouting |=
                                MediaRoute2ProviderService.SERVICE_INTERFACE_SYSTEM_MEDIA.equals(
                                        category);
                                MediaRoute2ProviderService.CATEGORY_SYSTEM_MEDIA.equals(category);
                    }
                }
                int sourceIndex = findProvider(serviceInfo.packageName, serviceInfo.name);