xref: /aosp_15_r20/hardware/interfaces/contexthub/aidl/default/ContextHub.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker  *
4*4d7e907cSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker  *
8*4d7e907cSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker  *
10*4d7e907cSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker  * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker  */
16*4d7e907cSAndroid Build Coastguard Worker 
17*4d7e907cSAndroid Build Coastguard Worker #include "contexthub-impl/ContextHub.h"
18*4d7e907cSAndroid Build Coastguard Worker 
19*4d7e907cSAndroid Build Coastguard Worker #ifndef LOG_TAG
20*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "CHRE"
21*4d7e907cSAndroid Build Coastguard Worker #endif
22*4d7e907cSAndroid Build Coastguard Worker 
23*4d7e907cSAndroid Build Coastguard Worker #include <inttypes.h>
24*4d7e907cSAndroid Build Coastguard Worker #include <log/log.h>
25*4d7e907cSAndroid Build Coastguard Worker 
26*4d7e907cSAndroid Build Coastguard Worker using ::ndk::ScopedAStatus;
27*4d7e907cSAndroid Build Coastguard Worker 
28*4d7e907cSAndroid Build Coastguard Worker namespace aidl::android::hardware::contexthub {
29*4d7e907cSAndroid Build Coastguard Worker 
30*4d7e907cSAndroid Build Coastguard Worker namespace {
31*4d7e907cSAndroid Build Coastguard Worker 
32*4d7e907cSAndroid Build Coastguard Worker constexpr uint64_t kMockVendorHubId = 0x1234567812345678;
33*4d7e907cSAndroid Build Coastguard Worker constexpr uint64_t kMockVendorHub2Id = 0x0EADBEEFDEADBEEF;
34*4d7e907cSAndroid Build Coastguard Worker 
35*4d7e907cSAndroid Build Coastguard Worker // Mock endpoints for the default implementation.
36*4d7e907cSAndroid Build Coastguard Worker // These endpoints just echo back any messages sent to them.
37*4d7e907cSAndroid Build Coastguard Worker constexpr size_t kMockEndpointCount = 4;
38*4d7e907cSAndroid Build Coastguard Worker const EndpointInfo kMockEndpointInfos[kMockEndpointCount] = {
39*4d7e907cSAndroid Build Coastguard Worker         {
40*4d7e907cSAndroid Build Coastguard Worker                 .id = {.hubId = kMockVendorHubId, .id = UINT64_C(0x1)},
41*4d7e907cSAndroid Build Coastguard Worker                 .type = EndpointInfo::EndpointType::GENERIC,
42*4d7e907cSAndroid Build Coastguard Worker                 .name = "Mock Endpoint 1",
43*4d7e907cSAndroid Build Coastguard Worker                 .version = 1,
44*4d7e907cSAndroid Build Coastguard Worker         },
45*4d7e907cSAndroid Build Coastguard Worker         {
46*4d7e907cSAndroid Build Coastguard Worker                 .id = {.hubId = kMockVendorHubId, .id = UINT64_C(0x2)},
47*4d7e907cSAndroid Build Coastguard Worker                 .type = EndpointInfo::EndpointType::GENERIC,
48*4d7e907cSAndroid Build Coastguard Worker                 .name = "Mock Endpoint 2",
49*4d7e907cSAndroid Build Coastguard Worker                 .version = 2,
50*4d7e907cSAndroid Build Coastguard Worker         },
51*4d7e907cSAndroid Build Coastguard Worker         {
52*4d7e907cSAndroid Build Coastguard Worker                 .id = {.hubId = kMockVendorHub2Id, .id = UINT64_C(0x1)},
53*4d7e907cSAndroid Build Coastguard Worker                 .type = EndpointInfo::EndpointType::GENERIC,
54*4d7e907cSAndroid Build Coastguard Worker                 .name = "Mock Endpoint 3",
55*4d7e907cSAndroid Build Coastguard Worker                 .version = 1,
56*4d7e907cSAndroid Build Coastguard Worker         },
57*4d7e907cSAndroid Build Coastguard Worker         {
58*4d7e907cSAndroid Build Coastguard Worker                 .id = {.hubId = kMockVendorHub2Id, .id = UINT64_C(0x2)},
59*4d7e907cSAndroid Build Coastguard Worker                 .type = EndpointInfo::EndpointType::GENERIC,
60*4d7e907cSAndroid Build Coastguard Worker                 .name = "Mock Endpoint 4",
61*4d7e907cSAndroid Build Coastguard Worker                 .version = 2,
62*4d7e907cSAndroid Build Coastguard Worker         },
63*4d7e907cSAndroid Build Coastguard Worker };
64*4d7e907cSAndroid Build Coastguard Worker 
65*4d7e907cSAndroid Build Coastguard Worker }  // anonymous namespace
66*4d7e907cSAndroid Build Coastguard Worker 
getContextHubs(std::vector<ContextHubInfo> * out_contextHubInfos)67*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::getContextHubs(std::vector<ContextHubInfo>* out_contextHubInfos) {
68*4d7e907cSAndroid Build Coastguard Worker     ContextHubInfo hub = {};
69*4d7e907cSAndroid Build Coastguard Worker     hub.name = "Mock Context Hub";
70*4d7e907cSAndroid Build Coastguard Worker     hub.vendor = "AOSP";
71*4d7e907cSAndroid Build Coastguard Worker     hub.toolchain = "n/a";
72*4d7e907cSAndroid Build Coastguard Worker     hub.id = kMockHubId;
73*4d7e907cSAndroid Build Coastguard Worker     hub.peakMips = 1;
74*4d7e907cSAndroid Build Coastguard Worker     hub.maxSupportedMessageLengthBytes = 4096;
75*4d7e907cSAndroid Build Coastguard Worker     hub.chrePlatformId = UINT64_C(0x476f6f6754000000);
76*4d7e907cSAndroid Build Coastguard Worker     hub.chreApiMajorVersion = 1;
77*4d7e907cSAndroid Build Coastguard Worker     hub.chreApiMinorVersion = 6;
78*4d7e907cSAndroid Build Coastguard Worker     hub.supportsReliableMessages = false;
79*4d7e907cSAndroid Build Coastguard Worker 
80*4d7e907cSAndroid Build Coastguard Worker     out_contextHubInfos->push_back(hub);
81*4d7e907cSAndroid Build Coastguard Worker 
82*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
83*4d7e907cSAndroid Build Coastguard Worker }
84*4d7e907cSAndroid Build Coastguard Worker 
85*4d7e907cSAndroid Build Coastguard Worker // We don't expose any nanoapps for the default impl, therefore all nanoapp-related APIs fail.
loadNanoapp(int32_t,const NanoappBinary &,int32_t)86*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::loadNanoapp(int32_t /* in_contextHubId */,
87*4d7e907cSAndroid Build Coastguard Worker                                       const NanoappBinary& /* in_appBinary */,
88*4d7e907cSAndroid Build Coastguard Worker                                       int32_t /* in_transactionId */) {
89*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
90*4d7e907cSAndroid Build Coastguard Worker }
91*4d7e907cSAndroid Build Coastguard Worker 
unloadNanoapp(int32_t,int64_t,int32_t)92*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::unloadNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */,
93*4d7e907cSAndroid Build Coastguard Worker                                         int32_t /* in_transactionId */) {
94*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
95*4d7e907cSAndroid Build Coastguard Worker }
96*4d7e907cSAndroid Build Coastguard Worker 
disableNanoapp(int32_t,int64_t,int32_t)97*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::disableNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */,
98*4d7e907cSAndroid Build Coastguard Worker                                          int32_t /* in_transactionId */) {
99*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
100*4d7e907cSAndroid Build Coastguard Worker }
101*4d7e907cSAndroid Build Coastguard Worker 
enableNanoapp(int32_t,int64_t,int32_t)102*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::enableNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */,
103*4d7e907cSAndroid Build Coastguard Worker                                         int32_t /* in_transactionId */) {
104*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
105*4d7e907cSAndroid Build Coastguard Worker }
106*4d7e907cSAndroid Build Coastguard Worker 
onSettingChanged(Setting,bool)107*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::onSettingChanged(Setting /* in_setting */, bool /*in_enabled */) {
108*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
109*4d7e907cSAndroid Build Coastguard Worker }
110*4d7e907cSAndroid Build Coastguard Worker 
queryNanoapps(int32_t in_contextHubId)111*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::queryNanoapps(int32_t in_contextHubId) {
112*4d7e907cSAndroid Build Coastguard Worker     if (in_contextHubId == kMockHubId && mCallback != nullptr) {
113*4d7e907cSAndroid Build Coastguard Worker         std::vector<NanoappInfo> nanoapps;
114*4d7e907cSAndroid Build Coastguard Worker         mCallback->handleNanoappInfo(nanoapps);
115*4d7e907cSAndroid Build Coastguard Worker         return ScopedAStatus::ok();
116*4d7e907cSAndroid Build Coastguard Worker     } else {
117*4d7e907cSAndroid Build Coastguard Worker         return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
118*4d7e907cSAndroid Build Coastguard Worker     }
119*4d7e907cSAndroid Build Coastguard Worker }
120*4d7e907cSAndroid Build Coastguard Worker 
getPreloadedNanoappIds(int32_t,std::vector<int64_t> * out_preloadedNanoappIds)121*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::getPreloadedNanoappIds(int32_t /* in_contextHubId */,
122*4d7e907cSAndroid Build Coastguard Worker                                                  std::vector<int64_t>* out_preloadedNanoappIds) {
123*4d7e907cSAndroid Build Coastguard Worker     if (out_preloadedNanoappIds == nullptr) {
124*4d7e907cSAndroid Build Coastguard Worker         return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
125*4d7e907cSAndroid Build Coastguard Worker     }
126*4d7e907cSAndroid Build Coastguard Worker 
127*4d7e907cSAndroid Build Coastguard Worker     for (uint64_t i = 0; i < 10; ++i) {
128*4d7e907cSAndroid Build Coastguard Worker         out_preloadedNanoappIds->push_back(i);
129*4d7e907cSAndroid Build Coastguard Worker     }
130*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
131*4d7e907cSAndroid Build Coastguard Worker }
132*4d7e907cSAndroid Build Coastguard Worker 
onNanSessionStateChanged(const NanSessionStateUpdate &)133*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::onNanSessionStateChanged(const NanSessionStateUpdate& /*in_update*/) {
134*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
135*4d7e907cSAndroid Build Coastguard Worker }
136*4d7e907cSAndroid Build Coastguard Worker 
registerCallback(int32_t in_contextHubId,const std::shared_ptr<IContextHubCallback> & in_cb)137*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::registerCallback(int32_t in_contextHubId,
138*4d7e907cSAndroid Build Coastguard Worker                                            const std::shared_ptr<IContextHubCallback>& in_cb) {
139*4d7e907cSAndroid Build Coastguard Worker     if (in_contextHubId == kMockHubId) {
140*4d7e907cSAndroid Build Coastguard Worker         mCallback = in_cb;
141*4d7e907cSAndroid Build Coastguard Worker         return ScopedAStatus::ok();
142*4d7e907cSAndroid Build Coastguard Worker     } else {
143*4d7e907cSAndroid Build Coastguard Worker         return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
144*4d7e907cSAndroid Build Coastguard Worker     }
145*4d7e907cSAndroid Build Coastguard Worker }
146*4d7e907cSAndroid Build Coastguard Worker 
sendMessageToHub(int32_t in_contextHubId,const ContextHubMessage &)147*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::sendMessageToHub(int32_t in_contextHubId,
148*4d7e907cSAndroid Build Coastguard Worker                                            const ContextHubMessage& /* in_message */) {
149*4d7e907cSAndroid Build Coastguard Worker     if (in_contextHubId == kMockHubId) {
150*4d7e907cSAndroid Build Coastguard Worker         // Return true here to indicate that the HAL has accepted the message.
151*4d7e907cSAndroid Build Coastguard Worker         // Successful delivery of the message to a nanoapp should be handled at
152*4d7e907cSAndroid Build Coastguard Worker         // a higher level protocol.
153*4d7e907cSAndroid Build Coastguard Worker         return ScopedAStatus::ok();
154*4d7e907cSAndroid Build Coastguard Worker     } else {
155*4d7e907cSAndroid Build Coastguard Worker         return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
156*4d7e907cSAndroid Build Coastguard Worker     }
157*4d7e907cSAndroid Build Coastguard Worker }
158*4d7e907cSAndroid Build Coastguard Worker 
setTestMode(bool enable)159*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::setTestMode(bool enable) {
160*4d7e907cSAndroid Build Coastguard Worker     if (enable) {
161*4d7e907cSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> lock(mEndpointMutex);
162*4d7e907cSAndroid Build Coastguard Worker         mEndpoints.clear();
163*4d7e907cSAndroid Build Coastguard Worker         mEndpointSessions.clear();
164*4d7e907cSAndroid Build Coastguard Worker         mEndpointCallback = nullptr;
165*4d7e907cSAndroid Build Coastguard Worker     }
166*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
167*4d7e907cSAndroid Build Coastguard Worker }
168*4d7e907cSAndroid Build Coastguard Worker 
onHostEndpointConnected(const HostEndpointInfo & in_info)169*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) {
170*4d7e907cSAndroid Build Coastguard Worker     mConnectedHostEndpoints.insert(in_info.hostEndpointId);
171*4d7e907cSAndroid Build Coastguard Worker 
172*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
173*4d7e907cSAndroid Build Coastguard Worker }
174*4d7e907cSAndroid Build Coastguard Worker 
onHostEndpointDisconnected(char16_t in_hostEndpointId)175*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) {
176*4d7e907cSAndroid Build Coastguard Worker     if (mConnectedHostEndpoints.count(in_hostEndpointId) > 0) {
177*4d7e907cSAndroid Build Coastguard Worker         mConnectedHostEndpoints.erase(in_hostEndpointId);
178*4d7e907cSAndroid Build Coastguard Worker     }
179*4d7e907cSAndroid Build Coastguard Worker 
180*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
181*4d7e907cSAndroid Build Coastguard Worker }
182*4d7e907cSAndroid Build Coastguard Worker 
sendMessageDeliveryStatusToHub(int32_t,const MessageDeliveryStatus &)183*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::sendMessageDeliveryStatusToHub(
184*4d7e907cSAndroid Build Coastguard Worker         int32_t /* in_contextHubId */,
185*4d7e907cSAndroid Build Coastguard Worker         const MessageDeliveryStatus& /* in_messageDeliveryStatus */) {
186*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
187*4d7e907cSAndroid Build Coastguard Worker }
188*4d7e907cSAndroid Build Coastguard Worker 
getHubs(std::vector<HubInfo> * _aidl_return)189*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::getHubs(std::vector<HubInfo>* _aidl_return) {
190*4d7e907cSAndroid Build Coastguard Worker     if (_aidl_return == nullptr) {
191*4d7e907cSAndroid Build Coastguard Worker         return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
192*4d7e907cSAndroid Build Coastguard Worker     }
193*4d7e907cSAndroid Build Coastguard Worker 
194*4d7e907cSAndroid Build Coastguard Worker     ContextHubInfo hub = {};
195*4d7e907cSAndroid Build Coastguard Worker     hub.name = "Mock Context Hub";
196*4d7e907cSAndroid Build Coastguard Worker     hub.vendor = "AOSP";
197*4d7e907cSAndroid Build Coastguard Worker     hub.toolchain = "n/a";
198*4d7e907cSAndroid Build Coastguard Worker     hub.id = kMockHubId;
199*4d7e907cSAndroid Build Coastguard Worker     hub.peakMips = 1;
200*4d7e907cSAndroid Build Coastguard Worker     hub.maxSupportedMessageLengthBytes = 4096;
201*4d7e907cSAndroid Build Coastguard Worker     hub.chrePlatformId = UINT64_C(0x476f6f6754000000);
202*4d7e907cSAndroid Build Coastguard Worker     hub.chreApiMajorVersion = 1;
203*4d7e907cSAndroid Build Coastguard Worker     hub.chreApiMinorVersion = 6;
204*4d7e907cSAndroid Build Coastguard Worker     hub.supportsReliableMessages = false;
205*4d7e907cSAndroid Build Coastguard Worker 
206*4d7e907cSAndroid Build Coastguard Worker     HubInfo hubInfo1 = {};
207*4d7e907cSAndroid Build Coastguard Worker     hubInfo1.hubId = hub.chrePlatformId;
208*4d7e907cSAndroid Build Coastguard Worker     hubInfo1.hubDetails = HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::contextHubInfo>(hub);
209*4d7e907cSAndroid Build Coastguard Worker 
210*4d7e907cSAndroid Build Coastguard Worker     VendorHubInfo vendorHub = {};
211*4d7e907cSAndroid Build Coastguard Worker     vendorHub.name = "Mock Vendor Hub";
212*4d7e907cSAndroid Build Coastguard Worker     vendorHub.version = 42;
213*4d7e907cSAndroid Build Coastguard Worker 
214*4d7e907cSAndroid Build Coastguard Worker     HubInfo hubInfo2 = {};
215*4d7e907cSAndroid Build Coastguard Worker     hubInfo2.hubId = kMockVendorHubId;
216*4d7e907cSAndroid Build Coastguard Worker     hubInfo2.hubDetails =
217*4d7e907cSAndroid Build Coastguard Worker             HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::vendorHubInfo>(vendorHub);
218*4d7e907cSAndroid Build Coastguard Worker 
219*4d7e907cSAndroid Build Coastguard Worker     VendorHubInfo vendorHub2 = {};
220*4d7e907cSAndroid Build Coastguard Worker     vendorHub2.name = "Mock Vendor Hub 2";
221*4d7e907cSAndroid Build Coastguard Worker     vendorHub2.version = 24;
222*4d7e907cSAndroid Build Coastguard Worker 
223*4d7e907cSAndroid Build Coastguard Worker     HubInfo hubInfo3 = {};
224*4d7e907cSAndroid Build Coastguard Worker     hubInfo3.hubId = kMockVendorHub2Id;
225*4d7e907cSAndroid Build Coastguard Worker     hubInfo3.hubDetails =
226*4d7e907cSAndroid Build Coastguard Worker             HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::vendorHubInfo>(vendorHub2);
227*4d7e907cSAndroid Build Coastguard Worker 
228*4d7e907cSAndroid Build Coastguard Worker     _aidl_return->push_back(hubInfo1);
229*4d7e907cSAndroid Build Coastguard Worker     _aidl_return->push_back(hubInfo2);
230*4d7e907cSAndroid Build Coastguard Worker     _aidl_return->push_back(hubInfo3);
231*4d7e907cSAndroid Build Coastguard Worker 
232*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
233*4d7e907cSAndroid Build Coastguard Worker };
234*4d7e907cSAndroid Build Coastguard Worker 
getEndpoints(std::vector<EndpointInfo> * _aidl_return)235*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::getEndpoints(std::vector<EndpointInfo>* _aidl_return) {
236*4d7e907cSAndroid Build Coastguard Worker     if (_aidl_return == nullptr) {
237*4d7e907cSAndroid Build Coastguard Worker         return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
238*4d7e907cSAndroid Build Coastguard Worker     }
239*4d7e907cSAndroid Build Coastguard Worker 
240*4d7e907cSAndroid Build Coastguard Worker     Service echoService;
241*4d7e907cSAndroid Build Coastguard Worker     echoService.format = Service::RpcFormat::CUSTOM;
242*4d7e907cSAndroid Build Coastguard Worker     echoService.serviceDescriptor = "ECHO";
243*4d7e907cSAndroid Build Coastguard Worker     echoService.majorVersion = 1;
244*4d7e907cSAndroid Build Coastguard Worker     echoService.minorVersion = 0;
245*4d7e907cSAndroid Build Coastguard Worker 
246*4d7e907cSAndroid Build Coastguard Worker     for (const EndpointInfo& endpoint : kMockEndpointInfos) {
247*4d7e907cSAndroid Build Coastguard Worker         EndpointInfo endpointWithService(endpoint);
248*4d7e907cSAndroid Build Coastguard Worker         endpointWithService.services.push_back(echoService);
249*4d7e907cSAndroid Build Coastguard Worker         _aidl_return->push_back(std::move(endpointWithService));
250*4d7e907cSAndroid Build Coastguard Worker     }
251*4d7e907cSAndroid Build Coastguard Worker 
252*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
253*4d7e907cSAndroid Build Coastguard Worker };
254*4d7e907cSAndroid Build Coastguard Worker 
registerEndpoint(const EndpointInfo & in_endpoint)255*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::registerEndpoint(const EndpointInfo& in_endpoint) {
256*4d7e907cSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mEndpointMutex);
257*4d7e907cSAndroid Build Coastguard Worker 
258*4d7e907cSAndroid Build Coastguard Worker     for (const EndpointInfo& endpoint : mEndpoints) {
259*4d7e907cSAndroid Build Coastguard Worker         if ((endpoint.id.id == in_endpoint.id.id && endpoint.id.hubId == in_endpoint.id.hubId) ||
260*4d7e907cSAndroid Build Coastguard Worker             endpoint.name == in_endpoint.name) {
261*4d7e907cSAndroid Build Coastguard Worker             return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
262*4d7e907cSAndroid Build Coastguard Worker         }
263*4d7e907cSAndroid Build Coastguard Worker     }
264*4d7e907cSAndroid Build Coastguard Worker     mEndpoints.push_back(in_endpoint);
265*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
266*4d7e907cSAndroid Build Coastguard Worker };
267*4d7e907cSAndroid Build Coastguard Worker 
unregisterEndpoint(const EndpointInfo & in_endpoint)268*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::unregisterEndpoint(const EndpointInfo& in_endpoint) {
269*4d7e907cSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mEndpointMutex);
270*4d7e907cSAndroid Build Coastguard Worker 
271*4d7e907cSAndroid Build Coastguard Worker     for (auto it = mEndpoints.begin(); it != mEndpoints.end(); ++it) {
272*4d7e907cSAndroid Build Coastguard Worker         if (it->id.id == in_endpoint.id.id && it->id.hubId == in_endpoint.id.hubId) {
273*4d7e907cSAndroid Build Coastguard Worker             mEndpoints.erase(it);
274*4d7e907cSAndroid Build Coastguard Worker             return ScopedAStatus::ok();
275*4d7e907cSAndroid Build Coastguard Worker         }
276*4d7e907cSAndroid Build Coastguard Worker     }
277*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
278*4d7e907cSAndroid Build Coastguard Worker };
279*4d7e907cSAndroid Build Coastguard Worker 
registerEndpointCallback(const std::shared_ptr<IEndpointCallback> & in_callback)280*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::registerEndpointCallback(
281*4d7e907cSAndroid Build Coastguard Worker         const std::shared_ptr<IEndpointCallback>& in_callback) {
282*4d7e907cSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mEndpointMutex);
283*4d7e907cSAndroid Build Coastguard Worker 
284*4d7e907cSAndroid Build Coastguard Worker     mEndpointCallback = in_callback;
285*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
286*4d7e907cSAndroid Build Coastguard Worker };
287*4d7e907cSAndroid Build Coastguard Worker 
requestSessionIdRange(int32_t in_size,std::vector<int32_t> * _aidl_return)288*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::requestSessionIdRange(int32_t in_size,
289*4d7e907cSAndroid Build Coastguard Worker                                                 std::vector<int32_t>* _aidl_return) {
290*4d7e907cSAndroid Build Coastguard Worker     constexpr int32_t kMaxSize = 1024;
291*4d7e907cSAndroid Build Coastguard Worker     if (in_size > kMaxSize || _aidl_return == nullptr) {
292*4d7e907cSAndroid Build Coastguard Worker         return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
293*4d7e907cSAndroid Build Coastguard Worker     }
294*4d7e907cSAndroid Build Coastguard Worker 
295*4d7e907cSAndroid Build Coastguard Worker     {
296*4d7e907cSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lock(mEndpointMutex);
297*4d7e907cSAndroid Build Coastguard Worker         mMaxValidSessionId = in_size;
298*4d7e907cSAndroid Build Coastguard Worker     }
299*4d7e907cSAndroid Build Coastguard Worker 
300*4d7e907cSAndroid Build Coastguard Worker     _aidl_return->push_back(0);
301*4d7e907cSAndroid Build Coastguard Worker     _aidl_return->push_back(in_size);
302*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
303*4d7e907cSAndroid Build Coastguard Worker };
304*4d7e907cSAndroid Build Coastguard Worker 
openEndpointSession(int32_t in_sessionId,const EndpointId & in_destination,const EndpointId & in_initiator,const std::optional<std::string> & in_serviceDescriptor)305*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::openEndpointSession(
306*4d7e907cSAndroid Build Coastguard Worker         int32_t in_sessionId, const EndpointId& in_destination, const EndpointId& in_initiator,
307*4d7e907cSAndroid Build Coastguard Worker         const std::optional<std::string>& in_serviceDescriptor) {
308*4d7e907cSAndroid Build Coastguard Worker     // We are not calling onCloseEndpointSession on failure because the remote endpoints (our
309*4d7e907cSAndroid Build Coastguard Worker     // mock endpoints) always accept the session.
310*4d7e907cSAndroid Build Coastguard Worker 
311*4d7e907cSAndroid Build Coastguard Worker     std::shared_ptr<IEndpointCallback> callback = nullptr;
312*4d7e907cSAndroid Build Coastguard Worker     {
313*4d7e907cSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> lock(mEndpointMutex);
314*4d7e907cSAndroid Build Coastguard Worker         if (in_sessionId > mMaxValidSessionId) {
315*4d7e907cSAndroid Build Coastguard Worker             ALOGE("openEndpointSession: session ID %" PRId32 " is invalid", in_sessionId);
316*4d7e907cSAndroid Build Coastguard Worker             return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
317*4d7e907cSAndroid Build Coastguard Worker         }
318*4d7e907cSAndroid Build Coastguard Worker 
319*4d7e907cSAndroid Build Coastguard Worker         for (const EndpointSession& session : mEndpointSessions) {
320*4d7e907cSAndroid Build Coastguard Worker             bool sessionAlreadyExists =
321*4d7e907cSAndroid Build Coastguard Worker                     (session.initiator == in_destination && session.peer == in_initiator) ||
322*4d7e907cSAndroid Build Coastguard Worker                     (session.peer == in_destination && session.initiator == in_initiator);
323*4d7e907cSAndroid Build Coastguard Worker             if (sessionAlreadyExists) {
324*4d7e907cSAndroid Build Coastguard Worker                 ALOGD("openEndpointSession: session ID %" PRId32 " already exists", in_sessionId);
325*4d7e907cSAndroid Build Coastguard Worker                 return (session.sessionId == in_sessionId &&
326*4d7e907cSAndroid Build Coastguard Worker                         session.serviceDescriptor == in_serviceDescriptor)
327*4d7e907cSAndroid Build Coastguard Worker                                ? ScopedAStatus::ok()
328*4d7e907cSAndroid Build Coastguard Worker                                : ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
329*4d7e907cSAndroid Build Coastguard Worker             } else if (session.sessionId == in_sessionId) {
330*4d7e907cSAndroid Build Coastguard Worker                 ALOGE("openEndpointSession: session ID %" PRId32 " is invalid: endpoint mismatch",
331*4d7e907cSAndroid Build Coastguard Worker                       in_sessionId);
332*4d7e907cSAndroid Build Coastguard Worker                 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
333*4d7e907cSAndroid Build Coastguard Worker             }
334*4d7e907cSAndroid Build Coastguard Worker         }
335*4d7e907cSAndroid Build Coastguard Worker 
336*4d7e907cSAndroid Build Coastguard Worker         // Verify the initiator and destination are valid endpoints
337*4d7e907cSAndroid Build Coastguard Worker         bool initiatorIsValid = findEndpoint(in_initiator, mEndpoints.begin(), mEndpoints.end());
338*4d7e907cSAndroid Build Coastguard Worker         if (!initiatorIsValid) {
339*4d7e907cSAndroid Build Coastguard Worker             ALOGE("openEndpointSession: initiator %" PRIu64 ":%" PRIu64 " is invalid",
340*4d7e907cSAndroid Build Coastguard Worker                   in_initiator.id, in_initiator.hubId);
341*4d7e907cSAndroid Build Coastguard Worker             return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
342*4d7e907cSAndroid Build Coastguard Worker         }
343*4d7e907cSAndroid Build Coastguard Worker         bool destinationIsValid = findEndpoint(in_destination, &kMockEndpointInfos[0],
344*4d7e907cSAndroid Build Coastguard Worker                                                &kMockEndpointInfos[kMockEndpointCount]);
345*4d7e907cSAndroid Build Coastguard Worker         if (!destinationIsValid) {
346*4d7e907cSAndroid Build Coastguard Worker             ALOGE("openEndpointSession: destination %" PRIu64 ":%" PRIu64 " is invalid",
347*4d7e907cSAndroid Build Coastguard Worker                   in_destination.id, in_destination.hubId);
348*4d7e907cSAndroid Build Coastguard Worker             return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
349*4d7e907cSAndroid Build Coastguard Worker         }
350*4d7e907cSAndroid Build Coastguard Worker 
351*4d7e907cSAndroid Build Coastguard Worker         mEndpointSessions.push_back({
352*4d7e907cSAndroid Build Coastguard Worker                 .sessionId = in_sessionId,
353*4d7e907cSAndroid Build Coastguard Worker                 .initiator = in_initiator,
354*4d7e907cSAndroid Build Coastguard Worker                 .peer = in_destination,
355*4d7e907cSAndroid Build Coastguard Worker                 .serviceDescriptor = in_serviceDescriptor,
356*4d7e907cSAndroid Build Coastguard Worker         });
357*4d7e907cSAndroid Build Coastguard Worker 
358*4d7e907cSAndroid Build Coastguard Worker         if (mEndpointCallback != nullptr) {
359*4d7e907cSAndroid Build Coastguard Worker             callback = mEndpointCallback;
360*4d7e907cSAndroid Build Coastguard Worker         }
361*4d7e907cSAndroid Build Coastguard Worker     }
362*4d7e907cSAndroid Build Coastguard Worker 
363*4d7e907cSAndroid Build Coastguard Worker     if (callback != nullptr) {
364*4d7e907cSAndroid Build Coastguard Worker         callback->onEndpointSessionOpenComplete(in_sessionId);
365*4d7e907cSAndroid Build Coastguard Worker     }
366*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
367*4d7e907cSAndroid Build Coastguard Worker };
368*4d7e907cSAndroid Build Coastguard Worker 
sendMessageToEndpoint(int32_t in_sessionId,const Message & in_msg)369*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::sendMessageToEndpoint(int32_t in_sessionId, const Message& in_msg) {
370*4d7e907cSAndroid Build Coastguard Worker     bool foundSession = false;
371*4d7e907cSAndroid Build Coastguard Worker     std::shared_ptr<IEndpointCallback> callback = nullptr;
372*4d7e907cSAndroid Build Coastguard Worker     {
373*4d7e907cSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> lock(mEndpointMutex);
374*4d7e907cSAndroid Build Coastguard Worker 
375*4d7e907cSAndroid Build Coastguard Worker         for (const EndpointSession& session : mEndpointSessions) {
376*4d7e907cSAndroid Build Coastguard Worker             if (session.sessionId == in_sessionId) {
377*4d7e907cSAndroid Build Coastguard Worker                 foundSession = true;
378*4d7e907cSAndroid Build Coastguard Worker                 break;
379*4d7e907cSAndroid Build Coastguard Worker             }
380*4d7e907cSAndroid Build Coastguard Worker         }
381*4d7e907cSAndroid Build Coastguard Worker 
382*4d7e907cSAndroid Build Coastguard Worker         if (mEndpointCallback != nullptr) {
383*4d7e907cSAndroid Build Coastguard Worker             callback = mEndpointCallback;
384*4d7e907cSAndroid Build Coastguard Worker         }
385*4d7e907cSAndroid Build Coastguard Worker     }
386*4d7e907cSAndroid Build Coastguard Worker 
387*4d7e907cSAndroid Build Coastguard Worker     if (!foundSession) {
388*4d7e907cSAndroid Build Coastguard Worker         ALOGE("sendMessageToEndpoint: session ID %" PRId32 " is invalid", in_sessionId);
389*4d7e907cSAndroid Build Coastguard Worker         return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
390*4d7e907cSAndroid Build Coastguard Worker     }
391*4d7e907cSAndroid Build Coastguard Worker 
392*4d7e907cSAndroid Build Coastguard Worker     if (callback != nullptr) {
393*4d7e907cSAndroid Build Coastguard Worker         if (in_msg.flags & Message::FLAG_REQUIRES_DELIVERY_STATUS) {
394*4d7e907cSAndroid Build Coastguard Worker             MessageDeliveryStatus msgStatus = {};
395*4d7e907cSAndroid Build Coastguard Worker             msgStatus.messageSequenceNumber = in_msg.sequenceNumber;
396*4d7e907cSAndroid Build Coastguard Worker             msgStatus.errorCode = ErrorCode::OK;
397*4d7e907cSAndroid Build Coastguard Worker             callback->onMessageDeliveryStatusReceived(in_sessionId, msgStatus);
398*4d7e907cSAndroid Build Coastguard Worker         }
399*4d7e907cSAndroid Build Coastguard Worker 
400*4d7e907cSAndroid Build Coastguard Worker         // Echo the message back
401*4d7e907cSAndroid Build Coastguard Worker         callback->onMessageReceived(in_sessionId, in_msg);
402*4d7e907cSAndroid Build Coastguard Worker     }
403*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
404*4d7e907cSAndroid Build Coastguard Worker };
405*4d7e907cSAndroid Build Coastguard Worker 
sendMessageDeliveryStatusToEndpoint(int32_t,const MessageDeliveryStatus &)406*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::sendMessageDeliveryStatusToEndpoint(
407*4d7e907cSAndroid Build Coastguard Worker         int32_t /* in_sessionId */, const MessageDeliveryStatus& /* in_msgStatus */) {
408*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
409*4d7e907cSAndroid Build Coastguard Worker };
410*4d7e907cSAndroid Build Coastguard Worker 
closeEndpointSession(int32_t in_sessionId,Reason)411*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::closeEndpointSession(int32_t in_sessionId, Reason /* in_reason */) {
412*4d7e907cSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mEndpointMutex);
413*4d7e907cSAndroid Build Coastguard Worker 
414*4d7e907cSAndroid Build Coastguard Worker     for (auto it = mEndpointSessions.begin(); it != mEndpointSessions.end(); ++it) {
415*4d7e907cSAndroid Build Coastguard Worker         if (it->sessionId == in_sessionId) {
416*4d7e907cSAndroid Build Coastguard Worker             mEndpointSessions.erase(it);
417*4d7e907cSAndroid Build Coastguard Worker             return ScopedAStatus::ok();
418*4d7e907cSAndroid Build Coastguard Worker         }
419*4d7e907cSAndroid Build Coastguard Worker     }
420*4d7e907cSAndroid Build Coastguard Worker     ALOGE("closeEndpointSession: session ID %" PRId32 " is invalid", in_sessionId);
421*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
422*4d7e907cSAndroid Build Coastguard Worker };
423*4d7e907cSAndroid Build Coastguard Worker 
endpointSessionOpenComplete(int32_t)424*4d7e907cSAndroid Build Coastguard Worker ScopedAStatus ContextHub::endpointSessionOpenComplete(int32_t /* in_sessionId */) {
425*4d7e907cSAndroid Build Coastguard Worker     return ScopedAStatus::ok();
426*4d7e907cSAndroid Build Coastguard Worker };
427*4d7e907cSAndroid Build Coastguard Worker 
428*4d7e907cSAndroid Build Coastguard Worker }  // namespace aidl::android::hardware::contexthub
429