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