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