blob: 80c9575026a2d458efd57c1202fd337b7c4acc08 [file] [log] [blame]
Arthur Ishiguroa257b782021-08-04 10:40:29 -07001/*
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#include "contexthub-impl/ContextHub.h"
Matthew Sedam0ec290c2024-12-11 11:18:15 -080018#include "aidl/android/hardware/contexthub/IContextHubCallback.h"
Arthur Ishiguroa257b782021-08-04 10:40:29 -070019
Matthew Sedam92c2bd82024-11-11 19:52:30 +000020#ifndef LOG_TAG
21#define LOG_TAG "CHRE"
22#endif
23
24#include <inttypes.h>
25#include <log/log.h>
Matthew Sedam0ec290c2024-12-11 11:18:15 -080026#include <optional>
27#include <thread>
Arthur Ishiguroa257b782021-08-04 10:40:29 -070028
Arthur Ishiguro070f47d2022-01-06 22:42:10 +000029using ::ndk::ScopedAStatus;
30
Matthew Sedam92c2bd82024-11-11 19:52:30 +000031namespace aidl::android::hardware::contexthub {
32
33namespace {
34
35constexpr uint64_t kMockVendorHubId = 0x1234567812345678;
36constexpr uint64_t kMockVendorHub2Id = 0x0EADBEEFDEADBEEF;
37
38// Mock endpoints for the default implementation.
39// These endpoints just echo back any messages sent to them.
40constexpr size_t kMockEndpointCount = 4;
41const EndpointInfo kMockEndpointInfos[kMockEndpointCount] = {
42 {
43 .id = {.hubId = kMockVendorHubId, .id = UINT64_C(0x1)},
44 .type = EndpointInfo::EndpointType::GENERIC,
45 .name = "Mock Endpoint 1",
46 .version = 1,
47 },
48 {
49 .id = {.hubId = kMockVendorHubId, .id = UINT64_C(0x2)},
50 .type = EndpointInfo::EndpointType::GENERIC,
51 .name = "Mock Endpoint 2",
52 .version = 2,
53 },
54 {
55 .id = {.hubId = kMockVendorHub2Id, .id = UINT64_C(0x1)},
56 .type = EndpointInfo::EndpointType::GENERIC,
57 .name = "Mock Endpoint 3",
58 .version = 1,
59 },
60 {
61 .id = {.hubId = kMockVendorHub2Id, .id = UINT64_C(0x2)},
62 .type = EndpointInfo::EndpointType::GENERIC,
63 .name = "Mock Endpoint 4",
64 .version = 2,
65 },
66};
67
Matthew Sedam0ec290c2024-12-11 11:18:15 -080068//! Mutex used to ensure callbacks are called after the initial function returns.
69std::mutex gCallbackMutex;
70
Matthew Sedam92c2bd82024-11-11 19:52:30 +000071} // anonymous namespace
72
Arthur Ishiguro070f47d2022-01-06 22:42:10 +000073ScopedAStatus ContextHub::getContextHubs(std::vector<ContextHubInfo>* out_contextHubInfos) {
Arthur Ishiguro94e1aa22021-10-26 17:25:19 +000074 ContextHubInfo hub = {};
75 hub.name = "Mock Context Hub";
76 hub.vendor = "AOSP";
77 hub.toolchain = "n/a";
78 hub.id = kMockHubId;
79 hub.peakMips = 1;
80 hub.maxSupportedMessageLengthBytes = 4096;
81 hub.chrePlatformId = UINT64_C(0x476f6f6754000000);
82 hub.chreApiMajorVersion = 1;
83 hub.chreApiMinorVersion = 6;
Matthew Sedamadfd5572023-11-21 05:53:00 -080084 hub.supportsReliableMessages = false;
Arthur Ishiguroa257b782021-08-04 10:40:29 -070085
Arthur Ishiguro94e1aa22021-10-26 17:25:19 +000086 out_contextHubInfos->push_back(hub);
87
Matthew Sedamadfd5572023-11-21 05:53:00 -080088 return ScopedAStatus::ok();
Arthur Ishiguroa257b782021-08-04 10:40:29 -070089}
90
Arthur Ishiguro94e1aa22021-10-26 17:25:19 +000091// We don't expose any nanoapps for the default impl, therefore all nanoapp-related APIs fail.
Arthur Ishiguro070f47d2022-01-06 22:42:10 +000092ScopedAStatus ContextHub::loadNanoapp(int32_t /* in_contextHubId */,
93 const NanoappBinary& /* in_appBinary */,
94 int32_t /* in_transactionId */) {
95 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
96}
97
98ScopedAStatus ContextHub::unloadNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */,
99 int32_t /* in_transactionId */) {
100 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
101}
102
103ScopedAStatus ContextHub::disableNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */,
104 int32_t /* in_transactionId */) {
105 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
106}
107
108ScopedAStatus ContextHub::enableNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */,
109 int32_t /* in_transactionId */) {
110 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
111}
112
113ScopedAStatus ContextHub::onSettingChanged(Setting /* in_setting */, bool /*in_enabled */) {
Matthew Sedamadfd5572023-11-21 05:53:00 -0800114 return ScopedAStatus::ok();
Arthur Ishiguroa257b782021-08-04 10:40:29 -0700115}
116
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000117ScopedAStatus ContextHub::queryNanoapps(int32_t in_contextHubId) {
Arthur Ishiguro94e1aa22021-10-26 17:25:19 +0000118 if (in_contextHubId == kMockHubId && mCallback != nullptr) {
119 std::vector<NanoappInfo> nanoapps;
120 mCallback->handleNanoappInfo(nanoapps);
Matthew Sedamadfd5572023-11-21 05:53:00 -0800121 return ScopedAStatus::ok();
Arthur Ishiguro94e1aa22021-10-26 17:25:19 +0000122 } else {
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000123 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
Arthur Ishiguro94e1aa22021-10-26 17:25:19 +0000124 }
Arthur Ishiguroa257b782021-08-04 10:40:29 -0700125}
126
Matthew Sedamd70f84d2023-03-06 18:34:24 +0000127ScopedAStatus ContextHub::getPreloadedNanoappIds(int32_t /* in_contextHubId */,
128 std::vector<int64_t>* out_preloadedNanoappIds) {
Arthur Ishigurofd5e65c2022-11-08 16:49:47 +0000129 if (out_preloadedNanoappIds == nullptr) {
130 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
131 }
132
133 for (uint64_t i = 0; i < 10; ++i) {
134 out_preloadedNanoappIds->push_back(i);
135 }
Matthew Sedamadfd5572023-11-21 05:53:00 -0800136 return ScopedAStatus::ok();
Arthur Ishigurofd5e65c2022-11-08 16:49:47 +0000137}
138
Anthony Stange7fba1002023-03-02 21:45:20 +0000139ScopedAStatus ContextHub::onNanSessionStateChanged(const NanSessionStateUpdate& /*in_update*/) {
Matthew Sedamadfd5572023-11-21 05:53:00 -0800140 return ScopedAStatus::ok();
Anthony Stange7344af92022-12-22 14:21:31 +0000141}
142
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000143ScopedAStatus ContextHub::registerCallback(int32_t in_contextHubId,
144 const std::shared_ptr<IContextHubCallback>& in_cb) {
Arthur Ishiguro94e1aa22021-10-26 17:25:19 +0000145 if (in_contextHubId == kMockHubId) {
146 mCallback = in_cb;
Matthew Sedamadfd5572023-11-21 05:53:00 -0800147 return ScopedAStatus::ok();
Arthur Ishiguro94e1aa22021-10-26 17:25:19 +0000148 } else {
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000149 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
Arthur Ishiguro94e1aa22021-10-26 17:25:19 +0000150 }
Arthur Ishiguroa257b782021-08-04 10:40:29 -0700151}
152
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000153ScopedAStatus ContextHub::sendMessageToHub(int32_t in_contextHubId,
154 const ContextHubMessage& /* in_message */) {
Arthur Ishiguro94e1aa22021-10-26 17:25:19 +0000155 if (in_contextHubId == kMockHubId) {
156 // Return true here to indicate that the HAL has accepted the message.
157 // Successful delivery of the message to a nanoapp should be handled at
158 // a higher level protocol.
Matthew Sedamadfd5572023-11-21 05:53:00 -0800159 return ScopedAStatus::ok();
Arthur Ishiguro94e1aa22021-10-26 17:25:19 +0000160 } else {
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000161 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
Arthur Ishiguro94e1aa22021-10-26 17:25:19 +0000162 }
Arthur Ishiguroa257b782021-08-04 10:40:29 -0700163}
164
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000165ScopedAStatus ContextHub::setTestMode(bool enable) {
166 if (enable) {
167 std::unique_lock<std::mutex> lock(mEndpointMutex);
168 mEndpoints.clear();
169 mEndpointSessions.clear();
170 mEndpointCallback = nullptr;
171 }
Matthew Sedamadfd5572023-11-21 05:53:00 -0800172 return ScopedAStatus::ok();
Matthew Sedamc8ce4d52023-01-09 20:18:21 +0000173}
174
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000175ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) {
Arthur Ishiguro065a9a52021-11-19 00:24:45 +0000176 mConnectedHostEndpoints.insert(in_info.hostEndpointId);
177
Matthew Sedamadfd5572023-11-21 05:53:00 -0800178 return ScopedAStatus::ok();
Arthur Ishiguro065a9a52021-11-19 00:24:45 +0000179}
180
Arthur Ishiguro070f47d2022-01-06 22:42:10 +0000181ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) {
Arthur Ishiguro065a9a52021-11-19 00:24:45 +0000182 if (mConnectedHostEndpoints.count(in_hostEndpointId) > 0) {
183 mConnectedHostEndpoints.erase(in_hostEndpointId);
Arthur Ishiguro065a9a52021-11-19 00:24:45 +0000184 }
Arthur Ishigurobb1d8bf2022-07-06 15:29:13 +0000185
Matthew Sedamadfd5572023-11-21 05:53:00 -0800186 return ScopedAStatus::ok();
Arthur Ishiguro065a9a52021-11-19 00:24:45 +0000187}
188
Matthew Sedamadfd5572023-11-21 05:53:00 -0800189ScopedAStatus ContextHub::sendMessageDeliveryStatusToHub(
190 int32_t /* in_contextHubId */,
191 const MessageDeliveryStatus& /* in_messageDeliveryStatus */) {
192 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
193}
194
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700195ScopedAStatus ContextHub::getHubs(std::vector<HubInfo>* _aidl_return) {
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000196 if (_aidl_return == nullptr) {
197 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
198 }
199
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700200 ContextHubInfo hub = {};
201 hub.name = "Mock Context Hub";
202 hub.vendor = "AOSP";
203 hub.toolchain = "n/a";
204 hub.id = kMockHubId;
205 hub.peakMips = 1;
206 hub.maxSupportedMessageLengthBytes = 4096;
207 hub.chrePlatformId = UINT64_C(0x476f6f6754000000);
208 hub.chreApiMajorVersion = 1;
209 hub.chreApiMinorVersion = 6;
210 hub.supportsReliableMessages = false;
211
212 HubInfo hubInfo1 = {};
213 hubInfo1.hubId = hub.chrePlatformId;
214 hubInfo1.hubDetails = HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::contextHubInfo>(hub);
215
216 VendorHubInfo vendorHub = {};
217 vendorHub.name = "Mock Vendor Hub";
218 vendorHub.version = 42;
219
220 HubInfo hubInfo2 = {};
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000221 hubInfo2.hubId = kMockVendorHubId;
Yifei Zhang3c265802024-11-04 15:00:05 -0800222 hubInfo2.hubDetails =
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700223 HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::vendorHubInfo>(vendorHub);
224
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000225 VendorHubInfo vendorHub2 = {};
226 vendorHub2.name = "Mock Vendor Hub 2";
227 vendorHub2.version = 24;
228
229 HubInfo hubInfo3 = {};
230 hubInfo3.hubId = kMockVendorHub2Id;
231 hubInfo3.hubDetails =
232 HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::vendorHubInfo>(vendorHub2);
233
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700234 _aidl_return->push_back(hubInfo1);
235 _aidl_return->push_back(hubInfo2);
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000236 _aidl_return->push_back(hubInfo3);
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700237
238 return ScopedAStatus::ok();
239};
240
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000241ScopedAStatus ContextHub::getEndpoints(std::vector<EndpointInfo>* _aidl_return) {
242 if (_aidl_return == nullptr) {
243 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
244 }
245
246 Service echoService;
247 echoService.format = Service::RpcFormat::CUSTOM;
Arthur Ishiguro39087712024-12-13 09:48:13 -0800248 echoService.serviceDescriptor = "android.hardware.contexthub.test.EchoService";
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000249 echoService.majorVersion = 1;
250 echoService.minorVersion = 0;
251
252 for (const EndpointInfo& endpoint : kMockEndpointInfos) {
253 EndpointInfo endpointWithService(endpoint);
254 endpointWithService.services.push_back(echoService);
255 _aidl_return->push_back(std::move(endpointWithService));
256 }
257
258 return ScopedAStatus::ok();
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700259};
260
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000261ScopedAStatus ContextHub::registerEndpoint(const EndpointInfo& in_endpoint) {
262 std::unique_lock<std::mutex> lock(mEndpointMutex);
263
264 for (const EndpointInfo& endpoint : mEndpoints) {
265 if ((endpoint.id.id == in_endpoint.id.id && endpoint.id.hubId == in_endpoint.id.hubId) ||
266 endpoint.name == in_endpoint.name) {
267 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
268 }
269 }
270 mEndpoints.push_back(in_endpoint);
271 return ScopedAStatus::ok();
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700272};
273
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000274ScopedAStatus ContextHub::unregisterEndpoint(const EndpointInfo& in_endpoint) {
275 std::unique_lock<std::mutex> lock(mEndpointMutex);
276
277 for (auto it = mEndpoints.begin(); it != mEndpoints.end(); ++it) {
278 if (it->id.id == in_endpoint.id.id && it->id.hubId == in_endpoint.id.hubId) {
279 mEndpoints.erase(it);
280 return ScopedAStatus::ok();
281 }
282 }
283 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700284};
285
286ScopedAStatus ContextHub::registerEndpointCallback(
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000287 const std::shared_ptr<IEndpointCallback>& in_callback) {
288 std::unique_lock<std::mutex> lock(mEndpointMutex);
289
290 mEndpointCallback = in_callback;
291 return ScopedAStatus::ok();
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700292};
293
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000294ScopedAStatus ContextHub::requestSessionIdRange(int32_t in_size,
Yifei Zhangcef8f662024-12-06 16:03:26 -0800295 std::array<int32_t, 2>* _aidl_return) {
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000296 constexpr int32_t kMaxSize = 1024;
297 if (in_size > kMaxSize || _aidl_return == nullptr) {
298 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
299 }
300
301 {
302 std::lock_guard<std::mutex> lock(mEndpointMutex);
303 mMaxValidSessionId = in_size;
304 }
305
Matthew Sedam0ec290c2024-12-11 11:18:15 -0800306 (*_aidl_return)[0] = 0;
307 (*_aidl_return)[1] = in_size;
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000308 return ScopedAStatus::ok();
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700309};
310
311ScopedAStatus ContextHub::openEndpointSession(
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000312 int32_t in_sessionId, const EndpointId& in_destination, const EndpointId& in_initiator,
313 const std::optional<std::string>& in_serviceDescriptor) {
314 // We are not calling onCloseEndpointSession on failure because the remote endpoints (our
315 // mock endpoints) always accept the session.
316
Matthew Sedam0ec290c2024-12-11 11:18:15 -0800317 std::weak_ptr<IEndpointCallback> callback;
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000318 {
319 std::unique_lock<std::mutex> lock(mEndpointMutex);
320 if (in_sessionId > mMaxValidSessionId) {
321 ALOGE("openEndpointSession: session ID %" PRId32 " is invalid", in_sessionId);
322 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
323 }
324
325 for (const EndpointSession& session : mEndpointSessions) {
326 bool sessionAlreadyExists =
327 (session.initiator == in_destination && session.peer == in_initiator) ||
328 (session.peer == in_destination && session.initiator == in_initiator);
329 if (sessionAlreadyExists) {
330 ALOGD("openEndpointSession: session ID %" PRId32 " already exists", in_sessionId);
331 return (session.sessionId == in_sessionId &&
332 session.serviceDescriptor == in_serviceDescriptor)
333 ? ScopedAStatus::ok()
334 : ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
335 } else if (session.sessionId == in_sessionId) {
336 ALOGE("openEndpointSession: session ID %" PRId32 " is invalid: endpoint mismatch",
337 in_sessionId);
338 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
339 }
340 }
341
342 // Verify the initiator and destination are valid endpoints
343 bool initiatorIsValid = findEndpoint(in_initiator, mEndpoints.begin(), mEndpoints.end());
344 if (!initiatorIsValid) {
345 ALOGE("openEndpointSession: initiator %" PRIu64 ":%" PRIu64 " is invalid",
346 in_initiator.id, in_initiator.hubId);
347 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
348 }
349 bool destinationIsValid = findEndpoint(in_destination, &kMockEndpointInfos[0],
350 &kMockEndpointInfos[kMockEndpointCount]);
351 if (!destinationIsValid) {
352 ALOGE("openEndpointSession: destination %" PRIu64 ":%" PRIu64 " is invalid",
353 in_destination.id, in_destination.hubId);
354 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
355 }
356
357 mEndpointSessions.push_back({
358 .sessionId = in_sessionId,
359 .initiator = in_initiator,
360 .peer = in_destination,
361 .serviceDescriptor = in_serviceDescriptor,
362 });
363
Matthew Sedam0ec290c2024-12-11 11:18:15 -0800364 if (mEndpointCallback == nullptr) {
365 return ScopedAStatus::ok();
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000366 }
Matthew Sedam0ec290c2024-12-11 11:18:15 -0800367 callback = mEndpointCallback;
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000368 }
369
Matthew Sedam0ec290c2024-12-11 11:18:15 -0800370 std::unique_lock<std::mutex> lock(gCallbackMutex);
371 std::thread{[callback, in_sessionId]() {
372 std::unique_lock<std::mutex> lock(gCallbackMutex);
373 if (auto cb = callback.lock(); cb != nullptr) {
374 cb->onEndpointSessionOpenComplete(in_sessionId);
375 }
376 }}.detach();
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000377 return ScopedAStatus::ok();
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700378};
379
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000380ScopedAStatus ContextHub::sendMessageToEndpoint(int32_t in_sessionId, const Message& in_msg) {
Matthew Sedam0ec290c2024-12-11 11:18:15 -0800381 std::weak_ptr<IEndpointCallback> callback;
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000382 {
383 std::unique_lock<std::mutex> lock(mEndpointMutex);
Matthew Sedam0ec290c2024-12-11 11:18:15 -0800384 bool foundSession = false;
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000385 for (const EndpointSession& session : mEndpointSessions) {
386 if (session.sessionId == in_sessionId) {
387 foundSession = true;
388 break;
389 }
390 }
391
Matthew Sedam0ec290c2024-12-11 11:18:15 -0800392 if (!foundSession) {
393 ALOGE("sendMessageToEndpoint: session ID %" PRId32 " is invalid", in_sessionId);
394 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000395 }
396
Matthew Sedam0ec290c2024-12-11 11:18:15 -0800397 if (mEndpointCallback == nullptr) {
398 return ScopedAStatus::ok();
399 }
400 callback = mEndpointCallback;
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000401 }
Matthew Sedam0ec290c2024-12-11 11:18:15 -0800402
403 std::unique_lock<std::mutex> lock(gCallbackMutex);
404 if ((in_msg.flags & Message::FLAG_REQUIRES_DELIVERY_STATUS) != 0) {
405 MessageDeliveryStatus msgStatus = {};
406 msgStatus.messageSequenceNumber = in_msg.sequenceNumber;
407 msgStatus.errorCode = ErrorCode::OK;
408
409 std::thread{[callback, in_sessionId, msgStatus]() {
410 std::unique_lock<std::mutex> lock(gCallbackMutex);
411 if (auto cb = callback.lock(); cb != nullptr) {
412 cb->onMessageDeliveryStatusReceived(in_sessionId, msgStatus);
413 }
414 }}.detach();
415 }
416
417 // Echo the message back
418 std::thread{[callback, in_sessionId, in_msg]() {
419 std::unique_lock<std::mutex> lock(gCallbackMutex);
420 if (auto cb = callback.lock(); cb != nullptr) {
421 cb->onMessageReceived(in_sessionId, in_msg);
422 }
423 }}.detach();
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000424 return ScopedAStatus::ok();
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700425};
426
427ScopedAStatus ContextHub::sendMessageDeliveryStatusToEndpoint(
428 int32_t /* in_sessionId */, const MessageDeliveryStatus& /* in_msgStatus */) {
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000429 return ScopedAStatus::ok();
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700430};
431
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000432ScopedAStatus ContextHub::closeEndpointSession(int32_t in_sessionId, Reason /* in_reason */) {
433 std::unique_lock<std::mutex> lock(mEndpointMutex);
434
435 for (auto it = mEndpointSessions.begin(); it != mEndpointSessions.end(); ++it) {
436 if (it->sessionId == in_sessionId) {
437 mEndpointSessions.erase(it);
438 return ScopedAStatus::ok();
439 }
440 }
441 ALOGE("closeEndpointSession: session ID %" PRId32 " is invalid", in_sessionId);
442 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700443};
444
445ScopedAStatus ContextHub::endpointSessionOpenComplete(int32_t /* in_sessionId */) {
Matthew Sedam92c2bd82024-11-11 19:52:30 +0000446 return ScopedAStatus::ok();
Yifei Zhang51eba2e2024-10-24 15:11:54 -0700447};
448
Matthew Sedamadfd5572023-11-21 05:53:00 -0800449} // namespace aidl::android::hardware::contexthub