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

Commit ab263c26 authored by Jakob Schneider's avatar Jakob Schneider Committed by Android (Google) Code Review
Browse files

Merge "Create draft session during unarchival call and pass the sessionId as...

Merge "Create draft session during unarchival call and pass the sessionId as the unarchiveID. Later on this session is taken over by the installer." into main
parents b94c7a94 f7b9678e
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -3865,7 +3865,7 @@ package android.content.pm {
    method @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull java.io.File, int) throws android.content.pm.PackageInstaller.PackageParsingException;
    method @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull java.io.File, int) throws android.content.pm.PackageInstaller.PackageParsingException;
    method @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull android.os.ParcelFileDescriptor, @Nullable String, int) throws android.content.pm.PackageInstaller.PackageParsingException;
    method @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull android.os.ParcelFileDescriptor, @Nullable String, int) throws android.content.pm.PackageInstaller.PackageParsingException;
    method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void requestArchive(@NonNull String, @NonNull android.content.IntentSender) throws android.content.pm.PackageManager.NameNotFoundException;
    method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void requestArchive(@NonNull String, @NonNull android.content.IntentSender) throws android.content.pm.PackageManager.NameNotFoundException;
    method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public void requestUnarchive(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
    method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public void requestUnarchive(@NonNull String) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException;
    method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
    method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
    field public static final String ACTION_CONFIRM_INSTALL = "android.content.pm.action.CONFIRM_INSTALL";
    field public static final String ACTION_CONFIRM_INSTALL = "android.content.pm.action.CONFIRM_INSTALL";
    field public static final String ACTION_CONFIRM_PRE_APPROVAL = "android.content.pm.action.CONFIRM_PRE_APPROVAL";
    field public static final String ACTION_CONFIRM_PRE_APPROVAL = "android.content.pm.action.CONFIRM_PRE_APPROVAL";
@@ -3877,6 +3877,7 @@ package android.content.pm {
    field public static final String EXTRA_LEGACY_STATUS = "android.content.pm.extra.LEGACY_STATUS";
    field public static final String EXTRA_LEGACY_STATUS = "android.content.pm.extra.LEGACY_STATUS";
    field @Deprecated public static final String EXTRA_RESOLVED_BASE_PATH = "android.content.pm.extra.RESOLVED_BASE_PATH";
    field @Deprecated public static final String EXTRA_RESOLVED_BASE_PATH = "android.content.pm.extra.RESOLVED_BASE_PATH";
    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ALL_USERS = "android.content.pm.extra.UNARCHIVE_ALL_USERS";
    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ALL_USERS = "android.content.pm.extra.UNARCHIVE_ALL_USERS";
    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ID = "android.content.pm.extra.UNARCHIVE_ID";
    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_PACKAGE_NAME = "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME";
    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_PACKAGE_NAME = "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME";
    field public static final int LOCATION_DATA_APP = 0; // 0x0
    field public static final int LOCATION_DATA_APP = 0; // 0x0
    field public static final int LOCATION_MEDIA_DATA = 2; // 0x2
    field public static final int LOCATION_MEDIA_DATA = 2; // 0x2
@@ -3933,6 +3934,7 @@ package android.content.pm {
    method public void setRequestDowngrade(boolean);
    method public void setRequestDowngrade(boolean);
    method @FlaggedApi("android.content.pm.rollback_lifetime") @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void setRollbackLifetimeMillis(long);
    method @FlaggedApi("android.content.pm.rollback_lifetime") @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void setRollbackLifetimeMillis(long);
    method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged();
    method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged();
    method @FlaggedApi("android.content.pm.archiving") public void setUnarchiveId(int);
  }
  }
  public class PackageItemInfo {
  public class PackageItemInfo {
+39 −1
Original line number Original line Diff line number Diff line
@@ -362,6 +362,19 @@ public class PackageInstaller {
    public static final String EXTRA_UNARCHIVE_PACKAGE_NAME =
    public static final String EXTRA_UNARCHIVE_PACKAGE_NAME =
            "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME";
            "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME";


    /**
     * Extra field for the unarchive ID. Sent as
     * part of the {@link android.content.Intent#ACTION_UNARCHIVE_PACKAGE} intent.
     *
     * @see Session#setUnarchiveId(int)
     *
     * @hide
     */
    @SystemApi
    @FlaggedApi(Flags.FLAG_ARCHIVING)
    public static final String EXTRA_UNARCHIVE_ID =
            "android.content.pm.extra.UNARCHIVE_ID";

    /**
    /**
     * If true, the requestor of the unarchival has specified that the app should be unarchived
     * If true, the requestor of the unarchival has specified that the app should be unarchived
     * for {@link android.os.UserHandle#ALL}.
     * for {@link android.os.UserHandle#ALL}.
@@ -2268,6 +2281,8 @@ public class PackageInstaller {
     * @throws PackageManager.NameNotFoundException If {@code packageName} isn't found or not
     * @throws PackageManager.NameNotFoundException If {@code packageName} isn't found or not
     *                                              visible to the caller or if the package has no
     *                                              visible to the caller or if the package has no
     *                                              installer on the device anymore to unarchive it.
     *                                              installer on the device anymore to unarchive it.
     * @throws IOException If parameters were unsatisfiable, such as lack of disk space.
     *
     * @hide
     * @hide
     */
     */
    @RequiresPermission(anyOf = {
    @RequiresPermission(anyOf = {
@@ -2276,11 +2291,12 @@ public class PackageInstaller {
    @SystemApi
    @SystemApi
    @FlaggedApi(Flags.FLAG_ARCHIVING)
    @FlaggedApi(Flags.FLAG_ARCHIVING)
    public void requestUnarchive(@NonNull String packageName)
    public void requestUnarchive(@NonNull String packageName)
            throws PackageManager.NameNotFoundException {
            throws IOException, PackageManager.NameNotFoundException {
        try {
        try {
            mInstaller.requestUnarchive(packageName, mInstallerPackageName,
            mInstaller.requestUnarchive(packageName, mInstallerPackageName,
                    new UserHandle(mUserId));
                    new UserHandle(mUserId));
        } catch (ParcelableException e) {
        } catch (ParcelableException e) {
            e.maybeRethrow(IOException.class);
            e.maybeRethrow(PackageManager.NameNotFoundException.class);
            e.maybeRethrow(PackageManager.NameNotFoundException.class);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
            throw e.rethrowFromSystemServer();
@@ -2548,6 +2564,8 @@ public class PackageInstaller {
        public boolean applicationEnabledSettingPersistent = false;
        public boolean applicationEnabledSettingPersistent = false;
        /** {@hide} */
        /** {@hide} */
        public int developmentInstallFlags = 0;
        public int developmentInstallFlags = 0;
        /** {@hide} */
        public int unarchiveId = -1;


        private final ArrayMap<String, Integer> mPermissionStates;
        private final ArrayMap<String, Integer> mPermissionStates;


@@ -2599,6 +2617,7 @@ public class PackageInstaller {
            packageSource = source.readInt();
            packageSource = source.readInt();
            applicationEnabledSettingPersistent = source.readBoolean();
            applicationEnabledSettingPersistent = source.readBoolean();
            developmentInstallFlags = source.readInt();
            developmentInstallFlags = source.readInt();
            unarchiveId = source.readInt();
        }
        }


        /** {@hide} */
        /** {@hide} */
@@ -2632,6 +2651,7 @@ public class PackageInstaller {
            ret.packageSource = packageSource;
            ret.packageSource = packageSource;
            ret.applicationEnabledSettingPersistent = applicationEnabledSettingPersistent;
            ret.applicationEnabledSettingPersistent = applicationEnabledSettingPersistent;
            ret.developmentInstallFlags = developmentInstallFlags;
            ret.developmentInstallFlags = developmentInstallFlags;
            ret.unarchiveId = unarchiveId;
            return ret;
            return ret;
        }
        }


@@ -3270,6 +3290,22 @@ public class PackageInstaller {
            }
            }
        }
        }


        /**
         * Used to set the unarchive ID received as part of an
         * {@link Intent#ACTION_UNARCHIVE_PACKAGE}.
         *
         * <p> The ID should be retrieved from the unarchive intent and passed into the
         * session that's being created to unarchive the app in question. Used to link the unarchive
         * intent and the install session to disambiguate.
         *
         * @hide
         */
        @FlaggedApi(Flags.FLAG_ARCHIVING)
        @SystemApi
        public void setUnarchiveId(int unarchiveId) {
            this.unarchiveId = unarchiveId;
        }

        /** @hide */
        /** @hide */
        @NonNull
        @NonNull
        public ArrayMap<String, Integer> getPermissionStates() {
        public ArrayMap<String, Integer> getPermissionStates() {
@@ -3327,6 +3363,7 @@ public class PackageInstaller {
            pw.printPair("applicationEnabledSettingPersistent",
            pw.printPair("applicationEnabledSettingPersistent",
                    applicationEnabledSettingPersistent);
                    applicationEnabledSettingPersistent);
            pw.printHexPair("developmentInstallFlags", developmentInstallFlags);
            pw.printHexPair("developmentInstallFlags", developmentInstallFlags);
            pw.printPair("unarchiveId", unarchiveId);
            pw.println();
            pw.println();
        }
        }


@@ -3370,6 +3407,7 @@ public class PackageInstaller {
            dest.writeInt(packageSource);
            dest.writeInt(packageSource);
            dest.writeBoolean(applicationEnabledSettingPersistent);
            dest.writeBoolean(applicationEnabledSettingPersistent);
            dest.writeInt(developmentInstallFlags);
            dest.writeInt(developmentInstallFlags);
            dest.writeInt(unarchiveId);
        }
        }


        public static final Parcelable.Creator<SessionParams>
        public static final Parcelable.Creator<SessionParams>
+11 −0
Original line number Original line Diff line number Diff line
@@ -1481,6 +1481,7 @@ public abstract class PackageManager {
            INSTALL_STAGED,
            INSTALL_STAGED,
            INSTALL_REQUEST_UPDATE_OWNERSHIP,
            INSTALL_REQUEST_UPDATE_OWNERSHIP,
            INSTALL_IGNORE_DEXOPT_PROFILE,
            INSTALL_IGNORE_DEXOPT_PROFILE,
            INSTALL_UNARCHIVE_DRAFT,
    })
    })
    @Retention(RetentionPolicy.SOURCE)
    @Retention(RetentionPolicy.SOURCE)
    public @interface InstallFlags {}
    public @interface InstallFlags {}
@@ -1724,6 +1725,16 @@ public abstract class PackageManager {
     */
     */
    public static final int INSTALL_IGNORE_DEXOPT_PROFILE = 1 << 28;
    public static final int INSTALL_IGNORE_DEXOPT_PROFILE = 1 << 28;


    /**
     * If set, then the session is a draft session created for an upcoming unarchival by its
     * installer.
     *
     * @see PackageInstaller#requestUnarchive(String)
     *
     * @hide
     */
    public static final int INSTALL_UNARCHIVE_DRAFT = 1 << 29;

    /**
    /**
     * Flag parameter for {@link #installPackage} to force a non-staged update of an APEX. This is
     * Flag parameter for {@link #installPackage} to force a non-staged update of an APEX. This is
     * a development-only feature and should not be used on end user devices.
     * a development-only feature and should not be used on end user devices.
+44 −3
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.content.pm.ArchivedActivityInfo.bytesFromBitmap;
import static android.content.pm.ArchivedActivityInfo.drawableToBitmap;
import static android.content.pm.ArchivedActivityInfo.drawableToBitmap;
import static android.content.pm.PackageManager.DELETE_ARCHIVE;
import static android.content.pm.PackageManager.DELETE_ARCHIVE;
import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
import static android.content.pm.PackageManager.INSTALL_UNARCHIVE_DRAFT;
import static android.os.PowerExemptionManager.REASON_PACKAGE_UNARCHIVE;
import static android.os.PowerExemptionManager.REASON_PACKAGE_UNARCHIVE;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;


@@ -61,6 +62,7 @@ import android.os.Process;
import android.os.SELinux;
import android.os.SELinux;
import android.os.UserHandle;
import android.os.UserHandle;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.ExceptionUtils;
import android.util.Slog;
import android.util.Slog;


import com.android.internal.R;
import com.android.internal.R;
@@ -398,7 +400,45 @@ public class PackageArchiver {
                                    packageName)));
                                    packageName)));
        }
        }


        mPm.mHandler.post(() -> unarchiveInternal(packageName, userHandle, installerPackage));
        int draftSessionId;
        try {
            draftSessionId = createDraftSession(packageName, installerPackage, userId);
        } catch (RuntimeException e) {
            if (e.getCause() instanceof IOException) {
                throw ExceptionUtils.wrap((IOException) e.getCause());
            } else {
                throw e;
            }
        }

        mPm.mHandler.post(
                () -> unarchiveInternal(packageName, userHandle, installerPackage, draftSessionId));
    }

    private int createDraftSession(String packageName, String installerPackage, int userId) {
        PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(
                PackageInstaller.SessionParams.MODE_FULL_INSTALL);
        sessionParams.setAppPackageName(packageName);
        sessionParams.installFlags = INSTALL_UNARCHIVE_DRAFT;
        int installerUid = mPm.snapshotComputer().getPackageUid(installerPackage, 0, userId);
        // Handles case of repeated unarchival calls for the same package.
        int existingSessionId = mPm.mInstallerService.getExistingDraftSessionId(installerUid,
                sessionParams,
                userId);
        if (existingSessionId != PackageInstaller.SessionInfo.INVALID_ID) {
            return existingSessionId;
        }

        int sessionId = Binder.withCleanCallingIdentity(
                () -> mPm.mInstallerService.createSessionInternal(
                        sessionParams,
                        installerPackage, mContext.getAttributionTag(),
                        installerUid,
                        userId));
        // TODO(b/297358628) Also cleanup sessions upon device restart.
        mPm.mHandler.postDelayed(() -> mPm.mInstallerService.cleanupDraftIfUnclaimed(sessionId),
                getUnarchiveForegroundTimeout());
        return sessionId;
    }
    }


    /**
    /**
@@ -487,10 +527,11 @@ public class PackageArchiver {
                    android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND},
                    android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND},
            conditional = true)
            conditional = true)
    private void unarchiveInternal(String packageName, UserHandle userHandle,
    private void unarchiveInternal(String packageName, UserHandle userHandle,
            String installerPackage) {
            String installerPackage, int unarchiveId) {
        int userId = userHandle.getIdentifier();
        int userId = userHandle.getIdentifier();
        Intent unarchiveIntent = new Intent(Intent.ACTION_UNARCHIVE_PACKAGE);
        Intent unarchiveIntent = new Intent(Intent.ACTION_UNARCHIVE_PACKAGE);
        unarchiveIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        unarchiveIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        unarchiveIntent.putExtra(PackageInstaller.EXTRA_UNARCHIVE_ID, unarchiveId);
        unarchiveIntent.putExtra(PackageInstaller.EXTRA_UNARCHIVE_PACKAGE_NAME, packageName);
        unarchiveIntent.putExtra(PackageInstaller.EXTRA_UNARCHIVE_PACKAGE_NAME, packageName);
        unarchiveIntent.putExtra(PackageInstaller.EXTRA_UNARCHIVE_ALL_USERS,
        unarchiveIntent.putExtra(PackageInstaller.EXTRA_UNARCHIVE_ALL_USERS,
                userId == UserHandle.USER_ALL);
                userId == UserHandle.USER_ALL);
+93 −20
Original line number Original line Diff line number Diff line
@@ -18,7 +18,9 @@ package com.android.server.pm;


import static android.app.admin.DevicePolicyResources.Strings.Core.PACKAGE_DELETED_BY_DO;
import static android.app.admin.DevicePolicyResources.Strings.Core.PACKAGE_DELETED_BY_DO;
import static android.content.pm.PackageInstaller.LOCATION_DATA_APP;
import static android.content.pm.PackageInstaller.LOCATION_DATA_APP;
import static android.content.pm.PackageManager.INSTALL_UNARCHIVE_DRAFT;
import static android.os.Process.INVALID_UID;
import static android.os.Process.INVALID_UID;
import static android.os.Process.SYSTEM_UID;


import static com.android.server.pm.PackageManagerService.SHELL_PACKAGE_NAME;
import static com.android.server.pm.PackageManagerService.SHELL_PACKAGE_NAME;


@@ -633,17 +635,18 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                        + "to use a data loader");
                        + "to use a data loader");
            }
            }


            // Draft sessions cannot be created through the public API.
            params.installFlags &= ~PackageManager.INSTALL_UNARCHIVE_DRAFT;
            return createSessionInternal(params, installerPackageName, callingAttributionTag,
            return createSessionInternal(params, installerPackageName, callingAttributionTag,
                    userId);
                    Binder.getCallingUid(), userId);
        } catch (IOException e) {
        } catch (IOException e) {
            throw ExceptionUtils.wrap(e);
            throw ExceptionUtils.wrap(e);
        }
        }
    }
    }


    private int createSessionInternal(SessionParams params, String installerPackageName,
    int createSessionInternal(SessionParams params, String installerPackageName,
            String installerAttributionTag, int userId)
            String installerAttributionTag, int callingUid, int userId)
            throws IOException {
            throws IOException {
        final int callingUid = Binder.getCallingUid();
        final Computer snapshot = mPm.snapshotComputer();
        final Computer snapshot = mPm.snapshotComputer();
        snapshot.enforceCrossUserPermission(callingUid, userId, true, true, "createSession");
        snapshot.enforceCrossUserPermission(callingUid, userId, true, true, "createSession");


@@ -692,7 +695,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
            // initiatingPackageName
            // initiatingPackageName
            installerPackageName = SHELL_PACKAGE_NAME;
            installerPackageName = SHELL_PACKAGE_NAME;
        } else {
        } else {
            if (callingUid != Process.SYSTEM_UID) {
            if (callingUid != SYSTEM_UID) {
                // The supplied installerPackageName must always belong to the calling app.
                // The supplied installerPackageName must always belong to the calling app.
                mAppOps.checkPackage(callingUid, installerPackageName);
                mAppOps.checkPackage(callingUid, installerPackageName);
            }
            }
@@ -707,6 +710,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements


            params.installFlags &= ~PackageManager.INSTALL_FROM_ADB;
            params.installFlags &= ~PackageManager.INSTALL_FROM_ADB;
            params.installFlags &= ~PackageManager.INSTALL_ALL_USERS;
            params.installFlags &= ~PackageManager.INSTALL_ALL_USERS;
            params.installFlags &= ~PackageManager.INSTALL_ARCHIVED;
            params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
            params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
            if ((params.installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0
            if ((params.installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0
                    && !mPm.isCallerVerifier(snapshot, callingUid)) {
                    && !mPm.isCallerVerifier(snapshot, callingUid)) {
@@ -903,6 +907,16 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
            }
            }
        }
        }


        int requestedInstallerPackageUid = INVALID_UID;
        if (requestedInstallerPackageName != null) {
            requestedInstallerPackageUid = snapshot.getPackageUid(requestedInstallerPackageName,
                    0 /* flags */, userId);
        }
        if (requestedInstallerPackageUid == INVALID_UID) {
            // Requested installer package is invalid, reset it
            requestedInstallerPackageName = null;
        }

        final int sessionId;
        final int sessionId;
        final PackageInstallerSession session;
        final PackageInstallerSession session;
        synchronized (mSessions) {
        synchronized (mSessions) {
@@ -923,8 +937,11 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                throw new IllegalStateException(
                throw new IllegalStateException(
                        "Too many historical sessions for UID " + callingUid);
                        "Too many historical sessions for UID " + callingUid);
            }
            }
            final int existingDraftSessionId =
                    getExistingDraftSessionId(requestedInstallerPackageUid, params, userId);


            sessionId = allocateSessionIdLocked();
            sessionId = existingDraftSessionId != SessionInfo.INVALID_ID ? existingDraftSessionId
                    : allocateSessionIdLocked();
        }
        }


        final long createdMillis = System.currentTimeMillis();
        final long createdMillis = System.currentTimeMillis();
@@ -945,15 +962,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                params.forceQueryableOverride = false;
                params.forceQueryableOverride = false;
            }
            }
        }
        }
        int requestedInstallerPackageUid = INVALID_UID;
        if (requestedInstallerPackageName != null) {
            requestedInstallerPackageUid = snapshot.getPackageUid(requestedInstallerPackageName,
                    0 /* flags */, userId);
        }
        if (requestedInstallerPackageUid == INVALID_UID) {
            // Requested installer package is invalid, reset it
            requestedInstallerPackageName = null;
        }


        final var dpmi = LocalServices.getService(DevicePolicyManagerInternal.class);
        final var dpmi = LocalServices.getService(DevicePolicyManagerInternal.class);
        if (dpmi != null && dpmi.isUserOrganizationManaged(userId)) {
        if (dpmi != null && dpmi.isUserOrganizationManaged(userId)) {
@@ -988,6 +996,68 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        return sessionId;
        return sessionId;
    }
    }


    int getExistingDraftSessionId(int installerUid,
            @NonNull SessionParams sessionParams, int userId) {
        synchronized (mSessions) {
            return getExistingDraftSessionIdInternal(installerUid, sessionParams, userId);
        }
    }

    @GuardedBy("mSessions")
    private int getExistingDraftSessionIdInternal(int installerUid,
            SessionParams sessionParams, int userId) {
        String appPackageName = sessionParams.appPackageName;
        if (!Flags.archiving() || installerUid == INVALID_UID || appPackageName == null) {
            return SessionInfo.INVALID_ID;
        }

        PackageStateInternal ps = mPm.snapshotComputer().getPackageStateInternal(appPackageName,
                SYSTEM_UID);
        if (ps == null || !PackageArchiver.isArchived(ps.getUserStateOrDefault(userId))) {
            return SessionInfo.INVALID_ID;
        }

        // If unarchiveId is present we match based on it. If unarchiveId is missing we
        // choose a draft session too to ensure we don't end up with duplicate sessions
        // if the installer doesn't set this field.
        if (sessionParams.unarchiveId > 0) {
            PackageInstallerSession session = mSessions.get(sessionParams.unarchiveId);
            if (session != null
                    && isValidDraftSession(session, appPackageName, installerUid, userId)) {
                return session.sessionId;
            }

            return SessionInfo.INVALID_ID;
        }

        for (int i = 0; i < mSessions.size(); i++) {
            PackageInstallerSession session = mSessions.valueAt(i);
            if (session != null
                    && isValidDraftSession(session, appPackageName, installerUid, userId)) {
                return session.sessionId;
            }
        }

        return SessionInfo.INVALID_ID;
    }

    private boolean isValidDraftSession(@NonNull PackageInstallerSession session,
            @NonNull String appPackageName, int installerUid, int userId) {
        return (session.getInstallFlags() & PackageManager.INSTALL_UNARCHIVE_DRAFT) != 0
                && appPackageName.equals(session.params.appPackageName)
                && session.userId == userId
                && installerUid == session.getInstallerUid();
    }

    void cleanupDraftIfUnclaimed(int sessionId) {
        synchronized (mSessions) {
            PackageInstallerSession session = mPm.mInstallerService.getSession(sessionId);
            if (session != null && (session.getInstallFlags() & INSTALL_UNARCHIVE_DRAFT) != 0) {
                session.abandon();
            }
        }
    }

    private boolean isStagedInstallerAllowed(String installerName) {
    private boolean isStagedInstallerAllowed(String installerName) {
        return SystemConfig.getInstance().getWhitelistedStagedInstallers().contains(installerName);
        return SystemConfig.getInstance().getWhitelistedStagedInstallers().contains(installerName);
    }
    }
@@ -1053,7 +1123,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
    }
    }


    private boolean checkOpenSessionAccess(final PackageInstallerSession session) {
    private boolean checkOpenSessionAccess(final PackageInstallerSession session) {
        if (session == null) {
        if (session == null
                || (session.getInstallFlags() & PackageManager.INSTALL_UNARCHIVE_DRAFT) != 0) {
            return false;
            return false;
        }
        }
        if (isCallingUidOwner(session)) {
        if (isCallingUidOwner(session)) {
@@ -1248,10 +1319,12 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                final PackageInstallerSession session = mSessions.valueAt(i);
                final PackageInstallerSession session = mSessions.valueAt(i);


                SessionInfo info =
                SessionInfo info =
                        session.generateInfoForCaller(false /*withIcon*/, Process.SYSTEM_UID);
                        session.generateInfoForCaller(false /*withIcon*/, SYSTEM_UID);
                if (Objects.equals(info.getInstallerPackageName(), installerPackageName)
                if (Objects.equals(info.getInstallerPackageName(), installerPackageName)
                        && session.userId == userId && !session.hasParentSessionId()
                        && session.userId == userId && !session.hasParentSessionId()
                        && isCallingUidOwner(session)) {
                        && isCallingUidOwner(session)
                        && (session.getInstallFlags() & PackageManager.INSTALL_UNARCHIVE_DRAFT)
                            == 0) {
                    result.add(info);
                    result.add(info);
                }
                }
            }
            }
@@ -1602,7 +1675,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        PackageInstallerSession session = null;
        PackageInstallerSession session = null;
        try {
        try {
            var sessionId = createSessionInternal(params, installerPackageName,
            var sessionId = createSessionInternal(params, installerPackageName,
                    null /*installerAttributionTag*/, userId);
                    null /*installerAttributionTag*/, Binder.getCallingUid(), userId);
            session = openSessionInternal(sessionId);
            session = openSessionInternal(sessionId);
            session.addFile(LOCATION_DATA_APP, "base", 0 /*lengthBytes*/, metadata.toByteArray(),
            session.addFile(LOCATION_DATA_APP, "base", 0 /*lengthBytes*/, metadata.toByteArray(),
                    null /*signature*/);
                    null /*signature*/);
@@ -2017,7 +2090,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                // we don't scrub the data here as this is sent only to the installer several
                // we don't scrub the data here as this is sent only to the installer several
                // privileged system packages
                // privileged system packages
                sendSessionUpdatedBroadcast(
                sendSessionUpdatedBroadcast(
                        session.generateInfoForCaller(false/*icon*/, Process.SYSTEM_UID),
                        session.generateInfoForCaller(false/*icon*/, SYSTEM_UID),
                        session.userId);
                        session.userId);
            }
            }
        }
        }
Loading