Skip to content
Browse files

Fix potential deadlock between LockScreen and WindowManagerService

If LockScreen is enhanced using SurfaceView/GLSurfaceView,
deadlock problem between LockScreen and WindowManagerService
can occur because of IWindow.resized() callback.
And it must lead to watchdog and reset.

IWindow.resized() callback is one-way function so calling resized()
callback of a remote IWindow object is never blocked.
However, calling resized() callback of a local IWindow object
(LockScreen is running on the same system_server process)
is always blocked until resized() callback returns.
Because resized() callback of SurfaceView/GLSurfaceView can lead to
WindowManagerService.relayoutWindow() call, deadlock can occur
between relayoutWindow() and performLayoutAndPlaceSurfacesLockedInner().
(Both functions need locking mWindowMap)

So this patch simulate one-way call when calling resized() callback
of a local IWindow object.

Change-Id: I2a6a5c74ed22d8e6b7a3bea3424ff2879d227105
Signed-off-by: Sangkyu Lee <sk82.lee@lge.com>
  • Loading branch information...
1 parent 22dfc9d commit 289362e1864b622e36070af4822db0ad90db2b1d Sangkyu Lee committed with jackmu95 Jan 16, 2013
Showing with 25 additions and 3 deletions.
  1. +25 −3 services/java/com/android/server/wm/WindowManagerService.java
View
28 services/java/com/android/server/wm/WindowManagerService.java
@@ -9531,9 +9531,31 @@ private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMe
if (DEBUG_ORIENTATION &&
winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i(
TAG, "Resizing " + win + " WITH DRAW PENDING");
- win.mClient.resized(win.mFrame, win.mLastContentInsets, win.mLastVisibleInsets,
- winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING,
- configChanged ? win.mConfiguration : null);
+ final boolean reportDraw
+ = winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING;
+ final Configuration newConfig = configChanged ? win.mConfiguration : null;
+ if (win.mClient instanceof IWindow.Stub) {
+ // Simulate one-way call if win.mClient is a local object.
+ final IWindow client = win.mClient;
+ final Rect frame = win.mFrame;
+ final Rect contentInsets = win.mLastContentInsets;
+ final Rect visibleInsets = win.mLastVisibleInsets;
+ mH.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ client.resized(frame, contentInsets, visibleInsets,
+ reportDraw, newConfig);
+ } catch (RemoteException e) {
+ // Actually, it's not a remote call.
+ // RemoteException mustn't be raised.
+ }
+ }
+ });
+ } else {
+ win.mClient.resized(win.mFrame, win.mLastContentInsets, win.mLastVisibleInsets,
+ reportDraw, newConfig);
+ }
win.mContentInsetsChanged = false;
win.mVisibleInsetsChanged = false;
winAnimator.mSurfaceResized = false;

0 comments on commit 289362e

Please sign in to comment.
Something went wrong with that request. Please try again.