• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 #pragma once
18 
19 #include <assert.h>
20 
21 #include <array>
22 #include <functional>
23 #include <mutex>
24 #include <optional>
25 #include <string>
26 #include <vector>
27 
28 #include <aidl/android/hardware/contexthub/BnContextHub.h>
29 #include <aidl/android/hardware/contexthub/BnEndpointCommunication.h>
30 #include <chre_host/generated/host_messages_generated.h>
31 #include <flatbuffers/flatbuffers.h>
32 
33 #include "message_hub_manager.h"
34 
35 namespace android::hardware::contexthub::common::implementation {
36 
37 using ::aidl::android::hardware::contexthub::BnEndpointCommunication;
38 using ::aidl::android::hardware::contexthub::EndpointId;
39 using ::aidl::android::hardware::contexthub::EndpointInfo;
40 using ::aidl::android::hardware::contexthub::HubInfo;
41 using ::aidl::android::hardware::contexthub::IEndpointCallback;
42 using ::aidl::android::hardware::contexthub::IEndpointCommunication;
43 using ::aidl::android::hardware::contexthub::Message;
44 using ::aidl::android::hardware::contexthub::MessageDeliveryStatus;
45 using ::aidl::android::hardware::contexthub::Reason;
46 using ::ndk::ScopedAStatus;
47 
48 /**
49  * Common parts of the IContextHub V4+ interface which can be shared by
50  * various HAL implementations.
51  */
52 class ContextHubV4Impl {
53  public:
54   using SendMessageFn =
55       std::function<bool(const flatbuffers::FlatBufferBuilder &builder)>;
56 
ContextHubV4Impl(SendMessageFn sendMessageFn)57   explicit ContextHubV4Impl(SendMessageFn sendMessageFn)
58       : mManager(std::bind(&ContextHubV4Impl::unlinkDeadHostHub, this,
59                            std::placeholders::_1)),
60         mSendMessageFn(std::move(sendMessageFn)) {}
61   ~ContextHubV4Impl() = default;
62 
63   /**
64    * Initializes the implementation.
65    *
66    * This should be called once a connection with CHRE has been established.
67    * Requests a dump of embedded hubs and endpoints from CHRE. Initializes the
68    * CHRE-side host hub proxies.
69    */
70   void init();
71 
72   /**
73    * Closes all existing sessions and embedded endpoints.
74    */
75   void onChreDisconnected();
76 
77   /**
78    * Sends host state to CHRE.
79    *
80    * This should be called once the connection with CHRE has been restored.
81    */
82   void onChreRestarted();
83 
84   // IContextHub (V4+) API implementation.
85   ScopedAStatus getHubs(std::vector<HubInfo> *hubs);
86   ScopedAStatus getEndpoints(std::vector<EndpointInfo> *endpoints);
87   ScopedAStatus registerEndpointHub(
88       const std::shared_ptr<IEndpointCallback> &callback,
89       const HubInfo &hubInfo,
90       std::shared_ptr<IEndpointCommunication> *hubInterface);
91 
92   // TODO(b/385474431): Add dump().
93 
94   /**
95    * Handles a CHRE message that is part of the V4 implementation.
96    *
97    * @param message Validated union of the various message types.
98    * @return true if the message could be handled
99    */
100   bool handleMessageFromChre(const ::chre::fbs::ChreMessageUnion &message);
101 
102  private:
103   // Callbacks for each message type from CHRE.
104   void onGetMessageHubsAndEndpointsResponse(
105       const ::chre::fbs::GetMessageHubsAndEndpointsResponseT &msg);
106   void onRegisterMessageHub(const ::chre::fbs::RegisterMessageHubT &msg);
107   void onUnregisterMessageHub(const ::chre::fbs::UnregisterMessageHubT &msg);
108   void onRegisterEndpoint(const ::chre::fbs::RegisterEndpointT &msg);
109   void onAddServiceToEndpoint(const ::chre::fbs::AddServiceToEndpointT &msg);
110   void onEndpointReady(const ::chre::fbs::EndpointReadyT &msg);
111   void onUnregisterEndpoint(const ::chre::fbs::UnregisterEndpointT &msg);
112   void onOpenEndpointSessionRequest(
113       const ::chre::fbs::OpenEndpointSessionRequestT &msg);
114   void onEndpointSessionOpened(const ::chre::fbs::EndpointSessionOpenedT &msg);
115   void onEndpointSessionClosed(const ::chre::fbs::EndpointSessionClosedT &msg);
116   void onEndpointSessionMessage(
117       const ::chre::fbs::EndpointSessionMessageT &msg);
118   void onEndpointSessionMessageDeliveryStatus(
119       const ::chre::fbs::EndpointSessionMessageDeliveryStatusT &msg);
120 
121   // Callback invoked when a HAL client associated with a host hub goes down.
122   void unlinkDeadHostHub(std::function<pw::Result<int64_t>()> unlinkFn);
123 
124   // Log error and close a session.
125   void handleSessionFailure(
126       const std::shared_ptr<MessageHubManager::HostHub> &hub, uint16_t session,
127       pw::Status status);
128 
129   MessageHubManager mManager;
130   SendMessageFn mSendMessageFn;
131 
132   // This lock is required to be held around any operation which modifies the
133   // sets of host hubs or endpoints known by mManager and then sends an update
134   // message to CHRE. This ensures that init()/onChreRestarted() are atomic
135   // w.r.t. registerEndpointHub(), unregister(), registerEndpoint() and
136   // unregisterEndpoint(). As init() resets CHRE-side host hub state,
137   // interleaving these operations could e.g. leave an existing host hub
138   // inaccessible from CHRE.
139   std::mutex mHostHubOpLock;
140 };
141 
142 /**
143  * Wrapper for a MessageHubManager::HostHub instance implementing
144  * IEndpointCommunication so that a client can directly make calls on its
145  * associated HostHub.
146  */
147 class HostHubInterface : public BnEndpointCommunication {
148  public:
HostHubInterface(std::shared_ptr<MessageHubManager::HostHub> hub,ContextHubV4Impl::SendMessageFn & sendMessageFn,std::mutex & hostHubOpLock)149   explicit HostHubInterface(std::shared_ptr<MessageHubManager::HostHub> hub,
150                             ContextHubV4Impl::SendMessageFn &sendMessageFn,
151                             std::mutex &hostHubOpLock)
152       : mHub(std::move(hub)),
153         mSendMessageFn(sendMessageFn),
154         mHostHubOpLock(hostHubOpLock) {
155     assert(mHub != nullptr);
156   }
157   ~HostHubInterface() = default;
158 
159   // Implementation of IEndpointCommunication.
160   ScopedAStatus registerEndpoint(const EndpointInfo &endpoint) override;
161   ScopedAStatus unregisterEndpoint(const EndpointInfo &endpoint) override;
162   ScopedAStatus requestSessionIdRange(int32_t size,
163                                       std::array<int32_t, 2> *ids);
164   ScopedAStatus openEndpointSession(
165       int32_t sessionId, const EndpointId &destination,
166       const EndpointId &initiator,
167       const std::optional<std::string> &serviceDescriptor) override;
168   ScopedAStatus sendMessageToEndpoint(int32_t sessionId,
169                                       const Message &msg) override;
170   ScopedAStatus sendMessageDeliveryStatusToEndpoint(
171       int32_t sessionId, const MessageDeliveryStatus &msgStatus) override;
172   ScopedAStatus closeEndpointSession(int32_t sessionId, Reason reason) override;
173   ScopedAStatus endpointSessionOpenComplete(int32_t sessionId) override;
174   ScopedAStatus unregister() override;
175 
176  private:
177   std::shared_ptr<MessageHubManager::HostHub> mHub;
178   // see ContextHubV4Impl::mSendMessageFn.
179   ContextHubV4Impl::SendMessageFn &mSendMessageFn;
180   std::mutex &mHostHubOpLock;  // see ContextHubV4Impl::mHostHubOpLock.
181 };
182 
183 }  // namespace android::hardware::contexthub::common::implementation
184