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 #ifndef android_hardware_automotive_vehicle_aidl_impl_fake_impl_hardware_include_FakeVehicleHardware_H_
18 #define android_hardware_automotive_vehicle_aidl_impl_fake_impl_hardware_include_FakeVehicleHardware_H_
19 
20 #include <ConcurrentQueue.h>
21 #include <ConfigDeclaration.h>
22 #include <FakeObd2Frame.h>
23 #include <FakeUserHal.h>
24 #include <GeneratorHub.h>
25 #include <IVehicleHardware.h>
26 #include <JsonConfigLoader.h>
27 #include <RecurrentTimer.h>
28 #include <VehicleHalTypes.h>
29 #include <VehiclePropertyStore.h>
30 #include <aidl/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.h>
31 #include <android-base/parseint.h>
32 #include <android-base/result.h>
33 #include <android-base/stringprintf.h>
34 #include <android-base/thread_annotations.h>
35 #include <grpc++/grpc++.h>
36 #include <wakeup_client.grpc.pb.h>
37 
38 #include <memory>
39 #include <mutex>
40 #include <unordered_map>
41 #include <unordered_set>
42 #include <vector>
43 
44 namespace android {
45 namespace hardware {
46 namespace automotive {
47 namespace vehicle {
48 namespace fake {
49 
50 class FakeVehicleHardware : public IVehicleHardware {
51   public:
52     using ValueResultType = VhalResult<VehiclePropValuePool::RecyclableType>;
53 
54     FakeVehicleHardware();
55 
56     FakeVehicleHardware(std::string defaultConfigDir, std::string overrideConfigDir,
57                         bool forceOverride);
58 
59     ~FakeVehicleHardware();
60 
61     // Get all the property configs.
62     std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
63     getAllPropertyConfigs() const override;
64 
65     // Set property values asynchronously. Server could return before the property set requests
66     // are sent to vehicle bus or before property set confirmation is received. The callback is
67     // safe to be called after the function returns and is safe to be called in a different thread.
68     aidl::android::hardware::automotive::vehicle::StatusCode setValues(
69             std::shared_ptr<const SetValuesCallback> callback,
70             const std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>&
71                     requests) override;
72 
73     // Get property values asynchronously. Server could return before the property values are ready.
74     // The callback is safe to be called after the function returns and is safe to be called in a
75     // different thread.
76     aidl::android::hardware::automotive::vehicle::StatusCode getValues(
77             std::shared_ptr<const GetValuesCallback> callback,
78             const std::vector<aidl::android::hardware::automotive::vehicle::GetValueRequest>&
79                     requests) const override;
80 
81     // Dump debug information in the server.
82     DumpResult dump(const std::vector<std::string>& options) override;
83 
84     // Check whether the system is healthy, return {@code StatusCode::OK} for healthy.
85     aidl::android::hardware::automotive::vehicle::StatusCode checkHealth() override;
86 
87     // Register a callback that would be called when there is a property change event from vehicle.
88     void registerOnPropertyChangeEvent(
89             std::unique_ptr<const PropertyChangeCallback> callback) override;
90 
91     // Register a callback that would be called when there is a property set error event from
92     // vehicle.
93     void registerOnPropertySetErrorEvent(
94             std::unique_ptr<const PropertySetErrorCallback> callback) override;
95 
96     // Subscribe to a new [propId, areaId] or change the update rate.
97     aidl::android::hardware::automotive::vehicle::StatusCode subscribe(
98             aidl::android::hardware::automotive::vehicle::SubscribeOptions options) override;
99 
100     // Unsubscribe to a [propId, areaId].
101     aidl::android::hardware::automotive::vehicle::StatusCode unsubscribe(int32_t propId,
102                                                                          int32_t areaId) override;
103 
104   protected:
105     // mValuePool is also used in mServerSidePropStore.
106     const std::shared_ptr<VehiclePropValuePool> mValuePool;
107     const std::shared_ptr<VehiclePropertyStore> mServerSidePropStore;
108 
109     const std::string mDefaultConfigDir;
110     const std::string mOverrideConfigDir;
111 
112     ValueResultType getValue(
113             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
114 
115     VhalResult<void> setValue(
116             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
117 
118     bool UseOverrideConfigDir();
119 
120   private:
121     // Expose private methods to unit test.
122     friend class FakeVehicleHardwareTestHelper;
123 
124     template <class CallbackType, class RequestType>
125     struct RequestWithCallback {
126         RequestType request;
127         std::shared_ptr<const CallbackType> callback;
128     };
129 
130     template <class CallbackType, class RequestType>
131     class PendingRequestHandler {
132       public:
133         PendingRequestHandler(FakeVehicleHardware* hardware);
134 
135         void addRequest(RequestType request, std::shared_ptr<const CallbackType> callback);
136 
137         void stop();
138 
139       private:
140         FakeVehicleHardware* mHardware;
141         std::thread mThread;
142         ConcurrentQueue<RequestWithCallback<CallbackType, RequestType>> mRequests;
143 
144         void handleRequestsOnce();
145     };
146 
147     struct RefreshInfo {
148         VehiclePropertyStore::EventMode eventMode;
149         int64_t intervalInNanos;
150     };
151 
152     struct ActionForInterval {
153         std::unordered_set<PropIdAreaId, PropIdAreaIdHash> propIdAreaIdsToRefresh;
154         std::shared_ptr<RecurrentTimer::Callback> recurrentAction;
155     };
156 
157     const std::unique_ptr<obd2frame::FakeObd2Frame> mFakeObd2Frame;
158     const std::unique_ptr<FakeUserHal> mFakeUserHal;
159     // RecurrentTimer is thread-safe.
160     std::unique_ptr<RecurrentTimer> mRecurrentTimer;
161     // GeneratorHub is thread-safe.
162     std::unique_ptr<GeneratorHub> mGeneratorHub;
163 
164     // Only allowed to set once.
165     std::unique_ptr<const PropertyChangeCallback> mOnPropertyChangeCallback;
166     std::unique_ptr<const PropertySetErrorCallback> mOnPropertySetErrorCallback;
167 
168     std::mutex mLock;
169     std::unordered_map<PropIdAreaId, RefreshInfo, PropIdAreaIdHash> mRefreshInfoByPropIdAreaId
170             GUARDED_BY(mLock);
171     std::unordered_map<int64_t, ActionForInterval> mActionByIntervalInNanos GUARDED_BY(mLock);
172     std::unordered_map<PropIdAreaId, VehiclePropValuePool::RecyclableType, PropIdAreaIdHash>
173             mSavedProps GUARDED_BY(mLock);
174     std::unordered_set<PropIdAreaId, PropIdAreaIdHash> mSubOnChangePropIdAreaIds GUARDED_BY(mLock);
175     // PendingRequestHandler is thread-safe.
176     mutable PendingRequestHandler<GetValuesCallback,
177                                   aidl::android::hardware::automotive::vehicle::GetValueRequest>
178             mPendingGetValueRequests;
179     mutable PendingRequestHandler<SetValuesCallback,
180                                   aidl::android::hardware::automotive::vehicle::SetValueRequest>
181             mPendingSetValueRequests;
182 
183     // Set of HVAC properties dependent on HVAC_POWER_ON
184     std::unordered_set<int32_t> hvacPowerDependentProps;
185 
186     const bool mForceOverride;
187     bool mAddExtraTestVendorConfigs = false;
188 
189     // Only used during initialization.
190     JsonConfigLoader mLoader;
191 
192     // Only used during initialization. If not empty, points to an external grpc server that
193     // provides power controlling related properties.
194     std::string mPowerControllerServiceAddress = "";
195 
196     void init();
197     // Stores the initial value to property store.
198     void storePropInitialValue(const ConfigDeclaration& config);
199     // The callback that would be called when a vehicle property value change happens.
200     void onValueChangeCallback(
201             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value)
202             EXCLUDES(mLock);
203     // The callback that would be called when multiple vehicle property value changes happen.
204     void onValuesChangeCallback(
205             std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue> values)
206             EXCLUDES(mLock);
207     // Load the config files in format '*.json' from the directory and parse the config files
208     // into a map from property ID to ConfigDeclarations.
209     bool loadPropConfigsFromDir(const std::string& dirPath,
210                                 std::unordered_map<int32_t, ConfigDeclaration>* configs);
211     // Function to be called when a value change event comes from vehicle bus. In our fake
212     // implementation, this function is only called during "--inject-event" dump command.
213     void eventFromVehicleBus(
214             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
215 
216     int getHvacTempNumIncrements(int requestedTemp, int minTemp, int maxTemp, int increment);
217     void updateHvacTemperatureValueSuggestionInput(
218             const std::vector<int>& hvacTemperatureSetConfigArray,
219             std::vector<float>* hvacTemperatureValueSuggestionInput);
220     VhalResult<void> setHvacTemperatureValueSuggestion(
221             const aidl::android::hardware::automotive::vehicle::VehiclePropValue&
222                     hvacTemperatureValueSuggestion);
223     VhalResult<void> maybeSetSpecialValue(
224             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
225             bool* isSpecialValue);
226     VhalResult<bool> isCruiseControlTypeStandard() const;
227     ValueResultType maybeGetSpecialValue(
228             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
229             bool* isSpecialValue) const;
230     VhalResult<void> setApPowerStateReport(
231             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
232     VhalResult<void> setApPowerStateReqShutdown(
233             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
234     VehiclePropValuePool::RecyclableType createApPowerStateReq(
235             aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq state);
236     VehiclePropValuePool::RecyclableType createAdasStateReq(int32_t propertyId, int32_t areaId,
237                                                             int32_t state);
238     VhalResult<void> setUserHalProp(
239             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
240     ValueResultType getUserHalProp(
241             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
242     ValueResultType getEchoReverseBytes(
243             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
244     bool isHvacPropAndHvacNotAvailable(int32_t propId, int32_t areaId) const;
245     VhalResult<void> isAdasPropertyAvailable(int32_t adasStatePropertyId) const;
246     VhalResult<void> synchronizeHvacTemp(int32_t hvacDualOnAreaId,
247                                          std::optional<float> newTempC) const;
248     std::optional<int32_t> getSyncedAreaIdIfHvacDualOn(int32_t hvacTemperatureSetAreaId) const;
249     ValueResultType getPowerPropFromExternalService(int32_t propId) const;
250     ValueResultType getVehicleInUse(
251             android::hardware::automotive::remoteaccess::PowerController::Stub* clientStub) const;
252     ValueResultType getApPowerBootupReason(
253             android::hardware::automotive::remoteaccess::PowerController::Stub* clientStub) const;
254 
255     std::unordered_map<int32_t, ConfigDeclaration> loadConfigDeclarations();
256 
257     std::string dumpAllProperties();
258     std::string dumpOnePropertyByConfig(
259             int rowNumber,
260             const aidl::android::hardware::automotive::vehicle::VehiclePropConfig& config);
261     std::string dumpOnePropertyById(int32_t propId, int32_t areaId);
262     std::string dumpHelp();
263     std::string dumpListProperties();
264     std::string dumpSpecificProperty(const std::vector<std::string>& options);
265     std::string dumpSetProperties(const std::vector<std::string>& options);
266     std::string dumpGetPropertyWithArg(const std::vector<std::string>& options);
267     std::string dumpSaveProperty(const std::vector<std::string>& options);
268     std::string dumpRestoreProperty(const std::vector<std::string>& options);
269     std::string dumpInjectEvent(const std::vector<std::string>& options);
270     std::string dumpSubscriptions();
271 
272     std::vector<std::string> getOptionValues(const std::vector<std::string>& options,
273                                              size_t* index);
274     android::base::Result<aidl::android::hardware::automotive::vehicle::VehiclePropValue>
275     parsePropOptions(const std::vector<std::string>& options);
276     android::base::Result<std::vector<uint8_t>> parseHexString(const std::string& s);
277 
278     android::base::Result<void> checkArgumentsSize(const std::vector<std::string>& options,
279                                                    size_t minSize);
280     aidl::android::hardware::automotive::vehicle::GetValueResult handleGetValueRequest(
281             const aidl::android::hardware::automotive::vehicle::GetValueRequest& request);
282     aidl::android::hardware::automotive::vehicle::SetValueResult handleSetValueRequest(
283             const aidl::android::hardware::automotive::vehicle::SetValueRequest& request);
284 
285     std::string genFakeDataCommand(const std::vector<std::string>& options);
286     void sendHvacPropertiesCurrentValues(int32_t areaId, int32_t hvacPowerOnVal);
287     void sendAdasPropertiesState(int32_t propertyId, int32_t state);
288     void generateVendorConfigs(
289             std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig>&) const;
290 
291     aidl::android::hardware::automotive::vehicle::StatusCode subscribePropIdAreaIdLocked(
292             int32_t propId, int32_t areaId, float sampleRateHz, bool enableVariableUpdateRate,
293             const aidl::android::hardware::automotive::vehicle::VehiclePropConfig&
294                     vehiclePropConfig) REQUIRES(mLock);
295 
296     void registerRefreshLocked(PropIdAreaId propIdAreaId, VehiclePropertyStore::EventMode eventMode,
297                                float sampleRateHz) REQUIRES(mLock);
298     void unregisterRefreshLocked(PropIdAreaId propIdAreaId) REQUIRES(mLock);
299     void refreshTimestampForInterval(int64_t intervalInNanos) EXCLUDES(mLock);
300 
301     static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
302             aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,
303             int32_t keyCode, int32_t targetDisplay);
304     static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwKeyInputV2Prop(
305             int32_t area, int32_t targetDisplay, int32_t keyCode, int32_t action,
306             int32_t repeatCount);
307     static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwMotionInputProp(
308             int32_t area, int32_t display, int32_t inputType, int32_t action, int32_t buttonState,
309             int32_t pointerCount, int32_t pointerId[], int32_t toolType[], float xData[],
310             float yData[], float pressure[], float size[]);
311 
312     static std::string genFakeDataHelp();
313     static std::string parseErrMsg(std::string fieldName, std::string value, std::string type);
314     static bool isVariableUpdateRateSupported(
315             const aidl::android::hardware::automotive::vehicle::VehiclePropConfig&
316                     vehiclePropConfig,
317             int32_t areaId);
318     template <typename T>
safelyParseInt(int index,const std::string & s)319     static android::base::Result<T> safelyParseInt(int index, const std::string& s) {
320         T out;
321         if (!::android::base::ParseInt(s, &out)) {
322             return android::base::Error() << android::base::StringPrintf(
323                            "non-integer argument at index %d: %s\n", index, s.c_str());
324         }
325         return out;
326     }
327     static android::base::Result<float> safelyParseFloat(int index, const std::string& s);
328     static android::base::Result<int32_t> parsePropId(const std::vector<std::string>& options,
329                                                       size_t index);
330 };
331 
332 }  // namespace fake
333 }  // namespace vehicle
334 }  // namespace automotive
335 }  // namespace hardware
336 }  // namespace android
337 
338 #endif  // android_hardware_automotive_vehicle_aidl_impl_fake_impl_hardware_include_FakeVehicleHardware_H_
339