AudioManager: add startBluetoothScoVirtualCall()

Add API to start bluetooth SCO audio connection explicitly
in virtual call mode.

Bug: 11824396.
Change-Id: I1dfab13c659f5855e0b78467ac48b3186af7874c
This commit is contained in:
Eric Laurent
2014-05-15 15:14:22 -07:00
parent 60c958cd9f
commit 83900754f3
4 changed files with 52 additions and 15 deletions

View File

@@ -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);

View File

@@ -1254,11 +1254,6 @@ 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>
@@ -1274,6 +1269,11 @@ public class AudioManager {
* it will be ignored. Similarly, if a call is received or sent while an application
* is using the SCO connection, the connection will be lost for the application and NOT
* returned automatically when the call ends.
* <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.
* @see #stopBluetoothSco()
* @see #ACTION_SCO_AUDIO_STATE_UPDATED
*/
@@ -1286,14 +1286,39 @@ public class AudioManager {
}
}
/**
* Start bluetooth SCO audio connection in virtual call mode.
* <p>Requires Permission:
* {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
* <p>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.
* <p>Requires Permission:
* {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
* <p>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();

View File

@@ -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) {

View File

@@ -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);