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