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_ConnectedClient_H_
18 #define android_hardware_automotive_vehicle_aidl_impl_vhal_include_ConnectedClient_H_
19 
20 #include "PendingRequestPool.h"
21 
22 #include <IVehicleHardware.h>
23 #include <VehicleHalTypes.h>
24 #include <VehicleUtils.h>
25 
26 #include <aidl/android/hardware/automotive/vehicle/IVehicleCallback.h>
27 #include <android-base/result.h>
28 
29 #include <memory>
30 #include <unordered_set>
31 #include <vector>
32 
33 namespace android {
34 namespace hardware {
35 namespace automotive {
36 namespace vehicle {
37 
38 // A class to represent a binder client with a callback interface. Each callback function, e.g.
39 // GetValues or SetValues for a specific binder client is a separate {@code ConnectedClient}.
40 // For one {@code ConnectedClient}, we use one pending request pool to manage all pending requests,
41 // so the request IDs must be unique for one client. We also manage a set of callback functions
42 // for one client, e.g. timeoutCallback which could be passed to hardware.
43 // This class is thread-safe.
44 class ConnectedClient {
45   public:
46     using CallbackType =
47             std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicleCallback>;
48 
49     ConnectedClient(std::shared_ptr<PendingRequestPool> requestPool, CallbackType callback);
50 
51     virtual ~ConnectedClient() = default;
52 
53     // Gets the unique ID for this client.
54     const void* id();
55 
56     // Adds client requests. The requests would be registered as pending requests until
57     // {@code tryFinishRequests} is called for them.
58     // Returns {@code INVALID_ARG} error if any of the requestIds are duplicate with one of the
59     // pending request IDs or {@code TRY_AGAIN} error if the pending request pool is full and could
60     // no longer add requests.
61     VhalResult<void> addRequests(const std::unordered_set<int64_t>& requestIds);
62 
63     // Marks the requests as finished. Returns a list of request IDs that was pending and has been
64     // finished. It must be a set of the requested request IDs.
65     std::unordered_set<int64_t> tryFinishRequests(const std::unordered_set<int64_t>& requestIds);
66 
67   protected:
68     // Gets the callback to be called when the request for this client has timeout.
69     virtual std::shared_ptr<const PendingRequestPool::TimeoutCallbackFunc> getTimeoutCallback() = 0;
70 
71     const std::shared_ptr<PendingRequestPool> mRequestPool;
72     const CallbackType mCallback;
73 };
74 
75 // A class to represent a client that calls {@code IVehicle.setValues} or {@code
76 // IVehicle.getValues}.
77 template <class ResultType, class ResultsType>
78 class GetSetValuesClient final : public ConnectedClient {
79   public:
80     GetSetValuesClient(std::shared_ptr<PendingRequestPool> requestPool, CallbackType callback);
81 
82     // Sends the results to this client.
83     void sendResults(std::vector<ResultType>&& results);
84 
85     // Sends each result separately to this client. Each result would be sent through one callback
86     // invocation.
87     void sendResultsSeparately(const std::vector<ResultType>& results);
88 
89     // Gets the callback to be called when the request for this client has finished.
90     std::shared_ptr<const std::function<void(std::vector<ResultType>)>> getResultCallback();
91 
92   protected:
93     // Gets the callback to be called when the request for this client has timeout.
94     std::shared_ptr<const PendingRequestPool::TimeoutCallbackFunc> getTimeoutCallback() override;
95 
96   private:
97     // The following members are only initialized during construction.
98     std::shared_ptr<const PendingRequestPool::TimeoutCallbackFunc> mTimeoutCallback;
99     std::shared_ptr<const std::function<void(std::vector<ResultType>)>> mResultCallback;
100 };
101 
102 class SubscriptionClient {
103   public:
104     using CallbackType =
105             std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicleCallback>;
106 
107     // Marshals the updated values into largeParcelable and sends it through {@code onPropertyEvent}
108     // callback.
109     static void sendUpdatedValues(
110             CallbackType callback,
111             std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&&
112                     updatedValues);
113     // Marshals the set property error events into largeParcelable and sends it through
114     // {@code onPropertySetError} callback.
115     static void sendPropertySetErrors(
116             CallbackType callback,
117             std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropError>&&
118                     vehiclePropErrors);
119 };
120 
121 }  // namespace vehicle
122 }  // namespace automotive
123 }  // namespace hardware
124 }  // namespace android
125 
126 #endif  // android_hardware_automotive_vehicle_aidl_impl_vhal_include_ConnectedClient_H_
127