Loading core/api/system-current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -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 } core/java/android/content/pm/verify/developer/DeveloperVerificationSession.java +50 −6 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 { Loading @@ -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 { Loading @@ -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) { Loading @@ -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(); Loading core/java/android/content/pm/verify/developer/IDeveloperVerificationSessionInterface.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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 core/tests/coretests/src/android/content/pm/verify/developer/DeveloperVerificationSessionTest.java +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading services/core/java/com/android/server/pm/PackageInstallerSession.java +20 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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; } Loading Loading @@ -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 Loading
core/api/system-current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -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 }
core/java/android/content/pm/verify/developer/DeveloperVerificationSession.java +50 −6 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 { Loading @@ -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 { Loading @@ -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) { Loading @@ -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(); Loading
core/java/android/content/pm/verify/developer/IDeveloperVerificationSessionInterface.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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
core/tests/coretests/src/android/content/pm/verify/developer/DeveloperVerificationSessionTest.java +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
services/core/java/com/android/server/pm/PackageInstallerSession.java +20 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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; } Loading Loading @@ -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