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

Commit 5befdff9 authored by Phil Yan's avatar Phil Yan
Browse files

Restore audio focus correctly after transient sounds

When multi-audio focus is enabled, media sound that is ducked by a
transient notification sound is not restored after the notification
ends.

The original logic in `notifyTopOfAudioFocusStack` only restored focus
to "locked" focus owners, not regular media players that experienced a
transient focus loss.

This change updates the logic to iterate through the multi-focus list
and restore focus to any requester that has experienced a transient
loss (`...CAN_DUCK` or `...TRANSIENT`). A helper method
`isLossReceivedTransient()` is added to `AudioFocusInfo`.

The change also preserves the original failsafe check for locked focus
owners.

Bug: 441513449
Test: Manually verified with logs that ducked media players are
restored successfully https://paste.googleplex.com/5371234006859776
Flag: android.media.audio.audio_focus_desktop

Change-Id: If3cf75fa980ac7d6791e919b50defa6997282c2d
parent 95436ef4
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -130,6 +130,12 @@ public final class AudioFocusInfo implements Parcelable {
     */
    public int getFlags() { return mFlags; }

    /** @hide */
    public boolean isLossReceivedTransient() {
        return mLossReceived == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT
                || mLossReceived == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK;
    }

    @Override
    public int describeContents() {
        return 0;
+18 −3
Original line number Diff line number Diff line
@@ -407,7 +407,21 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
            }
        }

        // Also handle focus restoration for apps in the multi-focus list.
        if (mMultiAudioFocusEnabled && !mMultiAudioFocusList.isEmpty()) {
            if (audioFocusDesktop()) {
                final boolean canReassignAudioFocus = canReassignAudioFocus();
                for (FocusRequester multifr : mMultiAudioFocusList) {
                    // Check if the requester needs its focus restored. This is true if:
                    //  - focus can be reassigned (e.g. no call) AND it had a transient loss,
                    //  - OR it's a locked focus owner.
                    if ((canReassignAudioFocus
                            && multifr.toAudioFocusInfo().isLossReceivedTransient())
                            || isLockedFocusOwner(multifr)) {
                        multifr.handleFocusGain(AudioManager.AUDIOFOCUS_GAIN);
                    }
                }
            } else {
                for (FocusRequester multifr : mMultiAudioFocusList) {
                    if (isLockedFocusOwner(multifr)) {
                        multifr.handleFocusGain(AudioManager.AUDIOFOCUS_GAIN);
@@ -415,6 +429,7 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
                }
            }
        }
    }

    /**
     * Focus is requested, propagate the associated loss throughout the stack.