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_hardware_include_IVehicleHardware_H_ 18 #define android_hardware_automotive_vehicle_aidl_impl_hardware_include_IVehicleHardware_H_ 19 20 #include <VehicleHalTypes.h> 21 #include <VehicleUtils.h> 22 23 #include <memory> 24 #include <optional> 25 #include <unordered_set> 26 #include <vector> 27 28 namespace android { 29 namespace hardware { 30 namespace automotive { 31 namespace vehicle { 32 33 // A structure used to return dumped information. 34 struct DumpResult { 35 // If callerShouldDumpState is true, caller would print the information in buffer and 36 // continue to dump its state, otherwise would just dump the buffer and skip its own 37 // dumping logic. 38 bool callerShouldDumpState; 39 // The dumped information for the caller to print. 40 std::string buffer; 41 // To pass if DefaultVehicleHal should refresh the property configs 42 bool refreshPropertyConfigs = false; 43 }; 44 45 // A structure to represent a set value error event reported from vehicle. 46 struct SetValueErrorEvent { 47 aidl::android::hardware::automotive::vehicle::StatusCode errorCode; 48 int32_t propId; 49 int32_t areaId; 50 }; 51 52 namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle; 53 54 // An abstract interface to access vehicle hardware. 55 // For virtualized VHAL, GrpcVehicleHardware would communicate with a VehicleHardware 56 // implementation in another VM through GRPC. For non-virtualzied VHAL, VHAL directly communicates 57 // with a VehicleHardware through this interface. 58 class IVehicleHardware { 59 public: 60 using SetValuesCallback = std::function<void(std::vector<aidlvhal::SetValueResult>)>; 61 using GetValuesCallback = std::function<void(std::vector<aidlvhal::GetValueResult>)>; 62 using PropertyChangeCallback = std::function<void(std::vector<aidlvhal::VehiclePropValue>)>; 63 using PropertySetErrorCallback = std::function<void(std::vector<SetValueErrorEvent>)>; 64 using SupportedValueChangeCallback = std::function<void(std::vector<PropIdAreaId>)>; 65 66 virtual ~IVehicleHardware() = default; 67 68 // Get all the property configs. 69 // 70 // Note that {@code VehicleAreaConfig.HasSupportedValueInfo} field is newly introduced in VHAL 71 // V4 to specify whether the [propertyId, areaId] has specified min/max supported value or 72 // supported values list. 73 // 74 // Since IVehicleHardware is designed to be backward compatible, this field can be set to null. 75 // If this field is set to null, VHAL client should fallback to use min/max supported value 76 // information in {@code VehicleAreaConfig} and {@code supportedEnumVaules} for enum properties. 77 // 78 // It is highly recommended to specify {@code VehicleAreaConfig.HasSupportedValueInfo} for new 79 // property implementations, even if the property does not specify supported values or the 80 // supported values are static. 81 virtual std::vector<aidlvhal::VehiclePropConfig> getAllPropertyConfigs() const = 0; 82 83 // Get the property configs for the specified propId. This is used for early-boot 84 // native VHAL clients to access certain property configs when not all property configs are 85 // available. For example, a config discovery process might be required to determine the 86 // property config for HVAC. However, for early boot properties, e.g. VHAL_HEARTBEAT, it 87 // could return before the config discovery process. 88 // 89 // Currently Android system may try to access the following properties during early boot: 90 // STORAGE_ENCRYPTION_BINDING_SEED, WATCHDOG_ALIVE, WATCHDOG_TERMINATE_PROCESS, VHAL_HEARTBEAT, 91 // CURRENT_POWER_POLICY, POWER_POLICY_REQ, POWER_POLICY_GROUP_REQ. They should return 92 // quickly otherwise the whole bootup process might be blocked. getPropertyConfig(int32_t propId)93 virtual std::optional<aidlvhal::VehiclePropConfig> getPropertyConfig(int32_t propId) const { 94 // The default implementation is to use getAllPropertyConfigs(). This should be 95 // overridden if getAllPropertyConfigs() takes a while to return for initial boot or 96 // relies on ethernet or other communication channel that is not available during early 97 // boot. 98 for (const auto& config : getAllPropertyConfigs()) { 99 if (config.prop == propId) { 100 return config; 101 } 102 } 103 return std::nullopt; 104 } 105 106 // Set property values asynchronously. Server could return before the property set requests 107 // are sent to vehicle bus or before property set confirmation is received. The callback is 108 // safe to be called after the function returns and is safe to be called in a different thread. 109 virtual aidlvhal::StatusCode setValues( 110 std::shared_ptr<const SetValuesCallback> callback, 111 const std::vector<aidlvhal::SetValueRequest>& requests) = 0; 112 113 // Get property values asynchronously. Server could return before the property values are ready. 114 // The callback is safe to be called after the function returns and is safe to be called in a 115 // different thread. 116 virtual aidl::android::hardware::automotive::vehicle::StatusCode getValues( 117 std::shared_ptr<const GetValuesCallback> callback, 118 const std::vector<aidl::android::hardware::automotive::vehicle::GetValueRequest>& 119 requests) const = 0; 120 121 // Dump debug information in the server. 122 virtual DumpResult dump(const std::vector<std::string>& options) = 0; 123 124 // Check whether the system is healthy, return {@code StatusCode::OK} for healthy. 125 virtual aidlvhal::StatusCode checkHealth() = 0; 126 127 // Register a callback that would be called when there is a property change event from vehicle. 128 // This function must only be called once during initialization. 129 virtual void registerOnPropertyChangeEvent( 130 std::unique_ptr<const PropertyChangeCallback> callback) = 0; 131 132 // Register a callback that would be called when there is a property set error event from 133 // vehicle. Must only be called once during initialization. 134 virtual void registerOnPropertySetErrorEvent( 135 std::unique_ptr<const PropertySetErrorCallback> callback) = 0; 136 137 // Gets the batching window used by DefaultVehicleHal for property change events. 138 // 139 // In DefaultVehicleHal, all the property change events generated within the batching window 140 // will be delivered through one callback to the VHAL client. This affects the maximum supported 141 // subscription rate. For example, if this returns 10ms, then only one callback for property 142 // change events will be called per 10ms, meaining that the max subscription rate for all 143 // continuous properties would be 100hz. 144 // 145 // A higher batching window means less callbacks to the VHAL client, causing a better 146 // performance. However, it also means a longer average latency for every property change 147 // events. 148 // 149 // 0 means no batching should be enabled in DefaultVehicleHal. In this case, batching can 150 // be optionally implemented in IVehicleHardware layer. getPropertyOnChangeEventBatchingWindow()151 virtual std::chrono::nanoseconds getPropertyOnChangeEventBatchingWindow() { 152 // By default batching is disabled. 153 return std::chrono::nanoseconds(0); 154 } 155 156 // A [propId, areaId] is newly subscribed or the subscribe options are changed. 157 // 158 // The subscribe options contain sample rate in Hz or enable/disable variable update rate. 159 // 160 // For continuous properties: 161 // 162 // The sample rate is never 0 and indicates the desired polling rate for this property. The 163 // sample rate is guaranteed to be within supported {@code minSampleRate} and 164 // {@code maxSampleRate} as specified in {@code VehiclePropConfig}. 165 // 166 // If the specified sample rate is not supported, e.g. vehicle bus only supports 5hz and 10hz 167 // polling rate but the sample rate is 8hz, impl must choose the higher polling rate (10hz). 168 // 169 // Whether variable update rate is enabled is specified by {@code enableVariableUpdateRate} in 170 // {@code SubscribeOptions}. If variable update rate is not supported for the 171 // [propId, areaId], impl must ignore this option and always treat it as disabled. 172 // 173 // If variable update rate is disabled/not supported, impl must report all the property events 174 // for this [propId, areaId] through {@code propertyChangeCallback} according to the sample 175 // rate. E.g. a sample rate of 10hz must generate at least 10 property change events per second. 176 // 177 // If variable update rate is enabled AND supported, impl must only report property events 178 // when the [propId, areaId]'s value or status changes (a.k.a same as on-change property). 179 // The sample rate still guides the polling rate, but duplicate property events must be dropped 180 // and not reported via {@code propertyChangeCallback}. 181 // 182 // Async property set error events are not affected by variable update rate and must always 183 // be reported. 184 // 185 // If the impl is always polling at {@code maxSampleRate} for all continuous [propId, areaId]s, 186 // and do not support variable update rate for any [propId, areaId], then this function can be a 187 // no-op. 188 // 189 // For on-change properties: 190 // 191 // The sample rate is always 0 and must be ignored. If the impl is always subscribing to all 192 // on-change properties, then this function can be no-op. 193 // 194 // For all properties: 195 // 196 // It is recommended to only deliver the subscribed property events to DefaultVehicleHal to 197 // improve performance. However, even if unsubscribed property events are delivered, they 198 // will be filtered out by DefaultVehicleHal. 199 // 200 // A subscription from VHAL client might not necessarily trigger this function. 201 // DefaultVehicleHal will aggregate all the subscriptions from all the clients and notify 202 // IVehicleHardware if new subscriptions are required or subscribe options are updated. 203 // 204 // For example: 205 // 1. VHAL initially have no subscriber for speed. 206 // 2. A new subscriber is subscribing speed for 10 times/s, 'subscribe' is called 207 // with sampleRate as 10. The impl is now polling vehicle speed from bus 10 times/s. 208 // 3. A new subscriber is subscribing speed for 5 times/s, because it is less than 10 209 // times/sec, 'subscribe' is not called. 210 // 4. The initial subscriber is removed, 'subscribe' is called with sampleRate as 211 // 5, because now it only needs to report event 5times/sec. The impl can now poll vehicle 212 // speed 5 times/s. If the impl is still polling at 10 times/s, that is okay as long as 213 // the polling rate is larger than 5times/s. DefaultVehicleHal would ignore the additional 214 // events. 215 // 5. The second subscriber is removed, 'unsubscribe' is called. 216 // The impl can optionally disable the polling for vehicle speed. 217 // subscribe(aidlvhal::SubscribeOptions options)218 virtual aidlvhal::StatusCode subscribe([[maybe_unused]] aidlvhal::SubscribeOptions options) { 219 return aidlvhal::StatusCode::OK; 220 } 221 222 // A [propId, areaId] is unsubscribed. This applies for both continuous or on-change property. unsubscribe(int32_t propId,int32_t areaId)223 virtual aidlvhal::StatusCode unsubscribe([[maybe_unused]] int32_t propId, 224 [[maybe_unused]] int32_t areaId) { 225 return aidlvhal::StatusCode::OK; 226 } 227 228 // This function is deprecated, subscribe/unsubscribe should be used instead. 229 // 230 // Update the sampling rate for the specified property and the specified areaId (0 for global 231 // property) if server supports it. The property must be a continuous property. 232 // {@code sampleRate} means that for this specific property, the server must generate at least 233 // this many OnPropertyChange events per seconds. 234 // A sampleRate of 0 means the property is no longer subscribed and server does not need to 235 // generate any onPropertyEvent for this property. 236 // This would be called if sample rate is updated for a subscriber, a new subscriber is added 237 // or an existing subscriber is removed. For example: 238 // 1. We have no subscriber for speed. 239 // 2. A new subscriber is subscribing speed for 10 times/s, updateSampleRate would be called 240 // with sampleRate as 10. The impl is now polling vehicle speed from bus 10 times/s. 241 // 3. A new subscriber is subscribing speed for 5 times/s, because it is less than 10 242 // times/sec, updateSampleRate would not be called. 243 // 4. The initial subscriber is removed, updateSampleRate would be called with sampleRate as 244 // 5, because now it only needs to report event 5times/sec. The impl can now poll vehicle 245 // speed 5 times/s. If the impl is still polling at 10 times/s, that is okay as long as 246 // the polling rate is larger than 5times/s. DefaultVehicleHal would ignore the additional 247 // events. 248 // 5. The second subscriber is removed, updateSampleRate would be called with sampleRate as 0. 249 // The impl can optionally disable the polling for vehicle speed. 250 // 251 // If the impl is always polling at {@code maxSampleRate} as specified in config, then this 252 // function can be a no-op. updateSampleRate(int32_t propId,int32_t areaId,float sampleRate)253 virtual aidlvhal::StatusCode updateSampleRate([[maybe_unused]] int32_t propId, 254 [[maybe_unused]] int32_t areaId, 255 [[maybe_unused]] float sampleRate) { 256 return aidlvhal::StatusCode::OK; 257 } 258 259 // Gets the min/max supported values for each of the specified [propId, areaId]s. 260 // 261 // The returned result may change dynamically. 262 // 263 // This is only called for [propId, areaId] that has 264 // {@code HasSupportedValueInfo.hasMinSupportedValue} or 265 // {@code HasSupportedValueInfo.hasMinSupportedValue} set to true. 266 // 267 // Client must implement (override) this function if at least one [propId, areaId]'s 268 // {@code HasSupportedValueInfo} is not null. getMinMaxSupportedValues(const std::vector<PropIdAreaId> & propIdAreaIds)269 virtual std::vector<aidlvhal::MinMaxSupportedValueResult> getMinMaxSupportedValues( 270 [[maybe_unused]] const std::vector<PropIdAreaId>& propIdAreaIds) { 271 return {}; 272 } 273 274 // Gets the supported values list for each of the specified [propId, areaId]s. 275 // 276 // The returned result may change dynamically. 277 // 278 // This is only called for [propId, areaId] that has 279 // {@code HasSupportedValueInfo.hasSupportedValuesList} set to true. 280 // 281 // Client must implement (override) this function if at least one [propId, areaId]'s 282 // {@code HasSupportedValueInfo} is not null. getSupportedValuesLists(const std::vector<PropIdAreaId> & propIdAreaIds)283 virtual std::vector<aidlvhal::SupportedValuesListResult> getSupportedValuesLists( 284 [[maybe_unused]] const std::vector<PropIdAreaId>& propIdAreaIds) { 285 return {}; 286 } 287 288 // Register a callback that would be called when the min/max supported value or supported 289 // values list change dynamically for propertyID returned from 290 // getPropertyIdsThatImplementGetSupportedValue 291 // 292 // This function must only be called once during initialization. 293 // 294 // Client must implement (override) this function if at least one [propId, areaId]'s 295 // {@code HasSupportedValueInfo} is not null. registerSupportedValueChangeCallback(std::unique_ptr<const SupportedValueChangeCallback> callback)296 virtual void registerSupportedValueChangeCallback( 297 [[maybe_unused]] std::unique_ptr<const SupportedValueChangeCallback> callback) { 298 // Do nothing. 299 } 300 301 // Subscribes to the min/max supported value or supported values list change for the specified 302 // [propId, areaId]s. 303 // 304 // If the propertyId's supported values are static, then must do nothing. 305 // 306 // If some of the [propId, areaId]s are already subscribed, then do nothing. 307 // 308 // This is only called for [propId, areaId] that has non-null {@code HasSupportedValueInfo}. 309 // 310 // Client must implement (override) this function if at least one [propId, areaId]'s 311 // {@code HasSupportedValueInfo} is not null. subscribeSupportedValueChange(const std::vector<PropIdAreaId> & propIdAreaIds)312 virtual aidlvhal::StatusCode subscribeSupportedValueChange( 313 [[maybe_unused]] const std::vector<PropIdAreaId>& propIdAreaIds) { 314 return aidlvhal::StatusCode::OK; 315 } 316 317 // Unsubscrbies to the min/max supported value or supported values list change. 318 // 319 // Must do nothing if the [propId, areaId] was not previously subscribed to for supported 320 // values change. 321 // 322 // This is only called for [propId, areaId] that has non-null {@code HasSupportedValueInfo}. 323 // 324 // Client must implement (override) this function if at least one [propId, areaId]'s 325 // {@code HasSupportedValueInfo} is not null. unsubscribeSupportedValueChange(const std::vector<PropIdAreaId> & propIdAreaIds)326 virtual aidlvhal::StatusCode unsubscribeSupportedValueChange( 327 [[maybe_unused]] const std::vector<PropIdAreaId>& propIdAreaIds) { 328 return aidlvhal::StatusCode::OK; 329 } 330 }; 331 332 } // namespace vehicle 333 } // namespace automotive 334 } // namespace hardware 335 } // namespace android 336 337 #endif // android_hardware_automotive_vehicle_aidl_impl_hardware_include_IVehicleHardware_H_ 338