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

Commit 075d75c6 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[ADI][46/N] enable experiment shell command" into main

parents d3e94a87 9c6d8a77
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -108,4 +108,6 @@ interface IPackageInstaller {

    @EnforcePermission("SET_DEVELOPER_VERIFICATION_USER_RESPONSE")
    DeveloperVerificationUserConfirmationInfo getDeveloperVerificationUserConfirmationInfo(int sessionId);

    void addDeveloperVerificationExperiment(String packageName, int verificationPolicy, in int[] results);
}
+10 −0
Original line number Diff line number Diff line
@@ -2132,6 +2132,16 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        return verifierComponentName;
    }

    @Override
    public void addDeveloperVerificationExperiment(String packageName, int verificationPolicy,
            int[] results) {
        List<Integer> resultsList = new ArrayList<>(results.length);
        for (int i = 0; i < results.length; i++) {
            resultsList.add(results[i]);
        }
        mDeveloperVerifierController.addExperiment(packageName, verificationPolicy, resultsList);
    }

    void onUserAdded(int userId) {
        synchronized (mDeveloperVerificationPolicyPerUser) {
            mDeveloperVerificationPolicyPerUser.put(userId, DEFAULT_VERIFICATION_POLICY);
+16 −5
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import static android.content.pm.PackageManager.INSTALL_STAGED;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
import static android.content.pm.verify.developer.DeveloperVerificationSession.DEVELOPER_VERIFICATION_BYPASSED_REASON_ADB;
import static android.content.pm.verify.developer.DeveloperVerificationSession.DEVELOPER_VERIFICATION_BYPASSED_REASON_EMERGENCY;
import static android.content.pm.verify.developer.DeveloperVerificationSession.DEVELOPER_VERIFICATION_BYPASSED_REASON_TEST;
import static android.content.pm.verify.developer.DeveloperVerificationSession.DEVELOPER_VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE;
import static android.os.Process.INVALID_UID;
import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
@@ -3032,18 +3033,28 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            onSessionVerificationFailure(e.error, errorMsg, /* extras= */ null);
        }
        if (shouldUseVerificationService()) {
            // Send the request to the verifier and wait for its response before the rest of
            // the installation can proceed.
            if (isMultiPackage()) {
            final String packageName = getPackageName();
            if (mDeveloperVerifierController.hasExperiments(packageName)) {
                // This is a local testing environment. Use previously configured test results
                // instead of doing the real verification.
                mDeveloperVerifierController.startLocalExperiment(
                        packageName, mDeveloperVerifierCallback);
                synchronized (mMetrics) {
                    mMetrics.onDeveloperVerificationBypassed(
                            DEVELOPER_VERIFICATION_BYPASSED_REASON_TEST);
                }
            } else if (isMultiPackage()) {
                // TODO(b/360129657) perform developer verification on each children session before
                // moving on to the next installation stage.
                resumeVerify();
            } else { // Not a parent session
                // Send the request to the verifier and wait for its response before the rest of
                // the installation can proceed.
                final var infoPair = getSigningInfoAndDeclaredLibraries();
                final SigningInfo signingInfo = infoPair.first;
                final List<SharedLibraryInfo> declaredLibraries = infoPair.second;
                if (!mDeveloperVerifierController.startVerificationSession(
                        mPm::snapshotComputer, userId, sessionId, getPackageName(),
                        mPm::snapshotComputer, userId, sessionId, packageName,
                        Uri.fromFile(stageDir), signingInfo,
                        declaredLibraries, mCurrentVerificationPolicy.get(),
                        /* extensionParams= */ params.extensionParams,
@@ -3274,7 +3285,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
         * Called by the session itself when the verifier cannot be connected because of infeasible
         * reasons such as it's not installed on the target user.
         */
        private void onConnectionInfeasible() {
        public void onConnectionInfeasible() {
            mHandler.post(() -> {
                mDeveloperVerificationStatusInternal.setInternalStatus(
                        DeveloperVerificationStatusInternal.STATUS_INFEASIBLE);
+49 −1
Original line number Diff line number Diff line
@@ -404,6 +404,8 @@ class PackageManagerShellCommand extends ShellCommand {
                    return runGetDeveloperVerificationPolicy();
                case "get-developer-verification-service-provider":
                    return runGetDeveloperVerificationServiceProvider();
                case "set-developer-verification-result":
                    return runSetDeveloperVerificationResult();
                default: {
                    if (ART_SERVICE_COMMANDS.contains(cmd)) {
                        return runArtServiceCommand();
@@ -4720,6 +4722,31 @@ class PackageManagerShellCommand extends ShellCommand {
        return 0;
    }

    private int runSetDeveloperVerificationResult() {
        final PrintWriter pw = getOutPrintWriter();
        try {
            final IPackageInstaller installer = mInterface.getPackageInstaller();
            final String packageName = getNextArgRequired();
            final int policy = Integer.parseInt(getNextArgRequired());
            final int firstResult = Integer.parseInt(getNextArgRequired());
            final List<Integer> results = new ArrayList<>(1);
            results.add(firstResult);
            String nextResult;
            while ((nextResult = getNextArg()) != null) {
                results.add(Integer.parseInt(nextResult));
            }
            final int[] resultArray = new int[results.size()];
            for (int i = 0; i < results.size(); i++) {
                resultArray[i] = results.get(i);
            }
            installer.addDeveloperVerificationExperiment(packageName, policy, resultArray);
        } catch (Exception e) {
            pw.println("Failure [" + e.getMessage() + "]");
            return 1;
        }
        return 0;
    }

    @Override
    public void onHelp() {
        final PrintWriter pw = getOutPrintWriter();
@@ -5150,10 +5177,31 @@ class PackageManagerShellCommand extends ShellCommand {
        pw.println("      --user: return the agent of the given user (SYSTEM_USER if unspecified)");
        pw.println("  get-package-storage-stats [--user <USER_ID>] <PACKAGE>");
        pw.println("    Return the storage stats for the given app, if present");
        pw.println("  get-verification-policy [--user USER_ID]");
        pw.println("  get-developer-verification-policy [--user USER_ID]");
        pw.println("    Display current verification enforcement policy which will be applied to");
        pw.println("    all the future installation sessions");
        pw.println("      --user: show the policy of the given user (SYSTEM_USER if unspecified)");
        pw.println("  get-developer-verification-service-provider");
        pw.println("    Displays component name of developer verification service provider.");
        pw.println("      --user: show the policy of the given user (SYSTEM_USER if unspecified)");
        pw.println("  set-developer-verification-result PACKAGE POLICY RESULT [RESULT...]");
        pw.println("    Set the developer verification enforcement policy and the result(s)");
        pw.println("    in sequence for the next N verification sessions for the given app where");
        pw.println("    N equals to the number of specified result(s).");
        pw.println("      The valid verification policy values are:");
        pw.println("        0 [none]: Do not block installs, regardless of verification result.");
        pw.println("        1 [open]: Only block installs when verification fails.");
        pw.println("        2 [warning]: The same as fail open.");
        pw.println("        3 [closed]: Block installs when verification fails or cannot perform.");
        pw.println("      The valid verification result values are:");
        pw.println("        0 [invalid]: An invalid result value which will be skipped.");
        pw.println("        1 [pass]: Verification passed.");
        pw.println("        2 [reject]: Verification failed.");
        pw.println("        3 [incomplete unknown]: Verification did not perform due to unknown.");
        pw.println("        4 [incomplete network]: Verification did not perform due to network.");
        pw.println("        5 [timeout]: Verification timed out.");
        pw.println("        6 [disconnect]: Verification service disconnected.");
        pw.println("        7 [infeasible]: Verification service was unavailable.");
        pw.println("");
        pw.println("");
        printArtServiceHelp();
+28 −0
Original line number Diff line number Diff line
@@ -141,6 +141,8 @@ public class DeveloperVerifierController {
    // Counter of active verification sessions per user; must be synced with the trackers map.
    private final SparseIntArray mSessionsCountPerUser = new SparseIntArray();

    private final DeveloperVerifierExperimentProvider mExperimentProvider;

    /**
     * Get an instance of VerifierController.
     */
@@ -162,6 +164,7 @@ public class DeveloperVerifierController {
        mHandler = handler;
        mDeveloperVerificationServiceProvider = developerVerificationServiceProvider;
        mInjector = injector;
        mExperimentProvider = new DeveloperVerifierExperimentProvider(mHandler);
    }

    /**
@@ -682,6 +685,31 @@ public class DeveloperVerifierController {
        }
    }

    /**
     * Add an experiment to the experiment provider.
     * <p>Notice that invalid status codes will be ignored. Valid status codes are defined in
     * {@link DeveloperVerificationStatusInternal}.
     * </p>
     */
    public void addExperiment(String packageName, int verificationPolicy, List<Integer> status) {
        mExperimentProvider.addExperiment(packageName, verificationPolicy, status);
    }

    /**
     * Check if there is an experiment for the given package.
     */
    public boolean hasExperiments(String packageName) {
        return mExperimentProvider.hasExperiments(packageName);
    }

    /**
     * Start a local experiment for the given package.
     */
    public void startLocalExperiment(String packageName,
            PackageInstallerSession.DeveloperVerifierCallback callback) {
        mExperimentProvider.runNextExperiment(packageName, callback);
    }

    private static class ServiceConnectorWrapper {
        // Remote service that receives verification requests
        private final @NonNull ServiceConnector<IDeveloperVerifierService> mRemoteService;
Loading