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

Commit e677b471 authored by William Loh's avatar William Loh
Browse files

Add API to skip application enable in install flow

This CL addes a new API to PackageInstaller.SessionParams that can be
used to skip the app enable step during the package install flow. This
can be used by installers to keep the app's existing enabled state
after a upgrade instead of setting it to enabled by default.

This also corrects the variable userId used in the enable step to
currentUserId that was preventing it from enabling the app when
installed for all users.

Bug: 244430570
Test: atest PackageManagerShellCommandTest#testAppUpdateSkipEnable
Change-Id: I42b003f8c42a7f8c45a581bd9383c78090462d0f
parent 90cef8f4
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -11736,6 +11736,7 @@ package android.content.pm {
    method @NonNull public int[] getChildSessionIds();
    method @NonNull public String[] getNames() throws java.io.IOException;
    method public int getParentSessionId();
    method public boolean isKeepApplicationEnabledSetting();
    method public boolean isMultiPackage();
    method public boolean isStaged();
    method @NonNull public java.io.InputStream openRead(@NonNull String) throws java.io.IOException;
@@ -11787,6 +11788,7 @@ package android.content.pm {
    method public boolean hasParentSessionId();
    method public boolean isActive();
    method public boolean isCommitted();
    method public boolean isKeepApplicationEnabledSetting();
    method public boolean isMultiPackage();
    method public boolean isSealed();
    method public boolean isStaged();
@@ -11819,6 +11821,7 @@ package android.content.pm {
    method public void setInstallLocation(int);
    method public void setInstallReason(int);
    method public void setInstallScenario(int);
    method public void setKeepApplicationEnabledSetting();
    method public void setMultiPackage();
    method public void setOriginatingUid(int);
    method public void setOriginatingUri(@Nullable android.net.Uri);
+2 −0
Original line number Diff line number Diff line
@@ -61,4 +61,6 @@ interface IPackageInstallerSession {
    int getInstallFlags();

    void requestUserPreapproval(in PackageInstaller.PreapprovalDetails details, in IntentSender statusReceiver);

    boolean isKeepApplicationEnabledSetting();
}
+39 −0
Original line number Diff line number Diff line
@@ -1717,6 +1717,18 @@ public class PackageInstaller {
                e.rethrowFromSystemServer();
            }
        }

        /**
         * @return {@code true} if this session will keep the existing application enabled setting
         * after installation.
         */
        public boolean isKeepApplicationEnabledSetting() {
            try {
                return mSession.isKeepApplicationEnabledSetting();
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

    /**
@@ -1855,6 +1867,8 @@ public class PackageInstaller {
        public boolean forceQueryableOverride;
        /** {@hide} */
        public int requireUserAction = USER_ACTION_UNSPECIFIED;
        /** {@hide} */
        public boolean keepApplicationEnabledSetting = false;

        /**
         * Construct parameters for a new package install session.
@@ -1899,6 +1913,7 @@ public class PackageInstaller {
            rollbackDataPolicy = source.readInt();
            requireUserAction = source.readInt();
            packageSource = source.readInt();
            keepApplicationEnabledSetting = source.readBoolean();
        }

        /** {@hide} */
@@ -1929,6 +1944,7 @@ public class PackageInstaller {
            ret.rollbackDataPolicy = rollbackDataPolicy;
            ret.requireUserAction = requireUserAction;
            ret.packageSource = packageSource;
            ret.keepApplicationEnabledSetting = keepApplicationEnabledSetting;
            return ret;
        }

@@ -2415,6 +2431,14 @@ public class PackageInstaller {
            this.installScenario = installScenario;
        }

        /**
         * Request to keep the original application enabled setting. This will prevent the
         * application from being enabled if it was previously in a disabled state.
         */
        public void setKeepApplicationEnabledSetting() {
            this.keepApplicationEnabledSetting = true;
        }

        /** {@hide} */
        public void dump(IndentingPrintWriter pw) {
            pw.printPair("mode", mode);
@@ -2443,6 +2467,7 @@ public class PackageInstaller {
            pw.printPair("requiredInstalledVersionCode", requiredInstalledVersionCode);
            pw.printPair("dataLoaderParams", dataLoaderParams);
            pw.printPair("rollbackDataPolicy", rollbackDataPolicy);
            pw.printPair("keepApplicationEnabledSetting", keepApplicationEnabledSetting);
            pw.println();
        }

@@ -2483,6 +2508,7 @@ public class PackageInstaller {
            dest.writeInt(rollbackDataPolicy);
            dest.writeInt(requireUserAction);
            dest.writeInt(packageSource);
            dest.writeBoolean(keepApplicationEnabledSetting);
        }

        public static final Parcelable.Creator<SessionParams>
@@ -2684,6 +2710,9 @@ public class PackageInstaller {
        /** @hide */
        public boolean isPreapprovalRequested;

        /** @hide */
        public boolean keepApplicationEnabledSetting;

        /** {@hide} */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public SessionInfo() {
@@ -2737,6 +2766,7 @@ public class PackageInstaller {
            requireUserAction = source.readInt();
            installerUid = source.readInt();
            packageSource = source.readInt();
            keepApplicationEnabledSetting = source.readBoolean();
        }

        /**
@@ -3268,6 +3298,14 @@ public class PackageInstaller {
            return installerUid;
        }

        /**
         * Returns {@code true} if this session will keep the existing application enabled setting
         * after installation.
         */
        public boolean isKeepApplicationEnabledSetting() {
            return keepApplicationEnabledSetting;
        }

        @Override
        public int describeContents() {
            return 0;
@@ -3317,6 +3355,7 @@ public class PackageInstaller {
            dest.writeInt(requireUserAction);
            dest.writeInt(installerUid);
            dest.writeInt(packageSource);
            dest.writeBoolean(keepApplicationEnabledSetting);
        }

        public static final Parcelable.Creator<SessionInfo>
+5 −2
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ final class InstallArgs {
    final boolean mForceQueryableOverride;
    final int mDataLoaderType;
    final int mPackageSource;
    final boolean mKeepApplicationEnabledSetting;

    // The list of instruction sets supported by this app. This is currently
    // only used during the rmdex() phase to clean up resources. We can get rid of this
@@ -72,7 +73,8 @@ final class InstallArgs {
            List<String> allowlistedRestrictedPermissions,
            int autoRevokePermissionsMode, String traceMethod, int traceCookie,
            SigningDetails signingDetails, int installReason, int installScenario,
            boolean forceQueryableOverride, int dataLoaderType, int packageSource) {
            boolean forceQueryableOverride, int dataLoaderType, int packageSource,
            boolean keepApplicationEnabledSetting) {
        mOriginInfo = originInfo;
        mMoveInfo = moveInfo;
        mInstallFlags = installFlags;
@@ -93,6 +95,7 @@ final class InstallArgs {
        mForceQueryableOverride = forceQueryableOverride;
        mDataLoaderType = dataLoaderType;
        mPackageSource = packageSource;
        mKeepApplicationEnabledSetting = keepApplicationEnabledSetting;
    }

    /**
@@ -104,7 +107,7 @@ final class InstallArgs {
                null, null, instructionSets, null, null, null, MODE_DEFAULT, null, 0,
                SigningDetails.UNKNOWN, PackageManager.INSTALL_REASON_UNKNOWN,
                PackageManager.INSTALL_SCENARIO_DEFAULT, false, DataLoaderType.NONE,
                PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
                PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED, false);
        mCodeFile = (codePath != null) ? new File(codePath) : null;
    }

+12 −5
Original line number Diff line number Diff line
@@ -2036,7 +2036,8 @@ final class InstallPackageHelper {
                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
                    }
                    // Enable system package for requested users
                    if (installedForUsers != null) {
                    if (installedForUsers != null
                            && !installRequest.isKeepApplicationEnabledSetting()) {
                        for (int origUserId : installedForUsers) {
                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
@@ -2086,18 +2087,24 @@ final class InstallPackageHelper {

                if (userId != UserHandle.USER_ALL) {
                    // It's implied that when a user requests installation, they want the app to
                    // be installed and enabled.
                    // be installed and enabled. The caller, however, can explicitly specify to
                    // keep the existing enabled state.
                    ps.setInstalled(true, userId);
                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
                    if (!installRequest.isKeepApplicationEnabledSetting()) {
                        ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId,
                                installerPackageName);
                    }
                } else if (allUsers != null) {
                    // The caller explicitly specified INSTALL_ALL_USERS flag.
                    // Thus, updating the settings to install the app for all users.
                    for (int currentUserId : allUsers) {
                        ps.setInstalled(true, currentUserId);
                        ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId,
                        if (!installRequest.isKeepApplicationEnabledSetting()) {
                            ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, currentUserId,
                                    installerPackageName);
                        }
                    }
                }

                mPm.mSettings.addInstallerPackageNames(ps.getInstallSource());

Loading