• 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 <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