summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Achim Thesmann <achim@google.com> 2024-05-09 22:33:12 +0000
committer Achim Thesmann <achim@google.com> 2024-07-09 23:16:34 +0000
commit9a4183ebb70b8f0a004ecf65e52354cb499fe04e (patch)
tree1c9974e38698a40988a138e7b17e3b2daec0fab0
parentc7c024121b368b4815c67b05c080a80f92a75a44 (diff)
Sending Intent needs to specify options
This only makes the existing API public. This API adds an options Bundle analog to PendingIntent.send. Since this is an existing API (just hidden) there are existing CTS tests, e.g. PackageManagerTest modified in ag/21435231 Without this change 1P and 3P cannot send IntentSenders to start Activities since that needs BAL opt in (actually since SDK 34, but most cases were covered by the BAL privilege of the creator, which is opt-in in SDK 35). The use of IntentSenders is much less common than PendingIntents, but for historical and API layering reasons some (system) APIs return IntentSenders and there is no existing way to convert an IntentSender back to a PendingIntent. Creating such a way would be a significant risk as this would force equivalence between these 2 classes (see https://chat.google.com/room/AAAAWc5iiZU/jAxcU6w0nVQ). Bug: 339720406 Test: atest BackgroundActivityLaunchTests Flag: com.android.window.flags.bal_send_intent_with_options API-Coverage-Bug: 269159993 Change-Id: I20804fd0f1aec687c0eaf8a2e53b5463d44399f7
-rw-r--r--core/api/current.txt1
-rw-r--r--core/java/android/content/IntentSender.java83
-rw-r--r--core/java/com/android/internal/app/SuspendedAppActivity.java4
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java5
-rw-r--r--services/core/java/com/android/server/pm/PackageArchiver.java10
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java15
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java20
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java4
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java5
9 files changed, 82 insertions, 65 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 46f426b9f8e9..d02b7555ae44 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -11603,6 +11603,7 @@ package android.content {
method public static android.content.IntentSender readIntentSenderOrNullFromParcel(android.os.Parcel);
method public void sendIntent(android.content.Context, int, android.content.Intent, android.content.IntentSender.OnFinished, android.os.Handler) throws android.content.IntentSender.SendIntentException;
method public void sendIntent(android.content.Context, int, android.content.Intent, android.content.IntentSender.OnFinished, android.os.Handler, String) throws android.content.IntentSender.SendIntentException;
+ method @FlaggedApi("com.android.window.flags.bal_send_intent_with_options") public void sendIntent(@Nullable android.content.Context, int, @Nullable android.content.Intent, @Nullable String, @Nullable android.os.Bundle, @Nullable java.util.concurrent.Executor, @Nullable android.content.IntentSender.OnFinished) throws android.content.IntentSender.SendIntentException;
method public static void writeIntentSenderOrNullToParcel(android.content.IntentSender, android.os.Parcel);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.content.IntentSender> CREATOR;
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
index 2e252c12c51d..32d1964dd4f0 100644
--- a/core/java/android/content/IntentSender.java
+++ b/core/java/android/content/IntentSender.java
@@ -16,6 +16,7 @@
package android.content;
+import android.annotation.FlaggedApi;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager.PendingIntentInfo;
@@ -32,6 +33,10 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.AndroidException;
+import com.android.window.flags.Flags;
+
+import java.util.concurrent.Executor;
+
/**
* A description of an Intent and target action to perform with it.
* The returned object can be
@@ -114,15 +119,15 @@ public class IntentSender implements Parcelable {
implements Runnable {
private final IntentSender mIntentSender;
private final OnFinished mWho;
- private final Handler mHandler;
+ private final Executor mExecutor;
private Intent mIntent;
private int mResultCode;
private String mResultData;
private Bundle mResultExtras;
- FinishedDispatcher(IntentSender pi, OnFinished who, Handler handler) {
+ FinishedDispatcher(IntentSender pi, OnFinished who, Executor executor) {
mIntentSender = pi;
mWho = who;
- mHandler = handler;
+ mExecutor = executor;
}
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean serialized, boolean sticky, int sendingUser) {
@@ -130,10 +135,10 @@ public class IntentSender implements Parcelable {
mResultCode = resultCode;
mResultData = data;
mResultExtras = extras;
- if (mHandler == null) {
+ if (mExecutor == null) {
run();
} else {
- mHandler.post(this);
+ mExecutor.execute(this);
}
}
public void run() {
@@ -147,16 +152,16 @@ public class IntentSender implements Parcelable {
* caller to specify information about the Intent to use and be notified
* when the send has completed.
*
- * @param context The Context of the caller. This may be null if
- * <var>intent</var> is also null.
+ * @param context The Context of the caller. This may be {@code null} if
+ * <var>intent</var> is also {@code null}.
* @param code Result code to supply back to the IntentSender's target.
* @param intent Additional Intent data. See {@link Intent#fillIn
* Intent.fillIn()} for information on how this is applied to the
- * original Intent. Use null to not modify the original Intent.
+ * original Intent. Use {@code null} to not modify the original Intent.
* @param onFinished The object to call back on when the send has
- * completed, or null for no callback.
+ * completed, or {@code null} for no callback.
* @param handler Handler identifying the thread on which the callback
- * should happen. If null, the callback will happen from the thread
+ * should happen. If {@code null}, the callback will happen from the thread
* pool of the process.
*
*
@@ -165,8 +170,8 @@ public class IntentSender implements Parcelable {
*/
public void sendIntent(Context context, int code, Intent intent,
OnFinished onFinished, Handler handler) throws SendIntentException {
- sendIntent(context, code, intent, onFinished, handler, null,
- SEND_INTENT_DEFAULT_OPTIONS);
+ sendIntent(context, code, intent, null, SEND_INTENT_DEFAULT_OPTIONS,
+ handler == null ? null : handler::post, onFinished);
}
/**
@@ -174,22 +179,22 @@ public class IntentSender implements Parcelable {
* caller to specify information about the Intent to use and be notified
* when the send has completed.
*
- * @param context The Context of the caller. This may be null if
- * <var>intent</var> is also null.
+ * @param context The Context of the caller. This may be {@code null} if
+ * <var>intent</var> is also {@code null}.
* @param code Result code to supply back to the IntentSender's target.
* @param intent Additional Intent data. See {@link Intent#fillIn
* Intent.fillIn()} for information on how this is applied to the
- * original Intent. Use null to not modify the original Intent.
+ * original Intent. Use {@code null} to not modify the original Intent.
* @param onFinished The object to call back on when the send has
- * completed, or null for no callback.
+ * completed, or {@code null} for no callback.
* @param handler Handler identifying the thread on which the callback
- * should happen. If null, the callback will happen from the thread
+ * should happen. If {@code null}, the callback will happen from the thread
* pool of the process.
* @param requiredPermission Name of permission that a recipient of the PendingIntent
* is required to hold. This is only valid for broadcast intents, and
* corresponds to the permission argument in
* {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
- * If null, no permission is required.
+ * If {@code null}, no permission is required.
*
*
* @throws SendIntentException Throws CanceledIntentException if the IntentSender
@@ -198,8 +203,8 @@ public class IntentSender implements Parcelable {
public void sendIntent(Context context, int code, Intent intent,
OnFinished onFinished, Handler handler, String requiredPermission)
throws SendIntentException {
- sendIntent(context, code, intent, onFinished, handler, requiredPermission,
- SEND_INTENT_DEFAULT_OPTIONS);
+ sendIntent(context, code, intent, requiredPermission, SEND_INTENT_DEFAULT_OPTIONS,
+ handler == null ? null : handler::post, onFinished);
}
/**
@@ -207,32 +212,32 @@ public class IntentSender implements Parcelable {
* caller to specify information about the Intent to use and be notified
* when the send has completed.
*
- * @param context The Context of the caller. This may be null if
- * <var>intent</var> is also null.
+ * @param context The Context of the caller. This may be {@code null} if
+ * <var>intent</var> is also {@code null}.
* @param code Result code to supply back to the IntentSender's target.
* @param intent Additional Intent data. See {@link Intent#fillIn
* Intent.fillIn()} for information on how this is applied to the
- * original Intent. Use null to not modify the original Intent.
+ * original Intent. Use {@code null} to not modify the original Intent.
* @param onFinished The object to call back on when the send has
- * completed, or null for no callback.
- * @param handler Handler identifying the thread on which the callback
- * should happen. If null, the callback will happen from the thread
+ * completed, or {@code null} for no callback.
+ * @param executor Executor identifying the thread on which the callback
+ * should happen. If {@code null}, the callback will happen from the thread
* pool of the process.
* @param requiredPermission Name of permission that a recipient of the PendingIntent
* is required to hold. This is only valid for broadcast intents, and
* corresponds to the permission argument in
* {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
- * If null, no permission is required.
+ * If {@code null}, no permission is required.
* @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.
+ * behavior. Typically built from using {@link ActivityOptions} to apply to an activity start.
*
* @throws SendIntentException Throws CanceledIntentException if the IntentSender
* is no longer allowing more intents to be sent through it.
- * @hide
*/
- public void sendIntent(Context context, int code, Intent intent,
- OnFinished onFinished, Handler handler, String requiredPermission,
- @Nullable Bundle options)
+ @FlaggedApi(Flags.FLAG_BAL_SEND_INTENT_WITH_OPTIONS)
+ public void sendIntent(@Nullable Context context, int code, @Nullable Intent intent,
+ @Nullable String requiredPermission, @Nullable Bundle options,
+ @Nullable Executor executor, @Nullable OnFinished onFinished)
throws SendIntentException {
try {
String resolvedType = intent != null ?
@@ -243,7 +248,7 @@ public class IntentSender implements Parcelable {
int res = ActivityManager.getService().sendIntentSender(app, mTarget, mWhitelistToken,
code, intent, resolvedType,
onFinished != null
- ? new FinishedDispatcher(this, onFinished, handler)
+ ? new FinishedDispatcher(this, onFinished, executor)
: null,
requiredPermission, options);
if (res < 0) {
@@ -268,7 +273,7 @@ public class IntentSender implements Parcelable {
* sending the Intent. The returned string is supplied by the system, so
* that an application can not spoof its package.
*
- * @return The package name of the PendingIntent, or null if there is
+ * @return The package name of the PendingIntent, or {@code null} if there is
* none associated with it.
*/
public String getCreatorPackage() {
@@ -296,7 +301,7 @@ public class IntentSender implements Parcelable {
* {@link android.os.Process#myUserHandle() Process.myUserHandle()} for
* more explanation of user handles.
*
- * @return The user handle of the PendingIntent, or null if there is
+ * @return The user handle of the PendingIntent, {@code null} if there is
* none associated with it.
*/
public UserHandle getCreatorUserHandle() {
@@ -355,11 +360,11 @@ public class IntentSender implements Parcelable {
};
/**
- * Convenience function for writing either a IntentSender or null pointer to
+ * Convenience function for writing either a IntentSender or {@code null} pointer to
* a Parcel. You must use this with {@link #readIntentSenderOrNullFromParcel}
* for later reading it.
*
- * @param sender The IntentSender to write, or null.
+ * @param sender The IntentSender to write, or {@code null}.
* @param out Where to write the IntentSender.
*/
public static void writeIntentSenderOrNullToParcel(IntentSender sender,
@@ -369,13 +374,13 @@ public class IntentSender implements Parcelable {
}
/**
- * Convenience function for reading either a Messenger or null pointer from
+ * Convenience function for reading either a Messenger or {@code null} pointer from
* a Parcel. You must have previously written the Messenger with
* {@link #writeIntentSenderOrNullToParcel}.
*
* @param in The Parcel containing the written Messenger.
*
- * @return Returns the Messenger read from the Parcel, or null if null had
+ * @return Returns the Messenger read from the Parcel, or @code null} if @code null} had
* been written.
*/
public static IntentSender readIntentSenderOrNullFromParcel(Parcel in) {
diff --git a/core/java/com/android/internal/app/SuspendedAppActivity.java b/core/java/com/android/internal/app/SuspendedAppActivity.java
index 7a8a47e5f9fc..9d5704141c93 100644
--- a/core/java/com/android/internal/app/SuspendedAppActivity.java
+++ b/core/java/com/android/internal/app/SuspendedAppActivity.java
@@ -342,8 +342,8 @@ public class SuspendedAppActivity extends AlertActivity
.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
.toBundle();
try {
- mOnUnsuspend.sendIntent(this, 0, null, null, null, null,
- activityOptions);
+ mOnUnsuspend.sendIntent(this, 0, null, null, activityOptions,
+ null, null);
} catch (IntentSender.SendIntentException e) {
Slog.e(TAG, "Error while starting intent " + mOnUnsuspend, e);
}
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 009e9b862b0f..8ee02dc4f901 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -801,8 +801,9 @@ final class InstallPackageHelper {
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- target.sendIntent(context, 0, fillIn, null /* onFinished*/, null /* handler */,
- null /* requiredPermission */, options.toBundle());
+ target.sendIntent(context, 0, fillIn,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (IntentSender.SendIntentException ignored) {
}
}
diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java
index 0d1095f5656d..6b7b702b9157 100644
--- a/services/core/java/com/android/server/pm/PackageArchiver.java
+++ b/services/core/java/com/android/server/pm/PackageArchiver.java
@@ -1194,8 +1194,9 @@ public class PackageArchiver {
MODE_BACKGROUND_ACTIVITY_START_DENIED);
for (IntentSender intentSender : unarchiveIntentSenders) {
try {
- intentSender.sendIntent(mContext, 0, broadcastIntent, /* onFinished= */ null,
- /* handler= */ null, /* requiredPermission= */ null, options.toBundle());
+ intentSender.sendIntent(mContext, 0, broadcastIntent,
+ /* requiredPermission */ null, options.toBundle(),
+ /* executor */ null, /* onFinished */ null);
} catch (IntentSender.SendIntentException e) {
Slog.e(TAG, TextUtils.formatSimple("Failed to send unarchive intent"), e);
} finally {
@@ -1328,8 +1329,9 @@ public class PackageArchiver {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityStartMode(
MODE_BACKGROUND_ACTIVITY_START_DENIED);
- statusReceiver.sendIntent(mContext, 0, intent, /* onFinished= */ null,
- /* handler= */ null, /* requiredPermission= */ null, options.toBundle());
+ statusReceiver.sendIntent(mContext, 0, intent,
+ /* requiredPermission */ null, options.toBundle(),
+ /* executor */ null, /* onFinished */ null);
} catch (IntentSender.SendIntentException e) {
Slog.e(
TAG,
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index b93dcdc93a82..f615ca1da2e2 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -1581,8 +1581,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- callback.sendIntent(mContext, 0, intent, null /* onFinished*/,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ callback.sendIntent(mContext, 0, intent,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (SendIntentException ignore) {
}
});
@@ -1912,8 +1913,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- mTarget.sendIntent(mContext, 0, fillIn, null /* onFinished*/,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ mTarget.sendIntent(mContext, 0, fillIn,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (SendIntentException ignored) {
}
}
@@ -1945,8 +1947,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- mTarget.sendIntent(mContext, 0, fillIn, null /* onFinished*/,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ mTarget.sendIntent(mContext, 0, fillIn,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (SendIntentException ignored) {
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 47a79a3c4051..ff8a69de35bc 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -5053,8 +5053,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- target.sendIntent(mContext, 0 /* code */, intent, null /* onFinished */,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ target.sendIntent(mContext, 0 /* code */, intent,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (IntentSender.SendIntentException ignored) {
}
}
@@ -5447,8 +5448,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- target.sendIntent(context, 0, fillIn, null /* onFinished */,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ target.sendIntent(context, 0, fillIn,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (IntentSender.SendIntentException ignored) {
}
}
@@ -5496,8 +5498,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- target.sendIntent(context, 0, fillIn, null /* onFinished */,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ target.sendIntent(context, 0, fillIn,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (IntentSender.SendIntentException ignored) {
}
}
@@ -5533,8 +5536,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
try {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
- target.sendIntent(context, 0, intent, null /* onFinished */,
- null /* handler */, null /* requiredPermission */, options.toBundle());
+ target.sendIntent(context, 0, intent,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (IntentSender.SendIntentException ignored) {
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c0b8034b9a56..ad59a6992ceb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5034,8 +5034,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setPendingIntentBackgroundActivityLaunchAllowed(false);
pi.sendIntent(null, success ? 1 : 0, null /* intent */,
- null /* onFinished*/, null /* handler */,
- null /* requiredPermission */, options.toBundle());
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (SendIntentException e) {
Slog.w(TAG, e);
}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 1cd77ffcedaa..5f201ff97e54 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -4482,8 +4482,9 @@ public class ShortcutService extends IShortcutService.Stub {
ActivityOptions options = ActivityOptions.makeBasic()
.setPendingIntentBackgroundActivityStartMode(
MODE_BACKGROUND_ACTIVITY_START_DENIED);
- intentSender.sendIntent(mContext, /* code= */ 0, extras,
- /* onFinished=*/ null, /* handler= */ null, null, options.toBundle());
+ intentSender.sendIntent(mContext, 0 /* code */, extras,
+ null /* requiredPermission */, options.toBundle(),
+ null /* executor */, null /* onFinished*/);
} catch (SendIntentException e) {
Slog.w(TAG, "sendIntent failed().", e);
}