• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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