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

Commit 209642a3 authored by Sumedh Sen's avatar Sumedh Sen
Browse files

Update conditions for updates without user action for Android U

-For Android U, updates without user action are permitted for apps
targeting API 31+
-Updated the conditions for SDK version check in PackageInstallerSession and associated
documentation in PackageInstaller.SesionParams

Bug: 265131695
Test: atest CtsSilentUpdateHostTestCases
Change-Id: I7167ab4f0a322c04096503afa3053a49fbbb30dc
parent 1a743081
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -2928,10 +2928,10 @@ public class PackageInstaller {
         *     <li>{@code requireUserAction} is set to {@link #USER_ACTION_NOT_REQUIRED}.</li>
         *     <li>The app being installed targets:
         *          <ul>
         *              <li>{@link android.os.Build.VERSION_CODES#Q API 29} or higher on
         *              Android S ({@link android.os.Build.VERSION_CODES#S API 31})</li>
         *              <li>{@link android.os.Build.VERSION_CODES#R API 30} or higher after
         *              Android S ({@link android.os.Build.VERSION_CODES#S API 31})</li>
         *              <li>{@link android.os.Build.VERSION_CODES#R API 30} or higher on
         *              Android T ({@link android.os.Build.VERSION_CODES#TIRAMISU API 33})</li>
         *              <li>{@link android.os.Build.VERSION_CODES#S API 31} or higher <b>after</b>
         *              Android T ({@link android.os.Build.VERSION_CODES#TIRAMISU API 33})</li>
         *          </ul>
         *     </li>
         *     <li>The installer is:
+50 −8
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@ import android.app.NotificationManager;
import android.app.admin.DevicePolicyEventLogger;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -123,6 +125,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.RevocableFileDescriptor;
import android.os.SELinux;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.incremental.IStorageHealthListener;
@@ -145,6 +148,7 @@ import android.util.ArraySet;
import android.util.EventLog;
import android.util.ExceptionUtils;
import android.util.IntArray;
import android.util.Log;
import android.util.MathUtils;
import android.util.Slog;
import android.util.SparseArray;
@@ -153,6 +157,7 @@ import android.util.apk.ApkSignatureVerifier;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.content.InstallLocationUtils;
import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.messages.nano.SystemMessageProto;
@@ -295,9 +300,19 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    private static final int INCREMENTAL_STORAGE_UNHEALTHY_TIMEOUT_MS = 7000;
    private static final int INCREMENTAL_STORAGE_UNHEALTHY_MONITORING_MS = 60000;

    /**
     * If an app being installed targets {@link Build.VERSION_CODES#S API 31} and above, the app
     * can be installed without user action.
     * See {@link PackageInstaller.SessionParams#setRequireUserAction} for other conditions required
     * to be satisfied for a silent install.
     */
    @ChangeId
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
    private static final long SILENT_INSTALL_ALLOWED = 265131695L;

    /**
     * The default value of {@link #mValidatedTargetSdk} is {@link Integer#MAX_VALUE}. If {@link
     * #mValidatedTargetSdk} is compared with {@link Build.VERSION_CODES#R} before getting the
     * #mValidatedTargetSdk} is compared with {@link Build.VERSION_CODES#S} before getting the
     * target sdk version from a validated apk in {@link #validateApkInstallLocked()}, the compared
     * result will not trigger any user action in
     * {@link #checkUserActionRequirement(PackageInstallerSession, IntentSender)}.
@@ -2347,13 +2362,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }

        if (!session.isApexSession() && userActionRequirement == USER_ACTION_PENDING_APK_PARSING) {
            final int validatedTargetSdk;
            synchronized (session.mLock) {
                validatedTargetSdk = session.mValidatedTargetSdk;
            }

            if (validatedTargetSdk != INVALID_TARGET_SDK_VERSION
                    && validatedTargetSdk < Build.VERSION_CODES.R) {
            if (!isTargetSdkConditionSatisfied(session)) {
                session.sendPendingUserActionIntent(target);
                return true;
            }
@@ -2374,6 +2383,39 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        return false;
    }

    /**
     * Checks if the app being installed has a targetSdk more than the minimum required for a
     * silent install. See {@link SessionParams#setRequireUserAction(int)} for details about the
     * targetSdk requirement.
     * @param session Current install session
     * @return true if the targetSdk of the app being installed is more than the minimum required,
     *          resulting in a silent install, false otherwise.
     */
    private static boolean isTargetSdkConditionSatisfied(PackageInstallerSession session) {
        final int validatedTargetSdk;
        final String packageName;
        synchronized (session.mLock) {
            validatedTargetSdk = session.mValidatedTargetSdk;
            packageName = session.mPackageName;
        }

        ApplicationInfo appInfo = new ApplicationInfo();
        appInfo.packageName = packageName;
        appInfo.targetSdkVersion = validatedTargetSdk;

        IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
        try {
            // Using manually constructed AppInfo to check if a change is enabled may not work
            // in the future.
            return validatedTargetSdk != INVALID_TARGET_SDK_VERSION
                    && platformCompat.isChangeEnabled(SILENT_INSTALL_ALLOWED, appInfo);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to get a response from PLATFORM_COMPAT_SERVICE", e);
            return false;
        }
    }

    private static @UserActionReason int userActionRequirementToReason(
            @UserActionRequirement int requirement) {
        switch (requirement) {