1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker * Copyright (C) 2024 The Android Open Source Project
3*84e33947SAndroid Build Coastguard Worker *
4*84e33947SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*84e33947SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*84e33947SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*84e33947SAndroid Build Coastguard Worker *
8*84e33947SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*84e33947SAndroid Build Coastguard Worker *
10*84e33947SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*84e33947SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*84e33947SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*84e33947SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*84e33947SAndroid Build Coastguard Worker * limitations under the License.
15*84e33947SAndroid Build Coastguard Worker */
16*84e33947SAndroid Build Coastguard Worker
17*84e33947SAndroid Build Coastguard Worker #include <pw_allocator/allocator.h>
18*84e33947SAndroid Build Coastguard Worker #include <pw_allocator/capability.h>
19*84e33947SAndroid Build Coastguard Worker #include <pw_allocator/unique_ptr.h>
20*84e33947SAndroid Build Coastguard Worker #include <cstddef>
21*84e33947SAndroid Build Coastguard Worker #include <cstdint>
22*84e33947SAndroid Build Coastguard Worker #include <optional>
23*84e33947SAndroid Build Coastguard Worker #include <utility>
24*84e33947SAndroid Build Coastguard Worker
25*84e33947SAndroid Build Coastguard Worker #include "chre/util/dynamic_vector.h"
26*84e33947SAndroid Build Coastguard Worker #include "chre/util/system/message_common.h"
27*84e33947SAndroid Build Coastguard Worker #include "chre/util/system/message_router.h"
28*84e33947SAndroid Build Coastguard Worker #include "chre/util/system/message_router_callback_allocator.h"
29*84e33947SAndroid Build Coastguard Worker #include "chre_api/chre.h"
30*84e33947SAndroid Build Coastguard Worker #include "gtest/gtest.h"
31*84e33947SAndroid Build Coastguard Worker
32*84e33947SAndroid Build Coastguard Worker namespace chre::message {
33*84e33947SAndroid Build Coastguard Worker namespace {
34*84e33947SAndroid Build Coastguard Worker
35*84e33947SAndroid Build Coastguard Worker constexpr size_t kMaxMessageHubs = 3;
36*84e33947SAndroid Build Coastguard Worker constexpr size_t kMaxSessions = 10;
37*84e33947SAndroid Build Coastguard Worker constexpr size_t kMaxFreeCallbackRecords = kMaxSessions * 2;
38*84e33947SAndroid Build Coastguard Worker constexpr size_t kNumEndpoints = 3;
39*84e33947SAndroid Build Coastguard Worker
40*84e33947SAndroid Build Coastguard Worker const EndpointInfo kEndpointInfos[kNumEndpoints] = {
41*84e33947SAndroid Build Coastguard Worker EndpointInfo(/* id= */ 1, /* name= */ "endpoint1", /* version= */ 1,
42*84e33947SAndroid Build Coastguard Worker EndpointType::NANOAPP, CHRE_MESSAGE_PERMISSION_NONE),
43*84e33947SAndroid Build Coastguard Worker EndpointInfo(/* id= */ 2, /* name= */ "endpoint2", /* version= */ 10,
44*84e33947SAndroid Build Coastguard Worker EndpointType::HOST_NATIVE, CHRE_MESSAGE_PERMISSION_BLE),
45*84e33947SAndroid Build Coastguard Worker EndpointInfo(/* id= */ 3, /* name= */ "endpoint3", /* version= */ 100,
46*84e33947SAndroid Build Coastguard Worker EndpointType::GENERIC, CHRE_MESSAGE_PERMISSION_AUDIO)};
47*84e33947SAndroid Build Coastguard Worker
48*84e33947SAndroid Build Coastguard Worker class TestAllocator : public pw::Allocator {
49*84e33947SAndroid Build Coastguard Worker public:
50*84e33947SAndroid Build Coastguard Worker static constexpr Capabilities kCapabilities = 0;
51*84e33947SAndroid Build Coastguard Worker
TestAllocator()52*84e33947SAndroid Build Coastguard Worker TestAllocator() : pw::Allocator(kCapabilities) {}
53*84e33947SAndroid Build Coastguard Worker
DoAllocate(Layout layout)54*84e33947SAndroid Build Coastguard Worker virtual void *DoAllocate(Layout layout) override {
55*84e33947SAndroid Build Coastguard Worker if (layout.alignment() > alignof(std::max_align_t)) {
56*84e33947SAndroid Build Coastguard Worker void *ptr;
57*84e33947SAndroid Build Coastguard Worker return posix_memalign(&ptr, layout.alignment(), layout.size()) == 0
58*84e33947SAndroid Build Coastguard Worker ? ptr
59*84e33947SAndroid Build Coastguard Worker : nullptr;
60*84e33947SAndroid Build Coastguard Worker } else {
61*84e33947SAndroid Build Coastguard Worker return malloc(layout.size());
62*84e33947SAndroid Build Coastguard Worker }
63*84e33947SAndroid Build Coastguard Worker }
64*84e33947SAndroid Build Coastguard Worker
DoDeallocate(void * ptr)65*84e33947SAndroid Build Coastguard Worker virtual void DoDeallocate(void *ptr) override {
66*84e33947SAndroid Build Coastguard Worker free(ptr);
67*84e33947SAndroid Build Coastguard Worker }
68*84e33947SAndroid Build Coastguard Worker };
69*84e33947SAndroid Build Coastguard Worker
70*84e33947SAndroid Build Coastguard Worker class MessageRouterTest : public ::testing::Test {
71*84e33947SAndroid Build Coastguard Worker protected:
SetUp()72*84e33947SAndroid Build Coastguard Worker void SetUp() override {}
73*84e33947SAndroid Build Coastguard Worker
74*84e33947SAndroid Build Coastguard Worker TestAllocator mAllocator;
75*84e33947SAndroid Build Coastguard Worker };
76*84e33947SAndroid Build Coastguard Worker
77*84e33947SAndroid Build Coastguard Worker //! Base class for MessageHubCallbacks used in tests
78*84e33947SAndroid Build Coastguard Worker class MessageHubCallbackBase : public MessageRouter::MessageHubCallback {
79*84e33947SAndroid Build Coastguard Worker public:
forEachEndpoint(const pw::Function<bool (const EndpointInfo &)> & function)80*84e33947SAndroid Build Coastguard Worker void forEachEndpoint(
81*84e33947SAndroid Build Coastguard Worker const pw::Function<bool(const EndpointInfo &)> &function) override {
82*84e33947SAndroid Build Coastguard Worker for (const EndpointInfo &endpointInfo : kEndpointInfos) {
83*84e33947SAndroid Build Coastguard Worker if (function(endpointInfo)) {
84*84e33947SAndroid Build Coastguard Worker return;
85*84e33947SAndroid Build Coastguard Worker }
86*84e33947SAndroid Build Coastguard Worker }
87*84e33947SAndroid Build Coastguard Worker }
88*84e33947SAndroid Build Coastguard Worker
getEndpointInfo(EndpointId endpointId)89*84e33947SAndroid Build Coastguard Worker std::optional<EndpointInfo> getEndpointInfo(EndpointId endpointId) override {
90*84e33947SAndroid Build Coastguard Worker for (const EndpointInfo &endpointInfo : kEndpointInfos) {
91*84e33947SAndroid Build Coastguard Worker if (endpointInfo.id == endpointId) {
92*84e33947SAndroid Build Coastguard Worker return endpointInfo;
93*84e33947SAndroid Build Coastguard Worker }
94*84e33947SAndroid Build Coastguard Worker }
95*84e33947SAndroid Build Coastguard Worker return std::nullopt;
96*84e33947SAndroid Build Coastguard Worker }
97*84e33947SAndroid Build Coastguard Worker };
98*84e33947SAndroid Build Coastguard Worker
99*84e33947SAndroid Build Coastguard Worker //! MessageHubCallback that stores the data passed to onMessageReceived and
100*84e33947SAndroid Build Coastguard Worker //! onSessionClosed
101*84e33947SAndroid Build Coastguard Worker class MessageHubCallbackStoreData : public MessageHubCallbackBase {
102*84e33947SAndroid Build Coastguard Worker public:
MessageHubCallbackStoreData(Message * message,Session * session)103*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData(Message *message, Session *session)
104*84e33947SAndroid Build Coastguard Worker : mMessage(message), mSession(session) {}
105*84e33947SAndroid Build Coastguard Worker
onMessageReceived(pw::UniquePtr<std::byte[]> && data,size_t length,uint32_t messageType,uint32_t messagePermissions,const Session & session,bool sentBySessionInitiator)106*84e33947SAndroid Build Coastguard Worker bool onMessageReceived(pw::UniquePtr<std::byte[]> &&data, size_t length,
107*84e33947SAndroid Build Coastguard Worker uint32_t messageType, uint32_t messagePermissions,
108*84e33947SAndroid Build Coastguard Worker const Session &session,
109*84e33947SAndroid Build Coastguard Worker bool sentBySessionInitiator) override {
110*84e33947SAndroid Build Coastguard Worker if (mMessage != nullptr) {
111*84e33947SAndroid Build Coastguard Worker mMessage->sender = sentBySessionInitiator ? session.initiator
112*84e33947SAndroid Build Coastguard Worker : session.peer;
113*84e33947SAndroid Build Coastguard Worker mMessage->recipient =
114*84e33947SAndroid Build Coastguard Worker sentBySessionInitiator ? session.peer : session.initiator;
115*84e33947SAndroid Build Coastguard Worker mMessage->sessionId = session.sessionId;
116*84e33947SAndroid Build Coastguard Worker mMessage->data = std::move(data);
117*84e33947SAndroid Build Coastguard Worker mMessage->length = length;
118*84e33947SAndroid Build Coastguard Worker mMessage->messageType = messageType;
119*84e33947SAndroid Build Coastguard Worker mMessage->messagePermissions = messagePermissions;
120*84e33947SAndroid Build Coastguard Worker }
121*84e33947SAndroid Build Coastguard Worker return true;
122*84e33947SAndroid Build Coastguard Worker }
123*84e33947SAndroid Build Coastguard Worker
onSessionClosed(const Session & session)124*84e33947SAndroid Build Coastguard Worker void onSessionClosed(const Session &session) override {
125*84e33947SAndroid Build Coastguard Worker if (mSession != nullptr) {
126*84e33947SAndroid Build Coastguard Worker *mSession = session;
127*84e33947SAndroid Build Coastguard Worker }
128*84e33947SAndroid Build Coastguard Worker }
129*84e33947SAndroid Build Coastguard Worker
130*84e33947SAndroid Build Coastguard Worker private:
131*84e33947SAndroid Build Coastguard Worker Message *mMessage;
132*84e33947SAndroid Build Coastguard Worker Session *mSession;
133*84e33947SAndroid Build Coastguard Worker };
134*84e33947SAndroid Build Coastguard Worker
135*84e33947SAndroid Build Coastguard Worker //! MessageHubCallback that always fails to process messages
136*84e33947SAndroid Build Coastguard Worker class MessageHubCallbackAlwaysFails : public MessageHubCallbackBase {
137*84e33947SAndroid Build Coastguard Worker public:
MessageHubCallbackAlwaysFails(bool * wasMessageReceivedCalled,bool * wasSessionClosedCalled)138*84e33947SAndroid Build Coastguard Worker MessageHubCallbackAlwaysFails(bool *wasMessageReceivedCalled,
139*84e33947SAndroid Build Coastguard Worker bool *wasSessionClosedCalled)
140*84e33947SAndroid Build Coastguard Worker : mWasMessageReceivedCalled(wasMessageReceivedCalled),
141*84e33947SAndroid Build Coastguard Worker mWasSessionClosedCalled(wasSessionClosedCalled) {}
142*84e33947SAndroid Build Coastguard Worker
onMessageReceived(pw::UniquePtr<std::byte[]> &&,size_t,uint32_t,uint32_t,const Session &,bool)143*84e33947SAndroid Build Coastguard Worker bool onMessageReceived(pw::UniquePtr<std::byte[]> && /* data */,
144*84e33947SAndroid Build Coastguard Worker size_t /* length */, uint32_t /* messageType */,
145*84e33947SAndroid Build Coastguard Worker uint32_t /* messagePermissions */,
146*84e33947SAndroid Build Coastguard Worker const Session & /* session */,
147*84e33947SAndroid Build Coastguard Worker bool /* sentBySessionInitiator */) override {
148*84e33947SAndroid Build Coastguard Worker if (mWasMessageReceivedCalled != nullptr) {
149*84e33947SAndroid Build Coastguard Worker *mWasMessageReceivedCalled = true;
150*84e33947SAndroid Build Coastguard Worker }
151*84e33947SAndroid Build Coastguard Worker return false;
152*84e33947SAndroid Build Coastguard Worker }
153*84e33947SAndroid Build Coastguard Worker
onSessionClosed(const Session &)154*84e33947SAndroid Build Coastguard Worker void onSessionClosed(const Session & /* session */) override {
155*84e33947SAndroid Build Coastguard Worker if (mWasSessionClosedCalled != nullptr) {
156*84e33947SAndroid Build Coastguard Worker *mWasSessionClosedCalled = true;
157*84e33947SAndroid Build Coastguard Worker }
158*84e33947SAndroid Build Coastguard Worker }
159*84e33947SAndroid Build Coastguard Worker
160*84e33947SAndroid Build Coastguard Worker private:
161*84e33947SAndroid Build Coastguard Worker bool *mWasMessageReceivedCalled;
162*84e33947SAndroid Build Coastguard Worker bool *mWasSessionClosedCalled;
163*84e33947SAndroid Build Coastguard Worker };
164*84e33947SAndroid Build Coastguard Worker
165*84e33947SAndroid Build Coastguard Worker //! MessageHubCallback that calls MessageHub APIs during callbacks
166*84e33947SAndroid Build Coastguard Worker class MessageHubCallbackCallsMessageHubApisDuringCallback
167*84e33947SAndroid Build Coastguard Worker : public MessageHubCallbackBase {
168*84e33947SAndroid Build Coastguard Worker public:
onMessageReceived(pw::UniquePtr<std::byte[]> &&,size_t,uint32_t,uint32_t,const Session &,bool)169*84e33947SAndroid Build Coastguard Worker bool onMessageReceived(pw::UniquePtr<std::byte[]> && /* data */,
170*84e33947SAndroid Build Coastguard Worker size_t /* length */, uint32_t /* messageType */,
171*84e33947SAndroid Build Coastguard Worker uint32_t /* messagePermissions */,
172*84e33947SAndroid Build Coastguard Worker const Session & /* session */,
173*84e33947SAndroid Build Coastguard Worker bool /* sentBySessionInitiator */) override {
174*84e33947SAndroid Build Coastguard Worker if (mMessageHub != nullptr) {
175*84e33947SAndroid Build Coastguard Worker // Call a function that locks the MessageRouter mutex
176*84e33947SAndroid Build Coastguard Worker mMessageHub->openSession(kEndpointInfos[0].id, mMessageHub->getId(),
177*84e33947SAndroid Build Coastguard Worker kEndpointInfos[1].id);
178*84e33947SAndroid Build Coastguard Worker }
179*84e33947SAndroid Build Coastguard Worker return true;
180*84e33947SAndroid Build Coastguard Worker }
181*84e33947SAndroid Build Coastguard Worker
onSessionClosed(const Session &)182*84e33947SAndroid Build Coastguard Worker void onSessionClosed(const Session & /* session */) override {
183*84e33947SAndroid Build Coastguard Worker if (mMessageHub != nullptr) {
184*84e33947SAndroid Build Coastguard Worker // Call a function that locks the MessageRouter mutex
185*84e33947SAndroid Build Coastguard Worker mMessageHub->openSession(kEndpointInfos[0].id, mMessageHub->getId(),
186*84e33947SAndroid Build Coastguard Worker kEndpointInfos[1].id);
187*84e33947SAndroid Build Coastguard Worker }
188*84e33947SAndroid Build Coastguard Worker }
189*84e33947SAndroid Build Coastguard Worker
setMessageHub(MessageRouter::MessageHub * messageHub)190*84e33947SAndroid Build Coastguard Worker void setMessageHub(MessageRouter::MessageHub *messageHub) {
191*84e33947SAndroid Build Coastguard Worker mMessageHub = messageHub;
192*84e33947SAndroid Build Coastguard Worker }
193*84e33947SAndroid Build Coastguard Worker
194*84e33947SAndroid Build Coastguard Worker private:
195*84e33947SAndroid Build Coastguard Worker MessageRouter::MessageHub *mMessageHub = nullptr;
196*84e33947SAndroid Build Coastguard Worker };
197*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,RegisterMessageHubNameIsUnique)198*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, RegisterMessageHubNameIsUnique) {
199*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
200*84e33947SAndroid Build Coastguard Worker
201*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
202*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
203*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub1 =
204*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
205*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub1.has_value());
206*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
207*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback);
208*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
209*84e33947SAndroid Build Coastguard Worker
210*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub3 =
211*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
212*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub3.has_value());
213*84e33947SAndroid Build Coastguard Worker }
214*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,RegisterMessageHubIdIsUnique)215*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, RegisterMessageHubIdIsUnique) {
216*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
217*84e33947SAndroid Build Coastguard Worker
218*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
219*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
220*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub1 =
221*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
222*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub1.has_value());
223*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
224*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback);
225*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
226*84e33947SAndroid Build Coastguard Worker
227*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub3 =
228*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub3", /* id= */ 1, callback);
229*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub3.has_value());
230*84e33947SAndroid Build Coastguard Worker }
231*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,RegisterMessageHubGetListOfHubs)232*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, RegisterMessageHubGetListOfHubs) {
233*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
234*84e33947SAndroid Build Coastguard Worker
235*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
236*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
237*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub1 =
238*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
239*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub1.has_value());
240*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
241*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback);
242*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
243*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub3 =
244*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub3", /* id= */ 3, callback);
245*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub3.has_value());
246*84e33947SAndroid Build Coastguard Worker
247*84e33947SAndroid Build Coastguard Worker DynamicVector<MessageHubInfo> messageHubs;
248*84e33947SAndroid Build Coastguard Worker router.forEachMessageHub(
249*84e33947SAndroid Build Coastguard Worker [&messageHubs](const MessageHubInfo &messageHubInfo) {
250*84e33947SAndroid Build Coastguard Worker messageHubs.push_back(messageHubInfo);
251*84e33947SAndroid Build Coastguard Worker return false;
252*84e33947SAndroid Build Coastguard Worker });
253*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs.size(), 3);
254*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[0].name, "hub1");
255*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[1].name, "hub2");
256*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[2].name, "hub3");
257*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[0].id, 1);
258*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[1].id, 2);
259*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[2].id, 3);
260*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[0].id, messageHub1->getId());
261*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[1].id, messageHub2->getId());
262*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[2].id, messageHub3->getId());
263*84e33947SAndroid Build Coastguard Worker }
264*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,RegisterMessageHubGetListOfHubsWithUnregister)265*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, RegisterMessageHubGetListOfHubsWithUnregister) {
266*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
267*84e33947SAndroid Build Coastguard Worker
268*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
269*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
270*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub1 =
271*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
272*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub1.has_value());
273*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
274*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback);
275*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
276*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub3 =
277*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub3", /* id= */ 3, callback);
278*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub3.has_value());
279*84e33947SAndroid Build Coastguard Worker
280*84e33947SAndroid Build Coastguard Worker DynamicVector<MessageHubInfo> messageHubs;
281*84e33947SAndroid Build Coastguard Worker router.forEachMessageHub(
282*84e33947SAndroid Build Coastguard Worker [&messageHubs](const MessageHubInfo &messageHubInfo) {
283*84e33947SAndroid Build Coastguard Worker messageHubs.push_back(messageHubInfo);
284*84e33947SAndroid Build Coastguard Worker return false;
285*84e33947SAndroid Build Coastguard Worker });
286*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs.size(), 3);
287*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[0].name, "hub1");
288*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[1].name, "hub2");
289*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[2].name, "hub3");
290*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[0].id, 1);
291*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[1].id, 2);
292*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[2].id, 3);
293*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[0].id, messageHub1->getId());
294*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[1].id, messageHub2->getId());
295*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[2].id, messageHub3->getId());
296*84e33947SAndroid Build Coastguard Worker
297*84e33947SAndroid Build Coastguard Worker // Clear messageHubs and reset messageHub2
298*84e33947SAndroid Build Coastguard Worker messageHubs.clear();
299*84e33947SAndroid Build Coastguard Worker messageHub2.reset();
300*84e33947SAndroid Build Coastguard Worker
301*84e33947SAndroid Build Coastguard Worker router.forEachMessageHub(
302*84e33947SAndroid Build Coastguard Worker [&messageHubs](const MessageHubInfo &messageHubInfo) {
303*84e33947SAndroid Build Coastguard Worker messageHubs.push_back(messageHubInfo);
304*84e33947SAndroid Build Coastguard Worker return false;
305*84e33947SAndroid Build Coastguard Worker });
306*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs.size(), 2);
307*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[0].name, "hub1");
308*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[1].name, "hub3");
309*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[0].id, 1);
310*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[1].id, 3);
311*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[0].id, messageHub1->getId());
312*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageHubs[1].id, messageHub3->getId());
313*84e33947SAndroid Build Coastguard Worker }
314*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,RegisterMessageHubTooManyFails)315*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, RegisterMessageHubTooManyFails) {
316*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
317*84e33947SAndroid Build Coastguard Worker static_assert(kMaxMessageHubs == 3);
318*84e33947SAndroid Build Coastguard Worker constexpr const char *kNames[3] = {"hub1", "hub2", "hub3"};
319*84e33947SAndroid Build Coastguard Worker
320*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
321*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
322*84e33947SAndroid Build Coastguard Worker MessageRouter::MessageHub messageHubs[kMaxMessageHubs];
323*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < kMaxMessageHubs; ++i) {
324*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
325*84e33947SAndroid Build Coastguard Worker router.registerMessageHub(kNames[i], /* id= */ i, callback);
326*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
327*84e33947SAndroid Build Coastguard Worker messageHubs[i] = std::move(*messageHub);
328*84e33947SAndroid Build Coastguard Worker }
329*84e33947SAndroid Build Coastguard Worker
330*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
331*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("shouldfail", /* id= */ kMaxMessageHubs * 2,
332*84e33947SAndroid Build Coastguard Worker callback);
333*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub.has_value());
334*84e33947SAndroid Build Coastguard Worker }
335*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,GetEndpointInfo)336*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, GetEndpointInfo) {
337*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
338*84e33947SAndroid Build Coastguard Worker
339*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
340*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
341*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub1 =
342*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
343*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub1.has_value());
344*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
345*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback);
346*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
347*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub3 =
348*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub3", /* id= */ 3, callback);
349*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub3.has_value());
350*84e33947SAndroid Build Coastguard Worker
351*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < kNumEndpoints; ++i) {
352*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(
353*84e33947SAndroid Build Coastguard Worker router.getEndpointInfo(messageHub1->getId(), kEndpointInfos[i].id),
354*84e33947SAndroid Build Coastguard Worker kEndpointInfos[i]);
355*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(
356*84e33947SAndroid Build Coastguard Worker router.getEndpointInfo(messageHub2->getId(), kEndpointInfos[i].id),
357*84e33947SAndroid Build Coastguard Worker kEndpointInfos[i]);
358*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(
359*84e33947SAndroid Build Coastguard Worker router.getEndpointInfo(messageHub3->getId(), kEndpointInfos[i].id),
360*84e33947SAndroid Build Coastguard Worker kEndpointInfos[i]);
361*84e33947SAndroid Build Coastguard Worker }
362*84e33947SAndroid Build Coastguard Worker }
363*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,RegisterSessionTwoDifferentMessageHubs)364*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, RegisterSessionTwoDifferentMessageHubs) {
365*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
366*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback1;
367*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback2;
368*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
369*84e33947SAndroid Build Coastguard Worker &sessionFromCallback1);
370*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback2(/* message= */ nullptr,
371*84e33947SAndroid Build Coastguard Worker &sessionFromCallback2);
372*84e33947SAndroid Build Coastguard Worker
373*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
374*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
375*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
376*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
377*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback2);
378*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
379*84e33947SAndroid Build Coastguard Worker
380*84e33947SAndroid Build Coastguard Worker // Open session from messageHub:1 to messageHub2:2
381*84e33947SAndroid Build Coastguard Worker SessionId sessionId = messageHub->openSession(
382*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id);
383*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
384*84e33947SAndroid Build Coastguard Worker
385*84e33947SAndroid Build Coastguard Worker // Get session from messageHub and compare it with messageHub2
386*84e33947SAndroid Build Coastguard Worker std::optional<Session> sessionAfterRegistering =
387*84e33947SAndroid Build Coastguard Worker messageHub->getSessionWithId(sessionId);
388*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering.has_value());
389*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->sessionId, sessionId);
390*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->initiator.messageHubId,
391*84e33947SAndroid Build Coastguard Worker messageHub->getId());
392*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->initiator.endpointId,
393*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id);
394*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->peer.messageHubId, messageHub2->getId());
395*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->peer.endpointId, kEndpointInfos[1].id);
396*84e33947SAndroid Build Coastguard Worker std::optional<Session> sessionAfterRegistering2 =
397*84e33947SAndroid Build Coastguard Worker messageHub2->getSessionWithId(sessionId);
398*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering2.has_value());
399*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2);
400*84e33947SAndroid Build Coastguard Worker
401*84e33947SAndroid Build Coastguard Worker // Close the session and verify it is closed on both message hubs
402*84e33947SAndroid Build Coastguard Worker EXPECT_NE(*sessionAfterRegistering, sessionFromCallback1);
403*84e33947SAndroid Build Coastguard Worker EXPECT_NE(*sessionAfterRegistering, sessionFromCallback2);
404*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub->closeSession(sessionId));
405*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*sessionAfterRegistering, sessionFromCallback1);
406*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*sessionAfterRegistering, sessionFromCallback2);
407*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub->getSessionWithId(sessionId).has_value());
408*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub2->getSessionWithId(sessionId).has_value());
409*84e33947SAndroid Build Coastguard Worker }
410*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,UnregisterMessageHubCausesSessionClosed)411*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, UnregisterMessageHubCausesSessionClosed) {
412*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
413*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback1;
414*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback2;
415*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
416*84e33947SAndroid Build Coastguard Worker &sessionFromCallback1);
417*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback2(/* message= */ nullptr,
418*84e33947SAndroid Build Coastguard Worker &sessionFromCallback2);
419*84e33947SAndroid Build Coastguard Worker
420*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
421*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
422*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
423*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
424*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback2);
425*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
426*84e33947SAndroid Build Coastguard Worker
427*84e33947SAndroid Build Coastguard Worker // Open session from messageHub:1 to messageHub2:2
428*84e33947SAndroid Build Coastguard Worker SessionId sessionId = messageHub->openSession(
429*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id);
430*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
431*84e33947SAndroid Build Coastguard Worker
432*84e33947SAndroid Build Coastguard Worker // Get session from messageHub and compare it with messageHub2
433*84e33947SAndroid Build Coastguard Worker std::optional<Session> sessionAfterRegistering =
434*84e33947SAndroid Build Coastguard Worker messageHub->getSessionWithId(sessionId);
435*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering.has_value());
436*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->sessionId, sessionId);
437*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->initiator.messageHubId,
438*84e33947SAndroid Build Coastguard Worker messageHub->getId());
439*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->initiator.endpointId,
440*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id);
441*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->peer.messageHubId, messageHub2->getId());
442*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->peer.endpointId, kEndpointInfos[1].id);
443*84e33947SAndroid Build Coastguard Worker std::optional<Session> sessionAfterRegistering2 =
444*84e33947SAndroid Build Coastguard Worker messageHub2->getSessionWithId(sessionId);
445*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering2.has_value());
446*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2);
447*84e33947SAndroid Build Coastguard Worker
448*84e33947SAndroid Build Coastguard Worker // Close the session and verify it is closed on the other hub
449*84e33947SAndroid Build Coastguard Worker EXPECT_NE(*sessionAfterRegistering, sessionFromCallback1);
450*84e33947SAndroid Build Coastguard Worker messageHub2.reset();
451*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*sessionAfterRegistering, sessionFromCallback1);
452*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub->getSessionWithId(sessionId).has_value());
453*84e33947SAndroid Build Coastguard Worker }
454*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,RegisterSessionSameMessageHubInvalid)455*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, RegisterSessionSameMessageHubInvalid) {
456*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
457*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback1;
458*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback2;
459*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
460*84e33947SAndroid Build Coastguard Worker &sessionFromCallback1);
461*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback2(/* message= */ nullptr,
462*84e33947SAndroid Build Coastguard Worker &sessionFromCallback2);
463*84e33947SAndroid Build Coastguard Worker
464*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
465*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
466*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
467*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
468*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback2);
469*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
470*84e33947SAndroid Build Coastguard Worker
471*84e33947SAndroid Build Coastguard Worker // Open session from messageHub:2 to messageHub:2
472*84e33947SAndroid Build Coastguard Worker SessionId sessionId = messageHub->openSession(
473*84e33947SAndroid Build Coastguard Worker kEndpointInfos[1].id, messageHub->getId(), kEndpointInfos[1].id);
474*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionId, SESSION_ID_INVALID);
475*84e33947SAndroid Build Coastguard Worker
476*84e33947SAndroid Build Coastguard Worker // Open session from messageHub:1 to messageHub:3
477*84e33947SAndroid Build Coastguard Worker sessionId = messageHub->openSession(kEndpointInfos[0].id, messageHub->getId(),
478*84e33947SAndroid Build Coastguard Worker kEndpointInfos[2].id);
479*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionId, SESSION_ID_INVALID);
480*84e33947SAndroid Build Coastguard Worker }
481*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,RegisterSessionDifferentMessageHubsSameEndpoints)482*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, RegisterSessionDifferentMessageHubsSameEndpoints) {
483*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
484*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback1;
485*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback2;
486*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
487*84e33947SAndroid Build Coastguard Worker &sessionFromCallback1);
488*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback2(/* message= */ nullptr,
489*84e33947SAndroid Build Coastguard Worker &sessionFromCallback2);
490*84e33947SAndroid Build Coastguard Worker
491*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
492*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
493*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
494*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
495*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback2);
496*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
497*84e33947SAndroid Build Coastguard Worker
498*84e33947SAndroid Build Coastguard Worker // Open session from messageHub:1 to messageHub:2
499*84e33947SAndroid Build Coastguard Worker SessionId sessionId = messageHub->openSession(
500*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[0].id);
501*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
502*84e33947SAndroid Build Coastguard Worker }
503*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,RegisterSessionTwoDifferentMessageHubsInvalidEndpoint)504*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest,
505*84e33947SAndroid Build Coastguard Worker RegisterSessionTwoDifferentMessageHubsInvalidEndpoint) {
506*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
507*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
508*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
509*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback2(/* message= */ nullptr,
510*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
511*84e33947SAndroid Build Coastguard Worker
512*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
513*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
514*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
515*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
516*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback2);
517*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
518*84e33947SAndroid Build Coastguard Worker
519*84e33947SAndroid Build Coastguard Worker // Open session from messageHub with other non-registered endpoint - not
520*84e33947SAndroid Build Coastguard Worker // valid
521*84e33947SAndroid Build Coastguard Worker SessionId sessionId = messageHub->openSession(
522*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id, messageHub2->getId(), /* toEndpointId= */ 10);
523*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionId, SESSION_ID_INVALID);
524*84e33947SAndroid Build Coastguard Worker }
525*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,ThirdMessageHubTriesToFindOthersSession)526*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, ThirdMessageHubTriesToFindOthersSession) {
527*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
528*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback1;
529*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback2;
530*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback3;
531*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
532*84e33947SAndroid Build Coastguard Worker &sessionFromCallback1);
533*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback2(/* message= */ nullptr,
534*84e33947SAndroid Build Coastguard Worker &sessionFromCallback2);
535*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback3(/* message= */ nullptr,
536*84e33947SAndroid Build Coastguard Worker &sessionFromCallback3);
537*84e33947SAndroid Build Coastguard Worker
538*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
539*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
540*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
541*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
542*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback2);
543*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
544*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub3 =
545*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub3", /* id= */ 3, callback3);
546*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub3.has_value());
547*84e33947SAndroid Build Coastguard Worker
548*84e33947SAndroid Build Coastguard Worker // Open session from messageHub:1 to messageHub2:2
549*84e33947SAndroid Build Coastguard Worker SessionId sessionId = messageHub->openSession(
550*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id);
551*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
552*84e33947SAndroid Build Coastguard Worker
553*84e33947SAndroid Build Coastguard Worker // Get session from messageHub and compare it with messageHub2
554*84e33947SAndroid Build Coastguard Worker std::optional<Session> sessionAfterRegistering =
555*84e33947SAndroid Build Coastguard Worker messageHub->getSessionWithId(sessionId);
556*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering.has_value());
557*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->sessionId, sessionId);
558*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->initiator.messageHubId,
559*84e33947SAndroid Build Coastguard Worker messageHub->getId());
560*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->initiator.endpointId,
561*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id);
562*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->peer.messageHubId, messageHub2->getId());
563*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->peer.endpointId, kEndpointInfos[1].id);
564*84e33947SAndroid Build Coastguard Worker std::optional<Session> sessionAfterRegistering2 =
565*84e33947SAndroid Build Coastguard Worker messageHub2->getSessionWithId(sessionId);
566*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering2.has_value());
567*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2);
568*84e33947SAndroid Build Coastguard Worker
569*84e33947SAndroid Build Coastguard Worker // Third message hub tries to find the session - not found
570*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub3->getSessionWithId(sessionId).has_value());
571*84e33947SAndroid Build Coastguard Worker // Third message hub tries to close the session - not found
572*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub3->closeSession(sessionId));
573*84e33947SAndroid Build Coastguard Worker
574*84e33947SAndroid Build Coastguard Worker // Get session from messageHub and compare it with messageHub2 again
575*84e33947SAndroid Build Coastguard Worker sessionAfterRegistering = messageHub->getSessionWithId(sessionId);
576*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering.has_value());
577*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->sessionId, sessionId);
578*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->initiator.messageHubId,
579*84e33947SAndroid Build Coastguard Worker messageHub->getId());
580*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->initiator.endpointId,
581*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id);
582*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->peer.messageHubId, messageHub2->getId());
583*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(sessionAfterRegistering->peer.endpointId, kEndpointInfos[1].id);
584*84e33947SAndroid Build Coastguard Worker sessionAfterRegistering2 = messageHub2->getSessionWithId(sessionId);
585*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering2.has_value());
586*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2);
587*84e33947SAndroid Build Coastguard Worker
588*84e33947SAndroid Build Coastguard Worker // Close the session and verify it is closed on both message hubs
589*84e33947SAndroid Build Coastguard Worker EXPECT_NE(*sessionAfterRegistering, sessionFromCallback1);
590*84e33947SAndroid Build Coastguard Worker EXPECT_NE(*sessionAfterRegistering, sessionFromCallback2);
591*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub->closeSession(sessionId));
592*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*sessionAfterRegistering, sessionFromCallback1);
593*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*sessionAfterRegistering, sessionFromCallback2);
594*84e33947SAndroid Build Coastguard Worker EXPECT_NE(*sessionAfterRegistering, sessionFromCallback3);
595*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub->getSessionWithId(sessionId).has_value());
596*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub2->getSessionWithId(sessionId).has_value());
597*84e33947SAndroid Build Coastguard Worker }
598*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,ThreeMessageHubsAndThreeSessions)599*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, ThreeMessageHubsAndThreeSessions) {
600*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
601*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
602*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
603*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback2(/* message= */ nullptr,
604*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
605*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback3(/* message= */ nullptr,
606*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
607*84e33947SAndroid Build Coastguard Worker
608*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
609*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
610*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
611*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
612*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback2);
613*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
614*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub3 =
615*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub3", /* id= */ 3, callback3);
616*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub3.has_value());
617*84e33947SAndroid Build Coastguard Worker
618*84e33947SAndroid Build Coastguard Worker // Open session from messageHub:1 to messageHub2:2
619*84e33947SAndroid Build Coastguard Worker SessionId sessionId = messageHub->openSession(
620*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id);
621*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
622*84e33947SAndroid Build Coastguard Worker
623*84e33947SAndroid Build Coastguard Worker // Open session from messageHub2:2 to messageHub3:3
624*84e33947SAndroid Build Coastguard Worker SessionId sessionId2 = messageHub2->openSession(
625*84e33947SAndroid Build Coastguard Worker kEndpointInfos[1].id, messageHub3->getId(), kEndpointInfos[2].id);
626*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
627*84e33947SAndroid Build Coastguard Worker
628*84e33947SAndroid Build Coastguard Worker // Open session from messageHub3:3 to messageHub1:1
629*84e33947SAndroid Build Coastguard Worker SessionId sessionId3 = messageHub3->openSession(
630*84e33947SAndroid Build Coastguard Worker kEndpointInfos[2].id, messageHub->getId(), kEndpointInfos[0].id);
631*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
632*84e33947SAndroid Build Coastguard Worker
633*84e33947SAndroid Build Coastguard Worker // Get sessions and compare
634*84e33947SAndroid Build Coastguard Worker // Find session: MessageHub1:1 -> MessageHub2:2
635*84e33947SAndroid Build Coastguard Worker std::optional<Session> sessionAfterRegistering =
636*84e33947SAndroid Build Coastguard Worker messageHub->getSessionWithId(sessionId);
637*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering.has_value());
638*84e33947SAndroid Build Coastguard Worker std::optional<Session> sessionAfterRegistering2 =
639*84e33947SAndroid Build Coastguard Worker messageHub2->getSessionWithId(sessionId);
640*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering2.has_value());
641*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub3->getSessionWithId(sessionId).has_value());
642*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2);
643*84e33947SAndroid Build Coastguard Worker
644*84e33947SAndroid Build Coastguard Worker // Find session: MessageHub2:2 -> MessageHub3:3
645*84e33947SAndroid Build Coastguard Worker sessionAfterRegistering = messageHub2->getSessionWithId(sessionId2);
646*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering.has_value());
647*84e33947SAndroid Build Coastguard Worker sessionAfterRegistering2 = messageHub3->getSessionWithId(sessionId2);
648*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering2.has_value());
649*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub->getSessionWithId(sessionId2).has_value());
650*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2);
651*84e33947SAndroid Build Coastguard Worker
652*84e33947SAndroid Build Coastguard Worker // Find session: MessageHub3:3 -> MessageHub1:1
653*84e33947SAndroid Build Coastguard Worker sessionAfterRegistering = messageHub3->getSessionWithId(sessionId3);
654*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering.has_value());
655*84e33947SAndroid Build Coastguard Worker sessionAfterRegistering2 = messageHub->getSessionWithId(sessionId3);
656*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(sessionAfterRegistering2.has_value());
657*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub2->getSessionWithId(sessionId3).has_value());
658*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(*sessionAfterRegistering, *sessionAfterRegistering2);
659*84e33947SAndroid Build Coastguard Worker
660*84e33947SAndroid Build Coastguard Worker // Close sessions from receivers and verify they are closed on all hubs
661*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2->closeSession(sessionId));
662*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub3->closeSession(sessionId2));
663*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub->closeSession(sessionId3));
664*84e33947SAndroid Build Coastguard Worker for (SessionId id : {sessionId, sessionId2, sessionId3}) {
665*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub->getSessionWithId(id).has_value());
666*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub2->getSessionWithId(id).has_value());
667*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub3->getSessionWithId(id).has_value());
668*84e33947SAndroid Build Coastguard Worker }
669*84e33947SAndroid Build Coastguard Worker }
670*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,SendMessageToSession)671*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, SendMessageToSession) {
672*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
673*84e33947SAndroid Build Coastguard Worker constexpr size_t kMessageSize = 5;
674*84e33947SAndroid Build Coastguard Worker pw::UniquePtr<std::byte[]> messageData =
675*84e33947SAndroid Build Coastguard Worker mAllocator.MakeUniqueArray<std::byte>(kMessageSize);
676*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < 5; ++i) {
677*84e33947SAndroid Build Coastguard Worker messageData[i] = static_cast<std::byte>(i + 1);
678*84e33947SAndroid Build Coastguard Worker }
679*84e33947SAndroid Build Coastguard Worker
680*84e33947SAndroid Build Coastguard Worker Message messageFromCallback1;
681*84e33947SAndroid Build Coastguard Worker Message messageFromCallback2;
682*84e33947SAndroid Build Coastguard Worker Message messageFromCallback3;
683*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback1;
684*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback2;
685*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback3;
686*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(&messageFromCallback1,
687*84e33947SAndroid Build Coastguard Worker &sessionFromCallback1);
688*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback2(&messageFromCallback2,
689*84e33947SAndroid Build Coastguard Worker &sessionFromCallback2);
690*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback3(&messageFromCallback3,
691*84e33947SAndroid Build Coastguard Worker &sessionFromCallback3);
692*84e33947SAndroid Build Coastguard Worker
693*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
694*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
695*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
696*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
697*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback2);
698*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
699*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub3 =
700*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub3", /* id= */ 3, callback3);
701*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub3.has_value());
702*84e33947SAndroid Build Coastguard Worker
703*84e33947SAndroid Build Coastguard Worker // Open session from messageHub:1 to messageHub2:2
704*84e33947SAndroid Build Coastguard Worker SessionId sessionId = messageHub->openSession(
705*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id);
706*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
707*84e33947SAndroid Build Coastguard Worker
708*84e33947SAndroid Build Coastguard Worker // Open session from messageHub2:2 to messageHub3:3
709*84e33947SAndroid Build Coastguard Worker SessionId sessionId2 = messageHub2->openSession(
710*84e33947SAndroid Build Coastguard Worker kEndpointInfos[1].id, messageHub3->getId(), kEndpointInfos[2].id);
711*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
712*84e33947SAndroid Build Coastguard Worker
713*84e33947SAndroid Build Coastguard Worker // Open session from messageHub3:3 to messageHub1:1
714*84e33947SAndroid Build Coastguard Worker SessionId sessionId3 = messageHub3->openSession(
715*84e33947SAndroid Build Coastguard Worker kEndpointInfos[2].id, messageHub->getId(), kEndpointInfos[0].id);
716*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
717*84e33947SAndroid Build Coastguard Worker
718*84e33947SAndroid Build Coastguard Worker // Send message from messageHub:1 to messageHub2:2
719*84e33947SAndroid Build Coastguard Worker ASSERT_TRUE(messageHub->sendMessage(std::move(messageData), kMessageSize,
720*84e33947SAndroid Build Coastguard Worker /* messageType= */ 1,
721*84e33947SAndroid Build Coastguard Worker /* messagePermissions= */ 0, sessionId));
722*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.sessionId, sessionId);
723*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.sender.messageHubId, messageHub->getId());
724*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.sender.endpointId, kEndpointInfos[0].id);
725*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.recipient.messageHubId, messageHub2->getId());
726*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.recipient.endpointId, kEndpointInfos[1].id);
727*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.messageType, 1);
728*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.messagePermissions, 0);
729*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.length, kMessageSize);
730*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < kMessageSize; ++i) {
731*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.data[i], static_cast<std::byte>(i + 1));
732*84e33947SAndroid Build Coastguard Worker }
733*84e33947SAndroid Build Coastguard Worker
734*84e33947SAndroid Build Coastguard Worker messageData = mAllocator.MakeUniqueArray<std::byte>(kMessageSize);
735*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < 5; ++i) {
736*84e33947SAndroid Build Coastguard Worker messageData[i] = static_cast<std::byte>(i + 1);
737*84e33947SAndroid Build Coastguard Worker }
738*84e33947SAndroid Build Coastguard Worker
739*84e33947SAndroid Build Coastguard Worker // Send message from messageHub2:2 to messageHub:1
740*84e33947SAndroid Build Coastguard Worker ASSERT_TRUE(messageHub2->sendMessage(std::move(messageData), kMessageSize,
741*84e33947SAndroid Build Coastguard Worker /* messageType= */ 2,
742*84e33947SAndroid Build Coastguard Worker /* messagePermissions= */ 3, sessionId));
743*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.sessionId, sessionId);
744*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.sender.messageHubId, messageHub2->getId());
745*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.sender.endpointId, kEndpointInfos[1].id);
746*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.recipient.messageHubId, messageHub->getId());
747*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.recipient.endpointId, kEndpointInfos[0].id);
748*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.messageType, 2);
749*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.messagePermissions, 3);
750*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.length, kMessageSize);
751*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < kMessageSize; ++i) {
752*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.data[i], static_cast<std::byte>(i + 1));
753*84e33947SAndroid Build Coastguard Worker }
754*84e33947SAndroid Build Coastguard Worker }
755*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,SendMessageToSessionUsingPointerAndFreeCallback)756*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, SendMessageToSessionUsingPointerAndFreeCallback) {
757*84e33947SAndroid Build Coastguard Worker struct FreeCallbackContext {
758*84e33947SAndroid Build Coastguard Worker bool *freeCallbackCalled;
759*84e33947SAndroid Build Coastguard Worker std::byte *message;
760*84e33947SAndroid Build Coastguard Worker size_t length;
761*84e33947SAndroid Build Coastguard Worker };
762*84e33947SAndroid Build Coastguard Worker
763*84e33947SAndroid Build Coastguard Worker pw::Vector<
764*84e33947SAndroid Build Coastguard Worker MessageRouterCallbackAllocator<FreeCallbackContext>::FreeCallbackRecord,
765*84e33947SAndroid Build Coastguard Worker 10>
766*84e33947SAndroid Build Coastguard Worker freeCallbackRecords;
767*84e33947SAndroid Build Coastguard Worker MessageRouterCallbackAllocator<FreeCallbackContext> allocator(
768*84e33947SAndroid Build Coastguard Worker [](std::byte *message, size_t length,
769*84e33947SAndroid Build Coastguard Worker const FreeCallbackContext &context) {
770*84e33947SAndroid Build Coastguard Worker *context.freeCallbackCalled =
771*84e33947SAndroid Build Coastguard Worker message == context.message && length == context.length;
772*84e33947SAndroid Build Coastguard Worker },
773*84e33947SAndroid Build Coastguard Worker freeCallbackRecords);
774*84e33947SAndroid Build Coastguard Worker
775*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
776*84e33947SAndroid Build Coastguard Worker constexpr size_t kMessageSize = 5;
777*84e33947SAndroid Build Coastguard Worker std::byte messageData[kMessageSize];
778*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < 5; ++i) {
779*84e33947SAndroid Build Coastguard Worker messageData[i] = static_cast<std::byte>(i + 1);
780*84e33947SAndroid Build Coastguard Worker }
781*84e33947SAndroid Build Coastguard Worker
782*84e33947SAndroid Build Coastguard Worker Message messageFromCallback1;
783*84e33947SAndroid Build Coastguard Worker Message messageFromCallback2;
784*84e33947SAndroid Build Coastguard Worker Message messageFromCallback3;
785*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback1;
786*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback2;
787*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback3;
788*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(&messageFromCallback1,
789*84e33947SAndroid Build Coastguard Worker &sessionFromCallback1);
790*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback2(&messageFromCallback2,
791*84e33947SAndroid Build Coastguard Worker &sessionFromCallback2);
792*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback3(&messageFromCallback3,
793*84e33947SAndroid Build Coastguard Worker &sessionFromCallback3);
794*84e33947SAndroid Build Coastguard Worker
795*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
796*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
797*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
798*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
799*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback2);
800*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
801*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub3 =
802*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub3", /* id= */ 3, callback3);
803*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub3.has_value());
804*84e33947SAndroid Build Coastguard Worker
805*84e33947SAndroid Build Coastguard Worker // Open session from messageHub:1 to messageHub2:2
806*84e33947SAndroid Build Coastguard Worker SessionId sessionId = messageHub->openSession(
807*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id);
808*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
809*84e33947SAndroid Build Coastguard Worker
810*84e33947SAndroid Build Coastguard Worker // Open session from messageHub2:2 to messageHub3:3
811*84e33947SAndroid Build Coastguard Worker SessionId sessionId2 = messageHub2->openSession(
812*84e33947SAndroid Build Coastguard Worker kEndpointInfos[1].id, messageHub3->getId(), kEndpointInfos[2].id);
813*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
814*84e33947SAndroid Build Coastguard Worker
815*84e33947SAndroid Build Coastguard Worker // Open session from messageHub3:3 to messageHub1:1
816*84e33947SAndroid Build Coastguard Worker SessionId sessionId3 = messageHub3->openSession(
817*84e33947SAndroid Build Coastguard Worker kEndpointInfos[2].id, messageHub->getId(), kEndpointInfos[0].id);
818*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
819*84e33947SAndroid Build Coastguard Worker
820*84e33947SAndroid Build Coastguard Worker // Send message from messageHub:1 to messageHub2:2
821*84e33947SAndroid Build Coastguard Worker bool freeCallbackCalled = false;
822*84e33947SAndroid Build Coastguard Worker FreeCallbackContext freeCallbackContext = {
823*84e33947SAndroid Build Coastguard Worker .freeCallbackCalled = &freeCallbackCalled,
824*84e33947SAndroid Build Coastguard Worker .message = messageData,
825*84e33947SAndroid Build Coastguard Worker .length = kMessageSize,
826*84e33947SAndroid Build Coastguard Worker };
827*84e33947SAndroid Build Coastguard Worker pw::UniquePtr<std::byte[]> data = allocator.MakeUniqueArrayWithCallback(
828*84e33947SAndroid Build Coastguard Worker messageData, kMessageSize, std::move(freeCallbackContext));
829*84e33947SAndroid Build Coastguard Worker ASSERT_NE(data.get(), nullptr);
830*84e33947SAndroid Build Coastguard Worker
831*84e33947SAndroid Build Coastguard Worker ASSERT_TRUE(messageHub->sendMessage(std::move(data), kMessageSize,
832*84e33947SAndroid Build Coastguard Worker /* messageType= */ 1,
833*84e33947SAndroid Build Coastguard Worker /* messagePermissions= */ 0, sessionId));
834*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.sessionId, sessionId);
835*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.sender.messageHubId, messageHub->getId());
836*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.sender.endpointId, kEndpointInfos[0].id);
837*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.recipient.messageHubId, messageHub2->getId());
838*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.recipient.endpointId, kEndpointInfos[1].id);
839*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.messageType, 1);
840*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.messagePermissions, 0);
841*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.length, kMessageSize);
842*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < kMessageSize; ++i) {
843*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.data[i], static_cast<std::byte>(i + 1));
844*84e33947SAndroid Build Coastguard Worker }
845*84e33947SAndroid Build Coastguard Worker
846*84e33947SAndroid Build Coastguard Worker // Check if free callback was called
847*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(freeCallbackCalled);
848*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback2.data.get(), messageData);
849*84e33947SAndroid Build Coastguard Worker messageFromCallback2.data.Reset();
850*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(freeCallbackCalled);
851*84e33947SAndroid Build Coastguard Worker
852*84e33947SAndroid Build Coastguard Worker // Send message from messageHub2:2 to messageHub:1
853*84e33947SAndroid Build Coastguard Worker freeCallbackCalled = false;
854*84e33947SAndroid Build Coastguard Worker FreeCallbackContext freeCallbackContext2 = {
855*84e33947SAndroid Build Coastguard Worker .freeCallbackCalled = &freeCallbackCalled,
856*84e33947SAndroid Build Coastguard Worker .message = messageData,
857*84e33947SAndroid Build Coastguard Worker .length = kMessageSize,
858*84e33947SAndroid Build Coastguard Worker };
859*84e33947SAndroid Build Coastguard Worker data = allocator.MakeUniqueArrayWithCallback(messageData, kMessageSize,
860*84e33947SAndroid Build Coastguard Worker std::move(freeCallbackContext2));
861*84e33947SAndroid Build Coastguard Worker ASSERT_NE(data.get(), nullptr);
862*84e33947SAndroid Build Coastguard Worker
863*84e33947SAndroid Build Coastguard Worker ASSERT_TRUE(messageHub2->sendMessage(std::move(data), kMessageSize,
864*84e33947SAndroid Build Coastguard Worker /* messageType= */ 2,
865*84e33947SAndroid Build Coastguard Worker /* messagePermissions= */ 3, sessionId));
866*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.sessionId, sessionId);
867*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.sender.messageHubId, messageHub2->getId());
868*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.sender.endpointId, kEndpointInfos[1].id);
869*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.recipient.messageHubId, messageHub->getId());
870*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.recipient.endpointId, kEndpointInfos[0].id);
871*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.messageType, 2);
872*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.messagePermissions, 3);
873*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.length, kMessageSize);
874*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < kMessageSize; ++i) {
875*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.data[i], static_cast<std::byte>(i + 1));
876*84e33947SAndroid Build Coastguard Worker }
877*84e33947SAndroid Build Coastguard Worker
878*84e33947SAndroid Build Coastguard Worker // Check if free callback was called
879*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(freeCallbackCalled);
880*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(messageFromCallback1.data.get(), messageData);
881*84e33947SAndroid Build Coastguard Worker messageFromCallback1.data.Reset();
882*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(freeCallbackCalled);
883*84e33947SAndroid Build Coastguard Worker }
884*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,SendMessageToSessionInvalidHubAndSession)885*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, SendMessageToSessionInvalidHubAndSession) {
886*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
887*84e33947SAndroid Build Coastguard Worker constexpr size_t kMessageSize = 5;
888*84e33947SAndroid Build Coastguard Worker pw::UniquePtr<std::byte[]> messageData =
889*84e33947SAndroid Build Coastguard Worker mAllocator.MakeUniqueArray<std::byte>(kMessageSize);
890*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < 5; ++i) {
891*84e33947SAndroid Build Coastguard Worker messageData[i] = static_cast<std::byte>(i + 1);
892*84e33947SAndroid Build Coastguard Worker }
893*84e33947SAndroid Build Coastguard Worker
894*84e33947SAndroid Build Coastguard Worker Message messageFromCallback1;
895*84e33947SAndroid Build Coastguard Worker Message messageFromCallback2;
896*84e33947SAndroid Build Coastguard Worker Message messageFromCallback3;
897*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback1;
898*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback2;
899*84e33947SAndroid Build Coastguard Worker Session sessionFromCallback3;
900*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(&messageFromCallback1,
901*84e33947SAndroid Build Coastguard Worker &sessionFromCallback1);
902*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback2(&messageFromCallback2,
903*84e33947SAndroid Build Coastguard Worker &sessionFromCallback2);
904*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback3(&messageFromCallback3,
905*84e33947SAndroid Build Coastguard Worker &sessionFromCallback3);
906*84e33947SAndroid Build Coastguard Worker
907*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
908*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
909*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
910*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
911*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback2);
912*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
913*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub3 =
914*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub3", /* id= */ 3, callback3);
915*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub3.has_value());
916*84e33947SAndroid Build Coastguard Worker
917*84e33947SAndroid Build Coastguard Worker // Open session from messageHub:1 to messageHub2:2
918*84e33947SAndroid Build Coastguard Worker SessionId sessionId = messageHub->openSession(
919*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id);
920*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
921*84e33947SAndroid Build Coastguard Worker
922*84e33947SAndroid Build Coastguard Worker // Open session from messageHub2:2 to messageHub3:3
923*84e33947SAndroid Build Coastguard Worker SessionId sessionId2 = messageHub2->openSession(
924*84e33947SAndroid Build Coastguard Worker kEndpointInfos[1].id, messageHub3->getId(), kEndpointInfos[2].id);
925*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
926*84e33947SAndroid Build Coastguard Worker
927*84e33947SAndroid Build Coastguard Worker // Open session from messageHub3:3 to messageHub1:1
928*84e33947SAndroid Build Coastguard Worker SessionId sessionId3 = messageHub3->openSession(
929*84e33947SAndroid Build Coastguard Worker kEndpointInfos[2].id, messageHub->getId(), kEndpointInfos[0].id);
930*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
931*84e33947SAndroid Build Coastguard Worker
932*84e33947SAndroid Build Coastguard Worker // Send message from messageHub:1 to messageHub2:2
933*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub->sendMessage(std::move(messageData), kMessageSize,
934*84e33947SAndroid Build Coastguard Worker /* messageType= */ 1,
935*84e33947SAndroid Build Coastguard Worker /* messagePermissions= */ 0,
936*84e33947SAndroid Build Coastguard Worker sessionId2));
937*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub2->sendMessage(std::move(messageData), kMessageSize,
938*84e33947SAndroid Build Coastguard Worker /* messageType= */ 2,
939*84e33947SAndroid Build Coastguard Worker /* messagePermissions= */ 3,
940*84e33947SAndroid Build Coastguard Worker sessionId3));
941*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub3->sendMessage(std::move(messageData), kMessageSize,
942*84e33947SAndroid Build Coastguard Worker /* messageType= */ 2,
943*84e33947SAndroid Build Coastguard Worker /* messagePermissions= */ 3,
944*84e33947SAndroid Build Coastguard Worker sessionId));
945*84e33947SAndroid Build Coastguard Worker }
946*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,SendMessageToSessionCallbackFailureClosesSession)947*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, SendMessageToSessionCallbackFailureClosesSession) {
948*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
949*84e33947SAndroid Build Coastguard Worker constexpr size_t kMessageSize = 5;
950*84e33947SAndroid Build Coastguard Worker pw::UniquePtr<std::byte[]> messageData =
951*84e33947SAndroid Build Coastguard Worker mAllocator.MakeUniqueArray<std::byte>(kMessageSize);
952*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < 5; ++i) {
953*84e33947SAndroid Build Coastguard Worker messageData[i] = static_cast<std::byte>(i + 1);
954*84e33947SAndroid Build Coastguard Worker }
955*84e33947SAndroid Build Coastguard Worker
956*84e33947SAndroid Build Coastguard Worker bool wasMessageReceivedCalled1 = false;
957*84e33947SAndroid Build Coastguard Worker bool wasMessageReceivedCalled2 = false;
958*84e33947SAndroid Build Coastguard Worker bool wasMessageReceivedCalled3 = false;
959*84e33947SAndroid Build Coastguard Worker MessageHubCallbackAlwaysFails callback1(
960*84e33947SAndroid Build Coastguard Worker &wasMessageReceivedCalled1,
961*84e33947SAndroid Build Coastguard Worker /* wasSessionClosedCalled= */ nullptr);
962*84e33947SAndroid Build Coastguard Worker MessageHubCallbackAlwaysFails callback2(
963*84e33947SAndroid Build Coastguard Worker &wasMessageReceivedCalled2,
964*84e33947SAndroid Build Coastguard Worker /* wasSessionClosedCalled= */ nullptr);
965*84e33947SAndroid Build Coastguard Worker MessageHubCallbackAlwaysFails callback3(
966*84e33947SAndroid Build Coastguard Worker &wasMessageReceivedCalled3,
967*84e33947SAndroid Build Coastguard Worker /* wasSessionClosedCalled= */ nullptr);
968*84e33947SAndroid Build Coastguard Worker
969*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
970*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback1);
971*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
972*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
973*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback2);
974*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
975*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub3 =
976*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub3", /* id= */ 3, callback3);
977*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub3.has_value());
978*84e33947SAndroid Build Coastguard Worker
979*84e33947SAndroid Build Coastguard Worker // Open session from messageHub:1 to messageHub2:2
980*84e33947SAndroid Build Coastguard Worker SessionId sessionId = messageHub->openSession(
981*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id);
982*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
983*84e33947SAndroid Build Coastguard Worker
984*84e33947SAndroid Build Coastguard Worker // Open session from messageHub2:2 to messageHub3:3
985*84e33947SAndroid Build Coastguard Worker SessionId sessionId2 = messageHub2->openSession(
986*84e33947SAndroid Build Coastguard Worker kEndpointInfos[1].id, messageHub3->getId(), kEndpointInfos[2].id);
987*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
988*84e33947SAndroid Build Coastguard Worker
989*84e33947SAndroid Build Coastguard Worker // Open session from messageHub3:3 to messageHub1:1
990*84e33947SAndroid Build Coastguard Worker SessionId sessionId3 = messageHub3->openSession(
991*84e33947SAndroid Build Coastguard Worker kEndpointInfos[2].id, messageHub->getId(), kEndpointInfos[0].id);
992*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
993*84e33947SAndroid Build Coastguard Worker
994*84e33947SAndroid Build Coastguard Worker // Send message from messageHub2:2 to messageHub3:3
995*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(wasMessageReceivedCalled1);
996*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(wasMessageReceivedCalled2);
997*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(wasMessageReceivedCalled3);
998*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub->getSessionWithId(sessionId2).has_value());
999*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2->getSessionWithId(sessionId2).has_value());
1000*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub3->getSessionWithId(sessionId2).has_value());
1001*84e33947SAndroid Build Coastguard Worker
1002*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub2->sendMessage(std::move(messageData), kMessageSize,
1003*84e33947SAndroid Build Coastguard Worker /* messageType= */ 1,
1004*84e33947SAndroid Build Coastguard Worker /* messagePermissions= */ 0,
1005*84e33947SAndroid Build Coastguard Worker sessionId2));
1006*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(wasMessageReceivedCalled1);
1007*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(wasMessageReceivedCalled2);
1008*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(wasMessageReceivedCalled3);
1009*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub->getSessionWithId(sessionId2).has_value());
1010*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub2->getSessionWithId(sessionId2).has_value());
1011*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub3->getSessionWithId(sessionId2).has_value());
1012*84e33947SAndroid Build Coastguard Worker
1013*84e33947SAndroid Build Coastguard Worker // Try to send a message on the same session - should fail
1014*84e33947SAndroid Build Coastguard Worker wasMessageReceivedCalled1 = false;
1015*84e33947SAndroid Build Coastguard Worker wasMessageReceivedCalled2 = false;
1016*84e33947SAndroid Build Coastguard Worker wasMessageReceivedCalled3 = false;
1017*84e33947SAndroid Build Coastguard Worker messageData = mAllocator.MakeUniqueArray<std::byte>(kMessageSize);
1018*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < 5; ++i) {
1019*84e33947SAndroid Build Coastguard Worker messageData[i] = static_cast<std::byte>(i + 1);
1020*84e33947SAndroid Build Coastguard Worker }
1021*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub2->sendMessage(std::move(messageData), kMessageSize,
1022*84e33947SAndroid Build Coastguard Worker /* messageType= */ 1,
1023*84e33947SAndroid Build Coastguard Worker /* messagePermissions= */ 0,
1024*84e33947SAndroid Build Coastguard Worker sessionId2));
1025*84e33947SAndroid Build Coastguard Worker messageData = mAllocator.MakeUniqueArray<std::byte>(kMessageSize);
1026*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < 5; ++i) {
1027*84e33947SAndroid Build Coastguard Worker messageData[i] = static_cast<std::byte>(i + 1);
1028*84e33947SAndroid Build Coastguard Worker }
1029*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(messageHub3->sendMessage(std::move(messageData), kMessageSize,
1030*84e33947SAndroid Build Coastguard Worker /* messageType= */ 1,
1031*84e33947SAndroid Build Coastguard Worker /* messagePermissions= */ 0,
1032*84e33947SAndroid Build Coastguard Worker sessionId2));
1033*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(wasMessageReceivedCalled1);
1034*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(wasMessageReceivedCalled2);
1035*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(wasMessageReceivedCalled3);
1036*84e33947SAndroid Build Coastguard Worker }
1037*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,MessageHubCallbackCanCallOtherMessageHubAPIs)1038*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, MessageHubCallbackCanCallOtherMessageHubAPIs) {
1039*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
1040*84e33947SAndroid Build Coastguard Worker constexpr size_t kMessageSize = 5;
1041*84e33947SAndroid Build Coastguard Worker pw::UniquePtr<std::byte[]> messageData =
1042*84e33947SAndroid Build Coastguard Worker mAllocator.MakeUniqueArray<std::byte>(kMessageSize);
1043*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < 5; ++i) {
1044*84e33947SAndroid Build Coastguard Worker messageData[i] = static_cast<std::byte>(i + 1);
1045*84e33947SAndroid Build Coastguard Worker }
1046*84e33947SAndroid Build Coastguard Worker
1047*84e33947SAndroid Build Coastguard Worker MessageHubCallbackCallsMessageHubApisDuringCallback callback;
1048*84e33947SAndroid Build Coastguard Worker MessageHubCallbackCallsMessageHubApisDuringCallback callback2;
1049*84e33947SAndroid Build Coastguard Worker MessageHubCallbackCallsMessageHubApisDuringCallback callback3;
1050*84e33947SAndroid Build Coastguard Worker
1051*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
1052*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
1053*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
1054*84e33947SAndroid Build Coastguard Worker callback.setMessageHub(&messageHub.value());
1055*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub2 =
1056*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub2", /* id= */ 2, callback2);
1057*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2.has_value());
1058*84e33947SAndroid Build Coastguard Worker callback2.setMessageHub(&messageHub2.value());
1059*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub3 =
1060*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub3", /* id= */ 3, callback3);
1061*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub3.has_value());
1062*84e33947SAndroid Build Coastguard Worker callback3.setMessageHub(&messageHub3.value());
1063*84e33947SAndroid Build Coastguard Worker
1064*84e33947SAndroid Build Coastguard Worker // Open session from messageHub:1 to messageHub2:2
1065*84e33947SAndroid Build Coastguard Worker SessionId sessionId = messageHub->openSession(
1066*84e33947SAndroid Build Coastguard Worker kEndpointInfos[0].id, messageHub2->getId(), kEndpointInfos[1].id);
1067*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
1068*84e33947SAndroid Build Coastguard Worker
1069*84e33947SAndroid Build Coastguard Worker // Open session from messageHub2:2 to messageHub3:3
1070*84e33947SAndroid Build Coastguard Worker SessionId sessionId2 = messageHub2->openSession(
1071*84e33947SAndroid Build Coastguard Worker kEndpointInfos[1].id, messageHub3->getId(), kEndpointInfos[2].id);
1072*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
1073*84e33947SAndroid Build Coastguard Worker
1074*84e33947SAndroid Build Coastguard Worker // Open session from messageHub3:3 to messageHub1:1
1075*84e33947SAndroid Build Coastguard Worker SessionId sessionId3 = messageHub3->openSession(
1076*84e33947SAndroid Build Coastguard Worker kEndpointInfos[2].id, messageHub->getId(), kEndpointInfos[0].id);
1077*84e33947SAndroid Build Coastguard Worker EXPECT_NE(sessionId, SESSION_ID_INVALID);
1078*84e33947SAndroid Build Coastguard Worker
1079*84e33947SAndroid Build Coastguard Worker // Send message from messageHub:1 to messageHub2:2
1080*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub->sendMessage(std::move(messageData), kMessageSize,
1081*84e33947SAndroid Build Coastguard Worker /* messageType= */ 1,
1082*84e33947SAndroid Build Coastguard Worker /* messagePermissions= */ 0, sessionId));
1083*84e33947SAndroid Build Coastguard Worker
1084*84e33947SAndroid Build Coastguard Worker // Send message from messageHub2:2 to messageHub:1
1085*84e33947SAndroid Build Coastguard Worker messageData = mAllocator.MakeUniqueArray<std::byte>(kMessageSize);
1086*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < 5; ++i) {
1087*84e33947SAndroid Build Coastguard Worker messageData[i] = static_cast<std::byte>(i + 1);
1088*84e33947SAndroid Build Coastguard Worker }
1089*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2->sendMessage(std::move(messageData), kMessageSize,
1090*84e33947SAndroid Build Coastguard Worker /* messageType= */ 2,
1091*84e33947SAndroid Build Coastguard Worker /* messagePermissions= */ 3, sessionId));
1092*84e33947SAndroid Build Coastguard Worker
1093*84e33947SAndroid Build Coastguard Worker // Close all sessions
1094*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub->closeSession(sessionId));
1095*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub2->closeSession(sessionId2));
1096*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub3->closeSession(sessionId3));
1097*84e33947SAndroid Build Coastguard Worker
1098*84e33947SAndroid Build Coastguard Worker // If we finish the test, both callbacks should have been called
1099*84e33947SAndroid Build Coastguard Worker // If the router holds the lock during the callback, this test will timeout
1100*84e33947SAndroid Build Coastguard Worker }
1101*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,ForEachEndpointOfHub)1102*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, ForEachEndpointOfHub) {
1103*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
1104*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
1105*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
1106*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
1107*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
1108*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
1109*84e33947SAndroid Build Coastguard Worker
1110*84e33947SAndroid Build Coastguard Worker DynamicVector<EndpointInfo> endpoints;
1111*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(router.forEachEndpointOfHub(
1112*84e33947SAndroid Build Coastguard Worker /* messageHubId= */ 1, [&endpoints](const EndpointInfo &info) {
1113*84e33947SAndroid Build Coastguard Worker endpoints.push_back(info);
1114*84e33947SAndroid Build Coastguard Worker return false;
1115*84e33947SAndroid Build Coastguard Worker }));
1116*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(endpoints.size(), kNumEndpoints);
1117*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < endpoints.size(); ++i) {
1118*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(endpoints[i].id, kEndpointInfos[i].id);
1119*84e33947SAndroid Build Coastguard Worker EXPECT_STREQ(endpoints[i].name, kEndpointInfos[i].name);
1120*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(endpoints[i].version, kEndpointInfos[i].version);
1121*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(endpoints[i].type, kEndpointInfos[i].type);
1122*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(endpoints[i].requiredPermissions,
1123*84e33947SAndroid Build Coastguard Worker kEndpointInfos[i].requiredPermissions);
1124*84e33947SAndroid Build Coastguard Worker }
1125*84e33947SAndroid Build Coastguard Worker }
1126*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,ForEachEndpoint)1127*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, ForEachEndpoint) {
1128*84e33947SAndroid Build Coastguard Worker const char *kHubName = "hub1";
1129*84e33947SAndroid Build Coastguard Worker constexpr MessageHubId kHubId = 1;
1130*84e33947SAndroid Build Coastguard Worker
1131*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
1132*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
1133*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
1134*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
1135*84e33947SAndroid Build Coastguard Worker router.registerMessageHub(kHubName, kHubId, callback);
1136*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
1137*84e33947SAndroid Build Coastguard Worker
1138*84e33947SAndroid Build Coastguard Worker DynamicVector<std::pair<MessageHubInfo, EndpointInfo>> endpoints;
1139*84e33947SAndroid Build Coastguard Worker router.forEachEndpoint(
1140*84e33947SAndroid Build Coastguard Worker [&endpoints](const MessageHubInfo &hubInfo, const EndpointInfo &info) {
1141*84e33947SAndroid Build Coastguard Worker endpoints.push_back(std::make_pair(hubInfo, info));
1142*84e33947SAndroid Build Coastguard Worker });
1143*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(endpoints.size(), kNumEndpoints);
1144*84e33947SAndroid Build Coastguard Worker for (size_t i = 0; i < endpoints.size(); ++i) {
1145*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(endpoints[i].first.id, kHubId);
1146*84e33947SAndroid Build Coastguard Worker EXPECT_STREQ(endpoints[i].first.name, kHubName);
1147*84e33947SAndroid Build Coastguard Worker
1148*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(endpoints[i].second.id, kEndpointInfos[i].id);
1149*84e33947SAndroid Build Coastguard Worker EXPECT_STREQ(endpoints[i].second.name, kEndpointInfos[i].name);
1150*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(endpoints[i].second.version, kEndpointInfos[i].version);
1151*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(endpoints[i].second.type, kEndpointInfos[i].type);
1152*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(endpoints[i].second.requiredPermissions,
1153*84e33947SAndroid Build Coastguard Worker kEndpointInfos[i].requiredPermissions);
1154*84e33947SAndroid Build Coastguard Worker }
1155*84e33947SAndroid Build Coastguard Worker }
1156*84e33947SAndroid Build Coastguard Worker
TEST_F(MessageRouterTest,ForEachEndpointOfHubInvalidHub)1157*84e33947SAndroid Build Coastguard Worker TEST_F(MessageRouterTest, ForEachEndpointOfHubInvalidHub) {
1158*84e33947SAndroid Build Coastguard Worker MessageRouterWithStorage<kMaxMessageHubs, kMaxSessions> router;
1159*84e33947SAndroid Build Coastguard Worker MessageHubCallbackStoreData callback(/* message= */ nullptr,
1160*84e33947SAndroid Build Coastguard Worker /* session= */ nullptr);
1161*84e33947SAndroid Build Coastguard Worker std::optional<MessageRouter::MessageHub> messageHub =
1162*84e33947SAndroid Build Coastguard Worker router.registerMessageHub("hub1", /* id= */ 1, callback);
1163*84e33947SAndroid Build Coastguard Worker EXPECT_TRUE(messageHub.has_value());
1164*84e33947SAndroid Build Coastguard Worker
1165*84e33947SAndroid Build Coastguard Worker DynamicVector<EndpointInfo> endpoints;
1166*84e33947SAndroid Build Coastguard Worker EXPECT_FALSE(router.forEachEndpointOfHub(
1167*84e33947SAndroid Build Coastguard Worker /* messageHubId= */ 2, [&endpoints](const EndpointInfo &info) {
1168*84e33947SAndroid Build Coastguard Worker endpoints.push_back(info);
1169*84e33947SAndroid Build Coastguard Worker return false;
1170*84e33947SAndroid Build Coastguard Worker }));
1171*84e33947SAndroid Build Coastguard Worker EXPECT_EQ(endpoints.size(), 0);
1172*84e33947SAndroid Build Coastguard Worker }
1173*84e33947SAndroid Build Coastguard Worker
1174*84e33947SAndroid Build Coastguard Worker } // namespace
1175*84e33947SAndroid Build Coastguard Worker } // namespace chre::message
1176