summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Michel Trivi <jmtrivi@google.com>2011-08-14 11:37:24 -0700
committerJean-Michel Trivi <jmtrivi@google.com>2011-08-14 11:37:24 -0700
commit061214bb71a4a4211e670001226c68f5e8036b84 (patch)
tree6382c2836c425c8d7aa1a0dd084587d942cc695e
parent3025b10aed854e1b3f4f09f72cce4897e1ae5b97 (diff)
downloadframeworks_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.java39
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;
}