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

Commit 56bc7795 authored by Kyunglyul Hyun's avatar Kyunglyul Hyun
Browse files

MediaRouterService binds services when necessary

MediaRouterService maintained bindings to provider services
once those are established.

With this CL, it only binds services when there is a non-empty
discovery preference set by a foreground app or an app is casting.

This change may break output switcher, which enables transfer media
of background apps.

To alleviate that MediaRouter2Manager#startScan and #stopScan are added
so that system UI can force the service bind to the services and find
remote devices to cast.

Bug: 169575701
Bug: 172920557

Test: manually and CTS
Change-Id: I4a47fdb1c9fe05a04d26950485833c9cbfb91a69
(cherry picked from commit 9f889ca4)
(cherry picked from commit 602b168f)
parent 65929722
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -73,6 +73,8 @@ interface IMediaRouterService {
    void unregisterManager(IMediaRouter2Manager manager);
    void setRouteVolumeWithManager(IMediaRouter2Manager manager, int requestId,
            in MediaRoute2Info route, int volume);
    void startScan(IMediaRouter2Manager manager);
    void stopScan(IMediaRouter2Manager manager);

    void requestCreateSessionWithManager(IMediaRouter2Manager manager, int requestId,
            in RoutingSessionInfo oldSession, in @nullable MediaRoute2Info route);
+30 −0
Original line number Diff line number Diff line
@@ -146,6 +146,36 @@ public final class MediaRouter2Manager {
        }
    }

    /**
     * Starts scanning remote routes.
     * @see #stopScan(String)
     */
    public void startScan() {
        Client client = getOrCreateClient();
        if (client != null) {
            try {
                mMediaRouterService.startScan(client);
            } catch (RemoteException ex) {
                Log.e(TAG, "Unable to get sessions. Service probably died.", ex);
            }
        }
    }

    /**
     * Stops scanning remote routes to reduce resource consumption.
     * @see #startScan(String)
     */
    public void stopScan() {
        Client client = getOrCreateClient();
        if (client != null) {
            try {
                mMediaRouterService.stopScan(client);
            } catch (RemoteException ex) {
                Log.e(TAG, "Unable to get sessions. Service probably died.", ex);
            }
        }
    }

    /**
     * Gets a {@link android.media.session.MediaController} associated with the
     * given routing session.
+1 −0
Original line number Diff line number Diff line
@@ -153,6 +153,7 @@ public final class RouteDiscoveryPreference implements Parcelable {
            return false;
        }
        RouteDiscoveryPreference other = (RouteDiscoveryPreference) o;
        //TODO: Make this order-free
        return Objects.equals(mPreferredFeatures, other.mPreferredFeatures)
                && mShouldPerformActiveScan == other.mShouldPerformActiveScan;
    }
+11 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.media.MediaMetadata;
import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
import android.media.RoutingSessionInfo;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
@@ -76,6 +77,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
    private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>();
    private final boolean mAboveStatusbar;
    private final NotificationEntryManager mNotificationEntryManager;
    private final MediaRouter2Manager mRouterManager;
    @VisibleForTesting
    final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();

@@ -92,7 +94,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
    public MediaOutputController(@NonNull Context context, String packageName,
            boolean aboveStatusbar, MediaSessionManager mediaSessionManager, LocalBluetoothManager
            lbm, ShadeController shadeController, ActivityStarter starter,
            NotificationEntryManager notificationEntryManager, UiEventLogger uiEventLogger) {
            NotificationEntryManager notificationEntryManager, UiEventLogger uiEventLogger,
            MediaRouter2Manager routerManager) {
        mContext = context;
        mPackageName = packageName;
        mMediaSessionManager = mediaSessionManager;
@@ -104,6 +107,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
        mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, packageName);
        mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
        mUiEventLogger = uiEventLogger;
        mRouterManager = routerManager;
    }

    void start(@NonNull Callback cb) {
@@ -134,6 +138,9 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
        mLocalMediaManager.stopScan();
        mLocalMediaManager.registerCallback(this);
        mLocalMediaManager.startScan();
        if (mRouterManager != null) {
            mRouterManager.startScan();
        }
    }

    void stop() {
@@ -144,6 +151,9 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
            mLocalMediaManager.unregisterCallback(this);
            mLocalMediaManager.stopScan();
        }
        if (mRouterManager != null) {
            mRouterManager.stopScan();
        }
        mMediaDevices.clear();
    }

+4 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.media.dialog

import android.content.Context
import android.media.session.MediaSessionManager
import android.media.MediaRouter2Manager
import com.android.internal.logging.UiEventLogger
import com.android.settingslib.bluetooth.LocalBluetoothManager
import com.android.systemui.plugins.ActivityStarter
@@ -35,7 +36,8 @@ class MediaOutputDialogFactory @Inject constructor(
    private val shadeController: ShadeController,
    private val starter: ActivityStarter,
    private val notificationEntryManager: NotificationEntryManager,
    private val uiEventLogger: UiEventLogger
    private val uiEventLogger: UiEventLogger,
    private val routerManager: MediaRouter2Manager
) {
    companion object {
        var mediaOutputDialog: MediaOutputDialog? = null
@@ -46,7 +48,7 @@ class MediaOutputDialogFactory @Inject constructor(
        mediaOutputDialog?.dismiss()
        mediaOutputDialog = MediaOutputController(context, packageName, aboveStatusBar,
                mediaSessionManager, lbm, shadeController, starter, notificationEntryManager,
                uiEventLogger).run {
                uiEventLogger, routerManager).run {
            MediaOutputDialog(context, aboveStatusBar, this, uiEventLogger)
        }
    }
Loading