diff options
author | Eric Laurent <elaurent@google.com> | 2013-04-19 15:39:22 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-04-19 15:39:22 +0000 |
commit | 56af4f212a21fe08b54de10322e023b09fa125aa (patch) | |
tree | b5b8ba39fa5f0b87e04462b2ceb68756d10d2e5b /media | |
parent | 6ead6ccac9727993559c9f09f1e8da3c69ee3313 (diff) | |
parent | c18c9138cee0f0859bcab636a004ce92ca4a9ab5 (diff) | |
download | frameworks_base-56af4f212a21fe08b54de10322e023b09fa125aa.zip frameworks_base-56af4f212a21fe08b54de10322e023b09fa125aa.tar.gz frameworks_base-56af4f212a21fe08b54de10322e023b09fa125aa.tar.bz2 |
Merge "AudioService: SCO audio backward compatibility" into jb-mr2-dev
Diffstat (limited to 'media')
-rw-r--r-- | media/java/android/media/AudioManager.java | 8 | ||||
-rw-r--r-- | media/java/android/media/AudioService.java | 58 | ||||
-rw-r--r-- | media/java/android/media/IAudioService.aidl | 2 |
3 files changed, 55 insertions, 13 deletions
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 917a47d..56e98e4 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -24,6 +24,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -1205,6 +1206,11 @@ public class AudioManager { * call {@link #stopBluetoothSco()} to clear the request and turn down the bluetooth connection. * <p>Even if a SCO connection is established, the following restrictions apply on audio * output streams so that they can be routed to SCO headset: + * <p>NOTE: up to and including API version + * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method initiates a virtual + * voice call to the bluetooth headset. + * After API version {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} only a raw SCO audio + * connection is established. * <ul> * <li> the stream type must be {@link #STREAM_VOICE_CALL} </li> * <li> the format must be mono </li> @@ -1226,7 +1232,7 @@ public class AudioManager { public void startBluetoothSco(){ IAudioService service = getService(); try { - service.startBluetoothSco(mICallBack); + service.startBluetoothSco(mICallBack, mContext.getApplicationInfo().targetSdkVersion); } catch (RemoteException e) { Log.e(TAG, "Dead object in startBluetoothSco", e); } diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 637ac85..0df4f82 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -48,6 +48,7 @@ import android.database.ContentObserver; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; @@ -369,6 +370,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished { // waiting for headset service to connect private static final int SCO_STATE_DEACTIVATE_EXT_REQ = 4; + // Indicates the mode used for SCO audio connection. The mode is virtual call if the request + // originated from an app targeting an API version before JB MR2 and raw audio after that. + private int mScoAudioMode; + // SCO audio mode is virtual voice call (BluetoothHeadset.startScoUsingVirtualVoiceCall()) + private static final int SCO_MODE_VIRTUAL_CALL = 0; + // SCO audio mode is raw audio (BluetoothHeadset.connectAudio()) + private static final int SCO_MODE_RAW = 1; + // Current connection state indicated by bluetooth headset private int mScoConnectionState; @@ -1910,7 +1919,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished { } /** @see AudioManager#startBluetoothSco() */ - public void startBluetoothSco(IBinder cb){ + public void startBluetoothSco(IBinder cb, int targetSdkVersion){ if (!checkAudioSettingsPermission("startBluetoothSco()") || !mBootCompleted) { return; @@ -1922,7 +1931,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished { // The caller identity must be cleared after getScoClient() because it is needed if a new // client is created. final long ident = Binder.clearCallingIdentity(); - client.incCount(); + client.incCount(targetSdkVersion); Binder.restoreCallingIdentity(ident); } @@ -1968,9 +1977,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished { } } - public void incCount() { + public void incCount(int targetSdkVersion) { synchronized(mScoClients) { - requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED); + requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, targetSdkVersion); if (mStartcount == 0) { try { mCb.linkToDeath(this, 0); @@ -1996,7 +2005,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished { Log.w(TAG, "decCount() going to 0 but not registered to binder"); } } - requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED); + requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0); } } } @@ -2012,7 +2021,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished { } mStartcount = 0; if (stopSco) { - requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED); + requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0); } } } @@ -2040,7 +2049,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished { } } - private void requestScoState(int state) { + private void requestScoState(int state, int targetSdkVersion) { checkScoAudioState(); if (totalCount() == 0) { if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) { @@ -2055,8 +2064,18 @@ public class AudioService extends IAudioService.Stub implements OnFinished { (mScoAudioState == SCO_STATE_INACTIVE || mScoAudioState == SCO_STATE_DEACTIVATE_REQ)) { if (mScoAudioState == SCO_STATE_INACTIVE) { + mScoAudioMode = + (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ? + SCO_MODE_VIRTUAL_CALL : SCO_MODE_RAW; if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) { - if (mBluetoothHeadset.connectAudio()) { + boolean status; + if (mScoAudioMode == SCO_MODE_RAW) { + status = mBluetoothHeadset.connectAudio(); + } else { + status = mBluetoothHeadset.startScoUsingVirtualVoiceCall( + mBluetoothHeadsetDevice); + } + if (status) { mScoAudioState = SCO_STATE_ACTIVE_INTERNAL; } else { broadcastScoConnectionState( @@ -2078,7 +2097,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished { mScoAudioState == SCO_STATE_ACTIVATE_REQ)) { if (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL) { if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) { - if (!mBluetoothHeadset.disconnectAudio()) { + boolean status; + if (mScoAudioMode == SCO_MODE_RAW) { + status = mBluetoothHeadset.disconnectAudio(); + } else { + status = mBluetoothHeadset.stopScoUsingVirtualVoiceCall( + mBluetoothHeadsetDevice); + } + if (!status) { mScoAudioState = SCO_STATE_INACTIVE; broadcastScoConnectionState( AudioManager.SCO_AUDIO_STATE_DISCONNECTED); @@ -2251,10 +2277,20 @@ public class AudioService extends IAudioService.Stub implements OnFinished { switch (mScoAudioState) { case SCO_STATE_ACTIVATE_REQ: mScoAudioState = SCO_STATE_ACTIVE_INTERNAL; - status = mBluetoothHeadset.connectAudio(); + if (mScoAudioMode == SCO_MODE_RAW) { + status = mBluetoothHeadset.connectAudio(); + } else { + status = mBluetoothHeadset.startScoUsingVirtualVoiceCall( + mBluetoothHeadsetDevice); + } break; case SCO_STATE_DEACTIVATE_REQ: - status = mBluetoothHeadset.disconnectAudio(); + if (mScoAudioMode == SCO_MODE_RAW) { + status = mBluetoothHeadset.disconnectAudio(); + } else { + status = mBluetoothHeadset.stopScoUsingVirtualVoiceCall( + mBluetoothHeadsetDevice); + } break; case SCO_STATE_DEACTIVATE_EXT_REQ: status = mBluetoothHeadset.stopVoiceRecognition( diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 13f6c02..0d285fc 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -179,7 +179,7 @@ interface IAudioService { int getRemoteStreamVolume(); oneway void registerRemoteVolumeObserverForRcc(int rccId, in IRemoteVolumeObserver rvo); - void startBluetoothSco(IBinder cb); + void startBluetoothSco(IBinder cb, int targetSdkVersion); void stopBluetoothSco(IBinder cb); void forceVolumeControlStream(int streamType, IBinder cb); |