Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28993d22 authored by Joanne Chung's avatar Joanne Chung
Browse files

Check commit() IntentSender should come from a mutable PendingIntent

When an IMMUTABLE PendingIntent was used to create an IntentSender
which was passed into Session.commit(IntentSender statusReceiver),
the PendingIntent cannot be modified and the caller couldn't receive
EXTRA_STATUS or any installation results.

The system should provide an error signal to let the caller know to
pass the correct parameter.

Bug: 240618202
Test: atest android.packageinstaller.install.cts.SessionTest
Test: manual. A sample app with an immutable PendingIntent

Change-Id: If3d2ade7d8acb8a91f1223618a02b751e7f5970a
parent cd0800aa
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -417,4 +417,12 @@ public class IntentSender implements Parcelable {

        return mCachedInfo;
    }

    /**
     * Check if the PendingIntent is marked with {@link android.app.PendingIntent#FLAG_IMMUTABLE}.
     * @hide
     */
    public boolean isImmutable() {
        return getCachedInfo().isImmutable();
    }
}
+9 −0
Original line number Diff line number Diff line
@@ -1062,6 +1062,9 @@ public class PackageInstaller {
     * @param timeoutMillis The maximum time to wait, in milliseconds until the
     *                      constraints are satisfied. The caller will be notified via
     *                      {@code statusReceiver} if timeout happens before commit.
     * @throws IllegalArgumentException if the {@code statusReceiver} from an immutable
     *             {@link android.app.PendingIntent} when caller has a target SDK of API
     *             {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} or above.
     */
    public void commitSessionAfterInstallConstraintsAreMet(int sessionId,
            @NonNull IntentSender statusReceiver, @NonNull InstallConstraints constraints,
@@ -1736,6 +1739,9 @@ public class PackageInstaller {
         *
         * @throws SecurityException if streams opened through
         *             {@link #openWrite(String, long, long)} are still open.
         * @throws IllegalArgumentException if the {@code statusReceiver} from an immutable
         *             {@link android.app.PendingIntent} when caller has a target SDK of API
         *             version {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} or above.
         *
         * @see android.app.admin.DevicePolicyManager
         * @see #requestUserPreapproval
@@ -1764,6 +1770,9 @@ public class PackageInstaller {
         * @param statusReceiver Called when the state of the session changes. Intents
         *                       sent to this receiver contain {@link #EXTRA_STATUS}. Refer to the
         *                       individual status codes on how to handle them.
         * @throws IllegalArgumentException if the {@code statusReceiver} from an immutable
         *             {@link android.app.PendingIntent} when caller has a target SDK of API
         *             {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} or above.
         *
         * @hide
         */
+16 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ import android.app.NotificationManager;
import android.app.admin.DevicePolicyEventLogger;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.content.ComponentName;
@@ -333,6 +334,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {

    private static final int APP_METADATA_FILE_ACCESS_MODE = 0640;

    /**
     * Throws IllegalArgumentException if the {@link IntentSender} from an immutable
     * {@link android.app.PendingIntent} when caller has a target SDK of API
     * {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} or above.
     */
    @ChangeId
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
    private static final long THROW_EXCEPTION_COMMIT_WITH_IMMUTABLE_PENDING_INTENT = 240618202L;

    // TODO: enforce INSTALL_ALLOW_TEST
    // TODO: enforce INSTALL_ALLOW_DOWNGRADE

@@ -1864,6 +1874,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    @Override
    public void commit(@NonNull IntentSender statusReceiver, boolean forTransfer) {
        assertNotChild("commit");
        boolean throwsExceptionCommitImmutableCheck = CompatChanges.isChangeEnabled(
                THROW_EXCEPTION_COMMIT_WITH_IMMUTABLE_PENDING_INTENT, Binder.getCallingUid());
        if (throwsExceptionCommitImmutableCheck && statusReceiver.isImmutable()) {
            throw new IllegalArgumentException(
                "The commit() status receiver should come from a mutable PendingIntent");
        }

        if (!markAsSealed(statusReceiver, forTransfer)) {
            return;