Merge "Amend tests on GSI that rely on RKP-only props" into main
diff --git a/Android.bp b/Android.bp
index baf3291..223a1a9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -51,6 +51,7 @@
// Lists all dependencies that can *not* be expected on the device.
static_libs: [
"VtsHalHidlTestUtils",
+ "libhidlbase",
"libhidl-gen-utils",
],
@@ -63,7 +64,6 @@
"libbase",
// All the following are dependencies of any HAL definition library.
"libcutils",
- "libhidlbase",
"liblog",
"libutils",
],
@@ -72,6 +72,14 @@
"-g",
],
+ target: {
+ android: {
+ shared_libs: [
+ "libvndksupport",
+ ],
+ },
+ },
+
require_root: true,
}
diff --git a/audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml b/audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml
index c92e852..4170b4c 100644
--- a/audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml
+++ b/audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml
@@ -33,6 +33,6 @@
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
<option name="module-name" value="{MODULE}" />
- <option name="native-test-timeout" value="10m" />
+ <option name="native-test-timeout" value="30m" />
</test>
</configuration>
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index 82a194e..e31aae6 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -353,8 +353,14 @@
mInput.resize(kBufferSize);
generateSineWaveInput(mInput);
}
- void SetUp() override { SetUpReverb(); }
- void TearDown() override { TearDownReverb(); }
+ void SetUp() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ SetUpReverb();
+ }
+ void TearDown() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ TearDownReverb();
+ }
void assertEnergyIncreasingWithParameter(bool bypass) {
createEnvParam(EnvironmentalReverb::bypass, bypass);
@@ -418,12 +424,16 @@
std::tie(mTag, mValue) = std::get<TAG_VALUE_PAIR>(GetParam());
}
void SetUp() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
SetUpReverb();
createEnvParam(EnvironmentalReverb::roomLevelMb, kMinRoomLevel);
ASSERT_NO_FATAL_FAILURE(
setAndVerifyParam(EX_NONE, mEnvParam, EnvironmentalReverb::roomLevelMb));
}
- void TearDown() override { TearDownReverb(); }
+ void TearDown() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ TearDownReverb();
+ }
EnvironmentalReverb::Tag mTag;
int mValue;
@@ -469,8 +479,14 @@
mInput.resize(kBufferSize);
generateSineWaveInput(mInput);
}
- void SetUp() override { SetUpReverb(); }
- void TearDown() override { TearDownReverb(); }
+ void SetUp() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ SetUpReverb();
+ }
+ void TearDown() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ TearDownReverb();
+ }
float getMean(std::vector<float>& buffer) {
return std::accumulate(buffer.begin(), buffer.end(), 0.0) / buffer.size();
@@ -543,8 +559,14 @@
generateSineWaveInput(mInput);
}
}
- void SetUp() override { SetUpReverb(); }
- void TearDown() override { TearDownReverb(); }
+ void SetUp() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ SetUpReverb();
+ }
+ void TearDown() override {
+ SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+ TearDownReverb();
+ }
EnvironmentalReverb::Tag mTag;
int mParamValues;
diff --git a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
index 477de31..dc78ed6 100644
--- a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
+++ b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
@@ -317,12 +317,20 @@
// Verify methods for extended info
const auto id = 0xFFFFFFFF; // meaningless id
std::vector<uint8_t> values;
+ bool isSupported = false;
auto status = pCam->setExtendedInfo(id, values);
if (isLogicalCam) {
EXPECT_TRUE(!status.isOk() && status.getServiceSpecificError() ==
static_cast<int>(EvsResult::NOT_SUPPORTED));
} else {
- EXPECT_TRUE(status.isOk());
+ if (status.isOk()) {
+ // 0xFFFFFFFF is valid for EVS HAL implementation under
+ // test.
+ isSupported = true;
+ } else {
+ EXPECT_TRUE(status.getServiceSpecificError() ==
+ static_cast<int>(EvsResult::INVALID_ARG));
+ }
}
status = pCam->getExtendedInfo(id, &values);
@@ -330,7 +338,12 @@
EXPECT_TRUE(!status.isOk() && status.getServiceSpecificError() ==
static_cast<int>(EvsResult::NOT_SUPPORTED));
} else {
- EXPECT_TRUE(status.isOk());
+ if (isSupported) {
+ EXPECT_TRUE(status.isOk());
+ } else {
+ EXPECT_TRUE(!status.isOk() && status.getServiceSpecificError() ==
+ static_cast<int>(EvsResult::INVALID_ARG));
+ }
}
// Explicitly close the camera so resources are released right away
diff --git a/automotive/vehicle/TEST_MAPPING b/automotive/vehicle/TEST_MAPPING
index 77629a9..d848774 100644
--- a/automotive/vehicle/TEST_MAPPING
+++ b/automotive/vehicle/TEST_MAPPING
@@ -45,6 +45,9 @@
"name": "FakeVehicleHardwareTest"
},
{
+ "name": "GRPCVehicleHardwareUnitTest"
+ },
+ {
"name": "CarServiceUnitTest",
"options" : [
{
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
index f44573a..73bb521 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
@@ -20,6 +20,7 @@
#include <android-base/logging.h>
#include <grpc++/grpc++.h>
+#include <utils/SystemClock.h>
#include <cstdlib>
#include <mutex>
@@ -28,11 +29,16 @@
namespace android::hardware::automotive::vehicle::virtualization {
-static std::shared_ptr<::grpc::ChannelCredentials> getChannelCredentials() {
- // TODO(chenhaosjtuacm): get secured credentials here
+namespace {
+
+constexpr size_t MAX_RETRY_COUNT = 5;
+
+std::shared_ptr<::grpc::ChannelCredentials> getChannelCredentials() {
return ::grpc::InsecureChannelCredentials();
}
+} // namespace
+
GRPCVehicleHardware::GRPCVehicleHardware(std::string service_addr)
: mServiceAddr(std::move(service_addr)),
mGrpcChannel(::grpc::CreateChannel(mServiceAddr, getChannelCredentials())),
@@ -40,11 +46,13 @@
mValuePollingThread([this] { ValuePollingLoop(); }) {}
// Only used for unit testing.
-GRPCVehicleHardware::GRPCVehicleHardware(std::unique_ptr<proto::VehicleServer::StubInterface> stub)
- : mServiceAddr(""),
- mGrpcChannel(nullptr),
- mGrpcStub(std::move(stub)),
- mValuePollingThread([] {}) {}
+GRPCVehicleHardware::GRPCVehicleHardware(std::unique_ptr<proto::VehicleServer::StubInterface> stub,
+ bool startValuePollingLoop)
+ : mServiceAddr(""), mGrpcChannel(nullptr), mGrpcStub(std::move(stub)) {
+ if (startValuePollingLoop) {
+ mValuePollingThread = std::thread([this] { ValuePollingLoop(); });
+ }
+}
GRPCVehicleHardware::~GRPCVehicleHardware() {
{
@@ -52,7 +60,9 @@
mShuttingDownFlag.store(true);
}
mShutdownCV.notify_all();
- mValuePollingThread.join();
+ if (mValuePollingThread.joinable()) {
+ mValuePollingThread.join();
+ }
}
std::vector<aidlvhal::VehiclePropConfig> GRPCVehicleHardware::getAllPropertyConfigs() const {
@@ -109,36 +119,117 @@
aidlvhal::StatusCode GRPCVehicleHardware::getValues(
std::shared_ptr<const GetValuesCallback> callback,
const std::vector<aidlvhal::GetValueRequest>& requests) const {
- ::grpc::ClientContext context;
+ std::vector<aidlvhal::GetValueResult> results;
+ auto status = getValuesWithRetry(requests, &results, /*retryCount=*/0);
+ if (status != aidlvhal::StatusCode::OK) {
+ return status;
+ }
+ if (!results.empty()) {
+ (*callback)(std::move(results));
+ }
+ return status;
+}
+
+aidlvhal::StatusCode GRPCVehicleHardware::getValuesWithRetry(
+ const std::vector<aidlvhal::GetValueRequest>& requests,
+ std::vector<aidlvhal::GetValueResult>* results, size_t retryCount) const {
+ if (retryCount == MAX_RETRY_COUNT) {
+ LOG(ERROR) << __func__ << ": GRPC GetValues Failed, failed to get the latest value after "
+ << retryCount << " retries";
+ return aidlvhal::StatusCode::TRY_AGAIN;
+ }
+
proto::VehiclePropValueRequests protoRequests;
- proto::GetValueResults protoResults;
+ std::unordered_map<int64_t, const aidlvhal::GetValueRequest*> requestById;
for (const auto& request : requests) {
auto& protoRequest = *protoRequests.add_requests();
protoRequest.set_request_id(request.requestId);
proto_msg_converter::aidlToProto(request.prop, protoRequest.mutable_value());
+ requestById[request.requestId] = &request;
}
+
// TODO(chenhaosjtuacm): Make it Async.
+ ::grpc::ClientContext context;
+ proto::GetValueResults protoResults;
auto grpc_status = mGrpcStub->GetValues(&context, protoRequests, &protoResults);
if (!grpc_status.ok()) {
LOG(ERROR) << __func__ << ": GRPC GetValues Failed: " << grpc_status.error_message();
return aidlvhal::StatusCode::INTERNAL_ERROR;
}
- std::vector<aidlvhal::GetValueResult> results;
+
+ std::vector<aidlvhal::GetValueRequest> retryRequests;
for (const auto& protoResult : protoResults.results()) {
- auto& result = results.emplace_back();
- result.requestId = protoResult.request_id();
- result.status = static_cast<aidlvhal::StatusCode>(protoResult.status());
- if (protoResult.has_value()) {
- aidlvhal::VehiclePropValue value;
- proto_msg_converter::protoToAidl(protoResult.value(), &value);
- result.prop = std::move(value);
+ int64_t requestId = protoResult.request_id();
+ auto it = requestById.find(requestId);
+ if (it == requestById.end()) {
+ LOG(ERROR) << __func__
+ << "Invalid getValue request with unknown request ID: " << requestId
+ << ", ignore";
+ continue;
}
+
+ if (!protoResult.has_value()) {
+ auto& result = results->emplace_back();
+ result.requestId = requestId;
+ result.status = static_cast<aidlvhal::StatusCode>(protoResult.status());
+ continue;
+ }
+
+ aidlvhal::VehiclePropValue value;
+ proto_msg_converter::protoToAidl(protoResult.value(), &value);
+
+ // VHAL proxy server uses a different timestamp then AAOS timestamp, so we have to reset
+ // the timestamp.
+ // TODO(b/350822044): Remove this once we use timestamp from proxy server.
+ if (!setAndroidTimestamp(&value)) {
+ // This is a rare case when we receive a property update event reflecting a new value
+ // for the property before we receive the get value result. This means that the result
+ // is already outdated, hence we should retry getting the latest value again.
+ LOG(WARNING) << __func__ << "getValue result for propId: " << value.prop
+ << " areaId: " << value.areaId << " is oudated, retry";
+ retryRequests.push_back(*(it->second));
+ continue;
+ }
+
+ auto& result = results->emplace_back();
+ result.requestId = requestId;
+ result.status = static_cast<aidlvhal::StatusCode>(protoResult.status());
+ result.prop = std::move(value);
}
- (*callback)(std::move(results));
+
+ if (retryRequests.size() != 0) {
+ return getValuesWithRetry(retryRequests, results, retryCount++);
+ }
return aidlvhal::StatusCode::OK;
}
+bool GRPCVehicleHardware::setAndroidTimestamp(aidlvhal::VehiclePropValue* propValue) const {
+ PropIdAreaId propIdAreaId = {
+ .propId = propValue->prop,
+ .areaId = propValue->areaId,
+ };
+ int64_t now = elapsedRealtimeNano();
+ int64_t externalTimestamp = propValue->timestamp;
+
+ {
+ std::lock_guard lck(mLatestUpdateTimestampsMutex);
+ auto it = mLatestUpdateTimestamps.find(propIdAreaId);
+ if (it == mLatestUpdateTimestamps.end() || externalTimestamp > (it->second).first) {
+ mLatestUpdateTimestamps[propIdAreaId].first = externalTimestamp;
+ mLatestUpdateTimestamps[propIdAreaId].second = now;
+ propValue->timestamp = now;
+ return true;
+ }
+ if (externalTimestamp == (it->second).first) {
+ propValue->timestamp = (it->second).second;
+ return true;
+ }
+ }
+ // externalTimestamp < (it->second).first, the value is outdated.
+ return false;
+}
+
void GRPCVehicleHardware::registerOnPropertyChangeEvent(
std::unique_ptr<const PropertyChangeCallback> callback) {
std::lock_guard lck(mCallbackMutex);
@@ -248,46 +339,61 @@
void GRPCVehicleHardware::ValuePollingLoop() {
while (!mShuttingDownFlag.load()) {
- ::grpc::ClientContext context;
-
- bool rpc_stopped{false};
- std::thread shuttingdown_watcher([this, &rpc_stopped, &context]() {
- std::unique_lock<std::mutex> lck(mShutdownMutex);
- mShutdownCV.wait(lck, [this, &rpc_stopped]() {
- return rpc_stopped || mShuttingDownFlag.load();
- });
- context.TryCancel();
- });
-
- auto value_stream =
- mGrpcStub->StartPropertyValuesStream(&context, ::google::protobuf::Empty());
- LOG(INFO) << __func__ << ": GRPC Value Streaming Started";
- proto::VehiclePropValues protoValues;
- while (!mShuttingDownFlag.load() && value_stream->Read(&protoValues)) {
- std::vector<aidlvhal::VehiclePropValue> values;
- for (const auto protoValue : protoValues.values()) {
- values.push_back(aidlvhal::VehiclePropValue());
- proto_msg_converter::protoToAidl(protoValue, &values.back());
- }
- std::shared_lock lck(mCallbackMutex);
- if (mOnPropChange) {
- (*mOnPropChange)(values);
- }
- }
-
- {
- std::lock_guard lck(mShutdownMutex);
- rpc_stopped = true;
- }
- mShutdownCV.notify_all();
- shuttingdown_watcher.join();
-
- auto grpc_status = value_stream->Finish();
- // never reach here until connection lost
- LOG(ERROR) << __func__ << ": GRPC Value Streaming Failed: " << grpc_status.error_message();
-
+ pollValue();
// try to reconnect
}
}
+void GRPCVehicleHardware::pollValue() {
+ ::grpc::ClientContext context;
+
+ bool rpc_stopped{false};
+ std::thread shuttingdown_watcher([this, &rpc_stopped, &context]() {
+ std::unique_lock<std::mutex> lck(mShutdownMutex);
+ mShutdownCV.wait(
+ lck, [this, &rpc_stopped]() { return rpc_stopped || mShuttingDownFlag.load(); });
+ context.TryCancel();
+ });
+
+ auto value_stream = mGrpcStub->StartPropertyValuesStream(&context, ::google::protobuf::Empty());
+ LOG(INFO) << __func__ << ": GRPC Value Streaming Started";
+ proto::VehiclePropValues protoValues;
+ while (!mShuttingDownFlag.load() && value_stream->Read(&protoValues)) {
+ std::vector<aidlvhal::VehiclePropValue> values;
+ for (const auto protoValue : protoValues.values()) {
+ aidlvhal::VehiclePropValue aidlValue = {};
+ proto_msg_converter::protoToAidl(protoValue, &aidlValue);
+
+ // VHAL proxy server uses a different timestamp then AAOS timestamp, so we have to
+ // reset the timestamp.
+ // TODO(b/350822044): Remove this once we use timestamp from proxy server.
+ if (!setAndroidTimestamp(&aidlValue)) {
+ LOG(WARNING) << __func__ << ": property event for propId: " << aidlValue.prop
+ << " areaId: " << aidlValue.areaId << " is outdated, ignore";
+ continue;
+ }
+
+ values.push_back(std::move(aidlValue));
+ }
+ if (values.empty()) {
+ continue;
+ }
+ std::shared_lock lck(mCallbackMutex);
+ if (mOnPropChange) {
+ (*mOnPropChange)(values);
+ }
+ }
+
+ {
+ std::lock_guard lck(mShutdownMutex);
+ rpc_stopped = true;
+ }
+ mShutdownCV.notify_all();
+ shuttingdown_watcher.join();
+
+ auto grpc_status = value_stream->Finish();
+ // never reach here until connection lost
+ LOG(ERROR) << __func__ << ": GRPC Value Streaming Failed: " << grpc_status.error_message();
+}
+
} // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
index 9750f62..1edf658 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
@@ -20,6 +20,7 @@
#include <VehicleHalTypes.h>
#include <VehicleUtils.h>
#include <android-base/result.h>
+#include <android-base/thread_annotations.h>
#include "VehicleServer.grpc.pb.h"
#include "VehicleServer.pb.h"
@@ -33,6 +34,7 @@
#include <shared_mutex>
#include <string>
#include <thread>
+#include <unordered_map>
#include <vector>
namespace android::hardware::automotive::vehicle::virtualization {
@@ -43,9 +45,6 @@
public:
explicit GRPCVehicleHardware(std::string service_addr);
- // Only used for unit testing.
- explicit GRPCVehicleHardware(std::unique_ptr<proto::VehicleServer::StubInterface> stub);
-
~GRPCVehicleHardware();
// Get all the property configs.
@@ -94,7 +93,7 @@
std::unique_ptr<const PropertyChangeCallback> mOnPropChange;
private:
- void ValuePollingLoop();
+ friend class GRPCVehicleHardwareUnitTest;
std::string mServiceAddr;
std::shared_ptr<::grpc::Channel> mGrpcChannel;
@@ -106,6 +105,31 @@
std::mutex mShutdownMutex;
std::condition_variable mShutdownCV;
std::atomic<bool> mShuttingDownFlag{false};
+
+ mutable std::mutex mLatestUpdateTimestampsMutex;
+
+ // A map from [propId, areaId] to the latest timestamp this property is updated.
+ // The key is a tuple, the first element is the external timestamp (timestamp set by VHAL
+ // server), the second element is the Android timestamp (elapsedRealtimeNano).
+ mutable std::unordered_map<PropIdAreaId, std::pair<int64_t, int64_t>,
+ PropIdAreaIdHash> mLatestUpdateTimestamps
+ GUARDED_BY(mLatestUpdateTimestampsMutex);
+
+ // Only used for unit testing.
+ GRPCVehicleHardware(std::unique_ptr<proto::VehicleServer::StubInterface> stub,
+ bool startValuePollingLoop);
+
+ void ValuePollingLoop();
+ void pollValue();
+
+ aidlvhal::StatusCode getValuesWithRetry(const std::vector<aidlvhal::GetValueRequest>& requests,
+ std::vector<aidlvhal::GetValueResult>* results,
+ size_t retryCount) const;
+
+ // Check the external timestamp of propValue against the latest updated external timestamp, if
+ // this is an outdated value, return false. Otherwise, update the external timestamp to the
+ // Android timestamp and return true.
+ bool setAndroidTimestamp(aidlvhal::VehiclePropValue* propValue) const;
};
} // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
index eb98af0..d7cbe1b 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
@@ -69,10 +69,13 @@
const proto::VehiclePropValueRequests* requests,
proto::SetValueResults* results) {
std::vector<aidlvhal::SetValueRequest> aidlRequests;
+ std::unordered_set<int64_t> requestIds;
for (const auto& protoRequest : requests->requests()) {
auto& aidlRequest = aidlRequests.emplace_back();
- aidlRequest.requestId = protoRequest.request_id();
+ int64_t requestId = protoRequest.request_id();
+ aidlRequest.requestId = requestId;
proto_msg_converter::protoToAidl(protoRequest.value(), &aidlRequest.value);
+ requestIds.insert(requestId);
}
auto waitMtx = std::make_shared<std::mutex>();
auto waitCV = std::make_shared<std::condition_variable>();
@@ -80,19 +83,27 @@
auto tmpResults = std::make_shared<proto::SetValueResults>();
auto aidlStatus = mHardware->setValues(
std::make_shared<const IVehicleHardware::SetValuesCallback>(
- [waitMtx, waitCV, complete,
- tmpResults](std::vector<aidlvhal::SetValueResult> setValueResults) {
- for (const auto& aidlResult : setValueResults) {
- auto& protoResult = *tmpResults->add_results();
- protoResult.set_request_id(aidlResult.requestId);
- protoResult.set_status(
- static_cast<proto::StatusCode>(aidlResult.status));
- }
+ [waitMtx, waitCV, complete, tmpResults,
+ &requestIds](std::vector<aidlvhal::SetValueResult> setValueResults) {
+ bool receivedAllResults = false;
{
std::lock_guard lck(*waitMtx);
- *complete = true;
+ for (const auto& aidlResult : setValueResults) {
+ auto& protoResult = *tmpResults->add_results();
+ int64_t requestIdForResult = aidlResult.requestId;
+ protoResult.set_request_id(requestIdForResult);
+ protoResult.set_status(
+ static_cast<proto::StatusCode>(aidlResult.status));
+ requestIds.erase(requestIdForResult);
+ }
+ if (requestIds.empty()) {
+ receivedAllResults = true;
+ *complete = true;
+ }
}
- waitCV->notify_all();
+ if (receivedAllResults) {
+ waitCV->notify_all();
+ }
}),
aidlRequests);
if (aidlStatus != aidlvhal::StatusCode::OK) {
@@ -114,10 +125,13 @@
const proto::VehiclePropValueRequests* requests,
proto::GetValueResults* results) {
std::vector<aidlvhal::GetValueRequest> aidlRequests;
+ std::unordered_set<int64_t> requestIds;
for (const auto& protoRequest : requests->requests()) {
auto& aidlRequest = aidlRequests.emplace_back();
- aidlRequest.requestId = protoRequest.request_id();
+ int64_t requestId = protoRequest.request_id();
+ aidlRequest.requestId = requestId;
proto_msg_converter::protoToAidl(protoRequest.value(), &aidlRequest.prop);
+ requestIds.insert(requestId);
}
auto waitMtx = std::make_shared<std::mutex>();
auto waitCV = std::make_shared<std::condition_variable>();
@@ -125,23 +139,31 @@
auto tmpResults = std::make_shared<proto::GetValueResults>();
auto aidlStatus = mHardware->getValues(
std::make_shared<const IVehicleHardware::GetValuesCallback>(
- [waitMtx, waitCV, complete,
- tmpResults](std::vector<aidlvhal::GetValueResult> getValueResults) {
- for (const auto& aidlResult : getValueResults) {
- auto& protoResult = *tmpResults->add_results();
- protoResult.set_request_id(aidlResult.requestId);
- protoResult.set_status(
- static_cast<proto::StatusCode>(aidlResult.status));
- if (aidlResult.prop) {
- auto* valuePtr = protoResult.mutable_value();
- proto_msg_converter::aidlToProto(*aidlResult.prop, valuePtr);
- }
- }
+ [waitMtx, waitCV, complete, tmpResults,
+ &requestIds](std::vector<aidlvhal::GetValueResult> getValueResults) {
+ bool receivedAllResults = false;
{
std::lock_guard lck(*waitMtx);
- *complete = true;
+ for (const auto& aidlResult : getValueResults) {
+ auto& protoResult = *tmpResults->add_results();
+ int64_t requestIdForResult = aidlResult.requestId;
+ protoResult.set_request_id(requestIdForResult);
+ protoResult.set_status(
+ static_cast<proto::StatusCode>(aidlResult.status));
+ if (aidlResult.prop) {
+ auto* valuePtr = protoResult.mutable_value();
+ proto_msg_converter::aidlToProto(*aidlResult.prop, valuePtr);
+ }
+ requestIds.erase(requestIdForResult);
+ }
+ if (requestIds.empty()) {
+ receivedAllResults = true;
+ *complete = true;
+ }
}
- waitCV->notify_all();
+ if (receivedAllResults) {
+ waitCV->notify_all();
+ }
}),
aidlRequests);
if (aidlStatus != aidlvhal::StatusCode::OK) {
diff --git a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp
index 3bd7e0e..20af231 100644
--- a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp
@@ -19,8 +19,10 @@
#include <gmock/gmock.h>
#include <grpc++/grpc++.h>
+#include <grpcpp/test/mock_stream.h>
#include <gtest/gtest.h>
+#include <utils/SystemClock.h>
#include <chrono>
#include <memory>
#include <string>
@@ -31,98 +33,48 @@
using ::testing::_;
using ::testing::DoAll;
+using ::testing::ElementsAre;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::SetArgPointee;
+using ::testing::SizeIs;
+
+using ::grpc::testing::MockClientReader;
using proto::MockVehicleServerStub;
-const std::string kFakeServerAddr = "0.0.0.0:54321";
-
-class FakeVehicleServer : public proto::VehicleServer::Service {
- public:
- ::grpc::Status StartPropertyValuesStream(
- ::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
- ::grpc::ServerWriter<proto::VehiclePropValues>* stream) override {
- stream->Write(proto::VehiclePropValues());
- // A fake disconnection.
- return ::grpc::Status(::grpc::StatusCode::ABORTED, "Connection lost.");
- }
-
- // Functions that we do not care.
- ::grpc::Status GetAllPropertyConfig(
- ::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
- ::grpc::ServerWriter<proto::VehiclePropConfig>* stream) override {
- return ::grpc::Status::OK;
- }
-
- ::grpc::Status SetValues(::grpc::ServerContext* context,
- const proto::VehiclePropValueRequests* requests,
- proto::SetValueResults* results) override {
- return ::grpc::Status::OK;
- }
-
- ::grpc::Status GetValues(::grpc::ServerContext* context,
- const proto::VehiclePropValueRequests* requests,
- proto::GetValueResults* results) override {
- return ::grpc::Status::OK;
- }
-};
-
-TEST(GRPCVehicleHardwareUnitTest, Reconnect) {
- auto receivedUpdate = std::make_shared<std::atomic<int>>(0);
- auto vehicleHardware = std::make_unique<GRPCVehicleHardware>(kFakeServerAddr);
- vehicleHardware->registerOnPropertyChangeEvent(
- std::make_unique<const IVehicleHardware::PropertyChangeCallback>(
- [receivedUpdate](const auto&) { receivedUpdate->fetch_add(1); }));
-
- constexpr size_t kServerRestartTimes = 5;
- for (size_t serverStart = 0; serverStart < kServerRestartTimes; ++serverStart) {
- EXPECT_EQ(receivedUpdate->load(), 0);
- auto fakeServer = std::make_unique<FakeVehicleServer>();
- ::grpc::ServerBuilder builder;
- builder.RegisterService(fakeServer.get());
- builder.AddListeningPort(kFakeServerAddr, ::grpc::InsecureServerCredentials());
- auto grpcServer = builder.BuildAndStart();
-
- // Wait until the vehicle hardware received the second update (after one fake
- // disconnection).
- constexpr auto kMaxWaitTime = std::chrono::seconds(5);
- auto startTime = std::chrono::steady_clock::now();
- while (receivedUpdate->load() <= 1 &&
- std::chrono::steady_clock::now() - startTime < kMaxWaitTime)
- ;
-
- grpcServer->Shutdown();
- grpcServer->Wait();
- EXPECT_GT(receivedUpdate->load(), 1);
-
- // Reset for the next round.
- receivedUpdate->store(0);
- }
-}
-
-class GRPCVehicleHardwareMockServerUnitTest : public ::testing::Test {
+class GRPCVehicleHardwareUnitTest : public ::testing::Test {
protected:
NiceMock<MockVehicleServerStub>* mGrpcStub;
std::unique_ptr<GRPCVehicleHardware> mHardware;
void SetUp() override {
auto stub = std::make_unique<NiceMock<MockVehicleServerStub>>();
- ;
mGrpcStub = stub.get();
- mHardware = std::make_unique<GRPCVehicleHardware>(std::move(stub));
+ // Cannot use make_unique here since the constructor is a private method.
+ mHardware = std::unique_ptr<GRPCVehicleHardware>(
+ new GRPCVehicleHardware(std::move(stub), /*startValuePollingLoop=*/false));
}
void TearDown() override { mHardware.reset(); }
+
+ // Access GRPCVehicleHardware private method.
+ void pollValue() { mHardware->pollValue(); }
+
+ void startValuePollingLoop(std::unique_ptr<proto::VehicleServer::StubInterface> stub) {
+ mHardware = std::unique_ptr<GRPCVehicleHardware>(
+ new GRPCVehicleHardware(std::move(stub), /*startValuePollingLoop=*/true));
+ }
+
+ void generatePropertyUpdateEvent(int32_t propId, int64_t timestamp);
};
MATCHER_P(RepeatedInt32Eq, expected_values, "") {
return std::vector<int32_t>(arg.begin(), arg.end()) == expected_values;
}
-TEST_F(GRPCVehicleHardwareMockServerUnitTest, Subscribe) {
+TEST_F(GRPCVehicleHardwareUnitTest, TestSubscribe) {
proto::VehicleHalCallStatus protoStatus;
protoStatus.set_status_code(proto::StatusCode::OK);
proto::SubscribeRequest actualRequest;
@@ -147,7 +99,7 @@
EXPECT_EQ(protoOptions.enable_variable_update_rate(), true);
}
-TEST_F(GRPCVehicleHardwareMockServerUnitTest, SubscribeLegacyServer) {
+TEST_F(GRPCVehicleHardwareUnitTest, TestSubscribeLegacyServer) {
EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _))
.WillOnce(Return(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")));
@@ -157,7 +109,7 @@
EXPECT_EQ(status, aidlvhal::StatusCode::OK);
}
-TEST_F(GRPCVehicleHardwareMockServerUnitTest, SubscribeGrpcFailure) {
+TEST_F(GRPCVehicleHardwareUnitTest, TestSubscribeGrpcFailure) {
EXPECT_CALL(*mGrpcStub, Subscribe(_, _, _))
.WillOnce(Return(::grpc::Status(::grpc::StatusCode::INTERNAL, "GRPC Error")));
@@ -167,7 +119,7 @@
EXPECT_EQ(status, aidlvhal::StatusCode::INTERNAL_ERROR);
}
-TEST_F(GRPCVehicleHardwareMockServerUnitTest, SubscribeProtoFailure) {
+TEST_F(GRPCVehicleHardwareUnitTest, TestSubscribeProtoFailure) {
proto::VehicleHalCallStatus protoStatus;
protoStatus.set_status_code(proto::StatusCode::NOT_AVAILABLE_SPEED_LOW);
@@ -181,7 +133,7 @@
EXPECT_EQ(status, aidlvhal::StatusCode::NOT_AVAILABLE_SPEED_LOW);
}
-TEST_F(GRPCVehicleHardwareMockServerUnitTest, Unsubscribe) {
+TEST_F(GRPCVehicleHardwareUnitTest, TestUnsubscribe) {
proto::VehicleHalCallStatus protoStatus;
protoStatus.set_status_code(proto::StatusCode::OK);
proto::UnsubscribeRequest actualRequest;
@@ -199,7 +151,7 @@
EXPECT_EQ(actualRequest.area_id(), areaId);
}
-TEST_F(GRPCVehicleHardwareMockServerUnitTest, UnsubscribeLegacyServer) {
+TEST_F(GRPCVehicleHardwareUnitTest, TestUnsubscribeLegacyServer) {
EXPECT_CALL(*mGrpcStub, Unsubscribe(_, _, _))
.WillOnce(Return(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")));
@@ -208,7 +160,7 @@
EXPECT_EQ(status, aidlvhal::StatusCode::OK);
}
-TEST_F(GRPCVehicleHardwareMockServerUnitTest, UnsubscribeGrpcFailure) {
+TEST_F(GRPCVehicleHardwareUnitTest, TestUnsubscribeGrpcFailure) {
EXPECT_CALL(*mGrpcStub, Unsubscribe(_, _, _))
.WillOnce(Return(::grpc::Status(::grpc::StatusCode::INTERNAL, "GRPC Error")));
@@ -217,7 +169,7 @@
EXPECT_EQ(status, aidlvhal::StatusCode::INTERNAL_ERROR);
}
-TEST_F(GRPCVehicleHardwareMockServerUnitTest, UnsubscribeProtoFailure) {
+TEST_F(GRPCVehicleHardwareUnitTest, TestUnsubscribeProtoFailure) {
proto::VehicleHalCallStatus protoStatus;
protoStatus.set_status_code(proto::StatusCode::NOT_AVAILABLE_SPEED_LOW);
@@ -230,4 +182,264 @@
EXPECT_EQ(status, aidlvhal::StatusCode::NOT_AVAILABLE_SPEED_LOW);
}
+TEST_F(GRPCVehicleHardwareUnitTest, TestPollValue) {
+ int64_t testTimestamp = 12345;
+ int32_t testPropId = 54321;
+ int64_t startTimestamp = elapsedRealtimeNano();
+
+ // This will be converted to a unique_ptr in StartPropertyValuesStream. The ownership is passed
+ // there.
+ auto clientReader = new MockClientReader<proto::VehiclePropValues>();
+ EXPECT_CALL(*mGrpcStub, StartPropertyValuesStreamRaw(_, _)).WillOnce(Return(clientReader));
+ EXPECT_CALL(*clientReader, Read(_))
+ .WillOnce([testTimestamp, testPropId](proto::VehiclePropValues* values) {
+ values->Clear();
+ auto value = values->add_values();
+ value->set_timestamp(testTimestamp);
+ value->set_prop(testPropId);
+ return true;
+ })
+ .WillOnce(Return(false));
+ EXPECT_CALL(*clientReader, Finish()).WillOnce(Return(::grpc::Status::OK));
+
+ std::vector<aidlvhal::VehiclePropValue> propertyEvents;
+
+ mHardware->registerOnPropertyChangeEvent(
+ std::make_unique<GRPCVehicleHardware::PropertyChangeCallback>(
+ [&propertyEvents](const std::vector<aidlvhal::VehiclePropValue>& events) {
+ for (const auto& event : events) {
+ propertyEvents.push_back(event);
+ }
+ }));
+
+ pollValue();
+
+ ASSERT_THAT(propertyEvents, SizeIs(1));
+ EXPECT_EQ(propertyEvents[0].prop, testPropId);
+ EXPECT_GT(propertyEvents[0].timestamp, startTimestamp)
+ << "Timestamp must be updated to Android timestamp";
+ EXPECT_LT(propertyEvents[0].timestamp, elapsedRealtimeNano())
+ << "Timestamp must be updated to Android timestamp";
+}
+
+TEST_F(GRPCVehicleHardwareUnitTest, TestPollValueIgnoreOutdatedValue) {
+ int64_t testTimestamp1 = 12345;
+ int32_t value1 = 1324;
+ int64_t testTimestamp2 = 12340;
+ int32_t value2 = 1423;
+ int32_t testPropId = 54321;
+ int64_t startTimestamp = elapsedRealtimeNano();
+
+ // This will be converted to a unique_ptr in StartPropertyValuesStream. The ownership is passed
+ // there.
+ auto clientReader = new MockClientReader<proto::VehiclePropValues>();
+ EXPECT_CALL(*mGrpcStub, StartPropertyValuesStreamRaw(_, _)).WillOnce(Return(clientReader));
+ EXPECT_CALL(*clientReader, Read(_))
+ .WillOnce([testTimestamp1, value1, testPropId](proto::VehiclePropValues* values) {
+ values->Clear();
+ auto value = values->add_values();
+ value->set_timestamp(testTimestamp1);
+ value->set_prop(testPropId);
+ value->add_int32_values(value1);
+ return true;
+ })
+ .WillOnce([testTimestamp2, value2, testPropId](proto::VehiclePropValues* values) {
+ values->Clear();
+ // This event is outdated, must be ignored.
+ auto value = values->add_values();
+ value->set_timestamp(testTimestamp2);
+ value->set_prop(testPropId);
+ value->add_int32_values(value2);
+ return true;
+ })
+ .WillOnce(Return(false));
+ EXPECT_CALL(*clientReader, Finish()).WillOnce(Return(::grpc::Status::OK));
+
+ std::vector<aidlvhal::VehiclePropValue> propertyEvents;
+
+ mHardware->registerOnPropertyChangeEvent(
+ std::make_unique<GRPCVehicleHardware::PropertyChangeCallback>(
+ [&propertyEvents](const std::vector<aidlvhal::VehiclePropValue>& events) {
+ for (const auto& event : events) {
+ propertyEvents.push_back(event);
+ }
+ }));
+
+ pollValue();
+
+ ASSERT_THAT(propertyEvents, SizeIs(1)) << "Outdated event must be ignored";
+ EXPECT_EQ(propertyEvents[0].prop, testPropId);
+ EXPECT_GT(propertyEvents[0].timestamp, startTimestamp);
+ EXPECT_LT(propertyEvents[0].timestamp, elapsedRealtimeNano());
+ EXPECT_THAT(propertyEvents[0].value.int32Values, ElementsAre(value1));
+}
+
+TEST_F(GRPCVehicleHardwareUnitTest, TestValuePollingLoop) {
+ int64_t testTimestamp = 12345;
+ int32_t testPropId = 54321;
+ auto stub = std::make_unique<NiceMock<MockVehicleServerStub>>();
+
+ // This will be converted to a unique_ptr in StartPropertyValuesStream. The ownership is passed
+ // there.
+ auto clientReader = new MockClientReader<proto::VehiclePropValues>();
+ EXPECT_CALL(*stub, StartPropertyValuesStreamRaw(_, _)).WillOnce(Return(clientReader));
+ EXPECT_CALL(*clientReader, Read(_))
+ .WillRepeatedly([testTimestamp, testPropId](proto::VehiclePropValues* values) {
+ // Sleep for 10ms and always return the same property event.
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ values->Clear();
+ auto value = values->add_values();
+ value->set_timestamp(testTimestamp);
+ value->set_prop(testPropId);
+ return true;
+ });
+ EXPECT_CALL(*clientReader, Finish()).WillOnce(Return(::grpc::Status::OK));
+
+ startValuePollingLoop(std::move(stub));
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ // This must stop the loop and wait for the thread to finish.
+ mHardware.reset();
+}
+
+TEST_F(GRPCVehicleHardwareUnitTest, TestGetValues) {
+ int64_t testRequestId = 1234;
+ int32_t testPropId = 4321;
+ int32_t testValue = 123456;
+ proto::VehiclePropValueRequests gotRequests;
+ EXPECT_CALL(*mGrpcStub, GetValues(_, _, _))
+ .WillOnce([&gotRequests, testRequestId, testPropId, testValue](
+ ::grpc::ClientContext* context,
+ const proto::VehiclePropValueRequests& request,
+ proto::GetValueResults* response) {
+ gotRequests = request;
+ response->Clear();
+ auto* resultPtr = response->add_results();
+ resultPtr->set_request_id(testRequestId);
+ resultPtr->set_status(proto::StatusCode::OK);
+ auto* valuePtr = resultPtr->mutable_value();
+ valuePtr->set_prop(testPropId);
+ valuePtr->add_int32_values(testValue);
+ return ::grpc::Status::OK;
+ });
+
+ std::vector<aidlvhal::GetValueRequest> requests;
+ requests.push_back(aidlvhal::GetValueRequest{.requestId = testRequestId,
+ .prop = {
+ .prop = testPropId,
+ }});
+
+ std::vector<aidlvhal::GetValueResult> gotResults;
+
+ auto status = mHardware->getValues(
+ std::make_shared<GRPCVehicleHardware::GetValuesCallback>(
+ [&gotResults](std::vector<aidlvhal::GetValueResult> results) {
+ for (const auto& result : results) {
+ gotResults.push_back(result);
+ }
+ }),
+ requests);
+
+ ASSERT_EQ(status, aidlvhal::StatusCode::OK);
+ ASSERT_THAT(gotRequests.requests(), SizeIs(1));
+ EXPECT_THAT(gotRequests.requests(0).request_id(), testRequestId);
+ EXPECT_THAT(gotRequests.requests(0).value().prop(), testPropId);
+
+ ASSERT_THAT(gotResults, SizeIs(1));
+ EXPECT_EQ(gotResults[0].requestId, testRequestId);
+ EXPECT_EQ(gotResults[0].status, aidlvhal::StatusCode::OK);
+ EXPECT_EQ(gotResults[0].prop->prop, testPropId);
+ EXPECT_THAT(gotResults[0].prop->value.int32Values, ElementsAre(testValue));
+}
+
+void GRPCVehicleHardwareUnitTest::generatePropertyUpdateEvent(int32_t propId, int64_t timestamp) {
+ // This will be converted to a unique_ptr in StartPropertyValuesStream. The ownership is passed
+ // there.
+ auto clientReader = new MockClientReader<proto::VehiclePropValues>();
+ EXPECT_CALL(*mGrpcStub, StartPropertyValuesStreamRaw(_, _)).WillOnce(Return(clientReader));
+ EXPECT_CALL(*clientReader, Read(_))
+ .WillOnce([timestamp, propId](proto::VehiclePropValues* values) {
+ values->Clear();
+ auto value = values->add_values();
+ value->set_timestamp(timestamp);
+ value->set_prop(propId);
+ return true;
+ })
+ .WillOnce(Return(false));
+ EXPECT_CALL(*clientReader, Finish()).WillOnce(Return(::grpc::Status::OK));
+
+ pollValue();
+}
+
+TEST_F(GRPCVehicleHardwareUnitTest, TestGetValuesOutdatedRetry) {
+ int64_t startTimestamp = elapsedRealtimeNano();
+ int64_t testRequestId = 1234;
+ int32_t testPropId = 4321;
+ int32_t testValue1 = 123456;
+ int32_t testValue2 = 654321;
+ int32_t testTimestamp1 = 1000;
+ int32_t testTimestamp2 = 2000;
+
+ // A property update event for testTimestamp2 happens before getValues returns.
+ generatePropertyUpdateEvent(testPropId, testTimestamp2);
+
+ // GetValues first returns an outdated result, then an up-to-date result.
+ EXPECT_CALL(*mGrpcStub, GetValues(_, _, _))
+ .WillOnce([testRequestId, testPropId, testValue1, testTimestamp1](
+ ::grpc::ClientContext* context,
+ const proto::VehiclePropValueRequests& request,
+ proto::GetValueResults* response) {
+ response->Clear();
+ auto* resultPtr = response->add_results();
+ resultPtr->set_request_id(testRequestId);
+ resultPtr->set_status(proto::StatusCode::OK);
+ auto* valuePtr = resultPtr->mutable_value();
+ valuePtr->set_prop(testPropId);
+ valuePtr->set_timestamp(testTimestamp1);
+ valuePtr->add_int32_values(testValue1);
+ return ::grpc::Status::OK;
+ })
+ .WillOnce([testRequestId, testPropId, testValue2, testTimestamp2](
+ ::grpc::ClientContext* context,
+ const proto::VehiclePropValueRequests& request,
+ proto::GetValueResults* response) {
+ response->Clear();
+ auto* resultPtr = response->add_results();
+ resultPtr->set_request_id(testRequestId);
+ resultPtr->set_status(proto::StatusCode::OK);
+ auto* valuePtr = resultPtr->mutable_value();
+ valuePtr->set_prop(testPropId);
+ valuePtr->set_timestamp(testTimestamp2);
+ valuePtr->add_int32_values(testValue2);
+ return ::grpc::Status::OK;
+ });
+
+ std::vector<aidlvhal::GetValueRequest> requests;
+ requests.push_back(aidlvhal::GetValueRequest{.requestId = testRequestId,
+ .prop = {
+ .prop = testPropId,
+ }});
+
+ std::vector<aidlvhal::GetValueResult> gotResults;
+
+ auto status = mHardware->getValues(
+ std::make_shared<GRPCVehicleHardware::GetValuesCallback>(
+ [&gotResults](std::vector<aidlvhal::GetValueResult> results) {
+ for (const auto& result : results) {
+ gotResults.push_back(result);
+ }
+ }),
+ requests);
+
+ ASSERT_EQ(status, aidlvhal::StatusCode::OK);
+ ASSERT_THAT(gotResults, SizeIs(1));
+ EXPECT_EQ(gotResults[0].requestId, testRequestId);
+ EXPECT_EQ(gotResults[0].status, aidlvhal::StatusCode::OK);
+ EXPECT_EQ(gotResults[0].prop->prop, testPropId);
+ EXPECT_THAT(gotResults[0].prop->value.int32Values, ElementsAre(testValue2));
+ EXPECT_GT(gotResults[0].prop->timestamp, startTimestamp);
+ EXPECT_LT(gotResults[0].prop->timestamp, elapsedRealtimeNano());
+}
+
} // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/broadcastradio/aidl/vts/Android.bp b/broadcastradio/aidl/vts/Android.bp
index 87e48a9..197ebb5 100644
--- a/broadcastradio/aidl/vts/Android.bp
+++ b/broadcastradio/aidl/vts/Android.bp
@@ -44,4 +44,5 @@
"general-tests",
"vts",
],
+ disable_framework: true,
}
diff --git a/cas/1.2/default/android.hardware.cas@1.2-service-lazy.xml b/cas/1.2/default/android.hardware.cas@1.2-service-lazy.xml
index 9b36406..87c9e02 100644
--- a/cas/1.2/default/android.hardware.cas@1.2-service-lazy.xml
+++ b/cas/1.2/default/android.hardware.cas@1.2-service-lazy.xml
@@ -1,5 +1,5 @@
<manifest version="1.0" type="device">
- <hal format="hidl">
+ <hal format="hidl" max-level="7">
<name>android.hardware.cas</name>
<transport>hwbinder</transport>
<version>1.2</version>
diff --git a/cas/1.2/default/android.hardware.cas@1.2-service.xml b/cas/1.2/default/android.hardware.cas@1.2-service.xml
index 9b36406..87c9e02 100644
--- a/cas/1.2/default/android.hardware.cas@1.2-service.xml
+++ b/cas/1.2/default/android.hardware.cas@1.2-service.xml
@@ -1,5 +1,5 @@
<manifest version="1.0" type="device">
- <hal format="hidl">
+ <hal format="hidl" max-level="7">
<name>android.hardware.cas</name>
<transport>hwbinder</transport>
<version>1.2</version>
diff --git a/media/bufferpool/aidl/default/Accessor.cpp b/media/bufferpool/aidl/default/Accessor.cpp
index 423fd84..81e8eac 100644
--- a/media/bufferpool/aidl/default/Accessor.cpp
+++ b/media/bufferpool/aidl/default/Accessor.cpp
@@ -444,7 +444,7 @@
std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> &accessors,
std::mutex &mutex,
std::condition_variable &cv) {
- std::list<const std::weak_ptr<Accessor>> evictList;
+ std::list<std::weak_ptr<Accessor>> evictList;
while (true) {
int expired = 0;
int evicted = 0;
diff --git a/neuralnetworks/1.2/utils/test/DeviceTest.cpp b/neuralnetworks/1.2/utils/test/DeviceTest.cpp
index 0d8c141..0e855c4 100644
--- a/neuralnetworks/1.2/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/1.2/utils/test/DeviceTest.cpp
@@ -54,6 +54,10 @@
.execTime = std::numeric_limits<float>::max(),
.powerUsage = std::numeric_limits<float>::max()};
+// FIXME: This function causes Clang to hang indefinitely when building with
+// -O1. Turn off optimization as a temporary workaround.
+// http://b/296850773
+#pragma clang optimize off
template <typename... Args>
auto makeCallbackReturn(Args&&... args) {
return [argPack = std::make_tuple(std::forward<Args>(args)...)](const auto& cb) {
@@ -61,6 +65,7 @@
return Void();
};
}
+#pragma clang optimize on
sp<MockDevice> createMockDevice() {
const auto mockDevice = MockDevice::create();
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index b214401..ec2a29c 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -2494,24 +2494,27 @@
{RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
- // Assert the value has changed
- serial = GetRandomSerialNumber();
- ndk::ScopedAStatus res = radio_network->isCellularIdentifierTransparencyEnabled(serial);
+ if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ // Assert the value has changed
+ serial = GetRandomSerialNumber();
+ ndk::ScopedAStatus res = radio_network->isCellularIdentifierTransparencyEnabled(serial);
- ASSERT_OK(res);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
- {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
- RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
- EXPECT_EQ(valueToSet, radioRsp_network->isCellularIdentifierTransparencyEnabled);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+ EXPECT_EQ(valueToSet, radioRsp_network->isCellularIdentifierTransparencyEnabled);
- // Reset original state
- radio_network->setCellularIdentifierTransparencyEnabled(serial, originalTransparencySetting);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ // Reset original state
+ radio_network->setCellularIdentifierTransparencyEnabled(serial,
+ originalTransparencySetting);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ }
}
/*
@@ -2547,24 +2550,26 @@
{RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
- // Assert the value has changed
- serial = GetRandomSerialNumber();
- ndk::ScopedAStatus res = radio_network->isSecurityAlgorithmsUpdatedEnabled(serial);
+ if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ // Assert the value has changed
+ serial = GetRandomSerialNumber();
+ ndk::ScopedAStatus res = radio_network->isSecurityAlgorithmsUpdatedEnabled(serial);
- ASSERT_OK(res);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
- {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
- RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
- EXPECT_EQ(valueToSet, radioRsp_network->isSecurityAlgorithmsUpdatedEnabled);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+ EXPECT_EQ(valueToSet, radioRsp_network->isSecurityAlgorithmsUpdatedEnabled);
- // Reset original state
- radio_network->setSecurityAlgorithmsUpdatedEnabled(serial, originalSecuritySetting);
- EXPECT_EQ(std::cv_status::no_timeout, wait());
- EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
- EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ // Reset original state
+ radio_network->setSecurityAlgorithmsUpdatedEnabled(serial, originalSecuritySetting);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ }
}
/**
diff --git a/security/keymint/support/fuzzer/Android.bp b/security/keymint/support/fuzzer/Android.bp
index 5b1bdb2..a3ceb91 100644
--- a/security/keymint/support/fuzzer/Android.bp
+++ b/security/keymint/support/fuzzer/Android.bp
@@ -46,6 +46,21 @@
"hardware/interfaces/security/keymint/support/include",
"frameworks/native/libs/binder/ndk/include_platform",
],
+ fuzz_config: {
+ cc: [
+ "android-hardware-security@google.com",
+ ],
+ componentid: 1084733,
+ hotlists: [
+ "4593311",
+ "4271696",
+ ],
+ description: "The fuzzer targets the APIs of libkeymint_support",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
+ },
}
cc_defaults {
@@ -92,3 +107,14 @@
"keymint_remote_fuzzer_defaults",
],
}
+
+cc_fuzz {
+ name: "keymint_rkpsupport_fuzzer",
+ srcs: [
+ "keymint_rkpsupport_fuzzer.cpp",
+ ],
+ defaults: [
+ "keymint_fuzzer_defaults",
+ "keymint_remote_fuzzer_defaults",
+ ],
+}
diff --git a/security/keymint/support/fuzzer/README.md b/security/keymint/support/fuzzer/README.md
index 13d3f34..4cf6927 100644
--- a/security/keymint/support/fuzzer/README.md
+++ b/security/keymint/support/fuzzer/README.md
@@ -13,6 +13,7 @@
+ [keymint_attestation_fuzzer](#KeyMintAttestation)
+ [keymint_authSet_fuzzer](#KeyMintAuthSet)
+ [keymint_remote_prov_fuzzer](#KeyMintRemoteProv)
++ [keymint_rkpsupport_fuzzer](#KeyMintRemoteKeyProvSupport)
# <a name="KeyMintAttestation"></a> Fuzzer for KeyMintAttestation
KeyMintAttestation supports the following parameters:
@@ -101,3 +102,30 @@
$ adb sync data
$ adb shell /data/fuzz/arm64/keymint_remote_prov_fuzzer/keymint_remote_prov_fuzzer
```
+
+# <a name="KeyMintRemoteKeyProvSupport"></a> Fuzzer for KeyMintRemoteKeyProvSupport
+KeyMintRemoteKeyProvSupport supports the following parameters:
+1. SupportedEekCurve(parameter name: "supportedEekCurve")
+2. Length(parameter name: "length")
+3. SerialNumberProp(parameter name: "serialNoProp")
+4. InstanceName(parameter name: "instanceName")
+5. Value(parameter name: "value")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |--------------| -------------------- |
+|`supportedEekCurve`| `uint8_t` |Value obtained from FuzzedDataProvider|
+|`length`| `uint8_t` |Value obtained from FuzzedDataProvider|
+|`serialNoProp`| `string` |Value obtained from FuzzedDataProvider|
+|`instanceName`| `string` |Value obtained from FuzzedDataProvider|
+|`value`| `uint8_t` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+$ mm -j$(nproc) keymint_rkpsupport_fuzzer
+```
+2. Run on device
+```
+$ adb sync data
+$ adb shell /data/fuzz/arm64/keymint_rkpsupport_fuzzer/keymint_rkpsupport_fuzzer
+```
diff --git a/security/keymint/support/fuzzer/keymint_rkpsupport_fuzzer.cpp b/security/keymint/support/fuzzer/keymint_rkpsupport_fuzzer.cpp
new file mode 100644
index 0000000..778d48f
--- /dev/null
+++ b/security/keymint/support/fuzzer/keymint_rkpsupport_fuzzer.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 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 <fuzzer/FuzzedDataProvider.h>
+#include <remote_prov/remote_prov_utils.h>
+
+namespace android::hardware::security::keymint_support::fuzzer {
+
+using namespace aidl::android::hardware::security::keymint::remote_prov;
+
+constexpr size_t kMaxBytes = 128;
+
+class KeyMintRemoteKeyProvSupport {
+ public:
+ KeyMintRemoteKeyProvSupport(const uint8_t* data, size_t size) : mFdp(data, size) {}
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+};
+
+void KeyMintRemoteKeyProvSupport::process() {
+ while (mFdp.remaining_bytes()) {
+ auto invokeProvAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() {
+ std::vector<uint8_t> eekId;
+ if (mFdp.ConsumeBool()) {
+ eekId = mFdp.ConsumeBytes<uint8_t>(kMaxBytes);
+ }
+ generateEekChain(mFdp.ConsumeIntegral<uint8_t>() /* supportedEekCurve */,
+ mFdp.ConsumeIntegral<uint8_t>() /* length */, eekId);
+ },
+ [&]() { getProdEekChain(mFdp.ConsumeIntegral<uint8_t>() /* supportedEekCurve */); },
+ [&]() {
+ std::string serialNoProp = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ std::string instanceName = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ cppbor::Array array;
+ array.add(mFdp.ConsumeIntegral<uint8_t>() /* value */);
+ jsonEncodeCsrWithBuild(instanceName, array, serialNoProp);
+ },
+ });
+ invokeProvAPI();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ KeyMintRemoteKeyProvSupport keymintRKPSupport(data, size);
+ keymintRKPSupport.process();
+ return 0;
+}
+
+} // namespace android::hardware::security::keymint_support::fuzzer
diff --git a/tests/extension/vibrator/aidl/default/CustomVibrator.cpp b/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
index 7a7c58b..9c306b5 100644
--- a/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
+++ b/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
@@ -60,7 +60,7 @@
ndk::SpAIBinder CustomVibrator::createBinder() {
auto binder = BnCustomVibrator::createBinder();
// e.g. AIBinder_setInheritRt(binder.get(), true);
- // e.g. AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_NORMAL, 20);
+ // e.g. AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_NORMAL, -2);
// e.g. AIBinder_setRequestingSid(binder.get(), true);
return binder;
}