xref: /aosp_15_r20/system/chre/host/hal_generic/aidl/generic_context_hub_aidl.h (revision 84e339476a462649f82315436d70fd732297a399)
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_CONTEXTHUB_AIDL_CONTEXTHUB_H
18 #define ANDROID_HARDWARE_CONTEXTHUB_AIDL_CONTEXTHUB_H
19 
20 #include <aidl/android/hardware/contexthub/BnContextHub.h>
21 #include <android_chre_flags.h>
22 #include <log/log.h>
23 #include <atomic>
24 #include <functional>
25 #include <future>
26 #include <map>
27 #include <mutex>
28 #include <optional>
29 #include <unordered_set>
30 
31 #include "chre_host/napp_header.h"
32 #include "context_hub_v4_impl.h"
33 #include "debug_dump_helper.h"
34 #include "event_logger.h"
35 #include "hal_chre_socket_connection.h"
36 
37 namespace aidl::android::hardware::contexthub {
38 
39 using ::android::chre::NanoAppBinaryHeader;
40 
41 /**
42  * Contains information about a preloaded nanoapp. Used when getting
43  * preloaded nanoapp information from the config.
44  */
45 struct chrePreloadedNanoappInfo {
chrePreloadedNanoappInfochrePreloadedNanoappInfo46   chrePreloadedNanoappInfo(int64_t _id, const std::string &_name,
47                            const NanoAppBinaryHeader &_header)
48       : id(_id), name(_name), header(_header) {}
49 
50   int64_t id;
51   std::string name;
52   NanoAppBinaryHeader header;
53 };
54 
55 class ContextHub : public BnContextHub,
56                    public ::android::hardware::contexthub::DebugDumpHelper,
57                    public ::android::hardware::contexthub::common::
58                        implementation::IChreSocketCallback {
59  public:
ContextHub()60   ContextHub()
61       : mDeathRecipient(
62             AIBinder_DeathRecipient_new(ContextHub::onServiceDied)) {
63     if (::android::chre::flags::offload_implementation()) {
64       mV4Impl.emplace([this](uint8_t *data, size_t size) {
65         return mConnection.sendRawMessage(data, size);
66       });
67     }
68   }
69   ::ndk::ScopedAStatus getContextHubs(
70       std::vector<ContextHubInfo> *out_contextHubInfos) override;
71   ::ndk::ScopedAStatus loadNanoapp(int32_t contextHubId,
72                                    const NanoappBinary &appBinary,
73                                    int32_t transactionId) override;
74   ::ndk::ScopedAStatus unloadNanoapp(int32_t contextHubId, int64_t appId,
75                                      int32_t transactionId) override;
76   ::ndk::ScopedAStatus disableNanoapp(int32_t contextHubId, int64_t appId,
77                                       int32_t transactionId) override;
78   ::ndk::ScopedAStatus enableNanoapp(int32_t contextHubId, int64_t appId,
79                                      int32_t transactionId) override;
80   ::ndk::ScopedAStatus onSettingChanged(Setting setting, bool enabled) override;
81   ::ndk::ScopedAStatus queryNanoapps(int32_t contextHubId) override;
82   ::ndk::ScopedAStatus getPreloadedNanoappIds(
83       int32_t contextHubId,
84       std::vector<int64_t> *out_preloadedNanoappIds) override;
85   ::ndk::ScopedAStatus registerCallback(
86       int32_t contextHubId,
87       const std::shared_ptr<IContextHubCallback> &cb) override;
88   ::ndk::ScopedAStatus sendMessageToHub(
89       int32_t contextHubId, const ContextHubMessage &message) override;
90   ::ndk::ScopedAStatus setTestMode(bool enable) override;
91   ::ndk::ScopedAStatus sendMessageDeliveryStatusToHub(
92       int32_t contextHubId,
93       const MessageDeliveryStatus &messageDeliveryStatus) override;
94   ::ndk::ScopedAStatus onHostEndpointConnected(
95       const HostEndpointInfo &in_info) override;
96   ::ndk::ScopedAStatus onHostEndpointDisconnected(
97       char16_t in_hostEndpointId) override;
98   ::ndk::ScopedAStatus onNanSessionStateChanged(
99       const NanSessionStateUpdate &in_update) override;
100   ::ndk::ScopedAStatus getHubs(std::vector<HubInfo> *hubs) override;
101   ::ndk::ScopedAStatus getEndpoints(
102       std::vector<EndpointInfo> *endpoints) override;
103   ::ndk::ScopedAStatus registerEndpoint(const EndpointInfo &endpoint) override;
104   ::ndk::ScopedAStatus unregisterEndpoint(
105       const EndpointInfo &endpoint) override;
106   ::ndk::ScopedAStatus registerEndpointCallback(
107       const std::shared_ptr<IEndpointCallback> &callback) override;
108   ::ndk::ScopedAStatus requestSessionIdRange(
109       int32_t size, std::vector<int32_t> *ids) override;
110   ::ndk::ScopedAStatus openEndpointSession(
111       int32_t sessionId, const EndpointId &destination,
112       const EndpointId &initiator,
113       const std::optional<std::string> &serviceDescriptor) override;
114   ::ndk::ScopedAStatus sendMessageToEndpoint(int32_t sessionId,
115                                              const Message &msg) override;
116   ::ndk::ScopedAStatus sendMessageDeliveryStatusToEndpoint(
117       int32_t sessionId, const MessageDeliveryStatus &msgStatus) override;
118   ::ndk::ScopedAStatus closeEndpointSession(int32_t sessionId,
119                                             Reason reason) override;
120   ::ndk::ScopedAStatus endpointSessionOpenComplete(int32_t sessionId) override;
121 
122   void onNanoappMessage(const ::chre::fbs::NanoappMessageT &message) override;
123 
124   void onNanoappListResponse(
125       const ::chre::fbs::NanoappListResponseT &response) override;
126 
127   void onTransactionResult(uint32_t transactionId, bool success) override;
128 
129   void onContextHubRestarted() override;
130 
131   void onDebugDumpData(const ::chre::fbs::DebugDumpDataT &data) override;
132 
133   void onDebugDumpComplete(
134       const ::chre::fbs::DebugDumpResponseT &response) override;
135 
136   bool onContextHubV4Message(
137       const ::chre::fbs::ChreMessageUnion &message) override;
138 
139   void handleServiceDeath();
140   static void onServiceDied(void *cookie);
141 
142   binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
143 
requestDebugDump()144   bool requestDebugDump() override {
145     return mConnection.requestDebugDump();
146   }
147 
148   void debugDumpFinish() override;
149 
150   void writeToDebugFile(const char *str) override;
151 
152  private:
153   /**
154    * Enables test mode on the context hub. This unloads all nanoapps and puts
155    * CHRE in a state that is consistent for testing.
156    *
157    * @return                            the status.
158    */
159   ::ndk::ScopedAStatus enableTestMode();
160 
161   /**
162    * Disables test mode. Reverses the affects of enableTestMode() by loading all
163    * preloaded nanoapps. This puts CHRE back in a normal state.
164    *
165    * @return                            the status.
166    */
167   ::ndk::ScopedAStatus disableTestMode();
168 
169   /**
170    * Queries the list of loaded nanoapps in a synchronous manner.
171    * The list is stored in the mQueryNanoappsInternalList variable.
172    *
173    * @param contextHubId                the ID of the context hub.
174    * @param nanoappIdList               (out) optional out parameter that
175    *                                    contains the nanoapp IDs.
176    *
177    * @return true                       the operation was successful.
178    * @return false                      the operation was not successful.
179    */
180   bool queryNanoappsInternal(int32_t contextHubId,
181                              std::vector<int64_t> *nanoappIdList);
182 
183   /**
184    * Loads a nanoapp.
185    *
186    * @param appBinary                   the nanoapp binary to load.
187    * @param transactionId               the transaction ID.
188    *
189    * @return true                       the operation was successful.
190    * @return false                      the operation was not successful.
191    */
192   bool loadNanoappInternal(const NanoappBinary &appBinary,
193                            int32_t transactionId);
194 
195   /**
196    * Loads the nanoapps in a synchronous manner.
197    *
198    * @param contextHubId                the ID of the context hub.
199    * @param nanoappBinaryList           the list of NanoappBinary's to load.
200    * @return true                       the operation was successful.
201    * @return false                      the operation was not successful.
202    */
203   bool loadNanoappsInternal(
204       int32_t contextHubId,
205       const std::vector<NanoappBinary> &nanoappBinaryList);
206 
207   /**
208    * Unloads a nanoapp.
209    *
210    * @param appId                       the nanoapp ID to unload.
211    * @param transactionId               the transaction ID.
212    *
213    * @return true                       the operation was successful.
214    * @return false                      the operation was not successful.
215    */
216   bool unloadNanoappInternal(int64_t appId, int32_t transactionId);
217 
218   /**
219    * Unloads the nanoapps in a synchronous manner.
220    *
221    * @param contextHubId                the ID of the context hub.
222    * @param nanoappIdsToUnload          the list of nanoapp IDs to unload.
223    * @return true                       the operation was successful.
224    * @return false                      the operation was not successful.
225    */
226   bool unloadNanoappsInternal(int32_t contextHubId,
227                               const std::vector<int64_t> &nanoappIdList);
228 
229   /**
230    * Get the preloaded nanoapp IDs from the config file and headers. All IDs,
231    * names and headers are in the same order (one nanoapp has the same index in
232    * each).
233    *
234    * @param out_preloadedNanoapps       out parameter, the nanoapp information.
235    * @param out_directory               out parameter, optional, the directory
236    * that contains the nanoapps.
237    * @return true                       the operation was successful.
238    * @return false                      the operation was not successful.
239    */
240   bool getPreloadedNanoappIdsFromConfigFile(
241       std::vector<chrePreloadedNanoappInfo> &out_preloadedNanoapps,
242       std::string *out_directory) const;
243 
244   /**
245    * Selects the nanoapps to load -> all preloaded and non-system nanoapps.
246    *
247    * @param preloadedNanoapps           the preloaded nanoapps.
248    * @param preloadedNanoappDirectory   the preloaded nanoapp directory.
249    * @return                            the nanoapps to load.
250    */
251   std::vector<NanoappBinary> selectPreloadedNanoappsToLoad(
252       std::vector<chrePreloadedNanoappInfo> &preloadedNanoapps,
253       const std::string &preloadedNanoappDirectory);
254 
isSettingEnabled(Setting setting)255   bool isSettingEnabled(Setting setting) {
256     return mSettingEnabled.count(setting) > 0 && mSettingEnabled[setting];
257   }
258 
toFbsSettingState(bool enabled)259   chre::fbs::SettingState toFbsSettingState(bool enabled) const {
260     return enabled ? chre::fbs::SettingState::ENABLED
261                    : chre::fbs::SettingState::DISABLED;
262   }
263 
264   ::android::hardware::contexthub::common::implementation::
265       HalChreSocketConnection mConnection{this};
266 
267   // A mutex to protect concurrent modifications to the callback pointer and
268   // access (invocations).
269   std::mutex mCallbackMutex;
270   std::shared_ptr<IContextHubCallback> mCallback;
271 
272   ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
273 
274   // Implementation of the V4 API.
275   std::optional<
276       ::android::hardware::contexthub::common::implementation::ContextHubV4Impl>
277       mV4Impl{};
278 
279   std::map<Setting, bool> mSettingEnabled;
280   std::optional<bool> mIsWifiAvailable;
281   std::optional<bool> mIsBleAvailable;
282 
283   std::mutex mConnectedHostEndpointsMutex;
284   std::unordered_set<char16_t> mConnectedHostEndpoints;
285 
286   // Logs events to be reported in debug dumps.
287   EventLogger mEventLogger;
288 
289   // A mutex to synchronize access to the list of preloaded nanoapp IDs.
290   std::mutex mPreloadedNanoappIdsMutex;
291   std::optional<std::vector<int64_t>> mPreloadedNanoappIds;
292 
293   // A mutex and condition variable to synchronize queryNanoappsInternal.
294   std::mutex mQueryNanoappsInternalMutex;
295   std::condition_variable mQueryNanoappsInternalCondVar;
296   std::optional<std::vector<NanoappInfo>> mQueryNanoappsInternalList;
297 
298   // State for synchronous loads and unloads. Primarily used for test mode.
299   std::mutex mSynchronousLoadUnloadMutex;
300   std::condition_variable mSynchronousLoadUnloadCondVar;
301   std::optional<bool> mSynchronousLoadUnloadSuccess;
302   std::optional<int32_t> mSynchronousLoadUnloadTransactionId;
303 
304   // A boolean and mutex to synchronize test mode state changes and
305   // load/unloads.
306   std::mutex mTestModeMutex;
307   bool mIsTestModeEnabled = false;
308 
309   // List of system nanoapp Ids.
310   std::vector<int64_t> mSystemNanoappIds;
311 };
312 
313 }  // namespace aidl::android::hardware::contexthub
314 
315 #endif  // ANDROID_HARDWARE_CONTEXTHUB_AIDL_CONTEXTHUB_H
316