Loading src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java +44 −28 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * Provides Bluetooth AVRCP Controller State Machine responsible for all remote control connections Loading Loading @@ -231,25 +232,39 @@ class AvrcpControllerStateMachine extends StateMachine { if (sActiveDevice == null || BluetoothMediaBrowserService.getPlaybackState() != PlaybackStateCompat.STATE_PLAYING) { return setActive(); return setActive(true); } return false; } /* * setActive * * Set this state machine as the active device and update media browse service /** * Attempt to set the active status for this device */ private boolean setActive() { if (DBG) Log.d(TAG, "setActive" + mDevice); if (A2dpSinkService.getA2dpSinkService().setActiveDeviceNative(mDeviceAddress)) { boolean setActive(boolean becomeActive) { logD("setActive(" + becomeActive + ")"); if (becomeActive) { if (isActive()) { return true; } A2dpSinkService a2dpSinkService = A2dpSinkService.getA2dpSinkService(); if (a2dpSinkService == null) { return false; } if (a2dpSinkService.setActiveDeviceNative(mDeviceAddress)) { sActiveDevice = mDevice; BluetoothMediaBrowserService.addressedPlayerChanged(mSessionCallbacks); BluetoothMediaBrowserService.notifyChanged(mAddressedPlayer.getPlaybackState()); BluetoothMediaBrowserService.notifyChanged(mBrowseTree.mNowPlayingNode); } return mDevice == sActiveDevice; } else if (isActive()) { sActiveDevice = null; BluetoothMediaBrowserService.trackChanged(null); BluetoothMediaBrowserService.addressedPlayerChanged(null); } return true; } @Override Loading Loading @@ -303,8 +318,15 @@ class AvrcpControllerStateMachine extends StateMachine { } private void notifyChanged(BrowseTree.BrowseNode node) { // We should only notify now playing content updates if we're the active device. VFS // updates are fine at any time int scope = node.getScope(); if (scope != AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING || (scope == AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING && isActive())) { BluetoothMediaBrowserService.notifyChanged(node); } } private void notifyChanged(PlaybackStateCompat state) { if (isActive()) { Loading Loading @@ -372,8 +394,6 @@ class AvrcpControllerStateMachine extends StateMachine { public void enter() { if (mMostRecentState == BluetoothProfile.STATE_CONNECTING) { requestActive(); BluetoothMediaBrowserService.addressedPlayerChanged(mSessionCallbacks); BluetoothMediaBrowserService.notifyChanged(mAddressedPlayer.getPlaybackState()); broadcastConnectionStateChanged(BluetoothProfile.STATE_CONNECTED); connectCoverArt(); // only works if we have a valid PSM } else { Loading Loading @@ -468,10 +488,7 @@ class AvrcpControllerStateMachine extends StateMachine { case MESSAGE_PROCESS_PLAY_POS_CHANGED: if (msg.arg2 != -1) { mAddressedPlayer.setPlayTime(msg.arg2); if (isActive()) { BluetoothMediaBrowserService.notifyChanged( mAddressedPlayer.getPlaybackState()); } notifyChanged(mAddressedPlayer.getPlaybackState()); } return true; Loading Loading @@ -540,8 +557,11 @@ class AvrcpControllerStateMachine extends StateMachine { } // Let the browse tree know of the newly downloaded image so it can attach it to // all the items that need it mBrowseTree.notifyImageDownload(handle, uri); // all the items that need it. Notify of changed nodes accordingly Set<BrowseTree.BrowseNode> nodes = mBrowseTree.notifyImageDownload(handle, uri); for (BrowseTree.BrowseNode node : nodes) { notifyChanged(node); } return true; case DISCONNECT: Loading @@ -555,7 +575,7 @@ class AvrcpControllerStateMachine extends StateMachine { } private void processPlayItem(BrowseTree.BrowseNode node) { setActive(); setActive(true); if (node == null) { Log.w(TAG, "Invalid item to play"); } else { Loading Loading @@ -872,11 +892,7 @@ class AvrcpControllerStateMachine extends StateMachine { public void enter() { disconnectCoverArt(); onBrowsingDisconnected(); if (isActive()) { sActiveDevice = null; BluetoothMediaBrowserService.trackChanged(null); BluetoothMediaBrowserService.addressedPlayerChanged(null); } setActive(false); broadcastConnectionStateChanged(BluetoothProfile.STATE_DISCONNECTING); transitionTo(mDisconnected); } Loading src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java +6 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,11 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { mSession.setQueue(mMediaQueue); } private void clearNowPlayingQueue() { mMediaQueue.clear(); mSession.setQueue(mMediaQueue); } static synchronized void notifyChanged(BrowseTree.BrowseNode node) { if (sBluetoothMediaBrowserService != null) { if (node.getScope() == AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING) { Loading @@ -177,6 +182,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { if (sBluetoothMediaBrowserService != null) { if (callback == null) { sBluetoothMediaBrowserService.setErrorPlaybackState(); sBluetoothMediaBrowserService.clearNowPlayingQueue(); } sBluetoothMediaBrowserService.mSession.setCallback(callback); } else { Loading src/com/android/bluetooth/avrcpcontroller/BrowseTree.java +5 −7 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.UUID; /** Loading Loading @@ -451,8 +452,10 @@ public class BrowseTree { /** * Adds the Uri of a newly downloaded image to all tree nodes using that specific handle. * Returns the set of parent nodes that have children impacted by the new art so clients can * be notified of the change. */ synchronized void notifyImageDownload(String handle, Uri uri) { synchronized Set<BrowseNode> notifyImageDownload(String handle, Uri uri) { if (DBG) Log.d(TAG, "Received downloaded image handle to cascade to BrowseNodes using it"); ArrayList<String> nodes = getNodesUsingCoverArt(handle); HashSet<BrowseNode> parents = new HashSet<BrowseNode>(); Loading @@ -468,12 +471,7 @@ public class BrowseTree { parents.add(node.mParent); } } // Update *parents* of changed nodes so applications will re-grab this node, now with art for (BrowseNode node : parents) { if (DBG) Log.d(TAG, "Notify node '" + node.getID() + "' that child has cover art now"); BluetoothMediaBrowserService.notifyChanged(node); } return parents; } Loading Loading
src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java +44 −28 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * Provides Bluetooth AVRCP Controller State Machine responsible for all remote control connections Loading Loading @@ -231,25 +232,39 @@ class AvrcpControllerStateMachine extends StateMachine { if (sActiveDevice == null || BluetoothMediaBrowserService.getPlaybackState() != PlaybackStateCompat.STATE_PLAYING) { return setActive(); return setActive(true); } return false; } /* * setActive * * Set this state machine as the active device and update media browse service /** * Attempt to set the active status for this device */ private boolean setActive() { if (DBG) Log.d(TAG, "setActive" + mDevice); if (A2dpSinkService.getA2dpSinkService().setActiveDeviceNative(mDeviceAddress)) { boolean setActive(boolean becomeActive) { logD("setActive(" + becomeActive + ")"); if (becomeActive) { if (isActive()) { return true; } A2dpSinkService a2dpSinkService = A2dpSinkService.getA2dpSinkService(); if (a2dpSinkService == null) { return false; } if (a2dpSinkService.setActiveDeviceNative(mDeviceAddress)) { sActiveDevice = mDevice; BluetoothMediaBrowserService.addressedPlayerChanged(mSessionCallbacks); BluetoothMediaBrowserService.notifyChanged(mAddressedPlayer.getPlaybackState()); BluetoothMediaBrowserService.notifyChanged(mBrowseTree.mNowPlayingNode); } return mDevice == sActiveDevice; } else if (isActive()) { sActiveDevice = null; BluetoothMediaBrowserService.trackChanged(null); BluetoothMediaBrowserService.addressedPlayerChanged(null); } return true; } @Override Loading Loading @@ -303,8 +318,15 @@ class AvrcpControllerStateMachine extends StateMachine { } private void notifyChanged(BrowseTree.BrowseNode node) { // We should only notify now playing content updates if we're the active device. VFS // updates are fine at any time int scope = node.getScope(); if (scope != AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING || (scope == AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING && isActive())) { BluetoothMediaBrowserService.notifyChanged(node); } } private void notifyChanged(PlaybackStateCompat state) { if (isActive()) { Loading Loading @@ -372,8 +394,6 @@ class AvrcpControllerStateMachine extends StateMachine { public void enter() { if (mMostRecentState == BluetoothProfile.STATE_CONNECTING) { requestActive(); BluetoothMediaBrowserService.addressedPlayerChanged(mSessionCallbacks); BluetoothMediaBrowserService.notifyChanged(mAddressedPlayer.getPlaybackState()); broadcastConnectionStateChanged(BluetoothProfile.STATE_CONNECTED); connectCoverArt(); // only works if we have a valid PSM } else { Loading Loading @@ -468,10 +488,7 @@ class AvrcpControllerStateMachine extends StateMachine { case MESSAGE_PROCESS_PLAY_POS_CHANGED: if (msg.arg2 != -1) { mAddressedPlayer.setPlayTime(msg.arg2); if (isActive()) { BluetoothMediaBrowserService.notifyChanged( mAddressedPlayer.getPlaybackState()); } notifyChanged(mAddressedPlayer.getPlaybackState()); } return true; Loading Loading @@ -540,8 +557,11 @@ class AvrcpControllerStateMachine extends StateMachine { } // Let the browse tree know of the newly downloaded image so it can attach it to // all the items that need it mBrowseTree.notifyImageDownload(handle, uri); // all the items that need it. Notify of changed nodes accordingly Set<BrowseTree.BrowseNode> nodes = mBrowseTree.notifyImageDownload(handle, uri); for (BrowseTree.BrowseNode node : nodes) { notifyChanged(node); } return true; case DISCONNECT: Loading @@ -555,7 +575,7 @@ class AvrcpControllerStateMachine extends StateMachine { } private void processPlayItem(BrowseTree.BrowseNode node) { setActive(); setActive(true); if (node == null) { Log.w(TAG, "Invalid item to play"); } else { Loading Loading @@ -872,11 +892,7 @@ class AvrcpControllerStateMachine extends StateMachine { public void enter() { disconnectCoverArt(); onBrowsingDisconnected(); if (isActive()) { sActiveDevice = null; BluetoothMediaBrowserService.trackChanged(null); BluetoothMediaBrowserService.addressedPlayerChanged(null); } setActive(false); broadcastConnectionStateChanged(BluetoothProfile.STATE_DISCONNECTING); transitionTo(mDisconnected); } Loading
src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java +6 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,11 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { mSession.setQueue(mMediaQueue); } private void clearNowPlayingQueue() { mMediaQueue.clear(); mSession.setQueue(mMediaQueue); } static synchronized void notifyChanged(BrowseTree.BrowseNode node) { if (sBluetoothMediaBrowserService != null) { if (node.getScope() == AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING) { Loading @@ -177,6 +182,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat { if (sBluetoothMediaBrowserService != null) { if (callback == null) { sBluetoothMediaBrowserService.setErrorPlaybackState(); sBluetoothMediaBrowserService.clearNowPlayingQueue(); } sBluetoothMediaBrowserService.mSession.setCallback(callback); } else { Loading
src/com/android/bluetooth/avrcpcontroller/BrowseTree.java +5 −7 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.UUID; /** Loading Loading @@ -451,8 +452,10 @@ public class BrowseTree { /** * Adds the Uri of a newly downloaded image to all tree nodes using that specific handle. * Returns the set of parent nodes that have children impacted by the new art so clients can * be notified of the change. */ synchronized void notifyImageDownload(String handle, Uri uri) { synchronized Set<BrowseNode> notifyImageDownload(String handle, Uri uri) { if (DBG) Log.d(TAG, "Received downloaded image handle to cascade to BrowseNodes using it"); ArrayList<String> nodes = getNodesUsingCoverArt(handle); HashSet<BrowseNode> parents = new HashSet<BrowseNode>(); Loading @@ -468,12 +471,7 @@ public class BrowseTree { parents.add(node.mParent); } } // Update *parents* of changed nodes so applications will re-grab this node, now with art for (BrowseNode node : parents) { if (DBG) Log.d(TAG, "Notify node '" + node.getID() + "' that child has cover art now"); BluetoothMediaBrowserService.notifyChanged(node); } return parents; } Loading