Merge "Update comments of RegState.REG_EM" into main-ims-dev
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index d6e6f50..4871058 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -100,6 +100,7 @@
"android/hardware/audio/core/MmapBufferDescriptor.aidl",
"android/hardware/audio/core/ModuleDebug.aidl",
"android/hardware/audio/core/StreamDescriptor.aidl",
+ "android/hardware/audio/core/SurroundSoundConfig.aidl",
],
imports: [
"android.hardware.common-V2",
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl
index fd80715..163b7a0 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl
@@ -34,4 +34,5 @@
package android.hardware.audio.core;
@VintfStability
interface IConfig {
+ android.hardware.audio.core.SurroundSoundConfig getSurroundSoundConfig();
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/SurroundSoundConfig.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/SurroundSoundConfig.aidl
new file mode 100644
index 0000000..08a1537
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/SurroundSoundConfig.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SurroundSoundConfig {
+ android.hardware.audio.core.SurroundSoundConfig.SurroundFormatFamily[] formatFamilies;
+ @VintfStability
+ parcelable SurroundFormatFamily {
+ android.media.audio.common.AudioFormatDescription primaryFormat;
+ android.media.audio.common.AudioFormatDescription[] subFormats;
+ }
+}
diff --git a/audio/aidl/android/hardware/audio/core/IConfig.aidl b/audio/aidl/android/hardware/audio/core/IConfig.aidl
index c7bb414..c8ba6be 100644
--- a/audio/aidl/android/hardware/audio/core/IConfig.aidl
+++ b/audio/aidl/android/hardware/audio/core/IConfig.aidl
@@ -16,9 +16,22 @@
package android.hardware.audio.core;
+import android.hardware.audio.core.SurroundSoundConfig;
+
/**
* This interface provides system-wide configuration parameters for audio I/O
* (by "system" here we mean the device running Android).
*/
@VintfStability
-interface IConfig {}
+interface IConfig {
+ /**
+ * Returns the surround sound configuration used for the Audio Policy
+ * Manager initial configuration.
+ *
+ * This method will only be called during the initialization of the Audio
+ * Policy Manager, and must always return the same result.
+ *
+ * @return The surround sound configuration
+ */
+ SurroundSoundConfig getSurroundSoundConfig();
+}
diff --git a/audio/aidl/android/hardware/audio/core/SurroundSoundConfig.aidl b/audio/aidl/android/hardware/audio/core/SurroundSoundConfig.aidl
new file mode 100644
index 0000000..eeda12a
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/SurroundSoundConfig.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.media.audio.common.AudioFormatDescription;
+
+/**
+ * SurroundSoundConfig defines the multi-channel formats that can be enabled on
+ * (primarily TV) devices.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable SurroundSoundConfig {
+ @VintfStability
+ parcelable SurroundFormatFamily {
+ /**
+ * A primaryFormat shall get an entry in the Surround Settings dialog on TV
+ * devices. There must be a corresponding Java ENCODING_... constant
+ * defined in AudioFormat.java, and a display name defined in
+ * AudioFormat.toDisplayName.
+ */
+ AudioFormatDescription primaryFormat;
+ /**
+ * List of formats that shall be equivalent to the primaryFormat from the
+ * users' point of view and don't need a dedicated Surround Settings
+ * dialog entry.
+ */
+ AudioFormatDescription[] subFormats;
+ }
+ SurroundFormatFamily[] formatFamilies;
+}
diff --git a/audio/aidl/default/Config.cpp b/audio/aidl/default/Config.cpp
index 3f7a3d3..0fdd5b4 100644
--- a/audio/aidl/default/Config.cpp
+++ b/audio/aidl/default/Config.cpp
@@ -13,7 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define LOG_TAG "AHAL_Module"
+#include <android-base/logging.h>
#include "core-impl/Config.h"
-namespace aidl::android::hardware::audio::core {} // namespace aidl::android::hardware::audio::core
+namespace aidl::android::hardware::audio::core {
+ndk::ScopedAStatus Config::getSurroundSoundConfig(SurroundSoundConfig* _aidl_return) {
+ SurroundSoundConfig surroundSoundConfig;
+ // TODO: parse from XML; for now, use empty config as default
+ *_aidl_return = std::move(surroundSoundConfig);
+ LOG(DEBUG) << __func__ << ": returning " << _aidl_return->toString();
+ return ndk::ScopedAStatus::ok();
+}
+} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/Config.h b/audio/aidl/default/include/core-impl/Config.h
index b62a14b..4555efd 100644
--- a/audio/aidl/default/include/core-impl/Config.h
+++ b/audio/aidl/default/include/core-impl/Config.h
@@ -20,6 +20,8 @@
namespace aidl::android::hardware::audio::core {
-class Config : public BnConfig {};
+class Config : public BnConfig {
+ ndk::ScopedAStatus getSurroundSoundConfig(SurroundSoundConfig* _aidl_return) override;
+};
} // namespace aidl::android::hardware::audio::core
diff --git a/automotive/remoteaccess/hal/default/Android.bp b/automotive/remoteaccess/hal/default/Android.bp
index 51be330..a2bf86c 100644
--- a/automotive/remoteaccess/hal/default/Android.bp
+++ b/automotive/remoteaccess/hal/default/Android.bp
@@ -47,7 +47,7 @@
cc_library {
name: "RemoteAccessService",
- vendor: true,
+ vendor_available: true,
local_include_dirs: ["include"],
export_include_dirs: ["include"],
srcs: [
@@ -74,3 +74,36 @@
"-Wno-unused-parameter",
],
}
+
+cc_fuzz {
+ name: "android.hardware.automotive.remoteaccess@V1-default-service.aidl_fuzzer",
+ srcs: ["fuzzer/fuzzer.cpp"],
+ whole_static_libs: [
+ "RemoteAccessService",
+ ],
+ static_libs: [
+ "libgtest",
+ "libgmock",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "liblog",
+ "libutils",
+ "libgrpc++",
+ "libprotobuf-cpp-full",
+ ],
+ defaults: [
+ "vhalclient_defaults",
+ "service_fuzzer_defaults",
+ ],
+ cflags: [
+ "-Wno-unused-parameter",
+ "-DGRPC_SERVICE_ADDRESS=\"localhost:50051\"",
+ ],
+ fuzz_config: {
+ cc: [
+ "shanyu@google.com",
+ ],
+ },
+}
diff --git a/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp b/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
new file mode 100644
index 0000000..292c80e
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2022 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 <RemoteAccessService.h>
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <gmock/gmock.h>
+#include <grpcpp/test/mock_stream.h>
+#include <wakeup_client.grpc.pb.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace remoteaccess {
+
+using ::grpc::ClientAsyncReaderInterface;
+using ::grpc::ClientAsyncResponseReaderInterface;
+using ::grpc::ClientContext;
+using ::grpc::ClientReader;
+using ::grpc::ClientReaderInterface;
+using ::grpc::CompletionQueue;
+using ::grpc::Status;
+using ::grpc::testing::MockClientReader;
+using ::testing::_;
+using ::testing::Return;
+
+class MockGrpcClientStub : public WakeupClient::StubInterface {
+ public:
+ ClientReaderInterface<GetRemoteTasksResponse>* GetRemoteTasksRaw(
+ [[maybe_unused]] ClientContext* context,
+ [[maybe_unused]] const GetRemoteTasksRequest& request) override {
+ MockClientReader<GetRemoteTasksResponse>* mockClientReader =
+ new MockClientReader<GetRemoteTasksResponse>();
+ ON_CALL(*mockClientReader, Finish()).WillByDefault(Return(Status::OK));
+ ON_CALL(*mockClientReader, Read(_)).WillByDefault(Return(false));
+ return mockClientReader;
+ }
+
+ Status NotifyWakeupRequired([[maybe_unused]] ClientContext* context,
+ [[maybe_unused]] const NotifyWakeupRequiredRequest& request,
+ [[maybe_unused]] NotifyWakeupRequiredResponse* response) {
+ return Status::OK;
+ }
+
+ // Async methods which we do not care.
+ ClientAsyncReaderInterface<GetRemoteTasksResponse>* AsyncGetRemoteTasksRaw(
+ [[maybe_unused]] ClientContext* context,
+ [[maybe_unused]] const GetRemoteTasksRequest& request,
+ [[maybe_unused]] CompletionQueue* cq, [[maybe_unused]] void* tag) {
+ return nullptr;
+ }
+
+ ClientAsyncReaderInterface<GetRemoteTasksResponse>* PrepareAsyncGetRemoteTasksRaw(
+ [[maybe_unused]] ClientContext* context,
+ [[maybe_unused]] const GetRemoteTasksRequest& request,
+ [[maybe_unused]] CompletionQueue* cq) {
+ return nullptr;
+ }
+
+ ClientAsyncResponseReaderInterface<NotifyWakeupRequiredResponse>* AsyncNotifyWakeupRequiredRaw(
+ [[maybe_unused]] ClientContext* context,
+ [[maybe_unused]] const NotifyWakeupRequiredRequest& request,
+ [[maybe_unused]] CompletionQueue* cq) {
+ return nullptr;
+ }
+
+ ClientAsyncResponseReaderInterface<NotifyWakeupRequiredResponse>*
+ PrepareAsyncNotifyWakeupRequiredRaw([[maybe_unused]] ClientContext* context,
+ [[maybe_unused]] const NotifyWakeupRequiredRequest& request,
+ [[maybe_unused]] CompletionQueue* c) {
+ return nullptr;
+ }
+};
+
+} // namespace remoteaccess
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ android::hardware::automotive::remoteaccess::MockGrpcClientStub stub;
+ std::shared_ptr<android::hardware::automotive::remoteaccess::RemoteAccessService> service =
+ ndk::SharedRefBase::make<
+ android::hardware::automotive::remoteaccess::RemoteAccessService>(&stub);
+ android::fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
+
+ return 0;
+}
diff --git a/automotive/remoteaccess/hal/default/proto/Android.bp b/automotive/remoteaccess/hal/default/proto/Android.bp
index 31b9d0e..3e0dba1 100644
--- a/automotive/remoteaccess/hal/default/proto/Android.bp
+++ b/automotive/remoteaccess/hal/default/proto/Android.bp
@@ -35,7 +35,6 @@
"wakeup_client.pb.h",
"wakeup_client.grpc.pb.h",
],
- vendor: true,
}
genrule {
@@ -52,12 +51,11 @@
"wakeup_client.pb.cc",
"wakeup_client.grpc.pb.cc",
],
- vendor: true,
}
cc_library_static {
name: "wakeup_client_protos",
- vendor: true,
+ vendor_available: true,
host_supported: true,
include_dirs: [
"external/protobuf/src",
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
index 72f37d7..5cd58d3 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
@@ -174,6 +174,7 @@
}
ScopedAStatus RemoteAccessService::getDeviceId(std::string* deviceId) {
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
auto vhalClient = IVhalClient::tryCreate();
if (vhalClient == nullptr) {
ALOGE("Failed to connect to VHAL");
@@ -181,6 +182,10 @@
/*errorCode=*/0, "Failed to connect to VHAL to get device ID");
}
return getDeviceIdWithClient(*vhalClient.get(), deviceId);
+#else
+ // Don't use VHAL client in fuzzing since IPC is not allowed.
+ return ScopedAStatus::ok();
+#endif
}
ScopedAStatus RemoteAccessService::getDeviceIdWithClient(IVhalClient& vhalClient,
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
index 68a1f26..651c9dc 100644
--- a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
@@ -56,43 +56,58 @@
return;
}
- if (FingerprintHalProperties::operation_enroll_fails().value_or(false)) {
- LOG(ERROR) << "Fail: operation_enroll_fails";
- cb->onError(Error::VENDOR, 0 /* vendorError */);
+ // Force error-out
+ auto err = FingerprintHalProperties::operation_enroll_error().value_or(0);
+ if (err != 0) {
+ LOG(ERROR) << "Fail: operation_enroll_error";
+ auto ec = convertError(err);
+ cb->onError(ec.first, ec.second);
return;
}
- // format is "<id>:<progress_ms>,<progress_ms>,...:<result>
+ // Format is "<id>:<progress_ms-[acquiredInfo..]>,...:<result>
auto nextEnroll = FingerprintHalProperties::next_enrollment().value_or("");
auto parts = Util::split(nextEnroll, ":");
if (parts.size() != 3) {
- LOG(ERROR) << "Fail: invalid next_enrollment";
+ LOG(ERROR) << "Fail: invalid next_enrollment:" << nextEnroll;
cb->onError(Error::VENDOR, 0 /* vendorError */);
return;
}
auto enrollmentId = std::stoi(parts[0]);
- auto progress = Util::split(parts[1], ",");
- for (size_t i = 0; i < progress.size(); i++) {
- auto left = progress.size() - i - 1;
- SLEEP_MS(std::stoi(progress[i]));
+ auto progress = parseEnrollmentCapture(parts[1]);
+ for (size_t i = 0; i < progress.size(); i += 2) {
+ auto left = (progress.size() - i) / 2 - 1;
+ auto duration = progress[i][0];
+ auto acquired = progress[i + 1];
+ auto N = acquired.size();
- if (shouldCancel(cancel)) {
- LOG(ERROR) << "Fail: cancel";
- cb->onError(Error::CANCELED, 0 /* vendorCode */);
- return;
+ for (int j = 0; j < N; j++) {
+ SLEEP_MS(duration / N);
+
+ if (shouldCancel(cancel)) {
+ LOG(ERROR) << "Fail: cancel";
+ cb->onError(Error::CANCELED, 0 /* vendorCode */);
+ return;
+ }
+ auto ac = convertAcquiredInfo(acquired[j]);
+ cb->onAcquired(ac.first, ac.second);
}
- cb->onAcquired(AcquiredInfo::GOOD, 0 /* vendorCode */);
if (left == 0 && !IS_TRUE(parts[2])) { // end and failed
LOG(ERROR) << "Fail: requested by caller: " << nextEnroll;
FingerprintHalProperties::next_enrollment({});
cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
} else { // progress and update props if last time
+ LOG(INFO) << "onEnroll: " << enrollmentId << " left: " << left;
if (left == 0) {
auto enrollments = FingerprintHalProperties::enrollments();
enrollments.emplace_back(enrollmentId);
FingerprintHalProperties::enrollments(enrollments);
FingerprintHalProperties::next_enrollment({});
+ // change authenticatorId after new enrollment
+ auto id = FingerprintHalProperties::authenticator_id().value_or(0);
+ auto newId = id + 1;
+ FingerprintHalProperties::authenticator_id(newId);
LOG(INFO) << "Enrolled: " << enrollmentId;
}
cb->onEnrollmentProgress(enrollmentId, left);
@@ -104,12 +119,31 @@
const std::future<void>& cancel) {
BEGIN_OP(FingerprintHalProperties::operation_authenticate_latency().value_or(DEFAULT_LATENCY));
- auto now = Util::getSystemNanoTime();
- int64_t duration = FingerprintHalProperties::operation_authenticate_duration().value_or(0);
+ int64_t now = Util::getSystemNanoTime();
+ int64_t duration = FingerprintHalProperties::operation_authenticate_duration().value_or(10);
+ auto acquired = FingerprintHalProperties::operation_authenticate_acquired().value_or("1");
+ auto acquiredInfos = parseIntSequence(acquired);
+ int N = acquiredInfos.size();
+
+ if (N == 0) {
+ LOG(ERROR) << "Fail to parse authentiate acquired info: " + acquired;
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
+
+ int i = 0;
do {
if (FingerprintHalProperties::operation_authenticate_fails().value_or(false)) {
LOG(ERROR) << "Fail: operation_authenticate_fails";
- cb->onError(Error::VENDOR, 0 /* vendorError */);
+ cb->onAuthenticationFailed();
+ return;
+ }
+
+ auto err = FingerprintHalProperties::operation_authenticate_error().value_or(0);
+ if (err != 0) {
+ LOG(ERROR) << "Fail: operation_authenticate_error";
+ auto ec = convertError(err);
+ cb->onError(ec.first, ec.second);
return;
}
@@ -126,20 +160,25 @@
return;
}
- auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
- auto enrolls = FingerprintHalProperties::enrollments();
- auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
- if (id > 0 && isEnrolled) {
- cb->onAuthenticationSucceeded(id, {} /* hat */);
- return;
+ if (i < N) {
+ auto ac = convertAcquiredInfo(acquiredInfos[i]);
+ cb->onAcquired(ac.first, ac.second);
+ i++;
}
- SLEEP_MS(100);
+ SLEEP_MS(duration / N);
} while (!Util::hasElapsed(now, duration));
- LOG(ERROR) << "Fail: not enrolled";
- cb->onAuthenticationFailed();
- cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
+ auto enrolls = FingerprintHalProperties::enrollments();
+ auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
+ if (id > 0 && isEnrolled) {
+ cb->onAuthenticationSucceeded(id, {} /* hat */);
+ return;
+ } else {
+ LOG(ERROR) << "Fail: fingerprint not enrolled";
+ cb->onAuthenticationFailed();
+ }
}
void FakeFingerprintEngine::detectInteractionImpl(ISessionCallback* cb,
@@ -147,17 +186,42 @@
BEGIN_OP(FingerprintHalProperties::operation_detect_interaction_latency().value_or(
DEFAULT_LATENCY));
- if (FingerprintHalProperties::operation_detect_interaction_fails().value_or(false)) {
- LOG(ERROR) << "Fail: operation_detect_interaction_fails";
- cb->onError(Error::VENDOR, 0 /* vendorError */);
+ int64_t duration =
+ FingerprintHalProperties::operation_detect_interaction_duration().value_or(10);
+ auto acquired = FingerprintHalProperties::operation_detect_interaction_acquired().value_or("1");
+ auto acquiredInfos = parseIntSequence(acquired);
+ int N = acquiredInfos.size();
+ int64_t now = Util::getSystemNanoTime();
+
+ if (N == 0) {
+ LOG(ERROR) << "Fail to parse detect interaction acquired info: " + acquired;
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
return;
}
- if (shouldCancel(cancel)) {
- LOG(ERROR) << "Fail: cancel";
- cb->onError(Error::CANCELED, 0 /* vendorCode */);
- return;
- }
+ int i = 0;
+ do {
+ auto err = FingerprintHalProperties::operation_detect_interaction_error().value_or(0);
+ if (err != 0) {
+ LOG(ERROR) << "Fail: operation_detect_interaction_error";
+ auto ec = convertError(err);
+ cb->onError(ec.first, ec.second);
+ return;
+ }
+
+ if (shouldCancel(cancel)) {
+ LOG(ERROR) << "Fail: cancel";
+ cb->onError(Error::CANCELED, 0 /* vendorCode */);
+ return;
+ }
+
+ if (i < N) {
+ auto ac = convertAcquiredInfo(acquiredInfos[i]);
+ cb->onAcquired(ac.first, ac.second);
+ i++;
+ }
+ SLEEP_MS(duration / N);
+ } while (!Util::hasElapsed(now, duration));
auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
auto enrolls = FingerprintHalProperties::enrollments();
@@ -211,24 +275,37 @@
void FakeFingerprintEngine::getAuthenticatorIdImpl(ISessionCallback* cb) {
BEGIN_OP(0);
- int64_t authenticatorId = FingerprintHalProperties::authenticator_id().value_or(0);
- if (FingerprintHalProperties::enrollments().size() > 0 && authenticatorId == 0) {
- authenticatorId = 99999999; // default authenticatorId, TODO(b/230515082)
+ int64_t authenticatorId;
+ if (FingerprintHalProperties::enrollments().size() == 0) {
+ authenticatorId = 0;
+ } else {
+ authenticatorId = FingerprintHalProperties::authenticator_id().value_or(0);
+ if (authenticatorId == 0) authenticatorId = 1;
}
cb->onAuthenticatorIdRetrieved(authenticatorId);
}
void FakeFingerprintEngine::invalidateAuthenticatorIdImpl(ISessionCallback* cb) {
BEGIN_OP(0);
- auto id = FingerprintHalProperties::authenticator_id().value_or(0);
- auto newId = id + 1;
+ int64_t newId;
+ if (FingerprintHalProperties::enrollments().size() == 0) {
+ newId = 0;
+ } else {
+ auto id = FingerprintHalProperties::authenticator_id().value_or(0);
+ newId = id + 1;
+ }
FingerprintHalProperties::authenticator_id(newId);
cb->onAuthenticatorIdInvalidated(newId);
}
void FakeFingerprintEngine::resetLockoutImpl(ISessionCallback* cb,
- const keymaster::HardwareAuthToken& /*hat*/) {
+ const keymaster::HardwareAuthToken& hat) {
BEGIN_OP(0);
+ if (hat.mac.empty()) {
+ LOG(ERROR) << "Fail: hat in resetLockout()";
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
FingerprintHalProperties::lockout(false);
cb->onLockoutCleared();
}
@@ -286,4 +363,96 @@
return {0 /* displayId (not used) */, 0 /* sensorLocationX */, 0 /* sensorLocationY */,
0 /* sensorRadius */, "" /* display */};
}
+
+std::vector<int32_t> FakeFingerprintEngine::parseIntSequence(const std::string& str,
+ const std::string& sep) {
+ std::vector<std::string> seqs = Util::split(str, sep);
+ std::vector<int32_t> res;
+
+ for (const auto& seq : seqs) {
+ int32_t val;
+ if (ParseInt(seq, &val)) {
+ res.push_back(val);
+ } else {
+ LOG(WARNING) << "Invalid int sequence:" + str;
+ res.clear();
+ break;
+ }
+ }
+
+ return res;
+}
+
+std::vector<std::vector<int32_t>> FakeFingerprintEngine::parseEnrollmentCapture(
+ const std::string& str) {
+ std::vector<int32_t> defaultAcquiredInfo = {(int32_t)AcquiredInfo::GOOD};
+ std::vector<std::vector<int32_t>> res;
+ int i = 0, N = str.length();
+ std::size_t found = 0;
+ bool aborted = true;
+
+ while (found != std::string::npos) {
+ std::string durationStr, acquiredStr;
+ found = str.find_first_of("-,", i);
+ if (found == std::string::npos) {
+ if (N - i < 1) break;
+ durationStr = str.substr(i, N - i);
+ } else {
+ durationStr = str.substr(i, found - i);
+ if (str[found] == '-') {
+ found = str.find_first_of('[', found + 1);
+ if (found == std::string::npos) break;
+ i = found + 1;
+ found = str.find_first_of(']', found + 1);
+ if (found == std::string::npos) break;
+ acquiredStr = str.substr(i, found - i);
+ found = str.find_first_of(',', found + 1);
+ }
+ }
+ std::vector<int32_t> duration{0};
+ if (!ParseInt(durationStr, &duration[0])) break;
+ res.push_back(duration);
+ if (!acquiredStr.empty()) {
+ std::vector<int32_t> acquiredInfo = parseIntSequence(acquiredStr);
+ if (acquiredInfo.empty()) break;
+ res.push_back(acquiredInfo);
+ } else
+ res.push_back(defaultAcquiredInfo);
+
+ i = found + 1;
+ if (found == std::string::npos || found == N - 1) aborted = false;
+ }
+
+ if (aborted) {
+ LOG(ERROR) << "Failed to parse enrollment captures:" + str;
+ res.clear();
+ }
+
+ return res;
+}
+
+std::pair<AcquiredInfo, int32_t> FakeFingerprintEngine::convertAcquiredInfo(int32_t code) {
+ std::pair<AcquiredInfo, int32_t> res;
+ if (code > FINGERPRINT_ACQUIRED_VENDOR_BASE) {
+ res.first = AcquiredInfo::VENDOR;
+ res.second = code - FINGERPRINT_ACQUIRED_VENDOR_BASE;
+ } else {
+ res.first = (AcquiredInfo)code;
+ res.second = 0;
+ }
+ return res;
+}
+
+std::pair<Error, int32_t> FakeFingerprintEngine::convertError(int32_t code) {
+ std::pair<Error, int32_t> res;
+ if (code > FINGERPRINT_ERROR_VENDOR_BASE) {
+ res.first = Error::VENDOR;
+ res.second = code - FINGERPRINT_ERROR_VENDOR_BASE;
+ } else {
+ res.first = (Error)code;
+ res.second = 0;
+ }
+ return res;
+}
+
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
index 922781c..74e7caf 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
@@ -65,8 +65,18 @@
{SW_COMPONENT_ID, "" /* hardwareVersion */, "" /* firmwareVersion */,
"" /* serialNumber */, SW_VERSION}};
- common::CommonProps commonProps = {SENSOR_ID, SENSOR_STRENGTH, MAX_ENROLLMENTS_PER_USER,
- componentInfo};
+ auto sensorId = FingerprintHalProperties::sensor_id().value_or(SENSOR_ID);
+ auto sensorStrength =
+ FingerprintHalProperties::sensor_strength().value_or((int)SENSOR_STRENGTH);
+ auto maxEnrollments =
+ FingerprintHalProperties::max_enrollments().value_or(MAX_ENROLLMENTS_PER_USER);
+ auto navigationGuesture = FingerprintHalProperties::navigation_guesture().value_or(false);
+ auto detectInteraction = FingerprintHalProperties::detect_interaction().value_or(false);
+ auto displayTouch = FingerprintHalProperties::display_touch().value_or(true);
+ auto controlIllumination = FingerprintHalProperties::control_illumination().value_or(false);
+
+ common::CommonProps commonProps = {sensorId, (common::SensorStrength)sensorStrength,
+ maxEnrollments, componentInfo};
SensorLocation sensorLocation = mEngine->getSensorLocation();
@@ -75,8 +85,10 @@
*out = {{commonProps,
mSensorType,
{sensorLocation},
- SUPPORTS_NAVIGATION_GESTURES,
- false /* supportsDetectInteraction */}};
+ navigationGuesture,
+ detectInteraction,
+ displayTouch,
+ controlIllumination}};
return ndk::ScopedAStatus::ok();
}
diff --git a/biometrics/fingerprint/aidl/default/README.md b/biometrics/fingerprint/aidl/default/README.md
index bb6bb48..ad471f7 100644
--- a/biometrics/fingerprint/aidl/default/README.md
+++ b/biometrics/fingerprint/aidl/default/README.md
@@ -65,7 +65,7 @@
$ adb shell getprop persist.vendor.fingerprint.virtual.enrollments
```
-### Authenticate
+## Authenticate
To authenticate successfully set the enrolled id that should succeed. Unset it
or change the value to make authenticate operations fail:
@@ -74,7 +74,52 @@
$ adb shell setprop vendor.fingerprint.virtual.enrollment_hit 1
````
-### View HAL State
+## Acquired Info Insertion
+
+Fingerprint image acquisition states at HAL are reported to framework via onAcquired() callback. The valid acquired state info for AIDL HAL include
+
+{UNKNOWN(0), GOOD(1), PARTIAL(2), INSUFFICIENT(3), SENSOR_DIRTY(4), TOO_SLOW(5), TOO_FAST(6), VENDOR(7), START(8), TOO_DARK(9), TOO_BRIGHT(10), IMMOBILE(11), RETRYING_CAPTURE(12)}
+
+Refer to [AcquiredInfo.aidl](../android/hardware/biometrics/fingerprint/AcquiredInfo.aidl) for details
+
+
+The states can be specified in sequence for the HAL operations involving fingerprint image captures, namely authenticate, enrollment and detectInteraction
+
+```shell
+$ adb shell setprop vendor.fingerprint.virtual.operation_authenticate_acquired 6,9,1
+$ adb shell setprop vendor.fingerprint.virtual.operation_detect_interaction_acquired 6,1
+$ adb shell setprop vendor.fingerprint.virtual.next_enrollment 2:1000-[5,1],500:true
+
+#next_enrollment format example:
+.---------------------- enrollment id (2)
+| .------------------ the image capture 1 duration (1000ms)
+| | .-------------- acquired info first (TOO_SLOW)
+| | | .------------ acquired info second (GOOD)
+| | | | .-------- the image capture 2 duration (500ms)
+| | | | | .---- enrollment end status (success)
+| | | | | |
+| | | | | |
+| | | | | |
+2:1000-[5,1],500:true
+```
+For vendor specific acquired info, acquiredInfo = 1000 + vendorAcquiredInfo
+
+## Error Insertion
+The valid error codes for AIDL HAL include
+
+{UNKNOWN(0), HW_UNAVAILABLE(1), UNABLE_TO_PROCESS(2), TIMEOUT(3), NO_SPACE(4), CANCELED(5), UNABLE_TO_REMOVE(6), VENDOR(7), BAD_CALIBRATION(8)}
+
+Refer to [Error.aidl](../android/hardware/biometrics/fingerprint/Error.aidl) for details
+
+
+There are many HAL operations which can result in errors, refer to [here](fingerprint.sysprop) file for details.
+
+```shell
+$ adb shell setprop vendor.fingerprint.virtual.operation_authenticate_error 8
+```
+For vendor specific error, errorCode = 1000 + vendorErrorCode
+
+## View HAL State
To view all the properties of the HAL (see `fingerprint.sysprop` file for the API):
diff --git a/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt b/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt
index 9dfb74d..fa21663 100644
--- a/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt
+++ b/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt
@@ -5,7 +5,7 @@
api_name: "authenticator_id"
type: Long
access: ReadWrite
- prop_name: "vendor.fingerprint.virtual.authenticator_id"
+ prop_name: "persist.vendor.fingerprint.virtual.authenticator_id"
}
prop {
api_name: "challenge"
@@ -14,6 +14,21 @@
prop_name: "vendor.fingerprint.virtual.challenge"
}
prop {
+ api_name: "control_illumination"
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.udfps.control_illumination"
+ }
+ prop {
+ api_name: "detect_interaction"
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.detect_interaction"
+ }
+ prop {
+ api_name: "display_touch"
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.udfps.display_touch"
+ }
+ prop {
api_name: "enrollment_hit"
type: Integer
access: ReadWrite
@@ -28,7 +43,18 @@
prop {
api_name: "lockout"
access: ReadWrite
- prop_name: "vendor.fingerprint.virtual.lockout"
+ prop_name: "persist.vendor.fingerprint.virtual.lockout"
+ }
+ prop {
+ api_name: "max_enrollments"
+ type: Integer
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.max_enrollments"
+ }
+ prop {
+ api_name: "navigation_guesture"
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.navigation_guesture"
}
prop {
api_name: "next_enrollment"
@@ -37,12 +63,24 @@
prop_name: "vendor.fingerprint.virtual.next_enrollment"
}
prop {
+ api_name: "operation_authenticate_acquired"
+ type: String
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_acquired"
+ }
+ prop {
api_name: "operation_authenticate_duration"
type: Integer
access: ReadWrite
prop_name: "vendor.fingerprint.virtual.operation_authenticate_duration"
}
prop {
+ api_name: "operation_authenticate_error"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_error"
+ }
+ prop {
api_name: "operation_authenticate_fails"
access: ReadWrite
prop_name: "vendor.fingerprint.virtual.operation_authenticate_fails"
@@ -54,9 +92,22 @@
prop_name: "vendor.fingerprint.virtual.operation_authenticate_latency"
}
prop {
- api_name: "operation_detect_interaction_fails"
+ api_name: "operation_detect_interaction_acquired"
+ type: String
access: ReadWrite
- prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_fails"
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_acquired"
+ }
+ prop {
+ api_name: "operation_detect_interaction_duration"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_duration"
+ }
+ prop {
+ api_name: "operation_detect_interaction_error"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_error"
}
prop {
api_name: "operation_detect_interaction_latency"
@@ -65,9 +116,10 @@
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_latency"
}
prop {
- api_name: "operation_enroll_fails"
+ api_name: "operation_enroll_error"
+ type: Integer
access: ReadWrite
- prop_name: "vendor.fingerprint.virtual.operation_enroll_fails"
+ prop_name: "vendor.fingerprint.virtual.operation_enroll_error"
}
prop {
api_name: "operation_enroll_latency"
@@ -76,12 +128,24 @@
prop_name: "vendor.fingerprint.virtual.operation_enroll_latency"
}
prop {
+ api_name: "sensor_id"
+ type: Integer
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.sensor_id"
+ }
+ prop {
api_name: "sensor_location"
type: String
access: ReadWrite
prop_name: "persist.vendor.fingerprint.virtual.sensor_location"
}
prop {
+ api_name: "sensor_strength"
+ type: Integer
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.sensor_strength"
+ }
+ prop {
api_name: "type"
type: String
access: ReadWrite
diff --git a/biometrics/fingerprint/aidl/default/fingerprint.sysprop b/biometrics/fingerprint/aidl/default/fingerprint.sysprop
index 85e93b0..9b8fada 100644
--- a/biometrics/fingerprint/aidl/default/fingerprint.sysprop
+++ b/biometrics/fingerprint/aidl/default/fingerprint.sysprop
@@ -32,8 +32,12 @@
api_name: "enrollment_hit"
}
-# the next enrollment in the format: "<id>:<delay>,<delay>,...:<result>"
-# for example: "2:0:true"
+# the next enrollment in the format of:
+# "<id>:<delay>,<delay>,...:<result>"
+# <delay> = <duration-[acquiredInfos]>
+# [acquiredInfos] = [acquiredInfo1, acquiredInfo2, ...]
+# (refer to README.md file for acquiredInfo values)
+# e.g. "2:100,20:true", "2:100-[5,1],20:true"
# this property is reset after enroll completes
prop {
prop_name: "vendor.fingerprint.virtual.next_enrollment"
@@ -45,7 +49,7 @@
# value for getAuthenticatorId or 0
prop {
- prop_name: "vendor.fingerprint.virtual.authenticator_id"
+ prop_name: "persist.vendor.fingerprint.virtual.authenticator_id"
type: Long
scope: Public
access: ReadWrite
@@ -63,7 +67,7 @@
# if locked out
prop {
- prop_name: "vendor.fingerprint.virtual.lockout"
+ prop_name: "persist.vendor.fingerprint.virtual.lockout"
type: Boolean
scope: Public
access: ReadWrite
@@ -79,22 +83,26 @@
api_name: "operation_authenticate_fails"
}
-# force all detectInteraction operations to fail
+# force all detectInteraction operations to error out
+# error consists of errorCode and vendorErrorCode
+# valid errorCodes are listed in README.md file
+# vendorErrorCode = (error>1000) ? error-1000 : 0
+# e.g. error(1002) --> errorCode(7) and vendorErrorCode(2)
prop {
- prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_fails"
- type: Boolean
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_error"
+ type: Integer
scope: Public
access: ReadWrite
- api_name: "operation_detect_interaction_fails"
+ api_name: "operation_detect_interaction_error"
}
-# force all enroll operations to fail
+# force all enroll operations to result in error
prop {
- prop_name: "vendor.fingerprint.virtual.operation_enroll_fails"
- type: Boolean
+ prop_name: "vendor.fingerprint.virtual.operation_enroll_error"
+ type: Integer
scope: Public
access: ReadWrite
- api_name: "operation_enroll_fails"
+ api_name: "operation_enroll_error"
}
# add a latency to authentication operations
@@ -134,6 +142,15 @@
api_name: "operation_authenticate_duration"
}
+# insert error for authenticate operations
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_error"
+ type: Integer
+ scope: Public
+ access: ReadWrite
+ api_name: "operation_authenticate_error"
+}
+
# sensor location
# <x>:<y>:<radius> in pixel
prop {
@@ -143,3 +160,99 @@
access: ReadWrite
api_name: "sensor_location"
}
+
+# acquired info during authentication in format of sequence
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_acquired"
+ type: String
+ scope: Public
+ access: ReadWrite
+ api_name: "operation_authenticate_acquired"
+}
+
+# millisecond duration for detect interaction operations
+# (waits for changes to enrollment_hit)
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_duration"
+ type: Integer
+ scope: Public
+ access: ReadWrite
+ api_name: "operation_detect_interaction_duration"
+}
+
+# acquired info during detect interaction operation in format of sequence
+# e.g. 5,6,1 (TOO_SLOW, TOO_FAST, GOOD)
+# onAcquired() callback will be invoked in sequence
+# vendorAcquiredCode = (acquired>1000) ? acquired-1000 : 0
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_acquired"
+ type: String
+ scope: Public
+ access: ReadWrite
+ api_name: "operation_detect_interaction_acquired"
+}
+
+# sensor id (default: 5)
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.sensor_id"
+ type: Integer
+ scope: Public
+ access: ReadWrite
+ api_name: "sensor_id"
+}
+
+# sensor strength (default: 2)
+# [0=CONVENECE, 1=WEAK, 2=STRONG]
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.sensor_strength"
+ type: Integer
+ scope: Public
+ access: ReadWrite
+ api_name: "sensor_strength"
+}
+
+# max enrollments per user (default: 5)
+#
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.max_enrollments"
+ type: Integer
+ scope: Public
+ access: ReadWrite
+ api_name: "max_enrollments"
+}
+
+# whether support navigation guestures (default: false)
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.navigation_guesture"
+ type: Boolean
+ scope: Public
+ access: ReadWrite
+ api_name: "navigation_guesture"
+}
+
+# whether support detect interaction (default: false)
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.detect_interaction"
+ type: Boolean
+ scope: Public
+ access: ReadWrite
+ api_name: "detect_interaction"
+}
+
+# whether support display touch by hal (default: true)
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.udfps.display_touch"
+ type: Boolean
+ scope: Public
+ access: ReadWrite
+ api_name: "display_touch"
+}
+
+# whether support illumination control by hal (default: false)
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.udfps.control_illumination"
+ type: Boolean
+ scope: Public
+ access: ReadWrite
+ api_name: "control_illumination"
+}
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index d7df818..22b1744 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -59,7 +59,17 @@
virtual SensorLocation defaultSensorLocation();
+ std::vector<int32_t> parseIntSequence(const std::string& str, const std::string& sep = ",");
+
+ std::vector<std::vector<int32_t>> parseEnrollmentCapture(const std::string& str);
+
std::mt19937 mRandom;
+
+ private:
+ static constexpr int32_t FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
+ static constexpr int32_t FINGERPRINT_ERROR_VENDOR_BASE = 1000;
+ std::pair<AcquiredInfo, int32_t> convertAcquiredInfo(int32_t code);
+ std::pair<Error, int32_t> convertError(int32_t code);
};
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
index 8696d26..32d01f4 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
@@ -38,8 +38,9 @@
mLastChallengeRevoked = challenge;
return ndk::ScopedAStatus::ok();
};
- ::ndk::ScopedAStatus onError(fingerprint::Error error, int32_t) override {
+ ::ndk::ScopedAStatus onError(fingerprint::Error error, int32_t vendorCode) override {
mError = error;
+ mErrorVendorCode = vendorCode;
return ndk::ScopedAStatus::ok();
};
::ndk::ScopedAStatus onEnrollmentProgress(int32_t enrollmentId, int32_t remaining) override {
@@ -62,7 +63,10 @@
mInteractionDetectedCount++;
return ndk::ScopedAStatus::ok();
};
- ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override {
+ ndk::ScopedAStatus onAcquired(AcquiredInfo info, int32_t vendorCode) override {
+ mLastAcquiredInfo = (int32_t)info;
+ mLastAcquiredVendorCode = vendorCode;
+ mLastAcquiredCount++;
return ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus onEnrollmentsEnumerated(
@@ -94,6 +98,7 @@
ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
Error mError = Error::UNKNOWN;
+ int32_t mErrorVendorCode = 0;
int64_t mLastChallenge = -1;
int64_t mLastChallengeRevoked = -1;
int32_t mLastEnrolled = -1;
@@ -105,6 +110,9 @@
bool mAuthenticatorIdInvalidated = false;
bool mLockoutPermanent = false;
int mInteractionDetectedCount = 0;
+ int32_t mLastAcquiredInfo = -1;
+ int32_t mLastAcquiredVendorCode = -1;
+ int32_t mLastAcquiredCount = 0;
};
class FakeFingerprintEngineTest : public ::testing::Test {
@@ -116,6 +124,12 @@
mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
}
+ void TearDown() override {
+ FingerprintHalProperties::operation_authenticate_error(0);
+ FingerprintHalProperties::operation_detect_interaction_error(0);
+ FingerprintHalProperties::operation_authenticate_acquired("");
+ }
+
FakeFingerprintEngine mEngine;
std::shared_ptr<TestSessionCallback> mCallback;
std::promise<void> mCancel;
@@ -135,11 +149,13 @@
TEST_F(FakeFingerprintEngineTest, ResetLockout) {
FingerprintHalProperties::lockout(true);
- mEngine.resetLockoutImpl(mCallback.get(), {});
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mEngine.resetLockoutImpl(mCallback.get(), hat);
ASSERT_FALSE(FingerprintHalProperties::lockout().value_or(true));
}
TEST_F(FakeFingerprintEngineTest, AuthenticatorId) {
+ FingerprintHalProperties::enrollments({1});
FingerprintHalProperties::authenticator_id(50);
mEngine.getAuthenticatorIdImpl(mCallback.get());
ASSERT_EQ(50, mCallback->mLastAuthenticatorId);
@@ -162,6 +178,7 @@
ASSERT_EQ(1, FingerprintHalProperties::enrollments().size());
ASSERT_EQ(4, FingerprintHalProperties::enrollments()[0].value());
ASSERT_EQ(4, mCallback->mLastEnrolled);
+ ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
}
TEST_F(FakeFingerprintEngineTest, EnrollCancel) {
@@ -189,12 +206,28 @@
ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
}
+TEST_F(FakeFingerprintEngineTest, EnrollAcquired) {
+ FingerprintHalProperties::enrollments({});
+ FingerprintHalProperties::next_enrollment("4:0,5-[12,1013]:true");
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ int32_t prevCnt = mCallback->mLastAcquiredCount;
+ mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+ ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
+ ASSERT_EQ(1, FingerprintHalProperties::enrollments().size());
+ ASSERT_EQ(4, FingerprintHalProperties::enrollments()[0].value());
+ ASSERT_EQ(4, mCallback->mLastEnrolled);
+ ASSERT_EQ(prevCnt + 3, mCallback->mLastAcquiredCount);
+ ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
+ ASSERT_EQ(13, mCallback->mLastAcquiredVendorCode);
+}
+
TEST_F(FakeFingerprintEngineTest, Authenticate) {
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit(2);
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
ASSERT_FALSE(mCallback->mAuthenticateFailed);
ASSERT_EQ(2, mCallback->mLastAuthenticated);
+ ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
}
TEST_F(FakeFingerprintEngineTest, AuthenticateCancel) {
@@ -211,7 +244,6 @@
FingerprintHalProperties::enrollment_hit({});
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
ASSERT_TRUE(mCallback->mAuthenticateFailed);
- ASSERT_EQ(mCallback->mError, Error::UNABLE_TO_PROCESS);
}
TEST_F(FakeFingerprintEngineTest, AuthenticateNotEnrolled) {
@@ -219,7 +251,6 @@
FingerprintHalProperties::enrollment_hit(3);
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
ASSERT_TRUE(mCallback->mAuthenticateFailed);
- ASSERT_EQ(mCallback->mError, Error::UNABLE_TO_PROCESS);
}
TEST_F(FakeFingerprintEngineTest, AuthenticateLockout) {
@@ -231,11 +262,41 @@
ASSERT_NE(mCallback->mError, Error::UNKNOWN);
}
+TEST_F(FakeFingerprintEngineTest, AuthenticateError8) {
+ FingerprintHalProperties::operation_authenticate_error(8);
+ mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ ASSERT_EQ(mCallback->mError, (Error)8);
+ ASSERT_EQ(mCallback->mErrorVendorCode, 0);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateError9) {
+ FingerprintHalProperties::operation_authenticate_error(1009);
+ mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ ASSERT_EQ(mCallback->mError, (Error)7);
+ ASSERT_EQ(mCallback->mErrorVendorCode, 9);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateAcquired) {
+ FingerprintHalProperties::lockout(false);
+ FingerprintHalProperties::enrollments({1, 2});
+ FingerprintHalProperties::enrollment_hit(2);
+ FingerprintHalProperties::operation_authenticate_acquired("4,1009");
+ int32_t prevCount = mCallback->mLastAcquiredCount;
+ mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ ASSERT_FALSE(mCallback->mAuthenticateFailed);
+ ASSERT_EQ(2, mCallback->mLastAuthenticated);
+ ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
+ ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
+ ASSERT_EQ(9, mCallback->mLastAcquiredVendorCode);
+}
+
TEST_F(FakeFingerprintEngineTest, InteractionDetect) {
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit(2);
+ FingerprintHalProperties::operation_detect_interaction_acquired("");
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
+ ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
}
TEST_F(FakeFingerprintEngineTest, InteractionDetectCancel) {
@@ -261,6 +322,26 @@
ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
}
+TEST_F(FakeFingerprintEngineTest, InteractionDetectError) {
+ FingerprintHalProperties::operation_detect_interaction_error(8);
+ mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
+ ASSERT_EQ(mCallback->mError, (Error)8);
+ ASSERT_EQ(mCallback->mErrorVendorCode, 0);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetectAcquired) {
+ FingerprintHalProperties::enrollments({1, 2});
+ FingerprintHalProperties::enrollment_hit(2);
+ FingerprintHalProperties::operation_detect_interaction_acquired("4,1013");
+ int32_t prevCount = mCallback->mLastAcquiredCount;
+ mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
+ ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
+ ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
+ ASSERT_EQ(13, mCallback->mLastAcquiredVendorCode);
+}
+
TEST_F(FakeFingerprintEngineTest, EnumerateEnrolled) {
FingerprintHalProperties::enrollments({2, 4, 8});
mEngine.enumerateEnrollmentsImpl(mCallback.get());
@@ -290,6 +371,76 @@
}
}
+TEST_F(FakeFingerprintEngineTest, parseIntSequence) {
+ std::vector<int32_t> seqV;
+ seqV = mEngine.parseIntSequence("");
+ ASSERT_EQ(0, seqV.size());
+ seqV = mEngine.parseIntSequence("2");
+ ASSERT_EQ(1, seqV.size());
+ ASSERT_EQ(2, seqV[0]);
+ seqV = mEngine.parseIntSequence("2,3,4");
+ std::vector<int32_t> expV{2, 3, 4};
+ ASSERT_EQ(expV, seqV);
+ seqV = mEngine.parseIntSequence("2,3,a");
+ ASSERT_EQ(0, seqV.size());
+ seqV = mEngine.parseIntSequence("2, 3, 4");
+ ASSERT_EQ(expV, seqV);
+ seqV = mEngine.parseIntSequence("123,456");
+ ASSERT_EQ(2, seqV.size());
+ std::vector<int32_t> expV1{123, 456};
+ ASSERT_EQ(expV1, seqV);
+ seqV = mEngine.parseIntSequence("12f3,456");
+ ASSERT_EQ(0, seqV.size());
+}
+
+TEST_F(FakeFingerprintEngineTest, parseEnrollmentCaptureOk) {
+ std::vector<std::vector<int32_t>> ecV;
+ ecV = mEngine.parseEnrollmentCapture("100,200,300");
+ ASSERT_EQ(6, ecV.size());
+ std::vector<std::vector<int32_t>> expE{{100}, {200}, {300}};
+ std::vector<int32_t> defC{1};
+ for (int i = 0; i < ecV.size(); i += 2) {
+ ASSERT_EQ(expE[i / 2], ecV[i]);
+ ASSERT_EQ(defC, ecV[i + 1]);
+ }
+ ecV = mEngine.parseEnrollmentCapture("100");
+ ASSERT_EQ(2, ecV.size());
+ ASSERT_EQ(expE[0], ecV[0]);
+ ASSERT_EQ(defC, ecV[1]);
+
+ ecV = mEngine.parseEnrollmentCapture("100-[5,6,7]");
+ std::vector<int32_t> expC{5, 6, 7};
+ ASSERT_EQ(2, ecV.size());
+ for (int i = 0; i < ecV.size(); i += 2) {
+ ASSERT_EQ(expE[i / 2], ecV[i]);
+ ASSERT_EQ(expC, ecV[i + 1]);
+ }
+ ecV = mEngine.parseEnrollmentCapture("100-[5,6,7], 200, 300-[9,10]");
+ std::vector<std::vector<int32_t>> expC1{{5, 6, 7}, {1}, {9, 10}};
+ ASSERT_EQ(6, ecV.size());
+ for (int i = 0; i < ecV.size(); i += 2) {
+ ASSERT_EQ(expE[i / 2], ecV[i]);
+ ASSERT_EQ(expC1[i / 2], ecV[i + 1]);
+ }
+ ecV = mEngine.parseEnrollmentCapture("100-[5,6,7], 200-[2,1], 300-[9]");
+ std::vector<std::vector<int32_t>> expC2{{5, 6, 7}, {2, 1}, {9}};
+ ASSERT_EQ(ecV.size(), 6);
+ for (int i = 0; i < ecV.size(); i += 2) {
+ ASSERT_EQ(expE[i / 2], ecV[i]);
+ ASSERT_EQ(expC2[i / 2], ecV[i + 1]);
+ }
+}
+
+TEST_F(FakeFingerprintEngineTest, parseEnrollmentCaptureFail) {
+ std::vector<std::string> badStr{"10c", "100-5", "100-[5,6,7", "100-5,6,7]",
+ "100,2x0,300", "200-[f]", "a,b"};
+ std::vector<std::vector<int32_t>> ecV;
+ for (const auto s : badStr) {
+ ecV = mEngine.parseEnrollmentCapture(s);
+ ASSERT_EQ(ecV.size(), 0);
+ }
+}
+
} // namespace aidl::android::hardware::biometrics::fingerprint
int main(int argc, char** argv) {
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
index 485f401..7c0021f 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
@@ -47,14 +47,10 @@
sc.sensorRadius == FakeFingerprintEngineUdfps::defaultSensorRadius && sc.display == "");
}
-TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocation) {
- FingerprintHalProperties::sensor_location("");
- SensorLocation sc = mEngine.getSensorLocation();
- ASSERT_TRUE(isDefaultLocation(sc));
-
+TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocationOk) {
auto loc = "100:200:30";
FingerprintHalProperties::sensor_location(loc);
- sc = mEngine.getSensorLocation();
+ SensorLocation sc = mEngine.getSensorLocation();
ASSERT_TRUE(sc.sensorLocationX == 100);
ASSERT_TRUE(sc.sensorLocationY == 200);
ASSERT_TRUE(sc.sensorRadius == 30);
@@ -66,8 +62,14 @@
ASSERT_TRUE(sc.sensorLocationY == 200);
ASSERT_TRUE(sc.sensorRadius == 30);
ASSERT_TRUE(sc.display == "screen1");
+}
- loc = "100";
+TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocationBad) {
+ FingerprintHalProperties::sensor_location("");
+ SensorLocation sc = mEngine.getSensorLocation();
+ ASSERT_TRUE(isDefaultLocation(sc));
+
+ auto loc = "100";
FingerprintHalProperties::sensor_location(loc);
sc = mEngine.getSensorLocation();
ASSERT_TRUE(isDefaultLocation(sc));
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl
index 659fa0b..5523fd8 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl
@@ -34,6 +34,7 @@
package android.hardware.radio.ims.media;
@VintfStability
parcelable DtmfParams {
- byte payloadTypeNumber;
+ byte rxPayloadTypeNumber;
+ byte txPayloadTypeNumber;
byte samplingRateKHz;
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl
index 330374e..b04e559 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl
@@ -36,5 +36,5 @@
enum ImsDeregistrationReason {
REASON_SIM_REMOVED = 1,
REASON_SIM_REFRESH = 2,
- REASON_NETWORK_MODE_CHANGED = 3,
+ REASON_ALLOWED_NETWORK_TYPES_CHANGED = 3,
}
diff --git a/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl b/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl
index ea286c4..82773f2 100644
--- a/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl
+++ b/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl
@@ -32,12 +32,12 @@
* on cellular networks. IMS service shall call stopImsTraffic when receiving
* this indication.
*
- * @param token The token of startImsTraffic() associated with this indication
* @param type Type of radio indication
+ * @param token The token of startImsTraffic() associated with this indication
* @param info Connection failure information
*/
- void onConnectionSetupFailure(in RadioIndicationType type, in String token,
- in ConnectionFailureInfo info);
+ void onConnectionSetupFailure(
+ in RadioIndicationType type, in String token, in ConnectionFailureInfo info);
/**
* Access Network Bitrate Recommendation (ANBR), see 3GPP TS 26.114.
@@ -49,19 +49,18 @@
* @param bitsPerSecond The recommended bit rate for the UE
* for a specific logical channel and a specific direction by NW
*/
- void notifyAnbr(in RadioIndicationType type, in ImsStreamType mediaType,
+ void notifyAnbr(in RadioIndicationType type, in ImsStreamType mediaType,
in ImsStreamDirection direction, int bitsPerSecond);
/**
- * Fired by radio when a graceful IMS deregistration needs to be performed by telephony
- * prior to radio performing network detach. Example scenarios are SIM refresh or user
- * mode preference change which would cause network detach. The radio waits for the
- * IMS deregistration, which will be notified by telephony via
+ * Requests IMS stack to perform graceful IMS deregistration before radio performing
+ * network detach in the events of SIM remove, refresh or and so on. The radio waits for
+ * the IMS deregistration, which will be notified by telephony via
* {@link IRadioIms#updateImsRegistrationInfo()}, or a certain timeout interval to start
* the network detach procedure.
*
* @param type Type of radio indication
* @param reason the reason why the deregistration is triggered
*/
- void triggerImsDeregistration(in RadioIndicationType type, in ImsDeregistrationReason reason);
+ void triggerImsDeregistration(in RadioIndicationType type, in ImsDeregistrationReason reason);
}
diff --git a/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl b/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl
index 83c0321..eac8db4 100644
--- a/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl
+++ b/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl
@@ -34,5 +34,5 @@
* Radio shall send this reason to IMS stack to perform graceful de-registration
* due to allowed network types bitmask changed that results in NAS detach.
*/
- REASON_NETWORK_MODE_CHANGED = 3,
+ REASON_ALLOWED_NETWORK_TYPES_CHANGED = 3,
}
diff --git a/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl b/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
index a17b8a4..2d12ed6 100644
--- a/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
+++ b/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
@@ -21,17 +21,17 @@
@Backing(type="int")
enum SuggestedAction {
/** Default value */
- NONE = 0,
+ NONE,
/**
* Indicates that the IMS registration is failed with fatal error such as 403 or 404
* on all P-CSCF addresses. The radio shall block the current PLMN or disable
* the RAT as per the carrier requirements.
*/
- TRIGGER_PLMN_BLOCK = 1 << 0,
+ TRIGGER_PLMN_BLOCK,
/**
* Indicates that the IMS registration on current PLMN failed multiple times.
* The radio shall block the current PLMN or disable the RAT during EPS or 5GS mobility
* management timer value as per the carrier requirements.
*/
- TRIGGER_PLMN_BLOCK_WITH_TIMEOUT = 1 << 1,
+ TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
}
diff --git a/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl b/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl
index ad920f2..a7dcb0d 100644
--- a/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl
@@ -19,11 +19,21 @@
@VintfStability
parcelable DtmfParams {
/**
- * Dynamic payload type number to be used for DTMF RTP packets. The values is
- * in the range from 96 to 127 chosen during the session establishment. The PT
- * value of the RTP header of all DTMF packets shall be set with this value.
+ * Dynamic payload type number to be used for DTMF RTP packets received.
+ * The values is in the range from 96 to 127 chosen during the session
+ * establishment. The PT value of the RTP header of all DTMF packets shall be
+ * set with this value.
*/
- byte payloadTypeNumber;
+ byte rxPayloadTypeNumber;
+
+ /**
+ * Dynamic payload type number to be used for DTMF RTP packets sent.
+ * The values is in the range from 96 to 127 chosen during the session
+ * establishment. The PT value of the RTP header of all DTMF packets shall be set
+ * with this value.
+ */
+ byte txPayloadTypeNumber;
+
/** Sampling rate in kHz */
byte samplingRateKHz;
}
diff --git a/radio/aidl/vts/radio_ims_indication.cpp b/radio/aidl/vts/radio_ims_indication.cpp
index 8e98d85..f382de0 100644
--- a/radio/aidl/vts/radio_ims_indication.cpp
+++ b/radio/aidl/vts/radio_ims_indication.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/radio/aidl/vts/radio_ims_response.cpp b/radio/aidl/vts/radio_ims_response.cpp
index 62912ea..9d8db4a 100644
--- a/radio/aidl/vts/radio_ims_response.cpp
+++ b/radio/aidl/vts/radio_ims_response.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/radio/aidl/vts/radio_ims_test.cpp b/radio/aidl/vts/radio_ims_test.cpp
index 27cc8d9..e5cbeb4 100644
--- a/radio/aidl/vts/radio_ims_test.cpp
+++ b/radio/aidl/vts/radio_ims_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
diff --git a/radio/aidl/vts/radio_ims_utils.h b/radio/aidl/vts/radio_ims_utils.h
index 98fd3cb..c981ebc 100644
--- a/radio/aidl/vts/radio_ims_utils.h
+++ b/radio/aidl/vts/radio_ims_utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -43,7 +43,8 @@
virtual ndk::ScopedAStatus updateImsRegistrationInfoResponse(
const RadioResponseInfo& info) override;
- virtual ndk::ScopedAStatus startImsTrafficResponse(const RadioResponseInfo& info,
+ virtual ndk::ScopedAStatus startImsTrafficResponse(
+ const RadioResponseInfo& info,
const std::optional<ConnectionFailureInfo>& response) override;
virtual ndk::ScopedAStatus stopImsTrafficResponse(const RadioResponseInfo& info) override;
diff --git a/security/keymint/RKP_CHANGELOG.md b/security/keymint/RKP_CHANGELOG.md
index dfcc938..243fc26 100644
--- a/security/keymint/RKP_CHANGELOG.md
+++ b/security/keymint/RKP_CHANGELOG.md
@@ -21,13 +21,13 @@
## IRemotelyProvisionedComponent 2 -> 3
* ProtectedData has been removed.
* DeviceInfo
- * `cert_type` has been added, with values corresponding to `widevine` or `keymint`
* `version` has moved to a top-level field within the CSR generated by the HAL
* IRemotelyProvisionedComponent
* The need for an EEK has been removed. There is no longer an encrypted portion of the CSR.
* Test mode has been removed.
* The schema for the CSR itself has been significantly simplified, please see
- IRemotelyProvisionedComponent.aidl for more details.
- * Notably, the chain of signing, MACing, and encryption operations has been replaced with a single
+ IRemotelyProvisionedComponent.aidl for more details. Notably,
+ * the chain of signing, MACing, and encryption operations has been replaced with a single
COSE_Sign1 object.
+ * CertificateType has been added to identify the type of certificate being requested.
diff --git a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
index 6854851..f0af619 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
@@ -49,16 +49,7 @@
* "security_level" : "tee" / "strongbox",
* "fused": 1 / 0, ; 1 if secure boot is enforced for the processor that the IRPC
* ; implementation is contained in. 0 otherwise.
- * "cert_type": CertificateType;
* }
- *
- * ; A tstr identifying the type of certificate. The set of supported certificate types may
- * ; be extended without requiring a version bump of the HAL. Custom certificate types may
- * ; be used, but the provisioning server may reject the request for an unknown certificate
- * ; type. The currently defined certificate types are:
- * ; - "widevine"
- * ; - "keymint"
- * CertificateType = tstr
*/
byte[] deviceInfo;
}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 77df99f..86c1717 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -315,38 +315,50 @@
*
* @return the following CBOR Certificate Signing Request (Csr) serialized into a byte array:
*
- * Csr = [
- * version: 3, ; The CDDL Schema version.
- * UdsCerts,
- * DiceCertChain,
- * SignedData
- * ]
+ * Csr = AuthenticatedMessage<CsrPayload>
*
- * ; COSE_Sign1 (untagged)
- * SignedData = [
- * protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
- * unprotected: {},
- * payload: bstr .cbor SignedDataPayload,
- * signature: bstr ; PureEd25519(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct) /
- * ; ECDSA(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct)
- * ]
- *
- * ; Sig_structure for SignedData
- * SignedDataSigStruct = [
- * context: "Signature1",
- * protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
- * external_aad: bstr .size 0,
- * payload: bstr .cbor SignedDataPayload
- * ]
- *
- * SignedDataPayload = [ ; CBOR Array defining the payload for SignedData
+ * CsrPayload = [ ; CBOR Array defining the payload for Csr
+ * version: 1, ; The CsrPayload CDDL Schema version.
+ * CertificateType, ; The type of certificate being requested.
* DeviceInfo, ; Defined in DeviceInfo.aidl
* challenge: bstr .size (32..64), ; Provided by the method parameters
* KeysToSign, ; Provided by the method parameters
* ]
*
+ * ; A tstr identifying the type of certificate. The set of supported certificate types may
+ * ; be extended without requiring a version bump of the HAL. Custom certificate types may
+ * ; be used, but the provisioning server may reject the request for an unknown certificate
+ * ; type. The currently defined certificate types are:
+ * ; - "widevine"
+ * ; - "keymint"
+ * CertificateType = tstr
+ *
* KeysToSign = [ * PublicKey ] ; Please see MacedPublicKey.aidl for the PublicKey definition.
*
+ * AuthenticatedMessage<T> = [
+ * version: 3, ; The AuthenticatedMessage CDDL Schema version.
+ * UdsCerts,
+ * DiceCertChain,
+ * SignedData<T>,
+ * ]
+ *
+ * ; COSE_Sign1 (untagged)
+ * SignedData<T> = [
+ * protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
+ * unprotected: {},
+ * payload: bstr .cbor T / nil,
+ * signature: bstr ; PureEd25519(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct<T>) /
+ * ; ECDSA(CDI_Leaf_Priv, bstr .cbor SignedDataSigStruct<T>)
+ * ]
+ *
+ * ; Sig_structure for SignedData
+ * SignedDataSigStruct<T> = [
+ * context: "Signature1",
+ * protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
+ * external_aad: bstr .size 0,
+ * payload: bstr .cbor T
+ * ]
+ *
* ; UdsCerts allows the platform to provide additional certifications for the UDS_Pub. For
* ; example, this could be provided by the hardware vendor, who certifies all of their chips.
* ; The SignerName is a free-form string describing who generated the signature. The root