MediaSessionStack.java revision d2b8c947ddfc6349a3ae6c3968b422b9cf50d7ed
11a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton/* 21a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * Copyright (C) 2014 The Android Open Source Project 31a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * 41a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * Licensed under the Apache License, Version 2.0 (the "License"); 51a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * you may not use this file except in compliance with the License. 61a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * You may obtain a copy of the License at 71a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * 81a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * http://www.apache.org/licenses/LICENSE-2.0 91a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * 101a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * Unless required by applicable law or agreed to in writing, software 111a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * distributed under the License is distributed on an "AS IS" BASIS, 121a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * See the License for the specific language governing permissions and 141a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * limitations under the License. 15777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips */ 161a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton 171a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Daltonpackage com.android.server.media; 18383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton 19383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Daltonimport android.media.session.MediaController.PlaybackInfo; 20383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Daltonimport android.media.session.PlaybackState; 21383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Daltonimport android.media.session.MediaSession; 22383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Daltonimport android.os.UserHandle; 231a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton 24a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Daltonimport java.io.PrintWriter; 25a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Daltonimport java.util.ArrayList; 26a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton 27a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton/** 28a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton * Keeps track of media sessions and their priority for notifications, media 29a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton * button dispatch, etc. 30a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton */ 31a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Daltonpublic class MediaSessionStack { 32a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton /** 33a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton * These are states that usually indicate the user took an action and should 34a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton * bump priority regardless of the old state. 35a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton */ 36a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton private static final int[] ALWAYS_PRIORITY_STATES = { 37a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton PlaybackState.STATE_FAST_FORWARDING, 38a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton PlaybackState.STATE_REWINDING, 391a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton PlaybackState.STATE_SKIPPING_TO_PREVIOUS, 401a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton PlaybackState.STATE_SKIPPING_TO_NEXT }; 411a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton /** 42383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * These are states that usually indicate the user took an action if they 43383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * were entered from a non-priority state. 441a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton */ 45bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon private static final int[] TRANSITION_PRIORITY_STATES = { 46e4679fa06a1ab57de15f20cff56911599fa2a73eChris Dalton PlaybackState.STATE_BUFFERING, 471a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton PlaybackState.STATE_CONNECTING, 481a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton PlaybackState.STATE_PLAYING }; 49383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton 50383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton private final ArrayList<MediaSessionRecord> mSessions = new ArrayList<MediaSessionRecord>(); 51a2ac30da36c80f616c909c671a240f2d468db124Chris Dalton 52a2ac30da36c80f616c909c671a240f2d468db124Chris Dalton private MediaSessionRecord mGlobalPrioritySession; 531a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton 541a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton private MediaSessionRecord mCachedButtonReceiver; 55383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton private MediaSessionRecord mCachedDefault; 56383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton private MediaSessionRecord mCachedVolumeDefault; 57a2ac30da36c80f616c909c671a240f2d468db124Chris Dalton private ArrayList<MediaSessionRecord> mCachedActiveList; 58a2ac30da36c80f616c909c671a240f2d468db124Chris Dalton private ArrayList<MediaSessionRecord> mCachedTransportControlList; 59a2ac30da36c80f616c909c671a240f2d468db124Chris Dalton 60a2ac30da36c80f616c909c671a240f2d468db124Chris Dalton /** 61383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * Add a record to the priority tracker. 62383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * 635ed4423090e63e4c7888d6dd44fde177adea13f3Chris Dalton * @param record The record to add. 641a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton */ 651a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton public void addSession(MediaSessionRecord record) { 661a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton mSessions.add(record); 671a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton clearCache(); 685ed4423090e63e4c7888d6dd44fde177adea13f3Chris Dalton } 695ed4423090e63e4c7888d6dd44fde177adea13f3Chris Dalton 705ed4423090e63e4c7888d6dd44fde177adea13f3Chris Dalton /** 715ed4423090e63e4c7888d6dd44fde177adea13f3Chris Dalton * Remove a record from the priority tracker. 72db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton * 73db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton * @param record The record to remove. 74db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton */ 75db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton public void removeSession(MediaSessionRecord record) { 76db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton mSessions.remove(record); 77db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton if (record == mGlobalPrioritySession) { 78db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton mGlobalPrioritySession = null; 79db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton } 80db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton clearCache(); 81db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton } 82db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton 83db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton /** 84db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton * Notify the priority tracker that a session's state changed. 85db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton * 86db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton * @param record The record that changed. 87db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton * @param oldState Its old playback state. 88db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton * @param newState Its new playback state. 89db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton * @return true if the priority order was updated, false otherwise. 90db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton */ 91db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton public boolean onPlaystateChange(MediaSessionRecord record, int oldState, int newState) { 92db91c6e7fbfc9d1d8fd203f7e08eefb602e4a0b9Chris Dalton if (shouldUpdatePriority(oldState, newState)) { 935ed4423090e63e4c7888d6dd44fde177adea13f3Chris Dalton mSessions.remove(record); 941a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton mSessions.add(0, record); 951a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton clearCache(); 961a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton return true; 971a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton } else if (newState == PlaybackState.STATE_PAUSED) { 981a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton // Just clear the volume cache in this case 991a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton mCachedVolumeDefault = null; 1001a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton } 1011a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton return false; 1021a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton } 103a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton 104a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton /** 1051a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * Handle any stack changes that need to occur in response to a session 1061a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * state change. TODO add the old and new session state as params 1071a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * 1081a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * @param record The record that changed. 1091a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton */ 110a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton public void onSessionStateChange(MediaSessionRecord record) { 111080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton if ((record.getFlags() & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) { 1121a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton mGlobalPrioritySession = record; 113383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton } 114383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton // For now just clear the cache. Eventually we'll selectively clear 1151a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton // depending on what changed. 1161a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton clearCache(); 1171a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton } 1181a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton 119c9c97b7fd5f9ca8b95223d99dac063d4a2510a4dChris Dalton /** 120c9c97b7fd5f9ca8b95223d99dac063d4a2510a4dChris Dalton * Get the current priority sorted list of active sessions. The most 121a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton * important session is at index 0 and the least important at size - 1. 122a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton * 123a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton * @param userId The user to check. 124a039d3bd06be63da883fcc5ef55efb736d044f6dChris Dalton * @return All the active sessions in priority order. 125a039d3bd06be63da883fcc5ef55efb736d044f6dChris Dalton */ 126a039d3bd06be63da883fcc5ef55efb736d044f6dChris Dalton public ArrayList<MediaSessionRecord> getActiveSessions(int userId) { 127a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton if (mCachedActiveList == null) { 128a039d3bd06be63da883fcc5ef55efb736d044f6dChris Dalton mCachedActiveList = getPriorityListLocked(true, 0, userId); 129a039d3bd06be63da883fcc5ef55efb736d044f6dChris Dalton } 130a039d3bd06be63da883fcc5ef55efb736d044f6dChris Dalton return mCachedActiveList; 131a039d3bd06be63da883fcc5ef55efb736d044f6dChris Dalton } 132a039d3bd06be63da883fcc5ef55efb736d044f6dChris Dalton 133383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton /** 1341a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * Get the current priority sorted list of active sessions that use 1351a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * transport controls. The most important session is at index 0 and the 1361a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * least important at size -1. 1371a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * 1381a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * @param userId The user to check. 1391a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * @return All the active sessions that handle transport controls in 140a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton * priority order. 141a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton */ 142080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton public ArrayList<MediaSessionRecord> getTransportControlSessions(int userId) { 143a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton if (mCachedTransportControlList == null) { 144080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton mCachedTransportControlList = getPriorityListLocked(true, 145080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS, userId); 146080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton } 147080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton return mCachedTransportControlList; 148a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 149a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton 150a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton /** 151080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton * Get the highest priority active session. 152080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton * 153a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton * @param userId The user to check. 154080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton * @return The current highest priority session or null. 155383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton */ 156383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton public MediaSessionRecord getDefaultSession(int userId) { 157383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton if (mCachedDefault != null) { 1581a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton return mCachedDefault; 1591a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton } 1601a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton ArrayList<MediaSessionRecord> records = getPriorityListLocked(true, 0, userId); 161a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton if (records.size() > 0) { 1621a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton return records.get(0); 1631a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton } 164080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton return null; 165a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 166a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton 167a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton /** 168a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton * Get the highest priority session that can handle media buttons. 1691a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * 170383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * @param userId The user to check. 1711a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton * @return The default media button session or null. 1721a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton */ 1731a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton public MediaSessionRecord getDefaultMediaButtonSession(int userId) { 1741a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton if (mGlobalPrioritySession != null && mGlobalPrioritySession.isActive()) { 175a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton return mGlobalPrioritySession; 176080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton } 1771a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton if (mCachedButtonReceiver != null) { 1781a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton return mCachedButtonReceiver; 1791a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton } 180383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton ArrayList<MediaSessionRecord> records = getPriorityListLocked(true, 181a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton MediaSession.FLAG_HANDLES_MEDIA_BUTTONS, userId); 1821a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton if (records.size() > 0) { 1831a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton mCachedButtonReceiver = records.get(0); 1841a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton } 185a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton return mCachedButtonReceiver; 186080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton } 187a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton 188a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton public MediaSessionRecord getDefaultVolumeSession(int userId) { 189a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton if (mGlobalPrioritySession != null && mGlobalPrioritySession.isActive()) { 1901a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton return mGlobalPrioritySession; 1911a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton } 192a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton if (mCachedVolumeDefault != null) { 193a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton return mCachedVolumeDefault; 194a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 195a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton ArrayList<MediaSessionRecord> records = getPriorityListLocked(true, 0, userId); 196a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton int size = records.size(); 197a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton for (int i = 0; i < size; i++) { 198a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton MediaSessionRecord record = records.get(i); 199a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton if (record.isPlaybackActive(false)) { 200a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton mCachedVolumeDefault = record; 201a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton return record; 202a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 203a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 204383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton return null; 205777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips } 206777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips 207777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips public MediaSessionRecord getDefaultRemoteSession(int userId) { 208383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton ArrayList<MediaSessionRecord> records = getPriorityListLocked(true, 0, userId); 209a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton 210c1e59638b4a08f5210f72f671292b1b3759f54c6Chris Dalton int size = records.size(); 211a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton for (int i = 0; i < size; i++) { 212c1e59638b4a08f5210f72f671292b1b3759f54c6Chris Dalton MediaSessionRecord record = records.get(i); 213a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton if (record.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE) { 214a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton return record; 215a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 216777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips } 217a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton return null; 218a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 219c1e59638b4a08f5210f72f671292b1b3759f54c6Chris Dalton 220c1e59638b4a08f5210f72f671292b1b3759f54c6Chris Dalton public void dump(PrintWriter pw, String prefix) { 221a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton ArrayList<MediaSessionRecord> sortedSessions = getPriorityListLocked(false, 0, 222383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton UserHandle.USER_ALL); 223383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton int count = sortedSessions.size(); 224a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton pw.println(prefix + "Global priority session is " + mGlobalPrioritySession); 225a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton pw.println(prefix + "Sessions Stack - have " + count + " sessions:"); 226777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips String indent = prefix + " "; 227777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips for (int i = 0; i < count; i++) { 228777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips MediaSessionRecord record = sortedSessions.get(i); 229a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton record.dump(pw, indent); 230c1e59638b4a08f5210f72f671292b1b3759f54c6Chris Dalton pw.println(); 231777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips } 232ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips } 23394a6ce84ece51ff1c46c698753716f3f47585742Greg Daniel 23494a6ce84ece51ff1c46c698753716f3f47585742Greg Daniel /** 23594a6ce84ece51ff1c46c698753716f3f47585742Greg Daniel * Get a priority sorted list of sessions. Can filter to only return active 236383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * sessions or sessions with specific flags. 237383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * 238383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * @param activeOnly True to only return active sessions, false to return 239383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * all sessions. 240383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * @param withFlags Only return sessions with all the specified flags set. 0 241383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * returns all sessions. 242383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * @param userId The user to get sessions for. {@link UserHandle#USER_ALL} 243383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * will return sessions for all users. 244383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton * @return The priority sorted list of sessions. 245383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton */ 246ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips private ArrayList<MediaSessionRecord> getPriorityListLocked(boolean activeOnly, int withFlags, 247ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips int userId) { 248383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton ArrayList<MediaSessionRecord> result = new ArrayList<MediaSessionRecord>(); 249383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton int lastLocalIndex = 0; 250383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton int lastActiveIndex = 0; 251383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton int lastPublishedIndex = 0; 252383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton 253383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton int size = mSessions.size(); 254383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton for (int i = 0; i < size; i++) { 255ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips final MediaSessionRecord session = mSessions.get(i); 256a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton 257a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton if (userId != UserHandle.USER_ALL && userId != session.getUserId()) { 258a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton // Filter out sessions for the wrong user 259a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton continue; 260a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 261a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton if ((session.getFlags() & withFlags) != withFlags) { 262a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton // Filter out sessions with the wrong flags 263c1e59638b4a08f5210f72f671292b1b3759f54c6Chris Dalton continue; 264a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 265a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton if (!session.isActive()) { 266c1e59638b4a08f5210f72f671292b1b3759f54c6Chris Dalton if (!activeOnly) { 267c1e59638b4a08f5210f72f671292b1b3759f54c6Chris Dalton // If we're getting unpublished as well always put them at 268a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton // the end 269a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton result.add(session); 270a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 271383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton continue; 2721a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton } 273a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton 2741a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton if (session.isSystemPriority()) { 2751a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton // System priority sessions are special and always go at the 2761a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton // front. We expect there to only be one of these at a time. 2779ca27849d8259e4b35243094bdca969612efba2fChris Dalton result.add(0, session); 2781a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton lastLocalIndex++; 279383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton lastActiveIndex++; 280a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton lastPublishedIndex++; 281a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } else if (session.isPlaybackActive(true)) { 282383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton // TODO this with real local route check 283a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton if (true) { 2841a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton // Active local sessions get top priority 285c1e59638b4a08f5210f72f671292b1b3759f54c6Chris Dalton result.add(lastLocalIndex, session); 2861a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton lastLocalIndex++; 287a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton lastActiveIndex++; 288c9c97b7fd5f9ca8b95223d99dac063d4a2510a4dChris Dalton lastPublishedIndex++; 289383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton } else { 2901a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton // Then active remote sessions 291a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton result.add(lastActiveIndex, session); 292a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton lastActiveIndex++; 293080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton lastPublishedIndex++; 2941a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton } 295a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } else { 296a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton // inactive sessions go at the end in order of whoever last did 297a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton // something. 298a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton result.add(lastPublishedIndex, session); 299a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton lastPublishedIndex++; 300a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 301a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 302080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton 303c9c97b7fd5f9ca8b95223d99dac063d4a2510a4dChris Dalton return result; 304080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton } 305080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton 306080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton private boolean shouldUpdatePriority(int oldState, int newState) { 307a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton if (containsState(newState, ALWAYS_PRIORITY_STATES)) { 308a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton return true; 309a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 310a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton if (!containsState(oldState, TRANSITION_PRIORITY_STATES) 311a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton && containsState(newState, TRANSITION_PRIORITY_STATES)) { 312a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton return true; 313a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 314a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton return false; 315a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 316a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton 317080baa44c50091d4e1a15550ded245c502a9ae3aChris Dalton private boolean containsState(int state, int[] states) { 3181a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton for (int i = 0; i < states.length; i++) { 3191a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton if (states[i] == state) { 320a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton return true; 321383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton } 3221a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton } 3231a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton return false; 324a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton } 325383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton 3261a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton private void clearCache() { 3271a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton mCachedDefault = null; 3281a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton mCachedVolumeDefault = null; 3291a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton mCachedButtonReceiver = null; 3301a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton mCachedActiveList = null; 331383a2ef6edb84dbebc7a9c22ea7423037bbf6a2fChris Dalton mCachedTransportControlList = null; 3321a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton } 3331a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton} 3341a325d25b941ef801b3e9b2c0342da43cf35cdbaChris Dalton