OSDN Git Service

DO NOT MERGE update play status based on A2dp audio state from stack.
authorZhihai Xu <zhihaixu@google.com>
Wed, 8 Jan 2014 01:34:43 +0000 (17:34 -0800)
committerZhihai Xu <zhihaixu@google.com>
Sat, 8 Mar 2014 07:39:02 +0000 (23:39 -0800)
this is to work around the problem:some video/audio player didn't
update the play status by calling setPlaybackState.
The headset(HBS730) register the play status update on the phone.
It will depend the play status reported from the phone to send
play or pause command.

bug:11325212
Change-Id: I7fde5960edd4a5b3474fa17456aacd5b4b432d4d

src/com/android/bluetooth/a2dp/A2dpService.java
src/com/android/bluetooth/a2dp/A2dpStateMachine.java
src/com/android/bluetooth/a2dp/Avrcp.java

index 3b449ac..743513e 100755 (executable)
@@ -51,8 +51,8 @@ public class A2dpService extends ProfileService {
     }
 
     protected boolean start() {
-        mStateMachine = A2dpStateMachine.make(this, this);
         mAvrcp = Avrcp.make(this);
+        mStateMachine = A2dpStateMachine.make(this, this);
         setA2dpService(this);
         return true;
     }
@@ -189,6 +189,10 @@ public class A2dpService extends ProfileService {
         mAvrcp.setAbsoluteVolume(volume);
     }
 
+    public void setAvrcpAudioState(int state) {
+        mAvrcp.setA2dpAudioState(state);
+    }
+
     synchronized boolean isA2dpPlaying(BluetoothDevice device) {
         enforceCallingOrSelfPermission(BLUETOOTH_PERM,
                                        "Need BLUETOOTH permission");
index f7cf37f..ebd9117 100755 (executable)
@@ -561,14 +561,16 @@ final class A2dpStateMachine extends StateMachine {
             switch (state) {
                 case AUDIO_STATE_STARTED:
                     if (mPlayingA2dpDevice == null) {
-                       mPlayingA2dpDevice = device;
-                       broadcastAudioState(device, BluetoothA2dp.STATE_PLAYING,
-                                           BluetoothA2dp.STATE_NOT_PLAYING);
+                        mPlayingA2dpDevice = device;
+                        mService.setAvrcpAudioState(BluetoothA2dp.STATE_PLAYING);
+                        broadcastAudioState(device, BluetoothA2dp.STATE_PLAYING,
+                                            BluetoothA2dp.STATE_NOT_PLAYING);
                     }
                     break;
                 case AUDIO_STATE_STOPPED:
-                    if(mPlayingA2dpDevice != null) {
+                    if (mPlayingA2dpDevice != null) {
                         mPlayingA2dpDevice = null;
+                        mService.setAvrcpAudioState(BluetoothA2dp.STATE_NOT_PLAYING);
                         broadcastAudioState(device, BluetoothA2dp.STATE_NOT_PLAYING,
                                             BluetoothA2dp.STATE_PLAYING);
                     }
index 16fc327..c1ebb70 100755 (executable)
@@ -20,6 +20,7 @@ import java.util.Timer;
 import java.util.TimerTask;
 
 import android.app.PendingIntent;
+import android.bluetooth.BluetoothA2dp;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
@@ -117,6 +118,7 @@ final class Avrcp {
     private static final int MESSAGE_FAST_FORWARD = 10;
     private static final int MESSAGE_REWIND = 11;
     private static final int MESSAGE_CHANGE_PLAY_POS = 12;
+    private static final int MESSAGE_SET_A2DP_AUDIO_STATE = 13;
     private static final int MSG_UPDATE_STATE = 100;
     private static final int MSG_SET_METADATA = 101;
     private static final int MSG_SET_TRANSPORT_CONTROLS = 102;
@@ -447,10 +449,24 @@ final class Avrcp {
                     sendMessageDelayed(posMsg, SKIP_PERIOD);
                 }
                 break;
+
+            case MESSAGE_SET_A2DP_AUDIO_STATE:
+                if (DEBUG) Log.v(TAG, "MESSAGE_SET_A2DP_AUDIO_STATE:" + msg.arg1);
+                updateA2dpAudioState(msg.arg1);
+                break;
             }
         }
     }
 
+    private void updateA2dpAudioState(int state) {
+        boolean isPlaying = (state == BluetoothA2dp.STATE_PLAYING);
+        if (isPlaying != isPlayingState(mCurrentPlayState)) {
+            updatePlayPauseState(isPlaying ? RemoteControlClient.PLAYSTATE_PLAYING :
+                                 RemoteControlClient.PLAYSTATE_PAUSED,
+                                 RemoteControlClient.PLAYBACK_POSITION_INVALID);
+        }
+    }
+
     private void updatePlayPauseState(int state, long currentPosMs) {
         if (DEBUG) Log.v(TAG,
                 "updatePlayPauseState, old=" + mCurrentPlayState + ", state=" + state);
@@ -735,6 +751,20 @@ final class Avrcp {
         return playStatus;
     }
 
+    private boolean isPlayingState(int playState) {
+        boolean isPlaying = false;
+        switch (playState) {
+            case RemoteControlClient.PLAYSTATE_PLAYING:
+            case RemoteControlClient.PLAYSTATE_BUFFERING:
+                isPlaying = true;
+                break;
+            default:
+                isPlaying = false;
+                break;
+        }
+        return isPlaying;
+    }
+
     /**
      * This is called from AudioService. It will return whether this device supports abs volume.
      * NOT USED AT THE MOMENT.
@@ -788,6 +818,14 @@ final class Avrcp {
         return (int) Math.ceil((double) volume*AVRCP_MAX_VOL/mAudioStreamMax);
     }
 
+    /**
+     * This is called from A2dpStateMachine to set A2dp audio state.
+     */
+    public void setA2dpAudioState(int state) {
+        Message msg = mHandler.obtainMessage(MESSAGE_SET_A2DP_AUDIO_STATE, state, 0);
+        mHandler.sendMessage(msg);
+    }
+
     // Do not modify without updating the HAL bt_rc.h files.
 
     // match up with btrc_play_status_t enum of bt_rc.h