1 /*
2 * Copyright (C) 2022 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 "EmulatedVehicleHardware"
18
19 #include "EmulatedVehicleHardware.h"
20 #include "VehicleEmulator.h"
21
22 #include <VehicleHalTypes.h>
23 #include <VehicleUtils.h>
24 #include <android-base/properties.h>
25 #include <android/binder_manager.h>
26 #include <utils/Log.h>
27
28 namespace android {
29 namespace hardware {
30 namespace automotive {
31 namespace vehicle {
32 namespace fake {
33
34 using ::aidl::android::hardware::automotive::vehicle::StatusCode;
35 using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
36 using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
37 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
38 using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
39 using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
40
41 using ::android::base::Result;
42 using ::android::hardware::automotive::vehicle::V2_0::impl::MessageSender;
43
EmulatedVehicleHardware()44 EmulatedVehicleHardware::EmulatedVehicleHardware() {
45 Init();
46 }
47
EmulatedVehicleHardware(std::string_view default_config_dir,std::string_view override_config_dir,bool force_override)48 EmulatedVehicleHardware::EmulatedVehicleHardware(
49 std::string_view default_config_dir, std::string_view override_config_dir,
50 bool force_override)
51 : FakeVehicleHardware(std::string(default_config_dir),
52 std::string(override_config_dir), force_override) {
53 Init();
54 }
55
EmulatedVehicleHardware(bool inQemu,std::unique_ptr<MessageSender> socketComm,std::unique_ptr<MessageSender> pipeComm)56 EmulatedVehicleHardware::EmulatedVehicleHardware(
57 bool inQemu,
58 std::unique_ptr<MessageSender> socketComm,
59 std::unique_ptr<MessageSender> pipeComm) {
60 mInQemu = inQemu;
61 mEmulator = std::make_unique<VehicleEmulator>(std::move(socketComm), std::move(pipeComm), this);
62 }
63
getEmulator()64 VehicleEmulator* EmulatedVehicleHardware::getEmulator() {
65 return mEmulator.get();
66 }
67
~EmulatedVehicleHardware()68 EmulatedVehicleHardware::~EmulatedVehicleHardware() {
69 mEmulator.reset();
70 stopVehicleBuses();
71 }
72
Init()73 void EmulatedVehicleHardware::Init() {
74 mInQemu = isInQemu();
75 ALOGD("mInQemu=%s", mInQemu ? "true" : "false");
76
77 mVehicleBusCallback = ::ndk::SharedRefBase::make<VehicleBusCallback>(this);
78 mEmulator = std::make_unique<VehicleEmulator>(this);
79 startVehicleBuses();
80 }
81
setValues(std::shared_ptr<const SetValuesCallback> callback,const std::vector<SetValueRequest> & requests)82 StatusCode EmulatedVehicleHardware::setValues(
83 std::shared_ptr<const SetValuesCallback> callback,
84 const std::vector<SetValueRequest>& requests) {
85 std::vector<SetValueResult> results;
86
87 for (const auto& request: requests) {
88 const VehiclePropValue& value = request.value;
89 int propId = value.prop;
90
91 ALOGD("Set value for property ID: %d", propId);
92
93 if (mInQemu && propId == toInt(VehicleProperty::DISPLAY_BRIGHTNESS)) {
94 ALOGD("Return OKAY for DISPLAY_BRIGHTNESS in QEMU");
95
96 // Emulator does not support remote brightness control, b/139959479
97 // do not send it down so that it does not bring unnecessary property change event
98 // return other error code, such NOT_AVAILABLE, causes Emulator to be freezing
99 // TODO: return StatusCode::NOT_AVAILABLE once the above issue is fixed
100 results.push_back({
101 .requestId = request.requestId,
102 .status = StatusCode::OK,
103 });
104 continue;
105 }
106
107 SetValueResult setValueResult;
108 setValueResult.requestId = request.requestId;
109
110 if (auto result = setValue(value); !result.ok()) {
111 ALOGE("failed to set value, error: %s, code: %d", getErrorMsg(result).c_str(),
112 getIntErrorCode(result));
113 setValueResult.status = getErrorCode(result);
114 } else {
115 setValueResult.status = StatusCode::OK;
116 // Inform the emulator about a new value change.
117 mEmulator->doSetValueFromClient(value);
118 }
119
120 results.push_back(std::move(setValueResult));
121 }
122 // In real Vehicle HAL, the values would be sent to vehicle bus. But here, we just assume
123 // it is done and notify the client.
124 (*callback)(std::move(results));
125
126 return StatusCode::OK;
127 }
128
startVehicleBuses()129 void EmulatedVehicleHardware::startVehicleBuses() {
130 std::vector<std::string> names;
131 AServiceManager_forEachDeclaredInstance(IVehicleBus::descriptor, static_cast<void*>(&names),
132 [](const char* instance, void* context) {
133 auto fullName = std::string(IVehicleBus::descriptor) + "/" + instance;
134 static_cast<std::vector<std::string>*>(context)->push_back(fullName);
135 });
136
137 for (const auto& fullName : names) {
138 ::ndk::SpAIBinder binder(AServiceManager_waitForService(fullName.c_str()));
139 if (binder.get() == nullptr) {
140 ALOGE("%s binder returned null", fullName.c_str());
141 continue;
142 }
143 std::shared_ptr<IVehicleBus> vehicleBus = IVehicleBus::fromBinder(binder);
144 if (vehicleBus == nullptr) {
145 ALOGE("Couldn't open %s", fullName.c_str());
146 continue;
147 }
148
149 vehicleBus->setOnNewPropValuesCallback(mVehicleBusCallback);
150 mVehicleBuses.push_back(vehicleBus);
151 }
152 }
153
onNewPropValues(const std::vector<AidlVehiclePropValue> & aidlPropValues)154 ::ndk::ScopedAStatus EmulatedVehicleHardware::VehicleBusCallback::onNewPropValues(
155 const std::vector<AidlVehiclePropValue>& aidlPropValues) {
156 for (const auto& aidlPropValue : aidlPropValues) {
157 if (auto result = mVehicleHardware->setValue(aidlPropValue); !result.ok()) {
158 ALOGE("Failed to set value, error: %s", getErrorMsg(result).c_str());
159 continue;
160 }
161 }
162 return ::ndk::ScopedAStatus::ok();
163 }
164
stopVehicleBuses()165 void EmulatedVehicleHardware::stopVehicleBuses() {
166 for (const auto& vehicleBus : mVehicleBuses) {
167 vehicleBus->unsetOnNewPropValuesCallback(mVehicleBusCallback);
168 }
169 }
170
getAllProperties() const171 std::vector<VehiclePropValuePool::RecyclableType> EmulatedVehicleHardware::getAllProperties()
172 const {
173 return mServerSidePropStore->readAllValues();
174 }
175
getPropConfig(int32_t propId) const176 EmulatedVehicleHardware::ConfigResultType EmulatedVehicleHardware::getPropConfig(int32_t propId)
177 const {
178 return mServerSidePropStore->getPropConfig(propId);
179 }
180
isInQemu()181 bool EmulatedVehicleHardware::isInQemu() {
182 return android::base::GetBoolProperty("ro.boot.qemu", false);
183 }
184
185 } // namespace fake
186 } // namespace vehicle
187 } // namespace automotive
188 } // namespace hardware
189 } // namespace android
190
191