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

Commit 9cd4601f authored by Santiago Seifert's avatar Santiago Seifert Committed by Android (Google) Code Review
Browse files

Merge "Add support for app route listing preferences"

parents d063f916 71e5d2f4
Loading
Loading
Loading
Loading
+17 −0
Original line number Original line Diff line number Diff line
@@ -23523,6 +23523,7 @@ package android.media {
    method public void registerRouteCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaRouter2.RouteCallback, @NonNull android.media.RouteDiscoveryPreference);
    method public void registerRouteCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaRouter2.RouteCallback, @NonNull android.media.RouteDiscoveryPreference);
    method public void registerTransferCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaRouter2.TransferCallback);
    method public void registerTransferCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaRouter2.TransferCallback);
    method public void setOnGetControllerHintsListener(@Nullable android.media.MediaRouter2.OnGetControllerHintsListener);
    method public void setOnGetControllerHintsListener(@Nullable android.media.MediaRouter2.OnGetControllerHintsListener);
    method public void setRouteListingPreference(@Nullable android.media.RouteListingPreference);
    method public void stop();
    method public void stop();
    method public void transferTo(@NonNull android.media.MediaRoute2Info);
    method public void transferTo(@NonNull android.media.MediaRoute2Info);
    method public void unregisterControllerCallback(@NonNull android.media.MediaRouter2.ControllerCallback);
    method public void unregisterControllerCallback(@NonNull android.media.MediaRouter2.ControllerCallback);
@@ -23896,6 +23897,22 @@ package android.media {
    method @NonNull public android.media.RouteDiscoveryPreference.Builder setShouldPerformActiveScan(boolean);
    method @NonNull public android.media.RouteDiscoveryPreference.Builder setShouldPerformActiveScan(boolean);
  }
  }
  public final class RouteListingPreference implements android.os.Parcelable {
    ctor public RouteListingPreference(@NonNull java.util.List<android.media.RouteListingPreference.Item>);
    method public int describeContents();
    method @NonNull public java.util.List<android.media.RouteListingPreference.Item> getItems();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteListingPreference> CREATOR;
  }
  public static final class RouteListingPreference.Item implements android.os.Parcelable {
    ctor public RouteListingPreference.Item(@NonNull String);
    method public int describeContents();
    method @NonNull public String getRouteId();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteListingPreference.Item> CREATOR;
  }
  public final class RoutingSessionInfo implements android.os.Parcelable {
  public final class RoutingSessionInfo implements android.os.Parcelable {
    method public int describeContents();
    method public int describeContents();
    method @NonNull public String getClientPackageName();
    method @NonNull public String getClientPackageName();
+3 −0
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@ package android.media;
import android.media.MediaRoute2ProviderInfo;
import android.media.MediaRoute2ProviderInfo;
import android.media.MediaRoute2Info;
import android.media.MediaRoute2Info;
import android.media.RouteDiscoveryPreference;
import android.media.RouteDiscoveryPreference;
import android.media.RouteListingPreference;
import android.media.RoutingSessionInfo;
import android.media.RoutingSessionInfo;


/**
/**
@@ -30,6 +31,8 @@ oneway interface IMediaRouter2Manager {
    void notifySessionReleased(in RoutingSessionInfo session);
    void notifySessionReleased(in RoutingSessionInfo session);
    void notifyDiscoveryPreferenceChanged(String packageName,
    void notifyDiscoveryPreferenceChanged(String packageName,
            in RouteDiscoveryPreference discoveryPreference);
            in RouteDiscoveryPreference discoveryPreference);
    void notifyRouteListingPreferenceChange(String packageName,
            in @nullable RouteListingPreference routeListingPreference);
    void notifyRoutesUpdated(in List<MediaRoute2Info> routes);
    void notifyRoutesUpdated(in List<MediaRoute2Info> routes);
    void notifyRequestFailed(int requestId, int reason);
    void notifyRequestFailed(int requestId, int reason);
}
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@ import android.media.IMediaRouterClient;
import android.media.MediaRoute2Info;
import android.media.MediaRoute2Info;
import android.media.MediaRouterClientState;
import android.media.MediaRouterClientState;
import android.media.RouteDiscoveryPreference;
import android.media.RouteDiscoveryPreference;
import android.media.RouteListingPreference;
import android.media.RoutingSessionInfo;
import android.media.RoutingSessionInfo;
import android.os.Bundle;
import android.os.Bundle;


@@ -57,6 +58,8 @@ interface IMediaRouterService {
    void unregisterRouter2(IMediaRouter2 router);
    void unregisterRouter2(IMediaRouter2 router);
    void setDiscoveryRequestWithRouter2(IMediaRouter2 router,
    void setDiscoveryRequestWithRouter2(IMediaRouter2 router,
            in RouteDiscoveryPreference preference);
            in RouteDiscoveryPreference preference);
    void setRouteListingPreference(IMediaRouter2 router,
            in @nullable RouteListingPreference routeListingPreference);
    void setRouteVolumeWithRouter2(IMediaRouter2 router, in MediaRoute2Info route, int volume);
    void setRouteVolumeWithRouter2(IMediaRouter2 router, in MediaRoute2Info route, int volume);


    void requestCreateSessionWithRouter2(IMediaRouter2 router, int requestId, long managerRequestId,
    void requestCreateSessionWithRouter2(IMediaRouter2 router, int requestId, long managerRequestId,
+50 −0
Original line number Original line Diff line number Diff line
@@ -112,6 +112,10 @@ public final class MediaRouter2 {
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    final Map<String, MediaRoute2Info> mRoutes = new ArrayMap<>();
    final Map<String, MediaRoute2Info> mRoutes = new ArrayMap<>();


    @GuardedBy("mLock")
    @Nullable
    private RouteListingPreference mRouteListingPreference;

    final RoutingController mSystemController;
    final RoutingController mSystemController;


    @GuardedBy("mLock")
    @GuardedBy("mLock")
@@ -461,6 +465,52 @@ public final class MediaRouter2 {
        }
        }
    }
    }


    /**
     * Sets the {@link RouteListingPreference} of the app associated to this media router.
     *
     * <p>Use this method to inform the system UI of the routes that you would like to list for
     * media routing, via the Output Switcher.
     *
     * <p>You should call this method before {@link #registerRouteCallback registering any route
     * callbacks} and immediately after receiving any {@link RouteCallback#onRoutesUpdated route
     * updates} in order to keep the system UI in a consistent state. You can also call this method
     * at any other point to update the listing preference dynamically.
     *
     * <p>Notes:
     *
     * <ol>
     *   <li>You should not include the ids of two or more routes with a match in their {@link
     *       MediaRoute2Info#getDeduplicationIds() deduplication ids}. If you do, the system will
     *       deduplicate them using its own criteria.
     *   <li>You can use this method to rank routes in the output switcher, placing the more
     *       important routes first. The system might override the proposed ranking.
     *   <li>You can use this method to avoid listing routes using dynamic criteria. For example,
     *       you can limit access to a specific type of device according to runtime criteria.
     * </ol>
     *
     * @param routeListingPreference The {@link RouteListingPreference} for the system to use for
     *     route listing. When null, the system uses its default listing criteria.
     */
    public void setRouteListingPreference(@Nullable RouteListingPreference routeListingPreference) {
        synchronized (mLock) {
            if (Objects.equals(mRouteListingPreference, routeListingPreference)) {
                // Nothing changed. We return early to save a call to the system server.
                return;
            }
            mRouteListingPreference = routeListingPreference;
            try {
                if (mStub == null) {
                    MediaRouter2Stub stub = new MediaRouter2Stub();
                    mMediaRouterService.registerRouter2(stub, mPackageName);
                    mStub = stub;
                }
                mMediaRouterService.setRouteListingPreference(mStub, mRouteListingPreference);
            } catch (RemoteException ex) {
                ex.rethrowFromSystemServer();
            }
        }
    }

    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private boolean updateDiscoveryPreferenceIfNeededLocked() {
    private boolean updateDiscoveryPreferenceIfNeededLocked() {
        RouteDiscoveryPreference newDiscoveryPreference = new RouteDiscoveryPreference.Builder(
        RouteDiscoveryPreference newDiscoveryPreference = new RouteDiscoveryPreference.Builder(
+58 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@ import android.util.Log;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Collections;
@@ -93,6 +94,11 @@ public final class MediaRouter2Manager {
    @NonNull
    @NonNull
    final ConcurrentMap<String, RouteDiscoveryPreference> mDiscoveryPreferenceMap =
    final ConcurrentMap<String, RouteDiscoveryPreference> mDiscoveryPreferenceMap =
            new ConcurrentHashMap<>();
            new ConcurrentHashMap<>();
    // TODO(b/241888071): Merge mDiscoveryPreferenceMap and mPackageToRouteListingPreferenceMap into
    //     a single record object maintained by a single package-to-record map.
    @NonNull
    private final ConcurrentMap<String, RouteListingPreference>
            mPackageToRouteListingPreferenceMap = new ConcurrentHashMap<>();


    private final AtomicInteger mNextRequestId = new AtomicInteger(1);
    private final AtomicInteger mNextRequestId = new AtomicInteger(1);
    private final CopyOnWriteArrayList<TransferRequest> mTransferRequests =
    private final CopyOnWriteArrayList<TransferRequest> mTransferRequests =
@@ -354,6 +360,16 @@ public final class MediaRouter2Manager {
        return mDiscoveryPreferenceMap.getOrDefault(packageName, RouteDiscoveryPreference.EMPTY);
        return mDiscoveryPreferenceMap.getOrDefault(packageName, RouteDiscoveryPreference.EMPTY);
    }
    }


    /**
     * Returns the {@link RouteListingPreference} of the app with the given {@code packageName}, or
     * null if the app has not set any.
     */
    @Nullable
    public RouteListingPreference getRouteListingPreference(@NonNull String packageName) {
        Preconditions.checkArgument(!TextUtils.isEmpty(packageName));
        return mPackageToRouteListingPreferenceMap.get(packageName);
    }

    /**
    /**
     * Gets the system routing session for the given {@code packageName}.
     * Gets the system routing session for the given {@code packageName}.
     * Apps can select a route that is not the global route. (e.g. an app can select the device
     * Apps can select a route that is not the global route. (e.g. an app can select the device
@@ -686,6 +702,24 @@ public final class MediaRouter2Manager {
        }
        }
    }
    }


    private void updateRouteListingPreference(
            @NonNull String packageName, @Nullable RouteListingPreference routeListingPreference) {
        RouteListingPreference oldRouteListingPreference =
                routeListingPreference == null
                        ? mPackageToRouteListingPreferenceMap.remove(packageName)
                        : mPackageToRouteListingPreferenceMap.put(
                                packageName, routeListingPreference);
        if (Objects.equals(oldRouteListingPreference, routeListingPreference)) {
            return;
        }
        for (CallbackRecord record : mCallbackRecords) {
            record.mExecutor.execute(
                    () ->
                            record.mCallback.onRouteListingPreferenceUpdated(
                                    packageName, routeListingPreference));
        }
    }

    /**
    /**
     * Gets the unmodifiable list of selected routes for the session.
     * Gets the unmodifiable list of selected routes for the session.
     */
     */
@@ -970,6 +1004,19 @@ public final class MediaRouter2Manager {
            onPreferredFeaturesChanged(packageName, discoveryPreference.getPreferredFeatures());
            onPreferredFeaturesChanged(packageName, discoveryPreference.getPreferredFeatures());
        }
        }


        /**
         * Called when the app with the given {@code packageName} updates its {@link
         * MediaRouter2#setRouteListingPreference route listing preference}.
         *
         * @param packageName The package name of the app that changed its listing preference.
         * @param routeListingPreference The new {@link RouteListingPreference} set by the app with
         *     the given {@code packageName}. Maybe null if an app has unset its preference (by
         *     passing null to {@link MediaRouter2#setRouteListingPreference}).
         */
        default void onRouteListingPreferenceUpdated(
                @NonNull String packageName,
                @Nullable RouteListingPreference routeListingPreference) {}

        /**
        /**
         * Called when a previous request has failed.
         * Called when a previous request has failed.
         *
         *
@@ -1055,6 +1102,17 @@ public final class MediaRouter2Manager {
                    MediaRouter2Manager.this, packageName, discoveryPreference));
                    MediaRouter2Manager.this, packageName, discoveryPreference));
        }
        }


        @Override
        public void notifyRouteListingPreferenceChange(
                String packageName, @Nullable RouteListingPreference routeListingPreference) {
            mHandler.sendMessage(
                    obtainMessage(
                            MediaRouter2Manager::updateRouteListingPreference,
                            MediaRouter2Manager.this,
                            packageName,
                            routeListingPreference));
        }

        @Override
        @Override
        public void notifyRoutesUpdated(List<MediaRoute2Info> routes) {
        public void notifyRoutesUpdated(List<MediaRoute2Info> routes) {
            mHandler.sendMessage(
            mHandler.sendMessage(
Loading