1 /*
2 * Copyright 2020 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 "MockAIBinderDeathRegistrationWrapper.h"
18 #include "MockCarWatchdogServiceForSystem.h"
19 #include "MockHidlServiceManager.h"
20 #include "MockVhalClient.h"
21 #include "MockWatchdogServiceHelper.h"
22 #include "WatchdogProcessService.h"
23 #include "WatchdogServiceHelper.h"
24
25 #include <android/binder_interface_utils.h>
26 #include <android/hidl/manager/1.0/IServiceManager.h>
27 #include <gmock/gmock.h>
28
29 #include <thread> // NOLINT(build/c++11)
30
31 namespace android {
32 namespace automotive {
33 namespace watchdog {
34
35 using ::aidl::android::automotive::watchdog::ICarWatchdogClient;
36 using ::aidl::android::automotive::watchdog::ICarWatchdogClientDefault;
37 using ::aidl::android::automotive::watchdog::TimeoutLength;
38 using ::aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor;
39 using ::aidl::android::automotive::watchdog::internal::ICarWatchdogMonitorDefault;
40 using ::aidl::android::automotive::watchdog::internal::ProcessIdentifier;
41 using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
42 using ::android::IBinder;
43 using ::android::Looper;
44 using ::android::sp;
45 using ::android::base::Error;
46 using ::android::frameworks::automotive::vhal::ClientStatusError;
47 using ::android::frameworks::automotive::vhal::ErrorCode;
48 using ::android::frameworks::automotive::vhal::IHalPropConfig;
49 using ::android::frameworks::automotive::vhal::IVhalClient;
50 using ::android::frameworks::automotive::vhal::VhalClientError;
51 using ::android::frameworks::automotive::vhal::VhalClientResult;
52 using ::android::hidl::base::V1_0::DebugInfo;
53 using ::android::hidl::manager::V1_0::IServiceManager;
54 using ::ndk::ScopedAStatus;
55 using ::ndk::SharedRefBase;
56 using ::ndk::SpAIBinder;
57 using ::testing::_;
58 using ::testing::ByMove;
59 using ::testing::Eq;
60 using ::testing::Field;
61 using ::testing::Invoke;
62 using ::testing::Matcher;
63 using ::testing::Return;
64
65 namespace {
66
67 constexpr std::chrono::milliseconds kMaxWaitForLooperExecutionMillis = 5s;
68 constexpr std::chrono::nanoseconds kTestVhalPidCachingRetryDelayNs = 20ms;
69 constexpr char kTestLooperThreadName[] = "WdProcSvcTest";
70 constexpr const int32_t kTestAidlVhalPid = 564269;
71 constexpr const int32_t kTestPidStartTime = 12356;
72 constexpr const int32_t kMaxVhalPidCachingAttempts = 2;
73
74 enum TestMessage {
75 NOTIFY_ALL,
76 ON_AIDL_VHAL_PID,
77 };
78
constructProcessIdentifier(int32_t pid,int64_t startTimeMillis)79 ProcessIdentifier constructProcessIdentifier(int32_t pid, int64_t startTimeMillis) {
80 ProcessIdentifier processIdentifier;
81 processIdentifier.pid = pid;
82 processIdentifier.startTimeMillis = startTimeMillis;
83 return processIdentifier;
84 }
85
86 MATCHER_P(ProcessIdentifierEq, expected, "") {
87 return ExplainMatchResult(AllOf(Field("pid", &ProcessIdentifier::pid, Eq(expected.pid)),
88 Field("startTimeMillis", &ProcessIdentifier::startTimeMillis,
89 Eq(expected.startTimeMillis))),
90 arg, result_listener);
91 }
92
93 } // namespace
94
95 namespace internal {
96
97 class WatchdogProcessServicePeer final {
98 public:
WatchdogProcessServicePeer(const sp<WatchdogProcessService> & watchdogProcessService)99 explicit WatchdogProcessServicePeer(const sp<WatchdogProcessService>& watchdogProcessService) :
100 mWatchdogProcessService(watchdogProcessService) {}
101
expectVhalProcessIdentifier(const Matcher<const ProcessIdentifier &> matcher)102 void expectVhalProcessIdentifier(const Matcher<const ProcessIdentifier&> matcher) {
103 Mutex::Autolock lock(mWatchdogProcessService->mMutex);
104 EXPECT_TRUE(mWatchdogProcessService->mVhalProcessIdentifier.has_value());
105 EXPECT_THAT(mWatchdogProcessService->mVhalProcessIdentifier.value(), matcher);
106 }
107
expectNoVhalProcessIdentifier()108 void expectNoVhalProcessIdentifier() {
109 EXPECT_FALSE(mWatchdogProcessService->mVhalProcessIdentifier.has_value());
110 }
111
112 private:
113 sp<WatchdogProcessService> mWatchdogProcessService;
114 };
115
116 } // namespace internal
117
118 class WatchdogProcessServiceTest : public ::testing::Test {
119 public:
WatchdogProcessServiceTest()120 WatchdogProcessServiceTest() :
121 mMockVhalClient(nullptr),
122 mMockHidlServiceManager(nullptr),
123 kTryCreateVhalClientFunc([this]() { return mMockVhalClient; }),
__anond8c07c360302() 124 kTryGetHidlServiceManagerFunc([this]() { return mMockHidlServiceManager; }),
__anond8c07c360402(pid_t) 125 kGetStartTimeForPidFunc([](pid_t) { return kTestPidStartTime; }) {}
126
127 protected:
SetUp()128 void SetUp() override {
129 mMessageHandler = sp<MessageHandlerImpl>::make(this);
130 mMockVehicle = SharedRefBase::make<MockVehicle>();
131 mMockVhalClient = std::make_shared<MockVhalClient>(mMockVehicle);
132 mMockHidlServiceManager = sp<MockHidlServiceManager>::make();
133 mMockDeathRegistrationWrapper = sp<MockAIBinderDeathRegistrationWrapper>::make();
134 mSupportedVehicleProperties = {VehicleProperty::VHAL_HEARTBEAT};
135 mNotSupportedVehicleProperties = {VehicleProperty::WATCHDOG_ALIVE,
136 VehicleProperty::WATCHDOG_TERMINATED_PROCESS};
137 startService();
138 }
139
TearDown()140 void TearDown() override {
141 terminateService();
142 mMockDeathRegistrationWrapper.clear();
143 mMockHidlServiceManager.clear();
144 mMockVhalClient.reset();
145 mMockVehicle.reset();
146 mMessageHandler.clear();
147 }
148
startService()149 void startService() {
150 prepareLooper();
151 mWatchdogProcessService =
152 sp<WatchdogProcessService>::make(kTryCreateVhalClientFunc,
153 kTryGetHidlServiceManagerFunc,
154 kGetStartTimeForPidFunc,
155 kTestVhalPidCachingRetryDelayNs, mHandlerLooper,
156 mMockDeathRegistrationWrapper);
157 mWatchdogProcessServicePeer =
158 std::make_unique<internal::WatchdogProcessServicePeer>(mWatchdogProcessService);
159
160 expectGetPropConfigs(mSupportedVehicleProperties, mNotSupportedVehicleProperties);
161
162 mWatchdogProcessService->start();
163 // Sync with the looper before proceeding to ensure that all startup looper messages are
164 // processed before testing the service.
165 syncLooper();
166 }
167
terminateService()168 void terminateService() {
169 wakeAndJoinLooper();
170 mWatchdogProcessServicePeer.reset();
171 mWatchdogProcessService->terminate();
172 mWatchdogProcessService.clear();
173 mHandlerLooper.clear();
174 }
175
expectLinkToDeath(AIBinder * aiBinder,ScopedAStatus expectedStatus)176 void expectLinkToDeath(AIBinder* aiBinder, ScopedAStatus expectedStatus) {
177 EXPECT_CALL(*mMockDeathRegistrationWrapper,
178 linkToDeath(Eq(aiBinder), _, static_cast<void*>(aiBinder)))
179 .WillOnce(Return(ByMove(std::move(expectedStatus))));
180 }
181
expectUnlinkToDeath(AIBinder * aiBinder,ScopedAStatus expectedStatus)182 void expectUnlinkToDeath(AIBinder* aiBinder, ScopedAStatus expectedStatus) {
183 EXPECT_CALL(*mMockDeathRegistrationWrapper,
184 unlinkToDeath(Eq(aiBinder), _, static_cast<void*>(aiBinder)))
185 .WillOnce(Return(ByMove(std::move(expectedStatus))));
186 }
187
expectNoUnlinkToDeath(AIBinder * aiBinder)188 void expectNoUnlinkToDeath(AIBinder* aiBinder) {
189 EXPECT_CALL(*mMockDeathRegistrationWrapper,
190 unlinkToDeath(Eq(aiBinder), _, static_cast<void*>(aiBinder)))
191 .Times(0);
192 }
193
expectGetPropConfigs(const std::vector<VehicleProperty> & supportedProperties,const std::vector<VehicleProperty> & notSupportedProperties)194 void expectGetPropConfigs(const std::vector<VehicleProperty>& supportedProperties,
195 const std::vector<VehicleProperty>& notSupportedProperties) {
196 for (const auto& propId : supportedProperties) {
197 EXPECT_CALL(*mMockVhalClient,
198 getPropConfigs(std::vector<int32_t>{static_cast<int32_t>(propId)}))
199 .WillOnce([]() { return std::vector<std::unique_ptr<IHalPropConfig>>(); });
200 }
201 for (const auto& propId : notSupportedProperties) {
202 EXPECT_CALL(*mMockVhalClient,
203 getPropConfigs(std::vector<int32_t>{static_cast<int32_t>(propId)}))
204 .WillOnce(
205 []() -> VhalClientResult<std::vector<std::unique_ptr<IHalPropConfig>>> {
206 return Error<VhalClientError>(ErrorCode::NOT_AVAILABLE_FROM_VHAL)
207 << "Not supported";
208 });
209 }
210 }
211
212 // Expect the requestAidlVhalPid call from the implementation on registering CarWatchdogService
213 // and mimic CarWatchdogService response by posting the onAidlVhalPidFetched call on the looper.
expectRequestAidlVhalPidAndRespond(const sp<MockWatchdogServiceHelper> & mockServiceHelper)214 void expectRequestAidlVhalPidAndRespond(
215 const sp<MockWatchdogServiceHelper>& mockServiceHelper) {
216 EXPECT_CALL(*mockServiceHelper, requestAidlVhalPid()).WillOnce([&]() {
217 mHandlerLooper->sendMessageDelayed(kTestVhalPidCachingRetryDelayNs.count() / 2,
218 mMessageHandler,
219 Message(TestMessage::ON_AIDL_VHAL_PID));
220 return ScopedAStatus::ok();
221 });
222 }
223
syncLooper(std::chrono::nanoseconds delay=0ns)224 void syncLooper(std::chrono::nanoseconds delay = 0ns) {
225 mHandlerLooper->sendMessageDelayed(delay.count(), mMessageHandler,
226 Message(TestMessage::NOTIFY_ALL));
227 waitForLooperNotification(delay);
228 }
229
waitForLooperNotification(std::chrono::nanoseconds delay=0ns)230 void waitForLooperNotification(std::chrono::nanoseconds delay = 0ns) {
231 std::unique_lock lock(mMutex);
232 mLooperCondition.wait_for(lock,
233 kMaxWaitForLooperExecutionMillis +
234 std::chrono::duration_cast<std::chrono::milliseconds>(
235 delay));
236 }
237
waitUntilVhalPidCachingAttemptsExhausted()238 void waitUntilVhalPidCachingAttemptsExhausted() {
239 syncLooper((kMaxVhalPidCachingAttempts + 1) * kTestVhalPidCachingRetryDelayNs);
240 }
241
242 sp<WatchdogProcessService> mWatchdogProcessService;
243 std::unique_ptr<internal::WatchdogProcessServicePeer> mWatchdogProcessServicePeer;
244 std::shared_ptr<MockVhalClient> mMockVhalClient;
245 std::shared_ptr<MockVehicle> mMockVehicle;
246 sp<MockHidlServiceManager> mMockHidlServiceManager;
247 sp<MockAIBinderDeathRegistrationWrapper> mMockDeathRegistrationWrapper;
248 std::vector<VehicleProperty> mSupportedVehicleProperties;
249 std::vector<VehicleProperty> mNotSupportedVehicleProperties;
250
251 private:
252 class MessageHandlerImpl : public android::MessageHandler {
253 public:
MessageHandlerImpl(WatchdogProcessServiceTest * test)254 explicit MessageHandlerImpl(WatchdogProcessServiceTest* test) : mTest(test) {}
255
handleMessage(const Message & message)256 void handleMessage(const Message& message) override {
257 switch (message.what) {
258 case static_cast<int>(TestMessage::NOTIFY_ALL):
259 break;
260 case static_cast<int>(TestMessage::ON_AIDL_VHAL_PID):
261 mTest->mWatchdogProcessService->onAidlVhalPidFetched(kTestAidlVhalPid);
262 break;
263 default:
264 ALOGE("Unknown TestMessage: %d", message.what);
265 return;
266 }
267 std::unique_lock lock(mTest->mMutex);
268 mTest->mLooperCondition.notify_all();
269 }
270
271 private:
272 WatchdogProcessServiceTest* mTest;
273 };
274
275 // Looper runs on the calling thread when it is polled for messages with the poll* calls.
276 // The poll* calls are blocking, so they must be executed on a separate thread.
prepareLooper()277 void prepareLooper() {
278 mHandlerLooper = Looper::prepare(/*opts=*/0);
279 mHandlerLooperThread = std::thread([this]() {
280 Looper::setForThread(mHandlerLooper);
281 if (int result = pthread_setname_np(pthread_self(), kTestLooperThreadName);
282 result != 0) {
283 ALOGE("Failed to set test looper thread name: %s", strerror(result));
284 }
285 mShouldTerminateLooper.store(false);
286 while (!mShouldTerminateLooper.load()) {
287 mHandlerLooper->pollAll(/*timeoutMillis=*/-1);
288 }
289 });
290 }
291
wakeAndJoinLooper()292 void wakeAndJoinLooper() {
293 // Sync with the looper to make sure all messages for the current time slot are processed
294 // before terminating the looper. This will help satisfy any pending EXPECT_CALLs.
295 syncLooper();
296 mShouldTerminateLooper.store(true);
297 mHandlerLooper->wake();
298 if (mHandlerLooperThread.joinable()) {
299 mHandlerLooperThread.join();
300 }
301 }
302
303 const std::function<std::shared_ptr<IVhalClient>()> kTryCreateVhalClientFunc;
304 const std::function<android::sp<android::hidl::manager::V1_0::IServiceManager>()>
305 kTryGetHidlServiceManagerFunc;
306 const std::function<int64_t(pid_t)> kGetStartTimeForPidFunc;
307
308 sp<Looper> mHandlerLooper;
309 sp<MessageHandlerImpl> mMessageHandler;
310 std::thread mHandlerLooperThread;
311 mutable std::mutex mMutex;
312 std::condition_variable mLooperCondition GUARDED_BY(mMutex);
313 std::atomic<bool> mShouldTerminateLooper;
314 };
315
TEST_F(WatchdogProcessServiceTest,TestTerminate)316 TEST_F(WatchdogProcessServiceTest, TestTerminate) {
317 std::vector<int32_t> propIds = {static_cast<int32_t>(VehicleProperty::VHAL_HEARTBEAT)};
318 EXPECT_CALL(*mMockVhalClient, removeOnBinderDiedCallback(_)).Times(1);
319 EXPECT_CALL(*mMockVehicle, unsubscribe(_, propIds))
320 .WillOnce(Return(ByMove(std::move(ScopedAStatus::ok()))));
321 mWatchdogProcessService->terminate();
322 // TODO(b/217405065): Verify looper removes all MSG_VHAL_HEALTH_CHECK messages.
323 }
324
325 // TODO(b/217405065): Add test to verify the handleVhalDeath method.
326
TEST_F(WatchdogProcessServiceTest,TestRegisterClient)327 TEST_F(WatchdogProcessServiceTest, TestRegisterClient) {
328 std::shared_ptr<ICarWatchdogClient> client = SharedRefBase::make<ICarWatchdogClientDefault>();
329 expectLinkToDeath(client->asBinder().get(), std::move(ScopedAStatus::ok()));
330
331 auto status = mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
332
333 ASSERT_TRUE(status.isOk()) << status.getMessage();
334
335 status = mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
336
337 ASSERT_TRUE(status.isOk()) << status.getMessage();
338 }
339
TEST_F(WatchdogProcessServiceTest,TestUnregisterClient)340 TEST_F(WatchdogProcessServiceTest, TestUnregisterClient) {
341 std::shared_ptr<ICarWatchdogClient> client = SharedRefBase::make<ICarWatchdogClientDefault>();
342 AIBinder* aiBinder = client->asBinder().get();
343 expectLinkToDeath(aiBinder, std::move(ScopedAStatus::ok()));
344
345 auto status = mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
346
347 ASSERT_TRUE(status.isOk()) << status.getMessage();
348
349 expectUnlinkToDeath(aiBinder, std::move(ScopedAStatus::ok()));
350
351 status = mWatchdogProcessService->unregisterClient(client);
352
353 ASSERT_TRUE(status.isOk()) << status.getMessage();
354 ASSERT_FALSE(mWatchdogProcessService->unregisterClient(client).isOk())
355 << "Unregistering an unregistered client should return an error";
356 }
357
TEST_F(WatchdogProcessServiceTest,TestErrorOnRegisterClientWithDeadBinder)358 TEST_F(WatchdogProcessServiceTest, TestErrorOnRegisterClientWithDeadBinder) {
359 std::shared_ptr<ICarWatchdogClient> client = SharedRefBase::make<ICarWatchdogClientDefault>();
360 expectLinkToDeath(client->asBinder().get(),
361 std::move(ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED)));
362
363 ASSERT_FALSE(
364 mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL).isOk())
365 << "When linkToDeath fails, registerClient should return an error";
366 }
367
TEST_F(WatchdogProcessServiceTest,TestHandleClientBinderDeath)368 TEST_F(WatchdogProcessServiceTest, TestHandleClientBinderDeath) {
369 std::shared_ptr<ICarWatchdogClient> client = SharedRefBase::make<ICarWatchdogClientDefault>();
370 AIBinder* aiBinder = client->asBinder().get();
371 expectLinkToDeath(aiBinder, std::move(ScopedAStatus::ok()));
372
373 auto status = mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
374
375 ASSERT_TRUE(status.isOk()) << status.getMessage();
376
377 mWatchdogProcessService->handleBinderDeath(static_cast<void*>(aiBinder));
378
379 expectNoUnlinkToDeath(aiBinder);
380
381 ASSERT_FALSE(mWatchdogProcessService->unregisterClient(client).isOk())
382 << "Unregistering a dead client should return an error";
383 }
384
TEST_F(WatchdogProcessServiceTest,TestRegisterCarWatchdogService)385 TEST_F(WatchdogProcessServiceTest, TestRegisterCarWatchdogService) {
386 sp<MockWatchdogServiceHelper> mockServiceHelper = sp<MockWatchdogServiceHelper>::make();
387
388 std::shared_ptr<MockCarWatchdogServiceForSystem> mockService =
389 SharedRefBase::make<MockCarWatchdogServiceForSystem>();
390 const auto binder = mockService->asBinder();
391
392 EXPECT_CALL(*mockServiceHelper, requestAidlVhalPid())
393 .WillOnce(Return(ByMove(std::move(ScopedAStatus::ok()))));
394
395 auto status = mWatchdogProcessService->registerCarWatchdogService(binder, mockServiceHelper);
396 ASSERT_TRUE(status.isOk()) << status.getMessage();
397
398 // The implementation posts message on the looper to cache VHAL pid when registering
399 // the car watchdog service. So, sync with the looper to ensure the above requestAidlVhalPid
400 // EXPECT_CALL is satisfied.
401 syncLooper();
402
403 // No new request to fetch AIDL VHAL pid should be sent on duplicate registration.
404 EXPECT_CALL(*mockServiceHelper, requestAidlVhalPid()).Times(0);
405
406 status = mWatchdogProcessService->registerCarWatchdogService(binder, mockServiceHelper);
407 ASSERT_TRUE(status.isOk()) << status.getMessage();
408 }
409
TEST_F(WatchdogProcessServiceTest,TestErrorOnRegisterCarWatchdogServiceWithNullWatchdogServiceHelper)410 TEST_F(WatchdogProcessServiceTest,
411 TestErrorOnRegisterCarWatchdogServiceWithNullWatchdogServiceHelper) {
412 std::shared_ptr<MockCarWatchdogServiceForSystem> mockService =
413 SharedRefBase::make<MockCarWatchdogServiceForSystem>();
414 const auto binder = mockService->asBinder();
415
416 ASSERT_FALSE(mWatchdogProcessService->registerCarWatchdogService(binder, nullptr).isOk())
417 << "Registering car watchdog service should fail when watchdog service helper is null";
418 }
419
TEST_F(WatchdogProcessServiceTest,TestRegisterMonitor)420 TEST_F(WatchdogProcessServiceTest, TestRegisterMonitor) {
421 std::shared_ptr<ICarWatchdogMonitor> monitorOne =
422 SharedRefBase::make<ICarWatchdogMonitorDefault>();
423 expectLinkToDeath(monitorOne->asBinder().get(), std::move(ScopedAStatus::ok()));
424
425 auto status = mWatchdogProcessService->registerMonitor(monitorOne);
426
427 ASSERT_TRUE(status.isOk()) << status.getMessage();
428
429 status = mWatchdogProcessService->registerMonitor(monitorOne);
430
431 ASSERT_TRUE(status.isOk()) << status.getMessage();
432
433 std::shared_ptr<ICarWatchdogMonitor> monitorTwo =
434 SharedRefBase::make<ICarWatchdogMonitorDefault>();
435 status = mWatchdogProcessService->registerMonitor(monitorTwo);
436
437 ASSERT_TRUE(status.isOk()) << status.getMessage();
438 }
439
TEST_F(WatchdogProcessServiceTest,TestErrorOnRegisterMonitorWithDeadBinder)440 TEST_F(WatchdogProcessServiceTest, TestErrorOnRegisterMonitorWithDeadBinder) {
441 std::shared_ptr<ICarWatchdogMonitor> monitor =
442 SharedRefBase::make<ICarWatchdogMonitorDefault>();
443 expectLinkToDeath(monitor->asBinder().get(),
444 std::move(ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED)));
445
446 ASSERT_FALSE(mWatchdogProcessService->registerMonitor(monitor).isOk())
447 << "When linkToDeath fails, registerMonitor should return an error";
448 }
449
TEST_F(WatchdogProcessServiceTest,TestUnregisterMonitor)450 TEST_F(WatchdogProcessServiceTest, TestUnregisterMonitor) {
451 std::shared_ptr<ICarWatchdogMonitor> monitor =
452 SharedRefBase::make<ICarWatchdogMonitorDefault>();
453 AIBinder* aiBinder = monitor->asBinder().get();
454 expectLinkToDeath(aiBinder, std::move(ScopedAStatus::ok()));
455
456 auto status = mWatchdogProcessService->registerMonitor(monitor);
457
458 ASSERT_TRUE(status.isOk()) << status.getMessage();
459
460 expectUnlinkToDeath(aiBinder, std::move(ScopedAStatus::ok()));
461
462 status = mWatchdogProcessService->unregisterMonitor(monitor);
463
464 ASSERT_TRUE(status.isOk()) << status.getMessage();
465 ASSERT_FALSE(mWatchdogProcessService->unregisterMonitor(monitor).isOk())
466 << "Unregistering an unregistered monitor should return an error";
467 }
468
TEST_F(WatchdogProcessServiceTest,TestHandleMonitorBinderDeath)469 TEST_F(WatchdogProcessServiceTest, TestHandleMonitorBinderDeath) {
470 std::shared_ptr<ICarWatchdogMonitor> monitor =
471 SharedRefBase::make<ICarWatchdogMonitorDefault>();
472 AIBinder* aiBinder = monitor->asBinder().get();
473 expectLinkToDeath(aiBinder, std::move(ScopedAStatus::ok()));
474
475 auto status = mWatchdogProcessService->registerMonitor(monitor);
476
477 ASSERT_TRUE(status.isOk()) << status.getMessage();
478
479 mWatchdogProcessService->handleBinderDeath(static_cast<void*>(aiBinder));
480
481 expectNoUnlinkToDeath(aiBinder);
482
483 ASSERT_FALSE(mWatchdogProcessService->unregisterMonitor(monitor).isOk())
484 << "Unregistering a dead monitor should return an error";
485 }
486
TEST_F(WatchdogProcessServiceTest,TestTellClientAlive)487 TEST_F(WatchdogProcessServiceTest, TestTellClientAlive) {
488 std::shared_ptr<ICarWatchdogClient> client = SharedRefBase::make<ICarWatchdogClientDefault>();
489 expectLinkToDeath(client->asBinder().get(), std::move(ScopedAStatus::ok()));
490
491 mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
492
493 ASSERT_FALSE(mWatchdogProcessService->tellClientAlive(client, 1234).isOk())
494 << "tellClientAlive not synced with checkIfAlive should return an error";
495 }
496
TEST_F(WatchdogProcessServiceTest,TestTellCarWatchdogServiceAlive)497 TEST_F(WatchdogProcessServiceTest, TestTellCarWatchdogServiceAlive) {
498 std::shared_ptr<MockCarWatchdogServiceForSystem> mockService =
499 SharedRefBase::make<MockCarWatchdogServiceForSystem>();
500
501 std::vector<ProcessIdentifier> processIdentifiers;
502 processIdentifiers.push_back(
503 constructProcessIdentifier(/* pid= */ 111, /* startTimeMillis= */ 0));
504 processIdentifiers.push_back(
505 constructProcessIdentifier(/* pid= */ 222, /* startTimeMillis= */ 0));
506 ASSERT_FALSE(mWatchdogProcessService
507 ->tellCarWatchdogServiceAlive(mockService, processIdentifiers, 1234)
508 .isOk())
509 << "tellCarWatchdogServiceAlive not synced with checkIfAlive should return an error";
510 }
511
TEST_F(WatchdogProcessServiceTest,TestTellDumpFinished)512 TEST_F(WatchdogProcessServiceTest, TestTellDumpFinished) {
513 std::shared_ptr<ICarWatchdogMonitor> monitor =
514 SharedRefBase::make<ICarWatchdogMonitorDefault>();
515 ASSERT_FALSE(mWatchdogProcessService
516 ->tellDumpFinished(monitor,
517 constructProcessIdentifier(/* pid= */ 1234,
518 /* startTimeMillis= */ 0))
519 .isOk())
520 << "Unregistered monitor cannot call tellDumpFinished";
521
522 expectLinkToDeath(monitor->asBinder().get(), std::move(ScopedAStatus::ok()));
523
524 mWatchdogProcessService->registerMonitor(monitor);
525 auto status = mWatchdogProcessService
526 ->tellDumpFinished(monitor,
527 constructProcessIdentifier(/* pid= */ 1234,
528 /* startTimeMillis= */ 0));
529
530 ASSERT_TRUE(status.isOk()) << status.getMessage();
531 }
532
TEST_F(WatchdogProcessServiceTest,TestCacheAidlVhalPidFromCarWatchdogService)533 TEST_F(WatchdogProcessServiceTest, TestCacheAidlVhalPidFromCarWatchdogService) {
534 sp<MockWatchdogServiceHelper> mockServiceHelper = sp<MockWatchdogServiceHelper>::make();
535
536 std::shared_ptr<MockCarWatchdogServiceForSystem> mockService =
537 SharedRefBase::make<MockCarWatchdogServiceForSystem>();
538 const auto binder = mockService->asBinder();
539
540 expectRequestAidlVhalPidAndRespond(mockServiceHelper);
541
542 auto status = mWatchdogProcessService->registerCarWatchdogService(binder, mockServiceHelper);
543 ASSERT_TRUE(status.isOk()) << status.getMessage();
544
545 // On processing the TestMessage::ON_AIDL_VHAL_PID, the looper notifies all waiting threads.
546 // Wait for the notification to ensure the VHAL pid caching is satisfied.
547 waitForLooperNotification();
548
549 ASSERT_NO_FATAL_FAILURE(mWatchdogProcessServicePeer->expectVhalProcessIdentifier(
550 ProcessIdentifierEq(constructProcessIdentifier(kTestAidlVhalPid, kTestPidStartTime))));
551 }
552
TEST_F(WatchdogProcessServiceTest,TestFailsCacheAidlVhalPidWithNoCarWatchdogServiceResponse)553 TEST_F(WatchdogProcessServiceTest, TestFailsCacheAidlVhalPidWithNoCarWatchdogServiceResponse) {
554 sp<MockWatchdogServiceHelper> mockServiceHelper = sp<MockWatchdogServiceHelper>::make();
555
556 std::shared_ptr<MockCarWatchdogServiceForSystem> mockService =
557 SharedRefBase::make<MockCarWatchdogServiceForSystem>();
558 const auto binder = mockService->asBinder();
559
560 EXPECT_CALL(*mockServiceHelper, requestAidlVhalPid())
561 .Times(kMaxVhalPidCachingAttempts)
562 .WillRepeatedly([&]() {
563 // No action taken by CarWatchdogService.
564 return ScopedAStatus::ok();
565 });
566
567 auto status = mWatchdogProcessService->registerCarWatchdogService(binder, mockServiceHelper);
568 ASSERT_TRUE(status.isOk()) << status.getMessage();
569
570 // Because CarWatchdogService doesn't respond with the AIDL VHAL pid, wait until all caching
571 // attempts are exhausted to ensure the expected number of caching attempts are satisfied.
572 waitUntilVhalPidCachingAttemptsExhausted();
573
574 ASSERT_NO_FATAL_FAILURE(mWatchdogProcessServicePeer->expectNoVhalProcessIdentifier());
575 }
576
TEST_F(WatchdogProcessServiceTest,TestNoCacheAidlVhalPidWithUnsupportedVhalHeartBeatProperty)577 TEST_F(WatchdogProcessServiceTest, TestNoCacheAidlVhalPidWithUnsupportedVhalHeartBeatProperty) {
578 // The supported vehicle property list is fetched as soon as VHAL is connected, which happens
579 // during the start of the service. So, restart the service for the new VHAL settings to take
580 // effect.
581 terminateService();
582
583 mSupportedVehicleProperties.clear();
584 mNotSupportedVehicleProperties.push_back(VehicleProperty::VHAL_HEARTBEAT);
585
586 startService();
587
588 sp<MockWatchdogServiceHelper> mockServiceHelper = sp<MockWatchdogServiceHelper>::make();
589 std::shared_ptr<MockCarWatchdogServiceForSystem> mockService =
590 SharedRefBase::make<MockCarWatchdogServiceForSystem>();
591 const auto binder = mockService->asBinder();
592
593 EXPECT_CALL(*mockServiceHelper, requestAidlVhalPid()).Times(0);
594
595 auto status = mWatchdogProcessService->registerCarWatchdogService(binder, mockServiceHelper);
596 ASSERT_TRUE(status.isOk()) << status.getMessage();
597
598 // VHAL process identifier caching happens on the looper thread. Sync with the looper before
599 // proceeding.
600 syncLooper();
601
602 ASSERT_NO_FATAL_FAILURE(mWatchdogProcessServicePeer->expectNoVhalProcessIdentifier());
603 }
604
TEST_F(WatchdogProcessServiceTest,TestCacheHidlVhalPidFromHidlServiceManager)605 TEST_F(WatchdogProcessServiceTest, TestCacheHidlVhalPidFromHidlServiceManager) {
606 // VHAL PID caching logic is determined as soon as VHAL is connected, which happens during
607 // the start of the service. So, restart the service for the new VHAL settings to take effect.
608 terminateService();
609
610 using InstanceDebugInfo = IServiceManager::InstanceDebugInfo;
611 EXPECT_CALL(*mMockVhalClient, isAidlVhal()).WillOnce(Return(false));
612 EXPECT_CALL(*mMockHidlServiceManager, debugDump(_))
613 .WillOnce(Invoke([](IServiceManager::debugDump_cb cb) {
614 cb({InstanceDebugInfo{"android.hardware.automotive.evs@1.0::IEvsCamera",
615 "vehicle_hal_insts",
616 8058,
617 {},
618 DebugInfo::Architecture::IS_64BIT},
619 InstanceDebugInfo{"android.hardware.automotive.vehicle@2.0::IVehicle",
620 "vehicle_hal_insts",
621 static_cast<int>(IServiceManager::PidConstant::NO_PID),
622 {},
623 DebugInfo::Architecture::IS_64BIT},
624 InstanceDebugInfo{"android.hardware.automotive.vehicle@2.0::IVehicle",
625 "vehicle_hal_insts",
626 2034,
627 {},
628 DebugInfo::Architecture::IS_64BIT}});
629 return android::hardware::Void();
630 }));
631
632 startService();
633
634 ASSERT_NO_FATAL_FAILURE(mWatchdogProcessServicePeer->expectVhalProcessIdentifier(
635 ProcessIdentifierEq(constructProcessIdentifier(2034, kTestPidStartTime))));
636 }
637
TEST_F(WatchdogProcessServiceTest,TestFailsCacheHidlVhalPidWithNoHidlVhalService)638 TEST_F(WatchdogProcessServiceTest, TestFailsCacheHidlVhalPidWithNoHidlVhalService) {
639 // VHAL PID caching logic is determined as soon as VHAL is connected, which happens during
640 // the start of the service. So, restart the service for the new VHAL settings to take effect.
641 terminateService();
642
643 using InstanceDebugInfo = IServiceManager::InstanceDebugInfo;
644 EXPECT_CALL(*mMockVhalClient, isAidlVhal()).WillRepeatedly(Return(false));
645 EXPECT_CALL(*mMockHidlServiceManager, debugDump(_))
646 .Times(kMaxVhalPidCachingAttempts)
647 .WillRepeatedly(Invoke([](IServiceManager::debugDump_cb cb) {
648 cb({InstanceDebugInfo{"android.hardware.automotive.evs@1.0::IEvsCamera",
649 "vehicle_hal_insts",
650 8058,
651 {},
652 DebugInfo::Architecture::IS_64BIT}});
653 return android::hardware::Void();
654 }));
655
656 startService();
657
658 // Because HIDL service manager doesn't have the HIDL VHAL pid, wait until all caching
659 // attempts are exhausted to ensure the expected number of caching attempts are satisfied.
660 waitUntilVhalPidCachingAttemptsExhausted();
661
662 ASSERT_NO_FATAL_FAILURE(mWatchdogProcessServicePeer->expectNoVhalProcessIdentifier());
663 }
664
TEST_F(WatchdogProcessServiceTest,TestNoCacheHidlVhalPidWithUnsupportedVhalHeartBeatProperty)665 TEST_F(WatchdogProcessServiceTest, TestNoCacheHidlVhalPidWithUnsupportedVhalHeartBeatProperty) {
666 // The supported vehicle property list is fetched as soon as VHAL is connected, which happens
667 // during the start of the service. So, restart the service for the new VHAL settings to take
668 // effect.
669 terminateService();
670
671 mSupportedVehicleProperties.clear();
672 mNotSupportedVehicleProperties.push_back(VehicleProperty::VHAL_HEARTBEAT);
673
674 EXPECT_CALL(*mMockHidlServiceManager, debugDump(_)).Times(0);
675
676 startService();
677
678 ASSERT_NO_FATAL_FAILURE(mWatchdogProcessServicePeer->expectNoVhalProcessIdentifier());
679 }
680
681 } // namespace watchdog
682 } // namespace automotive
683 } // namespace android
684