diff --git a/services/core/java/com/android/server/media/AudioPlaybackMonitor.java b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
new file mode 100644
index 0000000..791ee82
--- /dev/null
+++ b/services/core/java/com/android/server/media/AudioPlaybackMonitor.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import android.content.Context;
+import android.media.AudioManager.AudioPlaybackCallback;
+import android.media.AudioPlaybackConfiguration;
+import android.media.IAudioService;
+import android.media.IPlaybackConfigDispatcher;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.IntArray;
+import android.util.Log;
+import android.util.SparseArray;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 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 AudioPlaybackMonitor extends IPlaybackConfigDispatcher.Stub {
+    private static boolean DEBUG = MediaSessionService.DEBUG;
+    private static String TAG = "AudioPlaybackMonitor";
+
+    private static AudioPlaybackMonitor sInstance;
+
+    /**
+     * Called when audio playback is started for a given UID.
+     */
+    interface OnAudioPlaybackStartedListener {
+        void onAudioPlaybackStarted(int uid);
+    }
+
+    /**
+     * Called when audio player state is changed.
+     */
+    interface OnAudioPlayerActiveStateChangedListener {
+        void onAudioPlayerActiveStateChanged(int uid, boolean active);
+    }
+
+    private final Object mLock = new Object();
+    private final Context mContext;
+    private final List<OnAudioPlaybackStartedListener> mAudioPlaybackStartedListeners
+            = new ArrayList<>();
+    private final List<OnAudioPlayerActiveStateChangedListener>
+            mAudioPlayerActiveStateChangedListeners = new ArrayList<>();
+    private final Map<Integer, Integer> mAudioPlaybackStates = new HashMap<>();
+    private final Set<Integer> mActiveAudioPlaybackClientUids = new HashSet<>();
+
+    // 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.
+    // TODO(b/35278867): Find and use unique identifier for apps because apps may share the UID.
+    private final IntArray mSortedAudioPlaybackClientUids = new IntArray();
+
+    static AudioPlaybackMonitor getInstance(Context context, IAudioService audioService) {
+        if (sInstance == null) {
+            sInstance = new AudioPlaybackMonitor(context, audioService);
+        }
+        return sInstance;
+    }
+
+    private AudioPlaybackMonitor(Context context, IAudioService audioService) {
+        mContext = context;
+        try {
+            audioService.registerPlaybackCallback(this);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Failed to register playback callback", e);
+        }
+    }
+
+    /**
+     * Called when the {@link AudioPlaybackConfiguration} is updated.
+     * <p>If an app starts audio playback, the app's local media session will be the media button
+     * session. If the app has multiple media sessions, the playback active local session will be
+     * picked.
+     *
+     * @param configs List of the current audio playback configuration
+     */
+    @Override
+    public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
+            boolean flush) {
+        if (flush) {
+            Binder.flushPendingCommands();
+        }
+        final long token = Binder.clearCallingIdentity();
+        try {
+            List<Integer> newActiveAudioPlaybackClientUids = new ArrayList<>();
+            List<OnAudioPlayerActiveStateChangedListener> audioPlayerActiveStateChangedListeners;
+            List<OnAudioPlaybackStartedListener> audioPlaybackStartedListeners;
+            synchronized (mLock) {
+                // Update mActiveAudioPlaybackClientUids and mSortedAudioPlaybackClientUids,
+                // and find newly activated audio playbacks.
+                mActiveAudioPlaybackClientUids.clear();
+                for (AudioPlaybackConfiguration config : configs) {
+                    // Ignore inactive (i.e. not playing) or PLAYER_TYPE_JAM_SOUNDPOOL
+                    // (i.e. playback from the SoundPool class which is only for sound effects)
+                    // playback.
+                    // Note that we shouldn't ignore PLAYER_TYPE_UNKNOWN because it might be OEM
+                    // specific audio/video players.
+                    if (!config.isActive() || config.getPlayerType()
+                            == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
+                        continue;
+                    }
+
+                    mActiveAudioPlaybackClientUids.add(config.getClientUid());
+                    Integer oldState = mAudioPlaybackStates.get(config.getPlayerInterfaceId());
+                    if (!isActiveState(oldState)) {
+                        if (DEBUG) {
+                            Log.d(TAG, "Found a new active media playback. " +
+                                    AudioPlaybackConfiguration.toLogFriendlyString(config));
+                        }
+                        // New active audio playback.
+                        newActiveAudioPlaybackClientUids.add(config.getClientUid());
+                        int index = mSortedAudioPlaybackClientUids.indexOf(config.getClientUid());
+                        if (index == 0) {
+                            // It's the lastly played music app already. Skip updating.
+                            continue;
+                        } else if (index > 0) {
+                            mSortedAudioPlaybackClientUids.remove(index);
+                        }
+                        mSortedAudioPlaybackClientUids.add(0, config.getClientUid());
+                    }
+                }
+                audioPlayerActiveStateChangedListeners = new ArrayList<>(
+                        mAudioPlayerActiveStateChangedListeners);
+                audioPlaybackStartedListeners = new ArrayList<>(mAudioPlaybackStartedListeners);
+            }
+            // Notify the change of audio playback states.
+            for (AudioPlaybackConfiguration config : configs) {
+                boolean wasActive = isActiveState(
+                        mAudioPlaybackStates.get(config.getPlayerInterfaceId()));
+                boolean isActive = config.isActive();
+                if (wasActive != isActive) {
+                    for (OnAudioPlayerActiveStateChangedListener listener
+                            : audioPlayerActiveStateChangedListeners) {
+                        listener.onAudioPlayerActiveStateChanged(config.getClientUid(),
+                                isActive);
+                    }
+                }
+            }
+            // 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 {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /**
+     * Registers OnAudioPlaybackStartedListener.
+     */
+    public void registerOnAudioPlaybackStartedListener(OnAudioPlaybackStartedListener listener) {
+        synchronized (mLock) {
+            mAudioPlaybackStartedListeners.add(listener);
+        }
+    }
+
+    /**
+     * Unregisters OnAudioPlaybackStartedListener.
+     */
+    public void unregisterOnAudioPlaybackStartedListener(OnAudioPlaybackStartedListener listener) {
+        synchronized (mLock) {
+            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);
+        }
+    }
+
+    /**
+     * Returns the sorted list of UIDs that have had active audio playback. (i.e. playing an
+     * audio/video) The UID whose audio playback becomes active at the last comes first.
+     */
+    public IntArray getSortedAudioPlaybackClientUids() {
+        IntArray sortedAudioPlaybackClientUids = new IntArray();
+        synchronized (mLock) {
+            sortedAudioPlaybackClientUids.addAll(mSortedAudioPlaybackClientUids);
+        }
+        return sortedAudioPlaybackClientUids;
+    }
+
+    /**
+     * Returns if the audio playback is active for the uid.
+     */
+    public boolean isPlaybackActive(int uid) {
+        synchronized (mLock) {
+            return mActiveAudioPlaybackClientUids.contains(uid);
+        }
+    }
+
+    /**
+     * Cleans up the sorted list of audio playback client UIDs with given {@param
+     * mediaButtonSessionUid}.
+     * <p>UIDs whose audio playback started after the media button session's audio playback
+     * cannot be the lastly played media app. So they won't needed anymore.
+     *
+     * @param mediaButtonSessionUid UID of the media button session.
+     */
+    public void cleanUpAudioPlaybackUids(int mediaButtonSessionUid) {
+        synchronized (mLock) {
+            int userId = UserHandle.getUserId(mediaButtonSessionUid);
+            for (int i = mSortedAudioPlaybackClientUids.size() - 1; i >= 0; i--) {
+                if (mSortedAudioPlaybackClientUids.get(i) == mediaButtonSessionUid) {
+                    break;
+                }
+                int uid = mSortedAudioPlaybackClientUids.get(i);
+                if (userId == UserHandle.getUserId(uid) && !isPlaybackActive(uid)) {
+                    // Clean up unnecessary UIDs.
+                    // It doesn't need to be managed profile aware because it's just to prevent
+                    // the list from increasing indefinitely. The media button session updating
+                    // shouldn't be affected by cleaning up.
+                    mSortedAudioPlaybackClientUids.remove(i);
+                }
+            }
+        }
+    }
+
+    /**
+     * Dumps {@link AudioPlaybackMonitor}.
+     */
+    public void dump(PrintWriter pw, String prefix) {
+        synchronized (mLock) {
+            pw.println(prefix + "Audio playback (lastly played comes first)");
+            String indent = prefix + "  ";
+            for (int i = 0; i < mSortedAudioPlaybackClientUids.size(); i++) {
+                int uid = mSortedAudioPlaybackClientUids.get(i);
+                pw.print(indent + "uid=" + uid + " packages=");
+                String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
+                if (packages != null && packages.length > 0) {
+                    for (int j = 0; j < packages.length; j++) {
+                        pw.print(packages[j] + " ");
+                    }
+                }
+                pw.println();
+            }
+        }
+    }
+
+    private boolean isActiveState(Integer state) {
+        return state != null && state.equals(AudioPlaybackConfiguration.PLAYER_STATE_STARTED);
+    }
+}
diff --git a/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java b/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java
deleted file mode 100644
index 110f26d..0000000
--- a/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.media;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.media.AudioPlaybackConfiguration;
-import android.media.IAudioService;
-import android.media.IPlaybackConfigDispatcher;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.IntArray;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.io.PrintWriter;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Monitors the state changes of audio players.
- */
-class AudioPlayerStateMonitor extends IPlaybackConfigDispatcher.Stub {
-    private static boolean DEBUG = MediaSessionService.DEBUG;
-    private static String TAG = "AudioPlayerStateMonitor";
-
-    private static AudioPlayerStateMonitor sInstance = new AudioPlayerStateMonitor();
-
-    /**
-     * Called when the state of audio player is changed.
-     */
-    interface OnAudioPlayerStateChangedListener {
-        void onAudioPlayerStateChanged(
-                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) {
-            obtainMessage(MSG_AUDIO_PLAYER_STATE_CHANGED, uid, prevState, config).sendToTarget();
-        }
-    }
-
-    private final Object mLock = new Object();
-    @GuardedBy("mLock")
-    private final Map<OnAudioPlayerStateChangedListener, MessageHandler> mListenerMap =
-            new HashMap<>();
-    @GuardedBy("mLock")
-    private final Map<Integer, Integer> mAudioPlayerStates = new HashMap<>();
-    @GuardedBy("mLock")
-    private final Map<Integer, HashSet<Integer>> mAudioPlayersForUid = new HashMap<>();
-    // 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.
-    // TODO(b/35278867): Find and use unique identifier for apps because apps may share the UID.
-    @GuardedBy("mLock")
-    private final IntArray mSortedAudioPlaybackClientUids = new IntArray();
-
-    @GuardedBy("mLock")
-    private boolean mRegisteredToAudioService;
-
-    static AudioPlayerStateMonitor getInstance() {
-        return sInstance;
-    }
-
-    private AudioPlayerStateMonitor() {
-    }
-
-    /**
-     * Called when the {@link AudioPlaybackConfiguration} is updated.
-     * <p>If an app starts audio playback, the app's local media session will be the media button
-     * session. If the app has multiple media sessions, the playback active local session will be
-     * picked.
-     *
-     * @param configs List of the current audio playback configuration
-     */
-    @Override
-    public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
-            boolean flush) {
-        if (flush) {
-            Binder.flushPendingCommands();
-        }
-        final long token = Binder.clearCallingIdentity();
-        try {
-            final Map<Integer, Integer> prevAudioPlayerStates = new HashMap<>(mAudioPlayerStates);
-            final Map<Integer, HashSet<Integer>> prevAudioPlayersForUid =
-                    new HashMap<>(mAudioPlayersForUid);
-            synchronized (mLock) {
-                mAudioPlayerStates.clear();
-                mAudioPlayersForUid.clear();
-                for (AudioPlaybackConfiguration config : configs) {
-                    int pii = config.getPlayerInterfaceId();
-                    int uid = config.getClientUid();
-                    mAudioPlayerStates.put(pii, config.getPlayerState());
-                    HashSet<Integer> players = mAudioPlayersForUid.get(uid);
-                    if (players == null) {
-                        players = new HashSet<Integer>();
-                        players.add(pii);
-                        mAudioPlayersForUid.put(uid, players);
-                    } else {
-                        players.add(pii);
-                    }
-                }
-                for (AudioPlaybackConfiguration config : configs) {
-                    if (!config.isActive()) {
-                        continue;
-                    }
-
-                    int uid = config.getClientUid();
-                    if (!isActiveState(prevAudioPlayerStates.get(config.getPlayerInterfaceId()))) {
-                        if (DEBUG) {
-                            Log.d(TAG, "Found a new active media playback. " +
-                                    AudioPlaybackConfiguration.toLogFriendlyString(config));
-                        }
-                        // New active audio playback.
-                        int index = mSortedAudioPlaybackClientUids.indexOf(uid);
-                        if (index == 0) {
-                            // It's the lastly played music app already. Skip updating.
-                            continue;
-                        } else if (index > 0) {
-                            mSortedAudioPlaybackClientUids.remove(index);
-                        }
-                        mSortedAudioPlaybackClientUids.add(0, uid);
-                    }
-                }
-                // Notify the change of audio player states.
-                for (AudioPlaybackConfiguration config : configs) {
-                    Integer prevState = prevAudioPlayerStates.get(config.getPlayerInterfaceId());
-                    if (prevState == null || prevState != config.getPlayerState()) {
-                        sendAudioPlayerStateChangedMessageLocked(
-                                config.getClientUid(), prevState, config);
-                    }
-                }
-                for (Integer prevUid : prevAudioPlayersForUid.keySet()) {
-                    // If all players for prevUid is removed, notify the prev state was
-                    // 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);
-                    }
-                }
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * Registers OnAudioPlayerStateChangedListener.
-     */
-    public void registerListener(OnAudioPlayerStateChangedListener listener, Handler handler) {
-        synchronized (mLock) {
-            mListenerMap.put(listener, new MessageHandler((handler == null) ?
-                    Looper.myLooper() : handler.getLooper(), listener));
-        }
-    }
-
-    /**
-     * Unregisters OnAudioPlayerStateChangedListener.
-     */
-    public void unregisterListener(OnAudioPlayerStateChangedListener listener) {
-        synchronized (mLock) {
-            mListenerMap.remove(listener);
-        }
-    }
-
-    /**
-     * Returns the sorted list of UIDs that have had active audio playback. (i.e. playing an
-     * audio/video) The UID whose audio playback becomes active at the last comes first.
-     */
-    public IntArray getSortedAudioPlaybackClientUids() {
-        IntArray sortedAudioPlaybackClientUids = new IntArray();
-        synchronized (mLock) {
-            sortedAudioPlaybackClientUids.addAll(mSortedAudioPlaybackClientUids);
-        }
-        return sortedAudioPlaybackClientUids;
-    }
-
-    /**
-     * Returns if the audio playback is active for the uid.
-     */
-    public boolean isPlaybackActive(int uid) {
-        synchronized (mLock) {
-            Set<Integer> players = mAudioPlayersForUid.get(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
-     * mediaButtonSessionUid}.
-     * <p>UIDs whose audio playback are inactive and have started before the media button session's
-     * audio playback cannot be the lastly played media app. So they won't needed anymore.
-     *
-     * @param mediaButtonSessionUid UID of the media button session.
-     */
-    public void cleanUpAudioPlaybackUids(int mediaButtonSessionUid) {
-        synchronized (mLock) {
-            int userId = UserHandle.getUserId(mediaButtonSessionUid);
-            for (int i = mSortedAudioPlaybackClientUids.size() - 1; i >= 0; i--) {
-                if (mSortedAudioPlaybackClientUids.get(i) == mediaButtonSessionUid) {
-                    break;
-                }
-                int uid = mSortedAudioPlaybackClientUids.get(i);
-                if (userId == UserHandle.getUserId(uid) && !isPlaybackActive(uid)) {
-                    // Clean up unnecessary UIDs.
-                    // It doesn't need to be managed profile aware because it's just to prevent
-                    // the list from increasing indefinitely. The media button session updating
-                    // shouldn't be affected by cleaning up.
-                    mSortedAudioPlaybackClientUids.remove(i);
-                }
-            }
-        }
-    }
-
-    /**
-     * Dumps {@link AudioPlayerStateMonitor}.
-     */
-    public void dump(Context context, PrintWriter pw, String prefix) {
-        synchronized (mLock) {
-            pw.println(prefix + "Audio playback (lastly played comes first)");
-            String indent = prefix + "  ";
-            for (int i = 0; i < mSortedAudioPlaybackClientUids.size(); i++) {
-                int uid = mSortedAudioPlaybackClientUids.get(i);
-                pw.print(indent + "uid=" + uid + " packages=");
-                String[] packages = context.getPackageManager().getPackagesForUid(uid);
-                if (packages != null && packages.length > 0) {
-                    for (int j = 0; j < packages.length; j++) {
-                        pw.print(packages[j] + " ");
-                    }
-                }
-                pw.println();
-            }
-        }
-    }
-
-    public void registerSelfIntoAudioServiceIfNeeded(IAudioService audioService) {
-        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);
-    }
-}
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 3c9e1d4..1cfd5f0 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -19,14 +19,12 @@
 import com.android.internal.util.DumpUtils;
 import com.android.server.Watchdog;
 
-import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
-import android.media.AudioPlaybackConfiguration;
 import android.media.AudioRoutesInfo;
 import android.media.AudioSystem;
 import android.media.IAudioRoutesObserver;
@@ -98,8 +96,7 @@
     private int mCurrentUserId = -1;
     private boolean mGlobalBluetoothA2dpOn = false;
     private final IAudioService mAudioService;
-    private final AudioPlayerStateMonitor mAudioPlayerStateMonitor;
-    private final Handler mHandler = new Handler();
+    private final AudioPlaybackMonitor mAudioPlaybackMonitor;
     private final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo();
 
     public MediaRouterService(Context context) {
@@ -109,57 +106,31 @@
         mAudioService = IAudioService.Stub.asInterface(
                 ServiceManager.getService(Context.AUDIO_SERVICE));
 
-        mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance();
-        mAudioPlayerStateMonitor.registerListener(
-                new AudioPlayerStateMonitor.OnAudioPlayerStateChangedListener() {
-            static final long WAIT_MS = 500;
-            final Runnable mRestoreBluetoothA2dpRunnable = new Runnable() {
-                @Override
-                public void run() {
-                    restoreBluetoothA2dp();
-                }
-            };
-
+        mAudioPlaybackMonitor = AudioPlaybackMonitor.getInstance(context, mAudioService);
+        mAudioPlaybackMonitor.registerOnAudioPlayerActiveStateChangedListener(
+                new AudioPlaybackMonitor.OnAudioPlayerActiveStateChangedListener() {
             @Override
-            public void onAudioPlayerStateChanged(
-                    int uid, int prevState, @Nullable AudioPlaybackConfiguration config) {
-                int restoreUid = -1;
-                boolean active = config == null ? false : config.isActive();
+            public void onAudioPlayerActiveStateChanged(int uid, boolean active) {
                 if (active) {
-                    restoreUid = uid;
-                } else if (prevState != AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
-                    // Noting to do if the prev state is not an active state.
-                    return;
+                    restoreRoute(uid);
                 } else {
                     IntArray sortedAudioPlaybackClientUids =
-                            mAudioPlayerStateMonitor.getSortedAudioPlaybackClientUids();
-                    for (int i = 0; i < sortedAudioPlaybackClientUids.size(); ++i) {
-                        if (mAudioPlayerStateMonitor.isPlaybackActive(
+                            mAudioPlaybackMonitor.getSortedAudioPlaybackClientUids();
+                    boolean restored = false;
+                    for (int i = 0; i < sortedAudioPlaybackClientUids.size(); i++) {
+                        if (mAudioPlaybackMonitor.isPlaybackActive(
                                 sortedAudioPlaybackClientUids.get(i))) {
-                            restoreUid = sortedAudioPlaybackClientUids.get(i);
+                            restoreRoute(sortedAudioPlaybackClientUids.get(i));
+                            restored = true;
                             break;
                         }
                     }
-                }
-
-                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");
+                    if (!restored) {
+                        restoreBluetoothA2dp();
                     }
                 }
             }
-        }, mHandler);
-        mAudioPlayerStateMonitor.registerSelfIntoAudioServiceIfNeeded(mAudioService);
-
+        });
         AudioRoutesInfo audioRoutes = null;
         try {
             audioRoutes = mAudioService.startWatchingRoutes(new IAudioRoutesObserver.Stub() {
@@ -290,14 +261,9 @@
 
         final long token = Binder.clearCallingIdentity();
         try {
-            ClientRecord clientRecord;
             synchronized (mLock) {
-                clientRecord = mAllClientRecords.get(client.asBinder());
+                return isPlaybackActiveLocked(client);
             }
-            if (clientRecord != null) {
-                return mAudioPlayerStateMonitor.isPlaybackActive(clientRecord.mUid);
-            }
-            return false;
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -514,6 +480,14 @@
         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,
             int routeTypes, boolean activeScan) {
         final IBinder binder = client.asBinder();
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index f6a81d0..aa65244 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -16,7 +16,6 @@
 
 package com.android.server.media;
 
-import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.INotificationManager;
 import android.app.KeyguardManager;
@@ -32,7 +31,7 @@
 import android.content.pm.UserInfo;
 import android.database.ContentObserver;
 import android.media.AudioManager;
-import android.media.AudioPlaybackConfiguration;
+import android.media.AudioManagerInternal;
 import android.media.AudioSystem;
 import android.media.IAudioService;
 import android.media.IRemoteVolumeController;
@@ -69,6 +68,7 @@
 import android.view.ViewConfiguration;
 
 import com.android.internal.util.DumpUtils;
+import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.Watchdog;
 import com.android.server.Watchdog.Monitor;
@@ -104,6 +104,7 @@
 
     private KeyguardManager mKeyguardManager;
     private IAudioService mAudioService;
+    private AudioManagerInternal mAudioManagerInternal;
     private ContentResolver mContentResolver;
     private SettingsObserver mSettingsObserver;
     private INotificationManager mNotificationManager;
@@ -113,7 +114,7 @@
     // It's always not null after the MediaSessionService is started.
     private FullUserRecord mCurrentFullUserRecord;
     private MediaSessionRecord mGlobalPrioritySession;
-    private AudioPlayerStateMonitor mAudioPlayerStateMonitor;
+    private AudioPlaybackMonitor mAudioPlaybackMonitor;
 
     // Used to notify system UI when remote volume was changed. TODO find a
     // better way to handle this.
@@ -136,16 +137,11 @@
         mKeyguardManager =
                 (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
         mAudioService = getAudioService();
-        mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance();
-        mAudioPlayerStateMonitor.registerListener(
-                new AudioPlayerStateMonitor.OnAudioPlayerStateChangedListener() {
+        mAudioPlaybackMonitor = AudioPlaybackMonitor.getInstance(getContext(), mAudioService);
+        mAudioPlaybackMonitor.registerOnAudioPlaybackStartedListener(
+                new AudioPlaybackMonitor.OnAudioPlaybackStartedListener() {
             @Override
-            public void onAudioPlayerStateChanged(
-                    int uid, int prevState, @Nullable AudioPlaybackConfiguration config) {
-                if (config == null || !config.isActive() || config.getPlayerType()
-                        == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
-                    return;
-                }
+            public void onAudioPlaybackStarted(int uid) {
                 synchronized (mLock) {
                     FullUserRecord user =
                             getFullUserRecordLocked(UserHandle.getUserId(uid));
@@ -154,8 +150,8 @@
                     }
                 }
             }
-        }, null /* handler */);
-        mAudioPlayerStateMonitor.registerSelfIntoAudioServiceIfNeeded(mAudioService);
+        });
+        mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
         mContentResolver = getContext().getContentResolver();
         mSettingsObserver = new SettingsObserver();
         mSettingsObserver.observe();
@@ -654,7 +650,7 @@
 
         public FullUserRecord(int fullUserId) {
             mFullUserId = fullUserId;
-            mPriorityStack = new MediaSessionStack(mAudioPlayerStateMonitor, this);
+            mPriorityStack = new MediaSessionStack(mAudioPlaybackMonitor, this);
             // Restore the remembered media button receiver before the boot.
             String mediaButtonReceiver = Settings.Secure.getStringForUser(mContentResolver,
                     Settings.System.MEDIA_BUTTON_RECEIVER, mFullUserId);
@@ -1313,7 +1309,7 @@
                 for (int i = 0; i < count; i++) {
                     mUserRecords.valueAt(i).dumpLocked(pw, "");
                 }
-                mAudioPlayerStateMonitor.dump(getContext(), pw, "");
+                mAudioPlaybackMonitor.dump(pw, "");
             }
         }
 
diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java
index 719ec36..d9fe72e 100644
--- a/services/core/java/com/android/server/media/MediaSessionStack.java
+++ b/services/core/java/com/android/server/media/MediaSessionStack.java
@@ -75,7 +75,7 @@
      */
     private final List<MediaSessionRecord> mSessions = new ArrayList<MediaSessionRecord>();
 
-    private final AudioPlayerStateMonitor mAudioPlayerStateMonitor;
+    private final AudioPlaybackMonitor mAudioPlaybackMonitor;
     private final OnMediaButtonSessionChangedListener mOnMediaButtonSessionChangedListener;
 
     /**
@@ -84,6 +84,7 @@
      */
     private MediaSessionRecord mMediaButtonSession;
 
+    private MediaSessionRecord mCachedDefault;
     private MediaSessionRecord mCachedVolumeDefault;
 
     /**
@@ -92,8 +93,8 @@
     private final SparseArray<ArrayList<MediaSessionRecord>> mCachedActiveLists =
             new SparseArray<>();
 
-    MediaSessionStack(AudioPlayerStateMonitor monitor, OnMediaButtonSessionChangedListener listener) {
-        mAudioPlayerStateMonitor = monitor;
+    MediaSessionStack(AudioPlaybackMonitor monitor, OnMediaButtonSessionChangedListener listener) {
+        mAudioPlaybackMonitor = monitor;
         mOnMediaButtonSessionChangedListener = listener;
     }
 
@@ -186,13 +187,13 @@
         if (DEBUG) {
             Log.d(TAG, "updateMediaButtonSessionIfNeeded, callers=" + Debug.getCallers(2));
         }
-        IntArray audioPlaybackUids = mAudioPlayerStateMonitor.getSortedAudioPlaybackClientUids();
+        IntArray audioPlaybackUids = mAudioPlaybackMonitor.getSortedAudioPlaybackClientUids();
         for (int i = 0; i < audioPlaybackUids.size(); i++) {
             MediaSessionRecord mediaButtonSession =
                     findMediaButtonSession(audioPlaybackUids.get(i));
             if (mediaButtonSession != null) {
                 // Found the media button session.
-                mAudioPlayerStateMonitor.cleanUpAudioPlaybackUids(mediaButtonSession.getUid());
+                mAudioPlaybackMonitor.cleanUpAudioPlaybackUids(mediaButtonSession.getUid());
                 if (mMediaButtonSession != mediaButtonSession) {
                     updateMediaButtonSession(mediaButtonSession);
                 }
@@ -215,7 +216,7 @@
         for (MediaSessionRecord session : mSessions) {
             if (uid == session.getUid()) {
                 if (session.getPlaybackState() != null && session.isPlaybackActive() ==
-                        mAudioPlayerStateMonitor.isPlaybackActive(session.getUid())) {
+                        mAudioPlaybackMonitor.isPlaybackActive(session.getUid())) {
                     // If there's a media session whose PlaybackState matches
                     // the audio playback state, return it immediately.
                     return session;
@@ -375,6 +376,7 @@
     }
 
     private void clearCache(int userId) {
+        mCachedDefault = null;
         mCachedVolumeDefault = null;
         mCachedActiveLists.remove(userId);
         // mCachedActiveLists may also include the list of sessions for UserHandle.USER_ALL,
