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