Merge "[Magnifier-87] Fix deadlock causing ANR" into qt-dev

am: 9550c185f9

Change-Id: I0bd285dde76e8e232c119f66c5904bf1b461fb5b
This commit is contained in:
Mihai Popa
2019-06-18 02:22:45 -07:00
committed by android-build-merger

View File

@@ -277,7 +277,7 @@ public final class Magnifier {
mWindowElevation, mWindowCornerRadius, mWindowElevation, mWindowCornerRadius,
mOverlay != null ? mOverlay : new ColorDrawable(Color.TRANSPARENT), mOverlay != null ? mOverlay : new ColorDrawable(Color.TRANSPARENT),
Handler.getMain() /* draw the magnifier on the UI thread */, mLock, Handler.getMain() /* draw the magnifier on the UI thread */, mLock,
mDestroyLock, mCallback); mCallback);
} }
} }
performPixelCopy(startX, startY, true /* update window position */); performPixelCopy(startX, startY, true /* update window position */);
@@ -306,11 +306,9 @@ public final class Magnifier {
*/ */
public void dismiss() { public void dismiss() {
if (mWindow != null) { if (mWindow != null) {
synchronized (mDestroyLock) { synchronized (mLock) {
synchronized (mLock) { mWindow.destroy();
mWindow.destroy(); mWindow = null;
mWindow = null;
}
} }
mPrevShowSourceCoords.x = NONEXISTENT_PREVIOUS_CONFIG_VALUE; mPrevShowSourceCoords.x = NONEXISTENT_PREVIOUS_CONFIG_VALUE;
mPrevShowSourceCoords.y = NONEXISTENT_PREVIOUS_CONFIG_VALUE; mPrevShowSourceCoords.y = NONEXISTENT_PREVIOUS_CONFIG_VALUE;
@@ -835,24 +833,16 @@ public final class Magnifier {
private int mWindowPositionY; private int mWindowPositionY;
private boolean mPendingWindowPositionUpdate; 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;
// The current content of the magnifier. It is mBitmap + mOverlay, only used for testing. // The current content of the magnifier. It is mBitmap + mOverlay, only used for testing.
private Bitmap mCurrentContent; private Bitmap mCurrentContent;
InternalPopupWindow(final Context context, final Display display, InternalPopupWindow(final Context context, final Display display,
final SurfaceControl parentSurfaceControl, final int width, final int height, final SurfaceControl parentSurfaceControl, final int width, final int height,
final float elevation, final float cornerRadius, final Drawable overlay, final float elevation, final float cornerRadius, final Drawable overlay,
final Handler handler, final Object lock, final Object destroyLock, final Handler handler, final Object lock, final Callback callback) {
final Callback callback) {
mDisplay = display; mDisplay = display;
mOverlay = overlay; mOverlay = overlay;
mLock = lock; mLock = lock;
mDestroyLock = destroyLock;
mCallback = callback; mCallback = callback;
mContentWidth = width; mContentWidth = width;
@@ -1039,20 +1029,17 @@ public final class Magnifier {
} }
/** /**
* Destroys this instance. * Destroys this instance. The method has to be called in a context holding {@link #mLock}.
*/ */
public void destroy() { public void destroy() {
synchronized (mDestroyLock) { // Destroy the renderer. This will not proceed until pending frame callbacks complete.
mSurface.destroy(); mRenderer.destroy();
} mSurface.destroy();
synchronized (mLock) { mSurfaceControl.remove();
mRenderer.destroy(); mSurfaceSession.kill();
mSurfaceControl.remove(); mHandler.removeCallbacks(mMagnifierUpdater);
mSurfaceSession.kill(); if (mBitmap != null) {
mHandler.removeCallbacks(mMagnifierUpdater); mBitmap.recycle();
if (mBitmap != null) {
mBitmap.recycle();
}
} }
} }
@@ -1090,24 +1077,20 @@ public final class Magnifier {
final int pendingY = mWindowPositionY; final int pendingY = mWindowPositionY;
callback = frame -> { callback = frame -> {
synchronized (mDestroyLock) { if (!mSurface.isValid()) {
if (!mSurface.isValid()) { return;
return;
}
synchronized (mLock) {
// 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.setLayer(SURFACE_Z);
mSurfaceControl.show();
}
SurfaceControl.closeTransaction();
}
} }
// 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.setLayer(SURFACE_Z);
mSurfaceControl.show();
}
SurfaceControl.closeTransaction();
}; };
mRenderer.setLightCenter(mDisplay, pendingX, pendingY); mRenderer.setLightCenter(mDisplay, pendingX, pendingY);
} else { } else {