1 /*
2 * Copyright (C) 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 #define LOG_TAG "carwatchdog_testclient"
18
19 #include "WatchdogClient.h"
20
21 #include <android-base/parseint.h>
22 #include <android-base/result.h>
23 #include <android/binder_manager.h>
24 #include <android/binder_process.h>
25 #include <utils/Looper.h>
26
27 using aidl::android::automotive::watchdog::CommandParam;
28 using aidl::android::automotive::watchdog::WatchdogClient;
29 using android::Looper;
30 using android::sp;
31 using android::base::Error;
32 using android::base::ParseInt;
33 using android::base::Result;
34
checkArgument(int argc,char ** argv)35 Result<CommandParam> checkArgument(int argc, char** argv) {
36 CommandParam param;
37 if (argc < 4) {
38 return Error() << "Invalid syntax";
39 }
40 if (strcmp(argv[1], "critical") && strcmp(argv[1], "moderate") && strcmp(argv[1], "normal")) {
41 return Error() << "Invalid timeout";
42 }
43 param.timeout = argv[1];
44 std::string strValue = argv[2];
45 if (!ParseInt(strValue, ¶m.inactiveAfterInSec)) {
46 return Error() << "Invalid inactive after time";
47 }
48 strValue = argv[3];
49 if (!ParseInt(strValue, ¶m.terminateAfterInSec)) {
50 return Error() << "Invalid terminate after time";
51 }
52 param.forcedKill = false;
53 param.verbose = false;
54 for (int i = 4; i < argc; i++) {
55 if (!strcmp(argv[i], "--forcedkill")) {
56 param.forcedKill = true;
57 } else if (!strcmp(argv[i], "--verbose")) {
58 param.verbose = true;
59 } else {
60 return Error() << "Invalid option";
61 }
62 }
63 return param;
64 }
65 /**
66 * Usage: carwatchdog_testclient [timeout] [inactive_after] [terminate_after] [--forcedkill]
67 * [--verbose]
68 * timeout: critical|moderate|normal
69 * inactive_after: number in seconds. -1 for never being inactive.
70 * terminate_after: number in seconds. -1 for running forever.
71 * --forcedkill: terminate without unregistering from car watchdog daemon.
72 * --verbose: output verbose logs.
73 */
main(int argc,char ** argv)74 int main(int argc, char** argv) {
75 sp<Looper> looper(Looper::prepare(/*opts=*/0));
76
77 ABinderProcess_setThreadPoolMaxThreadCount(1);
78 ABinderProcess_startThreadPool();
79 std::shared_ptr<WatchdogClient> service = ndk::SharedRefBase::make<WatchdogClient>(looper);
80
81 auto param = checkArgument(argc, argv);
82 if (!param.ok()) {
83 ALOGE("%s: use \"carwatchdog_testclient timeout inactive_after terminate_after "
84 "[--forcedkill]\"",
85 param.error().message().c_str());
86 ALOGE("timeout: critical|moderate|normal");
87 ALOGE("inactive_after: number in seconds (-1 for never being inactive)");
88 ALOGE("terminate_after: number in seconds (-1 for running forever)");
89 ALOGE("--forcedkill: terminate without unregistering from car watchdog daemon");
90 ALOGE("--verbose: output verbose logs");
91 return 1;
92 }
93 if (!service->initialize(*param)) {
94 ALOGE("Failed to initialize watchdog client");
95 return 1;
96 }
97
98 while (true) {
99 looper->pollAll(/*timeoutMillis=*/-1);
100 }
101
102 return 0;
103 }
104