1 /* 2 * Copyright (C) 2022 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_COMMON_MULTICLIENTS_HAL_BASE_H_ 18 #define ANDROID_HARDWARE_CONTEXTHUB_COMMON_MULTICLIENTS_HAL_BASE_H_ 19 20 #ifndef LOG_TAG 21 #define LOG_TAG "CHRE.HAL" 22 #endif 23 24 #include <aidl/android/hardware/contexthub/BnContextHub.h> 25 #include <chre_host/generated/host_messages_generated.h> 26 27 #include "chre_connection_callback.h" 28 #include "chre_host/napp_header.h" 29 #include "chre_host/preloaded_nanoapp_loader.h" 30 #include "hal_client_id.h" 31 #include "hal_client_manager.h" 32 33 namespace android::hardware::contexthub::common::implementation { 34 35 using namespace aidl::android::hardware::contexthub; 36 using namespace android::chre; 37 using ::ndk::ScopedAStatus; 38 39 /** 40 * The base class of multiclients HAL. 41 * 42 * A subclass should initiate mConnection, mHalClientManager and 43 * mPreloadedNanoappLoader in its constructor. 44 * 45 * TODO(b/247124878): A few things are pending: 46 * - Some APIs of IContextHub are not implemented yet; 47 * - onHostEndpointConnected/Disconnected now returns an error if the endpoint 48 * id is illegal or already connected/disconnected. The doc of 49 * IContextHub.aidl should be updated accordingly. 50 * - registerCallback() can fail if mHalClientManager sees an error during 51 * registration. The doc of IContextHub.aidl should be updated accordingly. 52 * - Involve EventLogger to log API calls; 53 * - extends DebugDumpHelper to ease debugging 54 */ 55 class MultiClientContextHubBase 56 : public BnContextHub, 57 public ::android::hardware::contexthub::common::implementation:: 58 ChreConnectionCallback { 59 public: 60 /** The entry point of death recipient for a disconnected client. */ 61 static void onClientDied(void *cookie); 62 63 // functions implementing IContextHub 64 ScopedAStatus getContextHubs( 65 std::vector<ContextHubInfo> *contextHubInfos) override; 66 ScopedAStatus loadNanoapp(int32_t contextHubId, 67 const NanoappBinary &appBinary, 68 int32_t transactionId) override; 69 ScopedAStatus unloadNanoapp(int32_t contextHubId, int64_t appId, 70 int32_t transactionId) override; 71 ScopedAStatus disableNanoapp(int32_t contextHubId, int64_t appId, 72 int32_t transactionId) override; 73 ScopedAStatus enableNanoapp(int32_t contextHubId, int64_t appId, 74 int32_t transactionId) override; 75 ScopedAStatus onSettingChanged(Setting setting, bool enabled) override; 76 ScopedAStatus queryNanoapps(int32_t contextHubId) override; 77 ScopedAStatus registerCallback( 78 int32_t contextHubId, 79 const std::shared_ptr<IContextHubCallback> &callback) override; 80 ScopedAStatus sendMessageToHub(int32_t contextHubId, 81 const ContextHubMessage &message) override; 82 ScopedAStatus onHostEndpointConnected(const HostEndpointInfo &info) override; 83 ScopedAStatus onHostEndpointDisconnected(char16_t in_hostEndpointId) override; 84 ScopedAStatus getPreloadedNanoappIds(int32_t contextHubId, 85 std::vector<int64_t> *result) override; 86 ScopedAStatus onNanSessionStateChanged( 87 const NanSessionStateUpdate &in_update) override; 88 ScopedAStatus setTestMode(bool enable) override; 89 90 // The callback function implementing ChreConnectionCallback 91 void handleMessageFromChre(const unsigned char *messageBuffer, 92 size_t messageLen) override; 93 void onChreRestarted() override; 94 95 protected: 96 // The data needed by the death client to clear states of a client. 97 struct HalDeathRecipientCookie { 98 MultiClientContextHubBase *hal; 99 pid_t clientPid; HalDeathRecipientCookieHalDeathRecipientCookie100 HalDeathRecipientCookie(MultiClientContextHubBase *hal, pid_t pid) { 101 this->hal = hal; 102 this->clientPid = pid; 103 } 104 }; 105 MultiClientContextHubBase() = default; 106 107 bool sendFragmentedLoadRequest(HalClientId clientId, 108 FragmentedLoadRequest &fragmentedLoadRequest); 109 110 // Functions handling various types of messages 111 void handleHubInfoResponse(const ::chre::fbs::HubInfoResponseT &message); 112 void onNanoappListResponse(const ::chre::fbs::NanoappListResponseT &response, 113 HalClientId clientid); 114 void onNanoappLoadResponse(const ::chre::fbs::LoadNanoappResponseT &response, 115 HalClientId clientId); 116 void onNanoappUnloadResponse( 117 const ::chre::fbs::UnloadNanoappResponseT &response, 118 HalClientId clientId); 119 void onNanoappMessage(const ::chre::fbs::NanoappMessageT &message); 120 121 void handleClientDeath(pid_t pid); 122 isSettingEnabled(Setting setting)123 inline bool isSettingEnabled(Setting setting) { 124 return mSettingEnabled.find(setting) != mSettingEnabled.end() && 125 mSettingEnabled[setting]; 126 } 127 128 // HAL is the unique owner of the communication channel to CHRE. 129 std::unique_ptr<ChreConnection> mConnection{}; 130 131 // HalClientManager maintains states of hal clients. Each HAL should only have 132 // one instance of a HalClientManager. 133 std::unique_ptr<HalClientManager> mHalClientManager{}; 134 135 std::unique_ptr<PreloadedNanoappLoader> mPreloadedNanoappLoader{}; 136 137 std::unique_ptr<ContextHubInfo> mContextHubInfo; 138 139 // Mutex and CV are used to get context hub info synchronously. 140 std::mutex mHubInfoMutex; 141 std::condition_variable mHubInfoCondition; 142 143 // Death recipient handling clients' disconnections 144 ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; 145 146 // States of settings 147 std::unordered_map<Setting, bool> mSettingEnabled; 148 std::optional<bool> mIsWifiAvailable; 149 std::optional<bool> mIsBleAvailable; 150 151 // A mutex to synchronize access to the list of preloaded nanoapp IDs. 152 std::mutex mPreloadedNanoappIdsMutex; 153 std::optional<std::vector<uint64_t>> mPreloadedNanoappIds{}; 154 }; 155 } // namespace android::hardware::contexthub::common::implementation 156 #endif // ANDROID_HARDWARE_CONTEXTHUB_COMMON_MULTICLIENTS_HAL_BASE_H_ 157