Merge "OMX VTS: Use GetComponentRole from OMXUtils" into rvc-dev
diff --git a/automotive/evs/1.1/types.hal b/automotive/evs/1.1/types.hal
index 1f69f09..e699fd0 100644
--- a/automotive/evs/1.1/types.hal
+++ b/automotive/evs/1.1/types.hal
@@ -105,6 +105,10 @@
      * Master role has become available
      */
     MASTER_RELEASED,
+    /**
+     * Any other erroneous streaming events
+     */
+    STREAM_ERROR,
 };
 
 /**
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index a4fd641..d9ac239 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -15,12 +15,10 @@
 cc_defaults {
     name: "vhal_v2_0_defaults",
     shared_libs: [
-        "libbinder_ndk",
         "libhidlbase",
         "liblog",
         "libutils",
         "android.hardware.automotive.vehicle@2.0",
-        "carwatchdog_aidl_interface-ndk_platform",
     ],
     cflags: [
         "-Wall",
@@ -29,6 +27,15 @@
     ],
 }
 
+cc_defaults {
+    name: "vhal_v2_0_target_defaults",
+    defaults: ["vhal_v2_0_defaults"],
+    shared_libs: [
+        "libbinder_ndk",
+        "carwatchdog_aidl_interface-ndk_platform",
+    ],
+}
+
 cc_library_headers {
     name: "vhal_v2_0_common_headers",
     vendor: true,
@@ -39,7 +46,7 @@
 cc_library {
     name: "android.hardware.automotive.vehicle@2.0-manager-lib",
     vendor: true,
-    defaults: ["vhal_v2_0_defaults"],
+    defaults: ["vhal_v2_0_target_defaults"],
     srcs: [
         "common/src/Obd2SensorStore.cpp",
         "common/src/SubscriptionManager.cpp",
@@ -61,7 +68,7 @@
 cc_library_static {
     name: "android.hardware.automotive.vehicle@2.0-default-impl-lib",
     vendor: true,
-    defaults: ["vhal_v2_0_defaults"],
+    defaults: ["vhal_v2_0_target_defaults"],
     srcs: [
         "impl/vhal_v2_0/CommConn.cpp",
         "impl/vhal_v2_0/EmulatedVehicleConnector.cpp",
@@ -97,16 +104,59 @@
 cc_library_static {
     name: "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib",
     vendor: true,
-    defaults: ["vhal_v2_0_defaults"],
+    defaults: ["vhal_v2_0_target_defaults"],
     srcs: [
         "impl/vhal_v2_0/EmulatedUserHal.cpp",
     ],
 }
 
+// Vehicle HAL Server reference impl lib
+cc_library_static {
+    name: "android.hardware.automotive.vehicle@2.0-server-common-lib",
+    vendor: true,
+    host_supported: true,
+    defaults: ["vhal_v2_0_defaults"],
+    local_include_dirs: ["common/include/vhal_v2_0"],
+    export_include_dirs: ["common/include"],
+    srcs: [
+        "common/src/Obd2SensorStore.cpp",
+        "common/src/VehicleObjectPool.cpp",
+        "common/src/VehicleUtils.cpp",
+    ],
+}
+
+// Vehicle HAL Server default implementation
+cc_library_static {
+    name: "android.hardware.automotive.vehicle@2.0-server-impl-lib",
+    vendor: true,
+    host_supported: true,
+    defaults: ["vhal_v2_0_defaults"],
+    local_include_dirs: ["common/include/vhal_v2_0"],
+    export_include_dirs: ["impl"],
+    srcs: [
+        "impl/vhal_v2_0/EmulatedUserHal.cpp",
+        "impl/vhal_v2_0/GeneratorHub.cpp",
+        "impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
+        "impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
+        "impl/vhal_v2_0/ProtoMessageConverter.cpp",
+        "impl/vhal_v2_0/VehicleHalServer.cpp",
+    ],
+    whole_static_libs: [
+        "android.hardware.automotive.vehicle@2.0-server-common-lib",
+    ],
+    static_libs: [
+        "android.hardware.automotive.vehicle@2.0-libproto-native",
+    ],
+    shared_libs: [
+        "libbase",
+        "libjsoncpp",
+    ],
+}
+
 cc_test {
     name: "android.hardware.automotive.vehicle@2.0-manager-unit-tests",
     vendor: true,
-    defaults: ["vhal_v2_0_defaults"],
+    defaults: ["vhal_v2_0_target_defaults"],
     whole_static_libs: ["android.hardware.automotive.vehicle@2.0-manager-lib"],
     srcs: [
         "tests/RecurrentTimer_test.cpp",
@@ -126,7 +176,7 @@
 cc_test {
     name: "android.hardware.automotive.vehicle@2.0-default-impl-unit-tests",
     vendor: true,
-    defaults: ["vhal_v2_0_defaults"],
+    defaults: ["vhal_v2_0_target_defaults"],
     srcs: [
         "impl/vhal_v2_0/tests/ProtoMessageConverter_test.cpp",
     ],
@@ -140,7 +190,7 @@
 
 cc_binary {
     name: "android.hardware.automotive.vehicle@2.0-service",
-    defaults: ["vhal_v2_0_defaults"],
+    defaults: ["vhal_v2_0_target_defaults"],
     vintf_fragments: [
         "android.hardware.automotive.vehicle@2.0-service.xml",
     ],
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp
index 31ba8ab..c5b9ed6 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp
@@ -16,6 +16,7 @@
 cc_library_static {
     name: "android.hardware.automotive.vehicle@2.0-libproto-native",
     vendor: true,
+    host_supported: true,
     proto: {
         export_proto_headers: true,
         type: "lite",
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index acdea8a..b4aa11d 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -4280,6 +4280,16 @@
      * Admin users have additional privileges such as permission to create other users.
      */
     ADMIN = 0x08,
+
+    /**
+     * Disabled users are marked for deletion.
+     */
+    DISABLED = 0x10,
+
+     /**
+     * Profile user is a profile of another user.
+     */
+    PROFILE = 0x20,
 };
 
 /**
@@ -4294,10 +4304,16 @@
     /** The current foreground user. */
     UserInfo currentUser;
 
-    /** Number of existing users (includes the current user). */
+    /**
+     * Number of existing users; includes the current user, recently removed users (with DISABLED
+     * flag), and profile users (with PROFILE flag).
+     */
     int32_t numberUsers;
 
-    /** List of existing users (includes the current user). */
+    /**
+     * List of existing users; includes the current user, recently removed users (with DISABLED
+     * flag), and profile users (with PROFILE flag).
+     */
     vec<UserInfo> existingUsers;
  };
 
diff --git a/camera/device/3.2/ICameraDeviceCallback.hal b/camera/device/3.2/ICameraDeviceCallback.hal
index 607502e..206a649 100644
--- a/camera/device/3.2/ICameraDeviceCallback.hal
+++ b/camera/device/3.2/ICameraDeviceCallback.hal
@@ -87,8 +87,11 @@
      * ERROR_RESULT message.
      *
      * If an output buffer cannot be filled, its status field must be set to
-     * STATUS_ERROR. In addition, notify() must be called with a ERROR_BUFFER
-     * message.
+     * STATUS_ERROR. In this case, notify() isn't required to be called with
+     * an ERROR_BUFFER message. The framework will simply treat the notify()
+     * call with ERROR_BUFFER as a no-op, and derive whether and when to notify
+     * the application of buffer loss based on the buffer status and whether or not
+     * the entire capture has failed.
      *
      * If the entire capture has failed, then this method still needs to be
      * called to return the output buffers to the framework. All the buffer
diff --git a/camera/device/3.2/default/convert.cpp b/camera/device/3.2/default/convert.cpp
index d878deb..06ad7e9 100644
--- a/camera/device/3.2/default/convert.cpp
+++ b/camera/device/3.2/default/convert.cpp
@@ -38,7 +38,7 @@
     }
 
     const uint8_t* data = src.data();
-    // sanity check the size of CameraMetadata match underlying camera_metadata_t
+    // check that the size of CameraMetadata match underlying camera_metadata_t
     if (get_camera_metadata_size((camera_metadata_t*)data) != src.size()) {
         ALOGE("%s: input CameraMetadata is corrupt!", __FUNCTION__);
         return false;
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index f6860cf..3b8f833 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -1894,7 +1894,7 @@
 }
 
 // Verify that the device resource cost can be retrieved and the values are
-// sane.
+// correct.
 TEST_P(CameraHidlTest, getResourceCost) {
     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
 
@@ -2544,7 +2544,7 @@
     }
 }
 
-// Basic sanity tests related to camera parameters.
+// Basic correctness tests related to camera parameters.
 TEST_P(CameraHidlTest, getSetParameters) {
     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
 
diff --git a/current.txt b/current.txt
index 2608b54..90402b4 100644
--- a/current.txt
+++ b/current.txt
@@ -588,7 +588,7 @@
 578f640c653726d58f99c84a7e1bb63862e21ef7cbb4f7d95c3cc62de00dca35 android.hardware.automotive.evs@1.0::IEvsDisplay
 f5bc6aa840db933cb9fd36668b06d3e2021cf5384bb70e459f22e2f2f921fba5 android.hardware.automotive.evs@1.0::IEvsEnumerator
 d3a344b7bd4c0d2658ae7209f55a979b8f53f361fd00f4fca29d5baa56d11fd2 android.hardware.automotive.evs@1.0::types
-d123013165a19b6353cdc46a57b2ff4a17179619d36dbd595dfcf15dcd099af6 android.hardware.camera.device@3.2::ICameraDeviceCallback # b/155353799
+2924c3e43858190ee3e2da4c2fb93bba8ae065fe314451f035a7ec52cb80c94a android.hardware.camera.device@3.2::ICameraDeviceCallback # b/155353799
 2410dd02d67786a732d36e80b0f8ccf55086604ef37f9838e2013ff2c571e404 android.hardware.camera.device@3.5::types
 cd06a7911b9acd4a653bbf7133888878fbcb3f84be177c7a3f1becaae3d8618f android.hardware.camera.metadata@3.2::types
 5cf81b1001296fbb3c5b3d275a859244f61cec5fa858d7be9cca46c5b7dfa733 android.hardware.camera.metadata@3.2::types # b/150331548
@@ -658,7 +658,7 @@
 87958d728d7c0ee9b9391ab4a072b097914921a7b38f7dc3df427f933a5b528e android.hardware.automotive.evs@1.1::IEvsEnumerator
 f53b4e8de6209c6d0fa9036005671b34a2f98328b51423d3a5137a43bf42c84d android.hardware.automotive.evs@1.1::IEvsUltrasonicsArray
 0460bacbde906a846a3d71b2b7b33d6927cac3ff072e523ffac7853577464406 android.hardware.automotive.evs@1.1::IEvsUltrasonicsArrayStream
-3e374b5c4777f959f62a320abb3b9edca8874e24e383dbb19c66d224f151b363 android.hardware.automotive.evs@1.1::types
+f27cf8283e7b953d33dd258734749d2fca9cc63502ea41353060ffa78d8ce9f6 android.hardware.automotive.evs@1.1::types
 4e4904c4067dadae974ddf90351f362331dcd04bba1d890d313cc8ba91f68c15 android.hardware.automotive.sv@1.0::ISurroundView2dSession
 63336e9d03f545020ff2982ff76d9d8c44fa76ad476293b5ef6732cbbd71e61b android.hardware.automotive.sv@1.0::ISurroundView3dSession
 b7015428cd52ce8192d13bfcbf2c4455cda3727d57f2aac80d65a1747104f5ac android.hardware.automotive.sv@1.0::ISurroundViewService
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 6df7f8d..db06c66 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -587,8 +587,8 @@
                                static_cast<int32_t>(info.height)};
     unique_fd fence;
     uint8_t* data;
-    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
-                                    mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
+    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
+                                                                        region, fence.release())));
 
     // RGBA_8888
     fillRGBA8888(data, info.height, stride * 4, info.width * 4);
@@ -596,8 +596,8 @@
     ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
 
     // lock again for reading
-    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
-                                    mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
+    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
+                                                                        region, fence.release())));
 
     ASSERT_NO_FATAL_FAILURE(
             verifyRGBA8888(bufferHandle, data, info.height, stride * 4, info.width * 4));
@@ -627,8 +627,8 @@
     unique_fd fence;
     uint8_t* data;
 
-    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
-                                    mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
+    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
+                                                                        region, fence.release())));
 
     android_ycbcr yCbCr;
     int64_t hSubsampling = 0;
@@ -650,8 +650,8 @@
     ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
 
     // lock again for reading
-    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
-                                    mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
+    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
+                                                                        region, fence.release())));
 
     ASSERT_NO_FATAL_FAILURE(
             getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));
@@ -676,8 +676,8 @@
     unique_fd fence;
     uint8_t* data;
 
-    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
-                                    mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
+    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
+                                                                        region, fence.release())));
 
     android_ycbcr yCbCr;
     int64_t hSubsampling = 0;
@@ -699,8 +699,8 @@
     ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
 
     // lock again for reading
-    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
-                                    mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
+    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
+                                                                        region, fence.release())));
 
     ASSERT_NO_FATAL_FAILURE(
             getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));
@@ -725,8 +725,8 @@
     unique_fd fence;
     uint8_t* data;
 
-    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
-                                    mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
+    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
+                                                                        region, fence.release())));
 
     android_ycbcr yCbCr;
     int64_t hSubsampling = 0;
@@ -743,8 +743,8 @@
     ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
 
     // lock again for reading
-    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
-                                    mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
+    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage,
+                                                                        region, fence.release())));
 
     ASSERT_NO_FATAL_FAILURE(
             getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));
@@ -771,7 +771,7 @@
                                static_cast<int32_t>(info.height)};
     unique_fd fence;
 
-    ASSERT_NO_FATAL_FAILURE(mGralloc->lock(bufferHandle, info.usage, region, fence.get()));
+    ASSERT_NO_FATAL_FAILURE(mGralloc->lock(bufferHandle, info.usage, region, fence.release()));
 
     hidl_vec<uint8_t> vec;
     ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, &vec));
@@ -813,7 +813,7 @@
                                static_cast<int32_t>(info.height)};
     unique_fd fence;
 
-    ASSERT_NO_FATAL_FAILURE(mGralloc->lock(bufferHandle, info.usage, region, fence.get()));
+    ASSERT_NO_FATAL_FAILURE(mGralloc->lock(bufferHandle, info.usage, region, fence.release()));
 
     hidl_vec<uint8_t> vec;
     ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, &vec));
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index cd6f9b0..c1f44e7 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -14,19 +14,19 @@
         "ReaderAuthTests.cpp",
     ],
     shared_libs: [
-        "android.hardware.keymaster@4.0",
         "libbinder",
         "libcrypto",
-        "android.hardware.keymaster-ndk_platform",
     ],
     static_libs: [
         "libcppbor",
         "libkeymaster_portable",
         "libsoft_attestation_cert",
         "libpuresoftkeymasterdevice",
+        "android.hardware.keymaster@4.0",
         "android.hardware.identity-support-lib",
         "android.hardware.identity-cpp",
         "android.hardware.keymaster-cpp",
+        "android.hardware.keymaster-ndk_platform",
     ],
     test_suites: [
         "general-tests",
diff --git a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
index 0f27a72..f7ec7c5 100644
--- a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
+++ b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
@@ -33,6 +33,7 @@
 using ::std::string;
 using ::std::tuple;
 using ::std::vector;
+using ::std::pair;
 
 // ---------------------------------------------------------------------------
 // Miscellaneous utilities.
@@ -119,6 +120,12 @@
 optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
         const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId);
 
+// Like createEcKeyPairAndAttestation() but allows you to choose the public key.
+//
+optional<vector<vector<uint8_t>>> createAttestationForEcPublicKey(
+        const vector<uint8_t>& publicKey, const vector<uint8_t>& challenge,
+        const vector<uint8_t>& applicationId);
+
 // Creates an 256-bit EC key using the NID_X9_62_prime256v1 curve, returns the
 // PKCS#8 encoded key-pair.
 //
@@ -155,6 +162,12 @@
 //
 optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data);
 
+// Like signEcDsa() but instead of taking the data to be signed, takes a digest
+// of it instead.
+//
+optional<vector<uint8_t>> signEcDsaDigest(const vector<uint8_t>& key,
+                                          const vector<uint8_t>& dataDigest);
+
 // Calculates the HMAC with SHA-256 for |data| using |key|. The calculated HMAC
 // is returned and will be 32 bytes.
 //
@@ -175,6 +188,27 @@
 //
 optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& certificateChain);
 
+// Extracts the public-key from the top-most certificate in |certificateChain|
+// (which should be a concatenated chain of DER-encoded X.509 certificates).
+//
+// Return offset and size of the public-key
+//
+optional<pair<size_t, size_t>> certificateFindPublicKey(const vector<uint8_t>& x509Certificate);
+
+// Extracts the TbsCertificate from the top-most certificate in |certificateChain|
+// (which should be a concatenated chain of DER-encoded X.509 certificates).
+//
+// Return offset and size of the TbsCertificate
+//
+optional<pair<size_t, size_t>> certificateTbsCertificate(const vector<uint8_t>& x509Certificate);
+
+// Extracts the Signature from the top-most certificate in |certificateChain|
+// (which should be a concatenated chain of DER-encoded X.509 certificates).
+//
+// Return offset and size of the Signature
+//
+optional<pair<size_t, size_t>> certificateFindSignature(const vector<uint8_t>& x509Certificate);
+
 // Generates a X.509 certificate for |publicKey| (which must be in the format
 // returned by ecKeyPairGetPublicKey()).
 //
@@ -231,6 +265,11 @@
 //
 bool certificateChainValidate(const vector<uint8_t>& certificateChain);
 
+// Returns true if |certificate| is signed by |publicKey|.
+//
+bool certificateSignedByPublicKey(const vector<uint8_t>& certificate,
+                                  const vector<uint8_t>& publicKey);
+
 // Signs |data| and |detachedContent| with |key| (which must be in the format
 // returned by ecKeyPairGetPrivateKey()).
 //
@@ -243,6 +282,21 @@
                                         const vector<uint8_t>& detachedContent,
                                         const vector<uint8_t>& certificateChain);
 
+// Creates a COSE_Signature1 where |signatureToBeSigned| is the ECDSA signature
+// of the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process".
+//
+// The |signatureToBeSigned| is expected to be 64 bytes and contain the R value,
+// then the S value.
+//
+// The |data| parameter will be included in the COSE_Sign1 CBOR.
+//
+// If |certificateChain| is non-empty it's included in the 'x5chain'
+// protected header element (as as described in'draft-ietf-cose-x509-04').
+//
+optional<vector<uint8_t>> coseSignEcDsaWithSignature(const vector<uint8_t>& signatureToBeSigned,
+                                                     const vector<uint8_t>& data,
+                                                     const vector<uint8_t>& certificateChain);
+
 // Checks that |signatureCoseSign1| (in COSE_Sign1 format) is a valid signature
 // made with |public_key| (which must be in the format returned by
 // ecKeyPairGetPublicKey()) where |detachedContent| is the detached content.
@@ -251,9 +305,23 @@
                              const vector<uint8_t>& detachedContent,
                              const vector<uint8_t>& publicKey);
 
+// Converts a DER-encoded signature to the format used in 'signature' bstr in COSE_Sign1.
+bool ecdsaSignatureDerToCose(const vector<uint8_t>& ecdsaDerSignature,
+                             vector<uint8_t>& ecdsaCoseSignature);
+
+// Converts from the format in in 'signature' bstr in COSE_Sign1 to DER encoding.
+bool ecdsaSignatureCoseToDer(const vector<uint8_t>& ecdsaCoseSignature,
+                             vector<uint8_t>& ecdsaDerSignature);
+
 // Extracts the payload from a COSE_Sign1.
 optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1);
 
+// Extracts the signature (of the ToBeSigned CBOR) from a COSE_Sign1.
+optional<vector<uint8_t>> coseSignGetSignature(const vector<uint8_t>& signatureCoseSign1);
+
+// Extracts the signature algorithm from a COSE_Sign1.
+optional<int> coseSignGetAlg(const vector<uint8_t>& signatureCoseSign1);
+
 // Extracts the X.509 certificate chain, if present. Returns the data as a
 // concatenated chain of DER-encoded X.509 certificates
 //
@@ -269,6 +337,16 @@
 optional<vector<uint8_t>> coseMac0(const vector<uint8_t>& key, const vector<uint8_t>& data,
                                    const vector<uint8_t>& detachedContent);
 
+// Creates a COSE_Mac0 where |digestToBeMaced| is the HMAC-SHA256
+// of the ToBeMaced CBOR from RFC 8051 "6.3. How to Compute and Verify a MAC".
+//
+// The |digestToBeMaced| is expected to be 32 bytes.
+//
+// The |data| parameter will be included in the COSE_Mac0 CBOR.
+//
+optional<vector<uint8_t>> coseMacWithDigest(const vector<uint8_t>& digestToBeMaced,
+                                            const vector<uint8_t>& data);
+
 // ---------------------------------------------------------------------------
 // Utility functions specific to IdentityCredential.
 // ---------------------------------------------------------------------------
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
index e9d5d6c..8e099e7 100644
--- a/identity/support/src/IdentityCredentialSupport.cpp
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -24,6 +24,7 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <time.h>
+#include <chrono>
 #include <iomanip>
 
 #include <openssl/aes.h>
@@ -684,6 +685,48 @@
     return true;
 }
 
+bool certificateSignedByPublicKey(const vector<uint8_t>& certificate,
+                                  const vector<uint8_t>& publicKey) {
+    const unsigned char* p = certificate.data();
+    auto x509 = X509_Ptr(d2i_X509(nullptr, &p, certificate.size()));
+    if (x509 == nullptr) {
+        LOG(ERROR) << "Error parsing X509 certificate";
+        return false;
+    }
+
+    auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
+    if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
+        1) {
+        LOG(ERROR) << "Error decoding publicKey";
+        return false;
+    }
+    auto ecKey = EC_KEY_Ptr(EC_KEY_new());
+    auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    if (ecKey.get() == nullptr || pkey.get() == nullptr) {
+        LOG(ERROR) << "Memory allocation failed";
+        return false;
+    }
+    if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
+        LOG(ERROR) << "Error setting group";
+        return false;
+    }
+    if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
+        LOG(ERROR) << "Error setting point";
+        return false;
+    }
+    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
+        LOG(ERROR) << "Error setting key";
+        return false;
+    }
+
+    if (X509_verify(x509.get(), pkey.get()) != 1) {
+        return false;
+    }
+
+    return true;
+}
+
 // TODO: Right now the only check we perform is to check that each certificate
 //       is signed by its successor. We should - but currently don't - also check
 //       things like valid dates etc.
@@ -770,7 +813,8 @@
     return ret;
 }
 
-optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data) {
+optional<vector<uint8_t>> signEcDsaDigest(const vector<uint8_t>& key,
+                                          const vector<uint8_t>& dataDigest) {
     auto bn = BIGNUM_Ptr(BN_bin2bn(key.data(), key.size(), nullptr));
     if (bn.get() == nullptr) {
         LOG(ERROR) << "Error creating BIGNUM";
@@ -783,8 +827,7 @@
         return {};
     }
 
-    auto digest = sha256(data);
-    ECDSA_SIG* sig = ECDSA_do_sign(digest.data(), digest.size(), ec_key.get());
+    ECDSA_SIG* sig = ECDSA_do_sign(dataDigest.data(), dataDigest.size(), ec_key.get());
     if (sig == nullptr) {
         LOG(ERROR) << "Error signing digest";
         return {};
@@ -798,6 +841,10 @@
     return signature;
 }
 
+optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data) {
+    return signEcDsaDigest(key, sha256(data));
+}
+
 optional<vector<uint8_t>> hmacSha256(const vector<uint8_t>& key, const vector<uint8_t>& data) {
     HMAC_CTX ctx;
     HMAC_CTX_init(&ctx);
@@ -955,6 +1002,51 @@
     return make_pair(keyPair, attestationCert.value());
 }
 
+optional<vector<vector<uint8_t>>> createAttestationForEcPublicKey(
+        const vector<uint8_t>& publicKey, const vector<uint8_t>& challenge,
+        const vector<uint8_t>& applicationId) {
+    auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
+    if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
+        1) {
+        LOG(ERROR) << "Error decoding publicKey";
+        return {};
+    }
+    auto ecKey = EC_KEY_Ptr(EC_KEY_new());
+    auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    if (ecKey.get() == nullptr || pkey.get() == nullptr) {
+        LOG(ERROR) << "Memory allocation failed";
+        return {};
+    }
+    if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
+        LOG(ERROR) << "Error setting group";
+        return {};
+    }
+    if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
+        LOG(ERROR) << "Error setting point";
+        return {};
+    }
+    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
+        LOG(ERROR) << "Error setting key";
+        return {};
+    }
+
+    uint64_t now = (std::chrono::duration_cast<std::chrono::nanoseconds>(
+                    std::chrono::system_clock::now().time_since_epoch()).
+                    count()/ 1000000000);
+    uint64_t secondsInOneYear = 365 * 24 * 60 * 60;
+    uint64_t expireTimeMs = (now + secondsInOneYear) * 1000;
+
+    optional<vector<vector<uint8_t>>> attestationCert =
+            createAttestation(pkey.get(), applicationId, challenge, now * 1000, expireTimeMs);
+    if (!attestationCert) {
+        LOG(ERROR) << "Error create attestation from key and challenge";
+        return {};
+    }
+
+    return attestationCert.value();
+}
+
 optional<vector<uint8_t>> createEcKeyPair() {
     auto ec_key = EC_KEY_Ptr(EC_KEY_new());
     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
@@ -1477,6 +1569,120 @@
     return publicKey;
 }
 
+optional<pair<size_t, size_t>> certificateFindPublicKey(const vector<uint8_t>& x509Certificate) {
+    vector<X509_Ptr> certs;
+    if (!parseX509Certificates(x509Certificate, certs)) {
+        return {};
+    }
+    if (certs.size() < 1) {
+        LOG(ERROR) << "No certificates in chain";
+        return {};
+    }
+
+    auto pkey = EVP_PKEY_Ptr(X509_get_pubkey(certs[0].get()));
+    if (pkey.get() == nullptr) {
+        LOG(ERROR) << "No public key";
+        return {};
+    }
+
+    auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
+    if (ecKey.get() == nullptr) {
+        LOG(ERROR) << "Failed getting EC key";
+        return {};
+    }
+
+    auto ecGroup = EC_KEY_get0_group(ecKey.get());
+    auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
+    int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
+                                  nullptr);
+    if (size == 0) {
+        LOG(ERROR) << "Error generating public key encoding";
+        return {};
+    }
+    vector<uint8_t> publicKey;
+    publicKey.resize(size);
+    EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
+                       publicKey.size(), nullptr);
+
+    size_t publicKeyOffset = 0;
+    size_t publicKeySize = (size_t)size;
+    void* location = memmem((const void*)x509Certificate.data(), x509Certificate.size(),
+                            (const void*)publicKey.data(), publicKey.size());
+
+    if (location == NULL) {
+        LOG(ERROR) << "Error finding publicKey from x509Certificate";
+        return {};
+    }
+    publicKeyOffset = (size_t)((const char*)location - (const char*)x509Certificate.data());
+
+    return std::make_pair(publicKeyOffset, publicKeySize);
+}
+
+optional<pair<size_t, size_t>> certificateTbsCertificate(const vector<uint8_t>& x509Certificate) {
+    vector<X509_Ptr> certs;
+    if (!parseX509Certificates(x509Certificate, certs)) {
+        return {};
+    }
+    if (certs.size() < 1) {
+        LOG(ERROR) << "No certificates in chain";
+        return {};
+    }
+
+    unsigned char* buf = NULL;
+    int len = i2d_re_X509_tbs(certs[0].get(), &buf);
+    if ((len < 0) || (buf == NULL)) {
+        LOG(ERROR) << "fail to extract tbsCertificate in x509Certificate";
+        return {};
+    }
+
+    vector<uint8_t> tbsCertificate(len);
+    memcpy(tbsCertificate.data(), buf, len);
+
+    size_t tbsCertificateOffset = 0;
+    size_t tbsCertificateSize = (size_t)len;
+    void* location = memmem((const void*)x509Certificate.data(), x509Certificate.size(),
+                            (const void*)tbsCertificate.data(), tbsCertificate.size());
+
+    if (location == NULL) {
+        LOG(ERROR) << "Error finding tbsCertificate from x509Certificate";
+        return {};
+    }
+    tbsCertificateOffset = (size_t)((const char*)location - (const char*)x509Certificate.data());
+
+    return std::make_pair(tbsCertificateOffset, tbsCertificateSize);
+}
+
+optional<pair<size_t, size_t>> certificateFindSignature(const vector<uint8_t>& x509Certificate) {
+    vector<X509_Ptr> certs;
+    if (!parseX509Certificates(x509Certificate, certs)) {
+        return {};
+    }
+    if (certs.size() < 1) {
+        LOG(ERROR) << "No certificates in chain";
+        return {};
+    }
+
+    ASN1_BIT_STRING* psig;
+    X509_ALGOR* palg;
+    X509_get0_signature((const ASN1_BIT_STRING**)&psig, (const X509_ALGOR**)&palg, certs[0].get());
+
+    vector<char> signature(psig->length);
+    memcpy(signature.data(), psig->data, psig->length);
+
+    size_t signatureOffset = 0;
+    size_t signatureSize = (size_t)psig->length;
+    void* location = memmem((const void*)x509Certificate.data(), x509Certificate.size(),
+                            (const void*)signature.data(), signature.size());
+
+    if (location == NULL) {
+        LOG(ERROR) << "Error finding signature from x509Certificate";
+        return {};
+    }
+    signatureOffset = (size_t)((const char*)location - (const char*)x509Certificate.data());
+
+    return std::make_pair(signatureOffset, signatureSize);
+}
+
 // ---------------------------------------------------------------------------
 // COSE Utility Functions
 // ---------------------------------------------------------------------------
@@ -1574,6 +1780,55 @@
     return true;
 }
 
+optional<vector<uint8_t>> coseSignEcDsaWithSignature(const vector<uint8_t>& signatureToBeSigned,
+                                                     const vector<uint8_t>& data,
+                                                     const vector<uint8_t>& certificateChain) {
+    if (signatureToBeSigned.size() != 64) {
+        LOG(ERROR) << "Invalid size for signatureToBeSigned, expected 64 got "
+                   << signatureToBeSigned.size();
+        return {};
+    }
+
+    cppbor::Map unprotectedHeaders;
+    cppbor::Map protectedHeaders;
+
+    protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_ECDSA_256);
+
+    if (certificateChain.size() != 0) {
+        optional<vector<vector<uint8_t>>> certs = support::certificateChainSplit(certificateChain);
+        if (!certs) {
+            LOG(ERROR) << "Error splitting certificate chain";
+            return {};
+        }
+        if (certs.value().size() == 1) {
+            unprotectedHeaders.add(COSE_LABEL_X5CHAIN, certs.value()[0]);
+        } else {
+            cppbor::Array certArray;
+            for (const vector<uint8_t>& cert : certs.value()) {
+                certArray.add(cert);
+            }
+            unprotectedHeaders.add(COSE_LABEL_X5CHAIN, std::move(certArray));
+        }
+    }
+
+    vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
+
+    cppbor::Array coseSign1;
+    coseSign1.add(encodedProtectedHeaders);
+    coseSign1.add(std::move(unprotectedHeaders));
+    if (data.size() == 0) {
+        cppbor::Null nullValue;
+        coseSign1.add(std::move(nullValue));
+    } else {
+        coseSign1.add(data);
+    }
+    coseSign1.add(signatureToBeSigned);
+    vector<uint8_t> signatureCoseSign1;
+    signatureCoseSign1 = coseSign1.encode();
+
+    return signatureCoseSign1;
+}
+
 optional<vector<uint8_t>> coseSignEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data,
                                         const vector<uint8_t>& detachedContent,
                                         const vector<uint8_t>& certificateChain) {
@@ -1709,6 +1964,35 @@
     return true;
 }
 
+// Extracts the signature (of the ToBeSigned CBOR) from a COSE_Sign1.
+optional<vector<uint8_t>> coseSignGetSignature(const vector<uint8_t>& signatureCoseSign1) {
+    auto [item, _, message] = cppbor::parse(signatureCoseSign1);
+    if (item == nullptr) {
+        LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
+        return {};
+    }
+    const cppbor::Array* array = item->asArray();
+    if (array == nullptr) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array";
+        return {};
+    }
+    if (array->size() != 4) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
+        return {};
+    }
+
+    vector<uint8_t> signature;
+    const cppbor::Bstr* signatureAsBstr = (*array)[3]->asBstr();
+    if (signatureAsBstr == nullptr) {
+        LOG(ERROR) << "Value for signature is not a bstr";
+        return {};
+    }
+    // Copy payload into |data|
+    signature = signatureAsBstr->value();
+
+    return signature;
+}
+
 optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1) {
     auto [item, _, message] = cppbor::parse(signatureCoseSign1);
     if (item == nullptr) {
@@ -1746,6 +2030,59 @@
     return data;
 }
 
+optional<int> coseSignGetAlg(const vector<uint8_t>& signatureCoseSign1) {
+    auto [item, _, message] = cppbor::parse(signatureCoseSign1);
+    if (item == nullptr) {
+        LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
+        return {};
+    }
+    const cppbor::Array* array = item->asArray();
+    if (array == nullptr) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array";
+        return {};
+    }
+    if (array->size() != 4) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
+        return {};
+    }
+
+    const cppbor::Bstr* protectedHeadersBytes = (*array)[0]->asBstr();
+    if (protectedHeadersBytes == nullptr) {
+        LOG(ERROR) << "Value for protectedHeaders is not a bstr";
+        return {};
+    }
+    auto [item2, _2, message2] = cppbor::parse(protectedHeadersBytes->value());
+    if (item2 == nullptr) {
+        LOG(ERROR) << "Error parsing protectedHeaders: " << message2;
+        return {};
+    }
+    const cppbor::Map* protectedHeaders = item2->asMap();
+    if (protectedHeaders == nullptr) {
+        LOG(ERROR) << "Decoded CBOR for protectedHeaders is not a map";
+        return {};
+    }
+
+    for (size_t n = 0; n < protectedHeaders->size(); n++) {
+        auto [keyItem, valueItem] = (*protectedHeaders)[n];
+        const cppbor::Int* number = keyItem->asInt();
+        if (number == nullptr) {
+            LOG(ERROR) << "Key item in top-level map is not a number";
+            return {};
+        }
+        int label = number->value();
+        if (label == COSE_LABEL_ALG) {
+            const cppbor::Int* number = valueItem->asInt();
+            if (number != nullptr) {
+                return number->value();
+            }
+            LOG(ERROR) << "Value for COSE_LABEL_ALG label is not a number";
+            return {};
+        }
+    }
+    LOG(ERROR) << "Did not find COSE_LABEL_ALG label in protected headers";
+    return {};
+}
+
 optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCoseSign1) {
     auto [item, _, message] = cppbor::parse(signatureCoseSign1);
     if (item == nullptr) {
@@ -1861,6 +2198,28 @@
     return array.encode();
 }
 
+optional<vector<uint8_t>> coseMacWithDigest(const vector<uint8_t>& digestToBeMaced,
+                                            const vector<uint8_t>& data) {
+    cppbor::Map unprotectedHeaders;
+    cppbor::Map protectedHeaders;
+
+    protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_HMAC_256_256);
+
+    vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
+
+    cppbor::Array array;
+    array.add(encodedProtectedHeaders);
+    array.add(std::move(unprotectedHeaders));
+    if (data.size() == 0) {
+        cppbor::Null nullValue;
+        array.add(std::move(nullValue));
+    } else {
+        array.add(data);
+    }
+    array.add(digestToBeMaced);
+    return array.encode();
+}
+
 // ---------------------------------------------------------------------------
 // Utility functions specific to IdentityCredential.
 // ---------------------------------------------------------------------------
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index 87e8519..d802911 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -62,11 +62,12 @@
     defaults: ["neuralnetworks_vts_functional_defaults"],
     srcs: [
         "BasicTests.cpp",
+        "GeneratedTestHarness.cpp",
         "TestAssertions.cpp",
+        "TestMain.cpp",
         "ValidateModel.cpp",
         "ValidateRequest.cpp",
         "VtsHalNeuralnetworks.cpp",
-        "GeneratedTestHarness.cpp",
     ],
     shared_libs: [
         "libfmq",
diff --git a/neuralnetworks/1.0/vts/functional/AndroidTest.xml b/neuralnetworks/1.0/vts/functional/AndroidTest.xml
index 54e6e91..13671f9 100644
--- a/neuralnetworks/1.0/vts/functional/AndroidTest.xml
+++ b/neuralnetworks/1.0/vts/functional/AndroidTest.xml
@@ -26,10 +26,6 @@
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
-        <!-- b/155577050, temporarily disable the failing tests.
-             Must be deleted after corresponding driver issues are fixed.
-        -->
-        <option name="native-test-flag" value="--gtest_filter=-*Validation*:*CycleTest*:*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*" />
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="VtsHalNeuralnetworksV1_0TargetTest" />
     </test>
diff --git a/neuralnetworks/1.0/vts/functional/TestMain.cpp b/neuralnetworks/1.0/vts/functional/TestMain.cpp
new file mode 100644
index 0000000..6bf4e5f
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/TestMain.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include <gtest/gtest.h>
+#include "1.0/LogTestCaseToLogcat.h"
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    testing::UnitTest::GetInstance()->listeners().Append(
+            new android::hardware::neuralnetworks::LogTestCaseToLogcat());
+    return RUN_ALL_TESTS();
+}
diff --git a/neuralnetworks/1.0/vts/functional/include/1.0/LogTestCaseToLogcat.h b/neuralnetworks/1.0/vts/functional/include/1.0/LogTestCaseToLogcat.h
new file mode 100644
index 0000000..f1413ef
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/include/1.0/LogTestCaseToLogcat.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_0_LOG_TEST_CASE_TO_LOGCAT_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_0_LOG_TEST_CASE_TO_LOGCAT_H
+
+#include <android-base/logging.h>
+#include <gtest/gtest.h>
+
+namespace android::hardware::neuralnetworks {
+
+class LogTestCaseToLogcat : public ::testing::EmptyTestEventListener {
+  public:
+    void OnTestStart(const ::testing::TestInfo& test_info) override {
+        LOG(INFO) << "[Test Case] " << test_info.test_suite_name() << "." << test_info.name()
+                  << " BEGIN";
+    }
+
+    void OnTestEnd(const ::testing::TestInfo& test_info) override {
+        LOG(INFO) << "[Test Case] " << test_info.test_suite_name() << "." << test_info.name()
+                  << " END";
+    }
+};
+
+}  // namespace android::hardware::neuralnetworks
+
+#endif  // ANDROID_HARDWARE_NEURALNETWORKS_V1_0_LOG_TEST_CASE_TO_LOGCAT_H
diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp
index 9afa0af..405548f 100644
--- a/neuralnetworks/1.1/vts/functional/Android.bp
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -20,6 +20,7 @@
     srcs: [
         "BasicTests.cpp",
         "TestAssertions.cpp",
+        "TestMain.cpp",
         "ValidateModel.cpp",
         "ValidateRequest.cpp",
         "VtsHalNeuralnetworks.cpp",
diff --git a/neuralnetworks/1.1/vts/functional/AndroidTest.xml b/neuralnetworks/1.1/vts/functional/AndroidTest.xml
index a6f812f..cfde60c 100644
--- a/neuralnetworks/1.1/vts/functional/AndroidTest.xml
+++ b/neuralnetworks/1.1/vts/functional/AndroidTest.xml
@@ -26,10 +26,6 @@
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
-        <!-- b/155577050, temporarily disable the failing tests.
-             Must be deleted after corresponding driver issues are fixed.
-        -->
-        <option name="native-test-flag" value="--gtest_filter=-*Validation*:*CycleTest*:*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*" />
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="VtsHalNeuralnetworksV1_1TargetTest" />
     </test>
diff --git a/neuralnetworks/1.1/vts/functional/TestMain.cpp b/neuralnetworks/1.1/vts/functional/TestMain.cpp
new file mode 100644
index 0000000..6bf4e5f
--- /dev/null
+++ b/neuralnetworks/1.1/vts/functional/TestMain.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include <gtest/gtest.h>
+#include "1.0/LogTestCaseToLogcat.h"
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    testing::UnitTest::GetInstance()->listeners().Append(
+            new android::hardware::neuralnetworks::LogTestCaseToLogcat());
+    return RUN_ALL_TESTS();
+}
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index 182f716..93edca6 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -40,6 +40,7 @@
         "CompilationCachingTests.cpp",
         "GeneratedTestHarness.cpp",
         "TestAssertions.cpp",
+        "TestMain.cpp",
         "ValidateBurst.cpp",
         "ValidateModel.cpp",
         "ValidateRequest.cpp",
diff --git a/neuralnetworks/1.2/vts/functional/AndroidTest.xml b/neuralnetworks/1.2/vts/functional/AndroidTest.xml
index adbdf40..3f91618 100644
--- a/neuralnetworks/1.2/vts/functional/AndroidTest.xml
+++ b/neuralnetworks/1.2/vts/functional/AndroidTest.xml
@@ -26,10 +26,6 @@
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
-        <!-- b/155577050, b/155674368, b/153876253, temporarily disable the test.
-             Must be deleted after corresponding driver issues are fixed.
-        -->
-        <option name="native-test-flag" value="--gtest_filter=-*Validation*:*squeeze*_all*_inputs*:*strided_slice*_all*_inputs*:*transpose*_all*_inputs*:*l2_normalization_axis_corner_case*:*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*" />
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="VtsHalNeuralnetworksV1_2TargetTest" />
     </test>
diff --git a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
index 449b8f3..16b313a 100644
--- a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
@@ -315,7 +315,8 @@
 
     void saveModelToCache(const Model& model, const hidl_vec<hidl_handle>& modelCache,
                           const hidl_vec<hidl_handle>& dataCache,
-                          sp<IPreparedModel>* preparedModel = nullptr) {
+                          sp<IPreparedModel>* preparedModel = nullptr,
+                          bool allowGeneralFailure = false) {
         if (preparedModel != nullptr) *preparedModel = nullptr;
 
         // Launch prepare model.
@@ -329,7 +330,10 @@
 
         // Retrieve prepared model.
         preparedModelCallback->wait();
-        ASSERT_EQ(preparedModelCallback->getStatus(), ErrorStatus::NONE);
+        const auto prepareCallbackStatus = preparedModelCallback->getStatus();
+        if (!allowGeneralFailure || prepareCallbackStatus != ErrorStatus::GENERAL_FAILURE) {
+            ASSERT_EQ(prepareCallbackStatus, ErrorStatus::NONE);
+        }
         if (preparedModel != nullptr) {
             *preparedModel = IPreparedModel::castFrom(preparedModelCallback->getPreparedModel())
                                      .withDefault(nullptr);
@@ -1022,7 +1026,8 @@
 
 // Number of operations in the large test model.
 constexpr uint32_t kLargeModelSize = 100;
-constexpr uint32_t kNumIterationsTOCTOU = 100;
+constexpr uint32_t kNumSuccessfulIterationsTOCTOU = 100;
+constexpr uint32_t kMaxNumFailedIterationsTOCTOU = 100;
 
 TEST_P(CompilationCachingTest, SaveToCache_TOCTOU) {
     if (!mIsCachingSupported) return;
@@ -1050,18 +1055,30 @@
     // Use a different token for modelAdd.
     mToken[0]++;
 
-    // This test is probabilistic, so we run it multiple times.
-    for (uint32_t i = 0; i < kNumIterationsTOCTOU; i++) {
+    // This test is probabilistic, so we run it multiple times. We allow the compilation to fail
+    // because it is not related to the security aspect of the TOCTOU test. However, we need to have
+    // enough successful iterations to ensure the test coverage.
+    uint32_t numSuccessfulIterations = 0, numFailedIterations = 0;
+    while (numSuccessfulIterations < kNumSuccessfulIterationsTOCTOU) {
         // Save the modelAdd compilation to cache.
         {
             hidl_vec<hidl_handle> modelCache, dataCache;
             createCacheHandles(mModelCache, AccessMode::READ_WRITE, &modelCache);
             createCacheHandles(mDataCache, AccessMode::READ_WRITE, &dataCache);
 
+            sp<IPreparedModel> preparedModel = nullptr;
             // Spawn a thread to copy the cache content concurrently while saving to cache.
             std::thread thread(copyCacheFiles, std::cref(modelCacheMul), std::cref(mModelCache));
-            saveModelToCache(modelAdd, modelCache, dataCache);
+            saveModelToCache(modelAdd, modelCache, dataCache, &preparedModel,
+                             /*allowGeneralFailure=*/true);
             thread.join();
+
+            if (preparedModel == nullptr) {
+                numFailedIterations++;
+                ASSERT_LE(numFailedIterations, kMaxNumFailedIterationsTOCTOU);
+            } else {
+                numSuccessfulIterations++;
+            }
         }
 
         // Retrieve preparedModel from cache.
@@ -1112,14 +1129,26 @@
     // Use a different token for modelAdd.
     mToken[0]++;
 
-    // This test is probabilistic, so we run it multiple times.
-    for (uint32_t i = 0; i < kNumIterationsTOCTOU; i++) {
+    // This test is probabilistic, so we run it multiple times. We allow the compilation to fail
+    // because it is not related to the security aspect of the TOCTOU test. However, we need to have
+    // enough successful iterations to ensure the test coverage.
+    uint32_t numSuccessfulIterations = 0, numFailedIterations = 0;
+    while (numSuccessfulIterations < kNumSuccessfulIterationsTOCTOU) {
         // Save the modelAdd compilation to cache.
         {
             hidl_vec<hidl_handle> modelCache, dataCache;
             createCacheHandles(mModelCache, AccessMode::READ_WRITE, &modelCache);
             createCacheHandles(mDataCache, AccessMode::READ_WRITE, &dataCache);
-            saveModelToCache(modelAdd, modelCache, dataCache);
+            sp<IPreparedModel> preparedModel = nullptr;
+            saveModelToCache(modelAdd, modelCache, dataCache, &preparedModel,
+                             /*allowGeneralFailure=*/true);
+
+            if (preparedModel == nullptr) {
+                numFailedIterations++;
+                ASSERT_LE(numFailedIterations, kMaxNumFailedIterationsTOCTOU);
+            } else {
+                numSuccessfulIterations++;
+            }
         }
 
         // Retrieve preparedModel from cache.
diff --git a/neuralnetworks/1.2/vts/functional/TestMain.cpp b/neuralnetworks/1.2/vts/functional/TestMain.cpp
new file mode 100644
index 0000000..6bf4e5f
--- /dev/null
+++ b/neuralnetworks/1.2/vts/functional/TestMain.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include <gtest/gtest.h>
+#include "1.0/LogTestCaseToLogcat.h"
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    testing::UnitTest::GetInstance()->listeners().Append(
+            new android::hardware::neuralnetworks::LogTestCaseToLogcat());
+    return RUN_ALL_TESTS();
+}
diff --git a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
index d01336e..c4e2b15 100644
--- a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
@@ -21,6 +21,7 @@
 #include <android/hardware/neuralnetworks/1.2/IPreparedModel.h>
 #include <android/hardware/neuralnetworks/1.2/types.h>
 #include <gtest/gtest.h>
+#include <vector>
 #include "1.0/Utils.h"
 #include "1.2/Callbacks.h"
 
diff --git a/neuralnetworks/1.3/vts/functional/Android.bp b/neuralnetworks/1.3/vts/functional/Android.bp
index 771fc54..b17d445 100644
--- a/neuralnetworks/1.3/vts/functional/Android.bp
+++ b/neuralnetworks/1.3/vts/functional/Android.bp
@@ -43,6 +43,7 @@
         "MemoryDomainTests.cpp",
         "QualityOfServiceTests.cpp",
         "TestAssertions.cpp",
+        "TestMain.cpp",
         "ValidateBurst.cpp",
         "ValidateModel.cpp",
         "ValidateRequest.cpp",
diff --git a/neuralnetworks/1.3/vts/functional/AndroidTest.xml b/neuralnetworks/1.3/vts/functional/AndroidTest.xml
index 30cff2e..e5acd90 100644
--- a/neuralnetworks/1.3/vts/functional/AndroidTest.xml
+++ b/neuralnetworks/1.3/vts/functional/AndroidTest.xml
@@ -26,10 +26,6 @@
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
-        <!-- b/156691406, b/155577050, b/155674368, b/153876253, temporarily disable the test.
-             Must be deleted after corresponding driver issues are fixed.
-        -->
-        <option name="native-test-flag" value="--gtest_filter=-*Validation*:*DynamicOutputShapeTest*:*FencedComputeTest*:*MemoryDomain*:*QuantizationCouplingTest*:*DeadlineTest*:*resize_*_v1_3*:*squeeze*_all*_inputs*:*strided_slice*_all*_inputs*:*transpose*_all*_inputs*:*l2_normalization_axis_corner_case*:*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*" />
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="VtsHalNeuralnetworksV1_3TargetTest" />
     </test>
diff --git a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
index ac18c8f..382fc76 100644
--- a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
@@ -318,7 +318,8 @@
 
     void saveModelToCache(const Model& model, const hidl_vec<hidl_handle>& modelCache,
                           const hidl_vec<hidl_handle>& dataCache,
-                          sp<IPreparedModel>* preparedModel = nullptr) {
+                          sp<IPreparedModel>* preparedModel = nullptr,
+                          bool allowGeneralFailure = false) {
         if (preparedModel != nullptr) *preparedModel = nullptr;
 
         // Launch prepare model.
@@ -332,7 +333,10 @@
 
         // Retrieve prepared model.
         preparedModelCallback->wait();
-        ASSERT_EQ(preparedModelCallback->getStatus(), ErrorStatus::NONE);
+        const auto prepareCallbackStatus = preparedModelCallback->getStatus();
+        if (!allowGeneralFailure || prepareCallbackStatus != ErrorStatus::GENERAL_FAILURE) {
+            ASSERT_EQ(prepareCallbackStatus, ErrorStatus::NONE);
+        }
         if (preparedModel != nullptr) {
             *preparedModel = IPreparedModel::castFrom(preparedModelCallback->getPreparedModel())
                                      .withDefault(nullptr);
@@ -1013,7 +1017,8 @@
 
 // Number of operations in the large test model.
 constexpr uint32_t kLargeModelSize = 100;
-constexpr uint32_t kNumIterationsTOCTOU = 100;
+constexpr uint32_t kNumSuccessfulIterationsTOCTOU = 100;
+constexpr uint32_t kMaxNumFailedIterationsTOCTOU = 100;
 
 TEST_P(CompilationCachingTest, SaveToCache_TOCTOU) {
     if (!mIsCachingSupported) return;
@@ -1041,18 +1046,30 @@
     // Use a different token for modelAdd.
     mToken[0]++;
 
-    // This test is probabilistic, so we run it multiple times.
-    for (uint32_t i = 0; i < kNumIterationsTOCTOU; i++) {
+    // This test is probabilistic, so we run it multiple times. We allow the compilation to fail
+    // because it is not related to the security aspect of the TOCTOU test. However, we need to have
+    // enough successful iterations to ensure the test coverage.
+    uint32_t numSuccessfulIterations = 0, numFailedIterations = 0;
+    while (numSuccessfulIterations < kNumSuccessfulIterationsTOCTOU) {
         // Save the modelAdd compilation to cache.
         {
             hidl_vec<hidl_handle> modelCache, dataCache;
             createCacheHandles(mModelCache, AccessMode::READ_WRITE, &modelCache);
             createCacheHandles(mDataCache, AccessMode::READ_WRITE, &dataCache);
 
+            sp<IPreparedModel> preparedModel = nullptr;
             // Spawn a thread to copy the cache content concurrently while saving to cache.
             std::thread thread(copyCacheFiles, std::cref(modelCacheMul), std::cref(mModelCache));
-            saveModelToCache(modelAdd, modelCache, dataCache);
+            saveModelToCache(modelAdd, modelCache, dataCache, &preparedModel,
+                             /*allowGeneralFailure=*/true);
             thread.join();
+
+            if (preparedModel == nullptr) {
+                numFailedIterations++;
+                ASSERT_LE(numFailedIterations, kMaxNumFailedIterationsTOCTOU);
+            } else {
+                numSuccessfulIterations++;
+            }
         }
 
         // Retrieve preparedModel from cache.
@@ -1103,14 +1120,26 @@
     // Use a different token for modelAdd.
     mToken[0]++;
 
-    // This test is probabilistic, so we run it multiple times.
-    for (uint32_t i = 0; i < kNumIterationsTOCTOU; i++) {
+    // This test is probabilistic, so we run it multiple times. We allow the compilation to fail
+    // because it is not related to the security aspect of the TOCTOU test. However, we need to have
+    // enough successful iterations to ensure the test coverage.
+    uint32_t numSuccessfulIterations = 0, numFailedIterations = 0;
+    while (numSuccessfulIterations < kNumSuccessfulIterationsTOCTOU) {
         // Save the modelAdd compilation to cache.
         {
             hidl_vec<hidl_handle> modelCache, dataCache;
             createCacheHandles(mModelCache, AccessMode::READ_WRITE, &modelCache);
             createCacheHandles(mDataCache, AccessMode::READ_WRITE, &dataCache);
-            saveModelToCache(modelAdd, modelCache, dataCache);
+            sp<IPreparedModel> preparedModel = nullptr;
+            saveModelToCache(modelAdd, modelCache, dataCache, &preparedModel,
+                             /*allowGeneralFailure=*/true);
+
+            if (preparedModel == nullptr) {
+                numFailedIterations++;
+                ASSERT_LE(numFailedIterations, kMaxNumFailedIterationsTOCTOU);
+            } else {
+                numSuccessfulIterations++;
+            }
         }
 
         // Retrieve preparedModel from cache.
diff --git a/neuralnetworks/1.3/vts/functional/TestMain.cpp b/neuralnetworks/1.3/vts/functional/TestMain.cpp
new file mode 100644
index 0000000..6bf4e5f
--- /dev/null
+++ b/neuralnetworks/1.3/vts/functional/TestMain.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include <gtest/gtest.h>
+#include "1.0/LogTestCaseToLogcat.h"
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    testing::UnitTest::GetInstance()->listeners().Append(
+            new android::hardware::neuralnetworks::LogTestCaseToLogcat());
+    return RUN_ALL_TESTS();
+}
diff --git a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h
index de082c3..a2e5071 100644
--- a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h
@@ -21,6 +21,7 @@
 #include <android/hardware/neuralnetworks/1.3/IPreparedModel.h>
 #include <android/hardware/neuralnetworks/1.3/types.h>
 #include <gtest/gtest.h>
+#include <vector>
 #include "1.0/Utils.h"
 #include "1.3/Callbacks.h"
 
diff --git a/radio/1.5/vts/functional/radio_response.cpp b/radio/1.5/vts/functional/radio_response.cpp
index 8cbb2d0..9b6d450 100644
--- a/radio/1.5/vts/functional/radio_response.cpp
+++ b/radio/1.5/vts/functional/radio_response.cpp
@@ -1017,8 +1017,10 @@
     return Void();
 }
 
-Return<void> RadioResponse_v1_5::sendCdmaSmsExpectMoreResponse(const RadioResponseInfo& /*info*/,
+Return<void> RadioResponse_v1_5::sendCdmaSmsExpectMoreResponse(const RadioResponseInfo& info,
                                                                const SendSmsResult& /*sms*/) {
+    rspInfo = info;
+    parent_v1_5.notify(info.serial);
     return Void();
 }