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

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

Add getter for system session overrides

This is necessary in case SysUI crashes and needs to restart while a
mirroring session is already ongoing.

Bug: b/396394220
Test: atest CtsMediaRouterTestCases
Flag: com.android.media.flags.enable_mirroring_in_media_router_2
Change-Id: Ic3866066124f5b4c63dd4569e419a0c1415c702b
parent f28693b0
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.media;

import android.content.Intent;
import android.media.AppId;
import android.media.IMediaRouter2;
import android.media.IMediaRouter2Manager;
import android.media.IMediaRouterClient;
@@ -87,6 +88,7 @@ interface IMediaRouterService {
    List<RoutingSessionInfo> getRemoteSessions(IMediaRouter2Manager manager);
    RoutingSessionInfo getSystemSessionInfoForPackage(String callerPackageName,
        String targetPackageName);
    List<AppId> getSystemSessionOverridesAppIds(IMediaRouter2Manager manager);
    void registerManager(IMediaRouter2Manager manager, String packageName);
    void registerProxyRouter(IMediaRouter2Manager manager, String callingPackageName, String targetPackageName, in UserHandle targetUser);
    void unregisterManager(IMediaRouter2Manager manager);
+57 −0
Original line number Diff line number Diff line
@@ -1318,6 +1318,18 @@ public final class MediaRouter2 {
        mImpl.setRouteVolume(route, volume);
    }

    /**
     * Returns the set of apps currently affected by a system session override.
     *
     * <p>This method is only supported by proxy routers.
     *
     * @see SystemSessionOverridesListener
     * @hide
     */
    public Set<AppId> getSystemSessionOverridesAppIds() {
        return mImpl.getSystemSessionOverridesAppIds();
    }

    void syncRoutesOnHandler(
            List<MediaRoute2Info> currentRoutes, RoutingSessionInfo currentSystemSessionInfo) {
        if (currentRoutes == null || currentRoutes.isEmpty() || currentSystemSessionInfo == null) {
@@ -2971,6 +2983,13 @@ public final class MediaRouter2 {
         * @param listener The listener to unregister.
         */
        void unregisterSystemSessionOverridesListener(SystemSessionOverridesListener listener);

        /**
         * Returns the set of apps affected by a system session override.
         *
         * @see SystemSessionOverridesListener
         */
        Set<AppId> getSystemSessionOverridesAppIds();
    }

    /**
@@ -3002,6 +3021,17 @@ public final class MediaRouter2 {
        private final List<InstanceInvalidatedCallbackRecord> mInstanceInvalidatedCallbackRecords =
                new ArrayList<>();

        /**
         * Holds the last snapshot of ids of apps affected by a system session override.
         *
         * <p>Must hold an immutable set to avoid the need for a copy in {@link
         * #getSystemSessionOverridesAppIds}.
         *
         * @see SystemSessionOverridesListener
         */
        @GuardedBy("mLock")
        private Set<AppId> mLastSystemSessionSessionOverridesLocked = Set.of();

        ProxyMediaRouter2Impl(
                @NonNull Context context,
                @NonNull String clientPackageName,
@@ -3019,11 +3049,22 @@ public final class MediaRouter2 {
                        mContext.getApplicationContext().getPackageName(),
                        mClientPackageName,
                        mClientUser);
                initSystemSessionOverridesSnapshot();
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }

        private void initSystemSessionOverridesSnapshot() throws RemoteException {
            if (!Flags.enableMirroringInMediaRouter2()) {
                return;
            }
            synchronized (mLock) {
                mLastSystemSessionSessionOverridesLocked =
                        Set.copyOf(mMediaRouterService.getSystemSessionOverridesAppIds(mClient));
            }
        }

        public void registerInstanceInvalidatedCallback(
                @Nullable Executor executor, @Nullable Runnable onInstanceInvalidatedListener) {
            if (executor == null || onInstanceInvalidatedListener == null) {
@@ -3601,6 +3642,13 @@ public final class MediaRouter2 {
                            /* executor= */ Runnable::run, listener));
        }

        @Override
        public Set<AppId> getSystemSessionOverridesAppIds() {
            synchronized (mLock) {
                return mLastSystemSessionSessionOverridesLocked;
            }
        }

        /**
         * Retrieves the system session info for the given package.
         *
@@ -3921,6 +3969,9 @@ public final class MediaRouter2 {

        private void notifySystemSessionOverridesChangedOnHandler(List<AppId> appsWithOverrides) {
            var appsWithOverridesAsSet = Set.copyOf(appsWithOverrides);
            synchronized (mLock) {
                mLastSystemSessionSessionOverridesLocked = appsWithOverridesAsSet;
            }
            for (var record : mSystemSessionOverridesListenerRecords) {
                record.mExecutor.execute(
                        () ->
@@ -4436,6 +4487,12 @@ public final class MediaRouter2 {
                    "unregisterSystemSessionOverridesListener is only supported on proxy routers.");
        }

        @Override
        public Set<AppId> getSystemSessionOverridesAppIds() {
            throw new UnsupportedOperationException(
                    "getAppsWithSystemSessionOverrides is only supported on proxy routers.");
        }

        @GuardedBy("mLock")
        private void registerRouterStubIfNeededLocked() throws RemoteException {
            if (mStub == null) {
+52 −13
Original line number Diff line number Diff line
@@ -667,6 +667,19 @@ class MediaRouter2ServiceImpl {
        }
    }

    @NonNull
    public List<AppId> getSystemSessionOverridesAppIds(@NonNull IMediaRouter2Manager manager) {
        Objects.requireNonNull(manager, "manager must not be null");
        final long token = Binder.clearCallingIdentity();
        try {
            synchronized (mLock) {
                return getSystemSessionOverridesAppIdsLocked(manager);
            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
    public void registerManager(@NonNull IMediaRouter2Manager manager,
            @NonNull String callerPackageName) {
@@ -1860,6 +1873,18 @@ class MediaRouter2ServiceImpl {
        return sessionInfos;
    }

    @GuardedBy("mLock")
    public List<AppId> getSystemSessionOverridesAppIdsLocked(
            @NonNull IMediaRouter2Manager manager) {
        IBinder binder = manager.asBinder();
        ManagerRecord managerRecord = mAllManagerRecords.get(binder);
        if (managerRecord == null) {
            Slog.w(TAG, "getSystemSessionOverridesAppIdsLocked: Ignoring unknown manager");
            return Collections.emptyList();
        }
        return managerRecord.mUserRecord.getAppsWithSystemOverridesLocked();
    }

    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
    @GuardedBy("mLock")
    private void registerManagerLocked(
@@ -2410,7 +2435,8 @@ class MediaRouter2ServiceImpl {
        private final ArrayList<RouterRecord> mRouterRecords = new ArrayList<>();
        final ArrayList<ManagerRecord> mManagerRecords = new ArrayList<>();

        private final Set<String> mLastPackagesWithSystemOverridesOnHandler = new ArraySet<>();
        // @GuardedBy("mLock")
        private final Set<String> mLastPackagesWithSystemOverridesLocked = new ArraySet<>();

        // @GuardedBy("mLock")
        private final Map<String, Map<String, List<SuggestedDeviceInfo>>> mDeviceSuggestions =
@@ -2463,6 +2489,19 @@ class MediaRouter2ServiceImpl {
            return false;
        }

        @GuardedBy("mLock")
        private List<AppId> getAppsWithSystemOverridesLocked() {
            return mapPackageNamesToAppIdList(mLastPackagesWithSystemOverridesLocked);
        }

        /**
         * Returns a list of {@link AppId app ids} corresponding to the given package names, created
         * by associating each package name with {@link #mUserHandle}.
         */
        private List<AppId> mapPackageNamesToAppIdList(Collection<String> packageNames) {
            return packageNames.stream().map(it -> new AppId(it, mUserHandle)).toList();
        }

        // @GuardedBy("mLock")
        public void updateDeviceSuggestionsLocked(
                String packageName,
@@ -3819,20 +3858,20 @@ class MediaRouter2ServiceImpl {
                boolean shouldShowVolumeUi) {
            List<ManagerRecord> managers = getManagerRecords();
            List<AppId> appsWithOverridesToReport = null;

            boolean isGlobalSession = TextUtils.isEmpty(sessionInfo.getClientPackageName());
            synchronized (mLock) {
                if (isGlobalSession
                        && !Objects.equals(
                            mUserRecord.mLastPackagesWithSystemOverridesOnHandler,
                                mUserRecord.mLastPackagesWithSystemOverridesLocked,
                                packageNamesWithRoutingSessionOverrides)) {
                    appsWithOverridesToReport =
                        packageNamesWithRoutingSessionOverrides.stream()
                                .map(it -> new AppId(it, mUserRecord.mUserHandle))
                                .toList();
                mUserRecord.mLastPackagesWithSystemOverridesOnHandler.clear();
                mUserRecord.mLastPackagesWithSystemOverridesOnHandler.addAll(
                            mUserRecord.mapPackageNamesToAppIdList(
                                    packageNamesWithRoutingSessionOverrides);
                    mUserRecord.mLastPackagesWithSystemOverridesLocked.clear();
                    mUserRecord.mLastPackagesWithSystemOverridesLocked.addAll(
                            packageNamesWithRoutingSessionOverrides);
                }
            }
            for (ManagerRecord manager : managers) {
                if (Flags.enableMirroringInMediaRouter2()) {
                    if (appsWithOverridesToReport != null) {
+7 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.media.AppId;
import android.media.AudioPlaybackConfiguration;
import android.media.AudioRoutesInfo;
import android.media.AudioSystem;
@@ -605,6 +606,12 @@ public final class MediaRouterService extends IMediaRouterService.Stub
                callerPackageName, targetPackageName, setDeviceRouteSelected);
    }

    // Binder call
    @Override
    public List<AppId> getSystemSessionOverridesAppIds(IMediaRouter2Manager manager) {
        return mService2.getSystemSessionOverridesAppIds(manager);
    }

    // Binder call
    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
    @Override