diff options
| author | 2013-12-09 17:38:05 -0800 | |
|---|---|---|
| committer | 2013-12-10 16:48:13 -0800 | |
| commit | 7267ed1b4b5ca1fb0931b7979dfb4e931ab519ec (patch) | |
| tree | ba900e2b1fc17f2799d39917d09f97a803fdf0fc | |
| parent | 4524cc649affd5e83393ca07d5315fa09c617087 (diff) | |
Fix memory leak caused by mismatched linkToDeath() in WindowManagerService
This fixes a bug where an allocated DeathRecipient in WindowManagerService
was holding a reference to keyguard binder interface after a call to
linkToDeath() without a matchin unlinkToDeath().
It was causing the keyguard side of the binder interface to stick around,
which in tern prevented the keyguard side from releasing its references.
The solution is to ensure matching linkToDeath()/unlinkToDeath() calls.
Fixes bug 11982048
Change-Id: I6959816b819ba953512c53675162195cbf1e0653
| -rw-r--r-- | services/java/com/android/server/wm/WindowManagerService.java | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 2072671c007a..28dde0d54e14 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -432,8 +432,15 @@ public class WindowManagerService extends IWindowManager.Stub int mRotation = 0; int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; boolean mAltOrientation = false; - ArrayList<IRotationWatcher> mRotationWatchers - = new ArrayList<IRotationWatcher>(); + class RotationWatcher { + IRotationWatcher watcher; + IBinder.DeathRecipient deathRecipient; + RotationWatcher(IRotationWatcher w, IBinder.DeathRecipient d) { + watcher = w; + deathRecipient = d; + } + } + ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<RotationWatcher>(); int mDeferredRotationPauseCount; int mSystemDecorLayer = 0; @@ -5974,7 +5981,7 @@ public class WindowManagerService extends IWindowManager.Stub for (int i=mRotationWatchers.size()-1; i>=0; i--) { try { - mRotationWatchers.get(i).onRotationChanged(rotation); + mRotationWatchers.get(i).watcher.onRotationChanged(rotation); } catch (RemoteException e) { } } @@ -6006,10 +6013,11 @@ public class WindowManagerService extends IWindowManager.Stub public void binderDied() { synchronized (mWindowMap) { for (int i=0; i<mRotationWatchers.size(); i++) { - if (watcherBinder == mRotationWatchers.get(i).asBinder()) { - IRotationWatcher removed = mRotationWatchers.remove(i); - if (removed != null) { - removed.asBinder().unlinkToDeath(this, 0); + if (watcherBinder == mRotationWatchers.get(i).watcher.asBinder()) { + RotationWatcher removed = mRotationWatchers.remove(i); + IBinder binder = removed.watcher.asBinder(); + if (binder != null) { + binder.unlinkToDeath(this, 0); } i--; } @@ -6021,7 +6029,7 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mWindowMap) { try { watcher.asBinder().linkToDeath(dr, 0); - mRotationWatchers.add(watcher); + mRotationWatchers.add(new RotationWatcher(watcher, dr)); } catch (RemoteException e) { // Client died, no cleanup needed. } @@ -6035,8 +6043,13 @@ public class WindowManagerService extends IWindowManager.Stub final IBinder watcherBinder = watcher.asBinder(); synchronized (mWindowMap) { for (int i=0; i<mRotationWatchers.size(); i++) { - if (watcherBinder == mRotationWatchers.get(i).asBinder()) { - mRotationWatchers.remove(i); + RotationWatcher rotationWatcher = mRotationWatchers.get(i); + if (watcherBinder == rotationWatcher.watcher.asBinder()) { + RotationWatcher removed = mRotationWatchers.remove(i); + IBinder binder = removed.watcher.asBinder(); + if (binder != null) { + binder.unlinkToDeath(removed.deathRecipient, 0); + } i--; } } |