Merge "Fix AudioManager.forceVolumeControlStream()" into jb-dev
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 41d5c32..012e095 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -47,7 +47,6 @@
private final Context mContext;
private long mVolumeKeyUpTime;
- private int mVolumeControlStream = -1;
private final boolean mUseMasterVolume;
private static String TAG = "AudioManager";
@@ -304,13 +303,6 @@
public static final int FLAG_VIBRATE = 1 << 4;
/**
- * forces use of specified stream
- * @hide
- */
- public static final int FLAG_FORCE_STREAM = 1 << 5;
-
-
- /**
* Ringer mode that will be silent and will not vibrate. (This overrides the
* vibrate setting.)
*
@@ -458,10 +450,6 @@
: ADJUST_LOWER,
flags);
} else {
- if (mVolumeControlStream != -1) {
- stream = mVolumeControlStream;
- flags |= FLAG_FORCE_STREAM;
- }
adjustSuggestedStreamVolume(
keyCode == KeyEvent.KEYCODE_VOLUME_UP
? ADJUST_RAISE
@@ -500,10 +488,6 @@
}
} else {
int flags = FLAG_PLAY_SOUND;
- if (mVolumeControlStream != -1) {
- stream = mVolumeControlStream;
- flags |= FLAG_FORCE_STREAM;
- }
adjustSuggestedStreamVolume(
ADJUST_SAME,
stream,
@@ -943,7 +927,12 @@
* @hide
*/
public void forceVolumeControlStream(int streamType) {
- mVolumeControlStream = streamType;
+ IAudioService service = getService();
+ try {
+ service.forceVolumeControlStream(streamType, mICallBack);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in forceVolumeControlStream", e);
+ }
}
/**
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 48d3712..dcf72cc 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -149,6 +149,7 @@
private int mMode;
// protects mRingerMode
private final Object mSettingsLock = new Object();
+
private boolean mMediaServerOk;
private SoundPool mSoundPool;
@@ -343,6 +344,14 @@
// Keyguard manager proxy
private KeyguardManager mKeyguardManager;
+ // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume
+ // is controlled by Vol keys.
+ private int mVolumeControlStream = -1;
+ private final Object mForceControlStreamLock = new Object();
+ // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system
+ // server process so in theory it is not necessary to monitor the client death.
+ // However it is good to be ready for future evolutions.
+ private ForceControlStreamClient mForceControlStreamClient = null;
///////////////////////////////////////////////////////////////////////////
// Construction
@@ -538,8 +547,8 @@
public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) {
int streamType;
- if ((flags & AudioManager.FLAG_FORCE_STREAM) != 0) {
- streamType = suggestedStreamType;
+ if (mVolumeControlStream != -1) {
+ streamType = mVolumeControlStream;
} else {
streamType = getActiveStreamType(suggestedStreamType);
}
@@ -682,6 +691,57 @@
sendVolumeUpdate(streamType, oldIndex, index, flags);
}
+ /** @see AudioManager#forceVolumeControlStream(int) */
+ public void forceVolumeControlStream(int streamType, IBinder cb) {
+ synchronized(mForceControlStreamLock) {
+ mVolumeControlStream = streamType;
+ if (mVolumeControlStream == -1) {
+ if (mForceControlStreamClient != null) {
+ mForceControlStreamClient.release();
+ mForceControlStreamClient = null;
+ }
+ } else {
+ mForceControlStreamClient = new ForceControlStreamClient(cb);
+ }
+ }
+ }
+
+ private class ForceControlStreamClient implements IBinder.DeathRecipient {
+ private IBinder mCb; // To be notified of client's death
+
+ ForceControlStreamClient(IBinder cb) {
+ if (cb != null) {
+ try {
+ cb.linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ // Client has died!
+ Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death");
+ cb = null;
+ }
+ }
+ mCb = cb;
+ }
+
+ public void binderDied() {
+ synchronized(mForceControlStreamLock) {
+ Log.w(TAG, "SCO client died");
+ if (mForceControlStreamClient != this) {
+ Log.w(TAG, "unregistered control stream client died");
+ } else {
+ mForceControlStreamClient = null;
+ mVolumeControlStream = -1;
+ }
+ }
+ }
+
+ public void release() {
+ if (mCb != null) {
+ mCb.unlinkToDeath(this, 0);
+ mCb = null;
+ }
+ }
+ }
+
private int findVolumeDelta(int direction, int volume) {
int delta = 0;
if (direction == AudioManager.ADJUST_RAISE) {
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index b775095..0311c59 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -115,4 +115,6 @@
void startBluetoothSco(IBinder cb);
void stopBluetoothSco(IBinder cb);
+
+ void forceVolumeControlStream(int streamType, IBinder cb);
}