summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorSangkyu Lee <sk82.lee@lge.com>2013-01-16 14:53:17 +0900
committerSangkyu Lee <sk82.lee@lge.com>2013-04-02 14:31:19 +0900
commit88f3677be1532fdd62a597897e3ab57efe491643 (patch)
tree983b89b0316beaab73acd3575543ba390675244c /services
parentb7aca350e4c46bbc431f2ecaa4d8cee87915fe8b (diff)
downloadframeworks_base-88f3677be1532fdd62a597897e3ab57efe491643.zip
frameworks_base-88f3677be1532fdd62a597897e3ab57efe491643.tar.gz
frameworks_base-88f3677be1532fdd62a597897e3ab57efe491643.tar.bz2
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>
Diffstat (limited to 'services')
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java28
1 files changed, 25 insertions, 3 deletions
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 194c750..d6dfff4 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -9461,9 +9461,31 @@ public class WindowManagerService extends IWindowManager.Stub
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;