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

Commit 70d9bad3 authored by Song Chun Fan's avatar Song Chun Fan
Browse files

Revert "[2/N] implementation of verifier controller and status tracker"

This reverts commit a4c17763.

BUG: 374797861
Test: n/a
FLAG: android.content.pm.verification_service

Change-Id: I92a8b2c6451ad0b42d4d9bd2bd91363ca9ffaabb
parent 1adff66a
Loading
Loading
Loading
Loading
+1 −6
Original line number Diff line number Diff line
@@ -126,7 +126,6 @@ import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.utils.RequestThrottle;
import com.android.server.pm.verify.pkg.VerifierController;

import libcore.io.IoUtils;

@@ -214,7 +213,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
    private final StagingManager mStagingManager;

    private AppOpsManager mAppOps;
    private final VerifierController mVerifierController;
    private final InstallDependencyHelper mInstallDependencyHelper;

    private final HandlerThread mInstallThread;
@@ -328,7 +326,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        mGentleUpdateHelper = new GentleUpdateHelper(
                context, mInstallThread.getLooper(), new AppStateHelper(context));
        mPackageArchiver = new PackageArchiver(mContext, mPm);
        mVerifierController = new VerifierController(mContext, mInstallHandler);
        mInstallDependencyHelper = new InstallDependencyHelper(mContext,
                mPm.mInjector.getSharedLibrariesImpl());

@@ -528,7 +525,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                            session = PackageInstallerSession.readFromXml(in, mInternalCallback,
                                    mContext, mPm, mInstallThread.getLooper(), mStagingManager,
                                    mSessionsDir, this, mSilentUpdatePolicy,
                                    mVerifierController, mInstallDependencyHelper);
                                    mInstallDependencyHelper);
                        } catch (Exception e) {
                            Slog.e(TAG, "Could not read session", e);
                            continue;
@@ -1045,7 +1042,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                userId, callingUid, installSource, params, createdMillis, 0L, stageDir, stageCid,
                null, null, false, false, false, false, null, SessionInfo.INVALID_ID,
                false, false, false, PackageManager.INSTALL_UNKNOWN, "", null,
                mVerifierController,
                mInstallDependencyHelper);

        synchronized (mSessions) {
@@ -1056,7 +1052,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        mCallbacks.notifySessionCreated(session.sessionId, session.userId);

        mSettingsWriteRequest.schedule();

        if (LOGD) {
            Slog.d(TAG, "Created session id=" + sessionId + " staged=" + params.isStaged);
        }
+1 −116
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_VERIFICATION_FAIL
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_STAGED;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
import static android.content.pm.verify.pkg.VerificationSession.VERIFICATION_INCOMPLETE_UNKNOWN;
import static android.os.Process.INVALID_UID;
import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
import static android.system.OsConstants.O_CREAT;
@@ -110,7 +109,6 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.PackageInfoFlags;
import android.content.pm.PackageManagerInternal;
import android.content.pm.SigningDetails;
import android.content.pm.SigningInfo;
import android.content.pm.dex.DexMetadataHelper;
import android.content.pm.parsing.ApkLite;
import android.content.pm.parsing.ApkLiteParseUtils;
@@ -118,7 +116,6 @@ import android.content.pm.parsing.PackageLite;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
import android.content.pm.verify.domain.DomainSet;
import android.content.pm.verify.pkg.VerificationStatus;
import android.content.res.ApkAssets;
import android.content.res.AssetManager;
import android.content.res.Configuration;
@@ -126,7 +123,6 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.icu.util.ULocale;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -139,7 +135,6 @@ import android.os.Message;
import android.os.OutcomeReceiver;
import android.os.ParcelFileDescriptor;
import android.os.ParcelableException;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.RevocableFileDescriptor;
@@ -197,7 +192,6 @@ import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.verify.pkg.VerifierController;

import libcore.io.IoUtils;
import libcore.util.EmptyArray;
@@ -226,7 +220,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    private static final String TAG = "PackageInstallerSession";
@@ -413,7 +406,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
     * Note all calls must be done outside {@link #mLock} to prevent lock inversion.
     */
    private final StagingManager mStagingManager;
    @NonNull private final VerifierController mVerifierController;

    private final InstallDependencyHelper mInstallDependencyHelper;

@@ -1169,7 +1161,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            @Nullable int[] childSessionIds, int parentSessionId, boolean isReady,
            boolean isFailed, boolean isApplied, int sessionErrorCode,
            String sessionErrorMessage, DomainSet preVerifiedDomains,
            @NonNull VerifierController verifierController,
            InstallDependencyHelper installDependencyHelper) {
        mCallback = callback;
        mContext = context;
@@ -1179,7 +1170,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        mSilentUpdatePolicy = silentUpdatePolicy;
        mHandler = new Handler(looper, mHandlerCallback);
        mStagingManager = stagingManager;
        mVerifierController = verifierController;
        mInstallDependencyHelper = installDependencyHelper;

        this.sessionId = sessionId;
@@ -1265,14 +1255,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                        "Archived installation can only use Streaming System DataLoader.");
            }
        }

        if (Flags.verificationService()) {
            // Start binding to the verification service, if not bound already.
            mVerifierController.bindToVerifierServiceIfNeeded(() -> pm.snapshotComputer(), userId);
            if (!TextUtils.isEmpty(params.appPackageName)) {
                mVerifierController.notifyPackageNameAvailable(params.appPackageName);
            }
        }
    }

    PackageInstallerHistoricalSession createHistoricalSession() {
@@ -2870,35 +2852,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            setSessionFailed(e.error, errorMsg);
            onSessionVerificationFailure(e.error, errorMsg);
        }
        if (Flags.verificationService()) {
            final Supplier<Computer> snapshotSupplier = mPm::snapshotComputer;
            if (mVerifierController.isVerifierInstalled(snapshotSupplier, userId)) {
                // TODO: extract shared library declarations
                final SigningInfo signingInfo;
                synchronized (mLock) {
                    signingInfo = new SigningInfo(mSigningDetails);
                }
                // Send the request to the verifier and wait for its response before the rest of
                // the installation can proceed.
                if (!mVerifierController.startVerificationSession(snapshotSupplier, userId,
                        sessionId, getPackageName(), Uri.fromFile(stageDir), signingInfo,
                        /* declaredLibraries= */null, /* extensionParams= */ null,
                        new VerifierCallback(), /* retry= */ false)) {
                    // A verifier is installed but cannot be connected. Installation disallowed.
                    onSessionVerificationFailure(INSTALL_FAILED_INTERNAL_ERROR,
                            "A verifier agent is available on device but cannot be connected.");
                }
            } else {
                // Verifier is not installed. Let the installation pass for now.
                resumeVerify();
            }
        } else {
            // New verification feature is not enabled. Proceed to the rest of the verification.
            resumeVerify();
        }
    }

    private void resumeVerify() {
        if (mVerificationInProgress) {
            Slog.w(TAG, "Verification is already in progress for session " + sessionId);
            return;
@@ -2931,66 +2885,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }
    }

    /**
     * Used for the VerifierController to report status back.
     */
    public class VerifierCallback {
        /**
         * Called by the VerifierController when the connection has failed.
         */
        public void onConnectionFailed() {
            mHandler.post(() -> {
                onSessionVerificationFailure(INSTALL_FAILED_VERIFICATION_FAILURE,
                            "A verifier agent is available on device but cannot be connected.");
            });
        }
        /**
         * Called by the VerifierController when the verification request has timed out.
         */
        public void onTimeout() {
            mHandler.post(() -> {
                mVerifierController.notifyVerificationTimeout(sessionId);
                onSessionVerificationFailure(INSTALL_FAILED_VERIFICATION_FAILURE,
                        "Verification timed out; missing a response from the verifier within the"
                                + " time limit");
            });
        }
        /**
         * Called by the VerifierController when the verification request has received a complete
         * response.
         */
        public void onVerificationCompleteReceived(@NonNull VerificationStatus statusReceived,
                @Nullable PersistableBundle extensionResponse) {
            // TODO: handle extension response
            mHandler.post(() -> {
                if (statusReceived.isVerified()) {
                    // Continue with the rest of the verification and installation.
                    resumeVerify();
                } else {
                    StringBuilder sb = new StringBuilder("Verifier rejected the installation");
                    if (!TextUtils.isEmpty(statusReceived.getFailureMessage())) {
                        sb.append(" with message: ").append(statusReceived.getFailureMessage());
                    }
                    onSessionVerificationFailure(INSTALL_FAILED_VERIFICATION_FAILURE,
                            sb.toString());
                }
            });
        }
        /**
         * Called by the VerifierController when the verification request has received an incomplete
         * response.
         */
        public void onVerificationIncompleteReceived(int incompleteReason) {
            mHandler.post(() -> {
                if (incompleteReason == VERIFICATION_INCOMPLETE_UNKNOWN) {
                    // TODO: change this to a user confirmation and handle other incomplete reasons
                    onSessionVerificationFailure(INSTALL_FAILED_INTERNAL_ERROR,
                            "Verification cannot be completed for unknown reasons.");
                }
            });
        }
    }

    private IntentSender getRemoteStatusReceiver() {
        synchronized (mLock) {
            return mRemoteStatusReceiver;
@@ -5535,14 +5429,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            }
        } catch (InstallerException ignored) {
        }
        if (Flags.verificationService()
                && !TextUtils.isEmpty(params.appPackageName)
                && !isCommitted()) {
            // Only notify for the cancellation if the verification request has not
            // been sent out, which happens right after commit() is called.
            mVerifierController.notifyVerificationCancelled(
                    params.appPackageName);
        }
    }

    void dump(IndentingPrintWriter pw) {
@@ -5943,7 +5829,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            @NonNull StagingManager stagingManager, @NonNull File sessionsDir,
            @NonNull PackageSessionProvider sessionProvider,
            @NonNull SilentUpdatePolicy silentUpdatePolicy,
            @NonNull VerifierController verifierController,
            @NonNull InstallDependencyHelper installDependencyHelper)
            throws IOException, XmlPullParserException {
        final int sessionId = in.getAttributeInt(null, ATTR_SESSION_ID);
@@ -6148,7 +6033,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                installerUid, installSource, params, createdMillis, committedMillis, stageDir,
                stageCid, fileArray, checksumsMap, prepared, committed, destroyed, sealed,
                childSessionIdsArray, parentSessionId, isReady, isFailed, isApplied,
                sessionErrorCode, sessionErrorMessage, preVerifiedDomains, verifierController,
                sessionErrorCode, sessionErrorMessage, preVerifiedDomains,
                installDependencyHelper);
    }
}
+0 −101
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.pm.verify.pkg;

import android.annotation.CurrentTimeMillisLong;
import android.annotation.NonNull;

import com.android.internal.annotations.VisibleForTesting;

/**
 * This class keeps record of the current timeout status of a verification request.
 */
public final class VerificationStatusTracker {
    private final @CurrentTimeMillisLong long mStartTime;
    private @CurrentTimeMillisLong long mTimeoutTime;
    private final @CurrentTimeMillisLong long mMaxTimeoutTime;
    @NonNull
    private final VerifierController.Injector mInjector;
    // Record the package name associated with the verification result
    @NonNull
    private final String mPackageName;

    /**
     * By default, the timeout time is the default timeout duration plus the current time (when
     * the timer starts for a verification request). Both the default timeout time and the max
     * timeout time cannot be changed after the timer has started, but the actual timeout time
     * can be extended via {@link #extendTimeRemaining} to the maximum allowed.
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
    public VerificationStatusTracker(@NonNull String packageName,
            long defaultTimeoutMillis, long maxExtendedTimeoutMillis,
            @NonNull VerifierController.Injector injector) {
        mPackageName = packageName;
        mStartTime = injector.getCurrentTimeMillis();
        mTimeoutTime = mStartTime + defaultTimeoutMillis;
        mMaxTimeoutTime = mStartTime + maxExtendedTimeoutMillis;
        mInjector = injector;
    }

    /**
     * Used by the controller to inform the verifier agent about the timestamp when the verification
     * request will timeout.
     */
    public @CurrentTimeMillisLong long getTimeoutTime() {
        return mTimeoutTime;
    }

    /**
     * Used by the controller to decide when to check for timeout again.
     * @return 0 if the timeout time has been reached, otherwise the remaining time in milliseconds
     * before the timeout is reached.
     */
    public @CurrentTimeMillisLong long getRemainingTime() {
        final long remainingTime = mTimeoutTime - mInjector.getCurrentTimeMillis();
        if (remainingTime < 0) {
            return 0;
        }
        return remainingTime;
    }

    /**
     * Used by the controller to extend the timeout duration of the verification request, upon
     * receiving the callback from the verifier agent.
     * @return the amount of time in millis that the timeout has been extended, subject to the max
     * amount allowed.
     */
    public long extendTimeRemaining(@CurrentTimeMillisLong long additionalMs) {
        if (mTimeoutTime + additionalMs > mMaxTimeoutTime) {
            additionalMs = mMaxTimeoutTime - mTimeoutTime;
        }
        mTimeoutTime += additionalMs;
        return additionalMs;
    }

    /**
     * Used by the controller to get the timeout status of the request.
     * @return False if the request still has some time left before timeout, otherwise return True.
     */
    public boolean isTimeout() {
        return mInjector.getCurrentTimeMillis() >= mTimeoutTime;
    }

    @NonNull
    public String getPackageName() {
        return mPackageName;
    }
}
+0 −645

File deleted.

Preview size limit exceeded, changes collapsed.

+0 −3
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import android.util.AtomicFile
import android.util.Slog
import android.util.Xml
import com.android.internal.os.BackgroundThread
import com.android.server.pm.verify.pkg.VerifierController
import com.android.server.testutils.whenever
import com.google.common.truth.Truth.assertThat
import libcore.io.IoUtils
@@ -197,7 +196,6 @@ class PackageInstallerSessionTest {
            /* stagedSessionErrorCode */ PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
            /* stagedSessionErrorMessage */ "some error",
            /* preVerifiedDomains */ DomainSet(setOf("com.foo", "com.bar")),
            /* VerifierController */ mock(VerifierController::class.java),
            /* installDependencyHelper */ null
        )
    }
@@ -253,7 +251,6 @@ class PackageInstallerSessionTest {
                                mTmpDir,
                                mock(PackageSessionProvider::class.java),
                                mock(SilentUpdatePolicy::class.java),
                                mock(VerifierController::class.java),
                                mock(InstallDependencyHelper::class.java)
                            )
                            ret.add(session)
Loading