Adds the basic API of the attestation verification framework.

Bug: 201696614
Change-Id: I59d90091106db6e6343f3a6fb698f01559841137
Test: N/A (non-functional API definition)
CTS-Coverage-Bug: 201337503
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 05e2e87..85df620 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3842,6 +3842,7 @@
             UWB_SERVICE,
             MEDIA_METRICS_SERVICE,
             SUPPLEMENTAL_PROCESS_SERVICE,
+            //@hide: ATTESTATION_VERIFICATION_SERVICE,
             //@hide: SAFETY_CENTER_SERVICE,
     })
     @Retention(RetentionPolicy.SOURCE)
@@ -5740,6 +5741,15 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve an
+     * {@link android.security.attestationverification.AttestationVerificationManager}.
+     * @see #getSystemService(String)
+     * @see android.security.attestationverification.AttestationVerificationManager
+     * @hide
+     */
+    public static final String ATTESTATION_VERIFICATION_SERVICE = "attestation_verification";
+
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve an
      * {@link android.security.FileIntegrityManager}.
      * @see #getSystemService(String)
      * @see android.security.FileIntegrityManager
diff --git a/core/java/android/security/attestationverification/AttestationProfile.aidl b/core/java/android/security/attestationverification/AttestationProfile.aidl
new file mode 100644
index 0000000..51696a9
--- /dev/null
+++ b/core/java/android/security/attestationverification/AttestationProfile.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2021 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 android.security.attestationverification;
+
+/**
+ * {@hide}
+ */
+parcelable AttestationProfile;
diff --git a/core/java/android/security/attestationverification/AttestationProfile.java b/core/java/android/security/attestationverification/AttestationProfile.java
new file mode 100644
index 0000000..7a43dac
--- /dev/null
+++ b/core/java/android/security/attestationverification/AttestationProfile.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2021 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 android.security.attestationverification;
+
+import static android.security.attestationverification.AttestationVerificationManager.PROFILE_APP_DEFINED;
+import static android.security.attestationverification.AttestationVerificationManager.PROFILE_UNKNOWN;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcelable;
+import android.security.attestationverification.AttestationVerificationManager.AttestationProfileId;
+import android.util.Log;
+
+import com.android.internal.util.DataClass;
+
+
+/**
+ * An attestation profile defining the security requirements for verifying the attestation of a
+ * remote compute environment.
+ *
+ * <p>This class is immutable and thread-safe. When checking this profile against an expected
+ * profile, it is recommended to construct the expected profile and compare them with {@code
+ * equals()}.
+ *
+ * @hide
+ * @see AttestationVerificationManager
+ */
+@DataClass(
+        genConstructor = false,
+        genEqualsHashCode = true
+)
+public final class AttestationProfile implements Parcelable {
+
+    private static final String TAG = "AVF";
+
+    /**
+     * The ID of a system-defined attestation profile.
+     *
+     * See constants in {@link AttestationVerificationManager} prefixed with {@code PROFILE_}. If
+     * this has the value of {@link AttestationVerificationManager#PROFILE_APP_DEFINED}, then the
+     * packageName and profileName are non-null.
+     */
+    @AttestationProfileId
+    private final int mAttestationProfileId;
+
+    /**
+     * The package name of a app-defined attestation profile.
+     *
+     * This value will be null unless the value of attestationProfileId is {@link
+     * AttestationVerificationManager#PROFILE_APP_DEFINED}.
+     */
+    @Nullable
+    private final String mPackageName;
+
+
+    /**
+     * The name of an app-defined attestation profile.
+     *
+     * This value will be null unless the value of attestationProfileId is {@link
+     * AttestationVerificationManager#PROFILE_APP_DEFINED}.
+     */
+    @Nullable
+    private final String mProfileName;
+
+    private AttestationProfile(
+            @AttestationProfileId int attestationProfileId,
+            @Nullable String packageName,
+            @Nullable String profileName) {
+        mAttestationProfileId = attestationProfileId;
+        mPackageName = packageName;
+        mProfileName = profileName;
+    }
+
+    /**
+     * Create a profile with the given id.
+     *
+     * <p>This constructor is for specifying a profile which is defined by the system. These are
+     * available as constants in the {@link AttestationVerificationManager} class prefixed with
+     * {@code PROFILE_}.
+     *
+     * @param attestationProfileId the ID of the system-defined profile
+     * @throws IllegalArgumentException when called with
+     * {@link AttestationVerificationManager#PROFILE_APP_DEFINED}
+     *                                  (use {@link #AttestationProfile(String, String)})
+     */
+    public AttestationProfile(@AttestationProfileId int attestationProfileId) {
+        this(attestationProfileId, null, null);
+        if (attestationProfileId == PROFILE_APP_DEFINED) {
+            throw new IllegalArgumentException("App-defined profiles must be specified with the "
+                    + "constructor AttestationProfile#constructor(String, String)");
+        }
+    }
+
+    /**
+     * Create a profile with the given package name and profile name.
+     *
+     * <p>This constructor is for specifying a profile defined by an app. The packageName must
+     * match the package name of the app that defines the profile (as specified in the {@code
+     * package} attribute of the {@code
+     * <manifest>} tag in the app's manifest. The profile name matches the {@code name} attribute
+     * of the {@code <attestation-profile>} tag.
+     *
+     * <p>Apps must declare profiles in their manifest as an {@code <attestation-profile>} element.
+     * However, this constructor does not verify that such a profile exists. If the profile does not
+     * exist, verifications will fail.
+     *
+     * @param packageName the package name of the app defining the profile
+     * @param profileName the name of the profile
+     */
+    public AttestationProfile(@NonNull String packageName, @NonNull String profileName) {
+        this(PROFILE_APP_DEFINED, packageName, profileName);
+        if (packageName == null || profileName == null) {
+            throw new IllegalArgumentException("Both packageName and profileName must be non-null");
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (mAttestationProfileId == PROFILE_APP_DEFINED) {
+            return "AttestationProfile(package=" + mPackageName + ", name=" + mProfileName + ")";
+        } else {
+            String humanReadableProfileId;
+            switch (mAttestationProfileId) {
+                case PROFILE_UNKNOWN:
+                    humanReadableProfileId = "PROFILE_UNKNOWN";
+                    break;
+                default:
+                    Log.e(TAG, "ERROR: Missing case in AttestationProfile#toString");
+                    humanReadableProfileId = "ERROR";
+            }
+            return "AttestationProfile(" + humanReadableProfileId + "/" + mAttestationProfileId
+                    + ")";
+        }
+    }
+
+
+    // Code below generated by codegen v1.0.23.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/security
+    // /attestationverification/AttestationProfile.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /**
+     * The ID of a system-defined attestation profile.
+     *
+     * See constants in {@link AttestationVerificationManager} prefixed with {@code PROFILE_}. If
+     * this has the value of {@link AttestationVerificationManager#PROFILE_APP_DEFINED}, then the
+     * packageName and profileName are non-null.
+     */
+    @DataClass.Generated.Member
+    public @AttestationProfileId int getAttestationProfileId() {
+        return mAttestationProfileId;
+    }
+
+    /**
+     * The package name of a app-defined attestation profile.
+     *
+     * This value will be null unless the value of attestationProfileId is {@link
+     * AttestationVerificationManager#PROFILE_APP_DEFINED}.
+     */
+    @DataClass.Generated.Member
+    public @Nullable String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * The name of an app-defined attestation profile.
+     *
+     * This value will be null unless the value of attestationProfileId is {@link
+     * AttestationVerificationManager#PROFILE_APP_DEFINED}.
+     */
+    @DataClass.Generated.Member
+    public @Nullable String getProfileName() {
+        return mProfileName;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public boolean equals(@Nullable Object o) {
+        // You can override field equality logic by defining either of the methods like:
+        // boolean fieldNameEquals(AttestationProfile other) { ... }
+        // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        @SuppressWarnings("unchecked")
+        AttestationProfile that = (AttestationProfile) o;
+        //noinspection PointlessBooleanExpression
+        return true
+                && mAttestationProfileId == that.mAttestationProfileId
+                && java.util.Objects.equals(mPackageName, that.mPackageName)
+                && java.util.Objects.equals(mProfileName, that.mProfileName);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int hashCode() {
+        // You can override field hashCode logic by defining methods like:
+        // int fieldNameHashCode() { ... }
+
+        int _hash = 1;
+        _hash = 31 * _hash + mAttestationProfileId;
+        _hash = 31 * _hash + java.util.Objects.hashCode(mPackageName);
+        _hash = 31 * _hash + java.util.Objects.hashCode(mProfileName);
+        return _hash;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        byte flg = 0;
+        if (mPackageName != null) flg |= 0x2;
+        if (mProfileName != null) flg |= 0x4;
+        dest.writeByte(flg);
+        dest.writeInt(mAttestationProfileId);
+        if (mPackageName != null) dest.writeString(mPackageName);
+        if (mProfileName != null) dest.writeString(mProfileName);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ AttestationProfile(@NonNull android.os.Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        byte flg = in.readByte();
+        int attestationProfileId = in.readInt();
+        String packageName = (flg & 0x2) == 0 ? null : in.readString();
+        String profileName = (flg & 0x4) == 0 ? null : in.readString();
+
+        this.mAttestationProfileId = attestationProfileId;
+        com.android.internal.util.AnnotationValidations.validate(
+                AttestationProfileId.class, null, mAttestationProfileId);
+        this.mPackageName = packageName;
+        this.mProfileName = profileName;
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<AttestationProfile> CREATOR
+            = new Parcelable.Creator<AttestationProfile>() {
+        @Override
+        public AttestationProfile[] newArray(int size) {
+            return new AttestationProfile[size];
+        }
+
+        @Override
+        public AttestationProfile createFromParcel(@NonNull android.os.Parcel in) {
+            return new AttestationProfile(in);
+        }
+    };
+
+    @DataClass.Generated(
+            time = 1633629498403L,
+            codegenVersion = "1.0.23",
+            sourceFile = "frameworks/base/core/java/android/security/attestationverification/AttestationProfile.java",
+            inputSignatures = "private static final  java.lang.String TAG\nprivate final @android.security.attestationverification.AttestationVerificationManager.AttestationProfileId int mAttestationProfileId\nprivate final @android.annotation.Nullable java.lang.String mPackageName\nprivate final @android.annotation.Nullable java.lang.String mProfileName\npublic @java.lang.Override java.lang.String toString()\nclass AttestationProfile extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genEqualsHashCode=true)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/core/java/android/security/attestationverification/AttestationVerificationManager.java b/core/java/android/security/attestationverification/AttestationVerificationManager.java
new file mode 100644
index 0000000..8ed5b20
--- /dev/null
+++ b/core/java/android/security/attestationverification/AttestationVerificationManager.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2021 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 android.security.attestationverification;
+
+import android.Manifest;
+import android.annotation.CallbackExecutor;
+import android.annotation.CheckResult;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemService;
+import android.content.Context;
+import android.os.Bundle;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
+
+/**
+ * Provides methods for verifying that attestations from remote compute environments meet minimum
+ * security requirements specified by attestation profiles.
+ *
+ * @hide
+ */
+@SystemService(Context.ATTESTATION_VERIFICATION_SERVICE)
+public class AttestationVerificationManager {
+
+    /**
+     * Verifies that {@code attestation} describes a computing environment that meets the
+     * requirements of {@code profile}, {@code localBindingType}, and {@code requirements}.
+     *
+     * <p>This method verifies that at least one system-registered {@linkplain
+     * AttestationVerificationService attestation verifier} associated with {@code profile} and
+     * {@code localBindingType} has verified that {@code attestation} attests that the remote
+     * environment matching the local binding data (determined by {@code localBindingType}) in
+     * {@code requirements} meets the requirements of the profile.
+     *
+     * <p>For successful verification, the {@code requirements} bundle must contain locally-known
+     * data which must match {@code attestation}. The required data in the bundle is defined by the
+     * {@code localBindingType} (see documentation for the type). Verifiers will fail to verify the
+     * attestation if the bundle contains unsupported data.
+     *
+     * <p>The {@code localBindingType} specifies how {@code attestation} is bound to a local
+     * secure channel endpoint or similar connection with the target remote environment described by
+     * the attestation. The binding is expected to be related to a cryptographic protocol, and each
+     * binding type requires specific arguments to be present in the {@code requirements} bundle. It
+     * is this binding to something known locally that ensures an attestation is not only valid, but
+     * is also associated with a particular connection.
+     *
+     * <p>The {@code callback} is called with a result and {@link VerificationToken} (which may be
+     * null). The result is an integer (see constants in this class with the prefix {@code RESULT_}.
+     * The result is {@link #RESULT_SUCCESS} when at least one verifier has passed its checks. The
+     * token may be used in calls to other parts of the system.
+     *
+     * <p>It's expected that a verifier will be able to decode and understand the passed values,
+     * otherwise fail to verify. {@code attestation} should contain some type data to prevent parse
+     * errors.
+     *
+     * <p>The values put into the {@code requirements} Bundle depend on the {@code
+     * localBindingType} used.
+     *
+     * @param profile          the attestation profile which defines the security requirements which
+     *                         must be met by the environment described by {@code attestation}
+     * @param localBindingType the type of the local binding data; see constants in this class with
+     *                         the prefix {@code TYPE_}
+     * @param requirements     a {@link Bundle} containing locally-known data which must match
+     *                         {@code attestation}
+     * @param attestation      attestation data which describes a remote computing environment
+     * @param executor         {@code callback} will be executed on this executor
+     * @param callback         will be called with the results of the verification
+     * @see AttestationVerificationService
+     */
+    @RequiresPermission(Manifest.permission.USE_ATTESTATION_VERIFICATION_SERVICE)
+    public void verifyAttestation(
+            @NonNull AttestationProfile profile,
+            @LocalBindingType int localBindingType,
+            @NonNull Bundle requirements,
+            @NonNull byte[] attestation,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull BiConsumer<@VerificationResult Integer, VerificationToken> callback) {
+        executor.execute(() -> callback.accept(RESULT_UNKNOWN, null));
+    }
+
+    /**
+     * Verifies that {@code token} is a valid token, returning the result contained in valid
+     * tokens.
+     *
+     * <p>This verifies that the token was issued by the platform and thus the system verified
+     * attestation data against the specified {@code profile}, {@code localBindingType}, and {@code
+     * requirements}. The value returned by this method is the same as the one originally returned
+     * when the token was generated. Callers of this method should not trust the provider of the
+     * token to also specify the profile, local binding type, or requirements, but instead have
+     * their own security requirements about these arguments.
+     *
+     * <p>This method, in contrast to {@code verifyAttestation}, executes synchronously and only
+     * checks that a previous verification succeeded. This allows callers to pass the token to
+     * others, including system APIs, without those components needing to re-verify the attestation
+     * data, an operation which can take several seconds.
+     *
+     * <p>When {@code maximumAge} is not specified (null), this method verifies the token was
+     * generated in the past hour. Otherwise, it verifies the token was generated between now and
+     * {@code maximumAge} ago. The maximum value of {@code maximumAge} is one hour; specifying a
+     * duration greater than one hour will result in an {@link IllegalArgumentException}.
+     *
+     * @param profile          the attestation profile which must be in the token
+     * @param localBindingType the local binding type which must be in the token
+     * @param requirements     the requirements which must be in the token
+     * @param token            the token to be verified
+     * @param maximumAge       the maximum age to accept for the token
+     */
+    @RequiresPermission(Manifest.permission.USE_ATTESTATION_VERIFICATION_SERVICE)
+    @CheckResult
+    @VerificationResult
+    public int verifyToken(
+            @NonNull AttestationProfile profile,
+            @LocalBindingType int localBindingType,
+            @NonNull Bundle requirements,
+            @NonNull VerificationToken token,
+            @Nullable java.time.Duration maximumAge) {
+        return RESULT_UNKNOWN;
+    }
+
+    /** @hide */
+    public AttestationVerificationManager() {
+    }
+
+    /** @hide */
+    @IntDef(
+            prefix = {"PROFILE_"},
+            value = {
+                    PROFILE_UNKNOWN,
+                    PROFILE_APP_DEFINED,
+                    PROFILE_SELF_TRUSTED,
+                    PROFILE_PEER_DEVICE,
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AttestationProfileId {
+    }
+
+    /**
+     * The profile is unknown because it is a profile unknown to this version of the SDK.
+     */
+    public static final int PROFILE_UNKNOWN = 0;
+
+    /** The profile is defined by an app. */
+    public static final int PROFILE_APP_DEFINED = 1;
+
+    /**
+     * A system-defined profile which verifies that the attesting environment can create an
+     * attestation with the same root certificate as the verifying device with a matching
+     * attestation challenge.
+     *
+     * This profile is intended to be used only for testing.
+     */
+    public static final int PROFILE_SELF_TRUSTED = 2;
+
+    /**
+     * A system-defined profile which verifies that the attesting environment environment is similar
+     * to the current device in terms of security model and security configuration. This category is
+     * fairly broad and most securely configured Android devices should qualify, along with a
+     * variety of non-Android devices.
+     */
+    public static final int PROFILE_PEER_DEVICE = 3;
+
+    /** @hide */
+    @IntDef(
+            prefix = {"TYPE_"},
+            value = {
+                    TYPE_UNKNOWN,
+                    TYPE_APP_DEFINED,
+                    TYPE_PUBLIC_KEY,
+                    TYPE_CHALLENGE,
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface LocalBindingType {
+    }
+
+    /**
+     * The type of the local binding data is unknown because it is a type unknown to this version of
+     * the SDK.
+     */
+    public static final int TYPE_UNKNOWN = 0;
+
+    /**
+     * A local binding type for app-defined profiles which use local binding data which does not
+     * match any of the existing system-defined types.
+     */
+    public static final int TYPE_APP_DEFINED = 1;
+
+    /**
+     * A local binding type where the attestation is bound to a public key negotiated and
+     * authenticated to a public key.
+     *
+     * <p>When using this type, the {@code requirements} bundle contains values for:
+     * <ul>
+     *   <li>{@link #PARAM_PUBLIC_KEY}
+     *   <li>{@link #PARAM_ID}: identifying the remote environment, optional
+     * </ul>
+     */
+    public static final int TYPE_PUBLIC_KEY = 2;
+
+    /**
+     * A local binding type where the attestation is bound to a challenge.
+     *
+     * <p>When using this type, the {@code requirements} bundle contains values for:
+     * <ul>
+     *   <li>{@link #PARAM_CHALLENGE}: containing the challenge
+     * </ul>
+     */
+    public static final int TYPE_CHALLENGE = 3;
+
+    /** @hide */
+    @IntDef(
+            prefix = {"RESULT_"},
+            value = {
+                    RESULT_UNKNOWN,
+                    RESULT_SUCCESS,
+                    RESULT_FAILURE,
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
+    public @interface VerificationResult {
+    }
+
+    /** The result of the verification is unknown because it has a value unknown to this SDK. */
+    public static final int RESULT_UNKNOWN = 0;
+
+    /** The result of the verification was successful. */
+    public static final int RESULT_SUCCESS = 1;
+
+    /**
+     * The result of the attestation verification was failure. The attestation could not be
+     * verified.
+     */
+    public static final int RESULT_FAILURE = 2;
+
+    /**
+     * Requirements bundle parameter key for a public key, a byte array.
+     *
+     * <p>This should contain the encoded key bytes according to the ASN.1 type
+     * {@code SubjectPublicKeyInfo} defined in the X.509 standard, the same as a call to {@link
+     * java.security.spec.X509EncodedKeySpec#getEncoded()} would produce.
+     *
+     * @see Bundle#putByteArray(String, byte[])
+     */
+    public static final String PARAM_PUBLIC_KEY = "localbinding.public_key";
+
+    /** Requirements bundle parameter key for an ID, String. */
+    public static final String PARAM_ID = "localbinding.id";
+
+    /** Requirements bundle parameter for a challenge. */
+    public static final String PARAM_CHALLENGE = "localbinding.challenge";
+}
diff --git a/core/java/android/security/attestationverification/AttestationVerificationService.java b/core/java/android/security/attestationverification/AttestationVerificationService.java
new file mode 100644
index 0000000..26c3051
--- /dev/null
+++ b/core/java/android/security/attestationverification/AttestationVerificationService.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2021 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 android.security.attestationverification;
+
+import android.annotation.CheckResult;
+import android.annotation.NonNull;
+import android.app.Service;
+import android.os.Bundle;
+import android.security.attestationverification.AttestationVerificationManager.VerificationResult;
+
+/**
+ * A verifier which can be implemented by apps to verify an attestation (as described in {@link
+ * AttestationVerificationManager}).
+ *
+ * In the manifest for this service, specify the profile and local binding type this verifier
+ * supports. Create a new service for each combination of profile & local binding type that your app
+ * supports. Each service must declare an {@code intent-filter} action of {@link #SERVICE_INTERFACE}
+ * and permission of {@link android.Manifest.permission#BIND_ATTESTATION_VERIFICATION_SERVICE}.
+ *
+ * <p>Example:
+ * {@code
+ * <pre>
+ * <service android:name=".MyAttestationVerificationService"
+ *          android:permission="android.permission.BIND_ATTESTATION_VERIFICATION_SERVICE"
+ *          android:exported="true">
+ *   <intent-filter>
+ *     <action
+ *         android:name="android.security.attestationverification.AttestationVerificationService" />
+ *   </intent-filter>
+ *   <meta-data android:name="android.security.attestationverification.PROFILE_ID"
+ *              android:value="PROFILE_PLACEHOLDER_0" />
+ *   <meta-data android:name="android.security.attestationverification.LOCAL_BINDING_TYPE"
+ *              android:value="TYPE_PLACEHOLDER_0" />
+ * </service>
+ * </pre>
+ * }
+ *
+ * <p>For app-defined profiles, an example of the {@code <meta-data>}:
+ * {@code
+ * <pre>
+ *   <meta-data android:name="android.security.attestation.PROFILE_PACKAGE_NAME"
+ *              android:value="com.example" />
+ *   <meta-data android:name="android.security.attestation.PROFILE_NAME"
+ *              android:value="com.example.profile.PROFILE_FOO" />
+ * </pre>
+ * }
+ *
+ * @hide
+ */
+public abstract class AttestationVerificationService extends Service {
+
+    /**
+     * An intent action for a service to be bound and act as an attestation verifier.
+     *
+     * <p>The app will be kept alive for a short duration between verification calls after which
+     * the system will unbind from this service making the app eligible for cleanup.
+     *
+     * <p>The service must also require permission
+     * {@link android.Manifest.permission#BIND_ATTESTATION_VERIFICATION_SERVICE}.
+     */
+    public static final String SERVICE_INTERFACE =
+            "android.security.attestationverification.AttestationVerificationService";
+
+    /**
+     * Verifies that {@code attestation} attests that the device identified by the local binding
+     * data in {@code requirements} meets the minimum requirements of this verifier for this
+     * verifier's profile.
+     *
+     * <p>Called by the system to verify an attestation.
+     *
+     * <p>The data passed into this method comes directly from apps and should be treated as
+     * potentially dangerous user input.
+     *
+     * @param requirements a {@link Bundle} containing locally-known data which must match {@code
+     *                     attestation}
+     * @param attestation  the attestation to verify
+     * @return whether the verification passed
+     * @see AttestationVerificationManager#verifyAttestation(AttestationProfile, int, Bundle,
+     * byte[], java.util.concurrent.Executor, java.util.function.BiConsumer)
+     */
+    @CheckResult
+    @VerificationResult
+    public abstract int onVerifyPeerDeviceAttestation(
+            @NonNull Bundle requirements,
+            @NonNull byte[] attestation);
+}
diff --git a/core/java/android/security/attestationverification/VerificationToken.aidl b/core/java/android/security/attestationverification/VerificationToken.aidl
new file mode 100644
index 0000000..666a8b0
--- /dev/null
+++ b/core/java/android/security/attestationverification/VerificationToken.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2021 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 android.security.attestationverification;
+
+/**
+ * {@hide}
+ */
+parcelable VerificationToken;
diff --git a/core/java/android/security/attestationverification/VerificationToken.java b/core/java/android/security/attestationverification/VerificationToken.java
new file mode 100644
index 0000000..ae26823
--- /dev/null
+++ b/core/java/android/security/attestationverification/VerificationToken.java
@@ -0,0 +1,523 @@
+/*
+ * Copyright (C) 2021 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 android.security.attestationverification;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.security.attestationverification.AttestationVerificationManager.LocalBindingType;
+import android.security.attestationverification.AttestationVerificationManager.VerificationResult;
+
+import com.android.internal.util.DataClass;
+import com.android.internal.util.Parcelling;
+import com.android.internal.util.Parcelling.BuiltIn.ForInstant;
+
+import java.time.Duration;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
+
+/**
+ * Token representing the result of an attestation verification, which can be passed to other parts
+ * of the OS or other apps as proof of the verification.
+ *
+ * Tokens are only valid within the same UID (which means within a single app unless the deprecated
+ * android:sharedUserId manifest value is used).
+ *
+ * @hide
+ * @see Bundle#putParcelable(String, Parcelable)
+ */
+@DataClass(
+        genConstructor = false,
+        genHiddenBuilder = true
+)
+public final class VerificationToken implements Parcelable {
+
+    /**
+     * The attestation profile which was used to perform the verification.
+     * @hide
+     */
+    @NonNull
+    private final AttestationProfile mAttestationProfile;
+
+    /**
+     * The local binding type of the local binding data used to perform the verification.
+     * @hide
+     */
+    @LocalBindingType
+    private final int mLocalBindingType;
+
+    /**
+     * The requirements used to perform the verification.
+     * @hide
+     */
+    @NonNull
+    private final Bundle mRequirements;
+
+    /**
+     * The result of the {@link AttestationVerificationManager#verifyAttestation(int, int, Bundle,
+     * byte[], Executor, BiConsumer)} call. This value is kept hidden to prevent token holders from
+     * accidentally reading this value without calling {@code verifyToken}. Do <b>not</b> use this
+     * value directly; call {@link AttestationVerificationManager#verifyToken(VerificationToken,
+     * Duration)} to verify a valid token and it will return this value.
+     *
+     * If the token is valid, this value is returned directly by {#verifyToken}.
+     *
+     * @hide
+     */
+    @VerificationResult
+    private final int mVerificationResult;
+
+    /**
+     * Time when the token was generated, set by the system.
+     */
+    @NonNull
+    @DataClass.ParcelWith(ForInstant.class)
+    private final java.time.Instant mVerificationTime;
+
+    /**
+     * A Hash-based message authentication code used to verify the contents and authenticity of the
+     * rest of the token. The hash is created using a secret key known only to the system server.
+     * When verifying the token, the system re-hashes the token and verifies the generated HMAC is
+     * the same.
+     *
+     * @hide
+     */
+    @NonNull
+    private final byte[] mHmac;
+
+    /**
+     * The UID of the process which called {@code verifyAttestation} to create the token, as
+     * returned by {@link Binder#getCallingUid()}. Calls to {@code verifyToken} will fail if the UID
+     * of calling process does not match this value. This ensures that tokens cannot be shared
+     * between UIDs.
+     *
+     * @hide
+     */
+    private int mUid;
+
+
+    // Code below generated by codegen v1.0.23.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/security/attestationverification/VerificationToken.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    @DataClass.Generated.Member
+    /* package-private */ VerificationToken(
+            @NonNull AttestationProfile attestationProfile,
+            @LocalBindingType int localBindingType,
+            @NonNull Bundle requirements,
+            @VerificationResult int verificationResult,
+            @NonNull java.time.Instant verificationTime,
+            @NonNull byte[] hmac,
+            int uid) {
+        this.mAttestationProfile = attestationProfile;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mAttestationProfile);
+        this.mLocalBindingType = localBindingType;
+        com.android.internal.util.AnnotationValidations.validate(
+                LocalBindingType.class, null, mLocalBindingType);
+        this.mRequirements = requirements;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mRequirements);
+        this.mVerificationResult = verificationResult;
+        com.android.internal.util.AnnotationValidations.validate(
+                VerificationResult.class, null, mVerificationResult);
+        this.mVerificationTime = verificationTime;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mVerificationTime);
+        this.mHmac = hmac;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mHmac);
+        this.mUid = uid;
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    /**
+     * The attestation profile which was used to perform the verification.
+     */
+    @DataClass.Generated.Member
+    public @NonNull AttestationProfile getAttestationProfile() {
+        return mAttestationProfile;
+    }
+
+    /**
+     * The local binding type of the local binding data used to perform the verification.
+     */
+    @DataClass.Generated.Member
+    public @LocalBindingType int getLocalBindingType() {
+        return mLocalBindingType;
+    }
+
+    /**
+     * The requirements used to perform the verification.
+     */
+    @DataClass.Generated.Member
+    public @NonNull Bundle getRequirements() {
+        return mRequirements;
+    }
+
+    /**
+     * The result of the {@link AttestationVerificationManager#verifyAttestation(int, int, Bundle,
+     * byte[], Executor, BiConsumer)} call. This value is kept hidden to prevent token holders from
+     * accidentally reading this value without calling {@code verifyToken}. Do <b>not</b> use this
+     * value directly; call {@link AttestationVerificationManager#verifyToken(VerificationToken,
+     * Duration)} to verify a valid token and it will return this value.
+     *
+     * If the token is valid, this value is returned directly by {#verifyToken}.
+     *
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public @VerificationResult int getVerificationResult() {
+        return mVerificationResult;
+    }
+
+    /**
+     * Time when the token was generated, set by the system.
+     */
+    @DataClass.Generated.Member
+    public @NonNull java.time.Instant getVerificationTime() {
+        return mVerificationTime;
+    }
+
+    /**
+     * A Hash-based message authentication code used to verify the contents and authenticity of the
+     * rest of the token. The hash is created using a secret key known only to the system server.
+     * When verifying the token, the system re-hashes the token and verifies the generated HMAC is
+     * the same.
+     *
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public @NonNull byte[] getHmac() {
+        return mHmac;
+    }
+
+    /**
+     * The UID of the process which called {@code verifyAttestation} to create the token, as
+     * returned by {@link Binder#getCallingUid()}. Calls to {@code verifyToken} will fail if the UID
+     * of calling process does not match this value. This ensures that tokens cannot be shared
+     * between UIDs.
+     *
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public int getUid() {
+        return mUid;
+    }
+
+    @DataClass.Generated.Member
+    static Parcelling<java.time.Instant> sParcellingForVerificationTime =
+            Parcelling.Cache.get(
+                    ForInstant.class);
+    static {
+        if (sParcellingForVerificationTime == null) {
+            sParcellingForVerificationTime = Parcelling.Cache.put(
+                    new ForInstant());
+        }
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        dest.writeTypedObject(mAttestationProfile, flags);
+        dest.writeInt(mLocalBindingType);
+        dest.writeBundle(mRequirements);
+        dest.writeInt(mVerificationResult);
+        sParcellingForVerificationTime.parcel(mVerificationTime, dest, flags);
+        dest.writeByteArray(mHmac);
+        dest.writeInt(mUid);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ VerificationToken(@NonNull android.os.Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        AttestationProfile attestationProfile = (AttestationProfile) in.readTypedObject(AttestationProfile.CREATOR);
+        int localBindingType = in.readInt();
+        Bundle requirements = in.readBundle();
+        int verificationResult = in.readInt();
+        java.time.Instant verificationTime = sParcellingForVerificationTime.unparcel(in);
+        byte[] hmac = in.createByteArray();
+        int uid = in.readInt();
+
+        this.mAttestationProfile = attestationProfile;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mAttestationProfile);
+        this.mLocalBindingType = localBindingType;
+        com.android.internal.util.AnnotationValidations.validate(
+                LocalBindingType.class, null, mLocalBindingType);
+        this.mRequirements = requirements;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mRequirements);
+        this.mVerificationResult = verificationResult;
+        com.android.internal.util.AnnotationValidations.validate(
+                VerificationResult.class, null, mVerificationResult);
+        this.mVerificationTime = verificationTime;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mVerificationTime);
+        this.mHmac = hmac;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mHmac);
+        this.mUid = uid;
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<VerificationToken> CREATOR
+            = new Parcelable.Creator<VerificationToken>() {
+        @Override
+        public VerificationToken[] newArray(int size) {
+            return new VerificationToken[size];
+        }
+
+        @Override
+        public VerificationToken createFromParcel(@NonNull android.os.Parcel in) {
+            return new VerificationToken(in);
+        }
+    };
+
+    /**
+     * A builder for {@link VerificationToken}
+     * @hide
+     */
+    @SuppressWarnings("WeakerAccess")
+    @DataClass.Generated.Member
+    public static final class Builder {
+
+        private @NonNull AttestationProfile mAttestationProfile;
+        private @LocalBindingType int mLocalBindingType;
+        private @NonNull Bundle mRequirements;
+        private @VerificationResult int mVerificationResult;
+        private @NonNull java.time.Instant mVerificationTime;
+        private @NonNull byte[] mHmac;
+        private int mUid;
+
+        private long mBuilderFieldsSet = 0L;
+
+        /**
+         * Creates a new Builder.
+         *
+         * @param attestationProfile
+         *   The attestation profile which was used to perform the verification.
+         * @param localBindingType
+         *   The local binding type of the local binding data used to perform the verification.
+         * @param requirements
+         *   The requirements used to perform the verification.
+         * @param verificationResult
+         *   The result of the {@link AttestationVerificationManager#verifyAttestation(int, int, Bundle,
+         *   byte[], Executor, BiConsumer)} call. This value is kept hidden to prevent token holders from
+         *   accidentally reading this value without calling {@code verifyToken}. Do <b>not</b> use this
+         *   value directly; call {@link AttestationVerificationManager#verifyToken(VerificationToken,
+         *   Duration)} to verify a valid token and it will return this value.
+         *
+         *   If the token is valid, this value is returned directly by {#verifyToken}.
+         * @param verificationTime
+         *   Time when the token was generated, set by the system.
+         * @param hmac
+         *   A Hash-based message authentication code used to verify the contents and authenticity of the
+         *   rest of the token. The hash is created using a secret key known only to the system server.
+         *   When verifying the token, the system re-hashes the token and verifies the generated HMAC is
+         *   the same.
+         * @param uid
+         *   The UID of the process which called {@code verifyAttestation} to create the token, as
+         *   returned by {@link Binder#getCallingUid()}. Calls to {@code verifyToken} will fail if the UID
+         *   of calling process does not match this value. This ensures that tokens cannot be shared
+         *   between UIDs.
+         */
+        public Builder(
+                @NonNull AttestationProfile attestationProfile,
+                @LocalBindingType int localBindingType,
+                @NonNull Bundle requirements,
+                @VerificationResult int verificationResult,
+                @NonNull java.time.Instant verificationTime,
+                @NonNull byte[] hmac,
+                int uid) {
+            mAttestationProfile = attestationProfile;
+            com.android.internal.util.AnnotationValidations.validate(
+                    NonNull.class, null, mAttestationProfile);
+            mLocalBindingType = localBindingType;
+            com.android.internal.util.AnnotationValidations.validate(
+                    LocalBindingType.class, null, mLocalBindingType);
+            mRequirements = requirements;
+            com.android.internal.util.AnnotationValidations.validate(
+                    NonNull.class, null, mRequirements);
+            mVerificationResult = verificationResult;
+            com.android.internal.util.AnnotationValidations.validate(
+                    VerificationResult.class, null, mVerificationResult);
+            mVerificationTime = verificationTime;
+            com.android.internal.util.AnnotationValidations.validate(
+                    NonNull.class, null, mVerificationTime);
+            mHmac = hmac;
+            com.android.internal.util.AnnotationValidations.validate(
+                    NonNull.class, null, mHmac);
+            mUid = uid;
+        }
+
+        /**
+         * The attestation profile which was used to perform the verification.
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setAttestationProfile(@NonNull AttestationProfile value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x1;
+            mAttestationProfile = value;
+            return this;
+        }
+
+        /**
+         * The local binding type of the local binding data used to perform the verification.
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setLocalBindingType(@LocalBindingType int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x2;
+            mLocalBindingType = value;
+            return this;
+        }
+
+        /**
+         * The requirements used to perform the verification.
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setRequirements(@NonNull Bundle value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x4;
+            mRequirements = value;
+            return this;
+        }
+
+        /**
+         * The result of the {@link AttestationVerificationManager#verifyAttestation(int, int, Bundle,
+         * byte[], Executor, BiConsumer)} call. This value is kept hidden to prevent token holders from
+         * accidentally reading this value without calling {@code verifyToken}. Do <b>not</b> use this
+         * value directly; call {@link AttestationVerificationManager#verifyToken(VerificationToken,
+         * Duration)} to verify a valid token and it will return this value.
+         *
+         * If the token is valid, this value is returned directly by {#verifyToken}.
+         *
+         * @hide
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setVerificationResult(@VerificationResult int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x8;
+            mVerificationResult = value;
+            return this;
+        }
+
+        /**
+         * Time when the token was generated, set by the system.
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setVerificationTime(@NonNull java.time.Instant value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x10;
+            mVerificationTime = value;
+            return this;
+        }
+
+        /**
+         * A Hash-based message authentication code used to verify the contents and authenticity of the
+         * rest of the token. The hash is created using a secret key known only to the system server.
+         * When verifying the token, the system re-hashes the token and verifies the generated HMAC is
+         * the same.
+         *
+         * @hide
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setHmac(@NonNull byte... value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x20;
+            mHmac = value;
+            return this;
+        }
+
+        /**
+         * The UID of the process which called {@code verifyAttestation} to create the token, as
+         * returned by {@link Binder#getCallingUid()}. Calls to {@code verifyToken} will fail if the UID
+         * of calling process does not match this value. This ensures that tokens cannot be shared
+         * between UIDs.
+         *
+         * @hide
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setUid(int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x40;
+            mUid = value;
+            return this;
+        }
+
+        /** Builds the instance. This builder should not be touched after calling this! */
+        public @NonNull VerificationToken build() {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x80; // Mark builder used
+
+            VerificationToken o = new VerificationToken(
+                    mAttestationProfile,
+                    mLocalBindingType,
+                    mRequirements,
+                    mVerificationResult,
+                    mVerificationTime,
+                    mHmac,
+                    mUid);
+            return o;
+        }
+
+        private void checkNotUsed() {
+            if ((mBuilderFieldsSet & 0x80) != 0) {
+                throw new IllegalStateException(
+                        "This Builder should not be reused. Use a new Builder instance instead");
+            }
+        }
+    }
+
+    @DataClass.Generated(
+            time = 1633629747234L,
+            codegenVersion = "1.0.23",
+            sourceFile = "frameworks/base/core/java/android/security/attestationverification/VerificationToken.java",
+            inputSignatures = "private final @android.annotation.NonNull android.security.attestationverification.AttestationProfile mAttestationProfile\nprivate final @android.security.attestationverification.AttestationVerificationManager.LocalBindingType int mLocalBindingType\nprivate final @android.annotation.NonNull android.os.Bundle mRequirements\nprivate final  @android.security.attestationverification.AttestationVerificationManager.VerificationResult int mVerificationResult\nprivate final @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInstant.class) java.time.Instant mVerificationTime\nprivate final @android.annotation.NonNull byte[] mHmac\nprivate  int mUid\nclass VerificationToken extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genHiddenBuilder=true)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/core/java/android/security/attestationverification/package.html b/core/java/android/security/attestationverification/package.html
new file mode 100644
index 0000000..783d0a1
--- /dev/null
+++ b/core/java/android/security/attestationverification/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
diff --git a/core/java/com/android/internal/util/Parcelling.java b/core/java/com/android/internal/util/Parcelling.java
index 1ab316d..3147c34 100644
--- a/core/java/com/android/internal/util/Parcelling.java
+++ b/core/java/com/android/internal/util/Parcelling.java
@@ -23,6 +23,7 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -306,5 +307,33 @@
                 return string == null ? null : UUID.fromString(string);
             }
         }
+
+        /**
+         * A {@link Parcelling} for {@link Instant}.
+         *
+         * The minimum value of an instant uses a millisecond offset of about -3.15e19 which is
+         * larger than Long.MIN_VALUE, so we can use Long.MIN_VALUE as a sentinel value to indicate
+         * a null Instant.
+         */
+        class ForInstant implements Parcelling<Instant> {
+
+            @Override
+            public void parcel(Instant item, Parcel dest, int parcelFlags) {
+                dest.writeLong(item == null ? Long.MIN_VALUE : item.getEpochSecond());
+                dest.writeInt(item == null ? Integer.MIN_VALUE : item.getNano());
+            }
+
+            @Override
+            public Instant unparcel(Parcel source) {
+                long epochSecond = source.readLong();
+                int afterNano = source.readInt();
+
+                if (epochSecond == Long.MIN_VALUE) {
+                    return null;
+                } else {
+                    return Instant.ofEpochSecond(epochSecond, afterNano);
+                }
+            }
+        }
     }
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d926f98..d7dd379 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3470,6 +3470,23 @@
     <permission android:name="android.permission.UPDATE_FONTS"
         android:protectionLevel="signature|privileged" />
 
+    <!-- Allows an application to use the AttestationVerificationService.
+         @hide -->
+    <permission android:name="android.permission.USE_ATTESTATION_VERIFICATION_SERVICE"
+                android:protectionLevel="signature" />
+
+    <!-- Allows an application to export a AttestationVerificationService to verify attestations on
+         behalf of AttestationVerificationManager for system-defined attestation profiles.
+         @hide -->
+    <permission android:name="android.permission.VERIFY_ATTESTATION"
+                android:protectionLevel="signature" />
+
+    <!-- Must be required by any AttestationVerificationService to ensure that only the system can
+         bind to it.
+         @hide -->
+    <permission android:name="android.permission.BIND_ATTESTATION_VERIFICATION_SERVICE"
+                android:protectionLevel="signature" />
+
     <!-- ========================================= -->
     <!-- Permissions for special development tools -->
     <!-- ========================================= -->
diff --git a/tests/Internal/src/com/android/internal/util/ParcellingTests.java b/tests/Internal/src/com/android/internal/util/ParcellingTests.java
new file mode 100644
index 0000000..65a3436
--- /dev/null
+++ b/tests/Internal/src/com/android/internal/util/ParcellingTests.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 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.internal.util;
+
+import android.os.Parcel;
+import android.platform.test.annotations.Presubmit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.util.Parcelling.BuiltIn.ForInstant;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.time.Instant;
+
+/** Tests for {@link Parcelling}. */
+@SmallTest
+@Presubmit
+@RunWith(JUnit4.class)
+public class ParcellingTests {
+
+    private Parcel mParcel = Parcel.obtain();
+
+    @Test
+    public void forInstant_normal() {
+        testForInstant(Instant.ofEpochSecond(500L, 10));
+    }
+
+    @Test
+    public void forInstant_minimum() {
+        testForInstant(Instant.MIN);
+    }
+
+    @Test
+    public void forInstant_maximum() {
+        testForInstant(Instant.MAX);
+    }
+
+    @Test
+    public void forInstant_null() {
+        testForInstant(null);
+    }
+
+    private void testForInstant(Instant instant) {
+        Parcelling<Instant> parcelling = new ForInstant();
+        parcelling.parcel(instant, mParcel, 0);
+        mParcel.setDataPosition(0);
+
+        Instant created = parcelling.unparcel(mParcel);
+
+        if (instant == null) {
+            assertNull(created);
+        } else {
+            assertEquals(instant, created);
+        }
+    }
+
+}