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