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

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

Merge "[ADI][40/N] new API for verifier to report verification bypass" into main

parents 5ab5211f c56f8639
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -4772,12 +4772,17 @@ package android.content.pm.verify.developer {
    method @NonNull public android.content.pm.SigningInfo getSigningInfo();
    method @NonNull public android.net.Uri getStagedPackageUri();
    method @NonNull public java.time.Instant getTimeoutTime();
    method public void reportVerificationBypassed(int);
    method public void reportVerificationComplete(@NonNull android.content.pm.verify.developer.DeveloperVerificationStatus);
    method public void reportVerificationComplete(@NonNull android.content.pm.verify.developer.DeveloperVerificationStatus, @NonNull android.os.PersistableBundle);
    method public void reportVerificationIncomplete(int);
    method public boolean setPolicy(int);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.verify.developer.DeveloperVerificationSession> CREATOR;
    field public static final int DEVELOPER_VERIFICATION_BYPASSED_REASON_ADB = 1; // 0x1
    field public static final int DEVELOPER_VERIFICATION_BYPASSED_REASON_EMERGENCY = 2; // 0x2
    field public static final int DEVELOPER_VERIFICATION_BYPASSED_REASON_TEST = 3; // 0x3
    field public static final int DEVELOPER_VERIFICATION_BYPASSED_REASON_UNSPECIFIED = 0; // 0x0
    field public static final int DEVELOPER_VERIFICATION_INCOMPLETE_NETWORK_UNAVAILABLE = 1; // 0x1
    field public static final int DEVELOPER_VERIFICATION_INCOMPLETE_UNKNOWN = 0; // 0x0
  }
+50 −6
Original line number Diff line number Diff line
@@ -67,6 +67,30 @@ public final class DeveloperVerificationSession implements Parcelable {
    public @interface DeveloperVerificationIncompleteReason {
    }

    /**
     * The developer verification is bypassed because of an unspecified reason. This field is
     * reserved and must not be used when reporting a developer verification bypass.
     */
    public static final int DEVELOPER_VERIFICATION_BYPASSED_REASON_UNSPECIFIED = 0;
    /**
     * The developer verification is bypassed because the installation was initiated from the
     * Android Debug Bridge (ADB) service.
     */
    public static final int DEVELOPER_VERIFICATION_BYPASSED_REASON_ADB = 1;
    /**
     * The developer verification is bypassed because the verification could not be performed due
     * to emergency conditions such as the verification service being unresponsive. Only critical
     * packages such as the verifier itself, the installer or the update owner of the verifier, or
     * the emergency installer are allowed to bypass the developer verification with this reason.
     */
    public static final int DEVELOPER_VERIFICATION_BYPASSED_REASON_EMERGENCY = 2;
    /**
     * The developer verification is bypassed because this is a testing environment and the result
     * of the verification does not rely on the actual verification service.
     */
    public static final int DEVELOPER_VERIFICATION_BYPASSED_REASON_TEST = 3;


    private final int mId;
    private final int mInstallSessionId;
    @NonNull
@@ -247,8 +271,8 @@ public final class DeveloperVerificationSession implements Parcelable {
     * along with an approximate reason to pass on to the installer.
     * @throws SecurityException if the caller is not the current verifier bound by the system.
     * @throws IllegalStateException if this is called after the session has finished, because
     * this API or {@link #reportVerificationComplete} have already been called once, or because the
     * session has timed out.
     * this API or {@link #reportVerificationComplete} or {@link #reportVerificationBypassed}
     * have already been called once, or because the session has timed out.
     */
    public void reportVerificationIncomplete(@DeveloperVerificationIncompleteReason int reason) {
        try {
@@ -264,8 +288,8 @@ public final class DeveloperVerificationSession implements Parcelable {
     * of failure or continue to process the install in the case of success.
     * @throws SecurityException if the caller is not the current verifier bound by the system.
     * @throws IllegalStateException if this is called after the session has finished, because
     * this API or {@link #reportVerificationIncomplete} have already been called once, or because
     * the session has timed out.
     * this API or {@link #reportVerificationIncomplete} or {@link #reportVerificationBypassed}
     * have already been called once, or because the session has timed out.
     */
    public void reportVerificationComplete(@NonNull DeveloperVerificationStatus status) {
        try {
@@ -281,8 +305,8 @@ public final class DeveloperVerificationSession implements Parcelable {
     * installer in the installation result.
     * @throws SecurityException if the caller is not the current verifier bound by the system.
     * @throws IllegalStateException if this is called after the session has finished, because
     * this API or {@link #reportVerificationIncomplete} have already been called once, or because
     * the session has timed out.
     * this API or {@link #reportVerificationIncomplete} or {@link #reportVerificationBypassed} have
     * already been called once, or because the session has timed out.
     */
    public void reportVerificationComplete(@NonNull DeveloperVerificationStatus status,
            @NonNull PersistableBundle extensionResponse) {
@@ -293,6 +317,26 @@ public final class DeveloperVerificationSession implements Parcelable {
        }
    }

    /**
     * Report to the system that the developer verification verification has been bypassed because
     * of a certain reason.
     * @param bypassReason The reason for the verification bypass, which must be larger than
     *                     {@link #DEVELOPER_VERIFICATION_BYPASSED_REASON_UNSPECIFIED}.
     * @throws IllegalArgumentException if @bypassReason is less than or equal to
     * {@link #DEVELOPER_VERIFICATION_BYPASSED_REASON_UNSPECIFIED}.
     * @throws SecurityException if the caller is not the current verifier bound by the system.
     * @throws IllegalStateException if this is called after the session has finished, because
     * this API or {@link #reportVerificationComplete} or or {@link #reportVerificationIncomplete}
     * have already been called once, or because the session has timed out.
     */
    public void reportVerificationBypassed(int bypassReason) {
        try {
            mSession.reportVerificationBypassed(mId, bypassReason);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    private DeveloperVerificationSession(@NonNull Parcel in) {
        mId = in.readInt();
        mInstallSessionId = in.readInt();
+1 −0
Original line number Diff line number Diff line
@@ -29,4 +29,5 @@ interface IDeveloperVerificationSessionInterface {
    boolean setVerificationPolicy(int verificationId, int policy);
    void reportVerificationIncomplete(int verificationId, int reason);
    void reportVerificationComplete(int verificationId, in DeveloperVerificationStatus status, in @nullable PersistableBundle extensionResponse);
    void reportVerificationBypassed(int verificationId, int bypassReason);
}
 No newline at end of file
+6 −0
Original line number Diff line number Diff line
@@ -165,6 +165,12 @@ public class DeveloperVerificationSessionTest {
        mTestSession.reportVerificationIncomplete(reason);
        verify(mTestSessionInterface, times(1)).reportVerificationIncomplete(
                eq(TEST_ID), eq(reason));

        final int bypassReason =
                DeveloperVerificationSession.DEVELOPER_VERIFICATION_BYPASSED_REASON_ADB;
        mTestSession.reportVerificationBypassed(bypassReason);
        verify(mTestSessionInterface, times(1)).reportVerificationBypassed(
                eq(TEST_ID), eq(bypassReason));
    }

    @Test
+20 −1
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ 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.developer.DeveloperVerificationSession.DEVELOPER_VERIFICATION_BYPASSED_REASON_ADB;
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;
@@ -3082,7 +3083,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            // adb installs are exempted from verification unless explicitly requested
            if (!params.forceVerification) {
                synchronized (mMetrics) {
                    mMetrics.onDeveloperVerificationBypassedByAdb();
                    mMetrics.onDeveloperVerificationBypassed(
                            DEVELOPER_VERIFICATION_BYPASSED_REASON_ADB);
                }
                return false;
            }
@@ -3091,6 +3093,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        synchronized (mLock) {
            if (TextUtils.equals(verifierPackageName, mPackageName)) {
                // The verifier itself is being updated. Skip.
                // TODO(b/360129657): log bypass reason and this bypass should only happen if the
                // current verifier cannot be connected or isn't responding.
                Slog.w(TAG, "Skipping verification service because the verifier is being updated");
                return false;
            }
@@ -3403,6 +3407,21 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            });
        }

        /**
         * Called by the VerifierController when the verification request has been bypassed by the
         * verifier.
         */
        public void onVerificationBypassedReceived(int bypassReason) {
            mHandler.post(() -> {
                synchronized (mMetrics) {
                    mMetrics.onDeveloperVerificationBypassed(bypassReason);
                }
                // The verifier informed the system to bypass the verification. Continue with the
                // rest of the verification and installation.
                resumeVerify();
            });
        }

        private void maybeSendUserActionForVerification(boolean blockingFailure,
                @Nullable PersistableBundle extensionResponse) {
            Intent intent = getUserNotificationIntent();
Loading