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