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

Commit 12baf066 authored by Patrick Baumann's avatar Patrick Baumann Committed by Automerger Merge Worker
Browse files

Merge "Exposes way to bypass user action on update" into sc-dev am: 47c338bf

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13891756

Change-Id: I0e33d30d46d867376da10073d606d8687b3f90fd
parents cbe7c16e 47c338bf
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ package android {
    field public static final String TRANSMIT_IR = "android.permission.TRANSMIT_IR";
    field public static final String UNINSTALL_SHORTCUT = "com.android.launcher.permission.UNINSTALL_SHORTCUT";
    field public static final String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
    field public static final String UPDATE_PACKAGES_WITHOUT_USER_ACTION = "android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION";
    field public static final String USE_BIOMETRIC = "android.permission.USE_BIOMETRIC";
    field @Deprecated public static final String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
    field public static final String USE_FULL_SCREEN_INTENT = "android.permission.USE_FULL_SCREEN_INTENT";
@@ -12356,6 +12357,7 @@ package android.content.pm {
    method public int getParentSessionId();
    method public float getProgress();
    method @Nullable public android.net.Uri getReferrerUri();
    method public int getRequireUserAction();
    method public int getSessionId();
    method public long getSize();
    method public int getStagedSessionErrorCode();
@@ -12380,6 +12382,9 @@ package android.content.pm {
    field public static final int STAGED_SESSION_NO_ERROR = 0; // 0x0
    field public static final int STAGED_SESSION_UNKNOWN = 3; // 0x3
    field public static final int STAGED_SESSION_VERIFICATION_FAILED = 1; // 0x1
    field public static final int USER_ACTION_NOT_REQUIRED = 2; // 0x2
    field public static final int USER_ACTION_REQUIRED = 1; // 0x1
    field public static final int USER_ACTION_UNSPECIFIED = 0; // 0x0
  }
  public static class PackageInstaller.SessionParams implements android.os.Parcelable {
@@ -12397,6 +12402,7 @@ package android.content.pm {
    method public void setOriginatingUid(int);
    method public void setOriginatingUri(@Nullable android.net.Uri);
    method public void setReferrerUri(@Nullable android.net.Uri);
    method public void setRequireUserAction(boolean);
    method public void setSize(long);
    method public void setWhitelistedRestrictedPermissions(@Nullable java.util.Set<java.lang.String>);
    method public void writeToParcel(android.os.Parcel, int);
+105 −0
Original line number Diff line number Diff line
@@ -1565,6 +1565,8 @@ public class PackageInstaller {
        public int rollbackDataPolicy = PackageManager.RollbackDataPolicy.RESTORE;
        /** {@hide} */
        public boolean forceQueryableOverride;
        /** {@hide} */
        public Boolean requireUserAction;

        /**
         * Construct parameters for a new package install session.
@@ -1607,6 +1609,12 @@ public class PackageInstaller {
                dataLoaderParams = new DataLoaderParams(dataLoaderParamsParcel);
            }
            rollbackDataPolicy = source.readInt();
            int requireUserActionInt = source.readInt();
            requireUserAction = requireUserActionInt == 0
                    ? Boolean.FALSE
                    : requireUserActionInt == 1
                            ? Boolean.TRUE : null;

        }

        /** {@hide} */
@@ -1635,6 +1643,7 @@ public class PackageInstaller {
            ret.requiredInstalledVersionCode = requiredInstalledVersionCode;
            ret.dataLoaderParams = dataLoaderParams;
            ret.rollbackDataPolicy = rollbackDataPolicy;
            ret.requireUserAction = requireUserAction;
            return ret;
        }

@@ -2028,6 +2037,41 @@ public class PackageInstaller {
            this.forceQueryableOverride = true;
        }

        /**
         * Optionally indicate whether user action should be required when the session is
         * committed.
         * <p>
         * Defaults to {@code true} for installers using the
         * {@link android.Manifest.permission#REQUEST_INSTALL_PACKAGES android.permission
         * #REQUEST_INSTALL_PACKAGES} permission, and {@code false} otherwise. When {@code true},
         * installers will receive a {@link #STATUS_PENDING_USER_ACTION} callback once the
         * session is committed, indicating that the user is required for the install to proceed.
         * <p>
         * For installers using the {@link android.Manifest.permission#REQUEST_INSTALL_PACKAGES
         * android.permission.REQUEST_INSTALL_PACKAGES} permission, user action will not be
         * required when the following conditions are met:
         *
         * <ul>
         *     <li>{@code requireUserAction} is set to {@code false}.</li>
         *     <li>The being installed targets {@link android.os.Build.VERSION_CODES#Q API 29} or
         *     higher.</li>
         *     <li>The installer is the {@link InstallSourceInfo#getInstallingPackageName()
         *     installer of record} of an existing version of the app (i.e.: this install session
         *     is an app update or the installer is updating itself).</li>
         *     <li>The installer declares the
         *     {@link android.Manifest.permission#UPDATE_PACKAGES_WITHOUT_USER_ACTION android
         *     .permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION} permission.</li>
         * </ul>
         * <p>
         * Note: The target API level requirement will advance in future Android versions.
         * Session owners should always be prepared to handle {@link #STATUS_PENDING_USER_ACTION}
         *
         * @param requireUserAction whether user action should be required.
         */
        public void setRequireUserAction(boolean requireUserAction) {
            this.requireUserAction = requireUserAction;
        }

        /**
         * Sets the install scenario for this session, which describes the expected user journey.
         */
@@ -2058,6 +2102,7 @@ public class PackageInstaller {
            pw.printPair("isMultiPackage", isMultiPackage);
            pw.printPair("isStaged", isStaged);
            pw.printPair("forceQueryable", forceQueryableOverride);
            pw.printPair("requireUserAction", requireUserAction);
            pw.printPair("requiredInstalledVersionCode", requiredInstalledVersionCode);
            pw.printPair("dataLoaderParams", dataLoaderParams);
            pw.printPair("rollbackDataPolicy", rollbackDataPolicy);
@@ -2099,6 +2144,10 @@ public class PackageInstaller {
                dest.writeParcelable(null, flags);
            }
            dest.writeInt(rollbackDataPolicy);
            dest.writeInt(requireUserAction == Boolean.TRUE
                    ? 1
                    : requireUserAction == Boolean.FALSE
                            ? 0 : 2);
        }

        public static final Parcelable.Creator<SessionParams>
@@ -2165,6 +2214,31 @@ public class PackageInstaller {
         */
        public static final int STAGED_SESSION_CONFLICT = 4;

        /** @hide */
        @IntDef(prefix = {"USER_ACTION"}, value = {
                USER_ACTION_UNSPECIFIED,
                USER_ACTION_REQUIRED,
                USER_ACTION_NOT_REQUIRED
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface UserActionRequirement {}

        /**
         * The installer did not calling {@link SessionParams#setRequireUserAction(boolean)} to
         * specify whether user action should be required for the install.
         */
        public static final int USER_ACTION_UNSPECIFIED = 0;
        /**
         * The installer called {@link SessionParams#setRequireUserAction(boolean)} with
         * {@code true} to require user action for the install to complete.
         */
        public static final int USER_ACTION_REQUIRED = 1;
        /**
         * The installer called {@link SessionParams#setRequireUserAction(boolean)} with
         * {@code false} to request that user action not be required for this install.
         */
        public static final int USER_ACTION_NOT_REQUIRED = 2;

        /** {@hide} */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
        public int sessionId;
@@ -2256,6 +2330,9 @@ public class PackageInstaller {
        /** {@hide} */
        public int rollbackDataPolicy;

        /** {@hide} */
        public Boolean requireUserAction;

        /** {@hide} */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public SessionInfo() {
@@ -2305,6 +2382,11 @@ public class PackageInstaller {
            isCommitted = source.readBoolean();
            rollbackDataPolicy = source.readInt();
            createdMillis = source.readLong();
            int requireUserActionInt = source.readInt();
            requireUserAction = requireUserActionInt == 0
                    ? Boolean.FALSE
                    : requireUserActionInt == 1
                            ? Boolean.TRUE : null;
        }

        /**
@@ -2804,6 +2886,25 @@ public class PackageInstaller {
            return updatedMillis;
        }

        /**
         * Whether user action was required by the installer.
         *
         * <p>
         * Note: a return value of {@code USER_ACTION_NOT_REQUIRED} does not guarantee that the
         * install will not result in user action.
         *
         * @return {@link #USER_ACTION_NOT_REQUIRED}, {@link #USER_ACTION_REQUIRED} or
         *         {@link #USER_ACTION_UNSPECIFIED}
         */
        @UserActionRequirement
        public int getRequireUserAction() {
            return requireUserAction == null
                    ? USER_ACTION_UNSPECIFIED
                    : requireUserAction == Boolean.TRUE
                            ? USER_ACTION_REQUIRED
                            : USER_ACTION_NOT_REQUIRED;
        }

        @Override
        public int describeContents() {
            return 0;
@@ -2849,6 +2950,10 @@ public class PackageInstaller {
            dest.writeBoolean(isCommitted);
            dest.writeInt(rollbackDataPolicy);
            dest.writeLong(createdMillis);
            dest.writeInt(requireUserAction == Boolean.TRUE
                    ? 1
                    : requireUserAction == Boolean.FALSE
                            ? 0 : 2);
        }

        public static final Parcelable.Creator<SessionInfo>
+3 −2
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ public class ApkLiteParseUtils {
            final String packagePath = packageFile.getAbsolutePath();
            return input.success(
                    new PackageLite(packagePath, baseApk.getPath(), baseApk, null,
                            null, null, null, null, null));
                            null, null, null, null, null, baseApk.getTargetSdkVersion()));
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
@@ -242,7 +242,8 @@ public class ApkLiteParseUtils {
                splitNameToFileName(baseApk)).getAbsolutePath() : baseApk.getPath();
        return input.success(
                new PackageLite(codePath, baseCodePath, baseApk, splitNames, isFeatureSplits,
                        usesSplitNames, configForSplits, splitCodePaths, splitRevisionCodes));
                        usesSplitNames, configForSplits, splitCodePaths, splitRevisionCodes,
                        baseApk.getTargetSdkVersion()));
    }

    /**
+11 −3
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ public class PackageLite {
    /** Major and minor version number of this package */
    private final int mVersionCodeMajor;
    private final int mVersionCode;
    private final int mTargetSdk;
    /** Revision code of base APK */
    private final int mBaseRevisionCode;
    /** Revision codes of any split APKs, ordered by parsed splitName */
@@ -99,7 +100,8 @@ public class PackageLite {

    public PackageLite(String path, String baseApkPath, ApkLite baseApk,
            String[] splitNames, boolean[] isFeatureSplits, String[] usesSplitNames,
            String[] configForSplit, String[] splitApkPaths, int[] splitRevisionCodes) {
            String[] configForSplit, String[] splitApkPaths, int[] splitRevisionCodes,
            int targetSdk) {
        // The following paths may be different from the path in ApkLite because we
        // move or rename the APK files. Use parameters to indicate the correct paths.
        mPath = path;
@@ -125,6 +127,7 @@ public class PackageLite {
        mConfigForSplit = configForSplit;
        mSplitApkPaths = splitApkPaths;
        mSplitRevisionCodes = splitRevisionCodes;
        mTargetSdk = targetSdk;
    }

    /**
@@ -230,6 +233,11 @@ public class PackageLite {
        return mVersionCode;
    }

    @DataClass.Generated.Member
    public int getTargetSdk() {
        return mTargetSdk;
    }

    /**
     * Revision code of base APK
     */
@@ -349,10 +357,10 @@ public class PackageLite {
    }

    @DataClass.Generated(
            time = 1610596639255L,
            time = 1615914120261L,
            codegenVersion = "1.0.22",
            sourceFile = "frameworks/base/core/java/android/content/pm/parsing/PackageLite.java",
            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final  int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mProfileableByShell\nprivate final  boolean mUseEmbeddedDex\npublic  java.util.List<java.lang.String> getAllApkPaths()\npublic  long getLongVersionCode()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mTargetSdk\nprivate final  int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final  int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mProfileableByShell\nprivate final  boolean mUseEmbeddedDex\npublic  java.util.List<java.lang.String> getAllApkPaths()\npublic  long getLongVersionCode()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
    @Deprecated
    private void __metadata() {}

+13 −0
Original line number Diff line number Diff line
@@ -5687,6 +5687,19 @@
    <permission android:name="android.permission.SET_CLIP_SOURCE"
                android:protectionLevel="signature|recents" />

    <!-- Allows an application to request installs that update existing packages do so without
         user action via
         {@link android.content.pm.PackageInstaller.SessionParams#setRequireUserAction(boolean)}.
         This permission only grants the ability to make the request and is not a guarantee that the
         request will be honored. In order to execute the install, the caller must also have the
         "android.permission.REQUEST_INSTALL_PACKAGES" or "android.permission.INSTALL_PACKAGES"
         permissions.
         <p>Protection level: normal
    -->
    <permission android:name="android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION"
                android:protectionLevel="normal" />
    <uses-permission android:name="android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION"/>

    <!-- Attribution for Geofencing service. -->
    <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
    <!-- Attribution for Country Detector. -->
Loading