Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0438bd69 authored by Sangkyu Lee's avatar Sangkyu Lee Committed by Craig Mautner
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: default avatarSangkyu Lee <sk82.lee@lge.com>

Conflicts:
	services/java/com/android/server/wm/WindowManagerService.java
parent 5514aff4
Loading
Loading
Loading
Loading
+25 −4
Original line number Diff line number Diff line
@@ -8908,10 +8908,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.mLastOverscanInsets, win.mLastContentInsets,
                        win.mLastVisibleInsets,
                        winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING,
                        configChanged ? win.mConfiguration : null);
                final IWindow client = win.mClient;
                final Rect frame = win.mFrame;
                final Rect overscanInsets = win.mLastOverscanInsets;
                final Rect contentInsets = win.mLastContentInsets;
                final Rect visibleInsets = win.mLastVisibleInsets;
                final boolean reportDraw
                        = winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING;
                final Configuration newConfig = configChanged ? win.mConfiguration : null;
                if (win.mClient instanceof IWindow.Stub) {
                    // To prevent deadlock simulate one-way call if win.mClient is a local object.
                    mH.post(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                client.resized(frame, overscanInsets, contentInsets,
                                        visibleInsets, reportDraw, newConfig);
                            } catch (RemoteException e) {
                                // Not a remote call, RemoteException won't be raised.
                            }
                        }
                    });
                } else {
                   client.resized(frame, overscanInsets, contentInsets, visibleInsets, reportDraw,
                           newConfig);
                }
                win.mOverscanInsetsChanged = false;
                win.mContentInsetsChanged = false;
                win.mVisibleInsetsChanged = false;