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

Commit ea3257d7 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi Committed by Android (Google) Code Review
Browse files

Merge "Audio focus: fix delayed focus request during locked focus behavior"

parents 11be0cfb bec223b3
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -4003,8 +4003,7 @@ public class AudioManager {
     * @hide
     * flag set on test API calls,
     * see {@link #requestAudioFocusForTest(AudioFocusRequest, String, int, int)},
     * note that it isn't used in conjunction with other flags, it is passed as the single
     * value for flags */
     */
    public static final int AUDIOFOCUS_FLAG_TEST = 0x1 << 3;
    /** @hide */
    public static final int AUDIOFOCUS_FLAGS_APPS = AUDIOFOCUS_FLAG_DELAY_OK
@@ -4187,7 +4186,9 @@ public class AudioManager {
                    afr.getFocusGain(),
                    mICallBack,
                    mAudioFocusDispatcher,
                    clientFakeId, "com.android.test.fakeclient", clientFakeUid, clientTargetSdk);
                    clientFakeId, "com.android.test.fakeclient",
                    afr.getFlags() | AudioManager.AUDIOFOCUS_FLAG_TEST,
                    clientFakeUid, clientTargetSdk);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+1 −1
Original line number Diff line number Diff line
@@ -384,7 +384,7 @@ interface IAudioService {

    int requestAudioFocusForTest(in AudioAttributes aa, int durationHint, IBinder cb,
            in IAudioFocusDispatcher fd, in String clientId, in String callingPackageName,
            int uid, int sdk);
            int flags, int uid, int sdk);

    int abandonAudioFocusForTest(in IAudioFocusDispatcher fd, in String clientId,
            in AudioAttributes aa, in String callingPackageName);
+5 −2
Original line number Diff line number Diff line
@@ -8252,6 +8252,9 @@ public class AudioService extends IAudioService.Stub
    public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb,
            IAudioFocusDispatcher fd, String clientId, String callingPackageName,
            String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk) {
        if ((flags & AudioManager.AUDIOFOCUS_FLAG_TEST) != 0) {
            throw new IllegalArgumentException("Invalid test flag");
        }
        final int uid = Binder.getCallingUid();
        MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
                .setUid(uid)
@@ -8310,7 +8313,7 @@ public class AudioService extends IAudioService.Stub
    /** see {@link AudioManager#requestAudioFocusForTest(AudioFocusRequest, String, int, int)} */
    public int requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb,
            IAudioFocusDispatcher fd, String clientId, String callingPackageName,
            int fakeUid, int sdk) {
            int flags, int fakeUid, int sdk) {
        if (!enforceQueryAudioStateForTest("focus request")) {
            return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
        }
@@ -8320,7 +8323,7 @@ public class AudioService extends IAudioService.Stub
            return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
        }
        return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
                clientId, callingPackageName, null, AudioManager.AUDIOFOCUS_FLAG_TEST,
                clientId, callingPackageName, null, flags,
                sdk, false /*forceDuck*/, fakeUid);
    }

+36 −7
Original line number Diff line number Diff line
@@ -461,11 +461,17 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
     *                 at the top of the focus stack
     * Push the focus requester onto the audio focus stack at the first position immediately
     * following the locked focus owners.
     * Propagate through the stack the changes that the new (future) focus owner causes.
     * @param nfr the future focus owner that will gain focus when the locked focus owners are
     *            removed from the stack
     * @return {@link AudioManager#AUDIOFOCUS_REQUEST_GRANTED} or
     *     {@link AudioManager#AUDIOFOCUS_REQUEST_DELAYED}
     */
    @GuardedBy("mAudioFocusLock")
    private int pushBelowLockedFocusOwners(FocusRequester nfr) {
    private int pushBelowLockedFocusOwnersAndPropagate(FocusRequester nfr) {
        if (DEBUG) {
            Log.v(TAG, "pushBelowLockedFocusOwnersAndPropagate client=" + nfr.getClientId());
        }
        int lastLockedFocusOwnerIndex = mFocusStack.size();
        for (int index = mFocusStack.size() - 1; index >= 0; index--) {
            if (isLockedFocusOwner(mFocusStack.elementAt(index))) {
@@ -480,10 +486,33 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
            propagateFocusLossFromGain_syncAf(nfr.getGainRequest(), nfr, false /*forceDuck*/);
            mFocusStack.push(nfr);
            return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
        } else {
        }

        if (DEBUG) {
            Log.v(TAG, "> lastLockedFocusOwnerIndex=" + lastLockedFocusOwnerIndex);
        }
        mFocusStack.insertElementAt(nfr, lastLockedFocusOwnerIndex);
            return AudioManager.AUDIOFOCUS_REQUEST_DELAYED;

        // propagate potential focus loss (and removal from stack) after the newly
        // inserted FocusRequester (at index lastLockedFocusOwnerIndex-1)
        final List<String> clientsToRemove = new LinkedList<String>();
        for (int index = lastLockedFocusOwnerIndex - 1; index >= 0; index--) {
            final boolean isDefinitiveLoss =
                    mFocusStack.elementAt(index).handleFocusLossFromGain(
                            nfr.getGainRequest(), nfr, false /*forceDuck*/);
            if (isDefinitiveLoss) {
                clientsToRemove.add(mFocusStack.elementAt(index).getClientId());
            }
        }
        for (String clientToRemove : clientsToRemove) {
            if (DEBUG) {
                Log.v(TAG, "> removing focus client " + clientToRemove);
            }
            removeFocusStackEntry(clientToRemove, false /*signal*/,
                    true /*notifyFocusFollowers*/);
        }

        return AudioManager.AUDIOFOCUS_REQUEST_DELAYED;
    }

    /**
@@ -868,7 +897,7 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
     * @param forceDuck only true if
     *     {@link android.media.AudioFocusRequest.Builder#setFocusGain(int)} was set to true for
     *                  accessibility.
     * @param testUid ignored if flags is not AudioManager.AUDIOFOCUS_FLAG_TEST (strictly equals to)
     * @param testUid ignored if flags doesn't contain AudioManager.AUDIOFOCUS_FLAG_TEST
     *                otherwise the UID being injected for testing
     * @return
     */
@@ -1029,7 +1058,7 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
            if (focusGrantDelayed) {
                // focusGrantDelayed being true implies we can't reassign focus right now
                // which implies the focus stack is not empty.
                final int requestResult = pushBelowLockedFocusOwners(nfr);
                final int requestResult = pushBelowLockedFocusOwnersAndPropagate(nfr);
                if (requestResult != AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
                    notifyExtPolicyFocusGrant_syncAf(nfr.toAudioFocusInfo(), requestResult);
                }