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_COMMON_CHRE_SOCKET_H 18 #define ANDROID_HARDWARE_CONTEXTHUB_COMMON_CHRE_SOCKET_H 19 20 #include <condition_variable> 21 #include <mutex> 22 23 #include "chre_host/fragmented_load_transaction.h" 24 #include "chre_host/host_protocol_host.h" 25 #include "chre_host/socket_client.h" 26 27 #ifdef CHRE_HAL_SOCKET_METRICS_ENABLED 28 #include <aidl/android/frameworks/stats/IStats.h> 29 30 #include "chre_host/metrics_reporter.h" 31 #endif // CHRE_HAL_SOCKET_METRICS_ENABLED 32 33 namespace android { 34 namespace hardware { 35 namespace contexthub { 36 namespace common { 37 namespace implementation { 38 39 /** 40 * Callback interface to be used for 41 * HalChreSocketConnection::registerCallback(). 42 */ 43 class IChreSocketCallback { 44 public: ~IChreSocketCallback()45 virtual ~IChreSocketCallback() {} 46 47 /** 48 * Invoked when a transaction completed 49 * 50 * @param transactionId The ID of the transaction. 51 * @param success true if the transaction succeeded. 52 */ 53 virtual void onTransactionResult(uint32_t transactionId, bool success) = 0; 54 55 /** 56 * Invoked when a nanoapp sends a message to this socket client. 57 * 58 * @param message The message. 59 */ 60 virtual void onNanoappMessage( 61 const ::chre::fbs::NanoappMessageT &message) = 0; 62 63 /** 64 * Invoked to provide a list of nanoapps previously requested by 65 * HalChreSocketConnection::queryNanoapps(). 66 * 67 * @param response The list response. 68 */ 69 virtual void onNanoappListResponse( 70 const ::chre::fbs::NanoappListResponseT &response) = 0; 71 72 /** 73 * Invoked when CHRE restarts. 74 */ 75 virtual void onContextHubRestarted() = 0; 76 77 /** 78 * Invoked when a data is available as a result of a debug dump request 79 * through HalChreSocketConnection::requestDebugDump(). 80 * 81 * @param data The debug dump data. 82 */ 83 virtual void onDebugDumpData(const ::chre::fbs::DebugDumpDataT &data) = 0; 84 85 /** 86 * Invoked when a debug dump is completed. 87 * 88 * @param response The debug dump response. 89 */ 90 virtual void onDebugDumpComplete( 91 const ::chre::fbs::DebugDumpResponseT &response) = 0; 92 93 /** 94 * Handles a ContextHub V4+ message or returns false. 95 * 96 * @param message The union of possible messages. 97 * @return true on successful handling 98 */ 99 virtual bool onContextHubV4Message( 100 const ::chre::fbs::ChreMessageUnion &message) = 0; 101 }; 102 103 /** 104 * A helper class that can be used to connect to the CHRE socket. 105 */ 106 class HalChreSocketConnection { 107 public: 108 HalChreSocketConnection(IChreSocketCallback *callback); 109 110 bool getContextHubs(::chre::fbs::HubInfoResponseT *response); 111 112 bool sendMessageToHub(uint64_t nanoappId, uint32_t messageType, 113 uint16_t hostEndpointId, const unsigned char *payload, 114 size_t payloadLength); 115 116 bool sendDebugConfiguration(); 117 118 bool loadNanoapp(chre::FragmentedLoadTransaction &transaction); 119 120 bool unloadNanoapp(uint64_t appId, uint32_t transactionId); 121 122 bool queryNanoapps(); 123 124 bool requestDebugDump(); 125 126 bool sendSettingChangedNotification(::chre::fbs::Setting fbsSetting, 127 ::chre::fbs::SettingState fbsState); 128 129 bool sendRawMessage(uint8_t *data, size_t size); 130 131 bool onHostEndpointConnected(uint16_t hostEndpointId, uint8_t type, 132 const std::string &package_name, 133 const std::string &attribution_tag); 134 135 bool onHostEndpointDisconnected(uint16_t hostEndpointId); 136 137 /** 138 * Returns true if there exists a pending load transaction; false otherwise. 139 * 140 * @return true there exists a pending load transaction. 141 * @return false there does not exist a pending load 142 * transaction. 143 */ 144 bool isLoadTransactionPending(); 145 146 private: 147 class SocketCallbacks : public ::android::chre::SocketClient::ICallbacks, 148 public ::android::chre::IChreMessageHandlers { 149 public: 150 explicit SocketCallbacks(HalChreSocketConnection &parent, 151 IChreSocketCallback *callback); 152 153 void onMessageReceived(const void *data, size_t length) override; 154 void onConnected() override; 155 void onDisconnected() override; 156 void handleNanoappMessage( 157 const ::chre::fbs::NanoappMessageT &message) override; 158 void handleHubInfoResponse( 159 const ::chre::fbs::HubInfoResponseT &response) override; 160 void handleNanoappListResponse( 161 const ::chre::fbs::NanoappListResponseT &response) override; 162 void handleLoadNanoappResponse( 163 const ::chre::fbs::LoadNanoappResponseT &response) override; 164 void handleUnloadNanoappResponse( 165 const ::chre::fbs::UnloadNanoappResponseT &response) override; 166 void handleDebugDumpData(const ::chre::fbs::DebugDumpDataT &data) override; 167 void handleDebugDumpResponse( 168 const ::chre::fbs::DebugDumpResponseT &response) override; 169 bool handleContextHubV4Message( 170 const ::chre::fbs::ChreMessageUnion &message) override; 171 172 private: 173 HalChreSocketConnection &mParent; 174 IChreSocketCallback *mCallback = nullptr; 175 bool mHaveConnected = false; 176 }; 177 178 sp<SocketCallbacks> mSocketCallbacks; 179 180 ::android::chre::SocketClient mClient; 181 182 ::chre::fbs::HubInfoResponseT mHubInfoResponse; 183 bool mHubInfoValid = false; 184 std::mutex mHubInfoMutex; 185 std::condition_variable mHubInfoCond; 186 187 // The pending fragmented load request 188 uint32_t mCurrentFragmentId = 0; 189 std::optional<chre::FragmentedLoadTransaction> mPendingLoadTransaction; 190 std::mutex mPendingLoadTransactionMutex; 191 192 #ifdef CHRE_HAL_SOCKET_METRICS_ENABLED 193 android::chre::MetricsReporter mMetricsReporter; 194 #endif // CHRE_HAL_SOCKET_METRICS_ENABLED 195 196 /** 197 * Checks to see if a load response matches the currently pending 198 * fragmented load transaction. mPendingLoadTransactionMutex must 199 * be acquired prior to calling this function. 200 * 201 * @param response the received load response 202 * 203 * @return true if the response matches a pending load transaction 204 * (if any), false otherwise 205 */ 206 bool isExpectedLoadResponseLocked( 207 const ::chre::fbs::LoadNanoappResponseT &response); 208 209 /** 210 * Sends a fragmented load request to CHRE. The caller must ensure that 211 * transaction.isComplete() returns false prior to invoking this method. 212 * 213 * @param transaction the FragmentedLoadTransaction object 214 * 215 * @return true if the load succeeded 216 */ 217 bool sendFragmentedLoadNanoAppRequest( 218 chre::FragmentedLoadTransaction &transaction); 219 }; 220 221 } // namespace implementation 222 } // namespace common 223 } // namespace contexthub 224 } // namespace hardware 225 } // namespace android 226 227 #endif // ANDROID_HARDWARE_CONTEXTHUB_COMMON_CHRE_SOCKET_H 228