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

Commit 98d7df02 authored by Alex Dadukin's avatar Alex Dadukin Committed by Android (Google) Code Review
Browse files

Merge "Check if getSystemSessionInfo requested by a Proxy Router" into main

parents 4a1ddee5 5f0bca14
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ interface IMediaRouterService {
    // MediaRouterService.java for readability.

    // Methods for MediaRouter2
    List<MediaRoute2Info> getSystemRoutes();
    List<MediaRoute2Info> getSystemRoutes(String callerPackageName, boolean isProxyRouter);
    RoutingSessionInfo getSystemSessionInfo();

    void registerRouter2(IMediaRouter2 router, String packageName);
@@ -75,7 +75,8 @@ interface IMediaRouterService {

    // Methods for MediaRouter2Manager
    List<RoutingSessionInfo> getRemoteSessions(IMediaRouter2Manager manager);
    RoutingSessionInfo getSystemSessionInfoForPackage(String packageName);
    RoutingSessionInfo getSystemSessionInfoForPackage(String callerPackageName,
        String targetPackageName);
    void registerManager(IMediaRouter2Manager manager, String packageName);
    void registerProxyRouter(IMediaRouter2Manager manager, String callingPackageName, String targetPackageName, in UserHandle targetUser);
    void unregisterManager(IMediaRouter2Manager manager);
+12 −8
Original line number Diff line number Diff line
@@ -613,7 +613,7 @@ public final class MediaRouter2 {
        mImpl = new LocalMediaRouter2Impl(mContext.getPackageName());
        mHandler = new Handler(Looper.getMainLooper());

        loadSystemRoutes();
        loadSystemRoutes(/* isProxyRouter */ false);

        RoutingSessionInfo currentSystemSessionInfo = mImpl.getSystemSessionInfo();
        if (currentSystemSessionInfo == null) {
@@ -631,21 +631,22 @@ public final class MediaRouter2 {
                IMediaRouterService.Stub.asInterface(
                        ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));

        loadSystemRoutes();
        loadSystemRoutes(/* isProxyRouter */ true);

        mSystemController =
                new SystemRoutingController(
                        ProxyMediaRouter2Impl.getSystemSessionInfoImpl(
                                mMediaRouterService, clientPackageName));
                                mMediaRouterService, mContext.getPackageName(), clientPackageName));

        mImpl = new ProxyMediaRouter2Impl(context, clientPackageName, user);
    }

    @GuardedBy("mLock")
    private void loadSystemRoutes() {
    private void loadSystemRoutes(boolean isProxyRouter) {
        List<MediaRoute2Info> currentSystemRoutes = null;
        try {
            currentSystemRoutes = mMediaRouterService.getSystemRoutes();
            currentSystemRoutes = mMediaRouterService.getSystemRoutes(mContext.getPackageName(),
                    isProxyRouter);
        } catch (RemoteException ex) {
            ex.rethrowFromSystemServer();
        }
@@ -2644,7 +2645,8 @@ public final class MediaRouter2 {

        @Override
        public RoutingSessionInfo getSystemSessionInfo() {
            return getSystemSessionInfoImpl(mMediaRouterService, mClientPackageName);
            return getSystemSessionInfoImpl(
                    mMediaRouterService, mContext.getPackageName(), mClientPackageName);
        }

        /**
@@ -3049,9 +3051,11 @@ public final class MediaRouter2 {
         * <p>Extracted into a static method to allow calling this from the constructor.
         */
        /* package */ static RoutingSessionInfo getSystemSessionInfoImpl(
                @NonNull IMediaRouterService service, @NonNull String clientPackageName) {
                @NonNull IMediaRouterService service,
                @NonNull String callerPackageName,
                @NonNull String clientPackageName) {
            try {
                return service.getSystemSessionInfoForPackage(clientPackageName);
                return service.getSystemSessionInfoForPackage(callerPackageName, clientPackageName);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
+9 −6
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ public final class MediaRouter2Manager {
    @GuardedBy("sLock")
    private static MediaRouter2Manager sInstance;

    private final Context mContext;
    private final MediaSessionManager mMediaSessionManager;
    private final Client mClient;
    private final IMediaRouterService mMediaRouterService;
@@ -120,6 +121,7 @@ public final class MediaRouter2Manager {
    }

    private MediaRouter2Manager(Context context) {
        mContext = context.getApplicationContext();
        mMediaRouterService = IMediaRouterService.Stub.asInterface(
                ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
        mMediaSessionManager = (MediaSessionManager) context
@@ -374,16 +376,17 @@ public final class MediaRouter2Manager {
    }

    /**
     * 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
     * route while BT route is available.)
     * Gets the system routing session for the given {@code targetPackageName}. Apps can select a
     * route that is not the global route. (e.g. an app can select the device route while BT route
     * is available.)
     *
     * @param packageName the package name of the application.
     * @param targetPackageName the package name of the application.
     */
    @Nullable
    public RoutingSessionInfo getSystemRoutingSession(@Nullable String packageName) {
    public RoutingSessionInfo getSystemRoutingSession(@Nullable String targetPackageName) {
        try {
            return mMediaRouterService.getSystemSessionInfoForPackage(packageName);
            return mMediaRouterService.getSystemSessionInfoForPackage(
                    mContext.getPackageName(), targetPackageName);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
+42 −19
Original line number Diff line number Diff line
@@ -221,18 +221,27 @@ class MediaRouter2ServiceImpl {
    // Start of methods that implement MediaRouter2 operations.

    @NonNull
    public List<MediaRoute2Info> getSystemRoutes() {
    public List<MediaRoute2Info> getSystemRoutes(@NonNull String callerPackageName,
            boolean isProxyRouter) {
        final int uid = Binder.getCallingUid();
        final int pid = Binder.getCallingPid();
        final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
        final boolean hasSystemRoutingPermission = checkCallerHasSystemRoutingPermissions(pid, uid);

        boolean hasSystemRoutingPermissions;
        if (!isProxyRouter) {
            hasSystemRoutingPermissions = checkCallerHasSystemRoutingPermissions(pid, uid);
        } else {
            // Request from ProxyRouter.
            hasSystemRoutingPermissions =
                    checkCallerHasPrivilegedRoutingPermissions(pid, uid, callerPackageName);
        }

        final long token = Binder.clearCallingIdentity();
        try {
            Collection<MediaRoute2Info> systemRoutes;
            synchronized (mLock) {
                UserRecord userRecord = getOrCreateUserRecordLocked(userId);
                if (hasSystemRoutingPermission) {
                if (hasSystemRoutingPermissions) {
                    MediaRoute2ProviderInfo providerInfo =
                            userRecord.mHandler.mSystemProvider.getProviderInfo();
                    if (providerInfo != null) {
@@ -795,12 +804,21 @@ class MediaRouter2ServiceImpl {

    @Nullable
    public RoutingSessionInfo getSystemSessionInfo(
            @Nullable String packageName, boolean setDeviceRouteSelected) {
            @NonNull String callerPackageName,
            @Nullable String targetPackageName,
            boolean setDeviceRouteSelected) {
        final int uid = Binder.getCallingUid();
        final int pid = Binder.getCallingPid();
        final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
        final boolean hasSystemRoutingPermissions =
                checkCallerHasSystemRoutingPermissions(pid, uid);

        boolean hasSystemRoutingPermissions;
        if (targetPackageName == null) {
            hasSystemRoutingPermissions = checkCallerHasSystemRoutingPermissions(pid, uid);
        } else {
            // Request from ProxyRouter.
            hasSystemRoutingPermissions =
                    checkCallerHasPrivilegedRoutingPermissions(pid, uid, callerPackageName);
        }

        final long token = Binder.clearCallingIdentity();
        try {
@@ -812,14 +830,14 @@ class MediaRouter2ServiceImpl {
                        // Return a fake system session that shows the device route as selected and
                        // available bluetooth routes as transferable.
                        return userRecord.mHandler.mSystemProvider
                                .generateDeviceRouteSelectedSessionInfo(packageName);
                                .generateDeviceRouteSelectedSessionInfo(targetPackageName);
                    } else {
                        sessionInfos = userRecord.mHandler.mSystemProvider.getSessionInfos();
                        if (!sessionInfos.isEmpty()) {
                            // Return a copy of the current system session with no modification,
                            // except setting the client package name.
                            return new RoutingSessionInfo.Builder(sessionInfos.get(0))
                                    .setClientPackageName(packageName)
                                    .setClientPackageName(targetPackageName)
                                    .build();
                        } else {
                            Slog.w(TAG, "System provider does not have any session info.");
@@ -828,7 +846,7 @@ class MediaRouter2ServiceImpl {
                } else {
                    return new RoutingSessionInfo.Builder(
                                    userRecord.mHandler.mSystemProvider.getDefaultSessionInfo())
                            .setClientPackageName(packageName)
                            .setClientPackageName(targetPackageName)
                            .build();
                }
            }
@@ -843,6 +861,12 @@ class MediaRouter2ServiceImpl {
                || checkCallerHasBluetoothPermissions(pid, uid);
    }

    private boolean checkCallerHasPrivilegedRoutingPermissions(
            int pid, int uid, @NonNull String callerPackageName) {
        return checkMediaContentControlPermission(uid, pid)
                || checkMediaRoutingControlPermission(uid, pid, callerPackageName);
    }

    private boolean checkCallerHasModifyAudioRoutingPermission(int pid, int uid) {
        return mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_ROUTING, pid, uid)
                == PackageManager.PERMISSION_GRANTED;
@@ -864,30 +888,29 @@ class MediaRouter2ServiceImpl {
                Manifest.permission.MEDIA_CONTENT_CONTROL
            })
    private void enforcePrivilegedRoutingPermissions(
            int callerUid, int callerPid, @Nullable String callerPackageName) {
        if (hasMediaContentControlPermission(callerUid, callerPid)) {
            int callerUid, int callerPid, @NonNull String callerPackageName) {
        if (checkMediaContentControlPermission(callerUid, callerPid)) {
            return;
        }

        if (!Flags.enablePrivilegedRoutingForMediaRoutingControl()) {
            throw new SecurityException("Must hold MEDIA_CONTENT_CONTROL");
        }

        if (!checkMediaRoutingControlPermission(callerUid, callerPid, callerPackageName)) {
            throw new SecurityException(
                    "Must hold MEDIA_CONTENT_CONTROL or MEDIA_ROUTING_CONTROL permissions.");
        }
    }

    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
    private boolean hasMediaContentControlPermission(int callerUid, int callerPid) {
    private boolean checkMediaContentControlPermission(int callerUid, int callerPid) {
        return mContext.checkPermission(
                        Manifest.permission.MEDIA_CONTENT_CONTROL, callerPid, callerUid)
                == PackageManager.PERMISSION_GRANTED;
    }

    private boolean checkMediaRoutingControlPermission(
            int callerUid, int callerPid, @Nullable String callerPackageName) {
            int callerUid, int callerPid, @NonNull String callerPackageName) {
        if (!Flags.enablePrivilegedRoutingForMediaRoutingControl()) {
            return false;
        }

        return PermissionChecker.checkPermissionForDataDelivery(
                        mContext,
                        Manifest.permission.MEDIA_ROUTING_CONTROL,
@@ -1520,7 +1543,7 @@ class MediaRouter2ServiceImpl {
        boolean hasMediaRoutingControl =
                checkMediaRoutingControlPermission(callerUid, callerPid, callerPackageName);

        boolean hasMediaContentControl = hasMediaContentControlPermission(callerUid, callerPid);
        boolean hasMediaContentControl = checkMediaContentControlPermission(callerUid, callerPid);

        Slog.i(
                TAG,
+19 −6
Original line number Diff line number Diff line
@@ -411,15 +411,21 @@ public final class MediaRouterService extends IMediaRouterService.Stub

    // Binder call
    @Override
    public List<MediaRoute2Info> getSystemRoutes() {
        return mService2.getSystemRoutes();
    public List<MediaRoute2Info> getSystemRoutes(@NonNull String callerPackageName,
            boolean isProxyRouter) {
        if (!validatePackageName(Binder.getCallingUid(), callerPackageName)) {
            throw new SecurityException("callerPackageName does not match calling uid.");
        }
        return mService2.getSystemRoutes(callerPackageName, isProxyRouter);
    }

    // Binder call
    @Override
    public RoutingSessionInfo getSystemSessionInfo() {
        return mService2.getSystemSessionInfo(
                null /* packageName */, false /* setDeviceRouteSelected */);
                /* callerPackageName */ null,
                /* targetPackageName */ null, /* setDeviceRouteSelected */
                false);
    }

    // Binder call
@@ -530,16 +536,22 @@ public final class MediaRouterService extends IMediaRouterService.Stub

    // Binder call
    @Override
    public RoutingSessionInfo getSystemSessionInfoForPackage(@Nullable String packageName) {
    public RoutingSessionInfo getSystemSessionInfoForPackage(
            @NonNull String callerPackageName, @Nullable String targetPackageName) {
        final int uid = Binder.getCallingUid();
        final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();

        if (!validatePackageName(uid, callerPackageName)) {
            throw new SecurityException("callerPackageName does not match calling uid.");
        }

        boolean setDeviceRouteSelected = false;
        synchronized (mLock) {
            UserRecord userRecord = mUserRecords.get(userId);
            List<ClientRecord> userClientRecords =
                    userRecord != null ? userRecord.mClientRecords : Collections.emptyList();
            for (ClientRecord clientRecord : userClientRecords) {
                if (TextUtils.equals(clientRecord.mPackageName, packageName)) {
                if (TextUtils.equals(clientRecord.mPackageName, targetPackageName)) {
                    if (mDefaultAudioRouteId.equals(clientRecord.mSelectedRouteId)) {
                        setDeviceRouteSelected = true;
                        break;
@@ -547,7 +559,8 @@ public final class MediaRouterService extends IMediaRouterService.Stub
                }
            }
        }
        return mService2.getSystemSessionInfo(packageName, setDeviceRouteSelected);
        return mService2.getSystemSessionInfo(
                callerPackageName, targetPackageName, setDeviceRouteSelected);
    }

    // Binder call