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

Commit 061214bb authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

Fix leak of global references and AudioFocusDeathHandler objects.

Need to call unlinkToDeath() for the object to be garbage collected.
Save the object in the FocusStackEntry, unlink to death when we remove it from the stack.
See http://b/issue?id=5048400

Change-Id: I84c5ba46017d0a8744b5e7509a7c7a5c8dd918fb
author: olivier@google.com
parent 3025b10a
Loading
Loading
Loading
Loading
+25 −14
Original line number Diff line number Diff line
@@ -2580,6 +2580,7 @@ public class AudioService extends IAudioService.Stub {
        public IBinder mSourceRef = null;
        public String mClientId;
        public int mFocusChangeType;
        public AudioFocusDeathHandler mHandler;
        public String mPackageName;
        public int mCallingUid;

@@ -2587,15 +2588,23 @@ public class AudioService extends IAudioService.Stub {
        }

        public FocusStackEntry(int streamType, int duration,
                IAudioFocusDispatcher afl, IBinder source, String id, String pn, int uid) {
                IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr,
                String pn, int uid) {
            mStreamType = streamType;
            mFocusDispatcher = afl;
            mSourceRef = source;
            mClientId = id;
            mFocusChangeType = duration;
            mHandler = hdlr;
            mPackageName = pn;
            mCallingUid = uid;
        }

        public void unlinkToDeath() {
            if (mSourceRef != null && mHandler != null) {
                mSourceRef.unlinkToDeath(mHandler, 0);
            }
        }
    }

    private Stack<FocusStackEntry> mFocusStack = new Stack<FocusStackEntry>();
@@ -2630,7 +2639,8 @@ public class AudioService extends IAudioService.Stub {
        if (!mFocusStack.empty() && mFocusStack.peek().mClientId.equals(clientToRemove))
        {
            //Log.i(TAG, "   removeFocusStackEntry() removing top of stack");
            mFocusStack.pop();
            FocusStackEntry fse = mFocusStack.pop();
            fse.unlinkToDeath();
            if (signal) {
                // notify the new top of the stack it gained focus
                notifyTopOfAudioFocusStack();
@@ -2649,6 +2659,7 @@ public class AudioService extends IAudioService.Stub {
                    Log.i(TAG, " AudioFocus  abandonAudioFocus(): removing entry for "
                            + fse.mClientId);
                    stackIterator.remove();
                    fse.unlinkToDeath();
                }
            }
        }
@@ -2764,16 +2775,6 @@ public class AudioService extends IAudioService.Stub {
            // focus requester might already be somewhere below in the stack, remove it
            removeFocusStackEntry(clientId, false);

            // push focus requester at the top of the audio focus stack
            mFocusStack.push(new FocusStackEntry(mainStreamType, focusChangeHint, fd, cb,
                    clientId, callingPackageName, Binder.getCallingUid()));

            // there's a new top of the stack, let the remote control know
            synchronized(mRCStack) {
                checkUpdateRemoteControlDisplay(RC_INFO_ALL);
            }
        }//synchronized(mAudioFocusLock)

            // handle the potential premature death of the new holder of the focus
            // (premature death == death before abandoning focus)
            // Register for client death notification
@@ -2785,6 +2786,16 @@ public class AudioService extends IAudioService.Stub {
                Log.w(TAG, "AudioFocus  requestAudioFocus() could not link to "+cb+" binder death");
            }

            // push focus requester at the top of the audio focus stack
            mFocusStack.push(new FocusStackEntry(mainStreamType, focusChangeHint, fd, cb,
                    clientId, afdh, callingPackageName, Binder.getCallingUid()));

            // there's a new top of the stack, let the remote control know
            synchronized(mRCStack) {
                checkUpdateRemoteControlDisplay(RC_INFO_ALL);
            }
        }//synchronized(mAudioFocusLock)

        return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
    }