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

Commit 0b605349 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

Limit RemoteControlClient generation ID changes

At the beginning of each song, the Music app re-registers its
 media button event and requests audio focus, which causes
 the reevaluation of each corresponding stack of clients. Each
 reevaluation is accompanied by the incrementation of the
 RemoteControlClient generation ID, which causes RemoteController
 to issue a notification that the client has changed. The lockscreen
 correctly interprets this as a reason to dump the current
 RemoteControlClient data (including the artwork) because it will
 receive the new data if new one is available. This is what causes
 the "flashing" of the wallpaper on the lockscreen: for an instant,
 no client data is available.
The fix consists in not causing the client generation ID to be
 incremented when registrations don't cause any change in the
 RemoteControlClient stack. Even though Music re-registers everything,
 nothing has changed: it still is the current media button receiver,
 and it still has the same RemoteControlClient.

Bug 11307382

Change-Id: I4d2404b571e88aeedb0eca6bd19d39f7ec4fc8b1
parent 02e4c3a1
Loading
Loading
Loading
Loading
+15 −9
Original line number Diff line number Diff line
@@ -1476,16 +1476,17 @@ public class MediaFocusControl implements OnFinished {
     * Set the new remote control receiver at the top of the RC focus stack.
     * Called synchronized on mAudioFocusLock, then mRCStack
     * precondition: mediaIntent != null
     * @return true if mRCStack was changed, false otherwise
     */
    private void pushMediaButtonReceiver_syncAfRcs(PendingIntent mediaIntent, ComponentName target,
            IBinder token) {
    private boolean pushMediaButtonReceiver_syncAfRcs(PendingIntent mediaIntent,
            ComponentName target, IBinder token) {
        // already at top of stack?
        if (!mRCStack.empty() && mRCStack.peek().mMediaIntent.equals(mediaIntent)) {
            return;
            return false;
        }
        if (mAppOps.noteOp(AppOpsManager.OP_TAKE_MEDIA_BUTTONS, Binder.getCallingUid(),
                mediaIntent.getCreatorPackage()) != AppOpsManager.MODE_ALLOWED) {
            return;
            return false;
        }
        RemoteControlStackEntry rcse = null;
        boolean wasInsideStack = false;
@@ -1513,6 +1514,9 @@ public class MediaFocusControl implements OnFinished {
            mEventHandler.sendMessage( mEventHandler.obtainMessage(
                    MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0, target/*obj*/) );
        }

        // RC stack was modified
        return true;
    }

    /**
@@ -1856,12 +1860,13 @@ public class MediaFocusControl implements OnFinished {

        synchronized(mAudioFocusLock) {
            synchronized(mRCStack) {
                pushMediaButtonReceiver_syncAfRcs(mediaIntent, eventReceiver, token);
                if (pushMediaButtonReceiver_syncAfRcs(mediaIntent, eventReceiver, token)) {
                    // new RC client, assume every type of information shall be queried
                    checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
                }
            }
        }
    }

    /**
     * see AudioManager.unregisterMediaButtonIntent(PendingIntent mediaIntent)
@@ -1925,6 +1930,7 @@ public class MediaFocusControl implements OnFinished {
        int rccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
        synchronized(mAudioFocusLock) {
            synchronized(mRCStack) {
                boolean wasCurrentRcController = isCurrentRcController(mediaIntent);
                // store the new display information
                try {
                    for (int index = mRCStack.size()-1; index >= 0; index--) {
@@ -1971,9 +1977,9 @@ public class MediaFocusControl implements OnFinished {
                    Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
                }

                // if the eventReceiver is at the top of the stack
                // if the eventReceiver is now at the top of the stack but wasn't before
                // then check for potential refresh of the remote controls
                if (isCurrentRcController(mediaIntent)) {
                if (isCurrentRcController(mediaIntent) && !wasCurrentRcController) {
                    checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
                }
            }//synchronized(mRCStack)