Merge "broadcastradio@2.0 VTS uses DAB frequency invalid in some regions"
diff --git a/current.txt b/current.txt
index cd1446d..88b067d 100644
--- a/current.txt
+++ b/current.txt
@@ -836,4 +836,7 @@
 ead4ec8713a2cb40906fe31ba793d21a6b1190143c446690d16a6ea686aa2fea android.hardware.tetheroffload.control@1.1::ITetheringOffloadCallback
 e34b4c7bec5e032c14804707ca924dd6b99ed5ba139da7505fe7d698d0fe178f android.hardware.tetheroffload.control@1.1::types
 
+# ABI preserving changes to HALs during Android T
+62ace52d9c3ff1f60f94118557a2aaf0b953513e59dcd34d5f94ae28d4c7e780 android.hardware.fastboot@1.0::IFastboot
+
 # There should be no more HIDL HALs - please use AIDL instead.
diff --git a/fastboot/1.0/IFastboot.hal b/fastboot/1.0/IFastboot.hal
index dce3ad7..b39061c 100644
--- a/fastboot/1.0/IFastboot.hal
+++ b/fastboot/1.0/IFastboot.hal
@@ -33,7 +33,7 @@
     /**
      * Executes a fastboot OEM command.
      *
-     * @param oemCmdArgs The oem command that is passed to the fastboot HAL.
+     * @param oemCmd The oem command that is passed to the fastboot HAL.
      * @return result Returns the status SUCCESS if the operation is successful,
      *     INVALID_ARGUMENT for bad arguments,
      *     FAILURE_UNKNOWN for an invalid/unsupported command.
diff --git a/identity/aidl/default/common/WritableIdentityCredential.cpp b/identity/aidl/default/common/WritableIdentityCredential.cpp
index 25f129b..200ee61 100644
--- a/identity/aidl/default/common/WritableIdentityCredential.cpp
+++ b/identity/aidl/default/common/WritableIdentityCredential.cpp
@@ -210,6 +210,15 @@
                 "numAccessControlProfileRemaining_ is not zero"));
     }
 
+    // Ensure passed-in profile ids reference valid access control profiles
+    for (const int32_t id : accessControlProfileIds) {
+        if (accessControlProfileIds_.find(id) == accessControlProfileIds_.end()) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "An id in accessControlProfileIds references non-existing ACP"));
+        }
+    }
+
     if (remainingEntryCounts_.size() == 0) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                 IIdentityCredentialStore::STATUS_INVALID_DATA, "No more namespaces to add to"));
diff --git a/identity/aidl/vts/DeleteCredentialTests.cpp b/identity/aidl/vts/DeleteCredentialTests.cpp
index d3addf4..7627c9c 100644
--- a/identity/aidl/vts/DeleteCredentialTests.cpp
+++ b/identity/aidl/vts/DeleteCredentialTests.cpp
@@ -102,7 +102,7 @@
     ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk());
 
     // Single entry - don't care about the returned encrypted data
-    ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "Some Data", 1).isOk());
+    ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Some Data", 1).isOk());
     vector<uint8_t> encryptedData;
     ASSERT_TRUE(wc->addEntryValue({9}, &encryptedData).isOk());
 
diff --git a/identity/aidl/vts/ProveOwnershipTests.cpp b/identity/aidl/vts/ProveOwnershipTests.cpp
index fa0e293..c622193 100644
--- a/identity/aidl/vts/ProveOwnershipTests.cpp
+++ b/identity/aidl/vts/ProveOwnershipTests.cpp
@@ -102,7 +102,7 @@
     ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk());
 
     // Single entry - don't care about the returned encrypted data
-    ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "Some Data", 1).isOk());
+    ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Some Data", 1).isOk());
     vector<uint8_t> encryptedData;
     ASSERT_TRUE(wc->addEntryValue({9}, &encryptedData).isOk());
 
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
index 4547624..7f4674d 100644
--- a/identity/support/src/IdentityCredentialSupport.cpp
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -644,7 +644,7 @@
     // the VTS tests. Of course, this is a pretend-only game since hopefully no
     // relying party is ever going to trust our batch key and those keys above
     // it.
-    ::keymaster::PureSoftKeymasterContext context(::keymaster::KmVersion::KEYMASTER_4_1,
+    ::keymaster::PureSoftKeymasterContext context(::keymaster::KmVersion::KEYMINT_1,
                                                   KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT);
 
     keymaster_error_t error;
@@ -682,10 +682,9 @@
 
     i2d_X509_NAME(subjectName.get(), &subjectPtr);
 
-    uint64_t nowMilliSeconds = time(nullptr) * 1000;
     ::keymaster::AuthorizationSet auth_set(
             ::keymaster::AuthorizationSetBuilder()
-                    .Authorization(::keymaster::TAG_CERTIFICATE_NOT_BEFORE, nowMilliSeconds)
+                    .Authorization(::keymaster::TAG_CERTIFICATE_NOT_BEFORE, activeTimeMilliSeconds)
                     .Authorization(::keymaster::TAG_CERTIFICATE_NOT_AFTER, expireTimeMilliSeconds)
                     .Authorization(::keymaster::TAG_ATTESTATION_CHALLENGE, challenge.data(),
                                    challenge.size())
diff --git a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
index e0b529f..94ce5c1 100644
--- a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
@@ -357,16 +357,40 @@
         return false;
     }
 
+    // If fallbackModel is not provided, call prepareModelFromCache.
+    // If fallbackModel is provided, and prepareModelFromCache returns GENERAL_FAILURE,
+    // then prepareModel(fallbackModel) will be called.
+    // This replicates the behaviour of the runtime when loading a model from cache.
+    // NNAPI Shim depends on this behaviour and may try to load the model from cache in
+    // prepareModel (shim needs model information when loading from cache).
     void prepareModelFromCache(const std::vector<ndk::ScopedFileDescriptor>& modelCache,
                                const std::vector<ndk::ScopedFileDescriptor>& dataCache,
-                               std::shared_ptr<IPreparedModel>* preparedModel,
-                               ErrorStatus* status) {
+                               std::shared_ptr<IPreparedModel>* preparedModel, ErrorStatus* status,
+                               const Model* fallbackModel = nullptr) {
         // Launch prepare model from cache.
         std::shared_ptr<PreparedModelCallback> preparedModelCallback =
                 ndk::SharedRefBase::make<PreparedModelCallback>();
         std::vector<uint8_t> cacheToken(std::begin(mToken), std::end(mToken));
-        const auto prepareLaunchStatus = kDevice->prepareModelFromCache(
+        auto prepareLaunchStatus = kDevice->prepareModelFromCache(
                 kNoDeadline, modelCache, dataCache, cacheToken, preparedModelCallback);
+
+        // The shim does not support prepareModelFromCache() properly, but it
+        // will still attempt to create a model from cache when modelCache or
+        // dataCache is provided in prepareModel(). Instead of failing straight
+        // away, we try to utilize that other code path when fallbackModel is
+        // set. Note that we cannot verify whether the returned model was
+        // actually prepared from cache in that case.
+        if (!prepareLaunchStatus.isOk() &&
+            prepareLaunchStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
+            static_cast<ErrorStatus>(prepareLaunchStatus.getServiceSpecificError()) ==
+                    ErrorStatus::GENERAL_FAILURE &&
+            mIsCachingSupported && fallbackModel != nullptr) {
+            preparedModelCallback = ndk::SharedRefBase::make<PreparedModelCallback>();
+            prepareLaunchStatus = kDevice->prepareModel(
+                    *fallbackModel, ExecutionPreference::FAST_SINGLE_ANSWER, kDefaultPriority,
+                    kNoDeadline, modelCache, dataCache, cacheToken, preparedModelCallback);
+        }
+
         ASSERT_TRUE(prepareLaunchStatus.isOk() ||
                     prepareLaunchStatus.getExceptionCode() == EX_SERVICE_SPECIFIC)
                 << "prepareLaunchStatus: " << prepareLaunchStatus.getDescription();
@@ -382,6 +406,42 @@
         *preparedModel = preparedModelCallback->getPreparedModel();
     }
 
+    // Replicate behaviour of runtime when loading model from cache.
+    // Test if prepareModelFromCache behaves correctly when faced with bad
+    // arguments. If prepareModelFromCache is not supported (GENERAL_FAILURE),
+    // it attempts to call prepareModel with same arguments, which is expected either
+    // to not support the model (GENERAL_FAILURE) or return a valid model.
+    void verifyModelPreparationBehaviour(const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+                                         const std::vector<ndk::ScopedFileDescriptor>& dataCache,
+                                         const Model* model, const TestModel& testModel) {
+        std::shared_ptr<IPreparedModel> preparedModel;
+        ErrorStatus status;
+
+        // Verify that prepareModelFromCache fails either due to bad
+        // arguments (INVALID_ARGUMENT) or GENERAL_FAILURE if not supported.
+        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status,
+                              /*fallbackModel=*/nullptr);
+        if (status != ErrorStatus::INVALID_ARGUMENT) {
+            ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
+        }
+        ASSERT_EQ(preparedModel, nullptr);
+
+        // If caching is not supported, attempt calling prepareModel.
+        if (status == ErrorStatus::GENERAL_FAILURE) {
+            // Fallback with prepareModel should succeed regardless of cache files
+            prepareModelFromCache(modelCache, dataCache, &preparedModel, &status,
+                                  /*fallbackModel=*/model);
+            // Unless caching is not supported?
+            if (status != ErrorStatus::GENERAL_FAILURE) {
+                // But if it is, we should see a valid model.
+                ASSERT_EQ(status, ErrorStatus::NONE);
+                ASSERT_NE(preparedModel, nullptr);
+                EvaluatePreparedModel(kDevice, preparedModel, testModel,
+                                      /*testKind=*/TestKind::GENERAL);
+            }
+        }
+    }
+
     // Absolute path to the temporary cache directory.
     std::string mCacheDir;
 
@@ -397,7 +457,7 @@
     uint8_t mToken[static_cast<uint32_t>(IDevice::BYTE_SIZE_OF_CACHE_TOKEN)] = {};
     uint32_t mNumModelCache;
     uint32_t mNumDataCache;
-    uint32_t mIsCachingSupported;
+    bool mIsCachingSupported;
 
     const std::shared_ptr<IDevice> kDevice;
     // The primary data type of the testModel.
@@ -438,7 +498,8 @@
         std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
         createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache);
         createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache);
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
+        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status,
+                              /*fallbackModel=*/&model);
         if (!mIsCachingSupported) {
             ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
             ASSERT_EQ(preparedModel, nullptr);
@@ -498,7 +559,8 @@
         for (uint32_t i = 0; i < dataCache.size(); i++) {
             ASSERT_GE(read(dataCache[i].get(), &placeholderByte, 1), 0);
         }
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
+        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status,
+                              /*fallbackModel=*/&model);
         if (!mIsCachingSupported) {
             ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
             ASSERT_EQ(preparedModel, nullptr);
@@ -536,13 +598,7 @@
         // Execute and verify results.
         EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
         // Check if prepareModelFromCache fails.
-        preparedModel = nullptr;
-        ErrorStatus status;
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
-        if (status != ErrorStatus::INVALID_ARGUMENT) {
-            ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
-        }
-        ASSERT_EQ(preparedModel, nullptr);
+        verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
     }
 
     // Test with number of model cache files smaller than mNumModelCache.
@@ -560,13 +616,7 @@
         // Execute and verify results.
         EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
         // Check if prepareModelFromCache fails.
-        preparedModel = nullptr;
-        ErrorStatus status;
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
-        if (status != ErrorStatus::INVALID_ARGUMENT) {
-            ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
-        }
-        ASSERT_EQ(preparedModel, nullptr);
+        verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
     }
 
     // Test with number of data cache files greater than mNumDataCache.
@@ -583,13 +633,7 @@
         // Execute and verify results.
         EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
         // Check if prepareModelFromCache fails.
-        preparedModel = nullptr;
-        ErrorStatus status;
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
-        if (status != ErrorStatus::INVALID_ARGUMENT) {
-            ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
-        }
-        ASSERT_EQ(preparedModel, nullptr);
+        verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
     }
 
     // Test with number of data cache files smaller than mNumDataCache.
@@ -607,13 +651,7 @@
         // Execute and verify results.
         EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
         // Check if prepareModelFromCache fails.
-        preparedModel = nullptr;
-        ErrorStatus status;
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
-        if (status != ErrorStatus::INVALID_ARGUMENT) {
-            ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
-        }
-        ASSERT_EQ(preparedModel, nullptr);
+        verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
     }
 }
 
@@ -633,68 +671,48 @@
 
     // Test with number of model cache files greater than mNumModelCache.
     {
-        std::shared_ptr<IPreparedModel> preparedModel = nullptr;
-        ErrorStatus status;
         std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
         mModelCache.push_back({mTmpCache});
         createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache);
         createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache);
         mModelCache.pop_back();
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
-        if (status != ErrorStatus::GENERAL_FAILURE) {
-            ASSERT_EQ(status, ErrorStatus::INVALID_ARGUMENT);
-        }
-        ASSERT_EQ(preparedModel, nullptr);
+
+        verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
     }
 
     // Test with number of model cache files smaller than mNumModelCache.
     if (mModelCache.size() > 0) {
-        std::shared_ptr<IPreparedModel> preparedModel = nullptr;
-        ErrorStatus status;
         std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
         auto tmp = mModelCache.back();
         mModelCache.pop_back();
         createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache);
         createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache);
         mModelCache.push_back(tmp);
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
-        if (status != ErrorStatus::GENERAL_FAILURE) {
-            ASSERT_EQ(status, ErrorStatus::INVALID_ARGUMENT);
-        }
-        ASSERT_EQ(preparedModel, nullptr);
+
+        verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
     }
 
     // Test with number of data cache files greater than mNumDataCache.
     {
-        std::shared_ptr<IPreparedModel> preparedModel = nullptr;
-        ErrorStatus status;
         std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
         mDataCache.push_back({mTmpCache});
         createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache);
         createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache);
         mDataCache.pop_back();
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
-        if (status != ErrorStatus::GENERAL_FAILURE) {
-            ASSERT_EQ(status, ErrorStatus::INVALID_ARGUMENT);
-        }
-        ASSERT_EQ(preparedModel, nullptr);
+
+        verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
     }
 
     // Test with number of data cache files smaller than mNumDataCache.
     if (mDataCache.size() > 0) {
-        std::shared_ptr<IPreparedModel> preparedModel = nullptr;
-        ErrorStatus status;
         std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
         auto tmp = mDataCache.back();
         mDataCache.pop_back();
         createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache);
         createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache);
         mDataCache.push_back(tmp);
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
-        if (status != ErrorStatus::GENERAL_FAILURE) {
-            ASSERT_EQ(status, ErrorStatus::INVALID_ARGUMENT);
-        }
-        ASSERT_EQ(preparedModel, nullptr);
+
+        verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
     }
 }
 
@@ -719,13 +737,7 @@
         // Execute and verify results.
         EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
         // Check if prepareModelFromCache fails.
-        preparedModel = nullptr;
-        ErrorStatus status;
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
-        if (status != ErrorStatus::INVALID_ARGUMENT) {
-            ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
-        }
-        ASSERT_EQ(preparedModel, nullptr);
+        verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
     }
 
     // Go through each handle in data cache, test with invalid access mode.
@@ -741,13 +753,7 @@
         // Execute and verify results.
         EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL);
         // Check if prepareModelFromCache fails.
-        preparedModel = nullptr;
-        ErrorStatus status;
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
-        if (status != ErrorStatus::INVALID_ARGUMENT) {
-            ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
-        }
-        ASSERT_EQ(preparedModel, nullptr);
+        verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
     }
 }
 
@@ -769,30 +775,23 @@
 
     // Go through each handle in model cache, test with invalid access mode.
     for (uint32_t i = 0; i < mNumModelCache; i++) {
-        std::shared_ptr<IPreparedModel> preparedModel = nullptr;
-        ErrorStatus status;
         std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
         modelCacheMode[i] = AccessMode::WRITE_ONLY;
         createCacheFds(mModelCache, modelCacheMode, &modelCache);
         createCacheFds(mDataCache, dataCacheMode, &dataCache);
         modelCacheMode[i] = AccessMode::READ_WRITE;
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
-        ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
-        ASSERT_EQ(preparedModel, nullptr);
+
+        verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
     }
 
     // Go through each handle in data cache, test with invalid access mode.
     for (uint32_t i = 0; i < mNumDataCache; i++) {
-        std::shared_ptr<IPreparedModel> preparedModel = nullptr;
-        ErrorStatus status;
         std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
         dataCacheMode[i] = AccessMode::WRITE_ONLY;
         createCacheFds(mModelCache, modelCacheMode, &modelCache);
         createCacheFds(mDataCache, dataCacheMode, &dataCache);
         dataCacheMode[i] = AccessMode::READ_WRITE;
-        prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
-        ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE);
-        ASSERT_EQ(preparedModel, nullptr);
+        verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel);
     }
 }
 
@@ -872,7 +871,8 @@
             std::vector<ndk::ScopedFileDescriptor> modelCache, dataCache;
             createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache);
             createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache);
-            prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
+            prepareModelFromCache(modelCache, dataCache, &preparedModel, &status,
+                                  /*fallbackModel=*/nullptr);
 
             // The preparation may fail or succeed, but must not crash. If the preparation succeeds,
             // the prepared model must be executed with the correct result and not crash.
@@ -933,7 +933,8 @@
 
             // Spawn a thread to copy the cache content concurrently while preparing from cache.
             std::thread thread(copyCacheFiles, std::cref(modelCacheMul), std::cref(mModelCache));
-            prepareModelFromCache(modelCache, dataCache, &preparedModel, &status);
+            prepareModelFromCache(modelCache, dataCache, &preparedModel, &status,
+                                  /*fallbackModel=*/nullptr);
             thread.join();
 
             // The preparation may fail or succeed, but must not crash. If the preparation succeeds,
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 422e91c..34395ca 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -821,7 +821,7 @@
 /*
  * Test IRadio.updateSimPhonebookRecords() for the response returned.
  */
-TEST_F(RadioHidlTest_v1_6, updateSimPhonebookRecords) {
+TEST_P(RadioHidlTest_v1_6, updateSimPhonebookRecords) {
     serial = GetRandomSerialNumber();
     radio_v1_6->getSimPhonebookCapacity(serial);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -851,7 +851,11 @@
         EXPECT_EQ(std::cv_status::no_timeout, wait());
         EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
         EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
-        EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error);
+        ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_v1_6->rspInfo.error,
+            {::android::hardware::radio::V1_6::RadioError::NONE,
+             ::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED},
+             CHECK_GENERAL_ERROR));
 
         if(pbCapacity.maxAdnRecords > 0
                 && pbCapacity.usedAdnRecords < pbCapacity.maxAdnRecords) {
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 9cc795d..5b0b303 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -805,9 +805,10 @@
     byte[] convertStorageKeyToEphemeral(in byte[] storageKeyBlob);
 
     /**
-     * Returns parameters associated with the provided key. This should match the
-     * KeyCharacteristics present in the KeyCreationResult returned by generateKey(),
-     * importKey(), or importWrappedKey().
+     * Returns KeyMint-enforced parameters associated with the provided key. The returned tags are
+     * a subset of KeyCharacteristics found in the KeyCreationResult returned by generateKey(),
+     * importKey(), or importWrappedKey(). The returned value is a subset, as it does not include
+     * any Keystore-enforced parameters.
      *
      * @param keyBlob The opaque descriptor returned by generateKey, importKey or importWrappedKey.
      *
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index b8699e9..ae2becd 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -141,11 +141,18 @@
                               attest_key, &attested_key_blob, &attested_key_characteristics,
                               &attested_key_cert_chain));
 
+        // The returned key characteristics will include CREATION_DATETIME (checked below)
+        // in SecurityLevel::KEYSTORE; this will be stripped out in the CheckCharacteristics()
+        // call below, to match what getKeyCharacteristics() returns (which doesn't include
+        // any SecurityLevel::KEYSTORE characteristics).
+        CheckCharacteristics(attested_key_blob, attested_key_characteristics);
+
         CheckedDeleteKey(&attested_key_blob);
         CheckedDeleteKey(&attest_key.keyBlob);
 
         hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+
         // The client-specified CREATION_DATETIME should be in sw_enforced.
         // Its presence will also trigger verify_attestation_record() to check that it
         // is in the attestation extension with a matching value.
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index a9a67bc..44b8274 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -142,6 +142,15 @@
     return filtered;
 }
 
+// Remove any SecurityLevel::KEYSTORE entries from a list of key characteristics.
+void strip_keystore_tags(vector<KeyCharacteristics>* characteristics) {
+    characteristics->erase(std::remove_if(characteristics->begin(), characteristics->end(),
+                                          [](const auto& entry) {
+                                              return entry.securityLevel == SecurityLevel::KEYSTORE;
+                                          }),
+                           characteristics->end());
+}
+
 string x509NameToStr(X509_NAME* name) {
     char* s = X509_NAME_oneline(name, nullptr, 0);
     string retval(s);
@@ -320,6 +329,65 @@
     return GetReturnErrorCode(result);
 }
 
+ErrorCode KeyMintAidlTestBase::GetCharacteristics(const vector<uint8_t>& key_blob,
+                                                  const vector<uint8_t>& app_id,
+                                                  const vector<uint8_t>& app_data,
+                                                  vector<KeyCharacteristics>* key_characteristics) {
+    Status result =
+            keymint_->getKeyCharacteristics(key_blob, app_id, app_data, key_characteristics);
+    return GetReturnErrorCode(result);
+}
+
+ErrorCode KeyMintAidlTestBase::GetCharacteristics(const vector<uint8_t>& key_blob,
+                                                  vector<KeyCharacteristics>* key_characteristics) {
+    vector<uint8_t> empty_app_id, empty_app_data;
+    return GetCharacteristics(key_blob, empty_app_id, empty_app_data, key_characteristics);
+}
+
+void KeyMintAidlTestBase::CheckCharacteristics(
+        const vector<uint8_t>& key_blob,
+        const vector<KeyCharacteristics>& generate_characteristics) {
+    // Any key characteristics that were in SecurityLevel::KEYSTORE when returned from
+    // generateKey() should be excluded, as KeyMint will have no record of them.
+    // This applies to CREATION_DATETIME in particular.
+    vector<KeyCharacteristics> expected_characteristics(generate_characteristics);
+    strip_keystore_tags(&expected_characteristics);
+
+    vector<KeyCharacteristics> retrieved;
+    ASSERT_EQ(ErrorCode::OK, GetCharacteristics(key_blob, &retrieved));
+    EXPECT_EQ(expected_characteristics, retrieved);
+}
+
+void KeyMintAidlTestBase::CheckAppIdCharacteristics(
+        const vector<uint8_t>& key_blob, std::string_view app_id_string,
+        std::string_view app_data_string,
+        const vector<KeyCharacteristics>& generate_characteristics) {
+    // Exclude any SecurityLevel::KEYSTORE characteristics for comparisons.
+    vector<KeyCharacteristics> expected_characteristics(generate_characteristics);
+    strip_keystore_tags(&expected_characteristics);
+
+    vector<uint8_t> app_id(app_id_string.begin(), app_id_string.end());
+    vector<uint8_t> app_data(app_data_string.begin(), app_data_string.end());
+    vector<KeyCharacteristics> retrieved;
+    ASSERT_EQ(ErrorCode::OK, GetCharacteristics(key_blob, app_id, app_data, &retrieved));
+    EXPECT_EQ(expected_characteristics, retrieved);
+
+    // Check that key characteristics can't be retrieved if the app ID or app data is missing.
+    vector<uint8_t> empty;
+    vector<KeyCharacteristics> not_retrieved;
+    EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
+              GetCharacteristics(key_blob, empty, app_data, &not_retrieved));
+    EXPECT_EQ(not_retrieved.size(), 0);
+
+    EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
+              GetCharacteristics(key_blob, app_id, empty, &not_retrieved));
+    EXPECT_EQ(not_retrieved.size(), 0);
+
+    EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
+              GetCharacteristics(key_blob, empty, empty, &not_retrieved));
+    EXPECT_EQ(not_retrieved.size(), 0);
+}
+
 ErrorCode KeyMintAidlTestBase::DeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob) {
     Status result = keymint_->deleteKey(*key_blob);
     if (!keep_key_blob) {
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index d8f1bb3..c49b303 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <string_view>
+
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
 #include <binder/IServiceManager.h>
@@ -104,6 +106,18 @@
                                 unwrapping_params, 0 /* password_sid */, 0 /* biometric_sid */);
     }
 
+    ErrorCode GetCharacteristics(const vector<uint8_t>& key_blob, const vector<uint8_t>& app_id,
+                                 const vector<uint8_t>& app_data,
+                                 vector<KeyCharacteristics>* key_characteristics);
+    ErrorCode GetCharacteristics(const vector<uint8_t>& key_blob,
+                                 vector<KeyCharacteristics>* key_characteristics);
+
+    void CheckCharacteristics(const vector<uint8_t>& key_blob,
+                              const vector<KeyCharacteristics>& generate_characteristics);
+    void CheckAppIdCharacteristics(const vector<uint8_t>& key_blob, std::string_view app_id_string,
+                                   std::string_view app_data_string,
+                                   const vector<KeyCharacteristics>& generate_characteristics);
+
     ErrorCode DeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob = false);
     ErrorCode DeleteKey(bool keep_key_blob = false);
 
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 8b1eb30..5dcfcaa 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -560,6 +560,7 @@
 
                 EXPECT_GT(key_blob.size(), 0U);
                 CheckSymmetricParams(key_characteristics);
+                CheckCharacteristics(key_blob, key_characteristics);
 
                 AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -742,6 +743,7 @@
 
                 EXPECT_GT(key_blob.size(), 0U);
                 CheckSymmetricParams(key_characteristics);
+                CheckCharacteristics(key_blob, key_characteristics);
 
                 AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -788,6 +790,7 @@
 
                 EXPECT_GT(key_blob.size(), 0U);
                 CheckSymmetricParams(key_characteristics);
+                CheckCharacteristics(key_blob, key_characteristics);
 
                 AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -865,6 +868,7 @@
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -911,6 +915,7 @@
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -978,6 +983,7 @@
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -1108,6 +1114,7 @@
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -1176,6 +1183,7 @@
 
     ASSERT_GT(key_blob.size(), 0U);
     CheckBaseParams(key_characteristics);
+    CheckCharacteristics(key_blob, key_characteristics);
 
     AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -1211,6 +1219,7 @@
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -1266,6 +1275,7 @@
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -1362,6 +1372,7 @@
                                              &key_blob, &key_characteristics));
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -1405,6 +1416,7 @@
                               &key_blob, &key_characteristics));
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -1452,6 +1464,7 @@
                               &key_blob, &key_characteristics));
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -1511,6 +1524,7 @@
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -1555,6 +1569,7 @@
                                              &key_blob, &key_characteristics));
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -1594,6 +1609,7 @@
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
@@ -1726,6 +1742,7 @@
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
         EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
@@ -1761,6 +1778,7 @@
         ASSERT_GT(key_blob.size(), 0U);
         ASSERT_EQ(cert_chain_.size(), 0);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
         EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
@@ -1791,6 +1809,7 @@
 
         ASSERT_GT(key_blob.size(), 0U);
         CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
         EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
@@ -2044,6 +2063,9 @@
                                                  .Authorization(TAG_APPLICATION_ID, "clientid")
                                                  .Authorization(TAG_APPLICATION_DATA, "appdata")
                                                  .SetDefaultValidity()));
+
+    CheckAppIdCharacteristics(key_blob_, "clientid", "appdata", key_characteristics_);
+
     EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
               Begin(KeyPurpose::SIGN,
                     AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE)));
@@ -2558,6 +2580,9 @@
                                                  .Authorization(TAG_APPLICATION_ID, "clientid")
                                                  .Authorization(TAG_APPLICATION_DATA, "appdata")
                                                  .SetDefaultValidity()));
+
+    CheckAppIdCharacteristics(key_blob_, "clientid", "appdata", key_characteristics_);
+
     EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
               Begin(KeyPurpose::SIGN, AuthorizationSetBuilder().Digest(Digest::NONE)));
     AbortIfNeeded();
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index a2071c2..a177317 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -340,6 +340,7 @@
                                               cppbor::Array()  // SignedMacAad
                                                       .add(challenge_)
                                                       .add(std::move(deviceInfoMap))
+                                                      .add(keysToSignMac)
                                                       .encode());
         ASSERT_TRUE(macKey) << macKey.message();
 
diff --git a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
index 2fbd29a..fcf2ee8 100644
--- a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
+++ b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
@@ -39,7 +39,7 @@
      * 32-byte HMAC-SHA256 of the above values, computed as:
      *
      *    HMAC(H,
-     *         ISecureClock.TIME_STAMP_MAC_LABEL || challenge || timestamp || securityLevel )
+     *         ISecureClock.TIME_STAMP_MAC_LABEL || challenge || timestamp || 1 )
      *
      * where:
      *
@@ -50,9 +50,7 @@
      *   ``||'' represents concatenation
      *
      * The representation of challenge and timestamp is as 64-bit unsigned integers in big-endian
-     * order. SecurityLevel is represented as a 32-bit unsigned integer in big-endian order as
-     * described in android.hardware.security.keymint.SecurityLevel. It represents the security
-     * level of the secure clock environment.
+     * order.  1, above, is a 32-bit unsigned integer, also big-endian.
      */
     byte[] mac;
 }