162 lines
5.8 KiB
C++
162 lines
5.8 KiB
C++
/*
|
|
* 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
|