From b69e04e8b7c6b9f44920f4543cf8dc254cc17c2c Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Fri, 9 Dec 2022 17:37:14 -0800 Subject: Apply "most-recent" delivery policy to DREAMING related broadcasts. This allows us to skip any older DREAMING_STARTED or DREAMING_STOPPED broadcasts still waiting to be delivered to a process when a new DREAMING_STARTED or DREAMING_STOPPED broadcast is sent. Bug: 255532556 Test: atest ./tests/tests/dreams/src/android/service/dreams/cts/DreamServiceTest.java Change-Id: Ibc403aff4d0355a752aac30de7d733f294d2d91f --- .../com/android/server/dreams/DreamController.java | 34 ++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'services') diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java index c3313e0d11ca..e5357f61d076 100644 --- a/services/core/java/com/android/server/dreams/DreamController.java +++ b/services/core/java/com/android/server/dreams/DreamController.java @@ -19,6 +19,7 @@ package com.android.server.dreams; import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; import android.app.ActivityTaskManager; +import android.app.BroadcastOptions; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -45,6 +46,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Iterator; import java.util.NoSuchElementException; +import java.util.UUID; /** * Internal controller for starting and stopping the current dream and managing related state. @@ -69,6 +71,9 @@ final class DreamController { .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); private final Intent mDreamingStoppedIntent = new Intent(Intent.ACTION_DREAMING_STOPPED) .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + private static final String DREAMING_DELIVERY_GROUP_NAMESPACE = UUID.randomUUID().toString(); + private static final String DREAMING_DELIVERY_GROUP_KEY = UUID.randomUUID().toString(); + private final Bundle mDreamingStartedStoppedOptions = createDreamingStartedStoppedOptions(); private final Intent mCloseNotificationShadeIntent; @@ -93,6 +98,29 @@ final class DreamController { mCloseNotificationShadeIntent.putExtra("reason", "dream"); } + /** + * Create the {@link BroadcastOptions} bundle that will be used with sending the + * {@link Intent#ACTION_DREAMING_STARTED} and {@link Intent#ACTION_DREAMING_STOPPED} + * broadcasts. + */ + private Bundle createDreamingStartedStoppedOptions() { + final BroadcastOptions options = BroadcastOptions.makeBasic(); + // This allows the broadcasting system to discard any older broadcasts + // waiting to be delivered to a process. + options.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT); + // Set namespace and key to identify which older broadcasts can be discarded. + // We could use any strings here with the following requirements: + // - namespace needs to be unlikely to be reused with in + // the system_server process, as that could result in potentially discarding some + // non-dreaming_started/stopped related broadcast. + // - key needs to be the same for both DREAMING_STARTED and DREAMING_STOPPED broadcasts + // so that dreaming_stopped can also clear any older dreaming_started broadcasts that + // are yet to be delivered. + options.setDeliveryGroupMatchingKey( + DREAMING_DELIVERY_GROUP_NAMESPACE, DREAMING_DELIVERY_GROUP_KEY); + return options.toBundle(); + } + public void dump(PrintWriter pw) { pw.println("Dreamland:"); if (mCurrentDream != null) { @@ -244,7 +272,8 @@ final class DreamController { mCurrentDream = null; if (mSentStartBroadcast) { - mContext.sendBroadcastAsUser(mDreamingStoppedIntent, UserHandle.ALL); + mContext.sendBroadcastAsUser(mDreamingStoppedIntent, UserHandle.ALL, + null /* receiverPermission */, mDreamingStartedStoppedOptions); mSentStartBroadcast = false; } @@ -287,7 +316,8 @@ final class DreamController { mCurrentDream.mService = service; if (!mCurrentDream.mIsPreviewMode && !mSentStartBroadcast) { - mContext.sendBroadcastAsUser(mDreamingStartedIntent, UserHandle.ALL); + mContext.sendBroadcastAsUser(mDreamingStartedIntent, UserHandle.ALL, + null /* receiverPermission */, mDreamingStartedStoppedOptions); mSentStartBroadcast = true; } } -- cgit v1.2.3-59-g8ed1b