• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "WatchdogBinderMediator.h"
18 
19 #include <android/automotive/watchdog/BootPhase.h>
20 #include <android/automotive/watchdog/PowerCycle.h>
21 #include <android/automotive/watchdog/UserState.h>
22 #include <binder/IBinder.h>
23 #include <binder/IPCThreadState.h>
24 #include <errno.h>
25 #include <gtest/gtest.h>
26 #include <private/android_filesystem_config.h>
27 #include <utils/RefBase.h>
28 
29 #include "gmock/gmock.h"
30 
31 namespace android {
32 namespace automotive {
33 namespace watchdog {
34 
35 using android::sp;
36 using android::base::Result;
37 using binder::Status;
38 using ::testing::_;
39 using ::testing::Return;
40 
41 namespace {
42 
43 class MockWatchdogProcessService : public WatchdogProcessService {
44 public:
MockWatchdogProcessService()45     MockWatchdogProcessService() : WatchdogProcessService(nullptr) {}
46     MOCK_METHOD(Result<void>, dump, (int fd, const Vector<String16>& args), (override));
47 
48     MOCK_METHOD(Status, registerClient,
49                 (const sp<ICarWatchdogClient>& client, TimeoutLength timeout), (override));
50     MOCK_METHOD(Status, unregisterClient, (const sp<ICarWatchdogClient>& client), (override));
51     MOCK_METHOD(Status, registerMediator, (const sp<ICarWatchdogClient>& mediator), (override));
52     MOCK_METHOD(Status, unregisterMediator, (const sp<ICarWatchdogClient>& mediator), (override));
53     MOCK_METHOD(Status, registerMonitor, (const sp<ICarWatchdogMonitor>& monitor), (override));
54     MOCK_METHOD(Status, unregisterMonitor, (const sp<ICarWatchdogMonitor>& monitor), (override));
55     MOCK_METHOD(Status, tellClientAlive, (const sp<ICarWatchdogClient>& client, int32_t sessionId),
56                 (override));
57     MOCK_METHOD(Status, tellMediatorAlive,
58                 (const sp<ICarWatchdogClient>& mediator,
59                  const std::vector<int32_t>& clientsNotResponding, int32_t sessionId),
60                 (override));
61     MOCK_METHOD(Status, tellDumpFinished,
62                 (const android::sp<ICarWatchdogMonitor>& monitor, int32_t pid), (override));
63     MOCK_METHOD(Status, notifyPowerCycleChange, (PowerCycle cycle), (override));
64     MOCK_METHOD(Status, notifyUserStateChange, (userid_t userId, UserState state), (override));
65     MOCK_METHOD(void, binderDied, (const android::wp<IBinder>& who), (override));
66 };
67 
68 class MockIoPerfCollection : public IoPerfCollection {
69 public:
MockIoPerfCollection()70     MockIoPerfCollection() {}
71     MOCK_METHOD(Result<void>, onBootFinished, (), (override));
72     MOCK_METHOD(Result<void>, onCustomCollection, (int fd, const Vector<String16>& args),
73                 (override));
74     MOCK_METHOD(Result<void>, onDump, (int fd), (override));
75 };
76 
77 class MockICarWatchdogClient : public ICarWatchdogClient {
78 public:
79     MOCK_METHOD(Status, checkIfAlive, (int32_t sessionId, TimeoutLength timeout), (override));
80     MOCK_METHOD(Status, prepareProcessTermination, (), (override));
81     MOCK_METHOD(IBinder*, onAsBinder, (), (override));
82     MOCK_METHOD(int32_t, getInterfaceVersion, (), (override));
83     MOCK_METHOD(std::string, getInterfaceHash, (), (override));
84 };
85 
86 class MockICarWatchdogMonitor : public ICarWatchdogMonitor {
87 public:
88     MOCK_METHOD(Status, onClientsNotResponding, (const std::vector<int32_t>& pids), (override));
89     MOCK_METHOD(IBinder*, onAsBinder, (), (override));
90     MOCK_METHOD(int32_t, getInterfaceVersion, (), (override));
91     MOCK_METHOD(std::string, getInterfaceHash, (), (override));
92 };
93 
94 class ScopedChangeCallingUid : public RefBase {
95 public:
ScopedChangeCallingUid(uid_t uid)96     explicit ScopedChangeCallingUid(uid_t uid) {
97         mCallingUid = IPCThreadState::self()->getCallingUid();
98         mCallingPid = IPCThreadState::self()->getCallingPid();
99         if (mCallingUid == uid) {
100             return;
101         }
102         mChangedUid = uid;
103         int64_t token = ((int64_t)mChangedUid << 32) | mCallingPid;
104         IPCThreadState::self()->restoreCallingIdentity(token);
105     }
~ScopedChangeCallingUid()106     ~ScopedChangeCallingUid() {
107         if (mCallingUid == mChangedUid) {
108             return;
109         }
110         int64_t token = ((int64_t)mCallingUid << 32) | mCallingPid;
111         IPCThreadState::self()->restoreCallingIdentity(token);
112     }
113 
114 private:
115     uid_t mCallingUid;
116     uid_t mChangedUid;
117     pid_t mCallingPid;
118 };
119 
120 }  // namespace
121 
122 class WatchdogBinderMediatorTest : public ::testing::Test {
123 protected:
SetUp()124     virtual void SetUp() {
125         mMockWatchdogProcessService = new MockWatchdogProcessService();
126         mMockIoPerfCollection = new MockIoPerfCollection();
127         mWatchdogBinderMediator = new WatchdogBinderMediator();
128         mWatchdogBinderMediator->init(mMockWatchdogProcessService, mMockIoPerfCollection);
129     }
TearDown()130     virtual void TearDown() {
131         mWatchdogBinderMediator->terminate();
132         ASSERT_TRUE(mWatchdogBinderMediator->mWatchdogProcessService == nullptr);
133         ASSERT_TRUE(mWatchdogBinderMediator->mIoPerfCollection == nullptr);
134         mMockWatchdogProcessService = nullptr;
135         mMockIoPerfCollection = nullptr;
136         mWatchdogBinderMediator = nullptr;
137         mScopedChangeCallingUid = nullptr;
138     }
139     // Sets calling UID to imitate System's process.
setSystemCallingUid()140     void setSystemCallingUid() { mScopedChangeCallingUid = new ScopedChangeCallingUid(AID_SYSTEM); }
141     sp<MockWatchdogProcessService> mMockWatchdogProcessService;
142     sp<MockIoPerfCollection> mMockIoPerfCollection;
143     sp<WatchdogBinderMediator> mWatchdogBinderMediator;
144     sp<ScopedChangeCallingUid> mScopedChangeCallingUid;
145 };
146 
TEST_F(WatchdogBinderMediatorTest,TestErrorOnNullptrDuringInit)147 TEST_F(WatchdogBinderMediatorTest, TestErrorOnNullptrDuringInit) {
148     sp<WatchdogBinderMediator> mediator = new WatchdogBinderMediator();
149     ASSERT_FALSE(mediator->init(nullptr, new MockIoPerfCollection()).ok())
150             << "No error returned on nullptr watchdog process service";
151     ASSERT_FALSE(mediator->init(new MockWatchdogProcessService(), nullptr).ok())
152             << "No error returned on nullptr I/O perf collection";
153     ASSERT_FALSE(mediator->init(nullptr, nullptr).ok()) << "No error returned on nullptr";
154 }
155 
TEST_F(WatchdogBinderMediatorTest,TestHandlesEmptyDumpArgs)156 TEST_F(WatchdogBinderMediatorTest, TestHandlesEmptyDumpArgs) {
157     EXPECT_CALL(*mMockWatchdogProcessService, dump(-1, _)).WillOnce(Return(Result<void>()));
158     EXPECT_CALL(*mMockIoPerfCollection, onDump(-1)).WillOnce(Return(Result<void>()));
159     mWatchdogBinderMediator->dump(-1, Vector<String16>());
160 }
161 
TEST_F(WatchdogBinderMediatorTest,TestHandlesStartCustomIoPerfCollection)162 TEST_F(WatchdogBinderMediatorTest, TestHandlesStartCustomIoPerfCollection) {
163     EXPECT_CALL(*mMockIoPerfCollection, onCustomCollection(-1, _)).WillOnce(Return(Result<void>()));
164 
165     Vector<String16> args;
166     args.push_back(String16(kStartCustomCollectionFlag));
167     ASSERT_EQ(mWatchdogBinderMediator->dump(-1, args), OK);
168 }
169 
TEST_F(WatchdogBinderMediatorTest,TestHandlesStopCustomIoPerfCollection)170 TEST_F(WatchdogBinderMediatorTest, TestHandlesStopCustomIoPerfCollection) {
171     EXPECT_CALL(*mMockIoPerfCollection, onCustomCollection(-1, _)).WillOnce(Return(Result<void>()));
172 
173     Vector<String16> args;
174     args.push_back(String16(kEndCustomCollectionFlag));
175     ASSERT_EQ(mWatchdogBinderMediator->dump(-1, args), OK);
176 }
177 
TEST_F(WatchdogBinderMediatorTest,TestErrorOnInvalidDumpArgs)178 TEST_F(WatchdogBinderMediatorTest, TestErrorOnInvalidDumpArgs) {
179     Vector<String16> args;
180     args.push_back(String16("--invalid_option"));
181     ASSERT_EQ(mWatchdogBinderMediator->dump(-1, args), OK) << "Error returned on invalid args";
182 }
183 
TEST_F(WatchdogBinderMediatorTest,TestRegisterClient)184 TEST_F(WatchdogBinderMediatorTest, TestRegisterClient) {
185     sp<ICarWatchdogClient> client = new MockICarWatchdogClient();
186     TimeoutLength timeout = TimeoutLength::TIMEOUT_MODERATE;
187     EXPECT_CALL(*mMockWatchdogProcessService, registerClient(client, timeout))
188             .WillOnce(Return(Status::ok()));
189     Status status = mWatchdogBinderMediator->registerClient(client, timeout);
190     ASSERT_TRUE(status.isOk()) << status;
191 }
192 
TEST_F(WatchdogBinderMediatorTest,TestUnregisterClient)193 TEST_F(WatchdogBinderMediatorTest, TestUnregisterClient) {
194     sp<ICarWatchdogClient> client = new MockICarWatchdogClient();
195     EXPECT_CALL(*mMockWatchdogProcessService, unregisterClient(client))
196             .WillOnce(Return(Status::ok()));
197     Status status = mWatchdogBinderMediator->unregisterClient(client);
198     ASSERT_TRUE(status.isOk()) << status;
199 }
200 
TEST_F(WatchdogBinderMediatorTest,TestRegisterMediator)201 TEST_F(WatchdogBinderMediatorTest, TestRegisterMediator) {
202     setSystemCallingUid();
203     sp<ICarWatchdogClient> mediator = new MockICarWatchdogClient();
204     EXPECT_CALL(*mMockWatchdogProcessService, registerMediator(mediator))
205             .WillOnce(Return(Status::ok()));
206     Status status = mWatchdogBinderMediator->registerMediator(mediator);
207     ASSERT_TRUE(status.isOk()) << status;
208 }
209 
TEST_F(WatchdogBinderMediatorTest,TestErrorOnRegisterMediatorWithNonSystemCallingUid)210 TEST_F(WatchdogBinderMediatorTest, TestErrorOnRegisterMediatorWithNonSystemCallingUid) {
211     sp<ICarWatchdogClient> mediator = new MockICarWatchdogClient();
212     EXPECT_CALL(*mMockWatchdogProcessService, registerMediator(mediator)).Times(0);
213     Status status = mWatchdogBinderMediator->registerMediator(mediator);
214     ASSERT_FALSE(status.isOk()) << status;
215 }
216 
TEST_F(WatchdogBinderMediatorTest,TestUnregisterMediator)217 TEST_F(WatchdogBinderMediatorTest, TestUnregisterMediator) {
218     setSystemCallingUid();
219     sp<ICarWatchdogClient> mediator = new MockICarWatchdogClient();
220     EXPECT_CALL(*mMockWatchdogProcessService, unregisterMediator(mediator))
221             .WillOnce(Return(Status::ok()));
222     Status status = mWatchdogBinderMediator->unregisterMediator(mediator);
223     ASSERT_TRUE(status.isOk()) << status;
224 }
225 
TEST_F(WatchdogBinderMediatorTest,TestErrorOnUnegisterMediatorWithNonSystemCallingUid)226 TEST_F(WatchdogBinderMediatorTest, TestErrorOnUnegisterMediatorWithNonSystemCallingUid) {
227     sp<ICarWatchdogClient> mediator = new MockICarWatchdogClient();
228     EXPECT_CALL(*mMockWatchdogProcessService, unregisterMediator(mediator)).Times(0);
229     Status status = mWatchdogBinderMediator->unregisterMediator(mediator);
230     ASSERT_FALSE(status.isOk()) << status;
231 }
232 
TEST_F(WatchdogBinderMediatorTest,TestRegisterMonitor)233 TEST_F(WatchdogBinderMediatorTest, TestRegisterMonitor) {
234     setSystemCallingUid();
235     sp<ICarWatchdogMonitor> monitor = new MockICarWatchdogMonitor();
236     EXPECT_CALL(*mMockWatchdogProcessService, registerMonitor(monitor))
237             .WillOnce(Return(Status::ok()));
238     Status status = mWatchdogBinderMediator->registerMonitor(monitor);
239     ASSERT_TRUE(status.isOk()) << status;
240 }
241 
TEST_F(WatchdogBinderMediatorTest,TestErrorOnRegisterMonitorWithNonSystemCallingUid)242 TEST_F(WatchdogBinderMediatorTest, TestErrorOnRegisterMonitorWithNonSystemCallingUid) {
243     sp<ICarWatchdogMonitor> monitor = new MockICarWatchdogMonitor();
244     EXPECT_CALL(*mMockWatchdogProcessService, registerMonitor(monitor)).Times(0);
245     Status status = mWatchdogBinderMediator->registerMonitor(monitor);
246     ASSERT_FALSE(status.isOk()) << status;
247 }
248 
TEST_F(WatchdogBinderMediatorTest,TestUnregisterMonitor)249 TEST_F(WatchdogBinderMediatorTest, TestUnregisterMonitor) {
250     setSystemCallingUid();
251     sp<ICarWatchdogMonitor> monitor = new MockICarWatchdogMonitor();
252     EXPECT_CALL(*mMockWatchdogProcessService, unregisterMonitor(monitor))
253             .WillOnce(Return(Status::ok()));
254     Status status = mWatchdogBinderMediator->unregisterMonitor(monitor);
255     ASSERT_TRUE(status.isOk()) << status;
256 }
257 
TEST_F(WatchdogBinderMediatorTest,TestErrorOnUnregisterMonitorWithNonSystemCallingUid)258 TEST_F(WatchdogBinderMediatorTest, TestErrorOnUnregisterMonitorWithNonSystemCallingUid) {
259     sp<ICarWatchdogMonitor> monitor = new MockICarWatchdogMonitor();
260     EXPECT_CALL(*mMockWatchdogProcessService, unregisterMonitor(monitor)).Times(0);
261     Status status = mWatchdogBinderMediator->unregisterMonitor(monitor);
262     ASSERT_FALSE(status.isOk()) << status;
263 }
264 
TEST_F(WatchdogBinderMediatorTest,TestTellClientAlive)265 TEST_F(WatchdogBinderMediatorTest, TestTellClientAlive) {
266     sp<ICarWatchdogClient> client = new MockICarWatchdogClient();
267     EXPECT_CALL(*mMockWatchdogProcessService, tellClientAlive(client, 456))
268             .WillOnce(Return(Status::ok()));
269     Status status = mWatchdogBinderMediator->tellClientAlive(client, 456);
270     ASSERT_TRUE(status.isOk()) << status;
271 }
272 
TEST_F(WatchdogBinderMediatorTest,TestErrorOnTellMediatorAliveWithNonSystemCallingUid)273 TEST_F(WatchdogBinderMediatorTest, TestErrorOnTellMediatorAliveWithNonSystemCallingUid) {
274     sp<ICarWatchdogClient> mediator = new MockICarWatchdogClient();
275     std::vector clientsNotResponding = {123};
276     EXPECT_CALL(*mMockWatchdogProcessService, tellMediatorAlive(_, _, _)).Times(0);
277     Status status = mWatchdogBinderMediator->tellMediatorAlive(mediator, clientsNotResponding, 456);
278     ASSERT_FALSE(status.isOk()) << status;
279 }
280 
TEST_F(WatchdogBinderMediatorTest,TestTellMediatorAlive)281 TEST_F(WatchdogBinderMediatorTest, TestTellMediatorAlive) {
282     setSystemCallingUid();
283     sp<ICarWatchdogClient> mediator = new MockICarWatchdogClient();
284     std::vector clientsNotResponding = {123};
285     EXPECT_CALL(*mMockWatchdogProcessService,
286                 tellMediatorAlive(mediator, clientsNotResponding, 456))
287             .WillOnce(Return(Status::ok()));
288     Status status = mWatchdogBinderMediator->tellMediatorAlive(mediator, clientsNotResponding, 456);
289     ASSERT_TRUE(status.isOk()) << status;
290 }
291 
TEST_F(WatchdogBinderMediatorTest,TestErrorOnTellDumpFinishedWithNonSystemCallingUid)292 TEST_F(WatchdogBinderMediatorTest, TestErrorOnTellDumpFinishedWithNonSystemCallingUid) {
293     sp<ICarWatchdogMonitor> monitor = new MockICarWatchdogMonitor();
294     EXPECT_CALL(*mMockWatchdogProcessService, tellDumpFinished(_, _)).Times(0);
295     Status status = mWatchdogBinderMediator->tellDumpFinished(monitor, 456);
296     ASSERT_FALSE(status.isOk()) << status;
297 }
298 
TEST_F(WatchdogBinderMediatorTest,TestTellDumpFinished)299 TEST_F(WatchdogBinderMediatorTest, TestTellDumpFinished) {
300     setSystemCallingUid();
301     sp<ICarWatchdogMonitor> monitor = new MockICarWatchdogMonitor();
302     EXPECT_CALL(*mMockWatchdogProcessService, tellDumpFinished(monitor, 456))
303             .WillOnce(Return(Status::ok()));
304     Status status = mWatchdogBinderMediator->tellDumpFinished(monitor, 456);
305     ASSERT_TRUE(status.isOk()) << status;
306 }
307 
TEST_F(WatchdogBinderMediatorTest,TestErrorOnNotifyStateChangeWithNonSystemCallingUid)308 TEST_F(WatchdogBinderMediatorTest, TestErrorOnNotifyStateChangeWithNonSystemCallingUid) {
309     StateType type = StateType::POWER_CYCLE;
310     EXPECT_CALL(*mMockWatchdogProcessService, notifyPowerCycleChange(_)).Times(0);
311     Status status =
312             mWatchdogBinderMediator
313                     ->notifySystemStateChange(type,
314                                               static_cast<int32_t>(PowerCycle::POWER_CYCLE_SUSPEND),
315                                               -1);
316     ASSERT_FALSE(status.isOk()) << status;
317 }
318 
TEST_F(WatchdogBinderMediatorTest,TestNotifyPowerCycleChange)319 TEST_F(WatchdogBinderMediatorTest, TestNotifyPowerCycleChange) {
320     setSystemCallingUid();
321     StateType type = StateType::POWER_CYCLE;
322     EXPECT_CALL(*mMockWatchdogProcessService,
323                 notifyPowerCycleChange(PowerCycle::POWER_CYCLE_SUSPEND))
324             .WillOnce(Return(Status::ok()));
325     Status status =
326             mWatchdogBinderMediator
327                     ->notifySystemStateChange(type,
328                                               static_cast<int32_t>(PowerCycle::POWER_CYCLE_SUSPEND),
329                                               -1);
330     ASSERT_TRUE(status.isOk()) << status;
331 }
332 
TEST_F(WatchdogBinderMediatorTest,TestErrorOnNotifyPowerCycleChangeWithInvalidArgs)333 TEST_F(WatchdogBinderMediatorTest, TestErrorOnNotifyPowerCycleChangeWithInvalidArgs) {
334     EXPECT_CALL(*mMockWatchdogProcessService, notifyPowerCycleChange(_)).Times(0);
335     StateType type = StateType::POWER_CYCLE;
336 
337     Status status = mWatchdogBinderMediator->notifySystemStateChange(type, -1, -1);
338     ASSERT_FALSE(status.isOk()) << status;
339 
340     status = mWatchdogBinderMediator->notifySystemStateChange(type, 3000, -1);
341     ASSERT_FALSE(status.isOk()) << status;
342 }
343 
TEST_F(WatchdogBinderMediatorTest,TestNotifyUserStateChange)344 TEST_F(WatchdogBinderMediatorTest, TestNotifyUserStateChange) {
345     setSystemCallingUid();
346     StateType type = StateType::USER_STATE;
347     EXPECT_CALL(*mMockWatchdogProcessService,
348                 notifyUserStateChange(234567, UserState::USER_STATE_STOPPED))
349             .WillOnce(Return(Status::ok()));
350     Status status =
351             mWatchdogBinderMediator
352                     ->notifySystemStateChange(type, 234567,
353                                               static_cast<int32_t>(UserState::USER_STATE_STOPPED));
354     ASSERT_TRUE(status.isOk()) << status;
355 }
356 
TEST_F(WatchdogBinderMediatorTest,TestErrorOnNotifyUserStateChangeWithInvalidArgs)357 TEST_F(WatchdogBinderMediatorTest, TestErrorOnNotifyUserStateChangeWithInvalidArgs) {
358     EXPECT_CALL(*mMockWatchdogProcessService, notifyUserStateChange(_, _)).Times(0);
359     StateType type = StateType::USER_STATE;
360 
361     Status status = mWatchdogBinderMediator->notifySystemStateChange(type, 234567, -1);
362     ASSERT_FALSE(status.isOk()) << status;
363 
364     status = mWatchdogBinderMediator->notifySystemStateChange(type, 234567, 3000);
365     ASSERT_FALSE(status.isOk()) << status;
366 }
367 
TEST_F(WatchdogBinderMediatorTest,TestNotifyBootPhaseChange)368 TEST_F(WatchdogBinderMediatorTest, TestNotifyBootPhaseChange) {
369     setSystemCallingUid();
370     StateType type = StateType::BOOT_PHASE;
371     EXPECT_CALL(*mMockIoPerfCollection, onBootFinished()).WillOnce(Return(Result<void>()));
372     Status status = mWatchdogBinderMediator->notifySystemStateChange(
373         type, static_cast<int32_t>(BootPhase::BOOT_COMPLETED), -1);
374     ASSERT_TRUE(status.isOk()) << status;
375 }
376 
377 
TEST_F(WatchdogBinderMediatorTest,TestNotifyBootPhaseChangeWithNonBootCompletedPhase)378 TEST_F(WatchdogBinderMediatorTest, TestNotifyBootPhaseChangeWithNonBootCompletedPhase) {
379     setSystemCallingUid();
380     StateType type = StateType::BOOT_PHASE;
381     EXPECT_CALL(*mMockIoPerfCollection, onBootFinished()).Times(0);
382     Status status = mWatchdogBinderMediator->notifySystemStateChange(type, 0, -1);
383     ASSERT_TRUE(status.isOk()) << status;
384 }
385 
386 }  // namespace watchdog
387 }  // namespace automotive
388 }  // namespace android
389