diff options
author | Jean-Michel Trivi <jmtrivi@google.com> | 2011-08-14 11:37:24 -0700 |
---|---|---|
committer | Jean-Michel Trivi <jmtrivi@google.com> | 2011-08-14 11:37:24 -0700 |
commit | 061214bb71a4a4211e670001226c68f5e8036b84 (patch) | |
tree | 6382c2836c425c8d7aa1a0dd084587d942cc695e | |
parent | 3025b10aed854e1b3f4f09f72cce4897e1ae5b97 (diff) | |
download | frameworks_base-061214bb71a4a4211e670001226c68f5e8036b84.zip frameworks_base-061214bb71a4a4211e670001226c68f5e8036b84.tar.gz frameworks_base-061214bb71a4a4211e670001226c68f5e8036b84.tar.bz2 |
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
-rw-r--r-- | media/java/android/media/AudioService.java | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 8ebb07c..62a263e 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -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,9 +2775,20 @@ public class AudioService extends IAudioService.Stub { // focus requester might already be somewhere below in the stack, remove it removeFocusStackEntry(clientId, false); + // handle the potential premature death of the new holder of the focus + // (premature death == death before abandoning focus) + // Register for client death notification + AudioFocusDeathHandler afdh = new AudioFocusDeathHandler(cb); + try { + cb.linkToDeath(afdh, 0); + } catch (RemoteException e) { + // client has already died! + 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, callingPackageName, Binder.getCallingUid())); + clientId, afdh, callingPackageName, Binder.getCallingUid())); // there's a new top of the stack, let the remote control know synchronized(mRCStack) { @@ -2774,17 +2796,6 @@ public class AudioService extends IAudioService.Stub { } }//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 - AudioFocusDeathHandler afdh = new AudioFocusDeathHandler(cb); - try { - cb.linkToDeath(afdh, 0); - } catch (RemoteException e) { - // client has already died! - Log.w(TAG, "AudioFocus requestAudioFocus() could not link to "+cb+" binder death"); - } - return AudioManager.AUDIOFOCUS_REQUEST_GRANTED; } |