summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jim Miller <jaggies@google.com> 2013-12-09 17:38:05 -0800
committer Jim Miller <jaggies@google.com> 2013-12-10 16:48:13 -0800
commit7267ed1b4b5ca1fb0931b7979dfb4e931ab519ec (patch)
treeba900e2b1fc17f2799d39917d09f97a803fdf0fc
parent4524cc649affd5e83393ca07d5315fa09c617087 (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.java33
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--;
}
}