From e8a9c64ae8f72bc732ef9d73bd684df1c09e11b6 Mon Sep 17 00:00:00 2001 From: Miranda Kephart Date: Mon, 30 Aug 2021 16:04:58 +0000 Subject: [PATCH] Fix race condition causing screenshot view to be added to window twice In some cases, invoking multiple screenshots in quick succession causes an error as the decor view is added to the window twice. This change blocks attempting to attach the window between telling the window manager to add the decor view and getting the callback that it has been added. Bug: 190249438 Fix: 190249438 Test: manual Change-Id: I2bc3a1322651ab312e75bb9e9426909db368d84e --- .../android/systemui/screenshot/ScreenshotController.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index 3fbdc23f55d0e..8def475c192c0 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -33,6 +33,7 @@ import static java.util.Objects.requireNonNull; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.annotation.MainThread; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityOptions; @@ -261,6 +262,7 @@ public class ScreenshotController { private Bitmap mScreenBitmap; private SaveImageInBackgroundTask mSaveInBgTask; private boolean mScreenshotTakenInPortrait; + private boolean mBlockAttach; private Animator mScreenshotAnimation; private RequestCallback mCurrentRequestCallback; @@ -731,6 +733,7 @@ public class ScreenshotController { new ViewTreeObserver.OnWindowAttachListener() { @Override public void onWindowAttached() { + mBlockAttach = false; decorView.getViewTreeObserver().removeOnWindowAttachListener(this); action.run(); } @@ -747,14 +750,16 @@ public class ScreenshotController { mWindow.setContentView(contentView); } + @MainThread private void attachWindow() { View decorView = mWindow.getDecorView(); - if (decorView.isAttachedToWindow()) { + if (decorView.isAttachedToWindow() || mBlockAttach) { return; } if (DEBUG_WINDOW) { Log.d(TAG, "attachWindow"); } + mBlockAttach = true; mWindowManager.addView(decorView, mWindowLayoutParams); decorView.requestApplyInsets(); }