summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mihai Popa <popam@google.com> 2018-04-02 19:53:48 -0700
committer android-build-merger <android-build-merger@google.com> 2018-04-02 19:53:48 -0700
commitda02fac9fea2a3ea5730d6595fb246c48eb3462b (patch)
tree0a6b10c456e64e14b710b9147305681ff1872f9e
parentb0765db5b8e6ac8682b6e795810dc2d129352e26 (diff)
parent285797a45a83b20ccdf75a4ca7a762a285e54561 (diff)
Merge "[Magnifier-38] Avoid deadlock causing ANR" into pi-dev
am: 285797a45a Change-Id: I81474f04a8d33d2cf063aa0d89b7abca255d3864
-rw-r--r--core/java/android/widget/Magnifier.java34
1 files changed, 22 insertions, 12 deletions
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index c1c5d9d688ed..5eb66999b296 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -393,6 +393,12 @@ public final class Magnifier {
private int mWindowPositionY;
private boolean mPendingWindowPositionUpdate;
+ // The lock used to synchronize the UI and render threads when a #destroy
+ // 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();
+
InternalPopupWindow(final Context context, final Display display,
final Surface parentSurface,
final int width, final int height, final float elevation, final float cornerRadius,
@@ -517,9 +523,11 @@ public final class Magnifier {
* Destroys this instance.
*/
public void destroy() {
+ synchronized (mDestroyLock) {
+ mSurface.destroy();
+ }
synchronized (mLock) {
mRenderer.destroy();
- mSurface.destroy();
mSurfaceControl.destroy();
mSurfaceSession.kill();
mBitmapRenderNode.destroy();
@@ -567,21 +575,23 @@ public final class Magnifier {
final int pendingY = mWindowPositionY;
callback = frame -> {
- synchronized (mLock) {
+ synchronized (mDestroyLock) {
if (!mSurface.isValid()) {
return;
}
- mRenderer.setLightCenter(mDisplay, pendingX, pendingY);
- // Show or move the window at the content draw frame.
- SurfaceControl.openTransaction();
- mSurfaceControl.deferTransactionUntil(mSurface, frame);
- if (updateWindowPosition) {
- mSurfaceControl.setPosition(pendingX, pendingY);
- }
- if (firstDraw) {
- mSurfaceControl.show();
+ synchronized (mLock) {
+ mRenderer.setLightCenter(mDisplay, pendingX, pendingY);
+ // Show or move the window at the content draw frame.
+ SurfaceControl.openTransaction();
+ mSurfaceControl.deferTransactionUntil(mSurface, frame);
+ if (updateWindowPosition) {
+ mSurfaceControl.setPosition(pendingX, pendingY);
+ }
+ if (firstDraw) {
+ mSurfaceControl.show();
+ }
+ SurfaceControl.closeTransaction();
}
- SurfaceControl.closeTransaction();
}
};
} else {