/* * 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. */ #ifndef android_hardware_automotive_vehicle_aidl_impl_fake_impl_hardware_include_FakeVehicleHardware_H_ #define android_hardware_automotive_vehicle_aidl_impl_fake_impl_hardware_include_FakeVehicleHardware_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace android { namespace hardware { namespace automotive { namespace vehicle { namespace fake { class FakeVehicleHardware : public IVehicleHardware { public: using ValueResultType = VhalResult; FakeVehicleHardware(); FakeVehicleHardware(std::string defaultConfigDir, std::string overrideConfigDir, bool forceOverride); ~FakeVehicleHardware(); // Get all the property configs. std::vector getAllPropertyConfigs() const override; // Set property values asynchronously. Server could return before the property set requests // are sent to vehicle bus or before property set confirmation is received. The callback is // safe to be called after the function returns and is safe to be called in a different thread. aidl::android::hardware::automotive::vehicle::StatusCode setValues( std::shared_ptr callback, const std::vector& requests) override; // Get property values asynchronously. Server could return before the property values are ready. // The callback is safe to be called after the function returns and is safe to be called in a // different thread. aidl::android::hardware::automotive::vehicle::StatusCode getValues( std::shared_ptr callback, const std::vector& requests) const override; // Dump debug information in the server. DumpResult dump(const std::vector& options) override; // Check whether the system is healthy, return {@code StatusCode::OK} for healthy. aidl::android::hardware::automotive::vehicle::StatusCode checkHealth() override; // Register a callback that would be called when there is a property change event from vehicle. void registerOnPropertyChangeEvent( std::unique_ptr callback) override; // Register a callback that would be called when there is a property set error event from // vehicle. void registerOnPropertySetErrorEvent( std::unique_ptr callback) override; // Subscribe to a new [propId, areaId] or change the update rate. aidl::android::hardware::automotive::vehicle::StatusCode subscribe( aidl::android::hardware::automotive::vehicle::SubscribeOptions options) override; // Unsubscribe to a [propId, areaId]. aidl::android::hardware::automotive::vehicle::StatusCode unsubscribe(int32_t propId, int32_t areaId) override; protected: // mValuePool is also used in mServerSidePropStore. const std::shared_ptr mValuePool; const std::shared_ptr mServerSidePropStore; const std::string mDefaultConfigDir; const std::string mOverrideConfigDir; ValueResultType getValue( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const; VhalResult setValue( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value); bool UseOverrideConfigDir(); private: // Expose private methods to unit test. friend class FakeVehicleHardwareTestHelper; template struct RequestWithCallback { RequestType request; std::shared_ptr callback; }; template class PendingRequestHandler { public: PendingRequestHandler(FakeVehicleHardware* hardware); void addRequest(RequestType request, std::shared_ptr callback); void stop(); private: FakeVehicleHardware* mHardware; std::thread mThread; ConcurrentQueue> mRequests; void handleRequestsOnce(); }; struct RefreshInfo { VehiclePropertyStore::EventMode eventMode; int64_t intervalInNanos; }; struct ActionForInterval { std::unordered_set propIdAreaIdsToRefresh; std::shared_ptr recurrentAction; }; const std::unique_ptr mFakeObd2Frame; const std::unique_ptr mFakeUserHal; // RecurrentTimer is thread-safe. std::unique_ptr mRecurrentTimer; // GeneratorHub is thread-safe. std::unique_ptr mGeneratorHub; // Only allowed to set once. std::unique_ptr mOnPropertyChangeCallback; std::unique_ptr mOnPropertySetErrorCallback; std::mutex mLock; std::unordered_map mRefreshInfoByPropIdAreaId GUARDED_BY(mLock); std::unordered_map mActionByIntervalInNanos GUARDED_BY(mLock); std::unordered_map mSavedProps GUARDED_BY(mLock); std::unordered_set mSubOnChangePropIdAreaIds GUARDED_BY(mLock); // PendingRequestHandler is thread-safe. mutable PendingRequestHandler mPendingGetValueRequests; mutable PendingRequestHandler mPendingSetValueRequests; // Set of HVAC properties dependent on HVAC_POWER_ON std::unordered_set hvacPowerDependentProps; const bool mForceOverride; bool mAddExtraTestVendorConfigs = false; // Only used during initialization. JsonConfigLoader mLoader; // Only used during initialization. If not empty, points to an external grpc server that // provides power controlling related properties. std::string mPowerControllerServiceAddress = ""; void init(); // Stores the initial value to property store. void storePropInitialValue(const ConfigDeclaration& config); // The callback that would be called when a vehicle property value change happens. void onValueChangeCallback( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) EXCLUDES(mLock); // The callback that would be called when multiple vehicle property value changes happen. void onValuesChangeCallback( std::vector values) EXCLUDES(mLock); // Load the config files in format '*.json' from the directory and parse the config files // into a map from property ID to ConfigDeclarations. bool loadPropConfigsFromDir(const std::string& dirPath, std::unordered_map* configs); // Function to be called when a value change event comes from vehicle bus. In our fake // implementation, this function is only called during "--inject-event" dump command. void eventFromVehicleBus( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value); int getHvacTempNumIncrements(int requestedTemp, int minTemp, int maxTemp, int increment); void updateHvacTemperatureValueSuggestionInput( const std::vector& hvacTemperatureSetConfigArray, std::vector* hvacTemperatureValueSuggestionInput); VhalResult setHvacTemperatureValueSuggestion( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& hvacTemperatureValueSuggestion); VhalResult maybeSetSpecialValue( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value, bool* isSpecialValue); VhalResult isCruiseControlTypeStandard() const; ValueResultType maybeGetSpecialValue( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value, bool* isSpecialValue) const; VhalResult setApPowerStateReport( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value); VhalResult setApPowerStateReqShutdown( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value); VehiclePropValuePool::RecyclableType createApPowerStateReq( aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq state); VehiclePropValuePool::RecyclableType createAdasStateReq(int32_t propertyId, int32_t areaId, int32_t state); VhalResult setUserHalProp( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value); ValueResultType getUserHalProp( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const; ValueResultType getEchoReverseBytes( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const; bool isHvacPropAndHvacNotAvailable(int32_t propId, int32_t areaId) const; VhalResult isAdasPropertyAvailable(int32_t adasStatePropertyId) const; VhalResult synchronizeHvacTemp(int32_t hvacDualOnAreaId, std::optional newTempC) const; std::optional getSyncedAreaIdIfHvacDualOn(int32_t hvacTemperatureSetAreaId) const; ValueResultType getPowerPropFromExternalService(int32_t propId) const; ValueResultType getVehicleInUse( android::hardware::automotive::remoteaccess::PowerController::Stub* clientStub) const; ValueResultType getApPowerBootupReason( android::hardware::automotive::remoteaccess::PowerController::Stub* clientStub) const; std::unordered_map loadConfigDeclarations(); std::string dumpAllProperties(); std::string dumpOnePropertyByConfig( int rowNumber, const aidl::android::hardware::automotive::vehicle::VehiclePropConfig& config); std::string dumpOnePropertyById(int32_t propId, int32_t areaId); std::string dumpHelp(); std::string dumpListProperties(); std::string dumpSpecificProperty(const std::vector& options); std::string dumpSetProperties(const std::vector& options); std::string dumpGetPropertyWithArg(const std::vector& options); std::string dumpSaveProperty(const std::vector& options); std::string dumpRestoreProperty(const std::vector& options); std::string dumpInjectEvent(const std::vector& options); std::string dumpSubscriptions(); std::vector getOptionValues(const std::vector& options, size_t* index); android::base::Result parsePropOptions(const std::vector& options); android::base::Result> parseHexString(const std::string& s); android::base::Result checkArgumentsSize(const std::vector& options, size_t minSize); aidl::android::hardware::automotive::vehicle::GetValueResult handleGetValueRequest( const aidl::android::hardware::automotive::vehicle::GetValueRequest& request); aidl::android::hardware::automotive::vehicle::SetValueResult handleSetValueRequest( const aidl::android::hardware::automotive::vehicle::SetValueRequest& request); std::string genFakeDataCommand(const std::vector& options); void sendHvacPropertiesCurrentValues(int32_t areaId, int32_t hvacPowerOnVal); void sendAdasPropertiesState(int32_t propertyId, int32_t state); void generateVendorConfigs( std::vector&) const; aidl::android::hardware::automotive::vehicle::StatusCode subscribePropIdAreaIdLocked( int32_t propId, int32_t areaId, float sampleRateHz, bool enableVariableUpdateRate, const aidl::android::hardware::automotive::vehicle::VehiclePropConfig& vehiclePropConfig) REQUIRES(mLock); void registerRefreshLocked(PropIdAreaId propIdAreaId, VehiclePropertyStore::EventMode eventMode, float sampleRateHz) REQUIRES(mLock); void unregisterRefreshLocked(PropIdAreaId propIdAreaId) REQUIRES(mLock); void refreshTimestampForInterval(int64_t intervalInNanos) EXCLUDES(mLock); static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp( aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action, int32_t keyCode, int32_t targetDisplay); static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwKeyInputV2Prop( int32_t area, int32_t targetDisplay, int32_t keyCode, int32_t action, int32_t repeatCount); static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwMotionInputProp( int32_t area, int32_t display, int32_t inputType, int32_t action, int32_t buttonState, int32_t pointerCount, int32_t pointerId[], int32_t toolType[], float xData[], float yData[], float pressure[], float size[]); static std::string genFakeDataHelp(); static std::string parseErrMsg(std::string fieldName, std::string value, std::string type); static bool isVariableUpdateRateSupported( const aidl::android::hardware::automotive::vehicle::VehiclePropConfig& vehiclePropConfig, int32_t areaId); template static android::base::Result safelyParseInt(int index, const std::string& s) { T out; if (!::android::base::ParseInt(s, &out)) { return android::base::Error() << android::base::StringPrintf( "non-integer argument at index %d: %s\n", index, s.c_str()); } return out; } static android::base::Result safelyParseFloat(int index, const std::string& s); static android::base::Result parsePropId(const std::vector& options, size_t index); }; } // namespace fake } // namespace vehicle } // namespace automotive } // namespace hardware } // namespace android #endif // android_hardware_automotive_vehicle_aidl_impl_fake_impl_hardware_include_FakeVehicleHardware_H_