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