Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3194ea94 authored by Mike Lockwood's avatar Mike Lockwood
Browse files

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

Signed-off-by: default avatarMike Lockwood <lockwood@google.com>
parent 0dc37cce
Loading
Loading
Loading
Loading
+3 −120
Original line number Diff line number Diff line
@@ -146,7 +146,6 @@ public class AudioService extends IAudioService.Stub {
    private AudioHandler mAudioHandler;
    /** @see VolumeStreamState */
    private VolumeStreamState[] mStreamStates;
    private MasterMuteState mMasterMuteState;
    private SettingsObserver mSettingsObserver;

    private int mMode;
@@ -451,7 +450,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++) {
@@ -793,12 +791,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) */
@@ -2276,122 +2275,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() {