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

Commit 0aec178b authored by Eric Laurent's avatar Eric Laurent
Browse files

Revert "Fix overactive media routing"

This reverts commit 18341301.

NullPointerException when converting prevState to int with prevState == null at line 171 in AudioPlayerStateMonitor.java

Bug: 68748062
Bug: 65376604
Change-Id: Ib4b457e890a7ee8d9e347df7042dbad5e3018031
parent 18341301
Loading
Loading
Loading
Loading
+289 −0
Original line number Original line Diff line number Diff line
@@ -16,23 +16,20 @@


package com.android.server.media;
package com.android.server.media;


import android.annotation.Nullable;
import android.content.Context;
import android.content.Context;
import android.media.AudioManager.AudioPlaybackCallback;
import android.media.AudioPlaybackConfiguration;
import android.media.AudioPlaybackConfiguration;
import android.media.IAudioService;
import android.media.IAudioService;
import android.media.IPlaybackConfigDispatcher;
import android.media.IPlaybackConfigDispatcher;
import android.os.Binder;
import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserHandle;
import android.util.IntArray;
import android.util.IntArray;
import android.util.Log;
import android.util.Log;

import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;


import java.io.PrintWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.HashSet;
import java.util.HashMap;
import java.util.HashMap;
import java.util.List;
import java.util.List;
@@ -40,70 +37,58 @@ import java.util.Map;
import java.util.Set;
import java.util.Set;


/**
/**
 * Monitors the state changes of audio players.
 * Monitors changes in audio playback, and notify the newly started audio playback through the
 * {@link OnAudioPlaybackStartedListener} and the activeness change through the
 * {@link OnAudioPlaybackActiveStateListener}.
 */
 */
class AudioPlayerStateMonitor extends IPlaybackConfigDispatcher.Stub {
class AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub {
    private static boolean DEBUG = MediaSessionService.DEBUG;
    private static boolean DEBUG = MediaSessionService.DEBUG;
    private static String TAG = "AudioPlayerStateMonitor";
    private static String TAG = "AudioPlaybackMonitor";


    private static AudioPlayerStateMonitor sInstance = new AudioPlayerStateMonitor();
    private static AudioPlaybackMonitor sInstance;


    /**
    /**
     * Called when the state of audio player is changed.
     * Called when audio playback is started for a given UID.
     */
     */
    interface OnAudioPlayerStateChangedListener {
    interface OnAudioPlaybackStartedListener {
        void onAudioPlayerStateChanged(
        void onAudioPlaybackStarted(int uid);
                int uid, int prevState, @Nullable AudioPlaybackConfiguration config);
    }

    private final static class MessageHandler extends Handler {
        private static final int MSG_AUDIO_PLAYER_STATE_CHANGED = 1;

        private final OnAudioPlayerStateChangedListener mListsner;

        public MessageHandler(Looper looper, OnAudioPlayerStateChangedListener listener) {
            super(looper);
            mListsner = listener;
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_AUDIO_PLAYER_STATE_CHANGED:
                    mListsner.onAudioPlayerStateChanged(
                            msg.arg1, msg.arg2, (AudioPlaybackConfiguration) msg.obj);
                    break;
            }
    }
    }


        public void sendAudioPlayerStateChangedMessage(int uid, int prevState,
    /**
                AudioPlaybackConfiguration config) {
     * Called when audio player state is changed.
            obtainMessage(MSG_AUDIO_PLAYER_STATE_CHANGED, uid, prevState, config).sendToTarget();
     */
        }
    interface OnAudioPlayerActiveStateChangedListener {
        void onAudioPlayerActiveStateChanged(int uid, boolean active);
    }
    }


    private final Object mLock = new Object();
    private final Object mLock = new Object();
    @GuardedBy("mLock")
    private final Context mContext;
    private final Map<OnAudioPlayerStateChangedListener, MessageHandler> mListenerMap =
    private final List<OnAudioPlaybackStartedListener> mAudioPlaybackStartedListeners
            new HashMap<>();
            = new ArrayList<>();
    @GuardedBy("mLock")
    private final List<OnAudioPlayerActiveStateChangedListener>
    private final Map<Integer, Integer> mAudioPlayerStates = new HashMap<>();
            mAudioPlayerActiveStateChangedListeners = new ArrayList<>();
    @GuardedBy("mLock")
    private final Map<Integer, Integer> mAudioPlaybackStates = new HashMap<>();
    private final Map<Integer, HashSet<Integer>> mAudioPlayersForUid = new HashMap<>();
    private final Set<Integer> mActiveAudioPlaybackClientUids = new HashSet<>();

    // Sorted array of UIDs that had active audio playback. (i.e. playing an audio/video)
    // Sorted array of UIDs that had active audio playback. (i.e. playing an audio/video)
    // The UID whose audio playback becomes active at the last comes first.
    // The UID whose audio playback becomes active at the last comes first.
    // TODO(b/35278867): Find and use unique identifier for apps because apps may share the UID.
    // TODO(b/35278867): Find and use unique identifier for apps because apps may share the UID.
    @GuardedBy("mLock")
    private final IntArray mSortedAudioPlaybackClientUids = new IntArray();
    private final IntArray mSortedAudioPlaybackClientUids = new IntArray();


    @GuardedBy("mLock")
    static AudioPlaybackMonitor getInstance(Context context, IAudioService audioService) {
    private boolean mRegisteredToAudioService;
        if (sInstance == null) {

            sInstance = new AudioPlaybackMonitor(context, audioService);
    static AudioPlayerStateMonitor getInstance() {
        }
        return sInstance;
        return sInstance;
    }
    }


    private AudioPlayerStateMonitor() {
    private AudioPlaybackMonitor(Context context, IAudioService audioService) {
        mContext = context;
        try {
            audioService.registerPlaybackCallback(this);
        } catch (RemoteException e) {
            Log.wtf(TAG, "Failed to register playback callback", e);
        }
    }
    }


    /**
    /**
@@ -122,78 +107,69 @@ class AudioPlayerStateMonitor extends IPlaybackConfigDispatcher.Stub {
        }
        }
        final long token = Binder.clearCallingIdentity();
        final long token = Binder.clearCallingIdentity();
        try {
        try {
            final Map<Integer, Integer> prevAudioPlayerStates = new HashMap<>(mAudioPlayerStates);
            List<Integer> newActiveAudioPlaybackClientUids = new ArrayList<>();
            final Map<Integer, HashSet<Integer>> prevAudioPlayersForUid =
            List<OnAudioPlayerActiveStateChangedListener> audioPlayerActiveStateChangedListeners;
                    new HashMap<>(mAudioPlayersForUid);
            List<OnAudioPlaybackStartedListener> audioPlaybackStartedListeners;
            synchronized (mLock) {
            synchronized (mLock) {
                mAudioPlayerStates.clear();
                // Update mActiveAudioPlaybackClientUids and mSortedAudioPlaybackClientUids,
                mAudioPlayersForUid.clear();
                // and find newly activated audio playbacks.
                mActiveAudioPlaybackClientUids.clear();
                for (AudioPlaybackConfiguration config : configs) {
                for (AudioPlaybackConfiguration config : configs) {
                    int pii = config.getPlayerInterfaceId();
                    // Ignore inactive (i.e. not playing) or PLAYER_TYPE_JAM_SOUNDPOOL
                    int uid = config.getClientUid();
                    // (i.e. playback from the SoundPool class which is only for sound effects)
                    mAudioPlayerStates.put(pii, config.getPlayerState());
                    // playback.
                    HashSet<Integer> players = mAudioPlayersForUid.get(uid);
                    // Note that we shouldn't ignore PLAYER_TYPE_UNKNOWN because it might be OEM
                    if (players == null) {
                    // specific audio/video players.
                        players = new HashSet<Integer>();
                    if (!config.isActive() || config.getPlayerType()
                        players.add(pii);
                            == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
                        mAudioPlayersForUid.put(uid, players);
                    } else {
                        players.add(pii);
                    }
                }
                for (AudioPlaybackConfiguration config : configs) {
                    if (!config.isActive()) {
                        continue;
                        continue;
                    }
                    }


                    int uid = config.getClientUid();
                    mActiveAudioPlaybackClientUids.add(config.getClientUid());
                    if (!isActiveState(prevAudioPlayerStates.get(config.getPlayerInterfaceId()))) {
                    Integer oldState = mAudioPlaybackStates.get(config.getPlayerInterfaceId());
                    if (!isActiveState(oldState)) {
                        if (DEBUG) {
                        if (DEBUG) {
                            Log.d(TAG, "Found a new active media playback. " +
                            Log.d(TAG, "Found a new active media playback. " +
                                    AudioPlaybackConfiguration.toLogFriendlyString(config));
                                    AudioPlaybackConfiguration.toLogFriendlyString(config));
                        }
                        }
                        // New active audio playback.
                        // New active audio playback.
                        int index = mSortedAudioPlaybackClientUids.indexOf(uid);
                        newActiveAudioPlaybackClientUids.add(config.getClientUid());
                        int index = mSortedAudioPlaybackClientUids.indexOf(config.getClientUid());
                        if (index == 0) {
                        if (index == 0) {
                            // It's the lastly played music app already. Skip updating.
                            // It's the lastly played music app already. Skip updating.
                            continue;
                            continue;
                        } else if (index > 0) {
                        } else if (index > 0) {
                            mSortedAudioPlaybackClientUids.remove(index);
                            mSortedAudioPlaybackClientUids.remove(index);
                        }
                        }
                        mSortedAudioPlaybackClientUids.add(0, uid);
                        mSortedAudioPlaybackClientUids.add(0, config.getClientUid());
                    }
                }
                }
                audioPlayerActiveStateChangedListeners = new ArrayList<>(
                        mAudioPlayerActiveStateChangedListeners);
                audioPlaybackStartedListeners = new ArrayList<>(mAudioPlaybackStartedListeners);
            }
            }
                // Notify the change of audio player states.
            // Notify the change of audio playback states.
            for (AudioPlaybackConfiguration config : configs) {
            for (AudioPlaybackConfiguration config : configs) {
                    Integer prevState = prevAudioPlayerStates.get(config.getPlayerInterfaceId());
                boolean wasActive = isActiveState(
                    if (prevState == null || prevState != config.getPlayerState()) {
                        mAudioPlaybackStates.get(config.getPlayerInterfaceId()));
                        sendAudioPlayerStateChangedMessageLocked(
                boolean isActive = config.isActive();
                                config.getClientUid(), prevState, config);
                if (wasActive != isActive) {
                    }
                    for (OnAudioPlayerActiveStateChangedListener listener
                }
                            : audioPlayerActiveStateChangedListeners) {
                for (Integer prevUid : prevAudioPlayersForUid.keySet()) {
                        listener.onAudioPlayerActiveStateChanged(config.getClientUid(),
                    // If all players for prevUid is removed, notify the prev state was
                                isActive);
                    // PLAYER_STATE_STARTED only when there were a player whose state was
                    // PLAYER_STATE_STARTED, otherwise any inactive state is okay to notify.
                    if (!mAudioPlayersForUid.containsKey(prevUid)) {
                        Set<Integer> players = mAudioPlayersForUid.get(prevUid);
                        int prevState = AudioPlaybackConfiguration.PLAYER_STATE_UNKNOWN;
                        for (int pii : players) {
                            Integer state = prevAudioPlayerStates.get(pii);
                            if (state == null) {
                                continue;
                    }
                    }
                            if (state == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
                                prevState = state;
                                break;
                            } else if (prevState
                                    == AudioPlaybackConfiguration.PLAYER_STATE_UNKNOWN) {
                                prevState = state;
                }
                }
            }
            }
                        sendAudioPlayerStateChangedMessageLocked(prevUid, prevState, null);
            // Notify the start of audio playback
            for (int uid : newActiveAudioPlaybackClientUids) {
                for (OnAudioPlaybackStartedListener listener : audioPlaybackStartedListeners) {
                    listener.onAudioPlaybackStarted(uid);
                }
                }
            }
            }
            mAudioPlaybackStates.clear();
            for (AudioPlaybackConfiguration config : configs) {
                mAudioPlaybackStates.put(config.getPlayerInterfaceId(), config.getPlayerState());
            }
            }
        } finally {
        } finally {
            Binder.restoreCallingIdentity(token);
            Binder.restoreCallingIdentity(token);
@@ -201,21 +177,40 @@ class AudioPlayerStateMonitor extends IPlaybackConfigDispatcher.Stub {
    }
    }


    /**
    /**
     * Registers OnAudioPlayerStateChangedListener.
     * Registers OnAudioPlaybackStartedListener.
     */
     */
    public void registerListener(OnAudioPlayerStateChangedListener listener, Handler handler) {
    public void registerOnAudioPlaybackStartedListener(OnAudioPlaybackStartedListener listener) {
        synchronized (mLock) {
        synchronized (mLock) {
            mListenerMap.put(listener, new MessageHandler((handler == null) ?
            mAudioPlaybackStartedListeners.add(listener);
                    Looper.myLooper() : handler.getLooper(), listener));
        }
        }
    }
    }


    /**
    /**
     * Unregisters OnAudioPlayerStateChangedListener.
     * Unregisters OnAudioPlaybackStartedListener.
     */
     */
    public void unregisterListener(OnAudioPlayerStateChangedListener listener) {
    public void unregisterOnAudioPlaybackStartedListener(OnAudioPlaybackStartedListener listener) {
        synchronized (mLock) {
        synchronized (mLock) {
            mListenerMap.remove(listener);
            mAudioPlaybackStartedListeners.remove(listener);
        }
    }

    /**
     * Registers OnAudioPlayerActiveStateChangedListener.
     */
    public void registerOnAudioPlayerActiveStateChangedListener(
            OnAudioPlayerActiveStateChangedListener listener) {
        synchronized (mLock) {
            mAudioPlayerActiveStateChangedListeners.add(listener);
        }
    }

    /**
     * Unregisters OnAudioPlayerActiveStateChangedListener.
     */
    public void unregisterOnAudioPlayerActiveStateChangedListener(
            OnAudioPlayerActiveStateChangedListener listener) {
        synchronized (mLock) {
            mAudioPlayerActiveStateChangedListeners.remove(listener);
        }
        }
    }
    }


@@ -236,24 +231,15 @@ class AudioPlayerStateMonitor extends IPlaybackConfigDispatcher.Stub {
     */
     */
    public boolean isPlaybackActive(int uid) {
    public boolean isPlaybackActive(int uid) {
        synchronized (mLock) {
        synchronized (mLock) {
            Set<Integer> players = mAudioPlayersForUid.get(uid);
            return mActiveAudioPlaybackClientUids.contains(uid);
            if (players == null) {
                return false;
            }
            for (Integer pii : players) {
                if (isActiveState(mAudioPlayerStates.get(pii))) {
                    return true;
                }
            }
            return false;
        }
        }
    }
    }


    /**
    /**
     * Cleans up the sorted list of audio playback client UIDs with given {@param
     * Cleans up the sorted list of audio playback client UIDs with given {@param
     * mediaButtonSessionUid}.
     * mediaButtonSessionUid}.
     * <p>UIDs whose audio playback are inactive and have started before the media button session's
     * <p>UIDs whose audio playback started after the media button session's audio playback
     * audio playback cannot be the lastly played media app. So they won't needed anymore.
     * cannot be the lastly played media app. So they won't needed anymore.
     *
     *
     * @param mediaButtonSessionUid UID of the media button session.
     * @param mediaButtonSessionUid UID of the media button session.
     */
     */
@@ -277,16 +263,16 @@ class AudioPlayerStateMonitor extends IPlaybackConfigDispatcher.Stub {
    }
    }


    /**
    /**
     * Dumps {@link AudioPlayerStateMonitor}.
     * Dumps {@link AudioPlaybackMonitor}.
     */
     */
    public void dump(Context context, PrintWriter pw, String prefix) {
    public void dump(PrintWriter pw, String prefix) {
        synchronized (mLock) {
        synchronized (mLock) {
            pw.println(prefix + "Audio playback (lastly played comes first)");
            pw.println(prefix + "Audio playback (lastly played comes first)");
            String indent = prefix + "  ";
            String indent = prefix + "  ";
            for (int i = 0; i < mSortedAudioPlaybackClientUids.size(); i++) {
            for (int i = 0; i < mSortedAudioPlaybackClientUids.size(); i++) {
                int uid = mSortedAudioPlaybackClientUids.get(i);
                int uid = mSortedAudioPlaybackClientUids.get(i);
                pw.print(indent + "uid=" + uid + " packages=");
                pw.print(indent + "uid=" + uid + " packages=");
                String[] packages = context.getPackageManager().getPackagesForUid(uid);
                String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
                if (packages != null && packages.length > 0) {
                if (packages != null && packages.length > 0) {
                    for (int j = 0; j < packages.length; j++) {
                    for (int j = 0; j < packages.length; j++) {
                        pw.print(packages[j] + " ");
                        pw.print(packages[j] + " ");
@@ -297,28 +283,7 @@ class AudioPlayerStateMonitor extends IPlaybackConfigDispatcher.Stub {
        }
        }
    }
    }


    public void registerSelfIntoAudioServiceIfNeeded(IAudioService audioService) {
    private boolean isActiveState(Integer state) {
        synchronized (mLock) {
            try {
                if (!mRegisteredToAudioService) {
                    audioService.registerPlaybackCallback(this);
                    mRegisteredToAudioService = true;
                }
            } catch (RemoteException e) {
                Log.wtf(TAG, "Failed to register playback callback", e);
                mRegisteredToAudioService = false;
            }
        }
    }

    private void sendAudioPlayerStateChangedMessageLocked(
            final int uid, final int prevState, final AudioPlaybackConfiguration config) {
        for (MessageHandler messageHandler : mListenerMap.values()) {
            messageHandler.sendAudioPlayerStateChangedMessage(uid, prevState, config);
        }
    }

    private static boolean isActiveState(Integer state) {
        return state != null && state.equals(AudioPlaybackConfiguration.PLAYER_STATE_STARTED);
        return state != null && state.equals(AudioPlaybackConfiguration.PLAYER_STATE_STARTED);
    }
    }
}
}
+24 −50
Original line number Original line Diff line number Diff line
@@ -19,14 +19,12 @@ package com.android.server.media;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.DumpUtils;
import com.android.server.Watchdog;
import com.android.server.Watchdog;


import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.media.AudioPlaybackConfiguration;
import android.media.AudioRoutesInfo;
import android.media.AudioRoutesInfo;
import android.media.AudioSystem;
import android.media.AudioSystem;
import android.media.IAudioRoutesObserver;
import android.media.IAudioRoutesObserver;
@@ -98,8 +96,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
    private int mCurrentUserId = -1;
    private int mCurrentUserId = -1;
    private boolean mGlobalBluetoothA2dpOn = false;
    private boolean mGlobalBluetoothA2dpOn = false;
    private final IAudioService mAudioService;
    private final IAudioService mAudioService;
    private final AudioPlayerStateMonitor mAudioPlayerStateMonitor;
    private final AudioPlaybackMonitor mAudioPlaybackMonitor;
    private final Handler mHandler = new Handler();
    private final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo();
    private final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo();


    public MediaRouterService(Context context) {
    public MediaRouterService(Context context) {
@@ -109,57 +106,31 @@ public final class MediaRouterService extends IMediaRouterService.Stub
        mAudioService = IAudioService.Stub.asInterface(
        mAudioService = IAudioService.Stub.asInterface(
                ServiceManager.getService(Context.AUDIO_SERVICE));
                ServiceManager.getService(Context.AUDIO_SERVICE));


        mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance();
        mAudioPlaybackMonitor = AudioPlaybackMonitor.getInstance(context, mAudioService);
        mAudioPlayerStateMonitor.registerListener(
        mAudioPlaybackMonitor.registerOnAudioPlayerActiveStateChangedListener(
                new AudioPlayerStateMonitor.OnAudioPlayerStateChangedListener() {
                new AudioPlaybackMonitor.OnAudioPlayerActiveStateChangedListener() {
            static final long WAIT_MS = 500;
            final Runnable mRestoreBluetoothA2dpRunnable = new Runnable() {
            @Override
            @Override
                public void run() {
            public void onAudioPlayerActiveStateChanged(int uid, boolean active) {
                    restoreBluetoothA2dp();
                }
            };

            @Override
            public void onAudioPlayerStateChanged(
                    int uid, int prevState, @Nullable AudioPlaybackConfiguration config) {
                int restoreUid = -1;
                boolean active = config == null ? false : config.isActive();
                if (active) {
                if (active) {
                    restoreUid = uid;
                    restoreRoute(uid);
                } else if (prevState != AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
                    // Noting to do if the prev state is not an active state.
                    return;
                } else {
                } else {
                    IntArray sortedAudioPlaybackClientUids =
                    IntArray sortedAudioPlaybackClientUids =
                            mAudioPlayerStateMonitor.getSortedAudioPlaybackClientUids();
                            mAudioPlaybackMonitor.getSortedAudioPlaybackClientUids();
                    for (int i = 0; i < sortedAudioPlaybackClientUids.size(); ++i) {
                    boolean restored = false;
                        if (mAudioPlayerStateMonitor.isPlaybackActive(
                    for (int i = 0; i < sortedAudioPlaybackClientUids.size(); i++) {
                        if (mAudioPlaybackMonitor.isPlaybackActive(
                                sortedAudioPlaybackClientUids.get(i))) {
                                sortedAudioPlaybackClientUids.get(i))) {
                            restoreUid = sortedAudioPlaybackClientUids.get(i);
                            restoreRoute(sortedAudioPlaybackClientUids.get(i));
                            restored = true;
                            break;
                            break;
                        }
                        }
                    }
                    }
                }
                    if (!restored) {

                        restoreBluetoothA2dp();
                mHandler.removeCallbacks(mRestoreBluetoothA2dpRunnable);
                if (restoreUid >= 0) {
                    restoreRoute(restoreUid);
                    if (DEBUG) {
                        Slog.d(TAG, "onAudioPlayerStateChanged: " + "uid " + uid
                                + " active " + active + " restoring " + restoreUid);
                    }
                } else {
                    mHandler.postDelayed(mRestoreBluetoothA2dpRunnable, WAIT_MS);
                    if (DEBUG) {
                        Slog.d(TAG, "onAudioPlayerStateChanged: " + "uid " + uid
                                + " active " + active + " delaying");
                    }
                    }
                }
                }
            }
            }
        }, mHandler);
        });
        mAudioPlayerStateMonitor.registerSelfIntoAudioServiceIfNeeded(mAudioService);

        AudioRoutesInfo audioRoutes = null;
        AudioRoutesInfo audioRoutes = null;
        try {
        try {
            audioRoutes = mAudioService.startWatchingRoutes(new IAudioRoutesObserver.Stub() {
            audioRoutes = mAudioService.startWatchingRoutes(new IAudioRoutesObserver.Stub() {
@@ -290,14 +261,9 @@ public final class MediaRouterService extends IMediaRouterService.Stub


        final long token = Binder.clearCallingIdentity();
        final long token = Binder.clearCallingIdentity();
        try {
        try {
            ClientRecord clientRecord;
            synchronized (mLock) {
            synchronized (mLock) {
                clientRecord = mAllClientRecords.get(client.asBinder());
                return isPlaybackActiveLocked(client);
            }
            }
            if (clientRecord != null) {
                return mAudioPlayerStateMonitor.isPlaybackActive(clientRecord.mUid);
            }
            return false;
        } finally {
        } finally {
            Binder.restoreCallingIdentity(token);
            Binder.restoreCallingIdentity(token);
        }
        }
@@ -514,6 +480,14 @@ public final class MediaRouterService extends IMediaRouterService.Stub
        return null;
        return null;
    }
    }


    private boolean isPlaybackActiveLocked(IMediaRouterClient client) {
        ClientRecord clientRecord = mAllClientRecords.get(client.asBinder());
        if (clientRecord != null) {
            return mAudioPlaybackMonitor.isPlaybackActive(clientRecord.mUid);
        }
        return false;
    }

    private void setDiscoveryRequestLocked(IMediaRouterClient client,
    private void setDiscoveryRequestLocked(IMediaRouterClient client,
            int routeTypes, boolean activeScan) {
            int routeTypes, boolean activeScan) {
        final IBinder binder = client.asBinder();
        final IBinder binder = client.asBinder();
+12 −16

File changed.

Preview size limit exceeded, changes collapsed.

+8 −6
Original line number Original line Diff line number Diff line
@@ -75,7 +75,7 @@ class MediaSessionStack {
     */
     */
    private final List<MediaSessionRecord> mSessions = new ArrayList<MediaSessionRecord>();
    private final List<MediaSessionRecord> mSessions = new ArrayList<MediaSessionRecord>();


    private final AudioPlayerStateMonitor mAudioPlayerStateMonitor;
    private final AudioPlaybackMonitor mAudioPlaybackMonitor;
    private final OnMediaButtonSessionChangedListener mOnMediaButtonSessionChangedListener;
    private final OnMediaButtonSessionChangedListener mOnMediaButtonSessionChangedListener;


    /**
    /**
@@ -84,6 +84,7 @@ class MediaSessionStack {
     */
     */
    private MediaSessionRecord mMediaButtonSession;
    private MediaSessionRecord mMediaButtonSession;


    private MediaSessionRecord mCachedDefault;
    private MediaSessionRecord mCachedVolumeDefault;
    private MediaSessionRecord mCachedVolumeDefault;


    /**
    /**
@@ -92,8 +93,8 @@ class MediaSessionStack {
    private final SparseArray<ArrayList<MediaSessionRecord>> mCachedActiveLists =
    private final SparseArray<ArrayList<MediaSessionRecord>> mCachedActiveLists =
            new SparseArray<>();
            new SparseArray<>();


    MediaSessionStack(AudioPlayerStateMonitor monitor, OnMediaButtonSessionChangedListener listener) {
    MediaSessionStack(AudioPlaybackMonitor monitor, OnMediaButtonSessionChangedListener listener) {
        mAudioPlayerStateMonitor = monitor;
        mAudioPlaybackMonitor = monitor;
        mOnMediaButtonSessionChangedListener = listener;
        mOnMediaButtonSessionChangedListener = listener;
    }
    }


@@ -186,13 +187,13 @@ class MediaSessionStack {
        if (DEBUG) {
        if (DEBUG) {
            Log.d(TAG, "updateMediaButtonSessionIfNeeded, callers=" + Debug.getCallers(2));
            Log.d(TAG, "updateMediaButtonSessionIfNeeded, callers=" + Debug.getCallers(2));
        }
        }
        IntArray audioPlaybackUids = mAudioPlayerStateMonitor.getSortedAudioPlaybackClientUids();
        IntArray audioPlaybackUids = mAudioPlaybackMonitor.getSortedAudioPlaybackClientUids();
        for (int i = 0; i < audioPlaybackUids.size(); i++) {
        for (int i = 0; i < audioPlaybackUids.size(); i++) {
            MediaSessionRecord mediaButtonSession =
            MediaSessionRecord mediaButtonSession =
                    findMediaButtonSession(audioPlaybackUids.get(i));
                    findMediaButtonSession(audioPlaybackUids.get(i));
            if (mediaButtonSession != null) {
            if (mediaButtonSession != null) {
                // Found the media button session.
                // Found the media button session.
                mAudioPlayerStateMonitor.cleanUpAudioPlaybackUids(mediaButtonSession.getUid());
                mAudioPlaybackMonitor.cleanUpAudioPlaybackUids(mediaButtonSession.getUid());
                if (mMediaButtonSession != mediaButtonSession) {
                if (mMediaButtonSession != mediaButtonSession) {
                    updateMediaButtonSession(mediaButtonSession);
                    updateMediaButtonSession(mediaButtonSession);
                }
                }
@@ -215,7 +216,7 @@ class MediaSessionStack {
        for (MediaSessionRecord session : mSessions) {
        for (MediaSessionRecord session : mSessions) {
            if (uid == session.getUid()) {
            if (uid == session.getUid()) {
                if (session.getPlaybackState() != null && session.isPlaybackActive() ==
                if (session.getPlaybackState() != null && session.isPlaybackActive() ==
                        mAudioPlayerStateMonitor.isPlaybackActive(session.getUid())) {
                        mAudioPlaybackMonitor.isPlaybackActive(session.getUid())) {
                    // If there's a media session whose PlaybackState matches
                    // If there's a media session whose PlaybackState matches
                    // the audio playback state, return it immediately.
                    // the audio playback state, return it immediately.
                    return session;
                    return session;
@@ -375,6 +376,7 @@ class MediaSessionStack {
    }
    }


    private void clearCache(int userId) {
    private void clearCache(int userId) {
        mCachedDefault = null;
        mCachedVolumeDefault = null;
        mCachedVolumeDefault = null;
        mCachedActiveLists.remove(userId);
        mCachedActiveLists.remove(userId);
        // mCachedActiveLists may also include the list of sessions for UserHandle.USER_ALL,
        // mCachedActiveLists may also include the list of sessions for UserHandle.USER_ALL,