From 536973fda8105eac13a7f02aeb2b91aa4280c229 Mon Sep 17 00:00:00 2001 From: Chavi Weingarten Date: Thu, 22 Jun 2023 18:20:11 +0000 Subject: [PATCH] Post reportDrawFinished to the UI thread if running in system If VRI is running in the system process, the call to finishDrawing will not result in an IPC call and therefore will run on whatever thread SurfaceSyncGroup finished on. This is normally going to be the RenderThread. This could result in a deadlock because the finishDrawing is now blocking any additional calls to RT, which is unexpected behavior. Instead, post to the UI thread when the VRI is running in system process to ensure RT is unblocked. Test: Presubmit Bug: 286355097 Change-Id: Id8bd8eeced99f5228d7655382e0c043d03e0c196 --- core/java/android/view/ViewRootImpl.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 9316dbf8a4582..bef28b2789b85 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -3855,7 +3855,15 @@ public final class ViewRootImpl implements ViewParent, mWmsRequestSyncGroupState = WMS_SYNC_PENDING; mWmsRequestSyncGroup = new SurfaceSyncGroup("wmsSync-" + mTag, t -> { mWmsRequestSyncGroupState = WMS_SYNC_MERGED; - reportDrawFinished(t, seqId); + // See b/286355097. If the current process is not system, then invoking finishDraw on + // any thread is fine since once it calls into system process, finishDrawing will run + // on a different thread. However, when the current process is system, the finishDraw in + // system server will be run on the current thread, which could result in a deadlock. + if (mWindowSession instanceof Binder) { + reportDrawFinished(t, seqId); + } else { + mHandler.postAtFrontOfQueue(() -> reportDrawFinished(t, seqId)); + } }); if (DEBUG_BLAST) { Log.d(mTag, "Setup new sync=" + mWmsRequestSyncGroup.getName());