Separate VHAL emulator logic out.
Create EmulatedVehicleServer logic and moves emulator dependency
under it. This is part of the default VHAL refactoring. By letting
EmulatedVehicleServer depends on emulator, if we provides a
different VehicleServer implementation, it would not have emulator
dependency.
Create DefaultVehicleHal and let EmulatedVehicleHal inherits from
DefaultVehicleHal.
Test: Locally run in an emulator, test setting/getting properties
through emulator. Would add more tests in following CL.
Bug: 188204722
Change-Id: I20c4f69144277c717fed880a3bb9824f23ae0490
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index ea42c3e..4c51c62 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -47,6 +47,7 @@
cc_library_headers {
name: "vhal_v2_0_common_headers",
+ visibility: ["//visibility:public"],
vendor: true,
export_include_dirs: ["common/include/vhal_v2_0"],
}
@@ -58,6 +59,7 @@
defaults: ["vhal_v2_0_target_defaults"],
srcs: [
"common/src/Obd2SensorStore.cpp",
+ "common/src/ProtoMessageConverter.cpp",
"common/src/SubscriptionManager.cpp",
"common/src/VehicleHalManager.cpp",
"common/src/VehicleObjectPool.cpp",
@@ -68,9 +70,13 @@
],
shared_libs: [
"libbase",
+ "libprotobuf-cpp-lite",
],
local_include_dirs: ["common/include/vhal_v2_0"],
export_include_dirs: ["common/include"],
+ static_libs: [
+ "android.hardware.automotive.vehicle@2.0-libproto-native",
+ ],
}
// Vehicle default VehicleHAL implementation
@@ -80,24 +86,16 @@
defaults: ["vhal_v2_0_target_defaults"],
cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
srcs: [
- "impl/vhal_v2_0/CommConn.cpp",
- "impl/vhal_v2_0/EmulatedVehicleConnector.cpp",
- "impl/vhal_v2_0/EmulatedVehicleHal.cpp",
+ "impl/vhal_v2_0/DefaultVehicleHal.cpp",
"impl/vhal_v2_0/VehicleHalClient.cpp",
- "impl/vhal_v2_0/VehicleHalServer.cpp",
- "impl/vhal_v2_0/VehicleEmulator.cpp",
- "impl/vhal_v2_0/PipeComm.cpp",
- "impl/vhal_v2_0/ProtoMessageConverter.cpp",
- "impl/vhal_v2_0/SocketComm.cpp",
+ "impl/vhal_v2_0/DefaultVehicleHalServer.cpp",
"impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
"impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
"impl/vhal_v2_0/GeneratorHub.cpp",
- "impl/vhal_v2_0/qemu_pipe.cpp",
],
local_include_dirs: ["common/include/vhal_v2_0"],
export_include_dirs: ["impl"],
whole_static_libs: [
- "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib",
"android.hardware.automotive.vehicle@2.0-manager-lib",
],
shared_libs: [
@@ -110,19 +108,6 @@
],
}
-// Library used to emulate User HAL behavior through lshal debug requests.
-cc_library_static {
- name: "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib",
- vendor: true,
- defaults: ["vhal_v2_0_target_defaults"],
- srcs: [
- "impl/vhal_v2_0/EmulatedUserHal.cpp",
- ],
- whole_static_libs: [
- "android.hardware.automotive.vehicle@2.0-user-hal-helper-lib",
- ],
-}
-
// Vehicle HAL Server reference impl lib
cc_library_static {
name: "android.hardware.automotive.vehicle@2.0-server-common-lib",
@@ -133,10 +118,14 @@
export_include_dirs: ["common/include"],
srcs: [
"common/src/Obd2SensorStore.cpp",
+ "common/src/ProtoMessageConverter.cpp",
"common/src/VehicleObjectPool.cpp",
"common/src/VehiclePropertyStore.cpp",
"common/src/VehicleUtils.cpp",
],
+ static_libs: [
+ "android.hardware.automotive.vehicle@2.0-libproto-native",
+ ],
}
// Vehicle HAL Server default implementation
@@ -151,8 +140,7 @@
"impl/vhal_v2_0/GeneratorHub.cpp",
"impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
"impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
- "impl/vhal_v2_0/ProtoMessageConverter.cpp",
- "impl/vhal_v2_0/VehicleHalServer.cpp",
+ "impl/vhal_v2_0/DefaultVehicleHalServer.cpp",
],
whole_static_libs: [
"android.hardware.automotive.vehicle@2.0-server-common-lib",
@@ -234,8 +222,8 @@
],
static_libs: [
"android.hardware.automotive.vehicle@2.0-manager-lib",
- "android.hardware.automotive.vehicle@2.0-default-impl-lib",
"android.hardware.automotive.vehicle@2.0-libproto-native",
+ "//device/generic/car/emulator/vhal_v2_0:android.hardware.automotive.vehicle@2.0-emulator-impl-lib",
],
}
diff --git a/automotive/vehicle/2.0/default/VehicleService.cpp b/automotive/vehicle/2.0/default/VehicleService.cpp
index 7e8deb6..ba2a606 100644
--- a/automotive/vehicle/2.0/default/VehicleService.cpp
+++ b/automotive/vehicle/2.0/default/VehicleService.cpp
@@ -20,9 +20,9 @@
#include <iostream>
-#include <vhal_v2_0/EmulatedUserHal.h>
-#include <vhal_v2_0/EmulatedVehicleConnector.h>
-#include <vhal_v2_0/EmulatedVehicleHal.h>
+#include <EmulatedUserHal.h>
+#include <EmulatedVehicleConnector.h>
+#include <EmulatedVehicleHal.h>
#include <vhal_v2_0/VehicleHalManager.h>
using namespace android;
@@ -34,7 +34,7 @@
auto connector = std::make_unique<impl::EmulatedVehicleConnector>();
auto userHal = connector->getEmulatedUserHal();
auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get(), userHal);
- auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get());
+ auto emulator = connector->getEmulator();
auto service = std::make_unique<VehicleHalManager>(hal.get());
connector->setValuePool(hal->getValuePool());
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/ProtoMessageConverter.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/ProtoMessageConverter.h
similarity index 100%
rename from automotive/vehicle/2.0/default/impl/vhal_v2_0/ProtoMessageConverter.h
rename to automotive/vehicle/2.0/default/common/include/vhal_v2_0/ProtoMessageConverter.h
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/ProtoMessageConverter.cpp b/automotive/vehicle/2.0/default/common/src/ProtoMessageConverter.cpp
similarity index 100%
rename from automotive/vehicle/2.0/default/impl/vhal_v2_0/ProtoMessageConverter.cpp
rename to automotive/vehicle/2.0/default/common/src/ProtoMessageConverter.cpp
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.cpp
deleted file mode 100644
index 136b2e0..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#define LOG_TAG "CommConn"
-
-#include <thread>
-
-#include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
-#include <log/log.h>
-
-#include "CommConn.h"
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-void CommConn::start() {
- mReadThread = std::make_unique<std::thread>(std::bind(&CommConn::readThread, this));
-}
-
-void CommConn::stop() {
- if (mReadThread->joinable()) {
- mReadThread->join();
- }
-}
-
-void CommConn::sendMessage(vhal_proto::EmulatorMessage const& msg) {
- int numBytes = msg.ByteSize();
- std::vector<uint8_t> buffer(static_cast<size_t>(numBytes));
- if (!msg.SerializeToArray(buffer.data(), numBytes)) {
- ALOGE("%s: SerializeToString failed!", __func__);
- return;
- }
-
- write(buffer);
-}
-
-void CommConn::readThread() {
- std::vector<uint8_t> buffer;
- while (isOpen()) {
- buffer = read();
- if (buffer.size() == 0) {
- ALOGI("%s: Read returned empty message, exiting read loop.", __func__);
- break;
- }
-
- vhal_proto::EmulatorMessage rxMsg;
- if (rxMsg.ParseFromArray(buffer.data(), static_cast<int32_t>(buffer.size()))) {
- vhal_proto::EmulatorMessage respMsg;
- mMessageProcessor->processMessage(rxMsg, respMsg);
-
- sendMessage(respMsg);
- }
- }
-}
-
-} // namespace impl
-
-} // namespace V2_0
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.h
deleted file mode 100644
index 6d36da4..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/CommConn.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef android_hardware_automotive_vehicle_V2_0_impl_CommBase_H_
-#define android_hardware_automotive_vehicle_V2_0_impl_CommBase_H_
-
-#include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
-#include <string>
-#include <thread>
-#include <vector>
-
-#include "VehicleHalProto.pb.h"
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-/**
- * MessageProcess is an interface implemented by VehicleEmulator to process messages received
- * over a CommConn.
- */
-class MessageProcessor {
- public:
- virtual ~MessageProcessor() = default;
-
- /**
- * Process a single message received over a CommConn. Populate the given respMsg with the reply
- * message we should send.
- */
- virtual void processMessage(vhal_proto::EmulatorMessage const& rxMsg,
- vhal_proto::EmulatorMessage& respMsg) = 0;
-};
-
-/**
- * This is the interface that both PipeComm and SocketComm use to represent a connection. The
- * connection will listen for commands on a separate 'read' thread.
- */
-class CommConn {
- public:
- CommConn(MessageProcessor* messageProcessor) : mMessageProcessor(messageProcessor) {}
-
- virtual ~CommConn() {}
-
- /**
- * Start the read thread reading messages from this connection.
- */
- virtual void start();
-
- /**
- * Closes a connection if it is open.
- */
- virtual void stop();
-
- /**
- * Returns true if the connection is open and available to send/receive.
- */
- virtual bool isOpen() = 0;
-
- /**
- * Blocking call to read data from the connection.
- *
- * @return std::vector<uint8_t> Serialized protobuf data received from emulator. This will be
- * an empty vector if the connection was closed or some other error occurred.
- */
- virtual std::vector<uint8_t> read() = 0;
-
- /**
- * Transmits a string of data to the emulator.
- *
- * @param data Serialized protobuf data to transmit.
- *
- * @return int Number of bytes transmitted, or -1 if failed.
- */
- virtual int write(const std::vector<uint8_t>& data) = 0;
-
- /**
- * Serialized and send the given message to the other side.
- */
- void sendMessage(vhal_proto::EmulatorMessage const& msg);
-
- protected:
- std::unique_ptr<std::thread> mReadThread;
- MessageProcessor* mMessageProcessor;
-
- /**
- * A thread that reads messages in a loop, and responds. You can stop this thread by calling
- * stop().
- */
- void readThread();
-};
-
-} // namespace impl
-
-} // namespace V2_0
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
-
-#endif // android_hardware_automotive_vehicle_V2_0_impl_CommBase_H_
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleConnector.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleConnector.h
new file mode 100644
index 0000000..c3affb0
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleConnector.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_V2_0_impl_DefaultVehicleConnector_H_
+#define android_hardware_automotive_vehicle_V2_0_impl_DefaultVehicleConnector_H_
+
+#include <vhal_v2_0/VehicleConnector.h>
+
+#include "DefaultVehicleHalServer.h"
+#include "VehicleHalClient.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+class DefaultVehicleConnector
+ : public IPassThroughConnector<VehicleHalClient, DefaultVehicleHalServer> {
+ public:
+ DefaultVehicleConnector() = default;
+
+ void triggerSendAllValues() { this->sendAllValuesToClient(); }
+};
+
+} // namespace impl
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_automotive_vehicle_V2_0_impl_DefaultVehicleConnector_H_
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
new file mode 100644
index 0000000..a6e2c8f
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#define LOG_TAG "DefaultVehicleHal_v2_0"
+
+#include <utils/Log.h>
+#include <utils/SystemClock.h>
+#include <vhal_v2_0/RecurrentTimer.h>
+
+#include "VehicleUtils.h"
+
+#include "DefaultVehicleHal.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+DefaultVehicleHal::DefaultVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client)
+ : mPropStore(propStore), mRecurrentTimer(getTimerAction()), mVehicleClient(client) {
+ initStaticConfig();
+ mVehicleClient->registerPropertyValueCallback(
+ [this](const VehiclePropValue& value, bool updateStatus) {
+ onPropertyValue(value, updateStatus);
+ });
+}
+
+VehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(const VehiclePropValue& requestedPropValue,
+ StatusCode* outStatus) {
+ auto propId = requestedPropValue.prop;
+ ALOGV("get(%d)", propId);
+
+ VehiclePropValuePtr v = nullptr;
+ auto internalPropValue = mPropStore->readValueOrNull(requestedPropValue);
+ if (internalPropValue != nullptr) {
+ v = getValuePool()->obtain(*internalPropValue);
+ }
+
+ if (!v) {
+ *outStatus = StatusCode::INVALID_ARG;
+ } else if (v->status == VehiclePropertyStatus::AVAILABLE) {
+ *outStatus = StatusCode::OK;
+ } else {
+ *outStatus = StatusCode::TRY_AGAIN;
+ }
+ if (v.get()) {
+ v->timestamp = elapsedRealtimeNano();
+ }
+ return v;
+}
+
+std::vector<VehiclePropConfig> DefaultVehicleHal::listProperties() {
+ return mPropStore->getAllConfigs();
+}
+
+bool DefaultVehicleHal::dump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) {
+ return mVehicleClient->dump(fd, options);
+}
+
+StatusCode DefaultVehicleHal::set(const VehiclePropValue& propValue) {
+ if (propValue.status != VehiclePropertyStatus::AVAILABLE) {
+ // Android side cannot set property status - this value is the
+ // purview of the HAL implementation to reflect the state of
+ // its underlying hardware
+ return StatusCode::INVALID_ARG;
+ }
+ auto currentPropValue = mPropStore->readValueOrNull(propValue);
+
+ if (currentPropValue == nullptr) {
+ return StatusCode::INVALID_ARG;
+ }
+ if (currentPropValue->status != VehiclePropertyStatus::AVAILABLE) {
+ // do not allow Android side to set() a disabled/error property
+ return StatusCode::NOT_AVAILABLE;
+ }
+
+ // Send the value to the vehicle server, the server will talk to the (real or emulated) car
+ return mVehicleClient->setProperty(propValue, /*updateStatus=*/false);
+}
+
+// Parse supported properties list and generate vector of property values to hold current values.
+void DefaultVehicleHal::onCreate() {
+ auto configs = mVehicleClient->getAllPropertyConfig();
+
+ for (const auto& cfg : configs) {
+ int32_t numAreas = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs.size();
+
+ for (int i = 0; i < numAreas; i++) {
+ int32_t curArea = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs[i].areaId;
+
+ // Create a separate instance for each individual zone
+ VehiclePropValue prop = {
+ .areaId = curArea,
+ .prop = cfg.prop,
+ .status = VehiclePropertyStatus::UNAVAILABLE,
+ };
+ // Allow the initial values to set status.
+ mPropStore->writeValue(prop, /*updateStatus=*/true);
+ }
+ }
+
+ mVehicleClient->triggerSendAllValues();
+}
+
+void DefaultVehicleHal::onContinuousPropertyTimer(const std::vector<int32_t>& properties) {
+ auto& pool = *getValuePool();
+
+ for (int32_t property : properties) {
+ VehiclePropValuePtr v;
+ if (isContinuousProperty(property)) {
+ auto internalPropValue = mPropStore->readValueOrNull(property);
+ if (internalPropValue != nullptr) {
+ v = pool.obtain(*internalPropValue);
+ }
+ } else {
+ ALOGE("Unexpected onContinuousPropertyTimer for property: 0x%x", property);
+ continue;
+ }
+
+ if (v.get()) {
+ v->timestamp = elapsedRealtimeNano();
+ doHalEvent(std::move(v));
+ }
+ }
+}
+
+RecurrentTimer::Action DefaultVehicleHal::getTimerAction() {
+ return [this](const std::vector<int32_t>& properties) {
+ onContinuousPropertyTimer(properties);
+ };
+}
+
+StatusCode DefaultVehicleHal::subscribe(int32_t property, float sampleRate) {
+ ALOGI("%s propId: 0x%x, sampleRate: %f", __func__, property, sampleRate);
+
+ if (!isContinuousProperty(property)) {
+ return StatusCode::INVALID_ARG;
+ }
+ mRecurrentTimer.registerRecurrentEvent(hertzToNanoseconds(sampleRate), property);
+ return StatusCode::OK;
+}
+
+StatusCode DefaultVehicleHal::unsubscribe(int32_t property) {
+ ALOGI("%s propId: 0x%x", __func__, property);
+ if (!isContinuousProperty(property)) {
+ return StatusCode::INVALID_ARG;
+ }
+ // If the event was not registered before, this would do nothing.
+ mRecurrentTimer.unregisterRecurrentEvent(property);
+ return StatusCode::OK;
+}
+
+bool DefaultVehicleHal::isContinuousProperty(int32_t propId) const {
+ const VehiclePropConfig* config = mPropStore->getConfigOrNull(propId);
+ if (config == nullptr) {
+ ALOGW("Config not found for property: 0x%x", propId);
+ return false;
+ }
+ return config->changeMode == VehiclePropertyChangeMode::CONTINUOUS;
+}
+
+void DefaultVehicleHal::onPropertyValue(const VehiclePropValue& value, bool updateStatus) {
+ VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(value);
+
+ if (mPropStore->writeValue(*updatedPropValue, updateStatus)) {
+ doHalEvent(std::move(updatedPropValue));
+ }
+}
+
+void DefaultVehicleHal::initStaticConfig() {
+ auto configs = mVehicleClient->getAllPropertyConfig();
+ for (auto&& cfg : configs) {
+ mPropStore->registerProperty(cfg, nullptr);
+ }
+}
+
+} // namespace impl
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h
new file mode 100644
index 0000000..cc66c0f
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_V2_0_impl_DefaultVehicleHal_H_
+#define android_hardware_automotive_vehicle_V2_0_impl_DefaultVehicleHal_H_
+
+#include <vhal_v2_0/RecurrentTimer.h>
+#include <vhal_v2_0/VehicleHal.h>
+#include "vhal_v2_0/VehiclePropertyStore.h"
+
+#include "VehicleHalClient.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+/** Implementation of VehicleHal that connected to emulator instead of real vehicle network. */
+class DefaultVehicleHal : public VehicleHal {
+ public:
+ DefaultVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client);
+ ~DefaultVehicleHal() = default;
+
+ // Methods from VehicleHal
+ void onCreate() override;
+ std::vector<VehiclePropConfig> listProperties() override;
+ VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
+ StatusCode* outStatus) override;
+ StatusCode set(const VehiclePropValue& propValue) override;
+ StatusCode subscribe(int32_t property, float sampleRate) override;
+ StatusCode unsubscribe(int32_t property) override;
+ bool dump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
+
+ protected:
+ constexpr std::chrono::nanoseconds hertzToNanoseconds(float hz) const {
+ return std::chrono::nanoseconds(static_cast<int64_t>(1000000000L / hz));
+ }
+
+ VehiclePropertyStore* mPropStore;
+ RecurrentTimer mRecurrentTimer;
+ VehicleHalClient* mVehicleClient;
+ virtual bool isContinuousProperty(int32_t propId) const;
+ virtual void initStaticConfig();
+ virtual void onContinuousPropertyTimer(const std::vector<int32_t>& properties);
+ virtual void onPropertyValue(const VehiclePropValue& value, bool updateStatus);
+ // Returns a lambda that could be used in mRecurrentTimer.
+ RecurrentTimer::Action getTimerAction();
+};
+
+} // namespace impl
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_automotive_vehicle_V2_0_impl_DefaultVehicleHal_H_
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
similarity index 81%
rename from automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
rename to automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
index 57dd7d4..e7cc6a0 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -14,9 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "VehicleHalServer"
-
-#include "VehicleHalServer.h"
+#define LOG_TAG "DefaultVehicleHalServer"
#include <fstream>
@@ -26,63 +24,56 @@
#include "DefaultConfig.h"
#include "JsonFakeValueGenerator.h"
#include "LinearFakeValueGenerator.h"
-#include "Obd2SensorStore.h"
-namespace android::hardware::automotive::vehicle::V2_0::impl {
+#include "DefaultVehicleHalServer.h"
-static bool isDiagnosticProperty(VehiclePropConfig propConfig) {
- switch (propConfig.prop) {
- case OBD2_LIVE_FRAME:
- case OBD2_FREEZE_FRAME:
- case OBD2_FREEZE_FRAME_CLEAR:
- case OBD2_FREEZE_FRAME_INFO:
- return true;
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+void DefaultVehicleHalServer::storePropInitialValue(const ConfigDeclaration& config) {
+ VehiclePropConfig cfg = config.config;
+
+ // A global property will have only a single area
+ int32_t numAreas = isGlobalProp(cfg.prop) ? 1 : cfg.areaConfigs.size();
+
+ for (int i = 0; i < numAreas; i++) {
+ int32_t curArea = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs[i].areaId;
+
+ // Create a separate instance for each individual zone
+ VehiclePropValue prop = {
+ .areaId = curArea,
+ .prop = cfg.prop,
+ };
+
+ if (config.initialAreaValues.empty()) {
+ prop.value = config.initialValue;
+ } else if (auto valueForAreaIt = config.initialAreaValues.find(curArea);
+ valueForAreaIt != config.initialAreaValues.end()) {
+ prop.value = valueForAreaIt->second;
+ } else {
+ LOG(WARNING) << __func__ << " failed to get default value for"
+ << " prop 0x" << std::hex << cfg.prop << " area 0x" << std::hex << curArea;
+ prop.status = VehiclePropertyStatus::UNAVAILABLE;
+ }
+
+ mServerSidePropStore.writeValue(prop, true);
}
- return false;
}
-VehicleHalServer::VehicleHalServer() {
- constexpr bool shouldUpdateStatus = true;
-
+DefaultVehicleHalServer::DefaultVehicleHalServer() {
for (auto& it : kVehicleProperties) {
VehiclePropConfig cfg = it.config;
-
mServerSidePropStore.registerProperty(cfg);
-
- if (isDiagnosticProperty(cfg)) {
- continue;
- }
-
- // A global property will have only a single area
- int32_t numAreas = isGlobalProp(cfg.prop) ? 1 : cfg.areaConfigs.size();
-
- for (int i = 0; i < numAreas; i++) {
- int32_t curArea = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs[i].areaId;
-
- // Create a separate instance for each individual zone
- VehiclePropValue prop = {
- .areaId = curArea,
- .prop = cfg.prop,
- };
-
- if (it.initialAreaValues.empty()) {
- prop.value = it.initialValue;
- } else if (auto valueForAreaIt = it.initialAreaValues.find(curArea);
- valueForAreaIt != it.initialAreaValues.end()) {
- prop.value = valueForAreaIt->second;
- } else {
- LOG(WARNING) << __func__ << " failed to get default value for"
- << " prop 0x" << std::hex << cfg.prop << " area 0x" << std::hex
- << curArea;
- prop.status = VehiclePropertyStatus::UNAVAILABLE;
- }
-
- mServerSidePropStore.writeValue(prop, shouldUpdateStatus);
- }
+ storePropInitialValue(it);
}
}
-void VehicleHalServer::sendAllValuesToClient() {
+void DefaultVehicleHalServer::sendAllValuesToClient() {
constexpr bool update_status = true;
auto values = mServerSidePropStore.readAllValues();
for (const auto& value : values) {
@@ -90,25 +81,25 @@
}
}
-GeneratorHub* VehicleHalServer::getGenerator() {
+GeneratorHub* DefaultVehicleHalServer::getGenerator() {
return &mGeneratorHub;
}
-VehiclePropValuePool* VehicleHalServer::getValuePool() const {
+VehiclePropValuePool* DefaultVehicleHalServer::getValuePool() const {
if (!mValuePool) {
LOG(WARNING) << __func__ << ": Value pool not set!";
}
return mValuePool;
}
-void VehicleHalServer::setValuePool(VehiclePropValuePool* valuePool) {
+void DefaultVehicleHalServer::setValuePool(VehiclePropValuePool* valuePool) {
if (!valuePool) {
LOG(WARNING) << __func__ << ": Setting value pool to nullptr!";
}
mValuePool = valuePool;
}
-void VehicleHalServer::onFakeValueGenerated(const VehiclePropValue& value) {
+void DefaultVehicleHalServer::onFakeValueGenerated(const VehiclePropValue& value) {
constexpr bool updateStatus = true;
LOG(DEBUG) << __func__ << ": " << toString(value);
auto updatedPropValue = getValuePool()->obtain(value);
@@ -120,11 +111,11 @@
}
}
-std::vector<VehiclePropConfig> VehicleHalServer::onGetAllPropertyConfig() const {
+std::vector<VehiclePropConfig> DefaultVehicleHalServer::onGetAllPropertyConfig() const {
return mServerSidePropStore.getAllConfigs();
}
-StatusCode VehicleHalServer::handleGenerateFakeDataRequest(const VehiclePropValue& request) {
+StatusCode DefaultVehicleHalServer::handleGenerateFakeDataRequest(const VehiclePropValue& request) {
constexpr bool updateStatus = true;
LOG(INFO) << __func__;
@@ -209,7 +200,7 @@
return StatusCode::OK;
}
-VehicleHalServer::VehiclePropValuePtr VehicleHalServer::createApPowerStateReq(
+DefaultVehicleHalServer::VehiclePropValuePtr DefaultVehicleHalServer::createApPowerStateReq(
VehicleApPowerStateReq state, int32_t param) {
auto req = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 2);
req->prop = toInt(VehicleProperty::AP_POWER_STATE_REQ);
@@ -221,7 +212,7 @@
return req;
}
-VehicleHalServer::VehiclePropValuePtr VehicleHalServer::createHwInputKeyProp(
+DefaultVehicleHalServer::VehiclePropValuePtr DefaultVehicleHalServer::createHwInputKeyProp(
VehicleHwKeyInputAction action, int32_t keyCode, int32_t targetDisplay) {
auto keyEvent = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 3);
keyEvent->prop = toInt(VehicleProperty::HW_KEY_INPUT);
@@ -234,7 +225,8 @@
return keyEvent;
}
-StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool updateStatus) {
+StatusCode DefaultVehicleHalServer::onSetProperty(const VehiclePropValue& value,
+ bool updateStatus) {
LOG(DEBUG) << "onSetProperty(" << value.prop << ")";
// Some properties need to be treated non-trivially
@@ -337,4 +329,10 @@
return StatusCode::OK;
}
-} // namespace android::hardware::automotive::vehicle::V2_0::impl
+} // namespace impl
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.h
new file mode 100644
index 0000000..d8e1b4e
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <vhal_v2_0/VehicleObjectPool.h>
+#include <vhal_v2_0/VehiclePropertyStore.h>
+#include <vhal_v2_0/VehicleServer.h>
+
+#include "DefaultConfig.h"
+#include "GeneratorHub.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+// This contains the server operation for VHAL running in emulator.
+class DefaultVehicleHalServer : public IVehicleServer {
+ public:
+ DefaultVehicleHalServer();
+
+ // Send all the property values to client.
+ void sendAllValuesToClient();
+
+ // Methods from IVehicleServer
+
+ std::vector<VehiclePropConfig> onGetAllPropertyConfig() const override;
+
+ StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) override;
+
+ // Set the Property Value Pool used in this server
+ void setValuePool(VehiclePropValuePool* valuePool);
+
+ protected:
+ using VehiclePropValuePtr = recyclable_ptr<VehiclePropValue>;
+ GeneratorHub* getGenerator();
+
+ VehiclePropValuePool* getValuePool() const;
+
+ void onFakeValueGenerated(const VehiclePropValue& value);
+
+ StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request);
+
+ VehiclePropValuePtr createApPowerStateReq(VehicleApPowerStateReq req, int32_t param);
+
+ VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode,
+ int32_t targetDisplay);
+
+ void storePropInitialValue(const ConfigDeclaration& config);
+
+ protected:
+ GeneratorHub mGeneratorHub{
+ [this](const VehiclePropValue& value) { return onFakeValueGenerated(value); }};
+
+ VehiclePropValuePool* mValuePool{nullptr};
+ VehiclePropertyStore mServerSidePropStore;
+};
+
+} // namespace impl
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp
deleted file mode 100644
index 3bdf5a8..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define LOG_TAG "EmulatedUserHal"
-
-#include "EmulatedUserHal.h"
-
-#include <cutils/log.h>
-#include <utils/SystemClock.h>
-
-#include "UserHalHelper.h"
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-namespace {
-
-using android::base::Error;
-using android::base::Result;
-
-constexpr int32_t INITIAL_USER_INFO = static_cast<int32_t>(VehicleProperty::INITIAL_USER_INFO);
-constexpr int32_t SWITCH_USER = static_cast<int32_t>(VehicleProperty::SWITCH_USER);
-constexpr int32_t CREATE_USER = static_cast<int32_t>(VehicleProperty::CREATE_USER);
-constexpr int32_t REMOVE_USER = static_cast<int32_t>(VehicleProperty::REMOVE_USER);
-constexpr int32_t USER_IDENTIFICATION_ASSOCIATION =
- static_cast<int32_t>(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION);
-
-Result<int32_t> getRequestId(const VehiclePropValue& value) {
- if (value.value.int32Values.size() < 1) {
- return Error(static_cast<int>(StatusCode::INVALID_ARG))
- << "no int32values on " << toString(value);
- }
- return value.value.int32Values[0];
-}
-
-Result<SwitchUserMessageType> getSwitchUserMessageType(const VehiclePropValue& value) {
- if (value.value.int32Values.size() < 2) {
- return Error(static_cast<int>(StatusCode::INVALID_ARG))
- << "missing switch user message type " << toString(value);
- }
- return user_hal_helper::verifyAndCast<SwitchUserMessageType>(value.value.int32Values[1]);
-}
-
-} // namespace
-
-bool EmulatedUserHal::isSupported(int32_t prop) {
- switch (prop) {
- case INITIAL_USER_INFO:
- case SWITCH_USER:
- case CREATE_USER:
- case REMOVE_USER:
- case USER_IDENTIFICATION_ASSOCIATION:
- return true;
- default:
- return false;
- }
-}
-
-Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetProperty(
- const VehiclePropValue& value) {
- ALOGV("onSetProperty(): %s", toString(value).c_str());
-
- switch (value.prop) {
- case INITIAL_USER_INFO:
- return onSetInitialUserInfoResponse(value);
- case SWITCH_USER:
- return onSetSwitchUserResponse(value);
- case CREATE_USER:
- return onSetCreateUserResponse(value);
- case REMOVE_USER:
- ALOGI("REMOVE_USER is FYI only, nothing to do...");
- return {};
- case USER_IDENTIFICATION_ASSOCIATION:
- return onSetUserIdentificationAssociation(value);
- default:
- return Error(static_cast<int>(StatusCode::INVALID_ARG))
- << "Unsupported property: " << toString(value);
- }
-}
-
-Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onGetProperty(
- const VehiclePropValue& value) {
- ALOGV("onGetProperty(%s)", toString(value).c_str());
- switch (value.prop) {
- case INITIAL_USER_INFO:
- case SWITCH_USER:
- case CREATE_USER:
- case REMOVE_USER:
- ALOGE("onGetProperty(): %d is only supported on SET", value.prop);
- return Error(static_cast<int>(StatusCode::INVALID_ARG)) << "only supported on SET";
- case USER_IDENTIFICATION_ASSOCIATION:
- return onGetUserIdentificationAssociation(value);
- default:
- ALOGE("onGetProperty(): %d is not supported", value.prop);
- return Error(static_cast<int>(StatusCode::INVALID_ARG)) << "not supported by User HAL";
- }
-}
-
-Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onGetUserIdentificationAssociation(
- const VehiclePropValue& value) {
- if (mSetUserIdentificationAssociationResponseFromCmd == nullptr) {
- return defaultUserIdentificationAssociation(value);
- }
- ALOGI("get(USER_IDENTIFICATION_ASSOCIATION): returning %s",
- toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str());
- auto newValue = std::unique_ptr<VehiclePropValue>(
- new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd));
- auto requestId = getRequestId(value);
- if (requestId.ok()) {
- // Must use the same requestId
- newValue->value.int32Values[0] = *requestId;
- } else {
- ALOGE("get(USER_IDENTIFICATION_ASSOCIATION): no requestId on %s", toString(value).c_str());
- }
- return newValue;
-}
-
-Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetInitialUserInfoResponse(
- const VehiclePropValue& value) {
- auto requestId = getRequestId(value);
- if (!requestId.ok()) {
- ALOGE("Failed to get requestId on set(INITIAL_USER_INFO): %s",
- requestId.error().message().c_str());
- return requestId.error();
- }
-
- if (value.areaId != 0) {
- ALOGD("set(INITIAL_USER_INFO) called from lshal; storing it: %s", toString(value).c_str());
- mInitialUserResponseFromCmd.reset(new VehiclePropValue(value));
- return {};
- }
-
- ALOGD("set(INITIAL_USER_INFO) called from Android: %s", toString(value).c_str());
- if (mInitialUserResponseFromCmd != nullptr) {
- ALOGI("replying INITIAL_USER_INFO with lshal value: %s",
- toString(*mInitialUserResponseFromCmd).c_str());
- return sendUserHalResponse(std::move(mInitialUserResponseFromCmd), *requestId);
- }
-
- // Returns default response
- auto updatedValue = user_hal_helper::toVehiclePropValue(InitialUserInfoResponse{
- .requestId = *requestId,
- .action = InitialUserInfoResponseAction::DEFAULT,
- });
- ALOGI("no lshal response; replying with InitialUserInfoResponseAction::DEFAULT: %s",
- toString(*updatedValue).c_str());
- return updatedValue;
-}
-
-Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetSwitchUserResponse(
- const VehiclePropValue& value) {
- auto requestId = getRequestId(value);
- if (!requestId.ok()) {
- ALOGE("Failed to get requestId on set(SWITCH_USER): %s",
- requestId.error().message().c_str());
- return requestId.error();
- }
-
- auto messageType = getSwitchUserMessageType(value);
- if (!messageType.ok()) {
- ALOGE("Failed to get messageType on set(SWITCH_USER): %s",
- messageType.error().message().c_str());
- return messageType.error();
- }
-
- if (value.areaId != 0) {
- if (*messageType == SwitchUserMessageType::VEHICLE_REQUEST) {
- // User HAL can also request a user switch, so we need to check it first
- ALOGD("set(SWITCH_USER) called from lshal to emulate a vehicle request: %s",
- toString(value).c_str());
- return std::unique_ptr<VehiclePropValue>(new VehiclePropValue(value));
- }
- // Otherwise, we store it
- ALOGD("set(SWITCH_USER) called from lshal; storing it: %s", toString(value).c_str());
- mSwitchUserResponseFromCmd.reset(new VehiclePropValue(value));
- return {};
- }
- ALOGD("set(SWITCH_USER) called from Android: %s", toString(value).c_str());
-
- if (mSwitchUserResponseFromCmd != nullptr) {
- ALOGI("replying SWITCH_USER with lshal value: %s",
- toString(*mSwitchUserResponseFromCmd).c_str());
- return sendUserHalResponse(std::move(mSwitchUserResponseFromCmd), *requestId);
- }
-
- if (*messageType == SwitchUserMessageType::LEGACY_ANDROID_SWITCH ||
- *messageType == SwitchUserMessageType::ANDROID_POST_SWITCH) {
- ALOGI("request is %s; ignoring it", toString(*messageType).c_str());
- return {};
- }
-
- // Returns default response
- auto updatedValue = user_hal_helper::toVehiclePropValue(SwitchUserResponse{
- .requestId = *requestId,
- .messageType = SwitchUserMessageType::VEHICLE_RESPONSE,
- .status = SwitchUserStatus::SUCCESS,
- });
- ALOGI("no lshal response; replying with VEHICLE_RESPONSE / SUCCESS: %s",
- toString(*updatedValue).c_str());
- return updatedValue;
-}
-
-Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetCreateUserResponse(
- const VehiclePropValue& value) {
- auto requestId = getRequestId(value);
- if (!requestId.ok()) {
- ALOGE("Failed to get requestId on set(CREATE_USER): %s",
- requestId.error().message().c_str());
- return requestId.error();
- }
-
- if (value.areaId != 0) {
- ALOGD("set(CREATE_USER) called from lshal; storing it: %s", toString(value).c_str());
- mCreateUserResponseFromCmd.reset(new VehiclePropValue(value));
- return {};
- }
- ALOGD("set(CREATE_USER) called from Android: %s", toString(value).c_str());
-
- if (mCreateUserResponseFromCmd != nullptr) {
- ALOGI("replying CREATE_USER with lshal value: %s",
- toString(*mCreateUserResponseFromCmd).c_str());
- return sendUserHalResponse(std::move(mCreateUserResponseFromCmd), *requestId);
- }
-
- // Returns default response
- auto updatedValue = user_hal_helper::toVehiclePropValue(CreateUserResponse{
- .requestId = *requestId,
- .status = CreateUserStatus::SUCCESS,
- });
- ALOGI("no lshal response; replying with SUCCESS: %s", toString(*updatedValue).c_str());
- return updatedValue;
-}
-
-Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetUserIdentificationAssociation(
- const VehiclePropValue& value) {
- auto requestId = getRequestId(value);
- if (!requestId.ok()) {
- ALOGE("Failed to get requestId on set(USER_IDENTIFICATION_ASSOCIATION): %s",
- requestId.error().message().c_str());
- return requestId.error();
- }
-
- if (value.areaId != 0) {
- ALOGD("set(USER_IDENTIFICATION_ASSOCIATION) called from lshal; storing it: %s",
- toString(value).c_str());
- mSetUserIdentificationAssociationResponseFromCmd.reset(new VehiclePropValue(value));
- return {};
- }
- ALOGD("set(USER_IDENTIFICATION_ASSOCIATION) called from Android: %s", toString(value).c_str());
-
- if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) {
- ALOGI("replying USER_IDENTIFICATION_ASSOCIATION with lshal value: %s",
- toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str());
- // Not moving response so it can be used on GET requests
- auto copy = std::unique_ptr<VehiclePropValue>(
- new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd));
- return sendUserHalResponse(std::move(copy), *requestId);
- }
- // Returns default response
- return defaultUserIdentificationAssociation(value);
-}
-
-Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::defaultUserIdentificationAssociation(
- const VehiclePropValue& request) {
- // TODO(b/159498909): return a response with NOT_ASSOCIATED_ANY_USER for all requested types
- ALOGE("no lshal response for %s; replying with NOT_AVAILABLE", toString(request).c_str());
- return Error(static_cast<int>(StatusCode::NOT_AVAILABLE)) << "not set by lshal";
-}
-
-Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::sendUserHalResponse(
- std::unique_ptr<VehiclePropValue> response, int32_t requestId) {
- switch (response->areaId) {
- case 1:
- ALOGD("returning response with right request id");
- response->value.int32Values[0] = requestId;
- break;
- case 2:
- ALOGD("returning response with wrong request id");
- response->value.int32Values[0] = -requestId;
- break;
- case 3:
- ALOGD("not generating a property change event because of lshal prop: %s",
- toString(*response).c_str());
- return Error(static_cast<int>(StatusCode::NOT_AVAILABLE))
- << "not generating a property change event because of lshal prop: "
- << toString(*response);
- default:
- ALOGE("invalid action on lshal response: %s", toString(*response).c_str());
- return Error(static_cast<int>(StatusCode::INTERNAL_ERROR))
- << "invalid action on lshal response: " << toString(*response);
- }
-
- ALOGD("updating property to: %s", toString(*response).c_str());
- return response;
-}
-
-void EmulatedUserHal::showDumpHelp(int fd) {
- dprintf(fd, "%s: dumps state used for user management\n", kUserHalDumpOption);
-}
-
-void EmulatedUserHal::dump(int fd, std::string indent) {
- if (mInitialUserResponseFromCmd != nullptr) {
- dprintf(fd, "%sInitialUserInfo response: %s\n", indent.c_str(),
- toString(*mInitialUserResponseFromCmd).c_str());
- } else {
- dprintf(fd, "%sNo InitialUserInfo response\n", indent.c_str());
- }
- if (mSwitchUserResponseFromCmd != nullptr) {
- dprintf(fd, "%sSwitchUser response: %s\n", indent.c_str(),
- toString(*mSwitchUserResponseFromCmd).c_str());
- } else {
- dprintf(fd, "%sNo SwitchUser response\n", indent.c_str());
- }
- if (mCreateUserResponseFromCmd != nullptr) {
- dprintf(fd, "%sCreateUser response: %s\n", indent.c_str(),
- toString(*mCreateUserResponseFromCmd).c_str());
- } else {
- dprintf(fd, "%sNo CreateUser response\n", indent.c_str());
- }
- if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) {
- dprintf(fd, "%sSetUserIdentificationAssociation response: %s\n", indent.c_str(),
- toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str());
- } else {
- dprintf(fd, "%sNo SetUserIdentificationAssociation response\n", indent.c_str());
- }
-}
-
-} // namespace impl
-
-} // namespace V2_0
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.h
deleted file mode 100644
index db2f117..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_
-#define android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_
-
-#include <android-base/result.h>
-
-#include <android/hardware/automotive/vehicle/2.0/types.h>
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-constexpr char kUserHalDumpOption[] = "--user-hal";
-
-/**
- * Class used to emulate User HAL behavior through lshal debug requests.
- */
-class EmulatedUserHal {
- public:
- EmulatedUserHal() {}
-
- ~EmulatedUserHal() = default;
-
- /**
- * Checks if the emulator can handle the property.
- */
- bool isSupported(int32_t prop);
-
- /**
- * Lets the emulator set the property.
- *
- * @return updated property and StatusCode
- */
- android::base::Result<std::unique_ptr<VehiclePropValue>> onSetProperty(
- const VehiclePropValue& value);
-
- /**
- * Gets the property value from the emulator.
- *
- * @return property value and StatusCode
- */
- android::base::Result<std::unique_ptr<VehiclePropValue>> onGetProperty(
- const VehiclePropValue& value);
-
- /**
- * Shows the User HAL emulation help.
- */
- void showDumpHelp(int fd);
-
- /**
- * Dump its contents.
- */
- void dump(int fd, std::string indent);
-
- private:
- /**
- * INITIAL_USER_INFO is called by Android when it starts, and it's expecting a property change
- * indicating what the initial user should be.
- *
- * During normal circumstances, the emulator will reply right away, passing a response if
- * InitialUserInfoResponseAction::DEFAULT (so Android could use its own logic to decide which
- * user to boot).
- *
- * But during development / testing, the behavior can be changed using lshal dump, which must
- * use the areaId to indicate what should happen next.
- *
- * So, the behavior of set(INITIAL_USER_INFO) is:
- *
- * - if it has an areaId, store the property into mInitialUserResponseFromCmd (as it was called
- * by lshal).
- * - else if mInitialUserResponseFromCmd is not set, return a response with the same request id
- * and InitialUserInfoResponseAction::DEFAULT
- * - else the behavior is defined by the areaId on mInitialUserResponseFromCmd:
- * - if it's 1, reply with mInitialUserResponseFromCmd and the right request id
- * - if it's 2, reply with mInitialUserResponseFromCmd but a wrong request id (so Android can
- * test this error scenario)
- * - if it's 3, then don't send a property change (so Android can emulate a timeout)
- *
- */
- android::base::Result<std::unique_ptr<VehiclePropValue>> onSetInitialUserInfoResponse(
- const VehiclePropValue& value);
-
- /**
- * Used to emulate SWITCH_USER - see onSetInitialUserInfoResponse() for usage.
- */
- android::base::Result<std::unique_ptr<VehiclePropValue>> onSetSwitchUserResponse(
- const VehiclePropValue& value);
-
- /**
- * Used to emulate CREATE_USER - see onSetInitialUserInfoResponse() for usage.
- */
- android::base::Result<std::unique_ptr<VehiclePropValue>> onSetCreateUserResponse(
- const VehiclePropValue& value);
-
- /**
- * Used to emulate set USER_IDENTIFICATION_ASSOCIATION - see onSetInitialUserInfoResponse() for
- * usage.
- */
- android::base::Result<std::unique_ptr<VehiclePropValue>> onSetUserIdentificationAssociation(
- const VehiclePropValue& value);
-
- /**
- * Used to emulate get USER_IDENTIFICATION_ASSOCIATION - see onSetInitialUserInfoResponse() for
- * usage.
- */
- android::base::Result<std::unique_ptr<VehiclePropValue>> onGetUserIdentificationAssociation(
- const VehiclePropValue& value);
-
- /**
- * Creates a default USER_IDENTIFICATION_ASSOCIATION when it was not set by lshal.
- */
- android::base::Result<std::unique_ptr<VehiclePropValue>> defaultUserIdentificationAssociation(
- const VehiclePropValue& request);
-
- android::base::Result<std::unique_ptr<VehiclePropValue>> sendUserHalResponse(
- std::unique_ptr<VehiclePropValue> response, int32_t requestId);
-
- std::unique_ptr<VehiclePropValue> mInitialUserResponseFromCmd;
- std::unique_ptr<VehiclePropValue> mSwitchUserResponseFromCmd;
- std::unique_ptr<VehiclePropValue> mCreateUserResponseFromCmd;
- std::unique_ptr<VehiclePropValue> mSetUserIdentificationAssociationResponseFromCmd;
-};
-
-} // namespace impl
-
-} // namespace V2_0
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
-
-#endif // android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
deleted file mode 100644
index eae58d0..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#define LOG_TAG "automotive.vehicle@2.0-connector"
-
-#include <fstream>
-
-#include <android-base/logging.h>
-#include <utils/SystemClock.h>
-
-#include "EmulatedVehicleConnector.h"
-#include "JsonFakeValueGenerator.h"
-#include "LinearFakeValueGenerator.h"
-#include "Obd2SensorStore.h"
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-EmulatedUserHal* EmulatedVehicleConnector::getEmulatedUserHal() {
- return &mEmulatedUserHal;
-}
-
-void EmulatedVehicleConnector::triggerSendAllValues() {
- sendAllValuesToClient();
-}
-
-StatusCode EmulatedVehicleConnector::onSetProperty(const VehiclePropValue& value,
- bool updateStatus) {
- if (mEmulatedUserHal.isSupported(value.prop)) {
- LOG(INFO) << "onSetProperty(): property " << value.prop << " will be handled by UserHal";
-
- const auto& ret = mEmulatedUserHal.onSetProperty(value);
- if (!ret.ok()) {
- LOG(ERROR) << "onSetProperty(): HAL returned error: " << ret.error().message();
- return StatusCode(ret.error().code());
- }
- auto updatedValue = ret.value().get();
- if (updatedValue != nullptr) {
- LOG(INFO) << "onSetProperty(): updating property returned by HAL: "
- << toString(*updatedValue);
- onPropertyValueFromCar(*updatedValue, updateStatus);
- }
- return StatusCode::OK;
- }
- return this->VehicleHalServer::onSetProperty(value, updateStatus);
-}
-
-bool EmulatedVehicleConnector::onDump(const hidl_handle& handle,
- const hidl_vec<hidl_string>& options) {
- int fd = handle->data[0];
-
- if (options.size() > 0) {
- if (options[0] == "--help") {
- dprintf(fd, "Emulator-specific usage:\n");
- mEmulatedUserHal.showDumpHelp(fd);
- dprintf(fd, "\n");
- // Include caller's help options
- return true;
- } else if (options[0] == kUserHalDumpOption) {
- mEmulatedUserHal.dump(fd, "");
- return false;
-
- } else {
- // Let caller handle the options...
- return true;
- }
- }
-
- dprintf(fd, "Emulator-specific state:\n");
- mEmulatedUserHal.dump(fd, " ");
- dprintf(fd, "\n");
-
- return true;
-}
-
-} // namespace impl
-
-} // namespace V2_0
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
deleted file mode 100644
index 31ac7d8..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleConnector_H_
-#define android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleConnector_H_
-
-#include <vhal_v2_0/VehicleConnector.h>
-
-#include "EmulatedUserHal.h"
-#include "VehicleHalClient.h"
-#include "VehicleHalServer.h"
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-class EmulatedVehicleConnector : public IPassThroughConnector<VehicleHalClient, VehicleHalServer> {
- public:
- EmulatedVehicleConnector() = default;
-
- EmulatedUserHal* getEmulatedUserHal();
-
- // Methods from VehicleHalServer
- void triggerSendAllValues() override;
-
- StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) override;
-
- bool onDump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
-
- private:
- EmulatedUserHal mEmulatedUserHal;
-};
-
-} // namespace impl
-
-} // namespace V2_0
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
-
-#endif // android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleConnector_H_
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
deleted file mode 100644
index e8b79dc..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-#define LOG_TAG "DefaultVehicleHal_v2_0"
-
-#include <android-base/chrono_utils.h>
-#include <android-base/macros.h>
-#include <android-base/properties.h>
-#include <android/log.h>
-#include <dirent.h>
-#include <sys/system_properties.h>
-#include <utils/SystemClock.h>
-#include <fstream>
-#include <regex>
-
-#include "EmulatedVehicleHal.h"
-#include "JsonFakeValueGenerator.h"
-#include "LinearFakeValueGenerator.h"
-#include "Obd2SensorStore.h"
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-static constexpr std::chrono::nanoseconds kHeartBeatIntervalNs = 3s;
-
-static std::unique_ptr<Obd2SensorStore> fillDefaultObd2Frame(size_t numVendorIntegerSensors,
- size_t numVendorFloatSensors) {
- std::unique_ptr<Obd2SensorStore> sensorStore(
- new Obd2SensorStore(numVendorIntegerSensors, numVendorFloatSensors));
-
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::FUEL_SYSTEM_STATUS,
- toInt(Obd2FuelSystemStatus::CLOSED_LOOP));
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON, 0);
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::IGNITION_MONITORS_SUPPORTED,
- toInt(Obd2IgnitionMonitorKind::SPARK));
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::IGNITION_SPECIFIC_MONITORS,
- Obd2CommonIgnitionMonitors::COMPONENTS_AVAILABLE |
- Obd2CommonIgnitionMonitors::MISFIRE_AVAILABLE |
- Obd2SparkIgnitionMonitors::AC_REFRIGERANT_AVAILABLE |
- Obd2SparkIgnitionMonitors::EVAPORATIVE_SYSTEM_AVAILABLE);
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::INTAKE_AIR_TEMPERATURE, 35);
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::COMMANDED_SECONDARY_AIR_STATUS,
- toInt(Obd2SecondaryAirStatus::FROM_OUTSIDE_OR_OFF));
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT, 1);
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::RUNTIME_SINCE_ENGINE_START, 500);
- sensorStore->setIntegerSensor(
- DiagnosticIntegerSensorIndex::DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON, 0);
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::WARMUPS_SINCE_CODES_CLEARED, 51);
- sensorStore->setIntegerSensor(
- DiagnosticIntegerSensorIndex::DISTANCE_TRAVELED_SINCE_CODES_CLEARED, 365);
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::ABSOLUTE_BAROMETRIC_PRESSURE, 30);
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::CONTROL_MODULE_VOLTAGE, 12);
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::AMBIENT_AIR_TEMPERATURE, 18);
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::MAX_FUEL_AIR_EQUIVALENCE_RATIO, 1);
- sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::FUEL_TYPE,
- toInt(Obd2FuelType::GASOLINE));
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::CALCULATED_ENGINE_LOAD, 0.153);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1, -0.16);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1, -0.16);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK2, -0.16);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK2, -0.16);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::INTAKE_MANIFOLD_ABSOLUTE_PRESSURE, 7.5);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ENGINE_RPM, 1250.);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::VEHICLE_SPEED, 40.);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::TIMING_ADVANCE, 2.5);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::THROTTLE_POSITION, 19.75);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::OXYGEN_SENSOR1_VOLTAGE, 0.265);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::FUEL_TANK_LEVEL_INPUT, 0.824);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::EVAPORATION_SYSTEM_VAPOR_PRESSURE,
- -0.373);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::CATALYST_TEMPERATURE_BANK1_SENSOR1,
- 190.);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::RELATIVE_THROTTLE_POSITION, 3.);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ABSOLUTE_THROTTLE_POSITION_B, 0.306);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ACCELERATOR_PEDAL_POSITION_D, 0.188);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ACCELERATOR_PEDAL_POSITION_E, 0.094);
- sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::COMMANDED_THROTTLE_ACTUATOR, 0.024);
-
- return sensorStore;
-}
-
-EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client,
- EmulatedUserHal* emulatedUserHal)
- : mPropStore(propStore),
- mHvacPowerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)),
- mRecurrentTimer(std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer, this,
- std::placeholders::_1)),
- mVehicleClient(client),
- mEmulatedUserHal(emulatedUserHal) {
- initStaticConfig();
- mVehicleClient->registerPropertyValueCallback(std::bind(&EmulatedVehicleHal::onPropertyValue,
- this, std::placeholders::_1,
- std::placeholders::_2));
-
- mInitVhalValueOverride =
- android::base::GetBoolProperty("persist.vendor.vhal_init_value_override", false);
- if (mInitVhalValueOverride) {
- getAllPropertiesOverride();
- }
-}
-
-void EmulatedVehicleHal::getAllPropertiesOverride() {
- if (auto dir = opendir("/vendor/etc/vhaloverride/")) {
- std::regex reg_json(".*[.]json", std::regex::icase);
- while (auto f = readdir(dir)) {
- if (!regex_match(f->d_name, reg_json)) {
- continue;
- }
- std::string file = "/vendor/etc/vhaloverride/" + std::string(f->d_name);
- JsonFakeValueGenerator tmpGenerator(file);
-
- std::vector<VehiclePropValue> propvalues = tmpGenerator.getAllEvents();
- mVehiclePropertiesOverride.insert(std::end(mVehiclePropertiesOverride),
- std::begin(propvalues), std::end(propvalues));
- }
- closedir(dir);
- }
-}
-
-VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::get(
- const VehiclePropValue& requestedPropValue, StatusCode* outStatus) {
- auto propId = requestedPropValue.prop;
- ALOGV("get(%d)", propId);
-
- auto& pool = *getValuePool();
- VehiclePropValuePtr v = nullptr;
-
- switch (propId) {
- case OBD2_FREEZE_FRAME:
- v = pool.obtainComplex();
- *outStatus = fillObd2FreezeFrame(requestedPropValue, v.get());
- break;
- case OBD2_FREEZE_FRAME_INFO:
- v = pool.obtainComplex();
- *outStatus = fillObd2DtcInfo(v.get());
- break;
- default:
- if (mEmulatedUserHal != nullptr && mEmulatedUserHal->isSupported(propId)) {
- ALOGI("get(): getting value for prop %d from User HAL", propId);
- const auto& ret = mEmulatedUserHal->onGetProperty(requestedPropValue);
- if (!ret.ok()) {
- ALOGE("get(): User HAL returned error: %s", ret.error().message().c_str());
- *outStatus = StatusCode(ret.error().code());
- } else {
- auto value = ret.value().get();
- if (value != nullptr) {
- ALOGI("get(): User HAL returned value: %s", toString(*value).c_str());
- v = getValuePool()->obtain(*value);
- *outStatus = StatusCode::OK;
- } else {
- ALOGE("get(): User HAL returned null value");
- *outStatus = StatusCode::INTERNAL_ERROR;
- }
- }
- break;
- }
-
- auto internalPropValue = mPropStore->readValueOrNull(requestedPropValue);
- if (internalPropValue != nullptr) {
- v = getValuePool()->obtain(*internalPropValue);
- }
-
- if (!v) {
- *outStatus = StatusCode::INVALID_ARG;
- } else if (v->status == VehiclePropertyStatus::AVAILABLE) {
- *outStatus = StatusCode::OK;
- } else {
- *outStatus = StatusCode::TRY_AGAIN;
- }
- break;
- }
- if (v.get()) {
- v->timestamp = elapsedRealtimeNano();
- }
- return v;
-}
-
-bool EmulatedVehicleHal::dump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) {
- return mVehicleClient->dump(fd, options);
-}
-
-StatusCode EmulatedVehicleHal::set(const VehiclePropValue& propValue) {
- constexpr bool updateStatus = false;
-
- if (propValue.prop == kGenerateFakeDataControllingProperty) {
- // Send the generator controlling request to the server.
- // 'updateStatus' flag is only for the value sent by setProperty (propValue in this case)
- // instead of the generated values triggered by it. 'propValue' works as a control signal
- // here, since we never send the control signal back, the value of 'updateStatus' flag
- // does not matter here.
- auto status = mVehicleClient->setProperty(propValue, updateStatus);
- return status;
- } else if (mHvacPowerProps.count(propValue.prop)) {
- auto hvacPowerOn = mPropStore->readValueOrNull(
- toInt(VehicleProperty::HVAC_POWER_ON),
- (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT |
- VehicleAreaSeat::ROW_2_LEFT | VehicleAreaSeat::ROW_2_CENTER |
- VehicleAreaSeat::ROW_2_RIGHT));
-
- if (hvacPowerOn && hvacPowerOn->value.int32Values.size() == 1
- && hvacPowerOn->value.int32Values[0] == 0) {
- return StatusCode::NOT_AVAILABLE;
- }
- } else {
- // Handle property specific code
- switch (propValue.prop) {
- case OBD2_FREEZE_FRAME_CLEAR:
- return clearObd2FreezeFrames(propValue);
- case VEHICLE_MAP_SERVICE:
- // Placeholder for future implementation of VMS property in the default hal. For
- // now, just returns OK; otherwise, hal clients crash with property not supported.
- return StatusCode::OK;
- }
- }
-
- if (propValue.status != VehiclePropertyStatus::AVAILABLE) {
- // Android side cannot set property status - this value is the
- // purview of the HAL implementation to reflect the state of
- // its underlying hardware
- return StatusCode::INVALID_ARG;
- }
- auto currentPropValue = mPropStore->readValueOrNull(propValue);
-
- if (currentPropValue == nullptr) {
- return StatusCode::INVALID_ARG;
- }
- if (currentPropValue->status != VehiclePropertyStatus::AVAILABLE) {
- // do not allow Android side to set() a disabled/error property
- return StatusCode::NOT_AVAILABLE;
- }
-
- if (mInEmulator && propValue.prop == toInt(VehicleProperty::DISPLAY_BRIGHTNESS)) {
- // Emulator does not support remote brightness control, b/139959479
- // do not send it down so that it does not bring unnecessary property change event
- // return other error code, such NOT_AVAILABLE, causes Emulator to be freezing
- // TODO: return StatusCode::NOT_AVAILABLE once the above issue is fixed
- return StatusCode::OK;
- }
-
- /**
- * After checking all conditions, such as the property is available, a real vhal will
- * sent the events to Car ECU to take actions.
- */
-
- // Send the value to the vehicle server, the server will talk to the (real or emulated) car
- auto setValueStatus = mVehicleClient->setProperty(propValue, updateStatus);
- if (setValueStatus != StatusCode::OK) {
- return setValueStatus;
- }
-
- return StatusCode::OK;
-}
-
-static bool isDiagnosticProperty(VehiclePropConfig propConfig) {
- switch (propConfig.prop) {
- case OBD2_LIVE_FRAME:
- case OBD2_FREEZE_FRAME:
- case OBD2_FREEZE_FRAME_CLEAR:
- case OBD2_FREEZE_FRAME_INFO:
- return true;
- }
- return false;
-}
-
-// Parse supported properties list and generate vector of property values to hold current values.
-void EmulatedVehicleHal::onCreate() {
- static constexpr bool shouldUpdateStatus = true;
-
- auto configs = mVehicleClient->getAllPropertyConfig();
-
- for (const auto& cfg : configs) {
- if (isDiagnosticProperty(cfg)) {
- // do not write an initial empty value for the diagnostic properties
- // as we will initialize those separately.
- continue;
- }
-
- int32_t numAreas = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs.size();
-
- for (int i = 0; i < numAreas; i++) {
- int32_t curArea = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs[i].areaId;
-
- // Create a separate instance for each individual zone
- VehiclePropValue prop = {
- .areaId = curArea,
- .prop = cfg.prop,
- .status = VehiclePropertyStatus::UNAVAILABLE,
- };
-
- if (mInitVhalValueOverride) {
- for (auto& itOverride : mVehiclePropertiesOverride) {
- if (itOverride.prop == cfg.prop) {
- prop.status = VehiclePropertyStatus::AVAILABLE;
- prop.value = itOverride.value;
- }
- }
- }
- mPropStore->writeValue(prop, shouldUpdateStatus);
- }
- }
-
- mVehicleClient->triggerSendAllValues();
-
- initObd2LiveFrame(*mPropStore->getConfigOrDie(OBD2_LIVE_FRAME));
- initObd2FreezeFrame(*mPropStore->getConfigOrDie(OBD2_FREEZE_FRAME));
- mInEmulator = isInEmulator();
- ALOGD("mInEmulator=%s", mInEmulator ? "true" : "false");
- mRecurrentTimer.registerRecurrentEvent(kHeartBeatIntervalNs,
- static_cast<int32_t>(VehicleProperty::VHAL_HEARTBEAT));
-}
-
-std::vector<VehiclePropConfig> EmulatedVehicleHal::listProperties() {
- return mPropStore->getAllConfigs();
-}
-
-void EmulatedVehicleHal::onContinuousPropertyTimer(const std::vector<int32_t>& properties) {
- VehiclePropValuePtr v;
-
- auto& pool = *getValuePool();
-
- for (int32_t property : properties) {
- if (isContinuousProperty(property)) {
- auto internalPropValue = mPropStore->readValueOrNull(property);
- if (internalPropValue != nullptr) {
- v = pool.obtain(*internalPropValue);
- }
- } else if (property == static_cast<int32_t>(VehicleProperty::VHAL_HEARTBEAT)) {
- // VHAL_HEARTBEAT is not a continuous value, but it needs to be updated periodically.
- // So, the update is done through onContinuousPropertyTimer.
- v = doInternalHealthCheck();
- } else {
- ALOGE("Unexpected onContinuousPropertyTimer for property: 0x%x", property);
- }
-
- if (v.get()) {
- v->timestamp = elapsedRealtimeNano();
- doHalEvent(std::move(v));
- }
- }
-}
-
-StatusCode EmulatedVehicleHal::subscribe(int32_t property, float sampleRate) {
- ALOGI("%s propId: 0x%x, sampleRate: %f", __func__, property, sampleRate);
-
- if (isContinuousProperty(property)) {
- mRecurrentTimer.registerRecurrentEvent(hertzToNanoseconds(sampleRate), property);
- }
- return StatusCode::OK;
-}
-
-StatusCode EmulatedVehicleHal::unsubscribe(int32_t property) {
- ALOGI("%s propId: 0x%x", __func__, property);
- if (isContinuousProperty(property)) {
- mRecurrentTimer.unregisterRecurrentEvent(property);
- }
- return StatusCode::OK;
-}
-
-bool EmulatedVehicleHal::isContinuousProperty(int32_t propId) const {
- const VehiclePropConfig* config = mPropStore->getConfigOrNull(propId);
- if (config == nullptr) {
- ALOGW("Config not found for property: 0x%x", propId);
- return false;
- }
- return config->changeMode == VehiclePropertyChangeMode::CONTINUOUS;
-}
-
-bool EmulatedVehicleHal::setPropertyFromVehicle(const VehiclePropValue& propValue) {
- constexpr bool updateStatus = true;
- return mVehicleClient->setProperty(propValue, updateStatus) == StatusCode::OK;
-}
-
-std::vector<VehiclePropValue> EmulatedVehicleHal::getAllProperties() const {
- return mPropStore->readAllValues();
-}
-
-void EmulatedVehicleHal::onPropertyValue(const VehiclePropValue& value, bool updateStatus) {
- VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(value);
-
- if (mPropStore->writeValue(*updatedPropValue, updateStatus)) {
- getEmulatorOrDie()->doSetValueFromClient(*updatedPropValue);
- doHalEvent(std::move(updatedPropValue));
- }
-}
-
-void EmulatedVehicleHal::initStaticConfig() {
- auto configs = mVehicleClient->getAllPropertyConfig();
- for (auto&& cfg : configs) {
- VehiclePropertyStore::TokenFunction tokenFunction = nullptr;
-
- switch (cfg.prop) {
- case OBD2_FREEZE_FRAME: {
- tokenFunction = [](const VehiclePropValue& propValue) {
- return propValue.timestamp;
- };
- break;
- }
- default:
- break;
- }
-
- mPropStore->registerProperty(cfg, tokenFunction);
- }
-}
-
-void EmulatedVehicleHal::initObd2LiveFrame(const VehiclePropConfig& propConfig) {
- static constexpr bool shouldUpdateStatus = true;
-
- auto liveObd2Frame = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
- auto sensorStore = fillDefaultObd2Frame(static_cast<size_t>(propConfig.configArray[0]),
- static_cast<size_t>(propConfig.configArray[1]));
- sensorStore->fillPropValue("", liveObd2Frame.get());
- liveObd2Frame->prop = OBD2_LIVE_FRAME;
-
- mPropStore->writeValue(*liveObd2Frame, shouldUpdateStatus);
-}
-
-void EmulatedVehicleHal::initObd2FreezeFrame(const VehiclePropConfig& propConfig) {
- static constexpr bool shouldUpdateStatus = true;
-
- auto sensorStore = fillDefaultObd2Frame(static_cast<size_t>(propConfig.configArray[0]),
- static_cast<size_t>(propConfig.configArray[1]));
-
- static std::vector<std::string> sampleDtcs = {"P0070",
- "P0102"
- "P0123"};
- for (auto&& dtc : sampleDtcs) {
- auto freezeFrame = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
- sensorStore->fillPropValue(dtc, freezeFrame.get());
- freezeFrame->prop = OBD2_FREEZE_FRAME;
-
- mPropStore->writeValue(*freezeFrame, shouldUpdateStatus);
- }
-}
-
-StatusCode EmulatedVehicleHal::fillObd2FreezeFrame(const VehiclePropValue& requestedPropValue,
- VehiclePropValue* outValue) {
- if (requestedPropValue.value.int64Values.size() != 1) {
- ALOGE("asked for OBD2_FREEZE_FRAME without valid timestamp");
- return StatusCode::INVALID_ARG;
- }
- auto timestamp = requestedPropValue.value.int64Values[0];
- auto freezeFrame = mPropStore->readValueOrNull(OBD2_FREEZE_FRAME, 0, timestamp);
- if (freezeFrame == nullptr) {
- ALOGE("asked for OBD2_FREEZE_FRAME at invalid timestamp");
- return StatusCode::INVALID_ARG;
- }
- outValue->prop = OBD2_FREEZE_FRAME;
- outValue->value.int32Values = freezeFrame->value.int32Values;
- outValue->value.floatValues = freezeFrame->value.floatValues;
- outValue->value.bytes = freezeFrame->value.bytes;
- outValue->value.stringValue = freezeFrame->value.stringValue;
- outValue->timestamp = freezeFrame->timestamp;
- return StatusCode::OK;
-}
-
-StatusCode EmulatedVehicleHal::clearObd2FreezeFrames(const VehiclePropValue& propValue) {
- if (propValue.value.int64Values.size() == 0) {
- mPropStore->removeValuesForProperty(OBD2_FREEZE_FRAME);
- return StatusCode::OK;
- } else {
- for (int64_t timestamp : propValue.value.int64Values) {
- auto freezeFrame = mPropStore->readValueOrNull(OBD2_FREEZE_FRAME, 0, timestamp);
- if (freezeFrame == nullptr) {
- ALOGE("asked for OBD2_FREEZE_FRAME at invalid timestamp");
- return StatusCode::INVALID_ARG;
- }
- mPropStore->removeValue(*freezeFrame);
- }
- }
- return StatusCode::OK;
-}
-
-StatusCode EmulatedVehicleHal::fillObd2DtcInfo(VehiclePropValue* outValue) {
- std::vector<int64_t> timestamps;
- for (const auto& freezeFrame : mPropStore->readValuesForProperty(OBD2_FREEZE_FRAME)) {
- timestamps.push_back(freezeFrame.timestamp);
- }
- outValue->value.int64Values = timestamps;
- outValue->prop = OBD2_FREEZE_FRAME_INFO;
- return StatusCode::OK;
-}
-
-VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::doInternalHealthCheck() {
- VehicleHal::VehiclePropValuePtr v = nullptr;
-
- // This is an example of very simpe health checking. VHAL is considered healthy if we can read
- // PERF_VEHICLE_SPEED. The more comprehensive health checking is required.
- VehiclePropValue propValue = {
- .prop = static_cast<int32_t>(VehicleProperty::PERF_VEHICLE_SPEED),
- };
- auto internalPropValue = mPropStore->readValueOrNull(propValue);
- if (internalPropValue != nullptr) {
- v = createVhalHeartBeatProp();
- } else {
- ALOGW("VHAL health check failed");
- }
- return v;
-}
-
-VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::createVhalHeartBeatProp() {
- VehicleHal::VehiclePropValuePtr v = getValuePool()->obtainInt64(uptimeMillis());
- v->prop = static_cast<int32_t>(VehicleProperty::VHAL_HEARTBEAT);
- v->areaId = 0;
- v->status = VehiclePropertyStatus::AVAILABLE;
- return v;
-}
-
-} // impl
-
-} // namespace V2_0
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
index 7871c7b..1387f85 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -14,26 +14,14 @@
* limitations under the License.
*/
-#ifndef android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleHal_H_
-#define android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleHal_H_
+// This file is just used for soft migration from EmulatedVehicleHal to DefaultVehicleHal.
+// The virtualized VHAL that uses EmulatedVehicleHal is at a different repo and cannot be updated
+// together with this repo, so we need a soft migration. Once the rename is finished at the
+// virtualized VHAL side, this file would be removed.
-#include <map>
-#include <memory>
-#include <sys/socket.h>
-#include <thread>
-#include <unordered_set>
+#pragma once
-#include <utils/SystemClock.h>
-
-#include <vhal_v2_0/RecurrentTimer.h>
-#include <vhal_v2_0/VehicleHal.h>
-#include "vhal_v2_0/VehiclePropertyStore.h"
-
-#include "EmulatedUserHal.h"
-#include "EmulatedVehicleConnector.h"
-#include "GeneratorHub.h"
-#include "PropertyUtils.h"
-#include "VehicleEmulator.h"
+#include "DefaultVehicleHal.h"
namespace android {
namespace hardware {
@@ -43,66 +31,16 @@
namespace impl {
-/** Implementation of VehicleHal that connected to emulator instead of real vehicle network. */
-class EmulatedVehicleHal : public EmulatedVehicleHalIface {
-public:
- EmulatedVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client,
- EmulatedUserHal* emulatedUserHal = nullptr);
- ~EmulatedVehicleHal() = default;
-
- // Methods from VehicleHal
- void onCreate() override;
- std::vector<VehiclePropConfig> listProperties() override;
- VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
- StatusCode* outStatus) override;
- StatusCode set(const VehiclePropValue& propValue) override;
- StatusCode subscribe(int32_t property, float sampleRate) override;
- StatusCode unsubscribe(int32_t property) override;
- bool dump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
-
- // Methods from EmulatedVehicleHalIface
- bool setPropertyFromVehicle(const VehiclePropValue& propValue) override;
- std::vector<VehiclePropValue> getAllProperties() const override;
- void getAllPropertiesOverride();
-
-private:
- constexpr std::chrono::nanoseconds hertzToNanoseconds(float hz) const {
- return std::chrono::nanoseconds(static_cast<int64_t>(1000000000L / hz));
- }
-
- StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request);
- void onPropertyValue(const VehiclePropValue& value, bool updateStatus);
-
- void onContinuousPropertyTimer(const std::vector<int32_t>& properties);
- bool isContinuousProperty(int32_t propId) const;
- void initStaticConfig();
- void initObd2LiveFrame(const VehiclePropConfig& propConfig);
- void initObd2FreezeFrame(const VehiclePropConfig& propConfig);
- StatusCode fillObd2FreezeFrame(const VehiclePropValue& requestedPropValue,
- VehiclePropValue* outValue);
- StatusCode fillObd2DtcInfo(VehiclePropValue* outValue);
- StatusCode clearObd2FreezeFrames(const VehiclePropValue& propValue);
- VehicleHal::VehiclePropValuePtr doInternalHealthCheck();
- VehicleHal::VehiclePropValuePtr createVhalHeartBeatProp();
-
- /* Private members */
- VehiclePropertyStore* mPropStore;
- std::unordered_set<int32_t> mHvacPowerProps;
- RecurrentTimer mRecurrentTimer;
- VehicleHalClient* mVehicleClient;
- bool mInEmulator;
- bool mInitVhalValueOverride;
- std::vector<VehiclePropValue> mVehiclePropertiesOverride;
- EmulatedUserHal* mEmulatedUserHal;
+class EmulatedVehicleHal : public DefaultVehicleHal {
+ public:
+ EmulatedVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client)
+ : DefaultVehicleHal(propStore, client){};
};
-} // impl
+} // namespace impl
} // namespace V2_0
} // namespace vehicle
} // namespace automotive
} // namespace hardware
} // namespace android
-
-
-#endif // android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleHal_H_
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/PipeComm.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/PipeComm.cpp
deleted file mode 100644
index 81e7c78..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/PipeComm.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#define LOG_TAG "PipeComm"
-
-#include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
-#include <log/log.h>
-
-#include "PipeComm.h"
-#include "qemu_pipe.h"
-
-#define CAR_SERVICE_NAME "pipe:qemud:car"
-
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-PipeComm::PipeComm(MessageProcessor* messageProcessor) : CommConn(messageProcessor), mPipeFd(-1) {}
-
-void PipeComm::start() {
- int fd = qemu_pipe_open(CAR_SERVICE_NAME);
-
- if (fd < 0) {
- ALOGE("%s: Could not open connection to service: %s %d", __FUNCTION__, strerror(errno), fd);
- return;
- }
-
- ALOGI("%s: Starting pipe connection, fd=%d", __FUNCTION__, fd);
- mPipeFd = fd;
-
- CommConn::start();
-}
-
-void PipeComm::stop() {
- if (mPipeFd > 0) {
- ::close(mPipeFd);
- mPipeFd = -1;
- }
- CommConn::stop();
-}
-
-std::vector<uint8_t> PipeComm::read() {
- static constexpr int MAX_RX_MSG_SZ = 2048;
- std::vector<uint8_t> msg = std::vector<uint8_t>(MAX_RX_MSG_SZ);
- int numBytes;
-
- numBytes = qemu_pipe_frame_recv(mPipeFd, msg.data(), msg.size());
-
- if (numBytes == MAX_RX_MSG_SZ) {
- ALOGE("%s: Received max size = %d", __FUNCTION__, MAX_RX_MSG_SZ);
- } else if (numBytes > 0) {
- msg.resize(numBytes);
- return msg;
- } else {
- ALOGD("%s: Connection terminated on pipe %d, numBytes=%d", __FUNCTION__, mPipeFd, numBytes);
- mPipeFd = -1;
- }
-
- return std::vector<uint8_t>();
-}
-
-int PipeComm::write(const std::vector<uint8_t>& data) {
- int retVal = 0;
-
- if (mPipeFd != -1) {
- retVal = qemu_pipe_frame_send(mPipeFd, data.data(), data.size());
- }
-
- if (retVal < 0) {
- retVal = -errno;
- ALOGE("%s: send_cmd: (fd=%d): ERROR: %s", __FUNCTION__, mPipeFd, strerror(errno));
- }
-
- return retVal;
-}
-
-
-} // impl
-
-} // namespace V2_0
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
-
-
-
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/PipeComm.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/PipeComm.h
deleted file mode 100644
index c8eabb8..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/PipeComm.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef android_hardware_automotive_vehicle_V2_0_impl_PipeComm_H_
-#define android_hardware_automotive_vehicle_V2_0_impl_PipeComm_H_
-
-#include <mutex>
-#include <vector>
-#include "CommConn.h"
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-/**
- * PipeComm opens a qemu pipe to connect to the emulator, allowing the emulator UI to access the
- * Vehicle HAL and simulate changing properties.
- *
- * Since the pipe is a client, it directly implements CommConn, and only one PipeComm can be open
- * at a time.
- */
-class PipeComm : public CommConn {
- public:
- PipeComm(MessageProcessor* messageProcessor);
-
- void start() override;
- void stop() override;
-
- std::vector<uint8_t> read() override;
- int write(const std::vector<uint8_t>& data) override;
-
- inline bool isOpen() override { return mPipeFd > 0; }
-
- private:
- int mPipeFd;
-};
-
-} // impl
-
-} // namespace V2_0
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
-
-
-#endif // android_hardware_automotive_vehicle_V2_0_impl_PipeComm_H_
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.cpp
deleted file mode 100644
index 916c320..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#define LOG_TAG "SocketComm"
-
-#include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
-#include <android/log.h>
-#include <arpa/inet.h>
-#include <log/log.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-
-#include "SocketComm.h"
-
-// Socket to use when communicating with Host PC
-static constexpr int DEBUG_SOCKET = 33452;
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-SocketComm::SocketComm(MessageProcessor* messageProcessor)
- : mListenFd(-1), mMessageProcessor(messageProcessor) {}
-
-SocketComm::~SocketComm() {
-}
-
-void SocketComm::start() {
- if (!listen()) {
- return;
- }
-
- mListenThread = std::make_unique<std::thread>(std::bind(&SocketComm::listenThread, this));
-}
-
-void SocketComm::stop() {
- if (mListenFd > 0) {
- ::close(mListenFd);
- if (mListenThread->joinable()) {
- mListenThread->join();
- }
- mListenFd = -1;
- }
-}
-
-void SocketComm::sendMessage(vhal_proto::EmulatorMessage const& msg) {
- std::lock_guard<std::mutex> lock(mMutex);
- for (std::unique_ptr<SocketConn> const& conn : mOpenConnections) {
- conn->sendMessage(msg);
- }
-}
-
-bool SocketComm::listen() {
- int retVal;
- struct sockaddr_in servAddr;
-
- mListenFd = socket(AF_INET, SOCK_STREAM, 0);
- if (mListenFd < 0) {
- ALOGE("%s: socket() failed, mSockFd=%d, errno=%d", __FUNCTION__, mListenFd, errno);
- mListenFd = -1;
- return false;
- }
-
- memset(&servAddr, 0, sizeof(servAddr));
- servAddr.sin_family = AF_INET;
- servAddr.sin_addr.s_addr = INADDR_ANY;
- servAddr.sin_port = htons(DEBUG_SOCKET);
-
- retVal = bind(mListenFd, reinterpret_cast<struct sockaddr*>(&servAddr), sizeof(servAddr));
- if(retVal < 0) {
- ALOGE("%s: Error on binding: retVal=%d, errno=%d", __FUNCTION__, retVal, errno);
- close(mListenFd);
- mListenFd = -1;
- return false;
- }
-
- ALOGI("%s: Listening for connections on port %d", __FUNCTION__, DEBUG_SOCKET);
- if (::listen(mListenFd, 1) == -1) {
- ALOGE("%s: Error on listening: errno: %d: %s", __FUNCTION__, errno, strerror(errno));
- return false;
- }
- return true;
-}
-
-SocketConn* SocketComm::accept() {
- sockaddr_in cliAddr;
- socklen_t cliLen = sizeof(cliAddr);
- int sfd = ::accept(mListenFd, reinterpret_cast<struct sockaddr*>(&cliAddr), &cliLen);
-
- if (sfd > 0) {
- char addr[INET_ADDRSTRLEN];
- inet_ntop(AF_INET, &cliAddr.sin_addr, addr, INET_ADDRSTRLEN);
-
- ALOGD("%s: Incoming connection received from %s:%d", __FUNCTION__, addr, cliAddr.sin_port);
- return new SocketConn(mMessageProcessor, sfd);
- }
-
- return nullptr;
-}
-
-void SocketComm::listenThread() {
- while (true) {
- SocketConn* conn = accept();
- if (conn == nullptr) {
- return;
- }
-
- conn->start();
- {
- std::lock_guard<std::mutex> lock(mMutex);
- mOpenConnections.push_back(std::unique_ptr<SocketConn>(conn));
- }
- }
-}
-
-/**
- * Called occasionally to clean up connections that have been closed.
- */
-void SocketComm::removeClosedConnections() {
- std::lock_guard<std::mutex> lock(mMutex);
- std::remove_if(mOpenConnections.begin(), mOpenConnections.end(),
- [](std::unique_ptr<SocketConn> const& c) { return !c->isOpen(); });
-}
-
-SocketConn::SocketConn(MessageProcessor* messageProcessor, int sfd)
- : CommConn(messageProcessor), mSockFd(sfd) {}
-
-/**
- * Reads, in a loop, exactly numBytes from the given fd. If the connection is closed, returns
- * an empty buffer, otherwise will return exactly the given number of bytes.
- */
-std::vector<uint8_t> readExactly(int fd, int numBytes) {
- std::vector<uint8_t> buffer(numBytes);
- int totalRead = 0;
- int offset = 0;
- while (totalRead < numBytes) {
- int numRead = ::read(fd, &buffer.data()[offset], numBytes - offset);
- if (numRead == 0) {
- buffer.resize(0);
- return buffer;
- }
-
- totalRead += numRead;
- }
- return buffer;
-}
-
-/**
- * Reads an int, guaranteed to be non-zero, from the given fd. If the connection is closed, returns
- * -1.
- */
-int32_t readInt(int fd) {
- std::vector<uint8_t> buffer = readExactly(fd, sizeof(int32_t));
- if (buffer.size() == 0) {
- return -1;
- }
-
- int32_t value = *reinterpret_cast<int32_t*>(buffer.data());
- return ntohl(value);
-}
-
-std::vector<uint8_t> SocketConn::read() {
- int32_t msgSize = readInt(mSockFd);
- if (msgSize <= 0) {
- ALOGD("%s: Connection terminated on socket %d", __FUNCTION__, mSockFd);
- return std::vector<uint8_t>();
- }
-
- return readExactly(mSockFd, msgSize);
-}
-
-void SocketConn::stop() {
- if (mSockFd > 0) {
- close(mSockFd);
- mSockFd = -1;
- }
-}
-
-int SocketConn::write(const std::vector<uint8_t>& data) {
- static constexpr int MSG_HEADER_LEN = 4;
- int retVal = 0;
- union {
- uint32_t msgLen;
- uint8_t msgLenBytes[MSG_HEADER_LEN];
- };
-
- // Prepare header for the message
- msgLen = static_cast<uint32_t>(data.size());
- msgLen = htonl(msgLen);
-
- if (mSockFd > 0) {
- retVal = ::write(mSockFd, msgLenBytes, MSG_HEADER_LEN);
-
- if (retVal == MSG_HEADER_LEN) {
- retVal = ::write(mSockFd, data.data(), data.size());
- }
- }
-
- return retVal;
-}
-
-} // impl
-
-} // namespace V2_0
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
-
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.h
deleted file mode 100644
index 52326b9..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/SocketComm.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef android_hardware_automotive_vehicle_V2_0_impl_SocketComm_H_
-#define android_hardware_automotive_vehicle_V2_0_impl_SocketComm_H_
-
-#include <mutex>
-#include <thread>
-#include <vector>
-#include "CommConn.h"
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-class SocketConn;
-
-/**
- * SocketComm opens a socket, and listens for connections from clients. Typically the client will be
- * adb's TCP port-forwarding to enable a host PC to connect to the VehicleHAL.
- */
-class SocketComm {
- public:
- SocketComm(MessageProcessor* messageProcessor);
- virtual ~SocketComm();
-
- void start();
- void stop();
-
- /**
- * Serialized and send the given message to all connected clients.
- */
- void sendMessage(vhal_proto::EmulatorMessage const& msg);
-
- private:
- int mListenFd;
- std::unique_ptr<std::thread> mListenThread;
- std::vector<std::unique_ptr<SocketConn>> mOpenConnections;
- MessageProcessor* mMessageProcessor;
- std::mutex mMutex;
-
- /**
- * Opens the socket and begins listening.
- *
- * @return bool Returns true on success.
- */
- bool listen();
-
- /**
- * Blocks and waits for a connection from a client, returns a new SocketConn with the connection
- * or null, if the connection has been closed.
- *
- * @return int Returns fd or socket number if connection is successful.
- * Otherwise, returns -1 if no connection is availble.
- */
- SocketConn* accept();
-
- void listenThread();
-
- void removeClosedConnections();
-};
-
-/**
- * SocketConn represents a single connection to a client.
- */
-class SocketConn : public CommConn {
- public:
- SocketConn(MessageProcessor* messageProcessor, int sfd);
- virtual ~SocketConn() = default;
-
- /**
- * Blocking call to read data from the connection.
- *
- * @return std::vector<uint8_t> Serialized protobuf data received from emulator. This will be
- * an empty vector if the connection was closed or some other error occurred.
- */
- std::vector<uint8_t> read() override;
-
- /**
- * Closes a connection if it is open.
- */
- void stop() override;
-
- /**
- * Transmits a string of data to the emulator.
- *
- * @param data Serialized protobuf data to transmit.
- *
- * @return int Number of bytes transmitted, or -1 if failed.
- */
- int write(const std::vector<uint8_t>& data) override;
-
- inline bool isOpen() override { return mSockFd > 0; }
-
- private:
- int mSockFd;
-};
-
-} // impl
-
-} // namespace V2_0
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
-
-
-#endif // android_hardware_automotive_vehicle_V2_0_impl_SocketComm_H_
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp
deleted file mode 100644
index f7d0854..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-#define LOG_TAG "VehicleEmulator_v2_0"
-#include <android/log.h>
-
-#include <android-base/properties.h>
-#include <log/log.h>
-#include <utils/SystemClock.h>
-#include <algorithm>
-
-#include <vhal_v2_0/VehicleUtils.h>
-
-#include "PipeComm.h"
-#include "ProtoMessageConverter.h"
-#include "SocketComm.h"
-
-#include "VehicleEmulator.h"
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-VehicleEmulator::VehicleEmulator(EmulatedVehicleHalIface* hal) : mHal{hal} {
- mHal->registerEmulator(this);
-
- ALOGI("Starting SocketComm");
- mSocketComm = std::make_unique<SocketComm>(this);
- mSocketComm->start();
-
- if (isInEmulator()) {
- ALOGI("Starting PipeComm");
- mPipeComm = std::make_unique<PipeComm>(this);
- mPipeComm->start();
- }
-}
-
-VehicleEmulator::~VehicleEmulator() {
- mSocketComm->stop();
- if (mPipeComm) {
- mPipeComm->stop();
- }
-}
-
-/**
- * This is called by the HAL when a property changes. We need to notify our clients that it has
- * changed.
- */
-void VehicleEmulator::doSetValueFromClient(const VehiclePropValue& propValue) {
- vhal_proto::EmulatorMessage msg;
- vhal_proto::VehiclePropValue* val = msg.add_value();
- populateProtoVehiclePropValue(val, &propValue);
- msg.set_status(vhal_proto::RESULT_OK);
- msg.set_msg_type(vhal_proto::SET_PROPERTY_ASYNC);
-
- mSocketComm->sendMessage(msg);
- if (mPipeComm) {
- mPipeComm->sendMessage(msg);
- }
-}
-
-void VehicleEmulator::doGetConfig(VehicleEmulator::EmulatorMessage const& rxMsg,
- VehicleEmulator::EmulatorMessage& respMsg) {
- std::vector<VehiclePropConfig> configs = mHal->listProperties();
- vhal_proto::VehiclePropGet getProp = rxMsg.prop(0);
-
- respMsg.set_msg_type(vhal_proto::GET_CONFIG_RESP);
- respMsg.set_status(vhal_proto::ERROR_INVALID_PROPERTY);
-
- for (auto& config : configs) {
- // Find the config we are looking for
- if (config.prop == getProp.prop()) {
- vhal_proto::VehiclePropConfig* protoCfg = respMsg.add_config();
- populateProtoVehicleConfig(protoCfg, config);
- respMsg.set_status(vhal_proto::RESULT_OK);
- break;
- }
- }
-}
-
-void VehicleEmulator::doGetConfigAll(VehicleEmulator::EmulatorMessage const& /* rxMsg */,
- VehicleEmulator::EmulatorMessage& respMsg) {
- std::vector<VehiclePropConfig> configs = mHal->listProperties();
-
- respMsg.set_msg_type(vhal_proto::GET_CONFIG_ALL_RESP);
- respMsg.set_status(vhal_proto::RESULT_OK);
-
- for (auto& config : configs) {
- vhal_proto::VehiclePropConfig* protoCfg = respMsg.add_config();
- populateProtoVehicleConfig(protoCfg, config);
- }
-}
-
-void VehicleEmulator::doGetProperty(VehicleEmulator::EmulatorMessage const& rxMsg,
- VehicleEmulator::EmulatorMessage& respMsg) {
- int32_t areaId = 0;
- vhal_proto::VehiclePropGet getProp = rxMsg.prop(0);
- int32_t propId = getProp.prop();
- vhal_proto::Status status = vhal_proto::ERROR_INVALID_PROPERTY;
-
- respMsg.set_msg_type(vhal_proto::GET_PROPERTY_RESP);
-
- if (getProp.has_area_id()) {
- areaId = getProp.area_id();
- }
-
- {
- VehiclePropValue request = {
- .areaId = areaId,
- .prop = propId,
- };
- StatusCode halStatus;
- auto val = mHal->get(request, &halStatus);
- if (val != nullptr) {
- vhal_proto::VehiclePropValue* protoVal = respMsg.add_value();
- populateProtoVehiclePropValue(protoVal, val.get());
- status = vhal_proto::RESULT_OK;
- }
- }
-
- respMsg.set_status(status);
-}
-
-void VehicleEmulator::doGetPropertyAll(VehicleEmulator::EmulatorMessage const& /* rxMsg */,
- VehicleEmulator::EmulatorMessage& respMsg) {
- respMsg.set_msg_type(vhal_proto::GET_PROPERTY_ALL_RESP);
- respMsg.set_status(vhal_proto::RESULT_OK);
-
- {
- for (const auto& prop : mHal->getAllProperties()) {
- vhal_proto::VehiclePropValue* protoVal = respMsg.add_value();
- populateProtoVehiclePropValue(protoVal, &prop);
- }
- }
-}
-
-void VehicleEmulator::doSetProperty(VehicleEmulator::EmulatorMessage const& rxMsg,
- VehicleEmulator::EmulatorMessage& respMsg) {
- vhal_proto::VehiclePropValue protoVal = rxMsg.value(0);
- VehiclePropValue val = {
- .timestamp = elapsedRealtimeNano(),
- .areaId = protoVal.area_id(),
- .prop = protoVal.prop(),
- .status = (VehiclePropertyStatus)protoVal.status(),
- };
-
- respMsg.set_msg_type(vhal_proto::SET_PROPERTY_RESP);
-
- // Copy value data if it is set. This automatically handles complex data types if needed.
- if (protoVal.has_string_value()) {
- val.value.stringValue = protoVal.string_value().c_str();
- }
-
- if (protoVal.has_bytes_value()) {
- val.value.bytes = std::vector<uint8_t> { protoVal.bytes_value().begin(),
- protoVal.bytes_value().end() };
- }
-
- if (protoVal.int32_values_size() > 0) {
- val.value.int32Values = std::vector<int32_t> { protoVal.int32_values().begin(),
- protoVal.int32_values().end() };
- }
-
- if (protoVal.int64_values_size() > 0) {
- val.value.int64Values = std::vector<int64_t> { protoVal.int64_values().begin(),
- protoVal.int64_values().end() };
- }
-
- if (protoVal.float_values_size() > 0) {
- val.value.floatValues = std::vector<float> { protoVal.float_values().begin(),
- protoVal.float_values().end() };
- }
-
- bool halRes = mHal->setPropertyFromVehicle(val);
- respMsg.set_status(halRes ? vhal_proto::RESULT_OK : vhal_proto::ERROR_INVALID_PROPERTY);
-}
-
-void VehicleEmulator::processMessage(vhal_proto::EmulatorMessage const& rxMsg,
- vhal_proto::EmulatorMessage& respMsg) {
- switch (rxMsg.msg_type()) {
- case vhal_proto::GET_CONFIG_CMD:
- doGetConfig(rxMsg, respMsg);
- break;
- case vhal_proto::GET_CONFIG_ALL_CMD:
- doGetConfigAll(rxMsg, respMsg);
- break;
- case vhal_proto::GET_PROPERTY_CMD:
- doGetProperty(rxMsg, respMsg);
- break;
- case vhal_proto::GET_PROPERTY_ALL_CMD:
- doGetPropertyAll(rxMsg, respMsg);
- break;
- case vhal_proto::SET_PROPERTY_CMD:
- doSetProperty(rxMsg, respMsg);
- break;
- default:
- ALOGW("%s: Unknown message received, type = %d", __func__, rxMsg.msg_type());
- respMsg.set_status(vhal_proto::ERROR_UNIMPLEMENTED_CMD);
- break;
- }
-}
-
-void VehicleEmulator::populateProtoVehicleConfig(vhal_proto::VehiclePropConfig* protoCfg,
- const VehiclePropConfig& cfg) {
- return proto_msg_converter::toProto(protoCfg, cfg);
-}
-
-void VehicleEmulator::populateProtoVehiclePropValue(vhal_proto::VehiclePropValue* protoVal,
- const VehiclePropValue* val) {
- return proto_msg_converter::toProto(protoVal, *val);
-}
-
-bool isInEmulator() {
- return android::base::GetBoolProperty("ro.boot.qemu", false);
-}
-
-} // impl
-
-} // namespace V2_0
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.h
deleted file mode 100644
index 434d79b..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef android_hardware_automotive_vehicle_V2_0_impl_VehicleHalEmulator_H_
-#define android_hardware_automotive_vehicle_V2_0_impl_VehicleHalEmulator_H_
-
-#include <log/log.h>
-#include <memory>
-#include <thread>
-#include <vector>
-
-#include "vhal_v2_0/VehicleHal.h"
-
-#include "CommConn.h"
-#include "PipeComm.h"
-#include "SocketComm.h"
-#include "VehicleHalProto.pb.h"
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-class VehicleEmulator; // Forward declaration.
-
-/** Extension of VehicleHal that used by VehicleEmulator. */
-class EmulatedVehicleHalIface : public VehicleHal {
-public:
- virtual bool setPropertyFromVehicle(const VehiclePropValue& propValue) = 0;
- virtual std::vector<VehiclePropValue> getAllProperties() const = 0;
-
- void registerEmulator(VehicleEmulator* emulator) {
- ALOGI("%s, emulator: %p", __func__, emulator);
- std::lock_guard<std::mutex> g(mEmulatorLock);
- mEmulator = emulator;
- }
-
-protected:
- VehicleEmulator* getEmulatorOrDie() {
- std::lock_guard<std::mutex> g(mEmulatorLock);
- if (mEmulator == nullptr) abort();
- return mEmulator;
- }
-
-private:
- mutable std::mutex mEmulatorLock;
- VehicleEmulator* mEmulator;
-};
-
-/**
- * Emulates vehicle by providing controlling interface from host side either through ADB or Pipe.
- */
-class VehicleEmulator : public MessageProcessor {
- public:
- VehicleEmulator(EmulatedVehicleHalIface* hal);
- virtual ~VehicleEmulator();
-
- void doSetValueFromClient(const VehiclePropValue& propValue);
- void processMessage(vhal_proto::EmulatorMessage const& rxMsg,
- vhal_proto::EmulatorMessage& respMsg) override;
-
- private:
- friend class ConnectionThread;
- using EmulatorMessage = vhal_proto::EmulatorMessage;
-
- void doGetConfig(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
- void doGetConfigAll(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
- void doGetProperty(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
- void doGetPropertyAll(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
- void doSetProperty(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
- void populateProtoVehicleConfig(vhal_proto::VehiclePropConfig* protoCfg,
- const VehiclePropConfig& cfg);
- void populateProtoVehiclePropValue(vhal_proto::VehiclePropValue* protoVal,
- const VehiclePropValue* val);
-
-private:
- EmulatedVehicleHalIface* mHal;
- std::unique_ptr<SocketComm> mSocketComm;
- std::unique_ptr<PipeComm> mPipeComm;
-};
-
-// determine if it's running inside Android Emulator
-bool isInEmulator();
-
-} // impl
-
-} // namespace V2_0
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
-
-#endif // android_hardware_automotive_vehicle_V2_0_impl_VehicleHalEmulator_H_
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.cpp
index 25ffc6d..bafd170 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.cpp
@@ -18,7 +18,13 @@
#include <android-base/logging.h>
-namespace android::hardware::automotive::vehicle::V2_0::impl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
void VehicleHalClient::onPropertyValue(const VehiclePropValue& value, bool updateStatus) {
if (!mPropCallback) {
@@ -36,4 +42,10 @@
mPropCallback = std::move(callback);
}
-} // namespace android::hardware::automotive::vehicle::V2_0::impl
+} // namespace impl
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h
index 81dfca1..2473f19 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h
@@ -18,7 +18,13 @@
#include <vhal_v2_0/VehicleClient.h>
-namespace android::hardware::automotive::vehicle::V2_0::impl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
// The common client operations that may be used by both native and
// virtualized VHAL clients.
@@ -40,4 +46,10 @@
PropertyCallBackType mPropCallback;
};
-} // namespace android::hardware::automotive::vehicle::V2_0::impl
+} // namespace impl
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
index be88cd9..1290f30 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -14,56 +14,32 @@
* limitations under the License.
*/
+// This file is just used for soft migration from VehicleHalServer to DefaultVehicleHalServer.
+// The virtualized VHAL that uses VehichleHalServer is at a different repo and cannot be updated
+// together with this repo, so we need a soft migration. Once the rename is finished at the
+// virtualized VHAL side, this file would be removed.
+
#pragma once
-#include <vhal_v2_0/VehicleObjectPool.h>
-#include <vhal_v2_0/VehiclePropertyStore.h>
-#include <vhal_v2_0/VehicleServer.h>
+#include "DefaultVehicleHalServer.h"
-#include "GeneratorHub.h"
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
-namespace android::hardware::automotive::vehicle::V2_0::impl {
+namespace impl {
-// This contains the common server operations that will be used by
-// both native and virtualized VHAL server. Notice that in the virtualized
-// scenario, the server may be run on a different OS than Android.
-class VehicleHalServer : public IVehicleServer {
+class VehicleHalServer : public DefaultVehicleHalServer {
public:
- VehicleHalServer();
-
- void sendAllValuesToClient();
-
- // Methods from IVehicleServer
-
- std::vector<VehiclePropConfig> onGetAllPropertyConfig() const override;
-
- StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) override;
-
- // Set the Property Value Pool used in this server
- void setValuePool(VehiclePropValuePool* valuePool);
-
- private:
- using VehiclePropValuePtr = recyclable_ptr<VehiclePropValue>;
-
- GeneratorHub* getGenerator();
-
- VehiclePropValuePool* getValuePool() const;
-
- void onFakeValueGenerated(const VehiclePropValue& value);
-
- StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request);
-
- VehiclePropValuePtr createApPowerStateReq(VehicleApPowerStateReq req, int32_t param);
-
- VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode,
- int32_t targetDisplay);
-
- private:
- GeneratorHub mGeneratorHub{
- std::bind(&VehicleHalServer::onFakeValueGenerated, this, std::placeholders::_1)};
-
- VehiclePropValuePool* mValuePool{nullptr};
- VehiclePropertyStore mServerSidePropStore;
+ VehicleHalServer() : DefaultVehicleHalServer(){};
};
-} // namespace android::hardware::automotive::vehicle::V2_0::impl
+} // namespace impl
+
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp
index 6e85ae9..3307bd6 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp
@@ -24,6 +24,10 @@
cc_library_static {
name: "android.hardware.automotive.vehicle@2.0-libproto-native",
+ visibility: [
+ "//hardware/interfaces/automotive/vehicle/2.0/default:__subpackages__",
+ "//device/generic/car/emulator/vhal_v2_0:__subpackages__",
+ ],
vendor: true,
host_supported: true,
proto: {
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/qemu_pipe.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/qemu_pipe.cpp
deleted file mode 100644
index cf1a002..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/qemu_pipe.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2011 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 "qemu_pipe.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <android-base/file.h>
-
-using android::base::ReadFully;
-using android::base::WriteFully;
-
-// Define QEMU_PIPE_DEBUG if you want to print error messages when an error
-// occurs during pipe operations. The macro should simply take a printf-style
-// formatting string followed by optional arguments.
-#ifndef QEMU_PIPE_DEBUG
-#define QEMU_PIPE_DEBUG(...) (void)0
-#endif
-
-int qemu_pipe_open(const char* pipeName) {
- if (!pipeName) {
- errno = EINVAL;
- return -1;
- }
-
- int fd = TEMP_FAILURE_RETRY(open("/dev/qemu_pipe", O_RDWR));
- if (fd < 0) {
- QEMU_PIPE_DEBUG("%s: Could not open /dev/qemu_pipe: %s", __FUNCTION__, strerror(errno));
- return -1;
- }
-
- // Write the pipe name, *including* the trailing zero which is necessary.
- size_t pipeNameLen = strlen(pipeName);
- if (WriteFully(fd, pipeName, pipeNameLen + 1U)) {
- return fd;
- }
-
- // now, add 'pipe:' prefix and try again
- // Note: host side will wait for the trailing '\0' to start
- // service lookup.
- const char pipe_prefix[] = "pipe:";
- if (WriteFully(fd, pipe_prefix, strlen(pipe_prefix)) &&
- WriteFully(fd, pipeName, pipeNameLen + 1U)) {
- return fd;
- }
- QEMU_PIPE_DEBUG("%s: Could not write to %s pipe service: %s", __FUNCTION__, pipeName,
- strerror(errno));
- close(fd);
- return -1;
-}
-
-int qemu_pipe_frame_send(int fd, const void* buff, size_t len) {
- char header[5];
- snprintf(header, sizeof(header), "%04zx", len);
- if (!WriteFully(fd, header, 4)) {
- QEMU_PIPE_DEBUG("Can't write qemud frame header: %s", strerror(errno));
- return -1;
- }
- if (!WriteFully(fd, buff, len)) {
- QEMU_PIPE_DEBUG("Can't write qemud frame payload: %s", strerror(errno));
- return -1;
- }
- return 0;
-}
-
-int qemu_pipe_frame_recv(int fd, void* buff, size_t len) {
- char header[5];
- if (!ReadFully(fd, header, 4)) {
- QEMU_PIPE_DEBUG("Can't read qemud frame header: %s", strerror(errno));
- return -1;
- }
- header[4] = '\0';
- size_t size;
- if (sscanf(header, "%04zx", &size) != 1) {
- QEMU_PIPE_DEBUG("Malformed qemud frame header: [%.*s]", 4, header);
- return -1;
- }
- if (size > len) {
- QEMU_PIPE_DEBUG("Oversized qemud frame (% bytes, expected <= %)", size, len);
- return -1;
- }
- if (!ReadFully(fd, buff, size)) {
- QEMU_PIPE_DEBUG("Could not read qemud frame payload: %s", strerror(errno));
- return -1;
- }
- return size;
-}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/qemu_pipe.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/qemu_pipe.h
deleted file mode 100644
index 0987498..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/qemu_pipe.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ANDROID_CORE_INCLUDE_QEMU_PIPE_H
-#define ANDROID_CORE_INCLUDE_QEMU_PIPE_H
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-// Try to open a new Qemu fast-pipe. This function returns a file descriptor
-// that can be used to communicate with a named service managed by the
-// emulator.
-//
-// This file descriptor can be used as a standard pipe/socket descriptor.
-//
-// 'pipeName' is the name of the emulator service you want to connect to,
-// and should begin with 'pipe:' (e.g. 'pipe:camera' or 'pipe:opengles').
-// For backward compatibility, the 'pipe:' prefix can be omitted, and in
-// that case, qemu_pipe_open will add it for you.
-
-// On success, return a valid file descriptor, or -1/errno on failure. E.g.:
-//
-// EINVAL -> unknown/unsupported pipeName
-// ENOSYS -> fast pipes not available in this system.
-//
-// ENOSYS should never happen, except if you're trying to run within a
-// misconfigured emulator.
-//
-// You should be able to open several pipes to the same pipe service,
-// except for a few special cases (e.g. GSM modem), where EBUSY will be
-// returned if more than one client tries to connect to it.
-int qemu_pipe_open(const char* pipeName);
-
-// Send a framed message |buff| of |len| bytes through the |fd| descriptor.
-// This really adds a 4-hexchar prefix describing the payload size.
-// Returns 0 on success, and -1 on error.
-int qemu_pipe_frame_send(int fd, const void* buff, size_t len);
-
-// Read a frame message from |fd|, and store it into |buff| of |len| bytes.
-// If the framed message is larger than |len|, then this returns -1 and the
-// content is lost. Otherwise, this returns the size of the message. NOTE:
-// empty messages are possible in a framed wire protocol and do not mean
-// end-of-stream.
-int qemu_pipe_frame_recv(int fd, void* buff, size_t len);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ANDROID_CORE_INCLUDE_QEMU_PIPE_H */
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/ProtoMessageConverter_test.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/ProtoMessageConverter_test.cpp
index 3817e44..a507b50 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/ProtoMessageConverter_test.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/ProtoMessageConverter_test.cpp
@@ -17,9 +17,9 @@
#include <gtest/gtest.h>
#include <utils/SystemClock.h>
+#include <vhal_v2_0/ProtoMessageConverter.h>
#include "vhal_v2_0/DefaultConfig.h"
-#include "vhal_v2_0/ProtoMessageConverter.h"
#include "vhal_v2_0/VehicleUtils.h"
namespace android {