• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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