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