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

Commit 895f77c7 authored by François Gaffie's avatar François Gaffie Committed by Automerger Merge Worker
Browse files

[BUG] AudioService: fix mute/umute of aliased streams. am: 92a2d9aa

parents c73004ae 92a2d9aa
Loading
Loading
Loading
Loading
+79 −32
Original line number Diff line number Diff line
@@ -3343,15 +3343,7 @@ public class AudioService extends IAudioService.Stub
                } else {
                    state = direction == AudioManager.ADJUST_MUTE;
                }
                for (int stream = 0; stream < mStreamStates.length; stream++) {
                    if (streamTypeAlias == mStreamVolumeAlias[stream]) {
                        if (!(readCameraSoundForced()
                                    && (mStreamStates[stream].getStreamType()
                                        == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
                            mStreamStates[stream].mute(state);
                        }
                    }
                }
                muteAliasStreams(streamTypeAlias, state);
            } else if ((direction == AudioManager.ADJUST_RAISE) &&
                    !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {
                Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex);
@@ -3366,7 +3358,7 @@ public class AudioService extends IAudioService.Stub
                    // Unmute the stream if it was previously muted
                    if (direction == AudioManager.ADJUST_RAISE) {
                        // unmute immediately for volume up
                        streamState.mute(false);
                        muteAliasStreams(streamTypeAlias, false);
                    } else if (direction == AudioManager.ADJUST_LOWER) {
                        if (mIsSingleVolume) {
                            sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE,
@@ -3492,6 +3484,42 @@ public class AudioService extends IAudioService.Stub
        sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device);
    }
    /**
     * Loops on aliasted stream, update the mute cache attribute of each
     * {@see AudioService#VolumeStreamState}, and then apply the change.
     * It prevents to unnecessary {@see AudioSystem#setStreamVolume} done for each stream
     * and aliases before mute change changed and after.
     */
    private void muteAliasStreams(int streamAlias, boolean state) {
        synchronized (VolumeStreamState.class) {
            List<Integer> streamsToMute = new ArrayList<>();
            for (int stream = 0; stream < mStreamStates.length; stream++) {
                if (streamAlias == mStreamVolumeAlias[stream]) {
                    if (!(readCameraSoundForced()
                            && (mStreamStates[stream].getStreamType()
                                    == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
                        boolean changed = mStreamStates[stream].mute(state, /* apply= */ false);
                        if (changed) {
                            streamsToMute.add(stream);
                        }
                    }
                }
            }
            streamsToMute.forEach(streamToMute -> {
                mStreamStates[streamToMute].doMute();
                broadcastMuteSetting(streamToMute, state);
            });
        }
    }
    private void broadcastMuteSetting(int streamType, boolean isMuted) {
        // Stream mute changed, fire the intent.
        Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
        intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType);
        intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, isMuted);
        sendBroadcastToAll(intent);
    }
    // Called after a delay when volume down is pressed while muted
    private void onUnmuteStream(int stream, int flags) {
        boolean wasMuted;
@@ -3611,7 +3639,8 @@ public class AudioService extends IAudioService.Stub
        // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements
        if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO)
                && (getDeviceForStream(stream) == device)) {
            mStreamStates[stream].mute(index == 0);
            // As adjustStreamVolume with muteAdjust flags mute/unmutes stream and aliased streams.
            muteAliasStreams(stream, index == 0);
        }
    }
@@ -7846,8 +7875,8 @@ public class AudioService extends IAudioService.Stub
        private int mIndexMinNoPerm;
        private int mIndexMax;
        private boolean mIsMuted;
        private boolean mIsMutedInternally;
        private boolean mIsMuted = false;
        private boolean mIsMutedInternally = false;
        private String mVolumeIndexSettingName;
        @NonNull private Set<Integer> mObservedDeviceSet = new TreeSet<>();
@@ -8272,27 +8301,10 @@ public class AudioService extends IAudioService.Stub
        public boolean mute(boolean state) {
            boolean changed = false;
            synchronized (VolumeStreamState.class) {
                if (state != mIsMuted) {
                    changed = true;
                    mIsMuted = state;
                    // Set the new mute volume. This propagates the values to
                    // the audio system, otherwise the volume won't be changed
                    // at the lower level.
                    sendMsg(mAudioHandler,
                            MSG_SET_ALL_VOLUMES,
                            SENDMSG_QUEUE,
                            0,
                            0,
                            this, 0);
                }
                changed = mute(state, true);
            }
            if (changed) {
                // Stream mute changed, fire the intent.
                Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
                intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
                intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, state);
                sendBroadcastToAll(intent);
                broadcastMuteSetting(mStreamType, state);
            }
            return changed;
        }
@@ -8324,6 +8336,41 @@ public class AudioService extends IAudioService.Stub
            return mIsMuted || mIsMutedInternally;
        }
        /**
         * Mute/unmute the stream
         * @param state the new mute state
         * @param apply true to propagate to HW, or false just to update the cache. May be needed
         * to mute a stream and its aliases as applyAllVolume will force settings to aliases.
         * It prevents unnecessary calls to {@see AudioSystem#setStreamVolume}
         * @return true if the mute state was changed
         */
        public boolean mute(boolean state, boolean apply) {
            synchronized (VolumeStreamState.class) {
                boolean changed = state != mIsMuted;
                if (changed) {
                    mIsMuted = state;
                    if (apply) {
                        doMute();
                    }
                }
                return changed;
            }
        }
        public void doMute() {
            synchronized (VolumeStreamState.class) {
                // Set the new mute volume. This propagates the values to
                // the audio system, otherwise the volume won't be changed
                // at the lower level.
                sendMsg(mAudioHandler,
                        MSG_SET_ALL_VOLUMES,
                        SENDMSG_QUEUE,
                        0,
                        0,
                        this, 0);
            }
        }
        public int getStreamType() {
            return mStreamType;
        }