Remove reference counting and client death notification for master mute

The use case for master mute is to toggle it on and off from a
KEYCODE_VOLUME_MUTE event, so this was unnecessary and prevented unmuting
in certain cases

Bug: 5724755

Change-Id: I041a112cd39e1c00dcae27e2266a95ce225e9b64
Signed-off-by: Mike Lockwood <lockwood@google.com>
This commit is contained in:
Mike Lockwood
2011-12-07 11:47:31 -08:00
parent 3edc62bc35
commit a8f4e83595

View File

@@ -141,7 +141,6 @@ public class AudioService extends IAudioService.Stub {
private AudioHandler mAudioHandler;
/** @see VolumeStreamState */
private VolumeStreamState[] mStreamStates;
private MasterMuteState mMasterMuteState;
private SettingsObserver mSettingsObserver;
private int mMode;
@@ -443,7 +442,6 @@ public class AudioService extends IAudioService.Stub {
for (int i = 0; i < numStreamTypes; i++) {
streams[i] = new VolumeStreamState(System.VOLUME_SETTINGS[STREAM_VOLUME_ALIAS[i]], i);
}
mMasterMuteState = new MasterMuteState();
// Correct stream index values for streams with aliases
for (int i = 0; i < numStreamTypes; i++) {
@@ -745,12 +743,13 @@ public class AudioService extends IAudioService.Stub {
/** @see AudioManager#setMasterMute(boolean, IBinder) */
public void setMasterMute(boolean state, IBinder cb) {
mMasterMuteState.mute(cb, state);
AudioSystem.setMasterMute(state);
sendMasterMuteUpdate(state, AudioManager.FLAG_SHOW_UI);
}
/** get master mute state. */
public boolean isMasterMute() {
return (mMasterMuteState.muteCount() != 0);
return AudioSystem.getMasterMute();
}
/** @see AudioManager#getStreamVolume(int) */
@@ -2150,122 +2149,6 @@ public class AudioService extends IAudioService.Stub {
}
}
public class MasterMuteState {
private ArrayList<MasterMuteDeathHandler> mDeathHandlers;
private MasterMuteState() {
mDeathHandlers = new ArrayList<MasterMuteDeathHandler>();
}
public void mute(IBinder cb, boolean state) {
MasterMuteDeathHandler handler = getDeathHandler(cb, state);
if (handler == null) {
Log.e(TAG, "Could not get client death handler for master volume");
return;
}
handler.mute(state);
}
private class MasterMuteDeathHandler implements IBinder.DeathRecipient {
private IBinder mICallback; // To be notified of client's death
private int mMuteCount; // Number of active mutes for this client
MasterMuteDeathHandler(IBinder cb) {
mICallback = cb;
}
public void mute(boolean state) {
synchronized(mDeathHandlers) {
if (state) {
if (mMuteCount == 0) {
// Register for client death notification
try {
// mICallback can be 0 if muted by AudioService
if (mICallback != null) {
mICallback.linkToDeath(this, 0);
}
mDeathHandlers.add(this);
// If the stream is not yet muted by any client, set lvel to 0
if (muteCount() == 0) {
AudioSystem.setMasterMute(true);
sendMasterMuteUpdate(true, AudioManager.FLAG_SHOW_UI);
}
} catch (RemoteException e) {
// Client has died!
binderDied();
mDeathHandlers.notify();
return;
}
} else {
Log.w(TAG, "master volume was already muted by this client");
}
mMuteCount++;
} else {
if (mMuteCount == 0) {
Log.e(TAG, "unexpected unmute for master volume");
} else {
mMuteCount--;
if (mMuteCount == 0) {
// Unregistr from client death notification
mDeathHandlers.remove(this);
// mICallback can be 0 if muted by AudioService
if (mICallback != null) {
mICallback.unlinkToDeath(this, 0);
}
if (muteCount() == 0) {
AudioSystem.setMasterMute(false);
sendMasterMuteUpdate(false, AudioManager.FLAG_SHOW_UI);
}
}
}
}
mDeathHandlers.notify();
}
}
public void binderDied() {
Log.w(TAG, "Volume service client died for master volume");
if (mMuteCount != 0) {
// Reset all active mute requests from this client.
mMuteCount = 1;
mute(false);
}
}
}
private int muteCount() {
int count = 0;
int size = mDeathHandlers.size();
for (int i = 0; i < size; i++) {
count += mDeathHandlers.get(i).mMuteCount;
}
return count;
}
private MasterMuteDeathHandler getDeathHandler(IBinder cb, boolean state) {
synchronized(mDeathHandlers) {
MasterMuteDeathHandler handler;
int size = mDeathHandlers.size();
for (int i = 0; i < size; i++) {
handler = mDeathHandlers.get(i);
if (cb == handler.mICallback) {
return handler;
}
}
// If this is the first mute request for this client, create a new
// client death handler. Otherwise, it is an out of sequence unmute request.
if (state) {
handler = new MasterMuteDeathHandler(cb);
} else {
Log.w(TAG, "stream was not muted by this client");
handler = null;
}
return handler;
}
}
}
/** Thread that handles native AudioSystem control. */
private class AudioSystemThread extends Thread {
AudioSystemThread() {