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

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

Fix 5607938 AudioFocusDeathHandler leaks GREF

The AudioFocus death handler was correctly updating the audio
 focus stack when an audio focus client dies, but the death handler
 was leaking GREF if unlinkToDeath() is not called.
The fix consists in making sure unlinkToDeath() is always called
 by calling it in its finalizer.

Change-Id: I0c5343b4986ab582cadbf171fc53816952dc16f5
parent 24597eb7
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -2693,11 +2693,22 @@ public class AudioService extends IAudioService.Stub {
            mCallingUid = uid;
        }

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

        @Override
        protected void finalize() throws Throwable {
            try {
                unlinkToDeath();
            } catch (java.util.NoSuchElementException e) {
                Log.w(TAG, e + " thrown by unlinkToDeath() during finalize, ignoring");
            } finally {
                super.finalize();
            }
        }
    }

    private Stack<FocusStackEntry> mFocusStack = new Stack<FocusStackEntry>();
@@ -2732,8 +2743,7 @@ public class AudioService extends IAudioService.Stub {
        if (!mFocusStack.empty() && mFocusStack.peek().mClientId.equals(clientToRemove))
        {
            //Log.i(TAG, "   removeFocusStackEntry() removing top of stack");
            FocusStackEntry fse = mFocusStack.pop();
            fse.unlinkToDeath();
            mFocusStack.pop();
            if (signal) {
                // notify the new top of the stack it gained focus
                notifyTopOfAudioFocusStack();
@@ -2752,7 +2762,6 @@ public class AudioService extends IAudioService.Stub {
                    Log.i(TAG, " AudioFocus  abandonAudioFocus(): removing entry for "
                            + fse.mClientId);
                    stackIterator.remove();
                    fse.unlinkToDeath();
                }
            }
        }
@@ -2858,6 +2867,9 @@ public class AudioService extends IAudioService.Stub {
                // if focus is already owned by this client and the reason for acquiring the focus
                // hasn't changed, don't do anything
                if (mFocusStack.peek().mFocusChangeType == focusChangeHint) {
                    // unlink death handler so it can be gc'ed.
                    // linkToDeath() creates a JNI global reference preventing collection.
                    cb.unlinkToDeath(afdh, 0);
                    return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
                }
                // the reason for the audio focus request has changed: remove the current top of