Skip to content

Commit 45c90ce

Browse files
author
Eric Laurent
committed
Fix AudioManager.forceVolumeControlStream()
AudioManager.forceVolumeControlStream() is used by VolumePanel to temporarily force the stream type which volume is controlled by volume keys. Current implementation is not working if the VolumePanel is not executed by the same process as the one receiving the volume key events. Issue 6302421. Change-Id: I2700587a027ffb962429b42083312cd92fe79215
1 parent 1b8f499 commit 45c90ce

File tree

3 files changed

+70
-19
lines changed

3 files changed

+70
-19
lines changed

media/java/android/media/AudioManager.java

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ public class AudioManager {
4747

4848
private final Context mContext;
4949
private long mVolumeKeyUpTime;
50-
private int mVolumeControlStream = -1;
5150
private final boolean mUseMasterVolume;
5251
private static String TAG = "AudioManager";
5352

@@ -303,13 +302,6 @@ public class AudioManager {
303302
*/
304303
public static final int FLAG_VIBRATE = 1 << 4;
305304

306-
/**
307-
* forces use of specified stream
308-
* @hide
309-
*/
310-
public static final int FLAG_FORCE_STREAM = 1 << 5;
311-
312-
313305
/**
314306
* Ringer mode that will be silent and will not vibrate. (This overrides the
315307
* vibrate setting.)
@@ -458,10 +450,6 @@ public void handleKeyDown(KeyEvent event, int stream) {
458450
: ADJUST_LOWER,
459451
flags);
460452
} else {
461-
if (mVolumeControlStream != -1) {
462-
stream = mVolumeControlStream;
463-
flags |= FLAG_FORCE_STREAM;
464-
}
465453
adjustSuggestedStreamVolume(
466454
keyCode == KeyEvent.KEYCODE_VOLUME_UP
467455
? ADJUST_RAISE
@@ -500,10 +488,6 @@ public void handleKeyUp(KeyEvent event, int stream) {
500488
}
501489
} else {
502490
int flags = FLAG_PLAY_SOUND;
503-
if (mVolumeControlStream != -1) {
504-
stream = mVolumeControlStream;
505-
flags |= FLAG_FORCE_STREAM;
506-
}
507491
adjustSuggestedStreamVolume(
508492
ADJUST_SAME,
509493
stream,
@@ -943,7 +927,12 @@ public boolean isMasterMute() {
943927
* @hide
944928
*/
945929
public void forceVolumeControlStream(int streamType) {
946-
mVolumeControlStream = streamType;
930+
IAudioService service = getService();
931+
try {
932+
service.forceVolumeControlStream(streamType, mICallBack);
933+
} catch (RemoteException e) {
934+
Log.e(TAG, "Dead object in forceVolumeControlStream", e);
935+
}
947936
}
948937

949938
/**

media/java/android/media/AudioService.java

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ public class AudioService extends IAudioService.Stub {
149149
private int mMode;
150150
// protects mRingerMode
151151
private final Object mSettingsLock = new Object();
152+
152153
private boolean mMediaServerOk;
153154

154155
private SoundPool mSoundPool;
@@ -343,6 +344,14 @@ public void onError(int error) {
343344
// Keyguard manager proxy
344345
private KeyguardManager mKeyguardManager;
345346

347+
// mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume
348+
// is controlled by Vol keys.
349+
private int mVolumeControlStream = -1;
350+
private final Object mForceControlStreamLock = new Object();
351+
// VolumePanel is currently the only client of forceVolumeControlStream() and runs in system
352+
// server process so in theory it is not necessary to monitor the client death.
353+
// However it is good to be ready for future evolutions.
354+
private ForceControlStreamClient mForceControlStreamClient = null;
346355

347356
///////////////////////////////////////////////////////////////////////////
348357
// Construction
@@ -538,8 +547,8 @@ public void adjustVolume(int direction, int flags) {
538547
public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) {
539548

540549
int streamType;
541-
if ((flags & AudioManager.FLAG_FORCE_STREAM) != 0) {
542-
streamType = suggestedStreamType;
550+
if (mVolumeControlStream != -1) {
551+
streamType = mVolumeControlStream;
543552
} else {
544553
streamType = getActiveStreamType(suggestedStreamType);
545554
}
@@ -682,6 +691,57 @@ public void setStreamVolume(int streamType, int index, int flags) {
682691
sendVolumeUpdate(streamType, oldIndex, index, flags);
683692
}
684693

694+
/** @see AudioManager#forceVolumeControlStream(int) */
695+
public void forceVolumeControlStream(int streamType, IBinder cb) {
696+
synchronized(mForceControlStreamLock) {
697+
mVolumeControlStream = streamType;
698+
if (mVolumeControlStream == -1) {
699+
if (mForceControlStreamClient != null) {
700+
mForceControlStreamClient.release();
701+
mForceControlStreamClient = null;
702+
}
703+
} else {
704+
mForceControlStreamClient = new ForceControlStreamClient(cb);
705+
}
706+
}
707+
}
708+
709+
private class ForceControlStreamClient implements IBinder.DeathRecipient {
710+
private IBinder mCb; // To be notified of client's death
711+
712+
ForceControlStreamClient(IBinder cb) {
713+
if (cb != null) {
714+
try {
715+
cb.linkToDeath(this, 0);
716+
} catch (RemoteException e) {
717+
// Client has died!
718+
Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death");
719+
cb = null;
720+
}
721+
}
722+
mCb = cb;
723+
}
724+
725+
public void binderDied() {
726+
synchronized(mForceControlStreamLock) {
727+
Log.w(TAG, "SCO client died");
728+
if (mForceControlStreamClient != this) {
729+
Log.w(TAG, "unregistered control stream client died");
730+
} else {
731+
mForceControlStreamClient = null;
732+
mVolumeControlStream = -1;
733+
}
734+
}
735+
}
736+
737+
public void release() {
738+
if (mCb != null) {
739+
mCb.unlinkToDeath(this, 0);
740+
mCb = null;
741+
}
742+
}
743+
}
744+
685745
private int findVolumeDelta(int direction, int volume) {
686746
int delta = 0;
687747
if (direction == AudioManager.ADJUST_RAISE) {

media/java/android/media/IAudioService.aidl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,6 @@ interface IAudioService {
115115
void startBluetoothSco(IBinder cb);
116116

117117
void stopBluetoothSco(IBinder cb);
118+
119+
void forceVolumeControlStream(int streamType, IBinder cb);
118120
}

0 commit comments

Comments
 (0)