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 /** 95 * A helper class that can be used to connect to the CHRE socket. 96 */ 97 class HalChreSocketConnection { 98 public: 99 HalChreSocketConnection(IChreSocketCallback *callback); 100 101 bool getContextHubs(::chre::fbs::HubInfoResponseT *response); 102 103 bool sendMessageToHub(uint64_t nanoappId, uint32_t messageType, 104 uint16_t hostEndpointId, const unsigned char *payload, 105 size_t payloadLength); 106 107 bool sendDebugConfiguration(); 108 109 bool loadNanoapp(chre::FragmentedLoadTransaction &transaction); 110 111 bool unloadNanoapp(uint64_t appId, uint32_t transactionId); 112 113 bool queryNanoapps(); 114 115 bool requestDebugDump(); 116 117 bool sendSettingChangedNotification(::chre::fbs::Setting fbsSetting, 118 ::chre::fbs::SettingState fbsState); 119 120 bool onHostEndpointConnected(uint16_t hostEndpointId, uint8_t type, 121 const std::string &package_name, 122 const std::string &attribution_tag); 123 124 bool onHostEndpointDisconnected(uint16_t hostEndpointId); 125 126 /** 127 * Returns true if there exists a pending load transaction; false otherwise. 128 * 129 * @return true there exists a pending load transaction. 130 * @return false there does not exist a pending load 131 * transaction. 132 */ 133 bool isLoadTransactionPending(); 134 135 private: 136 class SocketCallbacks : public ::android::chre::SocketClient::ICallbacks, 137 public ::android::chre::IChreMessageHandlers { 138 public: 139 explicit SocketCallbacks(HalChreSocketConnection &parent, 140 IChreSocketCallback *callback); 141 142 void onMessageReceived(const void *data, size_t length) override; 143 void onConnected() override; 144 void onDisconnected() override; 145 void handleNanoappMessage( 146 const ::chre::fbs::NanoappMessageT &message) override; 147 void handleHubInfoResponse( 148 const ::chre::fbs::HubInfoResponseT &response) override; 149 void handleNanoappListResponse( 150 const ::chre::fbs::NanoappListResponseT &response) override; 151 void handleLoadNanoappResponse( 152 const ::chre::fbs::LoadNanoappResponseT &response) override; 153 void handleUnloadNanoappResponse( 154 const ::chre::fbs::UnloadNanoappResponseT &response) override; 155 void handleDebugDumpData(const ::chre::fbs::DebugDumpDataT &data) override; 156 void handleDebugDumpResponse( 157 const ::chre::fbs::DebugDumpResponseT &response) override; 158 159 private: 160 HalChreSocketConnection &mParent; 161 IChreSocketCallback *mCallback = nullptr; 162 bool mHaveConnected = false; 163 164 #ifdef CHRE_HAL_SOCKET_METRICS_ENABLED 165 long mLastClearedTimestamp = 0; 166 static constexpr uint32_t kOneDayinMillis = 24 * 60 * 60 * 1000; 167 static constexpr uint16_t kMaxDailyReportedApWakeUp = 200; 168 uint16_t mNanoappWokeUpCount = 0; 169 std::mutex mNanoappWokeApCountMutex; 170 #endif // CHRE_HAL_SOCKET_METRICS_ENABLED 171 }; 172 173 sp<SocketCallbacks> mSocketCallbacks; 174 175 ::android::chre::SocketClient mClient; 176 177 ::chre::fbs::HubInfoResponseT mHubInfoResponse; 178 bool mHubInfoValid = false; 179 std::mutex mHubInfoMutex; 180 std::condition_variable mHubInfoCond; 181 182 // The pending fragmented load request 183 uint32_t mCurrentFragmentId = 0; 184 std::optional<chre::FragmentedLoadTransaction> mPendingLoadTransaction; 185 std::mutex mPendingLoadTransactionMutex; 186 187 #ifdef CHRE_HAL_SOCKET_METRICS_ENABLED 188 android::chre::MetricsReporter mMetricsReporter; 189 #endif // CHRE_HAL_SOCKET_METRICS_ENABLED 190 191 /** 192 * Checks to see if a load response matches the currently pending 193 * fragmented load transaction. mPendingLoadTransactionMutex must 194 * be acquired prior to calling this function. 195 * 196 * @param response the received load response 197 * 198 * @return true if the response matches a pending load transaction 199 * (if any), false otherwise 200 */ 201 bool isExpectedLoadResponseLocked( 202 const ::chre::fbs::LoadNanoappResponseT &response); 203 204 /** 205 * Sends a fragmented load request to CHRE. The caller must ensure that 206 * transaction.isComplete() returns false prior to invoking this method. 207 * 208 * @param transaction the FragmentedLoadTransaction object 209 * 210 * @return true if the load succeeded 211 */ 212 bool sendFragmentedLoadNanoAppRequest( 213 chre::FragmentedLoadTransaction &transaction); 214 215 #ifdef CHRE_HAL_SOCKET_METRICS_ENABLED 216 // TODO(b/298459533): Remove this when the flag_log_nanoapp_load_metrics flag 217 // is cleaned up 218 /** 219 * Create and report CHRE vendor atom and send it to stats_client 220 * 221 * @param atom the vendor atom to be reported 222 */ 223 void reportMetric(const aidl::android::frameworks::stats::VendorAtom atom); 224 #endif // CHRE_HAL_SOCKET_METRICS_ENABLED 225 // TODO(b/298459533): Remove end 226 }; 227 228 } // namespace implementation 229 } // namespace common 230 } // namespace contexthub 231 } // namespace hardware 232 } // namespace android 233 234 #endif // ANDROID_HARDWARE_CONTEXTHUB_COMMON_CHRE_SOCKET_H 235