From c204db842178981a538ae0002aa08c9b9010e9f6 Mon Sep 17 00:00:00 2001 From: Bin Chen Date: Fri, 10 May 2019 16:05:05 +0800 Subject: [PATCH] Fix deadlock which causing ANR "main" prio=5 tid=1 Blocked | group="main" sCount=1 dsCount=0 flags=1 obj=0x74aeca00 self=0x7021814c00 | sysTid=27953 nice=-10 cgrp=default sched=0/0 handle=0x70a85ff548 | state=S schedstat=( 31382082536 9164116362 28130 ) utm=2661 stm=477 core=0 HZ=100 | stack=0x7ff7a52000-0x7ff7a54000 stackSize=8MB | held mutexes= at android.widget.Magnifier$InternalPopupWindow.destroy(Magnifier.java:607) - waiting to lock <0x0ef5c351> (a java.lang.Object) held by thread 13 at android.widget.Magnifier.dismiss(Magnifier.java:191) - locked <0x01cd07b6> (a java.lang.Object) "hwuiTask1" prio=5 tid=13 Blocked | group="main" sCount=1 dsCount=0 flags=1 obj=0x12f815d8 self=0x70000e7800 | sysTid=28075 nice=-2 cgrp=default sched=0/0 handle=0x70046ba4f0 | state=S schedstat=( 138800095 85604746 532 ) utm=10 stm=3 core=1 HZ=100 | stack=0x70045bf000-0x70045c1000 stackSize=1009KB | held mutexes= at android.widget.Magnifier$InternalPopupWindow.lambda$doDraw$0(Magnifier.java:663) - waiting to lock <0x01cd07b6> (a java.lang.Object) held by thread 1 - locked <0x0ef5c351> (a java.lang.Object) at android.widget.-$$Lambda$Magnifier$InternalPopupWindow$vZThyvjDQhg2J1GAeOWCNqy2iiw.onFrameDraw(lambda:-1) Change-Id: Idf0373ab0d5033d56da0f6f45d7d953f7e796813 Merged-In: Idf0373ab0d5033d56da0f6f45d7d953f7e796813 Signed-off-by: Bin Chen --- core/java/android/widget/Magnifier.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java index 929496f2d2373..350094edad540 100644 --- a/core/java/android/widget/Magnifier.java +++ b/core/java/android/widget/Magnifier.java @@ -106,6 +106,8 @@ public final class Magnifier { // Lock to synchronize between the UI thread and the thread that handles pixel copy results. // Only sync mWindow writes from UI thread with mWindow reads from sPixelCopyHandlerThread. private final Object mLock = new Object(); + // The lock used to synchronize the UI and render threads when a #dismiss is performed. + private final Object mDestroyLock = new Object(); /** * Initializes a magnifier. @@ -173,7 +175,7 @@ public final class Magnifier { mParentSurface.mSurface, mWindowWidth, mWindowHeight, mWindowElevation, mWindowCornerRadius, Handler.getMain() /* draw the magnifier on the UI thread */, mLock, - mCallback); + mDestroyLock, mCallback); } } performPixelCopy(startX, startY, true /* update window position */); @@ -187,9 +189,11 @@ public final class Magnifier { */ public void dismiss() { if (mWindow != null) { - synchronized (mLock) { - mWindow.destroy(); - mWindow = null; + synchronized (mDestroyLock) { + synchronized (mLock) { + mWindow.destroy(); + mWindow = null; + } } mPrevPosInView.x = NONEXISTENT_PREVIOUS_CONFIG_VALUE; mPrevPosInView.y = NONEXISTENT_PREVIOUS_CONFIG_VALUE; @@ -478,14 +482,16 @@ public final class Magnifier { // is performed on the UI thread and a frame callback on the render thread. // When both mLock and mDestroyLock need to be held at the same time, // mDestroyLock should be acquired before mLock in order to avoid deadlocks. - private final Object mDestroyLock = new Object(); + private final Object mDestroyLock; InternalPopupWindow(final Context context, final Display display, final Surface parentSurface, final int width, final int height, final float elevation, final float cornerRadius, - final Handler handler, final Object lock, final Callback callback) { + final Handler handler, final Object lock, final Object destroyLock, + final Callback callback) { mDisplay = display; mLock = lock; + mDestroyLock = destroyLock; mCallback = callback; mContentWidth = width;