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

Commit 6b11d1e5 authored by Jackal Guo's avatar Jackal Guo
Browse files

Introduce the concept of the update owner (1/n)

To address the cross-store update without user consent, we introduce
the update ownership enforcement. Installers can opt in this enforce-
ment on initial installation. After that, the user intervenrion will
be required once the update isn't performed by the update owner (even
if this installer grants INSTALL_PACKAGES).

Bug: 244413073
Test: build
Test: atest FrameworksServicesTests:SystemAppUpdateTrackerTest
Test: atest FrameworksServicesTests:LocaleManagerServiceTest
Test: atest FrameworksServicesTests:PackageInstallerSessionTest
Test: atest FrameworksServicesTests:AppsFilterImplTest
Test: atest FrameworksMockingServicesTests:StagingManagerTest
Test: atest CtsPackageInstallTestCases:UpdateOwnershipEnforcementTest
Change-Id: Iddaba09c1f06fc157352379b33a188692c5249c4
parent cda60c24
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ package android {
    field public static final String DIAGNOSTIC = "android.permission.DIAGNOSTIC";
    field public static final String DISABLE_KEYGUARD = "android.permission.DISABLE_KEYGUARD";
    field public static final String DUMP = "android.permission.DUMP";
    field public static final String ENFORCE_UPDATE_OWNERSHIP = "android.permission.ENFORCE_UPDATE_OWNERSHIP";
    field public static final String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
    field public static final String FACTORY_TEST = "android.permission.FACTORY_TEST";
    field public static final String FOREGROUND_SERVICE = "android.permission.FOREGROUND_SERVICE";
@@ -11691,6 +11692,7 @@ package android.content.pm {
    method @Nullable public String getInstallingPackageName();
    method @Nullable public String getOriginatingPackageName();
    method public int getPackageSource();
    method @Nullable public String getUpdateOwnerPackageName();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.InstallSourceInfo> CREATOR;
  }
@@ -11981,6 +11983,7 @@ package android.content.pm {
    method public int getParentSessionId();
    method public boolean isKeepApplicationEnabledSetting();
    method public boolean isMultiPackage();
    method public boolean isRequestUpdateOwnership();
    method public boolean isStaged();
    method @NonNull public java.io.InputStream openRead(@NonNull String) throws java.io.IOException;
    method @NonNull public java.io.OutputStream openWrite(@NonNull String, long, long) throws java.io.IOException;
@@ -12036,6 +12039,7 @@ package android.content.pm {
    method public boolean isCommitted();
    method public boolean isKeepApplicationEnabledSetting();
    method public boolean isMultiPackage();
    method public boolean isRequestUpdateOwnership();
    method public boolean isSealed();
    method public boolean isStaged();
    method public boolean isStagedSessionActive();
@@ -12074,6 +12078,7 @@ package android.content.pm {
    method public void setOriginatingUri(@Nullable android.net.Uri);
    method public void setPackageSource(int);
    method public void setReferrerUri(@Nullable android.net.Uri);
    method @RequiresPermission(android.Manifest.permission.ENFORCE_UPDATE_OWNERSHIP) public void setRequestUpdateOwnership(boolean);
    method public void setRequireUserAction(int);
    method public void setSize(long);
    method public void setWhitelistedRestrictedPermissions(@Nullable java.util.Set<java.lang.String>);
+1 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ interface IPackageInstallerSession {
    void requestUserPreapproval(in PackageInstaller.PreapprovalDetails details, in IntentSender statusReceiver);

    boolean isKeepApplicationEnabledSetting();
    boolean isRequestUpdateOwnership();

    ParcelFileDescriptor getAppMetadataFd();
    ParcelFileDescriptor openWriteAppMetadata();
+23 −2
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ public final class InstallSourceInfo implements Parcelable {

    @Nullable private final String mInstallingPackageName;

    @Nullable private final String mUpdateOwnerPackageName;

    @Nullable private final int mPackageSource;

    /** @hide */
@@ -42,18 +44,20 @@ public final class InstallSourceInfo implements Parcelable {
            @Nullable SigningInfo initiatingPackageSigningInfo,
            @Nullable String originatingPackageName, @Nullable String installingPackageName) {
        this(initiatingPackageName, initiatingPackageSigningInfo, originatingPackageName,
                installingPackageName, PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
                installingPackageName, null /* updateOwnerPackageName */,
                PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
    }

    /** @hide */
    public InstallSourceInfo(@Nullable String initiatingPackageName,
            @Nullable SigningInfo initiatingPackageSigningInfo,
            @Nullable String originatingPackageName, @Nullable String installingPackageName,
            int packageSource) {
            @Nullable String updateOwnerPackageName, int packageSource) {
        mInitiatingPackageName = initiatingPackageName;
        mInitiatingPackageSigningInfo = initiatingPackageSigningInfo;
        mOriginatingPackageName = originatingPackageName;
        mInstallingPackageName = installingPackageName;
        mUpdateOwnerPackageName = updateOwnerPackageName;
        mPackageSource = packageSource;
    }

@@ -69,6 +73,7 @@ public final class InstallSourceInfo implements Parcelable {
        dest.writeParcelable(mInitiatingPackageSigningInfo, flags);
        dest.writeString(mOriginatingPackageName);
        dest.writeString(mInstallingPackageName);
        dest.writeString8(mUpdateOwnerPackageName);
        dest.writeInt(mPackageSource);
    }

@@ -77,6 +82,7 @@ public final class InstallSourceInfo implements Parcelable {
        mInitiatingPackageSigningInfo = source.readParcelable(SigningInfo.class.getClassLoader(), android.content.pm.SigningInfo.class);
        mOriginatingPackageName = source.readString();
        mInstallingPackageName = source.readString();
        mUpdateOwnerPackageName = source.readString8();
        mPackageSource = source.readInt();
    }

@@ -136,6 +142,21 @@ public final class InstallSourceInfo implements Parcelable {
        return mInstallingPackageName;
    }

    /**
     * The name of the package that is the update owner, or null if not available.
     *
     * This indicates the update ownership enforcement is enabled for this app,
     * and which package is the update owner.
     *
     * Returns null if the update ownership enforcement is disabled for the app.
     *
     * @see PackageInstaller.SessionParams#setRequestUpdateOwnership
     */
    @Nullable
    public String getUpdateOwnerPackageName() {
        return mUpdateOwnerPackageName;
    }

    /**
     * Information about the package source when installer installed this app.
     */
+48 −0
Original line number Diff line number Diff line
@@ -1910,6 +1910,20 @@ public class PackageInstaller {
                throw e.rethrowFromSystemServer();
            }
        }

        /**
         * @return {@code true} if the installer requested the update ownership enforcement
         * for the packages in this session.
         *
         * @see PackageInstaller.SessionParams#setRequestUpdateOwnership
         */
        public boolean isRequestUpdateOwnership() {
            try {
                return mSession.isRequestUpdateOwnership();
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

    /**
@@ -2713,6 +2727,30 @@ public class PackageInstaller {
            this.keepApplicationEnabledSetting = true;
        }

        /**
         * Optionally indicate whether the package being installed needs the update ownership
         * enforcement. Once the update ownership enforcement is enabled, the other installers
         * will need the user action to update the package even if the installers have been
         * granted the {@link android.Manifest.permission#INSTALL_PACKAGES INSTALL_PACKAGES}
         * permission. Default to {@code false}.
         *
         * The update ownership enforcement can only be enabled on initial installation. Set
         * this to {@code true} on package update indicates the installer package wants to be
         * the update owner if the update ownership enforcement has enabled.
         *
         * Note: To enable the update ownership enforcement, the installer must have the
         * {@link android.Manifest.permission#ENFORCE_UPDATE_OWNERSHIP ENFORCE_UPDATE_OWNERSHIP}
         * permission.
         */
        @RequiresPermission(Manifest.permission.ENFORCE_UPDATE_OWNERSHIP)
        public void setRequestUpdateOwnership(boolean enable) {
            if (enable) {
                this.installFlags |= PackageManager.INSTALL_REQUEST_UPDATE_OWNERSHIP;
            } else {
                this.installFlags &= ~PackageManager.INSTALL_REQUEST_UPDATE_OWNERSHIP;
            }
        }

        /** {@hide} */
        public void dump(IndentingPrintWriter pw) {
            pw.printPair("mode", mode);
@@ -3585,6 +3623,16 @@ public class PackageInstaller {
            return isPreapprovalRequested;
        }

        /**
         * @return {@code true} if the installer requested the update ownership enforcement
         * for the packages in this session.
         *
         * @see PackageInstaller.SessionParams#setRequestUpdateOwnership
         */
        public boolean isRequestUpdateOwnership() {
            return (installFlags & PackageManager.INSTALL_REQUEST_UPDATE_OWNERSHIP) != 0;
        }

        @Override
        public int describeContents() {
            return 0;
+8 −0
Original line number Diff line number Diff line
@@ -1355,6 +1355,7 @@ public abstract class PackageManager {
            INSTALL_ENABLE_ROLLBACK,
            INSTALL_ALLOW_DOWNGRADE,
            INSTALL_STAGED,
            INSTALL_REQUEST_UPDATE_OWNERSHIP,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface InstallFlags {}
@@ -1553,6 +1554,13 @@ public abstract class PackageManager {
     */
    public static final int INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK = 0x00800000;

    /**
     * Flag parameter for {@link PackageInstaller.SessionParams} to indicate that the
     * update ownership enforcement is requested.
     * @hide
     */
    public static final int INSTALL_REQUEST_UPDATE_OWNERSHIP = 1 << 25;

    /** @hide */
    @IntDef(flag = true, value = {
            DONT_KILL_APP,
Loading