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 sendMessageDeliveryStatusToHub( 83 int32_t contextHubId, 84 const MessageDeliveryStatus &messageDeliveryStatus) override; 85 ::ndk::ScopedAStatus onHostEndpointConnected( 86 const HostEndpointInfo &in_info) override; 87 ::ndk::ScopedAStatus onHostEndpointDisconnected( 88 char16_t in_hostEndpointId) override; 89 ::ndk::ScopedAStatus onNanSessionStateChanged( 90 const NanSessionStateUpdate &in_update) override; 91 92 void onNanoappMessage(const ::chre::fbs::NanoappMessageT &message) override; 93 94 void onNanoappListResponse( 95 const ::chre::fbs::NanoappListResponseT &response) override; 96 97 void onTransactionResult(uint32_t transactionId, bool success) override; 98 99 void onContextHubRestarted() override; 100 101 void onDebugDumpData(const ::chre::fbs::DebugDumpDataT &data) override; 102 103 void onDebugDumpComplete( 104 const ::chre::fbs::DebugDumpResponseT &response) override; 105 106 void handleServiceDeath(); 107 static void onServiceDied(void *cookie); 108 109 binder_status_t dump(int fd, const char **args, uint32_t numArgs) override; 110 requestDebugDump()111 bool requestDebugDump() override { 112 return mConnection.requestDebugDump(); 113 } 114 115 void debugDumpFinish() override; 116 117 void writeToDebugFile(const char *str) override; 118 119 private: 120 /** 121 * Enables test mode on the context hub. This unloads all nanoapps and puts 122 * CHRE in a state that is consistent for testing. 123 * 124 * @return the status. 125 */ 126 ::ndk::ScopedAStatus enableTestMode(); 127 128 /** 129 * Disables test mode. Reverses the affects of enableTestMode() by loading all 130 * preloaded nanoapps. This puts CHRE back in a normal state. 131 * 132 * @return the status. 133 */ 134 ::ndk::ScopedAStatus disableTestMode(); 135 136 /** 137 * Queries the list of loaded nanoapps in a synchronous manner. 138 * The list is stored in the mQueryNanoappsInternalList variable. 139 * 140 * @param contextHubId the ID of the context hub. 141 * @param nanoappIdList (out) optional out parameter that 142 * contains the nanoapp IDs. 143 * 144 * @return true the operation was successful. 145 * @return false the operation was not successful. 146 */ 147 bool queryNanoappsInternal(int32_t contextHubId, 148 std::vector<int64_t> *nanoappIdList); 149 150 /** 151 * Loads a nanoapp. 152 * 153 * @param appBinary the nanoapp binary to load. 154 * @param transactionId the transaction ID. 155 * 156 * @return true the operation was successful. 157 * @return false the operation was not successful. 158 */ 159 bool loadNanoappInternal(const NanoappBinary &appBinary, 160 int32_t transactionId); 161 162 /** 163 * Loads the nanoapps in a synchronous manner. 164 * 165 * @param contextHubId the ID of the context hub. 166 * @param nanoappBinaryList the list of NanoappBinary's to load. 167 * @return true the operation was successful. 168 * @return false the operation was not successful. 169 */ 170 bool loadNanoappsInternal( 171 int32_t contextHubId, 172 const std::vector<NanoappBinary> &nanoappBinaryList); 173 174 /** 175 * Unloads a nanoapp. 176 * 177 * @param appId the nanoapp ID to unload. 178 * @param transactionId the transaction ID. 179 * 180 * @return true the operation was successful. 181 * @return false the operation was not successful. 182 */ 183 bool unloadNanoappInternal(int64_t appId, int32_t transactionId); 184 185 /** 186 * Unloads the nanoapps in a synchronous manner. 187 * 188 * @param contextHubId the ID of the context hub. 189 * @param nanoappIdsToUnload the list of nanoapp IDs to unload. 190 * @return true the operation was successful. 191 * @return false the operation was not successful. 192 */ 193 bool unloadNanoappsInternal(int32_t contextHubId, 194 const std::vector<int64_t> &nanoappIdList); 195 196 /** 197 * Get the preloaded nanoapp IDs from the config file and headers. All IDs, 198 * names and headers are in the same order (one nanoapp has the same index in 199 * each). 200 * 201 * @param out_preloadedNanoapps out parameter, the nanoapp information. 202 * @param out_directory out parameter, optional, the directory 203 * that contains the nanoapps. 204 * @return true the operation was successful. 205 * @return false the operation was not successful. 206 */ 207 bool getPreloadedNanoappIdsFromConfigFile( 208 std::vector<chrePreloadedNanoappInfo> &out_preloadedNanoapps, 209 std::string *out_directory) const; 210 211 /** 212 * Selects the nanoapps to load -> all preloaded and non-system nanoapps. 213 * 214 * @param preloadedNanoapps the preloaded nanoapps. 215 * @param preloadedNanoappDirectory the preloaded nanoapp directory. 216 * @return the nanoapps to load. 217 */ 218 std::vector<NanoappBinary> selectPreloadedNanoappsToLoad( 219 std::vector<chrePreloadedNanoappInfo> &preloadedNanoapps, 220 const std::string &preloadedNanoappDirectory); 221 isSettingEnabled(Setting setting)222 bool isSettingEnabled(Setting setting) { 223 return mSettingEnabled.count(setting) > 0 && mSettingEnabled[setting]; 224 } 225 toFbsSettingState(bool enabled)226 chre::fbs::SettingState toFbsSettingState(bool enabled) const { 227 return enabled ? chre::fbs::SettingState::ENABLED 228 : chre::fbs::SettingState::DISABLED; 229 } 230 231 ::android::hardware::contexthub::common::implementation:: 232 HalChreSocketConnection mConnection{this}; 233 234 // A mutex to protect concurrent modifications to the callback pointer and 235 // access (invocations). 236 std::mutex mCallbackMutex; 237 std::shared_ptr<IContextHubCallback> mCallback; 238 239 ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; 240 241 std::map<Setting, bool> mSettingEnabled; 242 std::optional<bool> mIsWifiAvailable; 243 std::optional<bool> mIsBleAvailable; 244 245 std::mutex mConnectedHostEndpointsMutex; 246 std::unordered_set<char16_t> mConnectedHostEndpoints; 247 248 // Logs events to be reported in debug dumps. 249 EventLogger mEventLogger; 250 251 // A mutex to synchronize access to the list of preloaded nanoapp IDs. 252 std::mutex mPreloadedNanoappIdsMutex; 253 std::optional<std::vector<int64_t>> mPreloadedNanoappIds; 254 255 // A mutex and condition variable to synchronize queryNanoappsInternal. 256 std::mutex mQueryNanoappsInternalMutex; 257 std::condition_variable mQueryNanoappsInternalCondVar; 258 std::optional<std::vector<NanoappInfo>> mQueryNanoappsInternalList; 259 260 // State for synchronous loads and unloads. Primarily used for test mode. 261 std::mutex mSynchronousLoadUnloadMutex; 262 std::condition_variable mSynchronousLoadUnloadCondVar; 263 std::optional<bool> mSynchronousLoadUnloadSuccess; 264 std::optional<int32_t> mSynchronousLoadUnloadTransactionId; 265 266 // A boolean and mutex to synchronize test mode state changes and 267 // load/unloads. 268 std::mutex mTestModeMutex; 269 bool mIsTestModeEnabled = false; 270 271 // List of system nanoapp Ids. 272 std::vector<int64_t> mSystemNanoappIds; 273 }; 274 275 } // namespace aidl::android::hardware::contexthub 276 277 #endif // ANDROID_HARDWARE_CONTEXTHUB_AIDL_CONTEXTHUB_H 278