diff options
Diffstat (limited to 'emulator/vhal_v2_0/EmulatedVehicleHalServer.cpp')
-rw-r--r-- | emulator/vhal_v2_0/EmulatedVehicleHalServer.cpp | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/emulator/vhal_v2_0/EmulatedVehicleHalServer.cpp b/emulator/vhal_v2_0/EmulatedVehicleHalServer.cpp new file mode 100644 index 0000000..be4eefe --- /dev/null +++ b/emulator/vhal_v2_0/EmulatedVehicleHalServer.cpp @@ -0,0 +1,161 @@ +/* + * 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 "EmulatedVehicleHalServer" + +#include <android/binder_manager.h> +#include <utils/SystemClock.h> +#include <vhal_v2_0/VehicleUtils.h> + +#include "EmulatedVehicleHalServer.h" + +namespace android { +namespace hardware { +namespace automotive { +namespace vehicle { +namespace V2_0 { + +namespace impl { + +EmulatedVehicleHalServer::EmulatedVehicleHalServer(): DefaultVehicleHalServer() { + mInQEMU = isInQEMU(); + ALOGD("mInQEMU=%s", mInQEMU ? "true" : "false"); + + mVehicleBusCallback = ::ndk::SharedRefBase::make<VehicleBusCallback>(this); + startVehicleBuses(); +} + +EmulatedVehicleHalServer::~EmulatedVehicleHalServer() { + stopVehicleBuses(); +} + +StatusCode EmulatedVehicleHalServer::onSetProperty(const VehiclePropValue& value, + bool updateStatus) { + if (mInQEMU && value.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; + } + + return DefaultVehicleHalServer::onSetProperty(value, updateStatus); +} + +bool EmulatedVehicleHalServer::setPropertyFromVehicle(const VehiclePropValue& propValue) { + auto updatedPropValue = getValuePool()->obtain(propValue); + updatedPropValue->timestamp = elapsedRealtimeNano(); + mServerSidePropStore.writeValue(*updatedPropValue, true); + onPropertyValueFromCar(*updatedPropValue, true); + return true; +} + +std::vector<VehiclePropValue> EmulatedVehicleHalServer::getAllProperties() const { + return mServerSidePropStore.readAllValues(); +} + +std::vector<VehiclePropConfig> EmulatedVehicleHalServer::listProperties() { + return mServerSidePropStore.getAllConfigs(); +} + +EmulatedVehicleHalServer::VehiclePropValuePtr EmulatedVehicleHalServer::get( + const VehiclePropValue& requestedPropValue, StatusCode* outStatus) { + EmulatedVehicleHalServer::VehiclePropValuePtr v = nullptr; + auto prop = mServerSidePropStore.readValueOrNull(requestedPropValue); + if (prop != nullptr) { + v = getValuePool()->obtain(*prop); + } + + 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; +} + +void EmulatedVehicleHalServer::startVehicleBuses() { + std::vector<std::string> names; + AServiceManager_forEachDeclaredInstance(IVehicleBus::descriptor, static_cast<void*>(&names), + [](const char* instance, void* context) { + auto fullName = std::string(IVehicleBus::descriptor) + "/" + instance; + static_cast<std::vector<std::string>*>(context)->emplace_back(fullName); + }); + + for (const auto& fullName : names) { + ::ndk::SpAIBinder binder(AServiceManager_waitForService(fullName.c_str())); + if (binder.get() == nullptr) { + ALOGE("%s binder returned null", fullName.c_str()); + continue; + } + std::shared_ptr<IVehicleBus> vehicleBus = IVehicleBus::fromBinder(binder); + if (vehicleBus == nullptr) { + ALOGE("Couldn't open %s", fullName.c_str()); + continue; + } + + vehicleBus->setOnNewPropValuesCallback(mVehicleBusCallback); + mVehicleBuses.push_back(vehicleBus); + } +} + +void EmulatedVehicleHalServer::stopVehicleBuses() { + for (const auto& vehicleBus : mVehicleBuses) { + vehicleBus->unsetOnNewPropValuesCallback(mVehicleBusCallback); + } +} + +VehiclePropValue EmulatedVehicleHalServer::VehicleBusCallback::makeHidlVehiclePropValue( + const AidlVehiclePropValue& aidlPropValue) { + VehiclePropValue hidlPropValue; + hidlPropValue.timestamp = aidlPropValue.timestamp; + hidlPropValue.areaId = aidlPropValue.areaId; + hidlPropValue.prop = aidlPropValue.prop; + hidlPropValue.status = static_cast<VehiclePropertyStatus>(aidlPropValue.status); + hidlPropValue.value.int32Values = aidlPropValue.value.int32Values; + hidlPropValue.value.floatValues = aidlPropValue.value.floatValues; + hidlPropValue.value.int64Values = aidlPropValue.value.int64Values; + hidlPropValue.value.bytes = aidlPropValue.value.byteValues; + hidlPropValue.value.stringValue = aidlPropValue.value.stringValue; + return hidlPropValue; +} + +::ndk::ScopedAStatus EmulatedVehicleHalServer::VehicleBusCallback::onNewPropValues( + const std::vector<AidlVehiclePropValue>& aidlPropValues) { + for (const auto& aidlPropValue : aidlPropValues) { + mVehicleHalServer->onPropertyValueFromCar( + makeHidlVehiclePropValue(aidlPropValue), true); + } + return ::ndk::ScopedAStatus::ok(); +} + +IVehicleServer::DumpResult EmulatedVehicleHalServer::debug(const std::vector<std::string>& options){ + return DefaultVehicleHalServer::onDump(options); +} + +} // namespace impl + +} // namespace V2_0 +} // namespace vehicle +} // namespace automotive +} // namespace hardware +} // namespace android |