OSDN Git Service

Fix 5615747 Don't leak remote control client death handlers
authorJean-Michel Trivi <jmtrivi@google.com>
Mon, 14 Nov 2011 23:23:04 +0000 (15:23 -0800)
committerJean-Michel Trivi <jmtrivi@google.com>
Tue, 15 Nov 2011 01:30:23 +0000 (17:30 -0800)
Whenever a remote control stack entry is GC'd or removed from
 the stack, unlink its death handler.

Change-Id: Ia4ed6667351849fd388272591e24ffc16959beaf

media/java/android/media/AudioService.java

index a8daab0..a2b80c2 100644 (file)
@@ -3062,6 +3062,7 @@ public class AudioService extends IAudioService.Stub {
             if ((mRcClientDeathHandler != null) && (mRcClientDeathHandler.mCb != null)) {
                 try {
                     mRcClientDeathHandler.mCb.unlinkToDeath(mRcClientDeathHandler, 0);
+                    mRcClientDeathHandler = null;
                 } catch (java.util.NoSuchElementException e) {
                     // not much we can do here
                     Log.e(TAG, "Encountered " + e + " in unlinkToRcClientDeath()");
@@ -3069,6 +3070,12 @@ public class AudioService extends IAudioService.Stub {
                 }
             }
         }
+
+        @Override
+        protected void finalize() throws Throwable {
+            unlinkToRcClientDeath();// unlink exception handled inside method
+            super.finalize();
+        }
     }
 
     /**
@@ -3115,6 +3122,7 @@ public class AudioService extends IAudioService.Stub {
                     if (packageName.equalsIgnoreCase(rcse.mReceiverComponent.getPackageName())) {
                         // a stack entry is from the package being removed, remove it from the stack
                         stackIterator.remove();
+                        rcse.unlinkToRcClientDeath();
                     }
                 }
                 if (mRCStack.empty()) {
@@ -3195,6 +3203,7 @@ public class AudioService extends IAudioService.Stub {
             RemoteControlStackEntry rcse = (RemoteControlStackEntry)stackIterator.next();
             if(rcse.mMediaIntent.equals(pi)) {
                 stackIterator.remove();
+                rcse.unlinkToRcClientDeath();
                 break;
             }
         }
@@ -3456,7 +3465,7 @@ public class AudioService extends IAudioService.Stub {
                         rcse.mCallingPackageName = callingPackageName;
                         rcse.mCallingUid = Binder.getCallingUid();
                         if (rcClient == null) {
-                            rcse.mRcClientDeathHandler = null;
+                            // here rcse.mRcClientDeathHandler is null;
                             break;
                         }
 
@@ -3512,7 +3521,6 @@ public class AudioService extends IAudioService.Stub {
                         rcse.unlinkToRcClientDeath();
                         // reset the client-related fields
                         rcse.mRcClient = null;
-                        rcse.mRcClientDeathHandler = null;
                         rcse.mCallingPackageName = null;
                     }
                 }