• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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