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
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 0cd42a3..82f4315 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -3619,6 +3619,17 @@
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 fc75323..3b2ea78 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -7873,4 +7873,15 @@
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 21de5cf..4327c7a 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -1484,4 +1484,15 @@
// 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 5562684..2c4b478 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
@@ -422,7 +422,7 @@
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 6f7d20a..067efe9 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -1697,7 +1697,7 @@
}
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 6615f6b..f9613d50 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 @@
@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 7a42642..c2c1306 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 @@
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 0477626..4349bd7 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 @@
}, 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 7ad594e..25399ec 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 @@
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 7a31fa5..f9f14e0 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 @@
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 fbd2c91..8e81727 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 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 @@
@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 20ff51c..8c0e19d 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 @@
// 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 @@
private final Bundle mDreamingStartedStoppedOptions = createDreamingStartedStoppedOptions();
private final Intent mCloseNotificationShadeIntent;
+ private final Bundle mCloseNotificationShadeOptions;
private DreamRecord mCurrentDream;
@@ -96,7 +101,14 @@
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 @@
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