diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 512b5e08bf31f..c58e627425b7d 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -878,6 +878,20 @@ public final class PendingIntent implements Parcelable {
send(context, code, intent, null, null, null, null);
}
+ /**
+ * Perform the operation associated with this PendingIntent, supplying additional
+ * options for the operation.
+ *
+ * @param options Additional options the caller would like to provide to modify the
+ * sending behavior. May be built from an {@link ActivityOptions} to apply to an
+ * activity start.
+ *
+ * @hide
+ */
+ public void send(Bundle options) throws CanceledException {
+ send(null, 0, null, null, null, null, options);
+ }
+
/**
* Perform the operation associated with this PendingIntent, allowing the
* caller to be notified when the send has completed.
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index e0e13f59b7065..fc199440e7827 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -24,6 +24,7 @@
+
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 2c9dad96b076b..4be1d30c8fe57 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -180,6 +180,9 @@
+
+
+
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java
index d0694ab124c66..429458fe07043 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java
@@ -17,6 +17,7 @@
package com.android.systemui.plugins;
import android.annotation.Nullable;
+import android.app.BroadcastOptions;
import android.app.PendingIntent;
import android.graphics.drawable.Drawable;
import android.view.View;
@@ -70,7 +71,9 @@ public interface GlobalActionsPanelPlugin extends Plugin {
/** Starts a PendingIntent, dismissing the keyguard if necessary. */
default void startPendingIntentDismissingKeyguard(PendingIntent pendingIntent) {
try {
- pendingIntent.send();
+ BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setInteractive(true);
+ pendingIntent.send(options.toBundle());
} catch (PendingIntent.CanceledException e) {
// no-op
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
index edd1c6891946d..3d9eee4e9febb 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
@@ -156,6 +156,8 @@ class DetailDialog(
// Remove the task explicitly, since onRelease() callback will be executed after
// startActivity() below is called.
broadcastSender.closeSystemDialogs()
+ // not sent as interactive, lest the higher-importance activity launch
+ // be impacted
pendingIntent.send()
false
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
index 2dd339d409a62..1cc8a1353a340 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
@@ -16,6 +16,7 @@
package com.android.systemui.media.controls.pipeline
+import android.app.BroadcastOptions
import android.app.Notification
import android.app.Notification.EXTRA_SUBSTITUTE_APP_NAME
import android.app.PendingIntent
@@ -1165,7 +1166,9 @@ class MediaDataManager(
private fun sendPendingIntent(intent: PendingIntent): Boolean {
return try {
- intent.send()
+ val options = BroadcastOptions.makeBasic()
+ options.setInteractive(true)
+ intent.send(options.toBundle())
true
} catch (e: PendingIntent.CanceledException) {
Log.d(TAG, "Intent canceled", e)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
index 15c34430f455b..ee0147f555366 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
@@ -23,6 +23,7 @@ import static com.android.systemui.media.controls.models.recommendation.Smartspa
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;
+import android.app.BroadcastOptions;
import android.app.PendingIntent;
import android.app.WallpaperColors;
import android.app.smartspace.SmartspaceAction;
@@ -113,6 +114,8 @@ import com.android.systemui.util.ColorUtilKt;
import com.android.systemui.util.animation.TransitionLayout;
import com.android.systemui.util.time.SystemClock;
+import dagger.Lazy;
+
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
@@ -120,7 +123,6 @@ import java.util.concurrent.Executor;
import javax.inject.Inject;
-import dagger.Lazy;
import kotlin.Unit;
/**
@@ -625,7 +627,9 @@ public class MediaControlPanel {
device.getIntent().getIntent(), true);
} else {
try {
- device.getIntent().send();
+ BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setInteractive(true);
+ device.getIntent().send(options.toBundle());
} catch (PendingIntent.CanceledException e) {
Log.e(TAG, "Device pending intent was canceled");
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
index b8684ee30b9ae..431b28fb7f28e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
@@ -16,12 +16,14 @@
package com.android.systemui.screenrecord;
+import android.app.BroadcastOptions;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.UserHandle;
import android.util.Log;
@@ -57,6 +59,7 @@ public class RecordingController
private boolean mIsStarting;
private boolean mIsRecording;
private PendingIntent mStopIntent;
+ private final Bundle mInteractiveBroadcastOption;
private CountDownTimer mCountDownTimer = null;
private final Executor mMainExecutor;
private final BroadcastDispatcher mBroadcastDispatcher;
@@ -106,6 +109,10 @@ public class RecordingController
mBroadcastDispatcher = broadcastDispatcher;
mUserContextProvider = userContextProvider;
mUserTracker = userTracker;
+
+ BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setInteractive(true);
+ mInteractiveBroadcastOption = options.toBundle();
}
/** Create a dialog to show screen recording options to the user. */
@@ -148,7 +155,7 @@ public class RecordingController
cb.onCountdownEnd();
}
try {
- startIntent.send();
+ startIntent.send(mInteractiveBroadcastOption);
mUserTracker.addCallback(mUserChangedCallback, mMainExecutor);
IntentFilter stateFilter = new IntentFilter(INTENT_UPDATE_STATE);
@@ -202,7 +209,7 @@ public class RecordingController
public void stopRecording() {
try {
if (mStopIntent != null) {
- mStopIntent.send();
+ mStopIntent.send(mInteractiveBroadcastOption);
} else {
Log.e(TAG, "Stop intent was null");
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java b/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java
index c4ea67e0f79e9..860bfe37aee27 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java
@@ -18,6 +18,7 @@ package com.android.systemui.screenshot;
import static java.util.Objects.requireNonNull;
+import android.app.BroadcastOptions;
import android.app.PendingIntent;
import android.content.Context;
import android.graphics.drawable.Icon;
@@ -96,7 +97,9 @@ public class OverlayActionChip extends FrameLayout {
public void setPendingIntent(PendingIntent intent, Runnable finisher) {
setOnClickListener(v -> {
try {
- intent.send();
+ BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setInteractive(true);
+ intent.send(options.toBundle());
finisher.run();
} catch (PendingIntent.CanceledException e) {
Log.e(TAG, "Intent cancelled", e);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index e8ceb521b6b06..736b892beff7e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -34,6 +34,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.app.ActivityManager;
+import android.app.BroadcastOptions;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
@@ -53,6 +54,7 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.graphics.drawable.InsetDrawable;
import android.graphics.drawable.LayerDrawable;
+import android.os.Bundle;
import android.os.Looper;
import android.os.RemoteException;
import android.util.AttributeSet;
@@ -169,6 +171,7 @@ public class ScreenshotView extends FrameLayout implements
private long mDefaultTimeoutOfTimeoutHandler;
private ActionIntentExecutor mActionExecutor;
private FeatureFlags mFlags;
+ private final Bundle mInteractiveBroadcastOption;
private enum PendingInteraction {
PREVIEW,
@@ -195,6 +198,10 @@ public class ScreenshotView extends FrameLayout implements
mResources = mContext.getResources();
mInteractionJankMonitor = getInteractionJankMonitorInstance();
+ BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setInteractive(true);
+ mInteractiveBroadcastOption = options.toBundle();
+
mFixedSize = mResources.getDimensionPixelSize(R.dimen.overlay_x_scale);
// standard material ease
@@ -1105,7 +1112,7 @@ public class ScreenshotView extends FrameLayout implements
private void startSharedTransition(ActionTransition transition) {
try {
mPendingSharedTransition = true;
- transition.action.actionIntent.send();
+ transition.action.actionIntent.send(mInteractiveBroadcastOption);
// fade out non-preview UI
createScreenshotFadeDismissAnimation().start();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index cf2f7742dc594..8dcfec71b68e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -122,6 +122,7 @@ public interface CentralSurfaces extends Dumpable, ActivityStarter, LifecycleOwn
options.setLaunchDisplayId(displayId);
options.setCallerDisplayId(displayId);
options.setPendingIntentBackgroundActivityLaunchAllowed(true);
+ options.setInteractive(true);
return options.toBundle();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java
index 3b1a4db067a35..33620979d681e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.tv.notifications;
+import android.app.BroadcastOptions;
import android.app.Notification;
import android.app.PendingIntent;
import android.service.notification.StatusBarNotification;
@@ -100,7 +101,9 @@ public class TvNotificationAdapter extends RecyclerView.Adapter {
try {
- walletCard.getPendingIntent().send();
+
+ BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setInteractive(true);
+ walletCard.getPendingIntent().send(options.toBundle());
} catch (PendingIntent.CanceledException e) {
Log.w(TAG, "Error sending pending intent for wallet card.");
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
index 69f3e987ec1d5..8127ccca3f3f9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
@@ -107,7 +107,7 @@ public class RecordingControllerTest extends SysuiTestCase {
mController.startCountdown(0, 0, startIntent, null);
verify(mCallback).onCountdownEnd();
- verify(startIntent).send();
+ verify(startIntent).send(any());
}
// Test that when recording is stopped, the stop intent is sent and listeners are notified.
@@ -125,7 +125,7 @@ public class RecordingControllerTest extends SysuiTestCase {
assertFalse(mController.isStarting());
assertFalse(mController.isRecording());
- verify(stopIntent).send();
+ verify(stopIntent).send(any());
verify(mCallback).onRecordingEnd();
}