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