• 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_vhal_include_SubscriptionManager_H_
18 #define android_hardware_automotive_vehicle_aidl_impl_vhal_include_SubscriptionManager_H_
19 
20 #include <IVehicleHardware.h>
21 #include <VehicleHalTypes.h>
22 #include <VehicleUtils.h>
23 
24 #include <aidl/android/hardware/automotive/vehicle/IVehicleCallback.h>
25 #include <android-base/result.h>
26 #include <android-base/thread_annotations.h>
27 
28 #include <mutex>
29 #include <optional>
30 #include <unordered_map>
31 #include <unordered_set>
32 #include <vector>
33 
34 namespace android {
35 namespace hardware {
36 namespace automotive {
37 namespace vehicle {
38 
39 // A class to represent all the subscription configs for a continuous [propId, areaId].
40 class ContSubConfigs final {
41   public:
42     using ClientIdType = const AIBinder*;
43 
44     void addClient(const ClientIdType& clientId, float sampleRate);
45     void removeClient(const ClientIdType& clientId);
46     float getMaxSampleRate();
47 
48   private:
49     float mMaxSampleRate = 0.;
50     std::unordered_map<ClientIdType, float> mSampleRates;
51 
52     void refreshMaxSampleRate();
53 };
54 
55 // A thread-safe subscription manager that manages all VHAL subscriptions.
56 class SubscriptionManager final {
57   public:
58     using ClientIdType = const AIBinder*;
59     using CallbackType =
60             std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicleCallback>;
61 
62     explicit SubscriptionManager(IVehicleHardware* hardware);
63     ~SubscriptionManager();
64 
65     // Subscribes to properties according to {@code SubscribeOptions}. Note that all option must
66     // contain non-empty areaIds field, which contains all area IDs to subscribe. As a result,
67     // the options here is different from the options passed from VHAL client.
68     // Returns error if any of the subscribe options is not valid or one of the properties failed
69     // to subscribe. Part of the properties maybe be subscribed successfully if this function
70     // returns error. Caller is safe to retry since subscribing to an already subscribed property
71     // is okay.
72     // Returns ok if all the options are parsed correctly and all the properties are subscribed.
73     VhalResult<void> subscribe(
74             const CallbackType& callback,
75             const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>&
76                     options,
77             bool isContinuousProperty);
78 
79     // Unsubscribes from the properties for the client.
80     // Returns error if the client was not subscribed before, or one of the given property was not
81     // subscribed, or one of the property failed to unsubscribe. Caller is safe to retry since
82     // unsubscribing to an already unsubscribed property is okay (it would be ignored).
83     // Returns ok if all the requested properties for the client are unsubscribed.
84     VhalResult<void> unsubscribe(ClientIdType client, const std::vector<int32_t>& propIds);
85 
86     // Unsubscribes from all the properties for the client.
87     // Returns error if the client was not subscribed before or one of the subscribed properties
88     // for the client failed to unsubscribe. Caller is safe to retry.
89     // Returns ok if all the properties for the client are unsubscribed.
90     VhalResult<void> unsubscribe(ClientIdType client);
91 
92     // For a list of updated properties, returns a map that maps clients subscribing to
93     // the updated properties to a list of updated values. This would only return on-change property
94     // clients that should be informed for the given updated values.
95     std::unordered_map<
96             CallbackType,
97             std::vector<const aidl::android::hardware::automotive::vehicle::VehiclePropValue*>>
98     getSubscribedClients(
99             const std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&
100                     updatedValues);
101 
102     // Gets the sample rate for the continuous property. Returns {@code std::nullopt} if the
103     // property has not been subscribed before or is not a continuous property.
104     std::optional<float> getSampleRate(const ClientIdType& clientId, int32_t propId,
105                                        int32_t areaId);
106 
107     // Checks whether the sample rate is valid.
108     static bool checkSampleRate(float sampleRate);
109 
110   private:
111     // Friend class for testing.
112     friend class DefaultVehicleHalTest;
113 
114     IVehicleHardware* mVehicleHardware;
115 
116     mutable std::mutex mLock;
117     std::unordered_map<PropIdAreaId, std::unordered_map<ClientIdType, CallbackType>,
118                        PropIdAreaIdHash>
119             mClientsByPropIdArea GUARDED_BY(mLock);
120     std::unordered_map<ClientIdType, std::unordered_set<PropIdAreaId, PropIdAreaIdHash>>
121             mSubscribedPropsByClient GUARDED_BY(mLock);
122     std::unordered_map<PropIdAreaId, ContSubConfigs, PropIdAreaIdHash> mContSubConfigsByPropIdArea
123             GUARDED_BY(mLock);
124 
125     VhalResult<void> updateSampleRateLocked(const ClientIdType& clientId,
126                                             const PropIdAreaId& propIdAreaId, float sampleRate)
127             REQUIRES(mLock);
128     VhalResult<void> removeSampleRateLocked(const ClientIdType& clientId,
129                                             const PropIdAreaId& propIdAreaId) REQUIRES(mLock);
130 
131     // Checks whether the manager is empty. For testing purpose.
132     bool isEmpty();
133 
134     // Get the interval in nanoseconds accroding to sample rate.
135     static android::base::Result<int64_t> getInterval(float sampleRate);
136 };
137 
138 }  // namespace vehicle
139 }  // namespace automotive
140 }  // namespace hardware
141 }  // namespace android
142 
143 #endif  // android_hardware_automotive_vehicle_aidl_impl_vhal_include_SubscriptionManager_H_
144