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 "MockPackageInfoResolver.h"
21 #include "MockVhalClient.h"
22 #include "MockWatchdogServiceHelper.h"
23 #include "PackageInfoResolver.h"
24 #include "WatchdogProcessService.h"
25 #include "WatchdogServiceHelper.h"
26 
27 #include <android/binder_interface_utils.h>
28 #include <android/hidl/manager/1.0/IServiceManager.h>
29 #include <android/util/ProtoOutputStream.h>
30 #include <gmock/gmock.h>
31 
32 #include <thread>  // NOLINT(build/c++11)
33 
34 #include <carwatchdog_daemon_dump.pb.h>
35 #include <health_check_client_info.pb.h>
36 #include <performance_stats.pb.h>
37 
38 namespace android {
39 namespace automotive {
40 namespace watchdog {
41 
42 using ::aidl::android::automotive::watchdog::ICarWatchdogClient;
43 using ::aidl::android::automotive::watchdog::ICarWatchdogClientDefault;
44 using ::aidl::android::automotive::watchdog::TimeoutLength;
45 using ::aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor;
46 using ::aidl::android::automotive::watchdog::internal::ICarWatchdogMonitorDefault;
47 using ::aidl::android::automotive::watchdog::internal::ProcessIdentifier;
48 using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
49 using ::android::IBinder;
50 using ::android::Looper;
51 using ::android::sp;
52 using ::android::base::Error;
53 using ::android::frameworks::automotive::vhal::ClientStatusError;
54 using ::android::frameworks::automotive::vhal::ErrorCode;
55 using ::android::frameworks::automotive::vhal::IHalPropConfig;
56 using ::android::frameworks::automotive::vhal::IVhalClient;
57 using ::android::frameworks::automotive::vhal::VhalClientError;
58 using ::android::frameworks::automotive::vhal::VhalClientResult;
59 using ::android::hidl::base::V1_0::DebugInfo;
60 using ::android::hidl::manager::V1_0::IServiceManager;
61 using ::android::util::ProtoReader;
62 using ::ndk::ScopedAStatus;
63 using ::ndk::SharedRefBase;
64 using ::ndk::SpAIBinder;
65 using ::testing::_;
66 using ::testing::ByMove;
67 using ::testing::Eq;
68 using ::testing::Field;
69 using ::testing::Invoke;
70 using ::testing::Matcher;
71 using ::testing::Return;
72 
73 namespace {
74 
75 constexpr std::chrono::milliseconds kMaxWaitForLooperExecutionMillis = 5s;
76 constexpr std::chrono::nanoseconds kTestVhalPidCachingRetryDelayNs = 20ms;
77 constexpr char kTestLooperThreadName[] = "WdProcSvcTest";
78 constexpr const int32_t kTestAidlVhalPid = 564269;
79 constexpr const int32_t kTestPidStartTime = 12356;
80 constexpr const int32_t kMaxVhalPidCachingAttempts = 2;
81 
82 enum TestMessage {
83     NOTIFY_ALL,
84     ON_AIDL_VHAL_PID,
85 };
86 
constructProcessIdentifier(int32_t pid,int64_t startTimeMillis)87 ProcessIdentifier constructProcessIdentifier(int32_t pid, int64_t startTimeMillis) {
88     ProcessIdentifier processIdentifier;
89     processIdentifier.pid = pid;
90     processIdentifier.startTimeMillis = startTimeMillis;
91     return processIdentifier;
92 }
93 
94 MATCHER_P(ProcessIdentifierEq, expected, "") {
95     return ExplainMatchResult(AllOf(Field("pid", &ProcessIdentifier::pid, Eq(expected.pid)),
96                                     Field("startTimeMillis", &ProcessIdentifier::startTimeMillis,
97                                           Eq(expected.startTimeMillis))),
98                               arg, result_listener);
99 }
100 
101 }  // namespace
102 
103 namespace internal {
104 
105 class WatchdogProcessServicePeer final {
106 public:
WatchdogProcessServicePeer(const sp<WatchdogProcessService> & watchdogProcessService)107     explicit WatchdogProcessServicePeer(const sp<WatchdogProcessService>& watchdogProcessService) :
108           mWatchdogProcessService(watchdogProcessService) {}
109 
expectVhalProcessIdentifier(const Matcher<const ProcessIdentifier &> matcher)110     void expectVhalProcessIdentifier(const Matcher<const ProcessIdentifier&> matcher) {
111         Mutex::Autolock lock(mWatchdogProcessService->mMutex);
112         EXPECT_TRUE(mWatchdogProcessService->mVhalProcessIdentifier.has_value());
113         EXPECT_THAT(mWatchdogProcessService->mVhalProcessIdentifier.value(), matcher);
114     }
115 
expectNoVhalProcessIdentifier()116     void expectNoVhalProcessIdentifier() {
117         EXPECT_FALSE(mWatchdogProcessService->mVhalProcessIdentifier.has_value());
118     }
119 
setWatchdogProcessServiceState(bool isEnabled,std::shared_ptr<aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor> monitor,std::chrono::nanoseconds overriddenClientHealthCheckWindowNs,std::unordered_set<userid_t> stoppedUserIds,std::chrono::milliseconds vhalHealthCheckWindowMillis,const ProcessIdentifier & processIdentifier)120     void setWatchdogProcessServiceState(
121             bool isEnabled,
122             std::shared_ptr<aidl::android::automotive::watchdog::internal::ICarWatchdogMonitor>
123                     monitor,
124             std::chrono::nanoseconds overriddenClientHealthCheckWindowNs,
125             std::unordered_set<userid_t> stoppedUserIds,
126             std::chrono::milliseconds vhalHealthCheckWindowMillis,
127             const ProcessIdentifier& processIdentifier) {
128         Mutex::Autolock lock(mWatchdogProcessService->mMutex);
129         mWatchdogProcessService->mIsEnabled = isEnabled;
130         mWatchdogProcessService->mMonitor = monitor;
131         mWatchdogProcessService->mOverriddenClientHealthCheckWindowNs =
132                 overriddenClientHealthCheckWindowNs;
133         mWatchdogProcessService->mStoppedUserIds = stoppedUserIds;
134         mWatchdogProcessService->mVhalHealthCheckWindowMillis = vhalHealthCheckWindowMillis;
135         mWatchdogProcessService->mVhalProcessIdentifier = processIdentifier;
136 
137         WatchdogProcessService::ClientInfoMap clientInfoMap;
138         WatchdogProcessService::ClientInfo clientInfo(nullptr, 1, 1, 1000,
139                                                       WatchdogProcessService(nullptr));
140         clientInfo.packageName = "shell";
141         clientInfoMap.insert({100, clientInfo});
142         mWatchdogProcessService->mClientsByTimeout.clear();
143         mWatchdogProcessService->mClientsByTimeout.insert(
144                 {TimeoutLength::TIMEOUT_CRITICAL, clientInfoMap});
145     }
146 
clearClientsByTimeout()147     void clearClientsByTimeout() { mWatchdogProcessService->mClientsByTimeout.clear(); }
148 
hasClientInfoWithPackageName(TimeoutLength timeoutLength,std::string packageName)149     bool hasClientInfoWithPackageName(TimeoutLength timeoutLength, std::string packageName) {
150         auto clientInfoMap = mWatchdogProcessService->mClientsByTimeout[timeoutLength];
151         for (const auto& [_, clientInfo] : clientInfoMap) {
152             if (clientInfo.packageName == packageName) {
153                 return true;
154             }
155         }
156         return false;
157     }
158 
setPackageInfoResolver(const sp<PackageInfoResolverInterface> & packageInfoResolver)159     void setPackageInfoResolver(const sp<PackageInfoResolverInterface>& packageInfoResolver) {
160         mWatchdogProcessService->mPackageInfoResolver = packageInfoResolver;
161     }
162 
163 private:
164     sp<WatchdogProcessService> mWatchdogProcessService;
165 };
166 
167 }  // namespace internal
168 
169 class WatchdogProcessServiceTest : public ::testing::Test {
170 public:
WatchdogProcessServiceTest()171     WatchdogProcessServiceTest() :
172           mMockVhalClient(nullptr),
173           mMockHidlServiceManager(nullptr),
174           kTryCreateVhalClientFunc([this]() { return mMockVhalClient; }),
__anon4d4bfcf10302() 175           kTryGetHidlServiceManagerFunc([this]() { return mMockHidlServiceManager; }),
__anon4d4bfcf10402(pid_t) 176           kGetStartTimeForPidFunc([](pid_t) { return kTestPidStartTime; }) {}
177 
178 protected:
SetUp()179     void SetUp() override {
180         mMessageHandler = sp<MessageHandlerImpl>::make(this);
181         mMockVehicle = SharedRefBase::make<MockVehicle>();
182         mMockVhalClient = std::make_shared<MockVhalClient>(mMockVehicle);
183         mMockHidlServiceManager = sp<MockHidlServiceManager>::make();
184         mMockDeathRegistrationWrapper = sp<MockAIBinderDeathRegistrationWrapper>::make();
185         mSupportedVehicleProperties = {VehicleProperty::VHAL_HEARTBEAT};
186         mNotSupportedVehicleProperties = {VehicleProperty::WATCHDOG_ALIVE,
187                                           VehicleProperty::WATCHDOG_TERMINATED_PROCESS};
188         mMockPackageInfoResolver = sp<MockPackageInfoResolver>::make();
189         startService();
190     }
191 
TearDown()192     void TearDown() override {
193         terminateService();
194         mMockDeathRegistrationWrapper.clear();
195         mMockHidlServiceManager.clear();
196         mMockVhalClient.reset();
197         mMockVehicle.reset();
198         mMessageHandler.clear();
199         mMockPackageInfoResolver.clear();
200     }
201 
startService()202     void startService() {
203         prepareLooper();
204         mWatchdogProcessService =
205                 sp<WatchdogProcessService>::make(kTryCreateVhalClientFunc,
206                                                  kTryGetHidlServiceManagerFunc,
207                                                  kGetStartTimeForPidFunc,
208                                                  kTestVhalPidCachingRetryDelayNs, mHandlerLooper,
209                                                  mMockDeathRegistrationWrapper);
210         mWatchdogProcessServicePeer =
211                 std::make_unique<internal::WatchdogProcessServicePeer>(mWatchdogProcessService);
212         mWatchdogProcessServicePeer->setPackageInfoResolver(mMockPackageInfoResolver);
213 
214         expectGetPropConfigs(mSupportedVehicleProperties, mNotSupportedVehicleProperties);
215 
216         mWatchdogProcessService->start();
217         // Sync with the looper before proceeding to ensure that all startup looper messages are
218         // processed before testing the service.
219         syncLooper();
220     }
221 
terminateService()222     void terminateService() {
223         wakeAndJoinLooper();
224         mWatchdogProcessServicePeer.reset();
225         mWatchdogProcessService->terminate();
226         mWatchdogProcessService.clear();
227         mHandlerLooper.clear();
228     }
229 
expectLinkToDeath(AIBinder * aiBinder,ScopedAStatus expectedStatus)230     void expectLinkToDeath(AIBinder* aiBinder, ScopedAStatus expectedStatus) {
231         EXPECT_CALL(*mMockDeathRegistrationWrapper,
232                     linkToDeath(Eq(aiBinder), _, static_cast<void*>(aiBinder)))
233                 .WillOnce(Return(ByMove(std::move(expectedStatus))));
234     }
235 
expectUnlinkToDeath(AIBinder * aiBinder,ScopedAStatus expectedStatus)236     void expectUnlinkToDeath(AIBinder* aiBinder, ScopedAStatus expectedStatus) {
237         EXPECT_CALL(*mMockDeathRegistrationWrapper,
238                     unlinkToDeath(Eq(aiBinder), _, static_cast<void*>(aiBinder)))
239                 .WillOnce(Return(ByMove(std::move(expectedStatus))));
240     }
241 
expectNoUnlinkToDeath(AIBinder * aiBinder)242     void expectNoUnlinkToDeath(AIBinder* aiBinder) {
243         EXPECT_CALL(*mMockDeathRegistrationWrapper,
244                     unlinkToDeath(Eq(aiBinder), _, static_cast<void*>(aiBinder)))
245                 .Times(0);
246     }
247 
expectGetPropConfigs(const std::vector<VehicleProperty> & supportedProperties,const std::vector<VehicleProperty> & notSupportedProperties)248     void expectGetPropConfigs(const std::vector<VehicleProperty>& supportedProperties,
249                               const std::vector<VehicleProperty>& notSupportedProperties) {
250         for (const auto& propId : supportedProperties) {
251             EXPECT_CALL(*mMockVhalClient,
252                         getPropConfigs(std::vector<int32_t>{static_cast<int32_t>(propId)}))
253                     .WillOnce([]() { return std::vector<std::unique_ptr<IHalPropConfig>>(); });
254         }
255         for (const auto& propId : notSupportedProperties) {
256             EXPECT_CALL(*mMockVhalClient,
257                         getPropConfigs(std::vector<int32_t>{static_cast<int32_t>(propId)}))
258                     .WillOnce(
259                             []() -> VhalClientResult<std::vector<std::unique_ptr<IHalPropConfig>>> {
260                                 return Error<VhalClientError>(ErrorCode::NOT_AVAILABLE_FROM_VHAL)
261                                         << "Not supported";
262                             });
263         }
264     }
265 
266     // Expect the requestAidlVhalPid call from the implementation on registering CarWatchdogService
267     // and mimic CarWatchdogService response by posting the onAidlVhalPidFetched call on the looper.
expectRequestAidlVhalPidAndRespond(const sp<MockWatchdogServiceHelper> & mockServiceHelper)268     void expectRequestAidlVhalPidAndRespond(
269             const sp<MockWatchdogServiceHelper>& mockServiceHelper) {
270         EXPECT_CALL(*mockServiceHelper, requestAidlVhalPid()).WillOnce([&]() {
271             mHandlerLooper->sendMessageDelayed(kTestVhalPidCachingRetryDelayNs.count() / 2,
272                                                mMessageHandler,
273                                                Message(TestMessage::ON_AIDL_VHAL_PID));
274             return ScopedAStatus::ok();
275         });
276     }
277 
syncLooper(std::chrono::nanoseconds delay=0ns)278     void syncLooper(std::chrono::nanoseconds delay = 0ns) {
279         // Acquire the lock before sending message to avoid any race condition.
280         std::unique_lock lock(mMutex);
281         mHandlerLooper->sendMessageDelayed(delay.count(), mMessageHandler,
282                                            Message(TestMessage::NOTIFY_ALL));
283         waitForLooperNotificationLocked(lock, delay);
284     }
285 
waitForLooperNotification(std::chrono::nanoseconds delay=0ns)286     void waitForLooperNotification(std::chrono::nanoseconds delay = 0ns) {
287         std::unique_lock lock(mMutex);
288         waitForLooperNotificationLocked(lock, delay);
289     }
290 
waitForLooperNotificationLocked(std::unique_lock<std::mutex> & lock,std::chrono::nanoseconds delay=0ns)291     void waitForLooperNotificationLocked(std::unique_lock<std::mutex>& lock,
292                                          std::chrono::nanoseconds delay = 0ns) {
293         // If a race condition is detected in the handler looper, the current locking mechanism
294         // should be re-evaluated as discussed in b/299676049.
295         std::cv_status status =
296                 mLooperCondition
297                         .wait_for(lock,
298                                   kMaxWaitForLooperExecutionMillis +
299                                           std::chrono::duration_cast<std::chrono::milliseconds>(
300                                                   delay));
301         ASSERT_EQ(status, std::cv_status::no_timeout) << "Looper notification not received";
302     }
303 
waitUntilVhalPidCachingAttemptsExhausted()304     void waitUntilVhalPidCachingAttemptsExhausted() {
305         syncLooper((kMaxVhalPidCachingAttempts + 1) * kTestVhalPidCachingRetryDelayNs);
306     }
307 
toString(util::ProtoOutputStream * proto)308     std::string toString(util::ProtoOutputStream* proto) {
309         std::string content;
310         content.reserve(proto->size());
311         sp<ProtoReader> reader = proto->data();
312         while (reader->hasNext()) {
313             content.push_back(reader->next());
314         }
315         return content;
316     }
317 
318     sp<WatchdogProcessService> mWatchdogProcessService;
319     std::unique_ptr<internal::WatchdogProcessServicePeer> mWatchdogProcessServicePeer;
320     std::shared_ptr<MockVhalClient> mMockVhalClient;
321     std::shared_ptr<MockVehicle> mMockVehicle;
322     sp<MockHidlServiceManager> mMockHidlServiceManager;
323     sp<MockAIBinderDeathRegistrationWrapper> mMockDeathRegistrationWrapper;
324     std::vector<VehicleProperty> mSupportedVehicleProperties;
325     std::vector<VehicleProperty> mNotSupportedVehicleProperties;
326     sp<MockPackageInfoResolver> mMockPackageInfoResolver;
327 
328 private:
329     class MessageHandlerImpl : public android::MessageHandler {
330     public:
MessageHandlerImpl(WatchdogProcessServiceTest * test)331         explicit MessageHandlerImpl(WatchdogProcessServiceTest* test) : mTest(test) {}
332 
handleMessage(const Message & message)333         void handleMessage(const Message& message) override {
334             switch (message.what) {
335                 case static_cast<int>(TestMessage::NOTIFY_ALL):
336                     break;
337                 case static_cast<int>(TestMessage::ON_AIDL_VHAL_PID):
338                     mTest->mWatchdogProcessService->onAidlVhalPidFetched(kTestAidlVhalPid);
339                     break;
340                 default:
341                     ALOGE("Unknown TestMessage: %d", message.what);
342                     return;
343             }
344             std::unique_lock lock(mTest->mMutex);
345             mTest->mLooperCondition.notify_all();
346         }
347 
348     private:
349         WatchdogProcessServiceTest* mTest;
350     };
351 
352     // Looper runs on the calling thread when it is polled for messages with the poll* calls.
353     // The poll* calls are blocking, so they must be executed on a separate thread.
prepareLooper()354     void prepareLooper() {
355         mHandlerLooper = Looper::prepare(/*opts=*/0);
356         mHandlerLooperThread = std::thread([this]() {
357             Looper::setForThread(mHandlerLooper);
358             if (int result = pthread_setname_np(pthread_self(), kTestLooperThreadName);
359                 result != 0) {
360                 ALOGE("Failed to set test looper thread name: %s", strerror(result));
361             }
362             mShouldTerminateLooper.store(false);
363             while (!mShouldTerminateLooper.load()) {
364                 mHandlerLooper->pollAll(/*timeoutMillis=*/-1);
365             }
366         });
367     }
368 
wakeAndJoinLooper()369     void wakeAndJoinLooper() {
370         // Sync with the looper to make sure all messages for the current time slot are processed
371         // before terminating the looper. This will help satisfy any pending EXPECT_CALLs.
372         syncLooper();
373         mShouldTerminateLooper.store(true);
374         mHandlerLooper->wake();
375         if (mHandlerLooperThread.joinable()) {
376             mHandlerLooperThread.join();
377         }
378     }
379 
380     const std::function<std::shared_ptr<IVhalClient>()> kTryCreateVhalClientFunc;
381     const std::function<android::sp<android::hidl::manager::V1_0::IServiceManager>()>
382             kTryGetHidlServiceManagerFunc;
383     const std::function<int64_t(pid_t)> kGetStartTimeForPidFunc;
384 
385     sp<Looper> mHandlerLooper;
386     sp<MessageHandlerImpl> mMessageHandler;
387     std::thread mHandlerLooperThread;
388     mutable std::mutex mMutex;
389     std::condition_variable mLooperCondition GUARDED_BY(mMutex);
390     std::atomic<bool> mShouldTerminateLooper;
391 };
392 
TEST_F(WatchdogProcessServiceTest,TestTerminate)393 TEST_F(WatchdogProcessServiceTest, TestTerminate) {
394     std::vector<int32_t> propIds = {static_cast<int32_t>(VehicleProperty::VHAL_HEARTBEAT)};
395     EXPECT_CALL(*mMockVhalClient, removeOnBinderDiedCallback(_)).Times(1);
396     EXPECT_CALL(*mMockVehicle, unsubscribe(_, propIds))
397             .WillOnce(Return(ByMove(std::move(ScopedAStatus::ok()))));
398     mWatchdogProcessService->terminate();
399     // TODO(b/217405065): Verify looper removes all MSG_VHAL_HEALTH_CHECK messages.
400 }
401 
402 // TODO(b/217405065): Add test to verify the handleVhalDeath method.
403 
TEST_F(WatchdogProcessServiceTest,TestRegisterClient)404 TEST_F(WatchdogProcessServiceTest, TestRegisterClient) {
405     std::shared_ptr<ICarWatchdogClient> client = SharedRefBase::make<ICarWatchdogClientDefault>();
406     expectLinkToDeath(client->asBinder().get(), std::move(ScopedAStatus::ok()));
407 
408     auto status = mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
409 
410     ASSERT_TRUE(status.isOk()) << status.getMessage();
411 
412     status = mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
413 
414     ASSERT_TRUE(status.isOk()) << status.getMessage();
415 }
416 
TEST_F(WatchdogProcessServiceTest,TestUnregisterClient)417 TEST_F(WatchdogProcessServiceTest, TestUnregisterClient) {
418     std::shared_ptr<ICarWatchdogClient> client = SharedRefBase::make<ICarWatchdogClientDefault>();
419     AIBinder* aiBinder = client->asBinder().get();
420     expectLinkToDeath(aiBinder, std::move(ScopedAStatus::ok()));
421 
422     auto status = mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
423 
424     ASSERT_TRUE(status.isOk()) << status.getMessage();
425 
426     expectUnlinkToDeath(aiBinder, std::move(ScopedAStatus::ok()));
427 
428     status = mWatchdogProcessService->unregisterClient(client);
429 
430     ASSERT_TRUE(status.isOk()) << status.getMessage();
431     ASSERT_FALSE(mWatchdogProcessService->unregisterClient(client).isOk())
432             << "Unregistering an unregistered client should return an error";
433 }
434 
TEST_F(WatchdogProcessServiceTest,TestErrorOnRegisterClientWithDeadBinder)435 TEST_F(WatchdogProcessServiceTest, TestErrorOnRegisterClientWithDeadBinder) {
436     std::shared_ptr<ICarWatchdogClient> client = SharedRefBase::make<ICarWatchdogClientDefault>();
437     expectLinkToDeath(client->asBinder().get(),
438                       std::move(ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED)));
439 
440     ASSERT_FALSE(
441             mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL).isOk())
442             << "When linkToDeath fails, registerClient should return an error";
443 }
444 
TEST_F(WatchdogProcessServiceTest,TestHandleClientBinderDeath)445 TEST_F(WatchdogProcessServiceTest, TestHandleClientBinderDeath) {
446     std::shared_ptr<ICarWatchdogClient> client = SharedRefBase::make<ICarWatchdogClientDefault>();
447     AIBinder* aiBinder = client->asBinder().get();
448     expectLinkToDeath(aiBinder, std::move(ScopedAStatus::ok()));
449 
450     auto status = mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
451 
452     ASSERT_TRUE(status.isOk()) << status.getMessage();
453 
454     mWatchdogProcessService->handleBinderDeath(static_cast<void*>(aiBinder));
455 
456     expectNoUnlinkToDeath(aiBinder);
457 
458     ASSERT_FALSE(mWatchdogProcessService->unregisterClient(client).isOk())
459             << "Unregistering a dead client should return an error";
460 }
461 
TEST_F(WatchdogProcessServiceTest,TestRegisterCarWatchdogService)462 TEST_F(WatchdogProcessServiceTest, TestRegisterCarWatchdogService) {
463     sp<MockWatchdogServiceHelper> mockServiceHelper = sp<MockWatchdogServiceHelper>::make();
464 
465     std::shared_ptr<MockCarWatchdogServiceForSystem> mockService =
466             SharedRefBase::make<MockCarWatchdogServiceForSystem>();
467     const auto binder = mockService->asBinder();
468 
469     EXPECT_CALL(*mockServiceHelper, requestAidlVhalPid())
470             .WillOnce(Return(ByMove(std::move(ScopedAStatus::ok()))));
471 
472     auto status = mWatchdogProcessService->registerCarWatchdogService(binder, mockServiceHelper);
473     ASSERT_TRUE(status.isOk()) << status.getMessage();
474 
475     // The implementation posts message on the looper to cache VHAL pid when registering
476     // the car watchdog service. So, sync with the looper to ensure the above requestAidlVhalPid
477     // EXPECT_CALL is satisfied.
478     syncLooper();
479 
480     // No new request to fetch AIDL VHAL pid should be sent on duplicate registration.
481     EXPECT_CALL(*mockServiceHelper, requestAidlVhalPid()).Times(0);
482 
483     status = mWatchdogProcessService->registerCarWatchdogService(binder, mockServiceHelper);
484     ASSERT_TRUE(status.isOk()) << status.getMessage();
485 }
486 
TEST_F(WatchdogProcessServiceTest,TestErrorOnRegisterCarWatchdogServiceWithNullWatchdogServiceHelper)487 TEST_F(WatchdogProcessServiceTest,
488        TestErrorOnRegisterCarWatchdogServiceWithNullWatchdogServiceHelper) {
489     std::shared_ptr<MockCarWatchdogServiceForSystem> mockService =
490             SharedRefBase::make<MockCarWatchdogServiceForSystem>();
491     const auto binder = mockService->asBinder();
492 
493     ASSERT_FALSE(mWatchdogProcessService->registerCarWatchdogService(binder, nullptr).isOk())
494             << "Registering car watchdog service should fail when watchdog service helper is null";
495 }
496 
TEST_F(WatchdogProcessServiceTest,TestRegisterMonitor)497 TEST_F(WatchdogProcessServiceTest, TestRegisterMonitor) {
498     std::shared_ptr<ICarWatchdogMonitor> monitorOne =
499             SharedRefBase::make<ICarWatchdogMonitorDefault>();
500     expectLinkToDeath(monitorOne->asBinder().get(), std::move(ScopedAStatus::ok()));
501 
502     auto status = mWatchdogProcessService->registerMonitor(monitorOne);
503 
504     ASSERT_TRUE(status.isOk()) << status.getMessage();
505 
506     status = mWatchdogProcessService->registerMonitor(monitorOne);
507 
508     ASSERT_TRUE(status.isOk()) << status.getMessage();
509 
510     std::shared_ptr<ICarWatchdogMonitor> monitorTwo =
511             SharedRefBase::make<ICarWatchdogMonitorDefault>();
512     status = mWatchdogProcessService->registerMonitor(monitorTwo);
513 
514     ASSERT_TRUE(status.isOk()) << status.getMessage();
515 }
516 
TEST_F(WatchdogProcessServiceTest,TestErrorOnRegisterMonitorWithDeadBinder)517 TEST_F(WatchdogProcessServiceTest, TestErrorOnRegisterMonitorWithDeadBinder) {
518     std::shared_ptr<ICarWatchdogMonitor> monitor =
519             SharedRefBase::make<ICarWatchdogMonitorDefault>();
520     expectLinkToDeath(monitor->asBinder().get(),
521                       std::move(ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED)));
522 
523     ASSERT_FALSE(mWatchdogProcessService->registerMonitor(monitor).isOk())
524             << "When linkToDeath fails, registerMonitor should return an error";
525 }
526 
TEST_F(WatchdogProcessServiceTest,TestUnregisterMonitor)527 TEST_F(WatchdogProcessServiceTest, TestUnregisterMonitor) {
528     std::shared_ptr<ICarWatchdogMonitor> monitor =
529             SharedRefBase::make<ICarWatchdogMonitorDefault>();
530     AIBinder* aiBinder = monitor->asBinder().get();
531     expectLinkToDeath(aiBinder, std::move(ScopedAStatus::ok()));
532 
533     auto status = mWatchdogProcessService->registerMonitor(monitor);
534 
535     ASSERT_TRUE(status.isOk()) << status.getMessage();
536 
537     expectUnlinkToDeath(aiBinder, std::move(ScopedAStatus::ok()));
538 
539     status = mWatchdogProcessService->unregisterMonitor(monitor);
540 
541     ASSERT_TRUE(status.isOk()) << status.getMessage();
542     ASSERT_FALSE(mWatchdogProcessService->unregisterMonitor(monitor).isOk())
543             << "Unregistering an unregistered monitor should return an error";
544 }
545 
TEST_F(WatchdogProcessServiceTest,TestHandleMonitorBinderDeath)546 TEST_F(WatchdogProcessServiceTest, TestHandleMonitorBinderDeath) {
547     std::shared_ptr<ICarWatchdogMonitor> monitor =
548             SharedRefBase::make<ICarWatchdogMonitorDefault>();
549     AIBinder* aiBinder = monitor->asBinder().get();
550     expectLinkToDeath(aiBinder, std::move(ScopedAStatus::ok()));
551 
552     auto status = mWatchdogProcessService->registerMonitor(monitor);
553 
554     ASSERT_TRUE(status.isOk()) << status.getMessage();
555 
556     mWatchdogProcessService->handleBinderDeath(static_cast<void*>(aiBinder));
557 
558     expectNoUnlinkToDeath(aiBinder);
559 
560     ASSERT_FALSE(mWatchdogProcessService->unregisterMonitor(monitor).isOk())
561             << "Unregistering a dead monitor should return an error";
562 }
563 
TEST_F(WatchdogProcessServiceTest,TestTellClientAlive)564 TEST_F(WatchdogProcessServiceTest, TestTellClientAlive) {
565     std::shared_ptr<ICarWatchdogClient> client = SharedRefBase::make<ICarWatchdogClientDefault>();
566     expectLinkToDeath(client->asBinder().get(), std::move(ScopedAStatus::ok()));
567 
568     mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
569 
570     ASSERT_FALSE(mWatchdogProcessService->tellClientAlive(client, 1234).isOk())
571             << "tellClientAlive not synced with checkIfAlive should return an error";
572 }
573 
TEST_F(WatchdogProcessServiceTest,TestTellCarWatchdogServiceAlive)574 TEST_F(WatchdogProcessServiceTest, TestTellCarWatchdogServiceAlive) {
575     std::shared_ptr<MockCarWatchdogServiceForSystem> mockService =
576             SharedRefBase::make<MockCarWatchdogServiceForSystem>();
577 
578     std::vector<ProcessIdentifier> processIdentifiers;
579     processIdentifiers.push_back(
580             constructProcessIdentifier(/* pid= */ 111, /* startTimeMillis= */ 0));
581     processIdentifiers.push_back(
582             constructProcessIdentifier(/* pid= */ 222, /* startTimeMillis= */ 0));
583     ASSERT_FALSE(mWatchdogProcessService
584                          ->tellCarWatchdogServiceAlive(mockService, processIdentifiers, 1234)
585                          .isOk())
586             << "tellCarWatchdogServiceAlive not synced with checkIfAlive should return an error";
587 }
588 
TEST_F(WatchdogProcessServiceTest,TestTellDumpFinished)589 TEST_F(WatchdogProcessServiceTest, TestTellDumpFinished) {
590     std::shared_ptr<ICarWatchdogMonitor> monitor =
591             SharedRefBase::make<ICarWatchdogMonitorDefault>();
592     ASSERT_FALSE(mWatchdogProcessService
593                          ->tellDumpFinished(monitor,
594                                             constructProcessIdentifier(/* pid= */ 1234,
595                                                                        /* startTimeMillis= */ 0))
596                          .isOk())
597             << "Unregistered monitor cannot call tellDumpFinished";
598 
599     expectLinkToDeath(monitor->asBinder().get(), std::move(ScopedAStatus::ok()));
600 
601     mWatchdogProcessService->registerMonitor(monitor);
602     auto status = mWatchdogProcessService
603                           ->tellDumpFinished(monitor,
604                                              constructProcessIdentifier(/* pid= */ 1234,
605                                                                         /* startTimeMillis= */ 0));
606 
607     ASSERT_TRUE(status.isOk()) << status.getMessage();
608 }
609 
TEST_F(WatchdogProcessServiceTest,TestCacheAidlVhalPidFromCarWatchdogService)610 TEST_F(WatchdogProcessServiceTest, TestCacheAidlVhalPidFromCarWatchdogService) {
611     sp<MockWatchdogServiceHelper> mockServiceHelper = sp<MockWatchdogServiceHelper>::make();
612 
613     std::shared_ptr<MockCarWatchdogServiceForSystem> mockService =
614             SharedRefBase::make<MockCarWatchdogServiceForSystem>();
615     const auto binder = mockService->asBinder();
616 
617     expectRequestAidlVhalPidAndRespond(mockServiceHelper);
618 
619     auto status = mWatchdogProcessService->registerCarWatchdogService(binder, mockServiceHelper);
620     ASSERT_TRUE(status.isOk()) << status.getMessage();
621 
622     // On processing the TestMessage::ON_AIDL_VHAL_PID, the looper notifies all waiting threads.
623     // Wait for the notification to ensure the VHAL pid caching is satisfied.
624     waitForLooperNotification();
625 
626     ASSERT_NO_FATAL_FAILURE(mWatchdogProcessServicePeer->expectVhalProcessIdentifier(
627             ProcessIdentifierEq(constructProcessIdentifier(kTestAidlVhalPid, kTestPidStartTime))));
628 }
629 
TEST_F(WatchdogProcessServiceTest,TestFailsCacheAidlVhalPidWithNoCarWatchdogServiceResponse)630 TEST_F(WatchdogProcessServiceTest, TestFailsCacheAidlVhalPidWithNoCarWatchdogServiceResponse) {
631     sp<MockWatchdogServiceHelper> mockServiceHelper = sp<MockWatchdogServiceHelper>::make();
632 
633     std::shared_ptr<MockCarWatchdogServiceForSystem> mockService =
634             SharedRefBase::make<MockCarWatchdogServiceForSystem>();
635     const auto binder = mockService->asBinder();
636 
637     EXPECT_CALL(*mockServiceHelper, requestAidlVhalPid())
638             .Times(kMaxVhalPidCachingAttempts)
639             .WillRepeatedly([&]() {
640                 // No action taken by CarWatchdogService.
641                 return ScopedAStatus::ok();
642             });
643 
644     auto status = mWatchdogProcessService->registerCarWatchdogService(binder, mockServiceHelper);
645     ASSERT_TRUE(status.isOk()) << status.getMessage();
646 
647     // Because CarWatchdogService doesn't respond with the AIDL VHAL pid, wait until all caching
648     // attempts are exhausted to ensure the expected number of caching attempts are satisfied.
649     waitUntilVhalPidCachingAttemptsExhausted();
650 
651     ASSERT_NO_FATAL_FAILURE(mWatchdogProcessServicePeer->expectNoVhalProcessIdentifier());
652 }
653 
TEST_F(WatchdogProcessServiceTest,TestNoCacheAidlVhalPidWithUnsupportedVhalHeartBeatProperty)654 TEST_F(WatchdogProcessServiceTest, TestNoCacheAidlVhalPidWithUnsupportedVhalHeartBeatProperty) {
655     // The supported vehicle property list is fetched as soon as VHAL is connected, which happens
656     // during the start of the service. So, restart the service for the new VHAL settings to take
657     // effect.
658     terminateService();
659 
660     mSupportedVehicleProperties.clear();
661     mNotSupportedVehicleProperties.push_back(VehicleProperty::VHAL_HEARTBEAT);
662 
663     startService();
664 
665     sp<MockWatchdogServiceHelper> mockServiceHelper = sp<MockWatchdogServiceHelper>::make();
666     std::shared_ptr<MockCarWatchdogServiceForSystem> mockService =
667             SharedRefBase::make<MockCarWatchdogServiceForSystem>();
668     const auto binder = mockService->asBinder();
669 
670     EXPECT_CALL(*mockServiceHelper, requestAidlVhalPid()).Times(0);
671 
672     auto status = mWatchdogProcessService->registerCarWatchdogService(binder, mockServiceHelper);
673     ASSERT_TRUE(status.isOk()) << status.getMessage();
674 
675     // VHAL process identifier caching happens on the looper thread. Sync with the looper before
676     // proceeding.
677     syncLooper();
678 
679     ASSERT_NO_FATAL_FAILURE(mWatchdogProcessServicePeer->expectNoVhalProcessIdentifier());
680 }
681 
TEST_F(WatchdogProcessServiceTest,TestCacheHidlVhalPidFromHidlServiceManager)682 TEST_F(WatchdogProcessServiceTest, TestCacheHidlVhalPidFromHidlServiceManager) {
683     // VHAL PID caching logic is determined as soon as VHAL is connected, which happens during
684     // the start of the service. So, restart the service for the new VHAL settings to take effect.
685     terminateService();
686 
687     using InstanceDebugInfo = IServiceManager::InstanceDebugInfo;
688     EXPECT_CALL(*mMockVhalClient, isAidlVhal()).WillOnce(Return(false));
689     EXPECT_CALL(*mMockHidlServiceManager, debugDump(_))
690             .WillOnce(Invoke([](IServiceManager::debugDump_cb cb) {
691                 cb({InstanceDebugInfo{"android.hardware.automotive.evs@1.0::IEvsCamera",
692                                       "vehicle_hal_insts",
693                                       8058,
694                                       {},
695                                       DebugInfo::Architecture::IS_64BIT},
696                     InstanceDebugInfo{"android.hardware.automotive.vehicle@2.0::IVehicle",
697                                       "vehicle_hal_insts",
698                                       static_cast<int>(IServiceManager::PidConstant::NO_PID),
699                                       {},
700                                       DebugInfo::Architecture::IS_64BIT},
701                     InstanceDebugInfo{"android.hardware.automotive.vehicle@2.0::IVehicle",
702                                       "vehicle_hal_insts",
703                                       2034,
704                                       {},
705                                       DebugInfo::Architecture::IS_64BIT}});
706                 return android::hardware::Void();
707             }));
708 
709     startService();
710 
711     ASSERT_NO_FATAL_FAILURE(mWatchdogProcessServicePeer->expectVhalProcessIdentifier(
712             ProcessIdentifierEq(constructProcessIdentifier(2034, kTestPidStartTime))));
713 }
714 
TEST_F(WatchdogProcessServiceTest,TestFailsCacheHidlVhalPidWithNoHidlVhalService)715 TEST_F(WatchdogProcessServiceTest, TestFailsCacheHidlVhalPidWithNoHidlVhalService) {
716     // VHAL PID caching logic is determined as soon as VHAL is connected, which happens during
717     // the start of the service. So, restart the service for the new VHAL settings to take effect.
718     terminateService();
719 
720     using InstanceDebugInfo = IServiceManager::InstanceDebugInfo;
721     EXPECT_CALL(*mMockVhalClient, isAidlVhal()).WillRepeatedly(Return(false));
722     EXPECT_CALL(*mMockHidlServiceManager, debugDump(_))
723             .Times(kMaxVhalPidCachingAttempts)
724             .WillRepeatedly(Invoke([](IServiceManager::debugDump_cb cb) {
725                 cb({InstanceDebugInfo{"android.hardware.automotive.evs@1.0::IEvsCamera",
726                                       "vehicle_hal_insts",
727                                       8058,
728                                       {},
729                                       DebugInfo::Architecture::IS_64BIT}});
730                 return android::hardware::Void();
731             }));
732 
733     startService();
734 
735     // Because HIDL service manager doesn't have the HIDL VHAL pid, wait until all caching
736     // attempts are exhausted to ensure the expected number of caching attempts are satisfied.
737     waitUntilVhalPidCachingAttemptsExhausted();
738 
739     ASSERT_NO_FATAL_FAILURE(mWatchdogProcessServicePeer->expectNoVhalProcessIdentifier());
740 }
741 
TEST_F(WatchdogProcessServiceTest,TestNoCacheHidlVhalPidWithUnsupportedVhalHeartBeatProperty)742 TEST_F(WatchdogProcessServiceTest, TestNoCacheHidlVhalPidWithUnsupportedVhalHeartBeatProperty) {
743     // The supported vehicle property list is fetched as soon as VHAL is connected, which happens
744     // during the start of the service. So, restart the service for the new VHAL settings to take
745     // effect.
746     terminateService();
747 
748     mSupportedVehicleProperties.clear();
749     mNotSupportedVehicleProperties.push_back(VehicleProperty::VHAL_HEARTBEAT);
750 
751     EXPECT_CALL(*mMockHidlServiceManager, debugDump(_)).Times(0);
752 
753     startService();
754 
755     ASSERT_NO_FATAL_FAILURE(mWatchdogProcessServicePeer->expectNoVhalProcessIdentifier());
756 }
757 
TEST_F(WatchdogProcessServiceTest,TestOnDumpProto)758 TEST_F(WatchdogProcessServiceTest, TestOnDumpProto) {
759     ProcessIdentifier processIdentifier;
760     processIdentifier.pid = 1;
761     processIdentifier.startTimeMillis = 1000;
762 
763     mWatchdogProcessServicePeer->setWatchdogProcessServiceState(true, nullptr,
764                                                                 std::chrono::milliseconds(20000),
765                                                                 {101, 102},
766                                                                 std::chrono::milliseconds(10000),
767                                                                 processIdentifier);
768 
769     util::ProtoOutputStream proto;
770     mWatchdogProcessService->onDumpProto(proto);
771 
772     CarWatchdogDaemonDump carWatchdogDaemonDump;
773     ASSERT_TRUE(carWatchdogDaemonDump.ParseFromString(toString(&proto)));
774     HealthCheckServiceDump healthCheckServiceDump =
775             carWatchdogDaemonDump.health_check_service_dump();
776     EXPECT_EQ(healthCheckServiceDump.is_enabled(), true);
777     EXPECT_EQ(healthCheckServiceDump.is_monitor_registered(), false);
778     EXPECT_EQ(healthCheckServiceDump.is_system_shut_down_in_progress(), false);
779     EXPECT_EQ(healthCheckServiceDump.stopped_users_size(), 2);
780     EXPECT_EQ(healthCheckServiceDump.critical_health_check_window_millis(), 20000);
781     EXPECT_EQ(healthCheckServiceDump.moderate_health_check_window_millis(), 20000);
782     EXPECT_EQ(healthCheckServiceDump.normal_health_check_window_millis(), 20000);
783 
784     VhalHealthCheckInfo vhalHealthCheckInfo = healthCheckServiceDump.vhal_health_check_info();
785 
786     EXPECT_EQ(vhalHealthCheckInfo.is_enabled(), true);
787     EXPECT_EQ(vhalHealthCheckInfo.health_check_window_millis(), 10000);
788     EXPECT_EQ(vhalHealthCheckInfo.pid_caching_progress_state(),
789               VhalHealthCheckInfo_CachingProgressState_SUCCESS);
790     EXPECT_EQ(vhalHealthCheckInfo.pid(), 1);
791     EXPECT_EQ(vhalHealthCheckInfo.start_time_millis(), 1000);
792 
793     EXPECT_EQ(healthCheckServiceDump.registered_client_infos_size(), 1);
794     HealthCheckClientInfo healthCheckClientInfo = healthCheckServiceDump.registered_client_infos(0);
795     EXPECT_EQ(healthCheckClientInfo.pid(), 1);
796 
797     UserPackageInfo userPackageInfo = healthCheckClientInfo.user_package_info();
798     EXPECT_EQ(userPackageInfo.user_id(), 1);
799     EXPECT_EQ(userPackageInfo.package_name(), "shell");
800 
801     EXPECT_EQ(healthCheckClientInfo.client_type(), HealthCheckClientInfo_ClientType_REGULAR);
802     EXPECT_EQ(healthCheckClientInfo.start_time_millis(), 1000);
803     EXPECT_EQ(healthCheckClientInfo.health_check_timeout(),
804               HealthCheckClientInfo_HealthCheckTimeout_CRITICAL);
805 
806     // Clean up test clients before exiting.
807     mWatchdogProcessServicePeer->clearClientsByTimeout();
808 }
809 
TEST_F(WatchdogProcessServiceTest,TestRegisterClientWithPackageName)810 TEST_F(WatchdogProcessServiceTest, TestRegisterClientWithPackageName) {
811     std::shared_ptr<ICarWatchdogClient> client = SharedRefBase::make<ICarWatchdogClientDefault>();
812     ON_CALL(*mMockPackageInfoResolver, asyncFetchPackageNamesForUids(_, _))
813             .WillByDefault([&](const std::vector<uid_t>& uids,
814                                const std::function<void(std::unordered_map<uid_t, std::string>)>&
815                                        callback) {
816                 callback({{uids[0], "shell"}});
817             });
818 
819     ASSERT_FALSE(mWatchdogProcessServicePeer
820                          ->hasClientInfoWithPackageName(TimeoutLength::TIMEOUT_CRITICAL, "shell"));
821 
822     auto status = mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
823 
824     ASSERT_TRUE(mWatchdogProcessServicePeer
825                         ->hasClientInfoWithPackageName(TimeoutLength::TIMEOUT_CRITICAL, "shell"));
826 }
827 
TEST_F(WatchdogProcessServiceTest,TestRegisterClientWithPackageNameAndNonExistentUid)828 TEST_F(WatchdogProcessServiceTest, TestRegisterClientWithPackageNameAndNonExistentUid) {
829     std::shared_ptr<ICarWatchdogClient> client = SharedRefBase::make<ICarWatchdogClientDefault>();
830     ON_CALL(*mMockPackageInfoResolver, asyncFetchPackageNamesForUids(_, _))
831             .WillByDefault([&](const std::vector<uid_t>& uids,
832                                const std::function<void(std::unordered_map<uid_t, std::string>)>&
833                                        callback) {
834                 callback({});
835                 ALOGI("No corresponding packageName for uid: %i", uids[0]);
836             });
837 
838     ASSERT_FALSE(mWatchdogProcessServicePeer
839                          ->hasClientInfoWithPackageName(TimeoutLength::TIMEOUT_CRITICAL, "shell"));
840 
841     auto status = mWatchdogProcessService->registerClient(client, TimeoutLength::TIMEOUT_CRITICAL);
842 
843     ASSERT_FALSE(mWatchdogProcessServicePeer
844                          ->hasClientInfoWithPackageName(TimeoutLength::TIMEOUT_CRITICAL, "shell"));
845 }
846 
847 }  // namespace watchdog
848 }  // namespace automotive
849 }  // namespace android
850