Merge "[Magnifier-87] Fix deadlock causing ANR" into qt-dev am: 9550c185f9
am: 8cb39cbec2
Change-Id: I549a844a9fdf1cc8ab480188c71005e7d47e54f4
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user