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

Commit 289362e1 authored by Sangkyu Lee's avatar Sangkyu Lee Committed by jackmu95
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>
parent 22dfc9d2
Loading
Loading
Loading
Loading
+25 −3
Original line number Diff line number Diff line
@@ -9531,9 +9531,31 @@ public class WindowManagerService extends IWindowManager.Stub
                if (DEBUG_ORIENTATION &&
                        winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i(
                        TAG, "Resizing " + win + " WITH DRAW PENDING");
                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,
                        winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING,
                        configChanged ? win.mConfiguration : null);
                                        reportDraw, newConfig);
                }
                win.mContentInsetsChanged = false;
                win.mVisibleInsetsChanged = false;
                winAnimator.mSurfaceResized = false;