From 777c82d9b7f51ab41a3f9f2c87e95cc21b258088 Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Tue, 11 Jun 2019 15:47:10 -0400 Subject: [PATCH] GlobalScreenshot - Fix race condition It is possible for the call to system windows to occur slightly after the ChooserActivity gets launched, therefore preventing it from ever showing. Wait on the future before attempting to launch the activity. Bug: 134976976 Test: Screenshot, then share over and over Change-Id: Iba98a079412f8e35643f3a1db04e749b3c654637 --- .../shared/system/ActivityManagerWrapper.java | 5 +++-- .../systemui/screenshot/GlobalScreenshot.java | 19 +++++++++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java index 6b07ed8e8edca..a2abb4b1695cf 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java @@ -64,6 +64,7 @@ import com.android.systemui.shared.recents.model.ThumbnailData; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Future; import java.util.function.Consumer; public class ActivityManagerWrapper { @@ -380,8 +381,8 @@ public class ActivityManagerWrapper { /** * Requests that the system close any open system windows (including other SystemUI). */ - public void closeSystemWindows(final String reason) { - mBackgroundExecutor.submit(new Runnable() { + public Future closeSystemWindows(final String reason) { + return mBackgroundExecutor.submit(new Runnable() { @Override public void run() { try { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 341461bf72023..11ca94f6f4e62 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -92,6 +92,11 @@ import java.io.OutputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + + /** * POD used in the AsyncTask which saves an image in the background. @@ -446,6 +451,8 @@ class GlobalScreenshot { static final String EXTRA_CANCEL_NOTIFICATION = "android:screenshot_cancel_notification"; static final String EXTRA_DISALLOW_ENTER_PIP = "android:screenshot_disallow_enter_pip"; + private static final String TAG = "GlobalScreenshot"; + private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130; private static final int SCREENSHOT_DROP_IN_DURATION = 430; private static final int SCREENSHOT_DROP_OUT_DELAY = 500; @@ -902,11 +909,19 @@ class GlobalScreenshot { * appropriate signals to the system (ie. to dismiss the keyguard if necessary). */ public static class ActionProxyReceiver extends BroadcastReceiver { + static final int CLOSE_WINDOWS_TIMEOUT_MILLIS = 3000; + @Override public void onReceive(Context context, final Intent intent) { Runnable startActivityRunnable = () -> { - ActivityManagerWrapper.getInstance().closeSystemWindows( - SYSTEM_DIALOG_REASON_SCREENSHOT); + try { + ActivityManagerWrapper.getInstance().closeSystemWindows( + SYSTEM_DIALOG_REASON_SCREENSHOT).get( + CLOSE_WINDOWS_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); + } catch (TimeoutException | InterruptedException | ExecutionException e) { + Slog.e(TAG, "Unable to share screenshot", e); + return; + } Intent actionIntent = intent.getParcelableExtra(EXTRA_ACTION_INTENT); if (intent.getBooleanExtra(EXTRA_CANCEL_NOTIFICATION, false)) {