• 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 sampleRateHz);
45     void removeClient(const ClientIdType& clientId);
46     float getMaxSampleRateHz() const;
47 
48   private:
49     float mMaxSampleRateHz = 0.;
50     std::unordered_map<ClientIdType, float> mSampleRateHzByClient;
51 
52     void refreshMaxSampleRateHz();
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* vehicleHardware);
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     // For a list of set property error events, returns a map that maps clients subscribing to the
103     // properties to a list of errors for each client.
104     std::unordered_map<CallbackType,
105                        std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropError>>
106     getSubscribedClientsForErrorEvents(const std::vector<SetValueErrorEvent>& errorEvents);
107 
108     // Checks whether the sample rate is valid.
109     static bool checkSampleRateHz(float sampleRateHz);
110 
111   private:
112     // Friend class for testing.
113     friend class DefaultVehicleHalTest;
114 
115     IVehicleHardware* mVehicleHardware;
116 
117     mutable std::mutex mLock;
118     std::unordered_map<PropIdAreaId, std::unordered_map<ClientIdType, CallbackType>,
119                        PropIdAreaIdHash>
120             mClientsByPropIdArea GUARDED_BY(mLock);
121     std::unordered_map<ClientIdType, std::unordered_set<PropIdAreaId, PropIdAreaIdHash>>
122             mSubscribedPropsByClient GUARDED_BY(mLock);
123     std::unordered_map<PropIdAreaId, ContSubConfigs, PropIdAreaIdHash> mContSubConfigsByPropIdArea
124             GUARDED_BY(mLock);
125 
126     VhalResult<void> addContinuousSubscriberLocked(const ClientIdType& clientId,
127                                                    const PropIdAreaId& propIdAreaId,
128                                                    float sampleRateHz) REQUIRES(mLock);
129     VhalResult<void> removeContinuousSubscriberLocked(const ClientIdType& clientId,
130                                                       const PropIdAreaId& propIdAreaId)
131             REQUIRES(mLock);
132 
133     VhalResult<void> updateContSubConfigs(const PropIdAreaId& PropIdAreaId,
134                                           const ContSubConfigs& newConfig) REQUIRES(mLock);
135 
136     // Checks whether the manager is empty. For testing purpose.
137     bool isEmpty();
138 
139     // Get the interval in nanoseconds accroding to sample rate.
140     static android::base::Result<int64_t> getIntervalNanos(float sampleRateHz);
141 };
142 
143 }  // namespace vehicle
144 }  // namespace automotive
145 }  // namespace hardware
146 }  // namespace android
147 
148 #endif  // android_hardware_automotive_vehicle_aidl_impl_vhal_include_SubscriptionManager_H_
149