diff --git a/api/current.txt b/api/current.txt index ddde2f714eb57..6387eb7d34848 100644 --- a/api/current.txt +++ b/api/current.txt @@ -13798,6 +13798,7 @@ package android.media { method public deprecated void setWiredHeadsetOn(boolean); method public deprecated boolean shouldVibrate(int); method public void startBluetoothSco(); + method public void startBluetoothScoVirtualCall(); method public void stopBluetoothSco(); method public void unloadSoundEffects(); method public void unregisterMediaButtonEventReceiver(android.content.ComponentName); diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index d35225ab66e2b..47b6024c113ef 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -1254,11 +1254,6 @@ public class AudioManager { * call {@link #stopBluetoothSco()} to clear the request and turn down the bluetooth connection. *
Even if a SCO connection is established, the following restrictions apply on audio * output streams so that they can be routed to SCO headset: - *
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. *
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. * @see #stopBluetoothSco() * @see #ACTION_SCO_AUDIO_STATE_UPDATED */ @@ -1286,14 +1286,39 @@ public class AudioManager { } } + /** + * Start bluetooth SCO audio connection in virtual call mode. + *
Requires Permission: + * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}. + *
Similar to {@link #startBluetoothSco()} with explicit selection of virtual call mode. + * Telephony and communication applications (VoIP, Video Chat) should preferably select + * virtual call mode. + * Applications using voice input for search or commands should first try raw audio connection + * with {@link #startBluetoothSco()} and fall back to startBluetoothScoVirtualCall() in case of + * failure. + * @see #startBluetoothSco() + * @see #stopBluetoothSco() + * @see #ACTION_SCO_AUDIO_STATE_UPDATED + */ + public void startBluetoothScoVirtualCall() { + IAudioService service = getService(); + try { + service.startBluetoothScoVirtualCall(mICallBack); + } catch (RemoteException e) { + Log.e(TAG, "Dead object in startBluetoothScoVirtualCall", e); + } + } + /** * Stop bluetooth SCO audio connection. *
Requires Permission: * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}. *
This method must be called by applications having requested the use of - * bluetooth SCO audio with {@link #startBluetoothSco()} - * when finished with the SCO connection or if connection fails. + * bluetooth SCO audio with {@link #startBluetoothSco()} or + * {@link #startBluetoothScoVirtualCall()} when finished with the SCO connection or + * if connection fails. * @see #startBluetoothSco() + * @see #startBluetoothScoVirtualCall() */ public void stopBluetoothSco(){ IAudioService service = getService(); diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 48479a434415c..6b7d7a9b101e6 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -2056,7 +2056,19 @@ public class AudioService extends IAudioService.Stub { } /** @see AudioManager#startBluetoothSco() */ - public void startBluetoothSco(IBinder cb, int targetSdkVersion){ + public void startBluetoothSco(IBinder cb, int targetSdkVersion) { + int scoAudioMode = + (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ? + SCO_MODE_VIRTUAL_CALL : SCO_MODE_RAW; + startBluetoothScoInt(cb, scoAudioMode); + } + + /** @see AudioManager#startBluetoothScoVirtualCall() */ + public void startBluetoothScoVirtualCall(IBinder cb) { + startBluetoothScoInt(cb, SCO_MODE_VIRTUAL_CALL); + } + + void startBluetoothScoInt(IBinder cb, int scoAudioMode){ if (!checkAudioSettingsPermission("startBluetoothSco()") || !mSystemReady) { return; @@ -2068,7 +2080,7 @@ public class AudioService extends IAudioService.Stub { // 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(targetSdkVersion); + client.incCount(scoAudioMode); Binder.restoreCallingIdentity(ident); } @@ -2114,9 +2126,9 @@ public class AudioService extends IAudioService.Stub { } } - public void incCount(int targetSdkVersion) { + public void incCount(int scoAudioMode) { synchronized(mScoClients) { - requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, targetSdkVersion); + requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode); if (mStartcount == 0) { try { mCb.linkToDeath(this, 0); @@ -2186,7 +2198,7 @@ public class AudioService extends IAudioService.Stub { } } - private void requestScoState(int state, int targetSdkVersion) { + private void requestScoState(int state, int scoAudioMode) { checkScoAudioState(); if (totalCount() == 0) { if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) { @@ -2201,9 +2213,7 @@ public class AudioService extends IAudioService.Stub { (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; + mScoAudioMode = scoAudioMode; if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) { boolean status; if (mScoAudioMode == SCO_MODE_RAW) { diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 169631e2e63e4..41e691d553031 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -217,6 +217,7 @@ interface IAudioService { oneway void registerRemoteVolumeObserverForRcc(int rccId, in IRemoteVolumeObserver rvo); void startBluetoothSco(IBinder cb, int targetSdkVersion); + void startBluetoothScoVirtualCall(IBinder cb); void stopBluetoothSco(IBinder cb); void forceVolumeControlStream(int streamType, IBinder cb);