• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "message_hub_manager.h"
18 
19 #include <cstddef>
20 #include <memory>
21 #include <random>
22 #include <unordered_map>
23 
24 #include <aidl/android/hardware/contexthub/IContextHub.h>
25 
26 #include "chre/platform/log.h"
27 
28 #include "gmock/gmock.h"
29 #include "gtest/gtest.h"
30 
31 namespace android::hardware::contexthub::common::implementation {
32 namespace {
33 
34 using ::aidl::android::hardware::contexthub::EndpointId;
35 using ::aidl::android::hardware::contexthub::EndpointInfo;
36 using ::aidl::android::hardware::contexthub::ErrorCode;
37 using ::aidl::android::hardware::contexthub::HubInfo;
38 using ::aidl::android::hardware::contexthub::IEndpointCallback;
39 using ::aidl::android::hardware::contexthub::Message;
40 using ::aidl::android::hardware::contexthub::MessageDeliveryStatus;
41 using ::aidl::android::hardware::contexthub::Reason;
42 using ::ndk::ScopedAStatus;
43 using ::ndk::SharedRefBase;
44 using ::ndk::SpAIBinder;
45 using ::testing::_;
46 using ::testing::AllOf;
47 using ::testing::AnyNumber;
48 using ::testing::Ge;
49 using ::testing::IsEmpty;
50 using ::testing::IsNull;
51 using ::testing::Le;
52 using ::testing::NiceMock;
53 using ::testing::Return;
54 using ::testing::UnorderedElementsAreArray;
55 
56 class MockEndpointCallback : public IEndpointCallback {
57  public:
58   MOCK_METHOD(ScopedAStatus, onEndpointStarted,
59               (const std::vector<EndpointInfo> &), (override));
60   MOCK_METHOD(ScopedAStatus, onEndpointStopped,
61               (const std::vector<EndpointId> &, Reason), (override));
62   MOCK_METHOD(ScopedAStatus, onMessageReceived, (int32_t, const Message &),
63               (override));
64   MOCK_METHOD(ScopedAStatus, onMessageDeliveryStatusReceived,
65               (int32_t, const MessageDeliveryStatus &), (override));
66   MOCK_METHOD(ScopedAStatus, onEndpointSessionOpenRequest,
67               (int32_t, const EndpointId &, const EndpointId &,
68                const std::optional<std::string> &),
69               (override));
70   MOCK_METHOD(ScopedAStatus, onCloseEndpointSession, (int32_t, Reason),
71               (override));
72   MOCK_METHOD(ScopedAStatus, onEndpointSessionOpenComplete, (int32_t),
73               (override));
74   MOCK_METHOD(SpAIBinder, asBinder, (), (override));
75   MOCK_METHOD(bool, isRemote, (), (override));
76   MOCK_METHOD(ScopedAStatus, getInterfaceVersion, (int32_t *), (override));
77   MOCK_METHOD(ScopedAStatus, getInterfaceHash, (std::string *), (override));
78 
MockEndpointCallback()79   MockEndpointCallback() {
80     ON_CALL(*this, onEndpointStarted)
81         .WillByDefault([](const std::vector<EndpointInfo> &) {
82           return ScopedAStatus::ok();
83         });
84     ON_CALL(*this, onEndpointStopped)
85         .WillByDefault([](const std::vector<EndpointId> &, Reason) {
86           return ScopedAStatus::ok();
87         });
88     ON_CALL(*this, onMessageReceived)
89         .WillByDefault(
90             [](int32_t, const Message &) { return ScopedAStatus::ok(); });
91     ON_CALL(*this, onMessageDeliveryStatusReceived)
92         .WillByDefault([](int32_t, const MessageDeliveryStatus &) {
93           return ScopedAStatus::ok();
94         });
95     ON_CALL(*this, onEndpointSessionOpenRequest)
96         .WillByDefault([](int32_t, const EndpointId &, const EndpointId &,
97                           const std::optional<std::string> &) {
98           return ScopedAStatus::ok();
99         });
100     ON_CALL(*this, onCloseEndpointSession).WillByDefault([](int32_t, Reason) {
101       return ScopedAStatus::ok();
102     });
103     ON_CALL(*this, onEndpointSessionOpenComplete).WillByDefault([](int32_t) {
104       return ScopedAStatus::ok();
105     });
106   }
107 };
108 
109 constexpr int64_t kHub1Id = 0x1, kHub2Id = 0x2;
110 constexpr int64_t kEndpoint1Id = 0x1, kEndpoint2Id = 0x2;
111 const std::string kTestServiceDescriptor = "test_service";
112 const HubInfo kHub1Info{.hubId = kHub1Id};
113 const HubInfo kHub2Info{.hubId = kHub2Id};
114 const Service kTestService{.serviceDescriptor = kTestServiceDescriptor};
115 const EndpointInfo kEndpoint1_1Info{
116     .id = {.id = kEndpoint1Id, .hubId = kHub1Id}};
117 const EndpointInfo kEndpoint1_2Info{
118     .id = {.id = kEndpoint2Id, .hubId = kHub1Id}, .services = {kTestService}};
119 const EndpointInfo kEndpoint2_1Info{
120     .id = {.id = kEndpoint1Id, .hubId = kHub2Id}};
121 const EndpointInfo kEndpoint2_2Info{
122     .id = {.id = kEndpoint2Id, .hubId = kHub2Id}, .services = {kTestService}};
123 
124 }  // namespace
125 
126 class MessageHubManagerTest : public ::testing::Test {
127  public:
128   using HostHub = MessageHubManager::HostHub;
129   using DeathRecipientCookie = HostHub::DeathRecipientCookie;
130   using HostHubDownCb = MessageHubManager::HostHubDownCb;
131 
132   static constexpr auto kSessionIdMaxRange = HostHub::kSessionIdMaxRange;
133   static constexpr auto kHostSessionIdBase =
134       MessageHubManager::kHostSessionIdBase;
135 
SetUp()136   void SetUp() override {
137     reinit([](std::function<pw::Result<int64_t>()>) { FAIL(); });
138   }
139 
TearDown()140   void TearDown() override {
141     mManager->forEachHostHub([](HostHub &hub) { delete hub.mCookie; });
142   }
143 
reinit(HostHubDownCb cb)144   void reinit(HostHubDownCb cb) {
145     auto deathRecipient = std::make_unique<NiceMock<MockDeathRecipient>>();
146     mDeathRecipient = deathRecipient.get();
147     ON_CALL(*deathRecipient, linkCallback(_, _))
148         .WillByDefault(Return(pw::OkStatus()));
149     ON_CALL(*deathRecipient, unlinkCallback(_, _))
150         .WillByDefault(Return(pw::OkStatus()));
151     mManager.reset(
152         new MessageHubManager(std::move(deathRecipient), std::move(cb)));
153   }
154 
onClientDeath(const std::shared_ptr<HostHub> & hub)155   void onClientDeath(const std::shared_ptr<HostHub> &hub) {
156     MessageHubManager::onClientDeath(hub->mCookie);
157   }
158 
setupDefaultHubs()159   void setupDefaultHubs() {
160     mManager->initEmbeddedState();
161     mManager->addEmbeddedHub(kHub2Info);
162     mManager->addEmbeddedEndpoint(kEndpoint2_1Info);
163     mManager->setEmbeddedEndpointReady(kEndpoint2_1Info.id);
164     mManager->addEmbeddedEndpoint(kEndpoint2_2Info);
165     mManager->setEmbeddedEndpointReady(kEndpoint2_2Info.id);
166     mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
167     mHostHub = *mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
168     EXPECT_TRUE(mHostHub->addEndpoint(kEndpoint1_1Info).ok());
169     EXPECT_TRUE(mHostHub->addEndpoint(kEndpoint1_2Info).ok());
170   }
171 
setupDefaultHubsAndSession()172   uint16_t setupDefaultHubsAndSession() {
173     setupDefaultHubs();
174     auto range = *mHostHub->reserveSessionIdRange(1);
175     EXPECT_TRUE(mHostHub
176                     ->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
177                                   range.first, {}, /*hostInitiated=*/true)
178                     .ok());
179     EXPECT_CALL(*mHostHubCb, onEndpointSessionOpenComplete(range.first));
180     EXPECT_TRUE(mManager->getHostHub(kHub1Id)
181                     ->ackSession(range.first,
182                                  /*hostAcked=*/false)
183                     .ok());
184     return range.first;
185   }
186 
187  protected:
188   class MockDeathRecipient : public MessageHubManager::DeathRecipient {
189    public:
190     MOCK_METHOD(pw::Status, linkCallback,
191                 (const std::shared_ptr<IEndpointCallback> &,
192                  DeathRecipientCookie *),
193                 (override));
194     MOCK_METHOD(pw::Status, unlinkCallback,
195                 (const std::shared_ptr<IEndpointCallback> &,
196                  DeathRecipientCookie *),
197                 (override));
198   };
199 
200   std::unique_ptr<MessageHubManager> mManager;
201   NiceMock<MockDeathRecipient> *mDeathRecipient;
202 
203   std::shared_ptr<HostHub> mHostHub;
204   std::shared_ptr<MockEndpointCallback> mHostHubCb;
205 };
206 
207 namespace {
208 
209 MATCHER_P(MatchSp, sp, "Matches an IEndpointCallback") {
210   return arg.get() == sp.get();
211 }
212 
TEST_F(MessageHubManagerTest,CreateAndUnregisterHostHub)213 TEST_F(MessageHubManagerTest, CreateAndUnregisterHostHub) {
214   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
215   DeathRecipientCookie *cookie;
216   EXPECT_CALL(*mDeathRecipient, linkCallback(MatchSp(mHostHubCb), _))
217       .WillOnce([&cookie](const std::shared_ptr<IEndpointCallback> &,
218                           DeathRecipientCookie *c) {
219         cookie = c;
220         return pw::OkStatus();
221       });
222   auto statusOrHub = mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
223   ASSERT_TRUE(statusOrHub.ok());
224 
225   mHostHub = *statusOrHub;
226   EXPECT_EQ(mHostHub->id(), kHub1Id);
227   EXPECT_EQ(mHostHub, mManager->getHostHub(kHub1Id));
228 
229   EXPECT_CALL(*mDeathRecipient, unlinkCallback(MatchSp(mHostHubCb), cookie))
230       .WillOnce(Return(pw::OkStatus()));
231   mHostHub->unregister();
232   EXPECT_EQ(mHostHub->unregister(), pw::Status::Aborted());
233   EXPECT_THAT(mManager->getHostHub(kHub1Id), IsNull());
234 }
235 
TEST_F(MessageHubManagerTest,CreateHostHubFails)236 TEST_F(MessageHubManagerTest, CreateHostHubFails) {
237   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
238   EXPECT_CALL(*mDeathRecipient, linkCallback(MatchSp(mHostHubCb), _))
239       .WillOnce(Return(pw::Status::Internal()));
240   EXPECT_FALSE(mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0).ok());
241 }
242 
TEST_F(MessageHubManagerTest,OnClientDeath)243 TEST_F(MessageHubManagerTest, OnClientDeath) {
244   bool unlinked = false;
245   reinit([&unlinked](std::function<pw::Result<int64_t>()> fn) {
246     auto statusOrHubId = fn();
247     ASSERT_TRUE(statusOrHubId.ok());
248     EXPECT_EQ(*statusOrHubId, kHub1Id);
249     unlinked = true;
250   });
251 
252   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
253   EXPECT_CALL(*mDeathRecipient, linkCallback(MatchSp(mHostHubCb), _))
254       .WillOnce(Return(pw::OkStatus()));
255   mHostHub = *mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
256   EXPECT_EQ(mHostHub->id(), kHub1Id);
257   EXPECT_EQ(mHostHub, mManager->getHostHub(kHub1Id));
258 
259   EXPECT_CALL(*mDeathRecipient, unlinkCallback(_, _)).Times(0);
260   onClientDeath(mHostHub);
261   EXPECT_THAT(mManager->getHostHub(kHub1Id), IsNull());
262 }
263 
TEST_F(MessageHubManagerTest,OnClientDeathAfterUnregister)264 TEST_F(MessageHubManagerTest, OnClientDeathAfterUnregister) {
265   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
266   mHostHub = *mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
267   mHostHub->unregister();
268   onClientDeath(mHostHub);
269 }
270 
TEST_F(MessageHubManagerTest,InitAndClearEmbeddedState)271 TEST_F(MessageHubManagerTest, InitAndClearEmbeddedState) {
272   mManager->addEmbeddedHub(kHub1Info);
273   EXPECT_THAT(mManager->getEmbeddedHubs(), IsEmpty());
274 
275   mManager->initEmbeddedState();
276   mManager->addEmbeddedHub(kHub1Info);
277   EXPECT_THAT(mManager->getEmbeddedHubs(),
278               UnorderedElementsAreArray({kHub1Info}));
279 
280   mManager->clearEmbeddedState();
281   EXPECT_THAT(mManager->getEmbeddedHubs(), IsEmpty());
282 }
283 
TEST_F(MessageHubManagerTest,AddAndRemoveEmbeddedHub)284 TEST_F(MessageHubManagerTest, AddAndRemoveEmbeddedHub) {
285   mManager->initEmbeddedState();
286   mManager->addEmbeddedHub(kHub1Info);
287   EXPECT_THAT(mManager->getEmbeddedHubs(),
288               UnorderedElementsAreArray({kHub1Info}));
289 
290   mManager->removeEmbeddedHub(kHub1Id);
291   EXPECT_THAT(mManager->getEmbeddedHubs(), IsEmpty());
292 }
293 
294 MATCHER_P(MatchEndpointInfo, info, "Matches an EndpointInfo") {
295   if (arg.id.id != info.id.id || arg.id.hubId != info.id.hubId ||
296       arg.services.size() != info.services.size()) {
297     return false;
298   }
299   for (size_t i = 0; i < arg.services.size(); ++i) {
300     if (arg.services[i].serviceDescriptor !=
301         info.services[i].serviceDescriptor) {
302       return false;
303     }
304   }
305   return true;
306 }
307 
TEST_F(MessageHubManagerTest,AddAndRemoveEmbeddedEndpoint)308 TEST_F(MessageHubManagerTest, AddAndRemoveEmbeddedEndpoint) {
309   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
310   auto hostHub = *mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
311   mManager->initEmbeddedState();
312   mManager->addEmbeddedHub(kHub2Info);
313 
314   mManager->addEmbeddedEndpoint({.id = kEndpoint2_2Info.id});
315   EXPECT_THAT(mManager->getEmbeddedEndpoints(), IsEmpty());
316 
317   mManager->addEmbeddedEndpointService(kEndpoint2_2Info.id,
318                                        kEndpoint2_2Info.services[0]);
319   EXPECT_THAT(mManager->getEmbeddedEndpoints(), IsEmpty());
320 
321   EXPECT_CALL(*mHostHubCb, onEndpointStarted(UnorderedElementsAreArray(
322                                {MatchEndpointInfo(kEndpoint2_2Info)})));
323   mManager->setEmbeddedEndpointReady(kEndpoint2_2Info.id);
324   EXPECT_THAT(mManager->getEmbeddedEndpoints(),
325               UnorderedElementsAreArray({MatchEndpointInfo(kEndpoint2_2Info)}));
326 
327   EXPECT_CALL(*mHostHubCb, onEndpointStopped(
328                                UnorderedElementsAreArray({kEndpoint2_2Info.id}),
329                                Reason::ENDPOINT_GONE));
330   mManager->removeEmbeddedEndpoint(kEndpoint2_2Info.id);
331   EXPECT_THAT(mManager->getEmbeddedEndpoints(), IsEmpty());
332 }
333 
TEST_F(MessageHubManagerTest,RemovingEmbeddedHubRemovesEndpoints)334 TEST_F(MessageHubManagerTest, RemovingEmbeddedHubRemovesEndpoints) {
335   mManager->initEmbeddedState();
336   mManager->addEmbeddedHub(kHub2Info);
337   mManager->addEmbeddedEndpoint(kEndpoint2_1Info);
338   mManager->setEmbeddedEndpointReady(kEndpoint2_1Info.id);
339   mManager->addEmbeddedEndpoint(kEndpoint2_2Info);
340   mManager->setEmbeddedEndpointReady(kEndpoint2_2Info.id);
341   EXPECT_THAT(mManager->getEmbeddedEndpoints(),
342               UnorderedElementsAreArray({MatchEndpointInfo(kEndpoint2_1Info),
343                                          MatchEndpointInfo(kEndpoint2_2Info)}));
344 
345   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
346   auto hostHub = *mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
347   EXPECT_CALL(*mHostHubCb,
348               onEndpointStopped(UnorderedElementsAreArray(
349                                     {kEndpoint2_1Info.id, kEndpoint2_2Info.id}),
350                                 Reason::HUB_RESET));
351   mManager->removeEmbeddedHub(kHub2Id);
352   EXPECT_THAT(mManager->getEmbeddedEndpoints(), IsEmpty());
353 }
354 
TEST_F(MessageHubManagerTest,AddEmbeddedEndpointForUnknownHub)355 TEST_F(MessageHubManagerTest, AddEmbeddedEndpointForUnknownHub) {
356   mManager->initEmbeddedState();
357   mManager->addEmbeddedEndpoint(kEndpoint1_1Info);
358   mManager->setEmbeddedEndpointReady(kEndpoint1_1Info.id);
359   EXPECT_THAT(mManager->getEmbeddedEndpoints(), IsEmpty());
360 }
361 
TEST_F(MessageHubManagerTest,AddAndRemoveHostEndpoint)362 TEST_F(MessageHubManagerTest, AddAndRemoveHostEndpoint) {
363   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
364   mHostHub = *mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
365 
366   EXPECT_TRUE(mHostHub->addEndpoint(kEndpoint1_1Info).ok());
367   EXPECT_THAT(mHostHub->getEndpoints(),
368               UnorderedElementsAreArray({kEndpoint1_1Info}));
369 
370   EXPECT_TRUE(mHostHub->removeEndpoint(kEndpoint1_1Info.id).ok());
371   EXPECT_THAT(mHostHub->getEndpoints(), IsEmpty());
372 }
373 
TEST_F(MessageHubManagerTest,AddDuplicateEndpoint)374 TEST_F(MessageHubManagerTest, AddDuplicateEndpoint) {
375   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
376   mHostHub = *mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
377   ASSERT_TRUE(mHostHub->addEndpoint(kEndpoint1_1Info).ok());
378   EXPECT_EQ(mHostHub->addEndpoint(kEndpoint1_1Info),
379             pw::Status::AlreadyExists());
380 }
381 
TEST_F(MessageHubManagerTest,RemoveNonexistentEndpoint)382 TEST_F(MessageHubManagerTest, RemoveNonexistentEndpoint) {
383   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
384   mHostHub = *mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
385   EXPECT_EQ(mHostHub->removeEndpoint(kEndpoint1_1Info.id).status(),
386             pw::Status::NotFound());
387 }
388 
TEST_F(MessageHubManagerTest,ReserveSessionIdRange)389 TEST_F(MessageHubManagerTest, ReserveSessionIdRange) {
390   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
391   mHostHub = *mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
392   std::random_device rand;
393   auto range = *mHostHub->reserveSessionIdRange(
394       std::uniform_int_distribution<size_t>(1, kSessionIdMaxRange)(rand));
395   EXPECT_THAT(range.second - range.first + 1,
396               AllOf(Ge(1), Le(kSessionIdMaxRange)));
397 }
398 
TEST_F(MessageHubManagerTest,ReserveBadSessionIdRange)399 TEST_F(MessageHubManagerTest, ReserveBadSessionIdRange) {
400   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
401   mHostHub = *mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
402   EXPECT_EQ(mHostHub->reserveSessionIdRange(0).status(),
403             pw::Status::InvalidArgument());
404   EXPECT_EQ(mHostHub->reserveSessionIdRange(kSessionIdMaxRange + 1).status(),
405             pw::Status::InvalidArgument());
406 }
407 
TEST_F(MessageHubManagerTest,ReserveSessionIdRangeFull)408 TEST_F(MessageHubManagerTest, ReserveSessionIdRangeFull) {
409   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
410   mHostHub = *mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
411   int iterations = (USHRT_MAX - kHostSessionIdBase + 1) / kSessionIdMaxRange;
412   for (int i = 0; i < iterations; ++i)
413     ASSERT_TRUE(mHostHub->reserveSessionIdRange(kSessionIdMaxRange).ok());
414   EXPECT_EQ(mHostHub->reserveSessionIdRange(kSessionIdMaxRange).status(),
415             pw::Status::ResourceExhausted());
416 }
417 
TEST_F(MessageHubManagerTest,OpenHostSessionRequest)418 TEST_F(MessageHubManagerTest, OpenHostSessionRequest) {
419   setupDefaultHubs();
420 
421   auto range = *mHostHub->reserveSessionIdRange(1);
422   EXPECT_TRUE(mHostHub
423                   ->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
424                                 range.first, {}, /*hostInitiated=*/true)
425                   .ok());
426   EXPECT_FALSE(mHostHub->checkSessionOpen(range.first).ok());
427 }
428 
TEST_F(MessageHubManagerTest,OpenHostSessionRequestBadSessionId)429 TEST_F(MessageHubManagerTest, OpenHostSessionRequestBadSessionId) {
430   setupDefaultHubs();
431 
432   auto range = *mHostHub->reserveSessionIdRange(1);
433   EXPECT_EQ(mHostHub->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
434                                   range.first + 1, {}, /*hostInitiated=*/true),
435             pw::Status::OutOfRange());
436 }
437 
TEST_F(MessageHubManagerTest,OpenEmbeddedSessionRequest)438 TEST_F(MessageHubManagerTest, OpenEmbeddedSessionRequest) {
439   setupDefaultHubs();
440 
441   static constexpr uint16_t kSessionId = 1;
442   std::optional<std::string> serviceDescriptor;
443   EXPECT_CALL(*mHostHubCb, onEndpointSessionOpenRequest(
444                                kSessionId, kEndpoint1_1Info.id,
445                                kEndpoint2_1Info.id, serviceDescriptor));
446   EXPECT_TRUE(mHostHub
447                   ->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
448                                 kSessionId, {}, /*hostInitiated=*/false)
449                   .ok());
450   EXPECT_FALSE(mHostHub->checkSessionOpen(kSessionId).ok());
451 }
452 
TEST_F(MessageHubManagerTest,OpenEmbeddedSessionRequestBadSessionId)453 TEST_F(MessageHubManagerTest, OpenEmbeddedSessionRequestBadSessionId) {
454   setupDefaultHubs();
455 
456   EXPECT_FALSE(mHostHub
457                    ->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
458                                  kHostSessionIdBase, {},
459                                  /*hostInitiated=*/false)
460                    .ok());
461   EXPECT_EQ(mHostHub->checkSessionOpen(kHostSessionIdBase),
462             pw::Status::NotFound());
463 }
464 
TEST_F(MessageHubManagerTest,OpenSessionRequestUnknownHostEndpoint)465 TEST_F(MessageHubManagerTest, OpenSessionRequestUnknownHostEndpoint) {
466   mManager->initEmbeddedState();
467   mManager->addEmbeddedHub(kHub2Info);
468   mManager->addEmbeddedEndpoint(kEndpoint2_1Info);
469   mManager->setEmbeddedEndpointReady(kEndpoint2_1Info.id);
470   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
471   mHostHub = *mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
472 
473   auto range = *mHostHub->reserveSessionIdRange(1);
474   EXPECT_EQ(mHostHub->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
475                                   range.first, {}, /*hostInitiated=*/true),
476             pw::Status::NotFound());
477 }
478 
TEST_F(MessageHubManagerTest,OpenSessionRequestUnknownEmbeddedEndpoint)479 TEST_F(MessageHubManagerTest, OpenSessionRequestUnknownEmbeddedEndpoint) {
480   mManager->initEmbeddedState();
481   mManager->addEmbeddedHub(kHub2Info);
482   mHostHubCb = SharedRefBase::make<MockEndpointCallback>();
483   mHostHub = *mManager->createHostHub(mHostHubCb, kHub1Info, 0, 0);
484   ASSERT_TRUE(mHostHub->addEndpoint(kEndpoint1_1Info).ok());
485 
486   auto range = *mHostHub->reserveSessionIdRange(1);
487   EXPECT_EQ(mHostHub->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
488                                   range.first, {}, /*hostInitiated=*/true),
489             pw::Status::NotFound());
490 }
491 
TEST_F(MessageHubManagerTest,OpenHostSessionRequestWithService)492 TEST_F(MessageHubManagerTest, OpenHostSessionRequestWithService) {
493   setupDefaultHubs();
494 
495   auto range = *mHostHub->reserveSessionIdRange(1);
496   uint16_t sessionId = range.first;
497   EXPECT_TRUE(mHostHub
498                   ->openSession(kEndpoint1_2Info.id, kEndpoint2_2Info.id,
499                                 sessionId, kTestServiceDescriptor,
500                                 /*hostInitiated=*/true)
501                   .ok());
502 }
503 
TEST_F(MessageHubManagerTest,OpenEmbeddedSessionRequestWithService)504 TEST_F(MessageHubManagerTest, OpenEmbeddedSessionRequestWithService) {
505   setupDefaultHubs();
506 
507   auto range = *mHostHub->reserveSessionIdRange(1);
508   uint16_t sessionId = range.first;
509   EXPECT_TRUE(mHostHub
510                   ->openSession(kEndpoint1_2Info.id, kEndpoint2_2Info.id,
511                                 sessionId, kTestServiceDescriptor,
512                                 /*hostInitiated=*/true)
513                   .ok());
514 }
515 
TEST_F(MessageHubManagerTest,OpenSessionWithServiceHostSideDoesNotSupport)516 TEST_F(MessageHubManagerTest, OpenSessionWithServiceHostSideDoesNotSupport) {
517   setupDefaultHubs();
518 
519   EXPECT_FALSE(mHostHub
520                    ->openSession(kEndpoint1_1Info.id, kEndpoint2_2Info.id,
521                                  kHostSessionIdBase, kTestServiceDescriptor,
522                                  /*hostInitiated=*/true)
523                    .ok());
524 }
525 
TEST_F(MessageHubManagerTest,OpenSessionWithServiceEmbeddedSideDoesNotSupport)526 TEST_F(MessageHubManagerTest,
527        OpenSessionWithServiceEmbeddedSideDoesNotSupport) {
528   setupDefaultHubs();
529 
530   EXPECT_FALSE(mHostHub
531                    ->openSession(kEndpoint1_2Info.id, kEndpoint2_1Info.id,
532                                  kHostSessionIdBase, kTestServiceDescriptor,
533                                  /*hostInitiated=*/true)
534                    .ok());
535 }
536 
TEST_F(MessageHubManagerTest,OpenSessionRequestServiceSupportedButNotUsed)537 TEST_F(MessageHubManagerTest, OpenSessionRequestServiceSupportedButNotUsed) {
538   setupDefaultHubs();
539 
540   std::optional<std::string> serviceDescriptor;
541   auto range = *mHostHub->reserveSessionIdRange(1);
542   uint16_t sessionId = range.first;
543   EXPECT_TRUE(mHostHub
544                   ->openSession(kEndpoint1_2Info.id, kEndpoint2_2Info.id,
545                                 sessionId, serviceDescriptor,
546                                 /*hostInitiated=*/true)
547                   .ok());
548 }
549 
TEST_F(MessageHubManagerTest,OpenHostSessionEmbeddedEndpointAccepts)550 TEST_F(MessageHubManagerTest, OpenHostSessionEmbeddedEndpointAccepts) {
551   auto sessionId = setupDefaultHubsAndSession();
552   EXPECT_TRUE(mHostHub->checkSessionOpen(sessionId).ok());
553 }
554 
TEST_F(MessageHubManagerTest,OpenHostSessionEmbeddedEndpointRejects)555 TEST_F(MessageHubManagerTest, OpenHostSessionEmbeddedEndpointRejects) {
556   setupDefaultHubs();
557   auto range = *mHostHub->reserveSessionIdRange(1);
558   ASSERT_TRUE(mHostHub
559                   ->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
560                                 range.first, {}, /*hostInitiated=*/true)
561                   .ok());
562 
563   EXPECT_CALL(*mHostHubCb,
564               onCloseEndpointSession(
565                   range.first, Reason::OPEN_ENDPOINT_SESSION_REQUEST_REJECTED));
566   EXPECT_TRUE(mManager->getHostHub(kHub1Id)
567                   ->closeSession(range.first,
568                                  Reason::OPEN_ENDPOINT_SESSION_REQUEST_REJECTED)
569                   .ok());
570   EXPECT_EQ(mHostHub->checkSessionOpen(range.first), pw::Status::NotFound());
571 }
572 
TEST_F(MessageHubManagerTest,OpenHostSessionHostTriesToAck)573 TEST_F(MessageHubManagerTest, OpenHostSessionHostTriesToAck) {
574   setupDefaultHubs();
575   auto range = *mHostHub->reserveSessionIdRange(1);
576   ASSERT_TRUE(mHostHub
577                   ->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
578                                 range.first, {}, /*hostInitiated=*/true)
579                   .ok());
580 
581   EXPECT_FALSE(mHostHub->ackSession(range.first, /*hostAcked=*/true).ok());
582 }
583 
TEST_F(MessageHubManagerTest,OpenEmbeddedSessionHostEndpointAccepts)584 TEST_F(MessageHubManagerTest, OpenEmbeddedSessionHostEndpointAccepts) {
585   setupDefaultHubs();
586   static constexpr uint16_t kSessionId = 1;
587   EXPECT_CALL(*mHostHubCb, onEndpointSessionOpenRequest(kSessionId, _, _, _));
588   ASSERT_TRUE(mHostHub
589                   ->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
590                                 kSessionId, {}, /*hostInitiated=*/false)
591                   .ok());
592 
593   EXPECT_TRUE(mHostHub->ackSession(kSessionId, /*hostAcked=*/true).ok());
594   EXPECT_FALSE(mHostHub->checkSessionOpen(kSessionId).ok());
595 }
596 
TEST_F(MessageHubManagerTest,OpenEmbeddedSessionMessageRouterTriesToAck)597 TEST_F(MessageHubManagerTest, OpenEmbeddedSessionMessageRouterTriesToAck) {
598   setupDefaultHubs();
599   static constexpr uint16_t kSessionId = 1;
600   EXPECT_CALL(*mHostHubCb, onEndpointSessionOpenRequest(kSessionId, _, _, _));
601   ASSERT_TRUE(mHostHub
602                   ->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
603                                 kSessionId, {}, /*hostInitiated=*/false)
604                   .ok());
605 
606   EXPECT_FALSE(mHostHub->ackSession(kSessionId, /*hostAcked=*/false).ok());
607 }
608 
TEST_F(MessageHubManagerTest,OpenEmbeddedSessionPrunePendingSession)609 TEST_F(MessageHubManagerTest, OpenEmbeddedSessionPrunePendingSession) {
610   setupDefaultHubs();
611   static constexpr uint16_t kSessionId = 1;
612   EXPECT_CALL(*mHostHubCb, onEndpointSessionOpenRequest(kSessionId, _, _, _));
613   EXPECT_TRUE(mHostHub
614                   ->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
615                                 kSessionId, {}, /*hostInitiated=*/false)
616                   .ok());
617   EXPECT_TRUE(mHostHub->ackSession(kSessionId, /*hostAcked=*/true).ok());
618 
619   EXPECT_CALL(*mHostHubCb, onCloseEndpointSession(kSessionId, _));
620   EXPECT_CALL(*mHostHubCb, onEndpointSessionOpenRequest(kSessionId, _, _, _));
621   EXPECT_TRUE(mHostHub
622                   ->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
623                                 kSessionId, {}, /*hostInitiated=*/false)
624                   .ok());
625 }
626 
TEST_F(MessageHubManagerTest,OpenEmbeddedSessionMessageRouterAcks)627 TEST_F(MessageHubManagerTest, OpenEmbeddedSessionMessageRouterAcks) {
628   setupDefaultHubs();
629   static constexpr uint16_t kSessionId = 1;
630   EXPECT_CALL(*mHostHubCb, onEndpointSessionOpenRequest(kSessionId, _, _, _));
631   ASSERT_TRUE(mHostHub
632                   ->openSession(kEndpoint1_1Info.id, kEndpoint2_1Info.id,
633                                 kSessionId, {}, /*hostInitiated=*/false)
634                   .ok());
635   ASSERT_TRUE(mHostHub->ackSession(kSessionId, /*hostAcked=*/true).ok());
636 
637   EXPECT_TRUE(mHostHub->ackSession(kSessionId, /*hostAcked=*/false).ok());
638   EXPECT_TRUE(mHostHub->checkSessionOpen(kSessionId).ok());
639 }
640 
TEST_F(MessageHubManagerTest,ActiveSessionEmbeddedHubGone)641 TEST_F(MessageHubManagerTest, ActiveSessionEmbeddedHubGone) {
642   auto sessionId = setupDefaultHubsAndSession();
643 
644   EXPECT_CALL(*mHostHubCb,
645               onCloseEndpointSession(sessionId, Reason::HUB_RESET));
646   EXPECT_CALL(*mHostHubCb,
647               onEndpointStopped(UnorderedElementsAreArray(
648                                     {kEndpoint2_1Info.id, kEndpoint2_2Info.id}),
649                                 Reason::HUB_RESET));
650   mManager->removeEmbeddedHub(kHub2Id);
651   EXPECT_EQ(mHostHub->checkSessionOpen(sessionId), pw::Status::NotFound());
652 }
653 
TEST_F(MessageHubManagerTest,ActiveSessionEmbeddedEndpointGone)654 TEST_F(MessageHubManagerTest, ActiveSessionEmbeddedEndpointGone) {
655   auto sessionId = setupDefaultHubsAndSession();
656 
657   EXPECT_CALL(*mHostHubCb,
658               onCloseEndpointSession(sessionId, Reason::ENDPOINT_GONE));
659   EXPECT_CALL(*mHostHubCb, onEndpointStopped(
660                                UnorderedElementsAreArray({kEndpoint2_1Info.id}),
661                                Reason::ENDPOINT_GONE));
662   mManager->removeEmbeddedEndpoint(kEndpoint2_1Info.id);
663   EXPECT_EQ(mHostHub->checkSessionOpen(sessionId), pw::Status::NotFound());
664 }
665 
TEST_F(MessageHubManagerTest,ActiveSessionHostEndpointGone)666 TEST_F(MessageHubManagerTest, ActiveSessionHostEndpointGone) {
667   auto sessionId = setupDefaultHubsAndSession();
668 
669   EXPECT_THAT(*mHostHub->removeEndpoint(kEndpoint1_1Info.id),
670               UnorderedElementsAreArray({sessionId}));
671   EXPECT_EQ(mHostHub->checkSessionOpen(sessionId), pw::Status::NotFound());
672 }
673 
TEST_F(MessageHubManagerTest,HandleMessage)674 TEST_F(MessageHubManagerTest, HandleMessage) {
675   auto sessionId = setupDefaultHubsAndSession();
676 
677   Message message{.content = {0xde, 0xad, 0xbe, 0xef}};
678   EXPECT_CALL(*mHostHubCb, onMessageReceived(sessionId, message));
679   EXPECT_TRUE(mHostHub->handleMessage(sessionId, message).ok());
680 }
681 
TEST_F(MessageHubManagerTest,HandleMessageForUnknownSession)682 TEST_F(MessageHubManagerTest, HandleMessageForUnknownSession) {
683   setupDefaultHubs();
684 
685   Message message{.content = {0xde, 0xad, 0xbe, 0xef}};
686   EXPECT_CALL(*mHostHubCb, onMessageReceived(_, _)).Times(0);
687   EXPECT_FALSE(mHostHub->handleMessage(1, message).ok());
688 }
689 
TEST_F(MessageHubManagerTest,HandleMessageDeliveryStatus)690 TEST_F(MessageHubManagerTest, HandleMessageDeliveryStatus) {
691   auto sessionId = setupDefaultHubsAndSession();
692 
693   MessageDeliveryStatus status{.errorCode = ErrorCode::TRANSIENT_ERROR};
694   EXPECT_CALL(*mHostHubCb, onMessageDeliveryStatusReceived(sessionId, status));
695   EXPECT_TRUE(mHostHub->handleMessageDeliveryStatus(sessionId, status).ok());
696 }
697 
TEST_F(MessageHubManagerTest,HandleMessageDeliveryStatusForUnknownSession)698 TEST_F(MessageHubManagerTest, HandleMessageDeliveryStatusForUnknownSession) {
699   setupDefaultHubs();
700 
701   MessageDeliveryStatus status{.errorCode = ErrorCode::TRANSIENT_ERROR};
702   EXPECT_CALL(*mHostHubCb, onMessageDeliveryStatusReceived(_, _)).Times(0);
703   EXPECT_FALSE(mHostHub->handleMessageDeliveryStatus(1, status).ok());
704 }
705 
706 }  // namespace
707 }  // namespace android::hardware::contexthub::common::implementation
708