DO NOT MERGE - 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
This commit is contained in:
@@ -437,8 +437,15 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
int mRotation = 0;
|
int mRotation = 0;
|
||||||
int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||||
boolean mAltOrientation = false;
|
boolean mAltOrientation = false;
|
||||||
ArrayList<IRotationWatcher> mRotationWatchers
|
class RotationWatcher {
|
||||||
= new ArrayList<IRotationWatcher>();
|
IRotationWatcher watcher;
|
||||||
|
IBinder.DeathRecipient dr;
|
||||||
|
RotationWatcher(IRotationWatcher w, IBinder.DeathRecipient d) {
|
||||||
|
watcher = w;
|
||||||
|
dr = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<RotationWatcher>();
|
||||||
int mDeferredRotationPauseCount;
|
int mDeferredRotationPauseCount;
|
||||||
|
|
||||||
int mSystemDecorLayer = 0;
|
int mSystemDecorLayer = 0;
|
||||||
@@ -5993,7 +6000,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
|
|
||||||
for (int i=mRotationWatchers.size()-1; i>=0; i--) {
|
for (int i=mRotationWatchers.size()-1; i>=0; i--) {
|
||||||
try {
|
try {
|
||||||
mRotationWatchers.get(i).onRotationChanged(rotation);
|
mRotationWatchers.get(i).watcher.onRotationChanged(rotation);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6025,10 +6032,10 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
public void binderDied() {
|
public void binderDied() {
|
||||||
synchronized (mWindowMap) {
|
synchronized (mWindowMap) {
|
||||||
for (int i=0; i<mRotationWatchers.size(); i++) {
|
for (int i=0; i<mRotationWatchers.size(); i++) {
|
||||||
if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
|
if (watcherBinder == mRotationWatchers.get(i).watcher.asBinder()) {
|
||||||
IRotationWatcher removed = mRotationWatchers.remove(i);
|
RotationWatcher removed = mRotationWatchers.remove(i);
|
||||||
if (removed != null) {
|
if (removed != null) {
|
||||||
removed.asBinder().unlinkToDeath(this, 0);
|
removed.watcher.asBinder().unlinkToDeath(this, 0);
|
||||||
}
|
}
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
@@ -6040,7 +6047,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
synchronized (mWindowMap) {
|
synchronized (mWindowMap) {
|
||||||
try {
|
try {
|
||||||
watcher.asBinder().linkToDeath(dr, 0);
|
watcher.asBinder().linkToDeath(dr, 0);
|
||||||
mRotationWatchers.add(watcher);
|
mRotationWatchers.add(new RotationWatcher(watcher, dr));
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// Client died, no cleanup needed.
|
// Client died, no cleanup needed.
|
||||||
}
|
}
|
||||||
@@ -6054,9 +6061,13 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
final IBinder watcherBinder = watcher.asBinder();
|
final IBinder watcherBinder = watcher.asBinder();
|
||||||
synchronized (mWindowMap) {
|
synchronized (mWindowMap) {
|
||||||
for (int i=0; i<mRotationWatchers.size(); i++) {
|
for (int i=0; i<mRotationWatchers.size(); i++) {
|
||||||
if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
|
RotationWatcher rotationWatcher = mRotationWatchers.get(i);
|
||||||
mRotationWatchers.remove(i);
|
if (watcherBinder == rotationWatcher.watcher.asBinder()) {
|
||||||
i--;
|
RotationWatcher removed = mRotationWatchers.remove(i);
|
||||||
|
if (removed != null) {
|
||||||
|
removed.watcher.asBinder().unlinkToDeath(removed.dr, 0);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user