diff options
author | 2023-03-15 14:24:10 -0700 | |
---|---|---|
committer | 2023-03-20 22:29:35 -0700 | |
commit | 2f1bbc2bb14dba88a0f033fb4ce32bbf20df25ed (patch) | |
tree | 619948d0ebac1188095233cfa4458d4c503cde04 | |
parent | 1fd2378e6bc43292ca94cef438be02a8039ec112 (diff) |
Apply delivery group policies to CLOSE_SYSTEM_DIALOG broadcast.
- The "set-defer-until-active" policy is applied so that the
broadcast targeted to apps in the Cached state is deferred until
they come out of that state.
- The "deliver-most-recent" policy is applied so that if there are
already pending broadcasts waiting to be delivered when a new
broadcast is sent, the old ones are discarded.
Bug: 271950524
Test: TH
Change-Id: Iab6064cf1436e02dd3d46badeeb6ab8dd6198c69
12 files changed, 56 insertions, 16 deletions
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 0cd42a364016..82f4315d033e 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -3619,6 +3619,17 @@ class ContextImpl extends Context { scheduleFinalCleanup(getClass().getName(), getOuterContext().getClass().getSimpleName()); } + @Override + public void closeSystemDialogs() { + final Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS) + .addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + final Bundle options = BroadcastOptions.makeBasic() + .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT) + .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE) + .toBundle(); + sendBroadcast(intent, null /* receiverPermission */, options); + } + // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index fc7532303ab1..3b2ea785988e 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -7873,4 +7873,15 @@ public abstract class Context { public boolean isConfigurationContext() { throw new RuntimeException("Not implemented. Must override in a subclass."); } + + /** + * Closes temporary system dialogs. Some examples of temporary system dialogs are the + * notification window-shade and the recent tasks dialog. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS) + public void closeSystemDialogs() { + throw new RuntimeException("Not implemented. Must override in a subclass."); + } } diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 21de5cf1511a..4327c7acf0f0 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -1484,4 +1484,15 @@ public class ContextWrapper extends Context { // Do nothing if the callback hasn't been registered to Application Context by // super.unregisterComponentCallbacks() for Application that is targeting prior to T. } + + /** + * Closes temporary system dialogs. Some examples of temporary system dialogs are the + * notification window-shade and the recent tasks dialog. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS) + public void closeSystemDialogs() { + mBase.closeSystemDialogs(); + } } diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java index 55626844594d..2c4b4786c968 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java @@ -422,7 +422,7 @@ public class DynamicSystemInstallationService extends Service Log.e(TAG, "Failed to disable DynamicSystem."); // Dismiss status bar and show a toast. - sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); + closeSystemDialogs(); Toast.makeText(this, getString(R.string.toast_failed_to_disable_dynsystem), Toast.LENGTH_LONG).show(); diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java index 6f7d20a950d5..067efe97f6b6 100644 --- a/packages/Shell/src/com/android/shell/BugreportProgressService.java +++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java @@ -1697,7 +1697,7 @@ public class BugreportProgressService extends Service { } private void collapseNotificationBar() { - sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); + closeSystemDialogs(); } private static Looper newLooper(String name) { diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt index 6615f6b0b9eb..f9613d505d87 100644 --- a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt +++ b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt @@ -109,7 +109,7 @@ class BroadcastSender @Inject constructor( @AnyThread fun closeSystemDialogs() { sendInBackground { - context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) + context.closeSystemDialogs() } } diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java index 7a42642f2667..c2c1306d2a32 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java @@ -772,9 +772,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { mSaverConfirmation.dismiss(); } // Also close the notification shade, if it's open. - mBroadcastSender.sendBroadcast( - new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS) - .setFlags(Intent.FLAG_RECEIVER_FOREGROUND)); + mBroadcastSender.closeSystemDialogs(); final Uri uri = Uri.parse(getURL()); Context context = widget.getContext(); diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java index 047762662aab..4349bd71f670 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java @@ -205,7 +205,7 @@ public class RecordingService extends Service implements ScreenMediaRecorderList }, false, false); // Close quick shade - sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); + closeSystemDialogs(); break; } return Service.START_STICKY; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index 7ad594ee87ac..25399ecfb8cf 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -959,7 +959,7 @@ public class ScreenshotController { transitionDestination, onTransitionEnd, longScreenshot); // TODO: Do this via ActionIntentExecutor instead. - mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); + mContext.closeSystemDialogs(); } ); diff --git a/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingSecondaryUserActivity.java b/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingSecondaryUserActivity.java index 7a31fa54b1cd..f9f14e0bc362 100644 --- a/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingSecondaryUserActivity.java +++ b/packages/SystemUI/src/com/android/systemui/wifi/WifiDebuggingSecondaryUserActivity.java @@ -97,7 +97,7 @@ public class WifiDebuggingSecondaryUserActivity extends AlertActivity filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); registerReceiver(mWifiChangeReceiver, filter); // Close quick shade - sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); + closeSystemDialogs(); } @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt index fbd2c918648a..8e8172757cbe 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt @@ -30,7 +30,6 @@ import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentCaptor import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @@ -126,13 +125,10 @@ class BroadcastSenderTest : SysuiTestCase() { @Test fun sendCloseSystemDialogs_dispatchesWithWakelock() { - val intentCaptor = ArgumentCaptor.forClass(Intent::class.java) - broadcastSender.closeSystemDialogs() runExecutorAssertingWakelock { - verify(mockContext).sendBroadcast(intentCaptor.capture()) - assertThat(intentCaptor.value.action).isEqualTo(Intent.ACTION_CLOSE_SYSTEM_DIALOGS) + verify(mockContext).closeSystemDialogs() } } diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java index 20ff51c22783..8c0e19d16545 100644 --- a/services/core/java/com/android/server/dreams/DreamController.java +++ b/services/core/java/com/android/server/dreams/DreamController.java @@ -63,6 +63,10 @@ final class DreamController { // Time to allow the dream to perform an exit transition when waking up. private static final int DREAM_FINISH_TIMEOUT = 5 * 1000; + // Extras used with ACTION_CLOSE_SYSTEM_DIALOGS broadcast + private static final String EXTRA_REASON_KEY = "reason"; + private static final String EXTRA_REASON_VALUE = "dream"; + private final Context mContext; private final Handler mHandler; private final Listener mListener; @@ -77,6 +81,7 @@ final class DreamController { private final Bundle mDreamingStartedStoppedOptions = createDreamingStartedStoppedOptions(); private final Intent mCloseNotificationShadeIntent; + private final Bundle mCloseNotificationShadeOptions; private DreamRecord mCurrentDream; @@ -96,7 +101,14 @@ final class DreamController { mListener = listener; mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class); mCloseNotificationShadeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - mCloseNotificationShadeIntent.putExtra("reason", "dream"); + mCloseNotificationShadeIntent.putExtra(EXTRA_REASON_KEY, EXTRA_REASON_VALUE); + mCloseNotificationShadeIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + mCloseNotificationShadeOptions = BroadcastOptions.makeBasic() + .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT) + .setDeliveryGroupMatchingKey(Intent.ACTION_CLOSE_SYSTEM_DIALOGS, + EXTRA_REASON_VALUE) + .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE) + .toBundle(); } /** @@ -149,7 +161,8 @@ final class DreamController { Trace.traceBegin(Trace.TRACE_TAG_POWER, "startDream"); try { // Close the notification shade. No need to send to all, but better to be explicit. - mContext.sendBroadcastAsUser(mCloseNotificationShadeIntent, UserHandle.ALL); + mContext.sendBroadcastAsUser(mCloseNotificationShadeIntent, UserHandle.ALL, + null /* receiverPermission */, mCloseNotificationShadeOptions); Slog.i(TAG, "Starting dream: name=" + name + ", isPreviewMode=" + isPreviewMode + ", canDoze=" + canDoze |