summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2013-04-19 15:39:22 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-04-19 15:39:22 +0000
commit56af4f212a21fe08b54de10322e023b09fa125aa (patch)
treeb5b8ba39fa5f0b87e04462b2ceb68756d10d2e5b /media
parent6ead6ccac9727993559c9f09f1e8da3c69ee3313 (diff)
parentc18c9138cee0f0859bcab636a004ce92ca4a9ab5 (diff)
downloadframeworks_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.java8
-rw-r--r--media/java/android/media/AudioService.java58
-rw-r--r--media/java/android/media/IAudioService.aidl2
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);