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