1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "EmulatedVehicleHalServer"
18 
19 #include <android/binder_manager.h>
20 #include <utils/SystemClock.h>
21 #include <vhal_v2_0/VehicleUtils.h>
22 
23 #include "EmulatedVehicleHalServer.h"
24 
25 namespace android {
26 namespace hardware {
27 namespace automotive {
28 namespace vehicle {
29 namespace V2_0 {
30 
31 namespace impl {
32 
EmulatedVehicleHalServer()33 EmulatedVehicleHalServer::EmulatedVehicleHalServer(): DefaultVehicleHalServer() {
34     mInQEMU = isInQEMU();
35     ALOGD("mInQEMU=%s", mInQEMU ? "true" : "false");
36 
37     mVehicleBusCallback = ::ndk::SharedRefBase::make<VehicleBusCallback>(this);
38     startVehicleBuses();
39 }
40 
~EmulatedVehicleHalServer()41 EmulatedVehicleHalServer::~EmulatedVehicleHalServer() {
42     stopVehicleBuses();
43 }
44 
onSetProperty(const VehiclePropValue & value,bool updateStatus)45 StatusCode EmulatedVehicleHalServer::onSetProperty(const VehiclePropValue& value,
46                                                    bool updateStatus) {
47     if (mInQEMU && value.prop == toInt(VehicleProperty::DISPLAY_BRIGHTNESS)) {
48         // Emulator does not support remote brightness control, b/139959479
49         // do not send it down so that it does not bring unnecessary property change event
50         // return other error code, such NOT_AVAILABLE, causes Emulator to be freezing
51         // TODO: return StatusCode::NOT_AVAILABLE once the above issue is fixed
52         return StatusCode::OK;
53     }
54 
55     return DefaultVehicleHalServer::onSetProperty(value, updateStatus);
56 }
57 
setPropertyFromVehicle(const VehiclePropValue & propValue)58 bool EmulatedVehicleHalServer::setPropertyFromVehicle(const VehiclePropValue& propValue) {
59     auto updatedPropValue = getValuePool()->obtain(propValue);
60     updatedPropValue->timestamp = elapsedRealtimeNano();
61     mServerSidePropStore.writeValue(*updatedPropValue, true);
62     onPropertyValueFromCar(*updatedPropValue, true);
63     return true;
64 }
65 
getAllProperties() const66 std::vector<VehiclePropValue> EmulatedVehicleHalServer::getAllProperties() const {
67     return mServerSidePropStore.readAllValues();
68 }
69 
listProperties()70 std::vector<VehiclePropConfig> EmulatedVehicleHalServer::listProperties() {
71     return mServerSidePropStore.getAllConfigs();
72 }
73 
get(const VehiclePropValue & requestedPropValue,StatusCode * outStatus)74 EmulatedVehicleHalServer::VehiclePropValuePtr EmulatedVehicleHalServer::get(
75         const VehiclePropValue& requestedPropValue, StatusCode* outStatus) {
76     EmulatedVehicleHalServer::VehiclePropValuePtr v = nullptr;
77     auto prop = mServerSidePropStore.readValueOrNull(requestedPropValue);
78     if (prop != nullptr) {
79         v = getValuePool()->obtain(*prop);
80     }
81 
82     if (!v) {
83         *outStatus = StatusCode::INVALID_ARG;
84     } else if (v->status == VehiclePropertyStatus::AVAILABLE) {
85         *outStatus = StatusCode::OK;
86     } else {
87         *outStatus = StatusCode::TRY_AGAIN;
88     }
89 
90     if (v.get()) {
91         v->timestamp = elapsedRealtimeNano();
92     }
93     return v;
94 }
95 
startVehicleBuses()96 void EmulatedVehicleHalServer::startVehicleBuses() {
97     std::vector<std::string> names;
98     AServiceManager_forEachDeclaredInstance(IVehicleBus::descriptor, static_cast<void*>(&names),
99         [](const char* instance, void* context) {
100             auto fullName = std::string(IVehicleBus::descriptor) + "/" + instance;
101             static_cast<std::vector<std::string>*>(context)->emplace_back(fullName);
102         });
103 
104     for (const auto& fullName : names) {
105         ::ndk::SpAIBinder binder(AServiceManager_waitForService(fullName.c_str()));
106         if (binder.get() == nullptr) {
107             ALOGE("%s binder returned null", fullName.c_str());
108             continue;
109         }
110         std::shared_ptr<IVehicleBus> vehicleBus = IVehicleBus::fromBinder(binder);
111         if (vehicleBus == nullptr) {
112             ALOGE("Couldn't open %s", fullName.c_str());
113             continue;
114         }
115 
116         vehicleBus->setOnNewPropValuesCallback(mVehicleBusCallback);
117         mVehicleBuses.push_back(vehicleBus);
118     }
119 }
120 
stopVehicleBuses()121 void EmulatedVehicleHalServer::stopVehicleBuses() {
122     for (const auto& vehicleBus : mVehicleBuses) {
123         vehicleBus->unsetOnNewPropValuesCallback(mVehicleBusCallback);
124     }
125 }
126 
makeHidlVehiclePropValue(const AidlVehiclePropValue & aidlPropValue)127 VehiclePropValue EmulatedVehicleHalServer::VehicleBusCallback::makeHidlVehiclePropValue(
128     const AidlVehiclePropValue& aidlPropValue) {
129     VehiclePropValue hidlPropValue;
130     hidlPropValue.timestamp = aidlPropValue.timestamp;
131     hidlPropValue.areaId = aidlPropValue.areaId;
132     hidlPropValue.prop = aidlPropValue.prop;
133     hidlPropValue.status = static_cast<VehiclePropertyStatus>(aidlPropValue.status);
134     hidlPropValue.value.int32Values = aidlPropValue.value.int32Values;
135     hidlPropValue.value.floatValues = aidlPropValue.value.floatValues;
136     hidlPropValue.value.int64Values = aidlPropValue.value.int64Values;
137     hidlPropValue.value.bytes = aidlPropValue.value.byteValues;
138     hidlPropValue.value.stringValue = aidlPropValue.value.stringValue;
139     return hidlPropValue;
140 }
141 
onNewPropValues(const std::vector<AidlVehiclePropValue> & aidlPropValues)142 ::ndk::ScopedAStatus EmulatedVehicleHalServer::VehicleBusCallback::onNewPropValues(
143      const std::vector<AidlVehiclePropValue>& aidlPropValues) {
144     for (const auto& aidlPropValue : aidlPropValues) {
145         mVehicleHalServer->onPropertyValueFromCar(
146             makeHidlVehiclePropValue(aidlPropValue), true);
147     }
148     return ::ndk::ScopedAStatus::ok();
149 }
150 
debug(const std::vector<std::string> & options)151 IVehicleServer::DumpResult EmulatedVehicleHalServer::debug(const std::vector<std::string>& options){
152     return DefaultVehicleHalServer::onDump(options);
153 }
154 
155 }  // namespace impl
156 
157 }  // namespace V2_0
158 }  // namespace vehicle
159 }  // namespace automotive
160 }  // namespace hardware
161 }  // namespace android
162