• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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_MULTICLIENTS_HAL_BASE_H_
18 #define ANDROID_HARDWARE_CONTEXTHUB_COMMON_MULTICLIENTS_HAL_BASE_H_
19 
20 #ifndef LOG_TAG
21 #define LOG_TAG "CHRE.HAL"
22 #endif
23 
24 #include <aidl/android/hardware/contexthub/BnContextHub.h>
25 #include <chre_host/generated/host_messages_generated.h>
26 
27 #include "chre_connection_callback.h"
28 #include "chre_host/napp_header.h"
29 #include "chre_host/preloaded_nanoapp_loader.h"
30 #include "hal_client_id.h"
31 #include "hal_client_manager.h"
32 
33 namespace android::hardware::contexthub::common::implementation {
34 
35 using namespace aidl::android::hardware::contexthub;
36 using namespace android::chre;
37 using ::ndk::ScopedAStatus;
38 
39 /**
40  * The base class of multiclients HAL.
41  *
42  * A subclass should initiate mConnection, mHalClientManager and
43  * mPreloadedNanoappLoader in its constructor.
44  *
45  * TODO(b/247124878): A few things are pending:
46  *   - Some APIs of IContextHub are not implemented yet;
47  *   - onHostEndpointConnected/Disconnected now returns an error if the endpoint
48  *     id is illegal or already connected/disconnected. The doc of
49  *     IContextHub.aidl should be updated accordingly.
50  *   - registerCallback() can fail if mHalClientManager sees an error during
51  *     registration. The doc of IContextHub.aidl should be updated accordingly.
52  *   - Involve EventLogger to log API calls;
53  *   - extends DebugDumpHelper to ease debugging
54  */
55 class MultiClientContextHubBase
56     : public BnContextHub,
57       public ::android::hardware::contexthub::common::implementation::
58           ChreConnectionCallback {
59  public:
60   /** The entry point of death recipient for a disconnected client. */
61   static void onClientDied(void *cookie);
62 
63   // functions implementing IContextHub
64   ScopedAStatus getContextHubs(
65       std::vector<ContextHubInfo> *contextHubInfos) override;
66   ScopedAStatus loadNanoapp(int32_t contextHubId,
67                             const NanoappBinary &appBinary,
68                             int32_t transactionId) override;
69   ScopedAStatus unloadNanoapp(int32_t contextHubId, int64_t appId,
70                               int32_t transactionId) override;
71   ScopedAStatus disableNanoapp(int32_t contextHubId, int64_t appId,
72                                int32_t transactionId) override;
73   ScopedAStatus enableNanoapp(int32_t contextHubId, int64_t appId,
74                               int32_t transactionId) override;
75   ScopedAStatus onSettingChanged(Setting setting, bool enabled) override;
76   ScopedAStatus queryNanoapps(int32_t contextHubId) override;
77   ScopedAStatus registerCallback(
78       int32_t contextHubId,
79       const std::shared_ptr<IContextHubCallback> &callback) override;
80   ScopedAStatus sendMessageToHub(int32_t contextHubId,
81                                  const ContextHubMessage &message) override;
82   ScopedAStatus onHostEndpointConnected(const HostEndpointInfo &info) override;
83   ScopedAStatus onHostEndpointDisconnected(char16_t in_hostEndpointId) override;
84   ScopedAStatus getPreloadedNanoappIds(int32_t contextHubId,
85                                        std::vector<int64_t> *result) override;
86   ScopedAStatus onNanSessionStateChanged(
87       const NanSessionStateUpdate &in_update) override;
88   ScopedAStatus setTestMode(bool enable) override;
89 
90   // The callback function implementing ChreConnectionCallback
91   void handleMessageFromChre(const unsigned char *messageBuffer,
92                              size_t messageLen) override;
93   void onChreRestarted() override;
94 
95  protected:
96   // The data needed by the death client to clear states of a client.
97   struct HalDeathRecipientCookie {
98     MultiClientContextHubBase *hal;
99     pid_t clientPid;
HalDeathRecipientCookieHalDeathRecipientCookie100     HalDeathRecipientCookie(MultiClientContextHubBase *hal, pid_t pid) {
101       this->hal = hal;
102       this->clientPid = pid;
103     }
104   };
105   MultiClientContextHubBase() = default;
106 
107   bool sendFragmentedLoadRequest(HalClientId clientId,
108                                  FragmentedLoadRequest &fragmentedLoadRequest);
109 
110   // Functions handling various types of messages
111   void handleHubInfoResponse(const ::chre::fbs::HubInfoResponseT &message);
112   void onNanoappListResponse(const ::chre::fbs::NanoappListResponseT &response,
113                              HalClientId clientid);
114   void onNanoappLoadResponse(const ::chre::fbs::LoadNanoappResponseT &response,
115                              HalClientId clientId);
116   void onNanoappUnloadResponse(
117       const ::chre::fbs::UnloadNanoappResponseT &response,
118       HalClientId clientId);
119   void onNanoappMessage(const ::chre::fbs::NanoappMessageT &message);
120 
121   void handleClientDeath(pid_t pid);
122 
isSettingEnabled(Setting setting)123   inline bool isSettingEnabled(Setting setting) {
124     return mSettingEnabled.find(setting) != mSettingEnabled.end() &&
125            mSettingEnabled[setting];
126   }
127 
128   // HAL is the unique owner of the communication channel to CHRE.
129   std::unique_ptr<ChreConnection> mConnection{};
130 
131   // HalClientManager maintains states of hal clients. Each HAL should only have
132   // one instance of a HalClientManager.
133   std::unique_ptr<HalClientManager> mHalClientManager{};
134 
135   std::unique_ptr<PreloadedNanoappLoader> mPreloadedNanoappLoader{};
136 
137   std::unique_ptr<ContextHubInfo> mContextHubInfo;
138 
139   // Mutex and CV are used to get context hub info synchronously.
140   std::mutex mHubInfoMutex;
141   std::condition_variable mHubInfoCondition;
142 
143   // Death recipient handling clients' disconnections
144   ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
145 
146   // States of settings
147   std::unordered_map<Setting, bool> mSettingEnabled;
148   std::optional<bool> mIsWifiAvailable;
149   std::optional<bool> mIsBleAvailable;
150 
151   // A mutex to synchronize access to the list of preloaded nanoapp IDs.
152   std::mutex mPreloadedNanoappIdsMutex;
153   std::optional<std::vector<uint64_t>> mPreloadedNanoappIds{};
154 };
155 }  // namespace android::hardware::contexthub::common::implementation
156 #endif  // ANDROID_HARDWARE_CONTEXTHUB_COMMON_MULTICLIENTS_HAL_BASE_H_
157