xref: /aosp_15_r20/system/chre/host/test/hal_generic/common/hal_client_manager_test.cc (revision 84e339476a462649f82315436d70fd732297a399)
1 /*
2  * Copyright (C) 2023 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 <array>
18 #include <chrono>
19 #include <cstdlib>
20 #include <fstream>
21 #include <optional>
22 #include <thread>
23 
24 #include <json/json.h>
25 
26 #include <aidl/android/hardware/contexthub/BnContextHubCallback.h>
27 #include <aidl/android/hardware/contexthub/IContextHub.h>
28 #include <aidl/android/hardware/contexthub/NanoappBinary.h>
29 #include "chre/platform/shared/host_protocol_common.h"
30 #include "gmock/gmock.h"
31 #include "gtest/gtest.h"
32 #include "hal_client_manager.h"
33 
34 namespace android::hardware::contexthub::common::implementation {
35 
36 namespace {
37 using aidl::android::hardware::contexthub::AsyncEventType;
38 using aidl::android::hardware::contexthub::BnContextHubCallback;
39 using aidl::android::hardware::contexthub::ContextHubMessage;
40 using aidl::android::hardware::contexthub::MessageDeliveryStatus;
41 using aidl::android::hardware::contexthub::NanoappInfo;
42 using aidl::android::hardware::contexthub::NanSessionRequest;
43 
44 using ndk::ScopedAStatus;
45 
46 using ::testing::_;
47 using ::testing::ByMove;
48 using ::testing::Eq;
49 using ::testing::IsEmpty;
50 using ::testing::Optional;
51 using ::testing::Return;
52 using ::testing::SizeIs;
53 using ::testing::UnorderedElementsAre;
54 
55 using HalClient = HalClientManager::Client;
56 
57 constexpr pid_t kSystemServerPid = 1000;
58 // The uuid assigned to ContextHubService
59 const std::string kSystemServerUuid = "9a17008d6bf1445a90116d21bd985b6c";
60 
61 constexpr pid_t kVendorPid = 1001;
62 const std::string kVendorUuid = "6e406b36cf4f4c0d8183db3708f45d8f";
63 
64 const std::string kClientIdMappingFilePath = "./chre_hal_clients.json";
65 const std::string kClientName = "HalClientManagerTest";
66 
67 class ContextHubCallbackForTest : public BnContextHubCallback {
68  public:
ContextHubCallbackForTest(const std::string & uuid)69   explicit ContextHubCallbackForTest(const std::string &uuid) {
70     assert(uuid.length() == 32);  // 2 digits for one bytes x 16 bytes
71     for (int i = 0; i < 16; i++) {
72       mUuid[i] = strtol(uuid.substr(i * 2, 2).c_str(), /* end_ptr= */ nullptr,
73                         /* base= */ 16);
74     }
75     ON_CALL(*this, handleContextHubAsyncEvent(_))
76         .WillByDefault(Return(ByMove(ScopedAStatus::ok())));
77   }
handleNanoappInfo(const std::vector<NanoappInfo> &)78   ScopedAStatus handleNanoappInfo(
79       const std::vector<NanoappInfo> & /*appInfo*/) override {
80     return ScopedAStatus::ok();
81   }
82 
handleContextHubMessage(const ContextHubMessage &,const std::vector<std::string> &)83   ScopedAStatus handleContextHubMessage(
84       const ContextHubMessage & /*message*/,
85       const std::vector<std::string> & /*msgContentPerms*/) override {
86     return ScopedAStatus::ok();
87   }
88 
89   MOCK_METHOD(ScopedAStatus, handleContextHubAsyncEvent, (AsyncEventType event),
90               (override));
91 
92   // Called after loading/unloading a nanoapp.
handleTransactionResult(int32_t,bool)93   ScopedAStatus handleTransactionResult(int32_t /*transactionId*/,
94                                         bool /*success*/) override {
95     return ScopedAStatus::ok();
96   }
97 
handleNanSessionRequest(const NanSessionRequest &)98   ScopedAStatus handleNanSessionRequest(
99       const NanSessionRequest & /* request */) override {
100     return ScopedAStatus::ok();
101   }
102 
handleMessageDeliveryStatus(char16_t,const MessageDeliveryStatus &)103   ScopedAStatus handleMessageDeliveryStatus(
104       char16_t /* hostEndPointId */,
105       const MessageDeliveryStatus & /* messageDeliveryStatus */) override {
106     return ScopedAStatus::ok();
107   }
108 
getUuid(std::array<uint8_t,16> * out_uuid)109   ScopedAStatus getUuid(std::array<uint8_t, 16> *out_uuid) override {
110     *out_uuid = mUuid;
111     return ScopedAStatus::ok();
112   }
113 
getName(std::string * out_name)114   ScopedAStatus getName(std::string *out_name) override {
115     *out_name = kClientName;
116     return ScopedAStatus::ok();
117   }
118 
119  private:
120   const std::string kClientName = "HalClientManagerUnitTest";
121   std::array<uint8_t, 16> mUuid{};
122 };
123 
124 class HalClientManagerForTest : public HalClientManager {
125  public:
HalClientManagerForTest(DeadClientUnlinker deadClientUnlinker,const std::string & clientIdMappingFilePath,const std::unordered_set<HalClientId> & reservedClientIds={})126   HalClientManagerForTest(
127       DeadClientUnlinker deadClientUnlinker,
128       const std::string &clientIdMappingFilePath,
129       const std::unordered_set<HalClientId> &reservedClientIds = {})
130       : HalClientManager(std::move(deadClientUnlinker), clientIdMappingFilePath,
131                          reservedClientIds) {}
132 
getClients()133   const std::vector<Client> getClients() {
134     return mClients;
135   }
136 
createClientForTest(const std::string & uuid,pid_t pid)137   bool createClientForTest(const std::string &uuid, pid_t pid) {
138     // No need to hold the lock during a unit test which is single-threaded
139     std::shared_ptr<ContextHubCallbackForTest> callback =
140         ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
141             kSystemServerUuid);
142     return createClient(uuid, pid, callback,
143                         /* deathRecipientCookie= */ nullptr);
144   }
145 
getNextClientId()146   HalClientId getNextClientId() {
147     return mNextClientId;
148   }
149 
getTransactionTimeoutSeconds()150   static int64_t getTransactionTimeoutSeconds() {
151     return kTransactionTimeoutThresholdMs / 1000;
152   }
153 
getClientIdTag()154   static const char *getClientIdTag() {
155     return kJsonClientId;
156   }
157 
getUuidTag()158   static const char *getUuidTag() {
159     return kJsonUuid;
160   }
161 
getNameTag()162   static const char *getNameTag() {
163     return kJsonName;
164   }
165 };
166 
167 class HalClientManagerTest : public ::testing::Test {
168  protected:
SetUp()169   void SetUp() override {
170     // Clears out the mapping file content
171     std::ofstream file(kClientIdMappingFilePath);
172     ASSERT_TRUE(file.good());
173   }
TearDown()174   void TearDown() override {}
175 };
176 
177 auto mockDeadClientUnlinker =
178     [](const std::shared_ptr<IContextHubCallback> & /*callback*/,
__anonecb3b08e0202(const std::shared_ptr<IContextHubCallback> & , void * ) 179        void * /*deathRecipientCookie*/) { return true; };
180 
createLoadTransaction(uint32_t transactionId)181 std::unique_ptr<FragmentedLoadTransaction> createLoadTransaction(
182     uint32_t transactionId) {
183   uint64_t appId = 0x476f6f676cabcdef;
184   uint32_t appVersion = 2;
185   uint32_t appFlags = 3;
186   uint32_t targetApiVersion = 4;
187   std::vector<uint8_t> binary = {0xf0, 0xf1};
188   return std::make_unique<FragmentedLoadTransaction>(
189       transactionId, appId, appVersion, appFlags, targetApiVersion, binary,
190       /* fragmentSize= */ 2048);
191 }
192 
TEST_F(HalClientManagerTest,ClientIdMappingFile)193 TEST_F(HalClientManagerTest, ClientIdMappingFile) {
194   HalClientId systemClientId = 100;
195   {
196     // Write systemClientId into the mapping file
197     Json::Value mappings;
198     Json::Value mapping;
199     mapping[HalClientManagerForTest::getClientIdTag()] = systemClientId;
200     mapping[HalClientManagerForTest::getUuidTag()] = kSystemServerUuid;
201     mapping[HalClientManagerForTest::getNameTag()] = kClientName;
202     mappings.append(mapping);
203     Json::StreamWriterBuilder factory;
204     std::unique_ptr<Json::StreamWriter> const writer(factory.newStreamWriter());
205     std::ofstream fileStream(kClientIdMappingFilePath);
206     writer->write(mappings, &fileStream);
207     fileStream << std::endl;
208   }
209 
210   auto halClientManager = std::make_unique<HalClientManagerForTest>(
211       mockDeadClientUnlinker, kClientIdMappingFilePath);
212   std::shared_ptr<ContextHubCallbackForTest> callback =
213       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
214           kSystemServerUuid);
215   EXPECT_TRUE(
216       halClientManager->registerCallback(kSystemServerPid, callback,
217                                          /* deathRecipientCookie= */ nullptr));
218 
219   std::vector<HalClient> clients = halClientManager->getClients();
220   const HalClient &client = clients.front();
221   EXPECT_THAT(clients, SizeIs(1));
222   EXPECT_THAT(client.endpointIds, IsEmpty());
223   EXPECT_EQ(client.callback, callback);
224   EXPECT_EQ(client.uuid, kSystemServerUuid);
225   EXPECT_EQ(client.pid, kSystemServerPid);
226   // The client id allocated should be the one specified in the mapping file
227   EXPECT_EQ(client.clientId, systemClientId);
228 }
229 
TEST_F(HalClientManagerTest,CallbackRegistryBasic)230 TEST_F(HalClientManagerTest, CallbackRegistryBasic) {
231   auto halClientManager = std::make_unique<HalClientManagerForTest>(
232       mockDeadClientUnlinker, kClientIdMappingFilePath);
233   std::shared_ptr<ContextHubCallbackForTest> callback =
234       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
235           kSystemServerUuid);
236 
237   EXPECT_TRUE(
238       halClientManager->registerCallback(kSystemServerPid, callback,
239                                          /* deathRecipientCookie= */ nullptr));
240 
241   std::vector<HalClient> clients = halClientManager->getClients();
242   const HalClient &client = clients.front();
243 
244   EXPECT_THAT(clients, SizeIs(1));
245   EXPECT_THAT(client.endpointIds, IsEmpty());
246   EXPECT_EQ(client.callback, callback);
247   EXPECT_EQ(client.uuid, kSystemServerUuid);
248   EXPECT_EQ(client.pid, kSystemServerPid);
249   EXPECT_NE(client.clientId, ::chre::kHostClientIdUnspecified);
250 }
251 
TEST_F(HalClientManagerTest,CallbackRegistryTwiceFromSameClient)252 TEST_F(HalClientManagerTest, CallbackRegistryTwiceFromSameClient) {
253   auto halClientManager = std::make_unique<HalClientManagerForTest>(
254       mockDeadClientUnlinker, kClientIdMappingFilePath);
255   std::shared_ptr<ContextHubCallbackForTest> callbackA =
256       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
257           kSystemServerUuid);
258   std::shared_ptr<ContextHubCallbackForTest> callbackB =
259       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
260           kSystemServerUuid);
261 
262   EXPECT_TRUE(
263       halClientManager->registerCallback(kSystemServerPid, callbackA,
264                                          /* deathRecipientCookie= */ nullptr));
265   EXPECT_THAT(halClientManager->getClients(), SizeIs(1));
266   EXPECT_EQ(halClientManager->getClients().front().callback, callbackA);
267   // Same client can override its callback
268   EXPECT_TRUE(
269       halClientManager->registerCallback(kSystemServerPid, callbackB,
270                                          /* deathRecipientCookie= */ nullptr));
271   EXPECT_THAT(halClientManager->getClients(), SizeIs(1));
272   EXPECT_EQ(halClientManager->getClients().front().callback, callbackB);
273 }
274 
TEST_F(HalClientManagerTest,CallbackRetrievalByEndpoint)275 TEST_F(HalClientManagerTest, CallbackRetrievalByEndpoint) {
276   auto halClientManager = std::make_unique<HalClientManagerForTest>(
277       mockDeadClientUnlinker, kClientIdMappingFilePath);
278   std::shared_ptr<ContextHubCallbackForTest> systemCallback =
279       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
280           kSystemServerUuid);
281   std::shared_ptr<ContextHubCallbackForTest> vendorCallback =
282       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(kVendorUuid);
283   uint16_t vendorEndpointId = 1;
284   uint16_t systemServerEndpointId = 1;
285 
286   // Register the callbacks and endpoint ids
287   EXPECT_TRUE(halClientManager->registerCallback(
288       kSystemServerPid, systemCallback, /* deathRecipientCookie= */ nullptr));
289   EXPECT_TRUE(halClientManager->registerEndpointId(kSystemServerPid,
290                                                    systemServerEndpointId));
291   EXPECT_TRUE(halClientManager->registerCallback(
292       kVendorPid, vendorCallback, /* deathRecipientCookie= */ nullptr));
293   EXPECT_TRUE(
294       halClientManager->registerEndpointId(kVendorPid, vendorEndpointId));
295 
296   // Though endpoint ids have the same value, they should be mutated before
297   // getting sent to CHRE and mapped to different callbacks
298   EXPECT_TRUE(halClientManager->mutateEndpointIdFromHostIfNeeded(
299       kVendorPid, vendorEndpointId));
300   EXPECT_TRUE(halClientManager->mutateEndpointIdFromHostIfNeeded(
301       kSystemServerPid, systemServerEndpointId));
302   EXPECT_EQ(halClientManager->getCallbackForEndpoint(vendorEndpointId),
303             vendorCallback);
304   EXPECT_EQ(halClientManager->getCallbackForEndpoint(systemServerEndpointId),
305             systemCallback);
306 }
307 
TEST_F(HalClientManagerTest,ClientCreation)308 TEST_F(HalClientManagerTest, ClientCreation) {
309   auto halClientManager = std::make_unique<HalClientManagerForTest>(
310       mockDeadClientUnlinker, kClientIdMappingFilePath);
311   int uuid = 1;
312   int pid = 1;
313   for (int i = 0; i < kMaxNumOfHalClients; i++, uuid++, pid++) {
314     EXPECT_TRUE(
315         halClientManager->createClientForTest(std::to_string(uuid), pid));
316   }
317   // if max number of clients are reached no more client can be created
318   EXPECT_FALSE(
319       halClientManager->createClientForTest(std::to_string(uuid), pid));
320   // mNextClientId is reset to ::chre::kHostClientIdUnspecified when new client
321   // is not accepted
322   EXPECT_EQ(halClientManager->getNextClientId(),
323             ::chre::kHostClientIdUnspecified);
324 }
325 
TEST_F(HalClientManagerTest,ClientCreationWithReservedClientId)326 TEST_F(HalClientManagerTest, ClientCreationWithReservedClientId) {
327   std::unordered_set<HalClientId> reservedClientIds{
328       ::chre::kHostClientIdUnspecified + 1, 64};
329   auto halClientManager = std::make_unique<HalClientManagerForTest>(
330       mockDeadClientUnlinker, kClientIdMappingFilePath, reservedClientIds);
331   int uuid = 1;
332   int pid = 1;
333   for (int i = 0; i < kMaxNumOfHalClients - reservedClientIds.size();
334        i++, uuid++, pid++) {
335     EXPECT_TRUE(
336         halClientManager->createClientForTest(std::to_string(uuid), pid));
337   }
338   // if max number of clients are reached no more client can be created
339   EXPECT_FALSE(
340       halClientManager->createClientForTest(std::to_string(uuid), pid));
341   // mNextClientId is reset to ::chre::kHostClientIdUnspecified when new client
342   // is not accepted
343   EXPECT_EQ(halClientManager->getNextClientId(),
344             ::chre::kHostClientIdUnspecified);
345   // Verify that every reserved client id is not used:
346   for (const HalClient &client : halClientManager->getClients()) {
347     EXPECT_EQ(reservedClientIds.find(client.clientId), reservedClientIds.end());
348   }
349 }
350 
TEST_F(HalClientManagerTest,TransactionRegistryAndOverridden)351 TEST_F(HalClientManagerTest, TransactionRegistryAndOverridden) {
352   auto halClientManager = std::make_unique<HalClientManagerForTest>(
353       mockDeadClientUnlinker, kClientIdMappingFilePath);
354   std::shared_ptr<ContextHubCallbackForTest> callback =
355       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
356           kSystemServerUuid);
357   EXPECT_TRUE(halClientManager->registerCallback(
358       kSystemServerPid, callback, /* deathRecipientCookie= */ nullptr));
359 
360   EXPECT_TRUE(halClientManager->registerPendingLoadTransaction(
361       kSystemServerPid, createLoadTransaction(/* transactionId= */ 1)));
362 
363   // Immediate transaction overridden is not allowed as each transaction is
364   // given a certain amount of time to finish
365   EXPECT_FALSE(halClientManager->registerPendingLoadTransaction(
366       kSystemServerPid, createLoadTransaction(/* transactionId= */ 2)));
367 
368   // Wait until the transaction is timed out to override it
369   std::this_thread::sleep_for(std::chrono::seconds(
370       HalClientManagerForTest::getTransactionTimeoutSeconds()));
371   EXPECT_TRUE(halClientManager->registerPendingLoadTransaction(
372       kSystemServerPid, createLoadTransaction(/* transactionId= */ 3)));
373 }
374 
TEST_F(HalClientManagerTest,TransactionRegistryLoadAndUnload)375 TEST_F(HalClientManagerTest, TransactionRegistryLoadAndUnload) {
376   auto halClientManager = std::make_unique<HalClientManagerForTest>(
377       mockDeadClientUnlinker, kClientIdMappingFilePath);
378   std::shared_ptr<ContextHubCallbackForTest> callback =
379       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
380           kSystemServerUuid);
381   EXPECT_TRUE(halClientManager->registerCallback(
382       kSystemServerPid, callback, /* deathRecipientCookie= */ nullptr));
383 
384   EXPECT_TRUE(halClientManager->registerPendingUnloadTransaction(
385       kSystemServerPid, /* transactionId= */ 1, /* nanoappId= */ 2));
386 
387   // Load and unload transaction can't coexist because unloading a nanoapp that
388   // is being loaded can cause problems.
389   EXPECT_FALSE(halClientManager->registerPendingLoadTransaction(
390       kSystemServerPid, createLoadTransaction(/* transactionId= */ 2)));
391 
392   // Clears out the pending unload transaction to register a new one.
393   halClientManager->resetPendingUnloadTransaction(
394       halClientManager->getClientId(kSystemServerPid), /* transactionId= */ 1);
395   EXPECT_TRUE(halClientManager->registerPendingLoadTransaction(
396       kSystemServerPid, createLoadTransaction(/* transactionId= */ 2)));
397 }
398 
TEST_F(HalClientManagerTest,EndpointRegistry)399 TEST_F(HalClientManagerTest, EndpointRegistry) {
400   auto halClientManager = std::make_unique<HalClientManagerForTest>(
401       mockDeadClientUnlinker, kClientIdMappingFilePath);
402   std::shared_ptr<ContextHubCallbackForTest> systemCallback =
403       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
404           kSystemServerUuid);
405   std::shared_ptr<ContextHubCallbackForTest> vendorCallback =
406       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(kVendorUuid);
407 
408   EXPECT_THAT(halClientManager->getAllConnectedEndpoints(kSystemServerPid),
409               Eq(std::nullopt));
410   halClientManager->registerCallback(kSystemServerPid, systemCallback,
411                                      /* deathRecipientCookie= */ nullptr);
412   halClientManager->registerCallback(kVendorPid, vendorCallback,
413                                      /* deathRecipientCookie= */ nullptr);
414 
415   std::vector<HalClient> clients = halClientManager->getClients();
416   EXPECT_THAT(clients, SizeIs(2));
417   EXPECT_THAT(halClientManager->getAllConnectedEndpoints(kSystemServerPid),
418               Optional(IsEmpty()));
419   EXPECT_THAT(halClientManager->getAllConnectedEndpoints(kVendorPid),
420               Optional(IsEmpty()));
421 
422   // only system server can register endpoint ids > 63.
423   EXPECT_TRUE(halClientManager->registerEndpointId(kSystemServerPid,
424                                                    /* endpointId= */ 64));
425   EXPECT_THAT(halClientManager->getAllConnectedEndpoints(kSystemServerPid),
426               Optional(UnorderedElementsAre(64)));
427 
428   EXPECT_TRUE(halClientManager->registerEndpointId(kVendorPid,
429                                                    /*endpointId= */ 63));
430   EXPECT_FALSE(halClientManager->registerEndpointId(kVendorPid,
431                                                     /* endpointId= */ 64));
432   EXPECT_THAT(halClientManager->getAllConnectedEndpoints(kVendorPid),
433               Optional(UnorderedElementsAre(63)));
434 }
435 
TEST_F(HalClientManagerTest,EndpointIdMutationForVendorClient)436 TEST_F(HalClientManagerTest, EndpointIdMutationForVendorClient) {
437   auto halClientManager = std::make_unique<HalClientManagerForTest>(
438       mockDeadClientUnlinker, kClientIdMappingFilePath);
439   std::shared_ptr<ContextHubCallbackForTest> vendorCallback =
440       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(kVendorUuid);
441   std::shared_ptr<ContextHubCallbackForTest> systemCallback =
442       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
443           kSystemServerUuid);
444   const uint16_t originalEndpointId = 10;  // 0b1010;
445   uint16_t mutatedEndpointId = originalEndpointId;
446 
447   // Register the system callback
448   EXPECT_TRUE(halClientManager->registerCallback(
449       kSystemServerPid, systemCallback, /* deathRecipientCookie= */ nullptr));
450   // Register the vendor callback
451   EXPECT_TRUE(halClientManager->registerCallback(
452       kVendorPid, vendorCallback, /* deathRecipientCookie= */ nullptr));
453 
454   // Mutate endpoint id from host to CHRE
455   EXPECT_TRUE(halClientManager->mutateEndpointIdFromHostIfNeeded(
456       kVendorPid, mutatedEndpointId));
457   HalClientId clientId = halClientManager->getClientId(kVendorPid);
458   EXPECT_EQ(mutatedEndpointId, 0x8000 | clientId << 6 | originalEndpointId);
459 
460   // Mutate endpoint id from CHRE to Host
461   EXPECT_EQ(halClientManager->convertToOriginalEndpointId(mutatedEndpointId),
462             originalEndpointId);
463 }
464 
TEST_F(HalClientManagerTest,EndpointIdMutationForSystemServer)465 TEST_F(HalClientManagerTest, EndpointIdMutationForSystemServer) {
466   auto halClientManager = std::make_unique<HalClientManagerForTest>(
467       mockDeadClientUnlinker, kClientIdMappingFilePath);
468   std::shared_ptr<ContextHubCallbackForTest> callback =
469       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
470           kSystemServerUuid);
471   const uint16_t originalEndpointId = 100;
472   uint16_t mutatedEndpointId = originalEndpointId;
473 
474   // Register the callback
475   EXPECT_TRUE(halClientManager->registerCallback(
476       kSystemServerPid, callback, /* deathRecipientCookie= */ nullptr));
477 
478   // Endpoint id from the system server shouldn't be mutated
479   EXPECT_TRUE(halClientManager->mutateEndpointIdFromHostIfNeeded(
480       kSystemServerPid, mutatedEndpointId));
481   EXPECT_EQ(mutatedEndpointId, originalEndpointId);
482   EXPECT_EQ(halClientManager->convertToOriginalEndpointId(mutatedEndpointId),
483             originalEndpointId);
484 }
485 
TEST_F(HalClientManagerTest,EndpointIdUnknownFromChre)486 TEST_F(HalClientManagerTest, EndpointIdUnknownFromChre) {
487   auto halClientManager = std::make_unique<HalClientManagerForTest>(
488       mockDeadClientUnlinker, kClientIdMappingFilePath);
489   std::shared_ptr<ContextHubCallbackForTest> vendorCallback =
490       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(kVendorUuid);
491   std::shared_ptr<ContextHubCallbackForTest> systemCallback =
492       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
493           kSystemServerUuid);
494   const HostEndpointId originalEndpointId = 0x10;  // unregistered endpoint id
495   HostEndpointId mutatedEndpointId = originalEndpointId;
496 
497   // Register the callback
498   EXPECT_TRUE(halClientManager->registerCallback(
499       kSystemServerPid, systemCallback, /* deathRecipientCookie= */ nullptr));
500   EXPECT_TRUE(halClientManager->registerCallback(
501       kVendorPid, vendorCallback, /* deathRecipientCookie= */ nullptr));
502 
503   // As long as a client's callback is registered, hal_client_manager won't
504   // block message exchanged from/to the client even if the endpoint id is
505   // not registered. The enforcement of endpoint id registration is done on the
506   // client side (contextHubService, library, etc.).
507   EXPECT_TRUE(halClientManager->mutateEndpointIdFromHostIfNeeded(
508       kVendorPid, mutatedEndpointId));
509   EXPECT_NE(mutatedEndpointId, originalEndpointId);
510   EXPECT_EQ(halClientManager->convertToOriginalEndpointId(mutatedEndpointId),
511             originalEndpointId);
512   EXPECT_EQ(halClientManager->getCallbackForEndpoint(mutatedEndpointId),
513             vendorCallback);
514 }
515 
TEST_F(HalClientManagerTest,handleDeathClient)516 TEST_F(HalClientManagerTest, handleDeathClient) {
517   auto halClientManager = std::make_unique<HalClientManagerForTest>(
518       mockDeadClientUnlinker, kClientIdMappingFilePath);
519   std::shared_ptr<ContextHubCallbackForTest> callback =
520       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
521           kSystemServerUuid);
522   halClientManager->registerCallback(kSystemServerPid, callback,
523                                      /* deathRecipientCookie= */ nullptr);
524   halClientManager->registerEndpointId(kSystemServerPid, /* endpointId= */ 10);
525 
526   halClientManager->handleClientDeath(kSystemServerPid);
527 
528   const std::vector<HalClient> &clients = halClientManager->getClients();
529   EXPECT_THAT(clients, SizeIs(1));
530   const HalClient &client = clients.front();
531   EXPECT_EQ(client.callback, nullptr);
532   EXPECT_EQ(client.pid, HalClient::kPidUnset);
533   EXPECT_EQ(client.uuid, kSystemServerUuid);
534   EXPECT_NE(client.clientId, ::chre::kHostClientIdUnspecified);
535   EXPECT_THAT(client.endpointIds, IsEmpty());
536 }
537 
TEST_F(HalClientManagerTest,handleChreRestart)538 TEST_F(HalClientManagerTest, handleChreRestart) {
539   auto halClientManager = std::make_unique<HalClientManagerForTest>(
540       mockDeadClientUnlinker, kClientIdMappingFilePath);
541   std::shared_ptr<ContextHubCallbackForTest> vendorCallback =
542       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(kVendorUuid);
543   std::shared_ptr<ContextHubCallbackForTest> systemCallback =
544       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
545           kSystemServerUuid);
546   // Register the system callback
547   EXPECT_TRUE(halClientManager->registerCallback(
548       kSystemServerPid, systemCallback, /* deathRecipientCookie= */ nullptr));
549   // Register the vendor callback
550   EXPECT_TRUE(halClientManager->registerCallback(
551       kVendorPid, vendorCallback, /* deathRecipientCookie= */ nullptr));
552 
553   // Calls to clients' handleContextHubAsyncEvent should be postponed to HAL.
554   EXPECT_CALL(*systemCallback,
555               handleContextHubAsyncEvent(AsyncEventType::RESTARTED))
556       .Times(0);
557   EXPECT_CALL(*vendorCallback,
558               handleContextHubAsyncEvent(AsyncEventType::RESTARTED))
559       .Times(0);
560 
561   halClientManager->handleChreRestart();
562 }
563 
TEST_F(HalClientManagerTest,getAllConnectedCallbacks)564 TEST_F(HalClientManagerTest, getAllConnectedCallbacks) {
565   auto halClientManager = std::make_unique<HalClientManagerForTest>(
566       mockDeadClientUnlinker, kClientIdMappingFilePath);
567   std::shared_ptr<ContextHubCallbackForTest> vendorCallback =
568       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(kVendorUuid);
569   std::shared_ptr<ContextHubCallbackForTest> systemCallback =
570       ContextHubCallbackForTest::make<ContextHubCallbackForTest>(
571           kSystemServerUuid);
572   // Register the system callback
573   EXPECT_TRUE(halClientManager->registerCallback(
574       kSystemServerPid, systemCallback, /* deathRecipientCookie= */ nullptr));
575   // Register the vendor callback
576   EXPECT_TRUE(halClientManager->registerCallback(
577       kVendorPid, vendorCallback, /* deathRecipientCookie= */ nullptr));
578 
579   EXPECT_THAT(halClientManager->getCallbacks(),
580               UnorderedElementsAre(vendorCallback, systemCallback));
581 }
582 
583 }  // namespace
584 }  // namespace android::hardware::contexthub::common::implementation
585