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 Original line Diff line number Diff line
@@ -4003,8 +4003,7 @@ public class AudioManager {
     * @hide
     * @hide
     * flag set on test API calls,
     * flag set on test API calls,
     * see {@link #requestAudioFocusForTest(AudioFocusRequest, String, int, int)},
     * 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;
    public static final int AUDIOFOCUS_FLAG_TEST = 0x1 << 3;
    /** @hide */
    /** @hide */
    public static final int AUDIOFOCUS_FLAGS_APPS = AUDIOFOCUS_FLAG_DELAY_OK
    public static final int AUDIOFOCUS_FLAGS_APPS = AUDIOFOCUS_FLAG_DELAY_OK
@@ -4187,7 +4186,9 @@ public class AudioManager {
                    afr.getFocusGain(),
                    afr.getFocusGain(),
                    mICallBack,
                    mICallBack,
                    mAudioFocusDispatcher,
                    mAudioFocusDispatcher,
                    clientFakeId, "com.android.test.fakeclient", clientFakeUid, clientTargetSdk);
                    clientFakeId, "com.android.test.fakeclient",
                    afr.getFlags() | AudioManager.AUDIOFOCUS_FLAG_TEST,
                    clientFakeUid, clientTargetSdk);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
            throw e.rethrowFromSystemServer();
        }
        }
+1 −1
Original line number Original line Diff line number Diff line
@@ -384,7 +384,7 @@ interface IAudioService {


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


+36 −7
Original line number Original line Diff line number Diff line
@@ -461,11 +461,17 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
     *                 at the top of the focus stack
     *                 at the top of the focus stack
     * Push the focus requester onto the audio focus stack at the first position immediately
     * Push the focus requester onto the audio focus stack at the first position immediately
     * following the locked focus owners.
     * 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
     * @return {@link AudioManager#AUDIOFOCUS_REQUEST_GRANTED} or
     *     {@link AudioManager#AUDIOFOCUS_REQUEST_DELAYED}
     *     {@link AudioManager#AUDIOFOCUS_REQUEST_DELAYED}
     */
     */
    @GuardedBy("mAudioFocusLock")
    @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();
        int lastLockedFocusOwnerIndex = mFocusStack.size();
        for (int index = mFocusStack.size() - 1; index >= 0; index--) {
        for (int index = mFocusStack.size() - 1; index >= 0; index--) {
            if (isLockedFocusOwner(mFocusStack.elementAt(index))) {
            if (isLockedFocusOwner(mFocusStack.elementAt(index))) {
@@ -480,10 +486,33 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
            propagateFocusLossFromGain_syncAf(nfr.getGainRequest(), nfr, false /*forceDuck*/);
            propagateFocusLossFromGain_syncAf(nfr.getGainRequest(), nfr, false /*forceDuck*/);
            mFocusStack.push(nfr);
            mFocusStack.push(nfr);
            return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
            return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
        } else {
        }

        if (DEBUG) {
            Log.v(TAG, "> lastLockedFocusOwnerIndex=" + lastLockedFocusOwnerIndex);
        }
        mFocusStack.insertElementAt(nfr, 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
     * @param forceDuck only true if
     *     {@link android.media.AudioFocusRequest.Builder#setFocusGain(int)} was set to true for
     *     {@link android.media.AudioFocusRequest.Builder#setFocusGain(int)} was set to true for
     *                  accessibility.
     *                  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
     *                otherwise the UID being injected for testing
     * @return
     * @return
     */
     */
@@ -1029,7 +1058,7 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
            if (focusGrantDelayed) {
            if (focusGrantDelayed) {
                // focusGrantDelayed being true implies we can't reassign focus right now
                // focusGrantDelayed being true implies we can't reassign focus right now
                // which implies the focus stack is not empty.
                // which implies the focus stack is not empty.
                final int requestResult = pushBelowLockedFocusOwners(nfr);
                final int requestResult = pushBelowLockedFocusOwnersAndPropagate(nfr);
                if (requestResult != AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
                if (requestResult != AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
                    notifyExtPolicyFocusGrant_syncAf(nfr.toAudioFocusInfo(), requestResult);
                    notifyExtPolicyFocusGrant_syncAf(nfr.toAudioFocusInfo(), requestResult);
                }
                }