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

Commit 6fd1d8b8 authored by Joanne Chung's avatar Joanne Chung Committed by Android (Google) Code Review
Browse files

Merge "Use PendingIntent instead of using in-memory intent sender object"

parents 342bbad5 26ff1c4e
Loading
Loading
Loading
Loading
+67 −30
Original line number Diff line number Diff line
@@ -46,10 +46,12 @@ import android.annotation.TestApi;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.AppGlobals;
import android.app.PendingIntent;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.PackageManager.DeleteFlags;
import android.content.pm.PackageManager.InstallReason;
@@ -62,11 +64,9 @@ import android.graphics.Bitmap;
import android.icu.util.ULocale;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.FileBridge;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
@@ -148,6 +148,9 @@ import java.util.function.Consumer;
public class PackageInstaller {
    private static final String TAG = "PackageInstaller";

    private static final String ACTION_WAIT_INSTALL_CONSTRAINTS =
            "android.content.pm.action.WAIT_INSTALL_CONSTRAINTS";

    /** {@hide} */
    public static final boolean ENABLE_REVOCABLE_FD =
            SystemProperties.getBoolean("fw.revocable_fd", false);
@@ -1077,34 +1080,68 @@ public class PackageInstaller {
            var session = mInstaller.openSession(sessionId);
            session.seal();
            var packageNames = session.fetchPackageNames();
            var intentSender = new IntentSender((IIntentSender) new IIntentSender.Stub() {
            var context = ActivityThread.currentApplication();
            var localIntentSender = new LocalIntentSender(context, sessionId, session,
                    statusReceiver);
            waitForInstallConstraints(packageNames, constraints,
                    localIntentSender.getIntentSender(), timeoutMillis);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    private static final class LocalIntentSender extends BroadcastReceiver {

        private final Context mContext;
        private final IntentSender mStatusReceiver;
        private final int mSessionId;
        private final IPackageInstallerSession mSession;

        LocalIntentSender(Context context, int sessionId, IPackageInstallerSession session,
                IntentSender statusReceiver) {
            mContext = context;
            mSessionId = sessionId;
            mSession = session;
            mStatusReceiver = statusReceiver;
        }

        private IntentSender getIntentSender() {
            Intent intent = new Intent(ACTION_WAIT_INSTALL_CONSTRAINTS).setPackage(
                    mContext.getPackageName());
            mContext.registerReceiver(this, new IntentFilter(ACTION_WAIT_INSTALL_CONSTRAINTS),
                    Context.RECEIVER_EXPORTED);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent,
                    PendingIntent.FLAG_MUTABLE);
            return pendingIntent.getIntentSender();
        }

        @Override
                public void send(int code, Intent intent, String resolvedType,
                        IBinder allowlistToken, IIntentReceiver finishedReceiver,
                        String requiredPermission, Bundle options)  {
                    var result = intent.getParcelableExtra(
        public void onReceive(Context context, Intent intent) {
            InstallConstraintsResult result = intent.getParcelableExtra(
                    PackageInstaller.EXTRA_INSTALL_CONSTRAINTS_RESULT,
                    InstallConstraintsResult.class);
            try {
                if (result.areAllConstraintsSatisfied()) {
                            session.commit(statusReceiver, false);
                    mSession.commit(mStatusReceiver, false);
                } else {
                    // timeout
                    final Intent fillIn = new Intent();
                            fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
                    fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId);
                    fillIn.putExtra(PackageInstaller.EXTRA_STATUS, STATUS_FAILURE_TIMEOUT);
                    fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
                            "Install constraints not satisfied within timeout");
                            statusReceiver.sendIntent(
                                    ActivityThread.currentApplication(), 0, fillIn, null, null);
                    mStatusReceiver.sendIntent(ActivityThread.currentApplication(), 0, fillIn, null,
                            null);
                }
            } catch (Exception ignore) {
                // no-op
            } finally {
                unregisterReceiver();
            }
        }
            });
            waitForInstallConstraints(packageNames, constraints, intentSender, timeoutMillis);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();

        private void unregisterReceiver() {
            mContext.unregisterReceiver(this);
        }
    }