Merge "audio: Fix remote submix configuration and 'prepareToClose'" into main am: 8a4394f8b8
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2825161
Change-Id: I370c8367226ef33724605f22354f8b3008becd41
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/audio/common/all-versions/default/service/android.hardware.audio.service.rc b/audio/common/all-versions/default/service/android.hardware.audio.service.rc
index 0de4eea..a1df67a 100644
--- a/audio/common/all-versions/default/service/android.hardware.audio.service.rc
+++ b/audio/common/all-versions/default/service/android.hardware.audio.service.rc
@@ -2,7 +2,7 @@
class hal
user audioserver
# media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
- group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock context_hub
+ group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock context_hub system
capabilities BLOCK_SUSPEND SYS_NICE
# setting RLIMIT_RTPRIO allows binder RT priority inheritance
rlimit rtprio 10 10
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h
index d2b701d..2378676 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h
@@ -57,7 +57,7 @@
float dispersion; // Defines minimum and maximum value based on initial value.
float increment; // Value that we will be added to currentValue with each timer tick.
int64_t interval;
- long lastEventTimestamp;
+ int64_t lastEventTimestamp;
};
GeneratorCfg mGenCfg;
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp
index 9133144..fe08dcf 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp
@@ -86,7 +86,7 @@
if (mGenCfg.lastEventTimestamp == 0) {
mGenCfg.lastEventTimestamp = elapsedRealtimeNano();
} else {
- long nextEventTime = mGenCfg.lastEventTimestamp + mGenCfg.interval;
+ int64_t nextEventTime = mGenCfg.lastEventTimestamp + mGenCfg.interval;
// Prevent overflow.
assert(nextEventTime > mGenCfg.lastEventTimestamp);
mGenCfg.lastEventTimestamp = nextEventTime;
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
index c3ebd3b..af1bb1d 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -99,12 +99,17 @@
const std::shared_ptr<VehiclePropValuePool> mValuePool;
const std::shared_ptr<VehiclePropertyStore> mServerSidePropStore;
+ const std::string mDefaultConfigDir;
+ const std::string mOverrideConfigDir;
+
ValueResultType getValue(
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
VhalResult<void> setValue(
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
+ bool UseOverrideConfigDir();
+
private:
// Expose private methods to unit test.
friend class FakeVehicleHardwareTestHelper;
@@ -156,8 +161,6 @@
aidl::android::hardware::automotive::vehicle::SetValueRequest>
mPendingSetValueRequests;
- const std::string mDefaultConfigDir;
- const std::string mOverrideConfigDir;
const bool mForceOverride;
bool mAddExtraTestVendorConfigs;
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index 3f5e4c4..250a226 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -39,7 +39,6 @@
#include <dirent.h>
#include <inttypes.h>
#include <sys/types.h>
-#include <fstream>
#include <regex>
#include <unordered_set>
#include <vector>
@@ -205,9 +204,10 @@
// Create a separate instance for each individual zone
VehiclePropValue prop = {
+ .timestamp = elapsedRealtimeNano(),
.areaId = curArea,
.prop = propId,
- .timestamp = elapsedRealtimeNano(),
+ .value = {},
};
if (config.initialAreaValues.empty()) {
@@ -240,6 +240,8 @@
std::string overrideConfigDir, bool forceOverride)
: mValuePool(std::make_unique<VehiclePropValuePool>()),
mServerSidePropStore(new VehiclePropertyStore(mValuePool)),
+ mDefaultConfigDir(defaultConfigDir),
+ mOverrideConfigDir(overrideConfigDir),
mFakeObd2Frame(new obd2frame::FakeObd2Frame(mServerSidePropStore)),
mFakeUserHal(new FakeUserHal(mValuePool)),
mRecurrentTimer(new RecurrentTimer()),
@@ -247,8 +249,6 @@
[this](const VehiclePropValue& value) { eventFromVehicleBus(value); })),
mPendingGetValueRequests(this),
mPendingSetValueRequests(this),
- mDefaultConfigDir(defaultConfigDir),
- mOverrideConfigDir(overrideConfigDir),
mForceOverride(forceOverride) {
init();
}
@@ -259,11 +259,15 @@
mGeneratorHub.reset();
}
+bool FakeVehicleHardware::UseOverrideConfigDir() {
+ return mForceOverride ||
+ android::base::GetBoolProperty(OVERRIDE_PROPERTY, /*default_value=*/false);
+}
+
std::unordered_map<int32_t, ConfigDeclaration> FakeVehicleHardware::loadConfigDeclarations() {
std::unordered_map<int32_t, ConfigDeclaration> configsByPropId;
loadPropConfigsFromDir(mDefaultConfigDir, &configsByPropId);
- if (mForceOverride ||
- android::base::GetBoolProperty(OVERRIDE_PROPERTY, /*default_value=*/false)) {
+ if (UseOverrideConfigDir()) {
loadPropConfigsFromDir(mOverrideConfigDir, &configsByPropId);
}
return configsByPropId;
@@ -938,7 +942,7 @@
<< StringPrintf("failed to get special value: %d, error: %s", value.prop,
getErrorMsg(result).c_str());
} else {
- return std::move(result);
+ return result;
}
}
@@ -953,7 +957,7 @@
}
}
- return std::move(readResult);
+ return readResult;
}
DumpResult FakeVehicleHardware::dump(const std::vector<std::string>& options) {
@@ -990,9 +994,11 @@
} else if (EqualsIgnoreCase(option, "--genTestVendorConfigs")) {
mAddExtraTestVendorConfigs = true;
result.refreshPropertyConfigs = true;
+ result.buffer = "successfully generated vendor configs";
} else if (EqualsIgnoreCase(option, "--restoreVendorConfigs")) {
mAddExtraTestVendorConfigs = false;
result.refreshPropertyConfigs = true;
+ result.buffer = "successfully restored vendor configs";
} else {
result.buffer = StringPrintf("Invalid option: %s\n", option.c_str());
}
@@ -1328,9 +1334,9 @@
VehiclePropValue FakeVehicleHardware::createHwInputKeyProp(VehicleHwKeyInputAction action,
int32_t keyCode, int32_t targetDisplay) {
VehiclePropValue value = {
- .prop = toInt(VehicleProperty::HW_KEY_INPUT),
- .areaId = 0,
.timestamp = elapsedRealtimeNano(),
+ .areaId = 0,
+ .prop = toInt(VehicleProperty::HW_KEY_INPUT),
.status = VehiclePropertyStatus::AVAILABLE,
.value.int32Values = {toInt(action), keyCode, targetDisplay},
};
@@ -1340,9 +1346,9 @@
VehiclePropValue FakeVehicleHardware::createHwKeyInputV2Prop(int32_t area, int32_t targetDisplay,
int32_t keyCode, int32_t action,
int32_t repeatCount) {
- VehiclePropValue value = {.prop = toInt(VehicleProperty::HW_KEY_INPUT_V2),
+ VehiclePropValue value = {.timestamp = elapsedRealtimeNano(),
.areaId = area,
- .timestamp = elapsedRealtimeNano(),
+ .prop = toInt(VehicleProperty::HW_KEY_INPUT_V2),
.status = VehiclePropertyStatus::AVAILABLE,
.value.int32Values = {targetDisplay, keyCode, action, repeatCount},
.value.int64Values = {elapsedRealtimeNano()}};
@@ -1380,9 +1386,9 @@
floatValues.push_back(size[i]);
}
- VehiclePropValue value = {.prop = toInt(VehicleProperty::HW_MOTION_INPUT),
+ VehiclePropValue value = {.timestamp = elapsedRealtimeNano(),
.areaId = area,
- .timestamp = elapsedRealtimeNano(),
+ .prop = toInt(VehicleProperty::HW_MOTION_INPUT),
.status = VehiclePropertyStatus::AVAILABLE,
.value.int32Values = intValues,
.value.floatValues = floatValues,
@@ -1451,8 +1457,9 @@
std::string FakeVehicleHardware::dumpOnePropertyById(int32_t propId, int32_t areaId) {
VehiclePropValue value = {
- .prop = propId,
.areaId = areaId,
+ .prop = propId,
+ .value = {},
};
bool isSpecialValue = false;
auto result = maybeGetSpecialValue(value, &isSpecialValue);
@@ -1523,12 +1530,12 @@
while (*index < options.size()) {
std::string option = options[*index];
if (SET_PROP_OPTIONS.find(option) != SET_PROP_OPTIONS.end()) {
- return std::move(values);
+ return values;
}
values.push_back(option);
(*index)++;
}
- return std::move(values);
+ return values;
}
Result<VehiclePropValue> FakeVehicleHardware::parsePropOptions(
@@ -1808,6 +1815,7 @@
void FakeVehicleHardware::registerOnPropertySetErrorEvent(
std::unique_ptr<const PropertySetErrorCallback> callback) {
+ // In FakeVehicleHardware, we will never use mOnPropertySetErrorCallback.
if (mOnPropertySetErrorCallback != nullptr) {
ALOGE("registerOnPropertySetErrorEvent must only be called once");
return;
@@ -1836,8 +1844,9 @@
// Refresh the property value. In real implementation, this should poll the latest value
// from vehicle bus. Here, we are just refreshing the existing value with a new timestamp.
auto result = getValue(VehiclePropValue{
- .prop = propId,
.areaId = areaId,
+ .prop = propId,
+ .value = {},
});
if (!result.ok()) {
// Failed to read current value, skip refreshing.
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
index e740da7..ddd620e 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
@@ -82,6 +82,10 @@
bool waitForConnected(std::chrono::milliseconds waitTime);
+ protected:
+ std::shared_mutex mCallbackMutex;
+ std::unique_ptr<const PropertyChangeCallback> mOnPropChange;
+
private:
void ValuePollingLoop();
@@ -90,8 +94,6 @@
std::unique_ptr<proto::VehicleServer::Stub> mGrpcStub;
std::thread mValuePollingThread;
- std::shared_mutex mCallbackMutex;
- std::unique_ptr<const PropertyChangeCallback> mOnPropChange;
std::unique_ptr<const PropertySetErrorCallback> mOnSetErr;
std::mutex mShutdownMutex;
diff --git a/automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.h b/automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.h
index 2e7298f..b3f4a0f 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.h
@@ -107,12 +107,18 @@
// Gets the callback to be called when the request for this client has finished.
std::shared_ptr<const IVehicleHardware::GetValuesCallback> getResultCallback();
- // Marshals the updated values into largeParcelable and sents it through {@code onPropertyEvent}
+ // Marshals the updated values into largeParcelable and sends it through {@code onPropertyEvent}
// callback.
static void sendUpdatedValues(
CallbackType callback,
std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&&
updatedValues);
+ // Marshals the set property error events into largeParcelable and sends it through
+ // {@code onPropertySetError} callback.
+ static void sendPropertySetErrors(
+ CallbackType callback,
+ std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropError>&&
+ vehiclePropErrors);
protected:
// Gets the callback to be called when the request for this client has timeout.
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index 2c2cf1a..74ad7ea 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -249,10 +249,14 @@
const CallbackType& callback, std::shared_ptr<PendingRequestPool> pendingRequestPool);
static void onPropertyChangeEvent(
- std::weak_ptr<SubscriptionManager> subscriptionManager,
+ const std::weak_ptr<SubscriptionManager>& subscriptionManager,
const std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&
updatedValues);
+ static void onPropertySetErrorEvent(
+ const std::weak_ptr<SubscriptionManager>& subscriptionManager,
+ const std::vector<SetValueErrorEvent>& errorEvents);
+
static void checkHealth(IVehicleHardware* hardware,
std::weak_ptr<SubscriptionManager> subscriptionManager);
diff --git a/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h b/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h
index 14799d9..301d56c 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h
@@ -99,6 +99,12 @@
const std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&
updatedValues);
+ // For a list of set property error events, returns a map that maps clients subscribing to the
+ // properties to a list of errors for each client.
+ std::unordered_map<CallbackType,
+ std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropError>>
+ getSubscribedClientsForErrorEvents(const std::vector<SetValueErrorEvent>& errorEvents);
+
// Checks whether the sample rate is valid.
static bool checkSampleRateHz(float sampleRateHz);
diff --git a/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp b/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp
index 81d231c..fb23a25 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp
@@ -38,6 +38,8 @@
using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropError;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
using ::android::base::Result;
@@ -300,7 +302,34 @@
if (ScopedAStatus callbackStatus =
callback->onPropertyEvent(vehiclePropValues, sharedMemoryFileCount);
!callbackStatus.isOk()) {
- ALOGE("subscribe: failed to call UpdateValues callback, client ID: %p, error: %s, "
+ ALOGE("subscribe: failed to call onPropertyEvent callback, client ID: %p, error: %s, "
+ "exception: %d, service specific error: %d",
+ callback->asBinder().get(), callbackStatus.getMessage(),
+ callbackStatus.getExceptionCode(), callbackStatus.getServiceSpecificError());
+ }
+}
+
+void SubscriptionClient::sendPropertySetErrors(std::shared_ptr<IVehicleCallback> callback,
+ std::vector<VehiclePropError>&& vehiclePropErrors) {
+ if (vehiclePropErrors.empty()) {
+ return;
+ }
+
+ VehiclePropErrors vehiclePropErrorsLargeParcelable;
+ ScopedAStatus status = vectorToStableLargeParcelable(std::move(vehiclePropErrors),
+ &vehiclePropErrorsLargeParcelable);
+ if (!status.isOk()) {
+ int statusCode = status.getServiceSpecificError();
+ ALOGE("subscribe: failed to marshal result into large parcelable, error: "
+ "%s, code: %d",
+ status.getMessage(), statusCode);
+ return;
+ }
+
+ if (ScopedAStatus callbackStatus =
+ callback->onPropertySetError(vehiclePropErrorsLargeParcelable);
+ !callbackStatus.isOk()) {
+ ALOGE("subscribe: failed to call onPropertySetError callback, client ID: %p, error: %s, "
"exception: %d, service specific error: %d",
callback->asBinder().get(), callbackStatus.getMessage(),
callbackStatus.getExceptionCode(), callbackStatus.getServiceSpecificError());
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index 98cfc39..0d5c070 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -144,6 +144,11 @@
[subscriptionManagerCopy](std::vector<VehiclePropValue> updatedValues) {
onPropertyChangeEvent(subscriptionManagerCopy, updatedValues);
}));
+ mVehicleHardware->registerOnPropertySetErrorEvent(
+ std::make_unique<IVehicleHardware::PropertySetErrorCallback>(
+ [subscriptionManagerCopy](std::vector<SetValueErrorEvent> errorEvents) {
+ onPropertySetErrorEvent(subscriptionManagerCopy, errorEvents);
+ }));
// Register heartbeat event.
mRecurrentAction = std::make_shared<std::function<void()>>(
@@ -177,7 +182,7 @@
}
void DefaultVehicleHal::onPropertyChangeEvent(
- std::weak_ptr<SubscriptionManager> subscriptionManager,
+ const std::weak_ptr<SubscriptionManager>& subscriptionManager,
const std::vector<VehiclePropValue>& updatedValues) {
auto manager = subscriptionManager.lock();
if (manager == nullptr) {
@@ -194,6 +199,20 @@
}
}
+void DefaultVehicleHal::onPropertySetErrorEvent(
+ const std::weak_ptr<SubscriptionManager>& subscriptionManager,
+ const std::vector<SetValueErrorEvent>& errorEvents) {
+ auto manager = subscriptionManager.lock();
+ if (manager == nullptr) {
+ ALOGW("the SubscriptionManager is destroyed, DefaultVehicleHal is ending");
+ return;
+ }
+ auto vehiclePropErrorsByClient = manager->getSubscribedClientsForErrorEvents(errorEvents);
+ for (auto& [callback, vehiclePropErrors] : vehiclePropErrorsByClient) {
+ SubscriptionClient::sendPropertySetErrors(callback, std::move(vehiclePropErrors));
+ }
+}
+
template <class T>
std::shared_ptr<T> DefaultVehicleHal::getOrCreateClient(
std::unordered_map<const AIBinder*, std::shared_ptr<T>>* clients,
@@ -692,15 +711,19 @@
// Create a new SubscriptionClient if there isn't an existing one.
mSubscriptionClients->maybeAddClient(callback);
- // Since we have already check the sample rates, the following functions must succeed.
if (!onChangeSubscriptions.empty()) {
- return toScopedAStatus(mSubscriptionManager->subscribe(callback, onChangeSubscriptions,
- /*isContinuousProperty=*/false));
+ auto result = mSubscriptionManager->subscribe(callback, onChangeSubscriptions,
+ /*isContinuousProperty=*/false);
+ if (!result.ok()) {
+ return toScopedAStatus(result);
+ }
}
if (!continuousSubscriptions.empty()) {
- return toScopedAStatus(mSubscriptionManager->subscribe(callback,
- continuousSubscriptions,
- /*isContinuousProperty=*/true));
+ auto result = mSubscriptionManager->subscribe(callback, continuousSubscriptions,
+ /*isContinuousProperty=*/true);
+ if (!result.ok()) {
+ return toScopedAStatus(result);
+ }
}
}
return ScopedAStatus::ok();
diff --git a/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp b/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
index bba730f..1f2690e 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
@@ -36,6 +36,7 @@
using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropError;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
using ::android::base::Error;
using ::android::base::Result;
@@ -269,6 +270,32 @@
return clients;
}
+std::unordered_map<std::shared_ptr<IVehicleCallback>, std::vector<VehiclePropError>>
+SubscriptionManager::getSubscribedClientsForErrorEvents(
+ const std::vector<SetValueErrorEvent>& errorEvents) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ std::unordered_map<std::shared_ptr<IVehicleCallback>, std::vector<VehiclePropError>> clients;
+
+ for (const auto& errorEvent : errorEvents) {
+ PropIdAreaId propIdAreaId{
+ .propId = errorEvent.propId,
+ .areaId = errorEvent.areaId,
+ };
+ if (mClientsByPropIdArea.find(propIdAreaId) == mClientsByPropIdArea.end()) {
+ continue;
+ }
+
+ for (const auto& [_, client] : mClientsByPropIdArea[propIdAreaId]) {
+ clients[client].push_back({
+ .propId = errorEvent.propId,
+ .areaId = errorEvent.areaId,
+ .errorCode = errorEvent.errorCode,
+ });
+ }
+ }
+ return clients;
+}
+
bool SubscriptionManager::isEmpty() {
std::scoped_lock<std::mutex> lockGuard(mLock);
return mSubscribedPropsByClient.empty() && mClientsByPropIdArea.empty();
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index 05e569a..96b71f0 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -62,6 +62,7 @@
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropError;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
@@ -1653,6 +1654,63 @@
ASSERT_EQ(msg.find("Vehicle HAL State: "), std::string::npos);
}
+TEST_F(DefaultVehicleHalTest, testOnPropertySetErrorEvent) {
+ std::vector<SubscribeOptions> options = {
+ {
+ .propId = GLOBAL_ON_CHANGE_PROP,
+ .areaIds = {0},
+ },
+ {
+ .propId = GLOBAL_CONTINUOUS_PROP,
+ .areaIds = {0},
+ .sampleRate = 1,
+ },
+ };
+ auto status = getClient()->subscribe(getCallbackClient(), options, 0);
+ ASSERT_TRUE(status.isOk()) << "subscribe failed: " << status.getMessage();
+ std::vector<SetValueErrorEvent> errorEvents = {
+ {
+ .propId = GLOBAL_ON_CHANGE_PROP,
+ .areaId = 0,
+ .errorCode = StatusCode::INTERNAL_ERROR,
+ },
+ {
+ .propId = GLOBAL_ON_CHANGE_PROP,
+ .areaId = 0,
+ .errorCode = StatusCode::ACCESS_DENIED,
+ },
+ {
+ .propId = GLOBAL_CONTINUOUS_PROP,
+ .areaId = 0,
+ .errorCode = StatusCode::INVALID_ARG,
+ },
+ };
+ std::vector<VehiclePropError> expectedResults = {
+ {
+ .propId = GLOBAL_ON_CHANGE_PROP,
+ .areaId = 0,
+ .errorCode = StatusCode::INTERNAL_ERROR,
+ },
+ {
+ .propId = GLOBAL_ON_CHANGE_PROP,
+ .areaId = 0,
+ .errorCode = StatusCode::ACCESS_DENIED,
+ },
+ {
+ .propId = GLOBAL_CONTINUOUS_PROP,
+ .areaId = 0,
+ .errorCode = StatusCode::INVALID_ARG,
+ },
+ };
+ getHardware()->sendOnPropertySetErrorEvent(errorEvents);
+
+ ASSERT_EQ(getCallback()->countOnPropertySetErrorResults(), 1u);
+ auto maybeVehiclePropErrors = getCallback()->nextOnPropertySetErrorResults();
+ ASSERT_TRUE(maybeVehiclePropErrors.has_value());
+ const auto& vehiclePropErrors = maybeVehiclePropErrors.value();
+ ASSERT_THAT(vehiclePropErrors.payloads, UnorderedElementsAreArray(expectedResults));
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
index f51ce5c..54fede1 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
@@ -81,8 +81,14 @@
return result;
}
-ScopedAStatus MockVehicleCallback::onPropertySetError(const VehiclePropErrors&) {
- return ScopedAStatus::ok();
+ScopedAStatus MockVehicleCallback::onPropertySetError(const VehiclePropErrors& results) {
+ ScopedAStatus result;
+ {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ result = storeResults(results, &mOnPropertySetErrorResults);
+ }
+ mCond.notify_all();
+ return result;
}
std::optional<GetValueResults> MockVehicleCallback::nextGetValueResults() {
@@ -105,6 +111,16 @@
return mOnPropertyEventResults.size();
}
+std::optional<VehiclePropErrors> MockVehicleCallback::nextOnPropertySetErrorResults() {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return pop(mOnPropertySetErrorResults);
+}
+
+size_t MockVehicleCallback::countOnPropertySetErrorResults() {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return mOnPropertySetErrorResults.size();
+}
+
bool MockVehicleCallback::waitForSetValueResults(size_t size, size_t timeoutInNano) {
std::unique_lock lk(mLock);
return mCond.wait_for(lk, std::chrono::nanoseconds(timeoutInNano), [this, size] {
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
index f17b273..1545eae 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
@@ -63,6 +63,9 @@
nextSetValueResults();
std::optional<aidl::android::hardware::automotive::vehicle::VehiclePropValues>
nextOnPropertyEventResults();
+ size_t countOnPropertySetErrorResults();
+ std::optional<aidl::android::hardware::automotive::vehicle::VehiclePropErrors>
+ nextOnPropertySetErrorResults();
size_t countOnPropertyEventResults();
bool waitForSetValueResults(size_t size, size_t timeoutInNano);
bool waitForGetValueResults(size_t size, size_t timeoutInNano);
@@ -77,6 +80,8 @@
std::list<aidl::android::hardware::automotive::vehicle::VehiclePropValues>
mOnPropertyEventResults GUARDED_BY(mLock);
int32_t mSharedMemoryFileCount GUARDED_BY(mLock);
+ std::list<aidl::android::hardware::automotive::vehicle::VehiclePropErrors>
+ mOnPropertySetErrorResults GUARDED_BY(mLock);
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp
index 4df4e1a..ba0d33d 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp
@@ -131,8 +131,9 @@
}
void MockVehicleHardware::registerOnPropertySetErrorEvent(
- std::unique_ptr<const PropertySetErrorCallback>) {
- // TODO(b/200737967): mock this.
+ std::unique_ptr<const PropertySetErrorCallback> callback) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mPropertySetErrorCallback = std::move(callback);
}
void MockVehicleHardware::setPropertyConfigs(const std::vector<VehiclePropConfig>& configs) {
@@ -254,6 +255,12 @@
std::list<std::vector<SetValueRequest>>* storedRequests,
std::list<std::vector<SetValueResult>>* storedResponses) const;
+void MockVehicleHardware::sendOnPropertySetErrorEvent(
+ const std::vector<SetValueErrorEvent>& errorEvents) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ (*mPropertySetErrorCallback)(errorEvents);
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h
index 743841c..46b30b9 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h
@@ -85,6 +85,7 @@
aidl::android::hardware::automotive::vehicle::StatusCode status);
void setSleepTime(int64_t timeInNano);
void setDumpResult(DumpResult result);
+ void sendOnPropertySetErrorEvent(const std::vector<SetValueErrorEvent>& errorEvents);
private:
mutable std::mutex mLock;
@@ -104,6 +105,7 @@
mStatusByFunctions GUARDED_BY(mLock);
int64_t mSleepTime GUARDED_BY(mLock) = 0;
std::unique_ptr<const PropertyChangeCallback> mPropertyChangeCallback GUARDED_BY(mLock);
+ std::unique_ptr<const PropertySetErrorCallback> mPropertySetErrorCallback GUARDED_BY(mLock);
std::function<aidl::android::hardware::automotive::vehicle::StatusCode(
std::shared_ptr<const GetValuesCallback>,
const std::vector<aidl::android::hardware::automotive::vehicle::GetValueRequest>&)>
diff --git a/automotive/vehicle/proto/Android.bp b/automotive/vehicle/proto/Android.bp
index 683f128..e7dabcf 100644
--- a/automotive/vehicle/proto/Android.bp
+++ b/automotive/vehicle/proto/Android.bp
@@ -27,6 +27,7 @@
visibility: [
"//hardware/interfaces/automotive/vehicle:__subpackages__",
"//device/generic/car/emulator:__subpackages__",
+ "//system/software_defined_vehicle/core_services:__subpackages__",
],
vendor: true,
host_supported: true,
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
index 90ec8f2..54076c8 100644
--- a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
@@ -31,6 +31,9 @@
namespace aidl::android::hardware::biometrics::fingerprint {
+FakeFingerprintEngine::FakeFingerprintEngine()
+ : mRandom(std::mt19937::default_seed), mWorkMode(WorkMode::kIdle) {}
+
void FakeFingerprintEngine::generateChallengeImpl(ISessionCallback* cb) {
BEGIN_OP(0);
std::uniform_int_distribution<int64_t> dist;
@@ -48,7 +51,7 @@
void FakeFingerprintEngine::enrollImpl(ISessionCallback* cb,
const keymaster::HardwareAuthToken& hat,
const std::future<void>& cancel) {
- BEGIN_OP(getLatency(FingerprintHalProperties::operation_enroll_latency()));
+ BEGIN_OP(0);
// Do proper HAT verification in the real implementation.
if (hat.mac.empty()) {
@@ -57,13 +60,77 @@
return;
}
+ updateContext(WorkMode::kEnroll, cb, const_cast<std::future<void>&>(cancel), 0, hat);
+}
+
+void FakeFingerprintEngine::authenticateImpl(ISessionCallback* cb, int64_t operationId,
+ const std::future<void>& cancel) {
+ BEGIN_OP(0);
+ updateContext(WorkMode::kAuthenticate, cb, const_cast<std::future<void>&>(cancel), operationId,
+ keymaster::HardwareAuthToken());
+}
+
+void FakeFingerprintEngine::detectInteractionImpl(ISessionCallback* cb,
+ const std::future<void>& cancel) {
+ BEGIN_OP(0);
+
+ auto detectInteractionSupported =
+ FingerprintHalProperties::detect_interaction().value_or(false);
+ if (!detectInteractionSupported) {
+ LOG(ERROR) << "Detect interaction is not supported";
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
+
+ updateContext(WorkMode::kDetectInteract, cb, const_cast<std::future<void>&>(cancel), 0,
+ keymaster::HardwareAuthToken());
+}
+
+void FakeFingerprintEngine::updateContext(WorkMode mode, ISessionCallback* cb,
+ std::future<void>& cancel, int64_t operationId,
+ const keymaster::HardwareAuthToken& hat) {
+ mCancel = std::move(cancel);
+ mWorkMode = mode;
+ mCb = cb;
+ mOperationId = operationId;
+ mHat = hat;
+}
+
+void FakeFingerprintEngine::fingerDownAction() {
+ bool isTerminal = false;
+ LOG(INFO) << __func__;
+ switch (mWorkMode) {
+ case WorkMode::kAuthenticate:
+ isTerminal = onAuthenticateFingerDown(mCb, mOperationId, mCancel);
+ break;
+ case WorkMode::kEnroll:
+ isTerminal = onEnrollFingerDown(mCb, mHat, mCancel);
+ break;
+ case WorkMode::kDetectInteract:
+ isTerminal = onDetectInteractFingerDown(mCb, mCancel);
+ break;
+ default:
+ LOG(WARNING) << "unexpected mode: on fingerDownAction(), " << (int)mWorkMode;
+ break;
+ }
+
+ if (isTerminal) {
+ mWorkMode = WorkMode::kIdle;
+ }
+}
+
+bool FakeFingerprintEngine::onEnrollFingerDown(ISessionCallback* cb,
+ const keymaster::HardwareAuthToken&,
+ const std::future<void>& cancel) {
+ BEGIN_OP(getLatency(FingerprintHalProperties::operation_enroll_latency()));
+
// 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;
+ return true;
}
// Format is "<id>:<progress_ms-[acquiredInfo..]>,...:<result>
@@ -72,7 +139,7 @@
if (parts.size() != 3) {
LOG(ERROR) << "Fail: invalid next_enrollment:" << nextEnroll;
cb->onError(Error::VENDOR, 0 /* vendorError */);
- return;
+ return true;
}
auto enrollmentId = std::stoi(parts[0]);
auto progress = parseEnrollmentCapture(parts[1]);
@@ -88,7 +155,7 @@
if (shouldCancel(cancel)) {
LOG(ERROR) << "Fail: cancel";
cb->onError(Error::CANCELED, 0 /* vendorCode */);
- return;
+ return true;
}
auto ac = convertAcquiredInfo(acquired[j]);
cb->onAcquired(ac.first, ac.second);
@@ -114,10 +181,13 @@
cb->onEnrollmentProgress(enrollmentId, left);
}
}
+
+ return true;
}
-void FakeFingerprintEngine::authenticateImpl(ISessionCallback* cb, int64_t /* operationId */,
- const std::future<void>& cancel) {
+bool FakeFingerprintEngine::onAuthenticateFingerDown(ISessionCallback* cb,
+ int64_t /* operationId */,
+ const std::future<void>& cancel) {
BEGIN_OP(getLatency(FingerprintHalProperties::operation_authenticate_latency()));
int64_t now = Util::getSystemNanoTime();
@@ -129,19 +199,12 @@
if (N == 0) {
LOG(ERROR) << "Fail to parse authentiate acquired info: " + acquired;
cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
- return;
+ return true;
}
// got lockout?
- FakeLockoutTracker::LockoutMode lockoutMode = mLockoutTracker.getMode();
- if (lockoutMode == FakeLockoutTracker::LockoutMode::kPermanent) {
- LOG(ERROR) << "Fail: lockout permanent";
- cb->onLockoutPermanent();
- return;
- } else if (lockoutMode == FakeLockoutTracker::LockoutMode::kTimed) {
- int64_t timeLeft = mLockoutTracker.getLockoutTimeLeft();
- LOG(ERROR) << "Fail: lockout timed " << timeLeft;
- cb->onLockoutTimed(timeLeft);
+ if (checkSensorLockout(cb)) {
+ return FakeLockoutTracker::LockoutMode::kPermanent == mLockoutTracker.getMode();
}
int i = 0;
@@ -150,7 +213,7 @@
LOG(ERROR) << "Fail: operation_authenticate_fails";
mLockoutTracker.addFailedAttempt();
cb->onAuthenticationFailed();
- return;
+ return false;
}
auto err = FingerprintHalProperties::operation_authenticate_error().value_or(0);
@@ -158,20 +221,21 @@
LOG(ERROR) << "Fail: operation_authenticate_error";
auto ec = convertError(err);
cb->onError(ec.first, ec.second);
- return;
+ return true; /* simply terminating current operation for any user inserted error,
+ revisit if tests need*/
}
if (FingerprintHalProperties::lockout().value_or(false)) {
LOG(ERROR) << "Fail: lockout";
cb->onLockoutPermanent();
cb->onError(Error::HW_UNAVAILABLE, 0 /* vendorError */);
- return;
+ return true;
}
if (shouldCancel(cancel)) {
LOG(ERROR) << "Fail: cancel";
cb->onError(Error::CANCELED, 0 /* vendorCode */);
- return;
+ return true;
}
if (i < N) {
@@ -189,29 +253,23 @@
if (id > 0 && isEnrolled) {
cb->onAuthenticationSucceeded(id, {} /* hat */);
mLockoutTracker.reset();
- return;
+ return true;
} else {
LOG(ERROR) << "Fail: fingerprint not enrolled";
cb->onAuthenticationFailed();
mLockoutTracker.addFailedAttempt();
+ checkSensorLockout(cb);
+ return false;
}
}
-void FakeFingerprintEngine::detectInteractionImpl(ISessionCallback* cb,
- const std::future<void>& cancel) {
+bool FakeFingerprintEngine::onDetectInteractFingerDown(ISessionCallback* cb,
+ const std::future<void>& cancel) {
BEGIN_OP(getLatency(FingerprintHalProperties::operation_detect_interaction_latency()));
int64_t duration =
FingerprintHalProperties::operation_detect_interaction_duration().value_or(10);
- auto detectInteractionSupported =
- FingerprintHalProperties::detect_interaction().value_or(false);
- if (!detectInteractionSupported) {
- LOG(ERROR) << "Detect interaction is not supported";
- cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
- return;
- }
-
auto acquired = FingerprintHalProperties::operation_detect_interaction_acquired().value_or("1");
auto acquiredInfos = parseIntSequence(acquired);
int N = acquiredInfos.size();
@@ -220,7 +278,7 @@
if (N == 0) {
LOG(ERROR) << "Fail to parse detect interaction acquired info: " + acquired;
cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
- return;
+ return true;
}
int i = 0;
@@ -230,13 +288,13 @@
LOG(ERROR) << "Fail: operation_detect_interaction_error";
auto ec = convertError(err);
cb->onError(ec.first, ec.second);
- return;
+ return true;
}
if (shouldCancel(cancel)) {
LOG(ERROR) << "Fail: cancel";
cb->onError(Error::CANCELED, 0 /* vendorCode */);
- return;
+ return true;
}
if (i < N) {
@@ -253,21 +311,18 @@
if (id <= 0 || !isEnrolled) {
LOG(ERROR) << "Fail: not enrolled";
cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
- return;
+ return true;
}
cb->onInteractionDetected();
+
+ return true;
}
void FakeFingerprintEngine::enumerateEnrollmentsImpl(ISessionCallback* cb) {
BEGIN_OP(0);
std::vector<int32_t> ids;
- // There are some enrollment sync issue with framework, which results in
- // a single template removal during the very firt sync command after reboot.
- // This is a workaround for now. TODO(b/243129174)
- ids.push_back(-1);
-
for (auto& enrollment : FingerprintHalProperties::enrollments()) {
auto id = enrollment.value_or(0);
if (id > 0) {
@@ -330,6 +385,11 @@
cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
return;
}
+ clearLockout(cb);
+ isLockoutTimerAborted = true;
+}
+
+void FakeFingerprintEngine::clearLockout(ISessionCallback* cb) {
FingerprintHalProperties::lockout(false);
cb->onLockoutCleared();
mLockoutTracker.reset();
@@ -339,6 +399,7 @@
int32_t /*y*/, float /*minor*/,
float /*major*/) {
BEGIN_OP(0);
+ fingerDownAction();
return ndk::ScopedAStatus::ok();
}
@@ -369,7 +430,8 @@
if (dim.size() >= 4) {
d = dim[3];
}
- if (isValidStr) out = {0, x, y, r, d};
+ if (isValidStr)
+ out = {.sensorLocationX = x, .sensorLocationY = y, .sensorRadius = r, .display = d};
return isValidStr;
}
@@ -385,8 +447,7 @@
}
SensorLocation FakeFingerprintEngine::defaultSensorLocation() {
- return {0 /* displayId (not used) */, 0 /* sensorLocationX */, 0 /* sensorLocationY */,
- 0 /* sensorRadius */, "" /* display */};
+ return SensorLocation();
}
std::vector<int32_t> FakeFingerprintEngine::parseIntSequence(const std::string& str,
@@ -513,4 +574,39 @@
return dist(mRandom);
}
+bool FakeFingerprintEngine::checkSensorLockout(ISessionCallback* cb) {
+ FakeLockoutTracker::LockoutMode lockoutMode = mLockoutTracker.getMode();
+ if (lockoutMode == FakeLockoutTracker::LockoutMode::kPermanent) {
+ LOG(ERROR) << "Fail: lockout permanent";
+ cb->onLockoutPermanent();
+ isLockoutTimerAborted = true;
+ return true;
+ } else if (lockoutMode == FakeLockoutTracker::LockoutMode::kTimed) {
+ int64_t timeLeft = mLockoutTracker.getLockoutTimeLeft();
+ LOG(ERROR) << "Fail: lockout timed " << timeLeft;
+ cb->onLockoutTimed(timeLeft);
+ if (isLockoutTimerSupported && !isLockoutTimerStarted) startLockoutTimer(timeLeft, cb);
+ return true;
+ }
+ return false;
+}
+
+void FakeFingerprintEngine::startLockoutTimer(int64_t timeout, ISessionCallback* cb) {
+ BEGIN_OP(0);
+ std::function<void(ISessionCallback*)> action =
+ std::bind(&FakeFingerprintEngine::lockoutTimerExpired, this, std::placeholders::_1);
+ std::thread([timeout, action, cb]() {
+ std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
+ action(cb);
+ }).detach();
+
+ isLockoutTimerStarted = true;
+}
+void FakeFingerprintEngine::lockoutTimerExpired(ISessionCallback* cb) {
+ if (!isLockoutTimerAborted) {
+ clearLockout(cb);
+ }
+ isLockoutTimerStarted = false;
+ isLockoutTimerAborted = false;
+}
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp
index 9f736e7..a78cdcd 100644
--- a/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp
@@ -27,11 +27,13 @@
namespace aidl::android::hardware::biometrics::fingerprint {
-SensorLocation FakeFingerprintEngineSide::defaultSensorLocation() {
- SensorLocation location;
+FakeFingerprintEngineSide::FakeFingerprintEngineSide() : FakeFingerprintEngine() {
+ isLockoutTimerSupported = true;
+}
- return {0 /* displayId (not used) */, defaultSensorLocationX /* sensorLocationX */,
- defaultSensorLocationY /* sensorLocationY */, defaultSensorRadius /* sensorRadius */,
- "" /* display */};
+SensorLocation FakeFingerprintEngineSide::defaultSensorLocation() {
+ return SensorLocation{.sensorLocationX = defaultSensorLocationX,
+ .sensorLocationY = defaultSensorLocationY,
+ .sensorRadius = defaultSensorRadius};
}
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngineUdfps.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineUdfps.cpp
index 3cdfc70..68b0f0d 100644
--- a/biometrics/fingerprint/aidl/default/FakeFingerprintEngineUdfps.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineUdfps.cpp
@@ -31,12 +31,12 @@
namespace aidl::android::hardware::biometrics::fingerprint {
FakeFingerprintEngineUdfps::FakeFingerprintEngineUdfps()
- : FakeFingerprintEngine(), mWorkMode(WorkMode::kIdle), mPointerDownTime(0), mUiReadyTime(0) {}
+ : FakeFingerprintEngine(), mPointerDownTime(0), mUiReadyTime(0) {}
SensorLocation FakeFingerprintEngineUdfps::defaultSensorLocation() {
- return {0 /* displayId (not used) */, defaultSensorLocationX /* sensorLocationX */,
- defaultSensorLocationY /* sensorLocationY */, defaultSensorRadius /* sensorRadius */,
- "" /* display */};
+ return SensorLocation{.sensorLocationX = defaultSensorLocationX,
+ .sensorLocationY = defaultSensorLocationY,
+ .sensorRadius = defaultSensorRadius};
}
ndk::ScopedAStatus FakeFingerprintEngineUdfps::onPointerDownImpl(int32_t /*pointerId*/,
@@ -70,68 +70,17 @@
}
void FakeFingerprintEngineUdfps::fingerDownAction() {
- switch (mWorkMode) {
- case WorkMode::kAuthenticate:
- onAuthenticateFingerDown();
- break;
- case WorkMode::kEnroll:
- onEnrollFingerDown();
- break;
- case WorkMode::kDetectInteract:
- onDetectInteractFingerDown();
- break;
- default:
- LOG(WARNING) << "unexpected call: onUiReady()";
- break;
- }
-
+ FakeFingerprintEngine::fingerDownAction();
mUiReadyTime = 0;
mPointerDownTime = 0;
}
-void FakeFingerprintEngineUdfps::onAuthenticateFingerDown() {
- FakeFingerprintEngine::authenticateImpl(mCb, mOperationId, mCancelVec[0]);
-}
-
-void FakeFingerprintEngineUdfps::onEnrollFingerDown() {
- // Any use case to emulate display touch for each capture during enrollment?
- FakeFingerprintEngine::enrollImpl(mCb, mHat, mCancelVec[0]);
-}
-
-void FakeFingerprintEngineUdfps::onDetectInteractFingerDown() {
- FakeFingerprintEngine::detectInteractionImpl(mCb, mCancelVec[0]);
-}
-
-void FakeFingerprintEngineUdfps::enrollImpl(ISessionCallback* cb,
- const keymaster::HardwareAuthToken& hat,
- const std::future<void>& cancel) {
- updateContext(WorkMode::kEnroll, cb, const_cast<std::future<void>&>(cancel), 0, hat);
-}
-
-void FakeFingerprintEngineUdfps::authenticateImpl(ISessionCallback* cb, int64_t operationId,
- const std::future<void>& cancel) {
- updateContext(WorkMode::kAuthenticate, cb, const_cast<std::future<void>&>(cancel), operationId,
- keymaster::HardwareAuthToken());
-}
-
-void FakeFingerprintEngineUdfps::detectInteractionImpl(ISessionCallback* cb,
- const std::future<void>& cancel) {
- updateContext(WorkMode::kDetectInteract, cb, const_cast<std::future<void>&>(cancel), 0,
- keymaster::HardwareAuthToken());
-}
-
void FakeFingerprintEngineUdfps::updateContext(WorkMode mode, ISessionCallback* cb,
std::future<void>& cancel, int64_t operationId,
const keymaster::HardwareAuthToken& hat) {
+ FakeFingerprintEngine::updateContext(mode, cb, cancel, operationId, hat);
mPointerDownTime = 0;
mUiReadyTime = 0;
- mCancelVec.clear();
-
- mCancelVec.push_back(std::move(cancel));
- mWorkMode = mode;
- mCb = cb;
- mOperationId = operationId;
- mHat = hat;
}
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp b/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp
index 5996406..b0163ee 100644
--- a/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp
@@ -67,9 +67,13 @@
int64_t res = 0;
if (mLockoutTimedStart > 0) {
+ int32_t lockoutTimedDuration =
+ FingerprintHalProperties::lockout_timed_duration().value_or(10 * 100);
auto now = Util::getSystemNanoTime();
- auto left = now - mLockoutTimedStart;
- res = (left > 0) ? (left / 1000000LL) : 0;
+ auto elapsed = (now - mLockoutTimedStart) / 1000000LL;
+ res = lockoutTimedDuration - elapsed;
+ LOG(INFO) << "xxxxxx: elapsed=" << elapsed << " now = " << now
+ << " mLockoutTimedStart=" << mLockoutTimedStart << " res=" << res;
}
return res;
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
index f00a49d..79b563e 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
@@ -17,6 +17,7 @@
#include "Fingerprint.h"
#include "Session.h"
+#include <android-base/properties.h>
#include <fingerprint.sysprop.h>
#include <android-base/file.h>
@@ -59,6 +60,7 @@
<< sensorTypeProp;
}
LOG(INFO) << "sensorTypeProp:" << sensorTypeProp;
+ LOG(INFO) << "ro.product.name=" << ::android::base::GetProperty("ro.product.name", "UNKNOWN");
}
ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector<SensorProps>* out) {
@@ -105,16 +107,16 @@
mSession->linkToDeath(cb->asBinder().get());
- LOG(INFO) << "createSession: sensorId:" << sensorId << " userId:" << userId;
+ LOG(INFO) << __func__ << ": sensorId:" << sensorId << " userId:" << userId;
return ndk::ScopedAStatus::ok();
}
binder_status_t Fingerprint::dump(int fd, const char** /*args*/, uint32_t numArgs) {
if (fd < 0) {
- LOG(ERROR) << "Fingerprint::dump fd invalid: " << fd;
+ LOG(ERROR) << __func__ << "fd invalid: " << fd;
return STATUS_BAD_VALUE;
} else {
- LOG(INFO) << "Fingerprint::dump fd:" << fd << "numArgs:" << numArgs;
+ LOG(INFO) << __func__ << " fd:" << fd << "numArgs:" << numArgs;
}
dprintf(fd, "----- FingerprintVirtualHal::dump -----\n");
@@ -131,11 +133,11 @@
binder_status_t Fingerprint::handleShellCommand(int in, int out, int err, const char** args,
uint32_t numArgs) {
- LOG(INFO) << "Fingerprint::handleShellCommand in:" << in << " out:" << out << " err:" << err
+ LOG(INFO) << __func__ << " in:" << in << " out:" << out << " err:" << err
<< " numArgs:" << numArgs;
if (numArgs == 0) {
- LOG(INFO) << "Fingerprint::handleShellCommand: available commands";
+ LOG(INFO) << __func__ << ": available commands";
onHelp(out);
return STATUS_OK;
}
@@ -163,7 +165,7 @@
}
void Fingerprint::resetConfigToDefault() {
- LOG(INFO) << "reset virtual HAL configuration to default";
+ LOG(INFO) << __func__ << ": reset virtual HAL configuration to default";
#define RESET_CONFIG_O(__NAME__) \
if (FingerprintHalProperties::__NAME__()) FingerprintHalProperties::__NAME__(std::nullopt)
#define RESET_CONFIG_V(__NAME__) \
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index 1279cd9..2450115 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -38,7 +38,7 @@
// A fake engine that is backed by system properties instead of hardware.
class FakeFingerprintEngine {
public:
- FakeFingerprintEngine() : mRandom(std::mt19937::default_seed) {}
+ FakeFingerprintEngine();
virtual ~FakeFingerprintEngine() {}
void generateChallengeImpl(ISessionCallback* cb);
@@ -66,6 +66,8 @@
virtual SensorLocation defaultSensorLocation();
+ virtual void fingerDownAction();
+
std::vector<int32_t> parseIntSequence(const std::string& str, const std::string& sep = ",");
std::vector<std::vector<int32_t>> parseEnrollmentCapture(const std::string& str);
@@ -74,15 +76,35 @@
std::mt19937 mRandom;
+ enum class WorkMode : int8_t { kIdle = 0, kAuthenticate, kEnroll, kDetectInteract };
+
+ WorkMode getWorkMode() { return mWorkMode; }
+
virtual std::string toString() const {
std::ostringstream os;
os << "----- FakeFingerprintEngine:: -----" << std::endl;
+ os << "mWorkMode:" << (int)mWorkMode;
os << "acquiredVendorInfoBase:" << FINGERPRINT_ACQUIRED_VENDOR_BASE;
os << ", errorVendorBase:" << FINGERPRINT_ERROR_VENDOR_BASE << std::endl;
os << mLockoutTracker.toString();
return os.str();
}
+ protected:
+ virtual void updateContext(WorkMode mode, ISessionCallback* cb, std::future<void>& cancel,
+ int64_t operationId, const keymaster::HardwareAuthToken& hat);
+
+ bool onEnrollFingerDown(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+ const std::future<void>& cancel);
+ bool onAuthenticateFingerDown(ISessionCallback* cb, int64_t, const std::future<void>& cancel);
+ bool onDetectInteractFingerDown(ISessionCallback* cb, const std::future<void>& cancel);
+
+ WorkMode mWorkMode;
+ ISessionCallback* mCb;
+ keymaster::HardwareAuthToken mHat;
+ std::future<void> mCancel;
+ int64_t mOperationId;
+
private:
static constexpr int32_t FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
static constexpr int32_t FINGERPRINT_ERROR_VENDOR_BASE = 1000;
@@ -91,8 +113,21 @@
bool parseEnrollmentCaptureSingle(const std::string& str,
std::vector<std::vector<int32_t>>& res);
int32_t getRandomInRange(int32_t bound1, int32_t bound2);
+ bool checkSensorLockout(ISessionCallback*);
+ void clearLockout(ISessionCallback* cb);
FakeLockoutTracker mLockoutTracker;
+
+ protected:
+ // lockout timer
+ void lockoutTimerExpired(ISessionCallback* cb);
+ bool isLockoutTimerSupported;
+ bool isLockoutTimerStarted;
+ bool isLockoutTimerAborted;
+
+ public:
+ void startLockoutTimer(int64_t timeout, ISessionCallback* cb);
+ bool getLockoutTimerStarted() { return isLockoutTimerStarted; }
};
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h
index c2fc005..67a3ebc 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h
@@ -28,7 +28,7 @@
static constexpr int32_t defaultSensorLocationY = 600;
static constexpr int32_t defaultSensorRadius = 150;
- FakeFingerprintEngineSide() : FakeFingerprintEngine() {}
+ FakeFingerprintEngineSide();
~FakeFingerprintEngineSide() {}
virtual SensorLocation defaultSensorLocation() override;
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineUdfps.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineUdfps.h
index c5e93e7..2270eca 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineUdfps.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineUdfps.h
@@ -42,39 +42,20 @@
SensorLocation defaultSensorLocation() override;
- void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
- const std::future<void>& cancel);
- void authenticateImpl(ISessionCallback* cb, int64_t operationId,
- const std::future<void>& cancel);
- void detectInteractionImpl(ISessionCallback* cb, const std::future<void>& cancel);
-
- enum class WorkMode : int8_t { kIdle = 0, kAuthenticate, kEnroll, kDetectInteract };
-
- WorkMode getWorkMode() { return mWorkMode; }
+ void updateContext(WorkMode mode, ISessionCallback* cb, std::future<void>& cancel,
+ int64_t operationId, const keymaster::HardwareAuthToken& hat);
+ void fingerDownAction();
std::string toString() const {
std::ostringstream os;
os << FakeFingerprintEngine::toString();
os << "----- FakeFingerprintEngineUdfps -----" << std::endl;
- os << "mWorkMode:" << (int)mWorkMode;
os << ", mUiReadyTime:" << mUiReadyTime;
os << ", mPointerDownTime:" << mPointerDownTime << std::endl;
return os.str();
}
private:
- void onAuthenticateFingerDown();
- void onEnrollFingerDown();
- void onDetectInteractFingerDown();
- void fingerDownAction();
- void updateContext(WorkMode mode, ISessionCallback* cb, std::future<void>& cancel,
- int64_t operationId, const keymaster::HardwareAuthToken& hat);
-
- WorkMode mWorkMode;
- ISessionCallback* mCb;
- keymaster::HardwareAuthToken mHat;
- std::vector<std::future<void>> mCancelVec;
- int64_t mOperationId;
int64_t mPointerDownTime;
int64_t mUiReadyTime;
};
diff --git a/biometrics/fingerprint/aidl/default/include/Fingerprint.h b/biometrics/fingerprint/aidl/default/include/Fingerprint.h
index fc4fb8d..2bd66d4 100644
--- a/biometrics/fingerprint/aidl/default/include/Fingerprint.h
+++ b/biometrics/fingerprint/aidl/default/include/Fingerprint.h
@@ -43,6 +43,7 @@
private:
void resetConfigToDefault();
void onHelp(int);
+ void onSimFingerDown();
std::unique_ptr<FakeFingerprintEngine> mEngine;
WorkerThread mWorker;
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
index a200b39..fe405f4 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
@@ -93,9 +93,13 @@
return ndk::ScopedAStatus::ok();
};
ndk::ScopedAStatus onLockoutTimed(int64_t /* timeout */) override {
+ mLockoutTimed = true;
return ndk::ScopedAStatus::ok();
}
- ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus onLockoutCleared() override {
+ mLockoutCleared = true;
+ return ndk::ScopedAStatus::ok();
+ }
ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
Error mError = Error::UNKNOWN;
@@ -110,6 +114,8 @@
bool mAuthenticateFailed = false;
bool mAuthenticatorIdInvalidated = false;
bool mLockoutPermanent = false;
+ bool mLockoutTimed = false;
+ bool mLockoutCleared = false;
int mInteractionDetectedCount = 0;
int32_t mLastAcquiredInfo = -1;
int32_t mLastAcquiredVendorCode = -1;
@@ -132,6 +138,8 @@
FingerprintHalProperties::operation_enroll_latency({});
FingerprintHalProperties::operation_authenticate_latency({});
FingerprintHalProperties::operation_detect_interaction_latency({});
+ FingerprintHalProperties::operation_authenticate_fails(false);
+ FingerprintHalProperties::operation_detect_interaction_latency({});
}
FakeFingerprintEngine mEngine;
@@ -178,11 +186,14 @@
FingerprintHalProperties::next_enrollment("4:0,0:true");
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+ ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kEnroll);
+ mEngine.fingerDownAction();
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(1, mCallback->mLastAcquiredInfo);
+ ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kIdle);
}
TEST_F(FakeFingerprintEngineTest, EnrollCancel) {
@@ -192,6 +203,7 @@
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
mCancel.set_value();
mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_EQ(Error::CANCELED, mCallback->mError);
ASSERT_EQ(-1, mCallback->mLastEnrolled);
ASSERT_EQ(0, FingerprintHalProperties::enrollments().size());
@@ -204,6 +216,7 @@
FingerprintHalProperties::next_enrollment(next);
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_EQ(Error::UNABLE_TO_PROCESS, mCallback->mError);
ASSERT_EQ(-1, mCallback->mLastEnrolled);
ASSERT_EQ(0, FingerprintHalProperties::enrollments().size());
@@ -216,6 +229,7 @@
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
int32_t prevCnt = mCallback->mLastAcquiredCount;
mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
ASSERT_EQ(1, FingerprintHalProperties::enrollments().size());
ASSERT_EQ(4, FingerprintHalProperties::enrollments()[0].value());
@@ -229,9 +243,12 @@
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit(2);
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kAuthenticate);
+ mEngine.fingerDownAction();
ASSERT_FALSE(mCallback->mAuthenticateFailed);
ASSERT_EQ(2, mCallback->mLastAuthenticated);
ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
+ ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kIdle);
}
TEST_F(FakeFingerprintEngineTest, AuthenticateCancel) {
@@ -239,6 +256,7 @@
FingerprintHalProperties::enrollment_hit(2);
mCancel.set_value();
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_EQ(Error::CANCELED, mCallback->mError);
ASSERT_EQ(-1, mCallback->mLastAuthenticated);
}
@@ -247,6 +265,7 @@
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit({});
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_TRUE(mCallback->mAuthenticateFailed);
}
@@ -254,7 +273,9 @@
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit(3);
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_TRUE(mCallback->mAuthenticateFailed);
+ ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kAuthenticate);
}
TEST_F(FakeFingerprintEngineTest, AuthenticateLockout) {
@@ -262,6 +283,7 @@
FingerprintHalProperties::enrollment_hit(2);
FingerprintHalProperties::lockout(true);
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_TRUE(mCallback->mLockoutPermanent);
ASSERT_NE(mCallback->mError, Error::UNKNOWN);
}
@@ -269,6 +291,7 @@
TEST_F(FakeFingerprintEngineTest, AuthenticateError8) {
FingerprintHalProperties::operation_authenticate_error(8);
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_EQ(mCallback->mError, (Error)8);
ASSERT_EQ(mCallback->mErrorVendorCode, 0);
}
@@ -276,10 +299,19 @@
TEST_F(FakeFingerprintEngineTest, AuthenticateError9) {
FingerprintHalProperties::operation_authenticate_error(1009);
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_EQ(mCallback->mError, (Error)7);
ASSERT_EQ(mCallback->mErrorVendorCode, 9);
}
+TEST_F(FakeFingerprintEngineTest, AuthenticateFails) {
+ FingerprintHalProperties::operation_authenticate_fails(true);
+ mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ mEngine.fingerDownAction();
+ ASSERT_TRUE(mCallback->mAuthenticateFailed);
+ ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kAuthenticate);
+}
+
TEST_F(FakeFingerprintEngineTest, AuthenticateAcquired) {
FingerprintHalProperties::lockout(false);
FingerprintHalProperties::enrollments({1, 2});
@@ -287,6 +319,7 @@
FingerprintHalProperties::operation_authenticate_acquired("4,1009");
int32_t prevCount = mCallback->mLastAcquiredCount;
mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_FALSE(mCallback->mAuthenticateFailed);
ASSERT_EQ(2, mCallback->mLastAuthenticated);
ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
@@ -300,8 +333,11 @@
FingerprintHalProperties::enrollment_hit(2);
FingerprintHalProperties::operation_detect_interaction_acquired("");
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kDetectInteract);
+ mEngine.fingerDownAction();
ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
+ ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kIdle);
}
TEST_F(FakeFingerprintEngineTest, InteractionDetectCancel) {
@@ -310,6 +346,7 @@
FingerprintHalProperties::enrollment_hit(2);
mCancel.set_value();
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_EQ(Error::CANCELED, mCallback->mError);
ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
}
@@ -319,6 +356,7 @@
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit({});
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
}
@@ -326,6 +364,7 @@
FingerprintHalProperties::enrollments({1, 2});
FingerprintHalProperties::enrollment_hit(25);
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
}
@@ -333,6 +372,7 @@
FingerprintHalProperties::detect_interaction(true);
FingerprintHalProperties::operation_detect_interaction_error(8);
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
ASSERT_EQ(mCallback->mError, (Error)8);
ASSERT_EQ(mCallback->mErrorVendorCode, 0);
@@ -345,6 +385,7 @@
FingerprintHalProperties::operation_detect_interaction_acquired("4,1013");
int32_t prevCount = mCallback->mLastAcquiredCount;
mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ mEngine.fingerDownAction();
ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
@@ -354,9 +395,7 @@
TEST_F(FakeFingerprintEngineTest, EnumerateEnrolled) {
FingerprintHalProperties::enrollments({2, 4, 8});
mEngine.enumerateEnrollmentsImpl(mCallback.get());
- ASSERT_EQ(
- 4,
- mCallback->mLastEnrollmentEnumerated.size()); // Due to workaround. TODO (b/243129174)
+ ASSERT_EQ(3, mCallback->mLastEnrollmentEnumerated.size());
for (auto id : FingerprintHalProperties::enrollments()) {
ASSERT_TRUE(std::find(mCallback->mLastEnrollmentEnumerated.begin(),
mCallback->mLastEnrollmentEnumerated.end(),
@@ -464,9 +503,15 @@
FingerprintHalProperties::operation_detect_interaction_latency()));
}
ASSERT_TRUE(latencySet.size() > 95);
- FingerprintHalProperties::operation_detect_interaction_latency({});
}
+TEST_F(FakeFingerprintEngineTest, lockoutTimer) {
+ mEngine.startLockoutTimer(200, mCallback.get());
+ ASSERT_TRUE(mEngine.getLockoutTimerStarted());
+ std::this_thread::sleep_for(std::chrono::milliseconds(210));
+ ASSERT_FALSE(mEngine.getLockoutTimerStarted());
+ ASSERT_TRUE(mCallback->mLockoutCleared);
+}
} // namespace aidl::android::hardware::biometrics::fingerprint
int main(int argc, char** argv) {
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
index 1b071ee..93c6f84 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
@@ -65,11 +65,11 @@
ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kTimed);
// time left
int N = 5;
- int64_t prevTimeLeft = INT_MIN;
+ int64_t prevTimeLeft = INT_MAX;
for (int i = 0; i < N; i++) {
SLEEP_MS(LOCKOUT_TIMED_DURATION / N + 1);
int64_t currTimeLeft = mLockoutTracker.getLockoutTimeLeft();
- ASSERT_TRUE(currTimeLeft > prevTimeLeft);
+ ASSERT_TRUE(currTimeLeft < prevTimeLeft);
prevTimeLeft = currTimeLeft;
}
ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl
index 3298cac..7769b8c 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl
@@ -70,9 +70,9 @@
/**
* Station name.
*
- * This is a generic field to cover any radio technology.
+ * <p>This is a generic field to cover any radio technology.
*
- * If the PROGRAM_NAME has the same content as DAB_*_NAME or RDS_PS,
+ * <p>Note: If the program name has the same content as dab*Name or ({@link Metadata#rdsPs},
* it may not be present, to preserve space - framework must repopulate
* it on the client side.
*/
@@ -86,10 +86,10 @@
/**
* DAB ensemble name abbreviated (string).
*
- * The string must be up to 8 characters long.
+ * <p>Note: The string must be up to 8 characters long.
*
- * If the short variant is present, the long (DAB_ENSEMBLE_NAME) one must be
- * present as well.
+ * <p>Note: If the short variant is present, the long ({@link Metadata#dabEnsembleName})
+ * one must be present as well.
*/
String dabEnsembleNameShort;
@@ -99,7 +99,9 @@
String dabServiceName;
/**
- * DAB service name abbreviated (see DAB_ENSEMBLE_NAME_SHORT) (string)
+ * DAB service name abbreviated (string)
+ *
+ * <p>Note: The string must be up to 8 characters long.
*/
String dabServiceNameShort;
@@ -109,7 +111,9 @@
String dabComponentName;
/**
- * DAB component name abbreviated (see DAB_ENSEMBLE_NAME_SHORT) (string)
+ * DAB component name abbreviated (string)
+ *
+ * <p>Note: The string must be up to 8 characters long.
*/
String dabComponentNameShort;
}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramIdentifier.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramIdentifier.aidl
index 2057d97..a2de5d6 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramIdentifier.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramIdentifier.aidl
@@ -30,8 +30,10 @@
IdentifierType type = IdentifierType.INVALID;
/**
- * The uint64_t value field holds the value in format described in comments
- * for IdentifierType enum.
+ * The value field holds the value in format described in comments for IdentifierType enum.
+ *
+ * The value should be 64-bit unsigned integer, but is represented as 64-bit signed integer
+ * in AIDL.
*/
long value;
}
diff --git a/broadcastradio/aidl/default/VirtualRadio.cpp b/broadcastradio/aidl/default/VirtualRadio.cpp
index 126bcff..86c5a96 100644
--- a/broadcastradio/aidl/default/VirtualRadio.cpp
+++ b/broadcastradio/aidl/default/VirtualRadio.cpp
@@ -53,18 +53,18 @@
static VirtualRadio amFmRadioMock(
"AM/FM radio mock",
{
- {makeSelectorAmfm(/* frequency= */ 94900), "Wild 94.9", "Drake ft. Rihanna",
+ {makeSelectorAmfm(/* frequency= */ 94900u), "Wild 94.9", "Drake ft. Rihanna",
"Too Good"},
- {makeSelectorAmfm(/* frequency= */ 96500), "KOIT", "Celine Dion", "All By Myself"},
- {makeSelectorAmfm(/* frequency= */ 97300), "Alice@97.3", "Drops of Jupiter", "Train"},
- {makeSelectorAmfm(/* frequency= */ 99700), "99.7 Now!", "The Chainsmokers", "Closer"},
- {makeSelectorAmfm(/* frequency= */ 101300), "101-3 KISS-FM", "Justin Timberlake",
+ {makeSelectorAmfm(/* frequency= */ 96500u), "KOIT", "Celine Dion", "All By Myself"},
+ {makeSelectorAmfm(/* frequency= */ 97300u), "Alice@97.3", "Drops of Jupiter", "Train"},
+ {makeSelectorAmfm(/* frequency= */ 99700u), "99.7 Now!", "The Chainsmokers", "Closer"},
+ {makeSelectorAmfm(/* frequency= */ 101300u), "101-3 KISS-FM", "Justin Timberlake",
"Rock Your Body"},
- {makeSelectorAmfm(/* frequency= */ 103700), "iHeart80s @ 103.7", "Michael Jackson",
+ {makeSelectorAmfm(/* frequency= */ 103700u), "iHeart80s @ 103.7", "Michael Jackson",
"Billie Jean"},
- {makeSelectorAmfm(/* frequency= */ 106100), "106 KMEL", "Drake", "Marvins Room"},
- {makeSelectorAmfm(/* frequency= */ 700), "700 AM", "Artist700", "Title700"},
- {makeSelectorAmfm(/* frequency= */ 1700), "1700 AM", "Artist1700", "Title1700"},
+ {makeSelectorAmfm(/* frequency= */ 106100u), "106 KMEL", "Drake", "Marvins Room"},
+ {makeSelectorAmfm(/* frequency= */ 700u), "700 AM", "Artist700", "Title700"},
+ {makeSelectorAmfm(/* frequency= */ 1700u), "1700 AM", "Artist1700", "Title1700"},
});
// clang-format on
return amFmRadioMock;
@@ -77,13 +77,13 @@
"DAB radio mock",
{
{makeSelectorDab(/* sidExt= */ 0xA000000001u, /* ensemble= */ 0x0001u,
- /* freq= */ 225648), "BBC Radio 1", "Khalid", "Talk"},
+ /* freq= */ 225648u), "BBC Radio 1", "Khalid", "Talk"},
{makeSelectorDab(/* sidExt= */ 0xB000000001u, /* ensemble= */ 0x1001u,
- /* freq= */ 222064), "Classic FM", "Jean Sibelius", "Andante Festivo"},
+ /* freq= */ 222064u), "Classic FM", "Jean Sibelius", "Andante Festivo"},
{makeSelectorDab(/* sidExt= */ 0xB000000002u, /* ensemble= */ 0x1002u,
- /* freq= */ 227360), "Absolute Radio", "Coldplay", "Clocks"},
+ /* freq= */ 227360u), "Absolute Radio", "Coldplay", "Clocks"},
{makeSelectorDab(/* sidExt= */ 0xB000000002u, /* ensemble= */ 0x1002u,
- /* freq= */ 222064), "Absolute Radio", "Coldplay", "Clocks"},
+ /* freq= */ 222064u), "Absolute Radio", "Coldplay", "Clocks"},
});
// clang-format on
return dabRadioMock;
diff --git a/broadcastradio/common/utilsaidl/Utils.cpp b/broadcastradio/common/utilsaidl/Utils.cpp
index 0551bad..de4f529 100644
--- a/broadcastradio/common/utilsaidl/Utils.cpp
+++ b/broadcastradio/common/utilsaidl/Utils.cpp
@@ -204,7 +204,7 @@
}
bool isValid(const ProgramIdentifier& id) {
- int64_t val = id.value;
+ uint64_t val = static_cast<uint64_t>(id.value);
bool valid = true;
auto expect = [&valid](bool condition, const string& message) {
@@ -231,11 +231,11 @@
expect(val <= 0xFFFFu, "16bit id");
break;
case IdentifierType::HD_STATION_ID_EXT: {
- int64_t stationId = val & 0xFFFFFFFF; // 32bit
+ uint64_t stationId = val & 0xFFFFFFFF; // 32bit
val >>= 32;
- int64_t subchannel = val & 0xF; // 4bit
+ uint64_t subchannel = val & 0xF; // 4bit
val >>= 4;
- int64_t freq = val & 0x3FFFF; // 18bit
+ uint64_t freq = val & 0x3FFFF; // 18bit
expect(stationId != 0u, "HD station id != 0");
expect(subchannel < 8u, "HD subch < 8");
expect(freq > 100u, "f > 100kHz");
@@ -252,9 +252,9 @@
break;
}
case IdentifierType::DAB_SID_EXT: {
- int64_t sid = val & 0xFFFFFFFF; // 32bit
+ uint64_t sid = val & 0xFFFFFFFF; // 32bit
val >>= 32;
- int64_t ecc = val & 0xFF; // 8bit
+ uint64_t ecc = val & 0xFF; // 8bit
expect(sid != 0u, "DAB SId != 0");
expect(ecc >= 0xA0u && ecc <= 0xF6u, "Invalid ECC, see ETSI TS 101 756 V2.1.1");
break;
@@ -305,19 +305,19 @@
return {type, value};
}
-ProgramSelector makeSelectorAmfm(int32_t frequency) {
+ProgramSelector makeSelectorAmfm(uint32_t frequency) {
ProgramSelector sel = {};
sel.primaryId = makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, frequency);
return sel;
}
-ProgramSelector makeSelectorDab(int64_t sidExt) {
+ProgramSelector makeSelectorDab(uint64_t sidExt) {
ProgramSelector sel = {};
sel.primaryId = makeIdentifier(IdentifierType::DAB_SID_EXT, sidExt);
return sel;
}
-ProgramSelector makeSelectorDab(int64_t sidExt, int32_t ensemble, int64_t freq) {
+ProgramSelector makeSelectorDab(uint64_t sidExt, uint32_t ensemble, uint64_t freq) {
ProgramSelector sel = {};
sel.primaryId = makeIdentifier(IdentifierType::DAB_SID_EXT, sidExt);
vector<ProgramIdentifier> secondaryIds = {
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
index ad075f2..ee85a17 100644
--- a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
@@ -137,9 +137,9 @@
bool isValid(const ProgramSelector& sel);
ProgramIdentifier makeIdentifier(IdentifierType type, int64_t value);
-ProgramSelector makeSelectorAmfm(int32_t frequency);
-ProgramSelector makeSelectorDab(int64_t sidExt);
-ProgramSelector makeSelectorDab(int64_t sidExt, int32_t ensemble, int64_t freq);
+ProgramSelector makeSelectorAmfm(uint32_t frequency);
+ProgramSelector makeSelectorDab(uint64_t sidExt);
+ProgramSelector makeSelectorDab(uint64_t sidExt, uint32_t ensemble, uint64_t freq);
bool satisfies(const ProgramFilter& filter, const ProgramSelector& sel);
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml
index 83d2665..523d8de 100644
--- a/compatibility_matrices/compatibility_matrix.9.xml
+++ b/compatibility_matrices/compatibility_matrix.9.xml
@@ -574,6 +574,14 @@
</interface>
</hal>
<hal format="aidl" optional="true">
+ <name>android.hardware.threadnetwork</name>
+ <version>1</version>
+ <interface>
+ <name>IThreadChip</name>
+ <instance>chip0</instance>
+ </interface>
+ </hal>
+ <hal format="aidl" optional="true">
<name>android.hardware.tv.hdmi.cec</name>
<version>1</version>
<interface>
diff --git a/drm/aidl/Android.bp b/drm/aidl/Android.bp
index fb04d84..afcb603 100644
--- a/drm/aidl/Android.bp
+++ b/drm/aidl/Android.bp
@@ -23,7 +23,7 @@
sdk_version: "module_current",
},
ndk: {
- min_sdk_version: "UpsideDownCake",
+ min_sdk_version: "34",
},
},
double_loadable: true,
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index 4f5e6a0..5e2cbe3 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -486,8 +486,6 @@
auto status = aidl_gnss_hal_->startSvStatus();
EXPECT_TRUE(status.isOk());
- ASSERT_TRUE(aidl_gnss_cb_->sv_info_list_timestamps_millis_cbq_.size() ==
- aidl_gnss_cb_->sv_info_list_cbq_.size());
long lastElapsedRealtimeMillis = 0;
for (int i = 0; i < numMeasurementEvents; i++) {
long timeStamp;
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index 7bc2eeb..83e1193 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -887,6 +887,15 @@
return true;
}
+StaLinkLayerLinkStats::StaLinkState convertLegacyMlLinkStateToAidl(wifi_link_state state) {
+ if (state == wifi_link_state::WIFI_LINK_STATE_NOT_IN_USE) {
+ return StaLinkLayerLinkStats::StaLinkState::NOT_IN_USE;
+ } else if (state == wifi_link_state::WIFI_LINK_STATE_IN_USE) {
+ return StaLinkLayerLinkStats::StaLinkState::IN_USE;
+ }
+ return StaLinkLayerLinkStats::StaLinkState::UNKNOWN;
+}
+
bool convertLegacyLinkLayerMlStatsToAidl(const legacy_hal::LinkLayerMlStats& legacy_ml_stats,
StaLinkLayerStats* aidl_stats) {
if (!aidl_stats) {
@@ -898,6 +907,7 @@
for (const auto& link : legacy_ml_stats.links) {
StaLinkLayerLinkStats linkStats = {};
linkStats.linkId = link.stat.link_id;
+ linkStats.state = convertLegacyMlLinkStateToAidl(link.stat.state);
linkStats.radioId = link.stat.radio;
linkStats.frequencyMhz = link.stat.frequency;
linkStats.beaconRx = link.stat.beacon_rx;
diff --git a/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
index 5c334f8..995a13d 100644
--- a/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
+++ b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
@@ -123,6 +123,9 @@
// Add two radio stats
legacy_ml_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
legacy_ml_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+ wifi_link_state states[sizeof(wifi_link_state)] = {wifi_link_state::WIFI_LINK_STATE_UNKNOWN,
+ wifi_link_state::WIFI_LINK_STATE_NOT_IN_USE,
+ wifi_link_state::WIFI_LINK_STATE_IN_USE};
// Add two links.
legacy_ml_stats.links.push_back(legacy_hal::LinkStats{});
legacy_ml_stats.links.push_back(legacy_hal::LinkStats{});
@@ -133,6 +136,7 @@
link.stat.beacon_rx = rand();
// MLO link id: 0 - 15
link.stat.link_id = rand() % 16;
+ link.stat.state = states[rand() % sizeof(states)];
// Maximum number of radios is limited to 3 for testing.
link.stat.radio = rand() % 4;
link.stat.frequency = rand();
@@ -241,6 +245,18 @@
int l = 0;
for (legacy_hal::LinkStats& link : legacy_ml_stats.links) {
EXPECT_EQ(link.stat.link_id, (uint8_t)converted.iface.links[l].linkId);
+ StaLinkLayerLinkStats::StaLinkState expectedState;
+ switch (link.stat.state) {
+ case wifi_link_state::WIFI_LINK_STATE_NOT_IN_USE:
+ expectedState = StaLinkLayerLinkStats::StaLinkState::NOT_IN_USE;
+ break;
+ case wifi_link_state::WIFI_LINK_STATE_IN_USE:
+ expectedState = StaLinkLayerLinkStats::StaLinkState::IN_USE;
+ break;
+ default:
+ expectedState = StaLinkLayerLinkStats::StaLinkState::UNKNOWN;
+ }
+ EXPECT_EQ(expectedState, converted.iface.links[l].state);
EXPECT_EQ(link.stat.radio, converted.iface.links[l].radioId);
EXPECT_EQ(link.stat.frequency, (uint32_t)converted.iface.links[l].frequencyMhz);
EXPECT_EQ(link.stat.beacon_rx, (uint32_t)converted.iface.links[l].beaconRx);
diff --git a/wifi/aidl/default/wifi_chip.cpp b/wifi/aidl/default/wifi_chip.cpp
index 6dd9156..8265e5b 100644
--- a/wifi/aidl/default/wifi_chip.cpp
+++ b/wifi/aidl/default/wifi_chip.cpp
@@ -1452,14 +1452,24 @@
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to get SupportedRadioCombinations matrix from legacy HAL: "
<< legacyErrorToString(legacy_status);
+ if (legacy_matrix != nullptr) {
+ free(legacy_matrix);
+ }
return {aidl_combinations, createWifiStatusFromLegacyError(legacy_status)};
}
if (!aidl_struct_util::convertLegacyRadioCombinationsMatrixToAidl(legacy_matrix,
&aidl_combinations)) {
LOG(ERROR) << "Failed convertLegacyRadioCombinationsMatrixToAidl() ";
+ if (legacy_matrix != nullptr) {
+ free(legacy_matrix);
+ }
return {aidl_combinations, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
}
+
+ if (legacy_matrix != nullptr) {
+ free(legacy_matrix);
+ }
return {aidl_combinations, ndk::ScopedAStatus::ok()};
}