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