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

Commit a0d47419 authored by Kyunglyul Hyun's avatar Kyunglyul Hyun
Browse files

Media: Implement Seamless Transfer with a single provider.

Seamless transfer for a single provider case and two providers case
should be dealt with in different ways.

For a single provider case, the provider can handle transfer and returns
the result of transfer.

For multiple providers case, the media app handles the transfer.

This CL covers seamless transfer within a single provider.

If a user requests semless transfer in System UI, MR2Manager.selectRoute
should be called and this request is sent to MediaRoute2ProviderService
that can handle seamless transfer internally.

The new test, testSingleProviderSelect() in MediaRouterManagerTest tests the path for
seamless transfer and ensure transfer request is handled by a provider.

From this CL, we use packagename instead of uid to select app for seamless transfer.
This is required to handle unlaunched apps that don't have uid.
It would prevent to use media router 2 in a multi-user case, that will
be supported by another CL.

I also added onUnselectRoute in MediaRoute2ProviderService, which is
essential to notify a provider that a media app stopped casting.

Bug: 136775407
Test: atest mediaroutertest

Change-Id: Ie3d0e988a72eedea6036f465454e661c424a0495
parent 293bb896
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@ import android.media.IMediaRoute2ProviderClient;
 * {@hide}
 */
oneway interface IMediaRoute2Provider {
    void registerClient(IMediaRoute2ProviderClient client);
    void selectRoute(IMediaRoute2ProviderClient client, int uid, String id);
    void notifyControlRequestSent(IMediaRoute2ProviderClient client, String id, in Intent request);
    void setClient(IMediaRoute2ProviderClient client);
    void selectRoute(String packageName, String id);
    void unselectRoute(String packageName, String id);
    void notifyControlRequestSent(String id, in Intent request);
}
+0 −1
Original line number Diff line number Diff line
@@ -22,6 +22,5 @@ import android.media.MediaRoute2ProviderInfo;
 * @hide
 */
oneway interface IMediaRoute2ProviderClient {
    void notifyRouteSelected(int uid, String routeId);
    void notifyProviderInfoUpdated(in MediaRoute2ProviderInfo info);
}
+2 −2
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ import android.media.MediaRoute2Info;
 * {@hide}
 */
oneway interface IMediaRouter2Manager {
    void notifyRouteSelected(int uid, in MediaRoute2Info route);
    void notifyControlCategoriesChanged(int uid, in List<String> categories);
    void notifyRouteSelected(String packageName, in MediaRoute2Info route);
    void notifyControlCategoriesChanged(String packageName, in List<String> categories);
    void notifyProviderInfosUpdated(in List<MediaRoute2ProviderInfo> providers);
}
+6 −6
Original line number Diff line number Diff line
@@ -48,8 +48,8 @@ interface IMediaRouterService {
    /**
     * Changes the selected route of the client.
     *
     * @param client Client to change it's selected route.
     * @param route Route to be selected.
     * @param client the client that changes it's selected route
     * @param route the route to be selected
     */
    void selectRoute2(IMediaRouter2Client client, in @nullable MediaRoute2Info route);
    void setControlCategories(IMediaRouter2Client client, in List<String> categories);
@@ -60,10 +60,10 @@ interface IMediaRouterService {
    /**
     * Changes the selected route of an application.
     *
     * @param manager Manager that calls the method
     * @param uid UID of the client that will change the selected route.
     * @param route Route to be selected.
     * @param manager the manager that calls the method
     * @param packageName the package name of the client that will change the selected route
     * @param route the route to be selected
     */
    void selectClientRoute2(IMediaRouter2Manager manager, int clientUid,
    void selectClientRoute2(IMediaRouter2Manager manager, String packageName,
            in @nullable MediaRoute2Info route);
}
+27 −0
Original line number Diff line number Diff line
@@ -52,6 +52,8 @@ public final class MediaRoute2Info implements Parcelable {
    @Nullable
    final String mDescription;
    @Nullable
    final String mClientPackageName;
    @Nullable
    final Bundle mExtras;

    MediaRoute2Info(@NonNull Builder builder) {
@@ -59,6 +61,7 @@ public final class MediaRoute2Info implements Parcelable {
        mProviderId = builder.mProviderId;
        mName = builder.mName;
        mDescription = builder.mDescription;
        mClientPackageName = builder.mClientPackageName;
        mExtras = builder.mExtras;
    }

@@ -67,6 +70,7 @@ public final class MediaRoute2Info implements Parcelable {
        mProviderId = in.readString();
        mName = in.readString();
        mDescription = in.readString();
        mClientPackageName = in.readString();
        mExtras = in.readBundle();
    }

@@ -98,6 +102,7 @@ public final class MediaRoute2Info implements Parcelable {
                && Objects.equals(mProviderId, other.mProviderId)
                && Objects.equals(mName, other.mName)
                && Objects.equals(mDescription, other.mDescription)
                && Objects.equals(mClientPackageName, other.mClientPackageName)
                //TODO: This will be evaluated as false in most cases. Try not to.
                && Objects.equals(mExtras, other.mExtras);
    }
@@ -131,6 +136,16 @@ public final class MediaRoute2Info implements Parcelable {
        return mDescription;
    }

    /**
     * Gets the package name of the client that uses the route.
     * Returns null if no clients use this.
     * @hide
     */
    @Nullable
    public String getClientPackageName() {
        return mClientPackageName;
    }

    @Nullable
    public Bundle getExtras() {
        return mExtras;
@@ -147,6 +162,7 @@ public final class MediaRoute2Info implements Parcelable {
        dest.writeString(mProviderId);
        dest.writeString(mName);
        dest.writeString(mDescription);
        dest.writeString(mClientPackageName);
        dest.writeBundle(mExtras);
    }

@@ -170,6 +186,7 @@ public final class MediaRoute2Info implements Parcelable {
        String mProviderId;
        String mName;
        String mDescription;
        String mClientPackageName;
        Bundle mExtras;

        public Builder(@NonNull String id, @NonNull String name) {
@@ -194,6 +211,7 @@ public final class MediaRoute2Info implements Parcelable {
            }
            setName(routeInfo.mName);
            mDescription = routeInfo.mDescription;
            setClientPackageName(routeInfo.mClientPackageName);
            if (routeInfo.mExtras != null) {
                mExtras = new Bundle(routeInfo.mExtras);
            }
@@ -245,6 +263,15 @@ public final class MediaRoute2Info implements Parcelable {
            return this;
        }

        /**
         * Sets the package name of the app using the route.
         */
        @NonNull
        public Builder setClientPackageName(@Nullable String packageName) {
            mClientPackageName = packageName;
            return this;
        }

        /**
         * Sets a bundle of extras for the route.
         */
Loading