1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "ability_command.h"
16
17 #include <csignal>
18 #include <cstdlib>
19 #include <getopt.h>
20 #include <regex>
21 #include "ability_manager_client.h"
22 #include "app_mgr_client.h"
23 #include "hilog_wrapper.h"
24 #include "iservice_registry.h"
25 #include "mission_snapshot.h"
26 #include "bool_wrapper.h"
27 #include "sa_mgr_client.h"
28 #include "system_ability_definition.h"
29 #include "test_observer.h"
30
31 using namespace OHOS::AppExecFwk;
32
33 namespace OHOS {
34 namespace AAFwk {
35 namespace {
36 constexpr size_t PARAM_LENGTH = 1024;
37
38 const std::string SHORT_OPTIONS = "ch:d:a:b:p:s:m:CDSN";
39 constexpr struct option LONG_OPTIONS[] = {
40 {"help", no_argument, nullptr, 'h'},
41 {"device", required_argument, nullptr, 'd'},
42 {"ability", required_argument, nullptr, 'a'},
43 {"bundle", required_argument, nullptr, 'b'},
44 {"perf", required_argument, nullptr, 'p'},
45 {"setting", required_argument, nullptr, 's'},
46 {"module", required_argument, nullptr, 'm'},
47 {"cold-start", no_argument, nullptr, 'C'},
48 {"debug", no_argument, nullptr, 'D'},
49 {"native-debug", no_argument, nullptr, 'N'},
50 {nullptr, 0, nullptr, 0},
51 };
52 const std::string SHORT_OPTIONS_APPLICATION_NOT_RESPONDING = "hp:";
53 #ifdef ABILITY_COMMAND_FOR_TEST
54 constexpr struct option LONG_OPTIONS_ApplicationNotResponding[] = {
55 {"help", no_argument, nullptr, 'h'},
56 {"pid", required_argument, nullptr, 'p'},
57 {nullptr, 0, nullptr, 0},
58 };
59 #endif
60 #ifdef ABILITY_FAULT_AND_EXIT_TEST
61 const std::string SHORT_OPTIONS_FORCE_EXIT_APP = "hp:r:";
62 constexpr struct option LONG_OPTIONS_FORCE_EXIT_APP[] = {
63 { "help", no_argument, nullptr, 'h' },
64 { "pid", required_argument, nullptr, 'p' },
65 { "reason", required_argument, nullptr, 'r' },
66 { nullptr, 0, nullptr, 0 },
67 };
68 const std::string SHORT_OPTIONS_NOTIFY_APP_FAULT = "hn:m:s:t:p:";
69 constexpr struct option LONG_OPTIONS_NOTIFY_APP_FAULT[] = {
70 {"help", no_argument, nullptr, 'h'},
71 {"errorName", required_argument, nullptr, 'n'},
72 {"errorMessage", required_argument, nullptr, 'm'},
73 {"errorStack", required_argument, nullptr, 's'},
74 {"faultType", required_argument, nullptr, 't'},
75 {"pid", required_argument, nullptr, 'p'},
76 {nullptr, 0, nullptr, 0},
77 };
78 #endif
79 const std::string SHORT_OPTIONS_DUMPSYS = "hal::i:e::p::r::d::u:c";
80 constexpr struct option LONG_OPTIONS_DUMPSYS[] = {
81 {"help", no_argument, nullptr, 'h'},
82 {"all", no_argument, nullptr, 'a'},
83 {"mission-list", no_argument, nullptr, 'l'},
84 {"ability", required_argument, nullptr, 'i'},
85 {"extension", no_argument, nullptr, 'e'},
86 {"pending", no_argument, nullptr, 'p'},
87 {"process", no_argument, nullptr, 'r'},
88 {"data", no_argument, nullptr, 'd'},
89 {"userId", required_argument, nullptr, 'u'},
90 {"client", no_argument, nullptr, 'c'},
91 {nullptr, 0, nullptr, 0},
92 };
93 const std::string SHORT_OPTIONS_PROCESS = "ha:b:p:m:D:S";
94 constexpr struct option LONG_OPTIONS_PROCESS[] = {
95 {"help", no_argument, nullptr, 'h'},
96 {"ability", required_argument, nullptr, 'a'},
97 {"bundle", required_argument, nullptr, 'b'},
98 {"perf", required_argument, nullptr, 'p'},
99 {"module", required_argument, nullptr, 'm'},
100 {"debug", required_argument, nullptr, 'D'},
101 {nullptr, 0, nullptr, 0},
102 };
103 } // namespace
104
AbilityManagerShellCommand(int argc,char * argv[])105 AbilityManagerShellCommand::AbilityManagerShellCommand(int argc, char* argv[]) : ShellCommand(argc, argv, TOOL_NAME)
106 {
107 for (int i = 0; i < argc_; i++) {
108 HILOG_INFO("argv_[%{public}d]: %{public}s", i, argv_[i]);
109 }
110 }
111
CreateCommandMap()112 ErrCode AbilityManagerShellCommand::CreateCommandMap()
113 {
114 commandMap_ = {
115 {"help", std::bind(&AbilityManagerShellCommand::RunAsHelpCommand, this)},
116 {"screen", std::bind(&AbilityManagerShellCommand::RunAsScreenCommand, this)},
117 {"start", std::bind(&AbilityManagerShellCommand::RunAsStartAbility, this)},
118 {"stop-service", std::bind(&AbilityManagerShellCommand::RunAsStopService, this)},
119 {"dump", std::bind(&AbilityManagerShellCommand::RunAsDumpsysCommand, this)},
120 {"force-stop", std::bind(&AbilityManagerShellCommand::RunAsForceStop, this)},
121 {"test", std::bind(&AbilityManagerShellCommand::RunAsTestCommand, this)},
122 {"process", std::bind(&AbilityManagerShellCommand::RunAsProcessCommand, this)},
123 #ifdef ABILITY_COMMAND_FOR_TEST
124 {"force-timeout", std::bind(&AbilityManagerShellCommand::RunForceTimeoutForTest, this)},
125 {"ApplicationNotResponding", std::bind(&AbilityManagerShellCommand::RunAsSendAppNotRespondingProcessID, this)},
126 {"block-ability", std::bind(&AbilityManagerShellCommand::RunAsBlockAbilityCommand, this)},
127 {"block-ams-service", std::bind(&AbilityManagerShellCommand::RunAsBlockAmsServiceCommand, this)},
128 {"block-app-service", std::bind(&AbilityManagerShellCommand::RunAsBlockAppServiceCommand, this)},
129 #endif
130 #ifdef ABILITY_FAULT_AND_EXIT_TEST
131 {"forceexitapp", std::bind(&AbilityManagerShellCommand::RunAsForceExitAppCommand, this)},
132 {"notifyappfault", std::bind(&AbilityManagerShellCommand::RunAsNotifyAppFaultCommand, this)},
133 #endif
134 };
135
136 return OHOS::ERR_OK;
137 }
138
CreateMessageMap()139 ErrCode AbilityManagerShellCommand::CreateMessageMap()
140 {
141 messageMap_ = {
142 // code + message
143 {
144 RESOLVE_ABILITY_ERR,
145 "error: resolve ability err.",
146 },
147 {
148 GET_ABILITY_SERVICE_FAILED,
149 "error: get ability service failed.",
150 },
151 {
152 ABILITY_SERVICE_NOT_CONNECTED,
153 "error: ability service not connected.",
154 },
155 {
156 RESOLVE_APP_ERR,
157 "error: resolve app err.",
158 },
159 {
160 ABILITY_EXISTED,
161 "error: ability existed.",
162 },
163 {
164 CREATE_MISSION_STACK_FAILED,
165 "error: create mission stack failed.",
166 },
167 {
168 CREATE_ABILITY_RECORD_FAILED,
169 "error: create ability record failed.",
170 },
171 {
172 START_ABILITY_WAITING,
173 "start ability successfully. waiting...",
174 },
175 {
176 TERMINATE_LAUNCHER_DENIED,
177 "error: terminate launcher denied.",
178 },
179 {
180 CONNECTION_NOT_EXIST,
181 "error: connection not exist.",
182 },
183 {
184 INVALID_CONNECTION_STATE,
185 "error: invalid connection state.",
186 },
187 {
188 LOAD_ABILITY_TIMEOUT,
189 "error: load ability timeout.",
190 },
191 {
192 CONNECTION_TIMEOUT,
193 "error: connection timeout.",
194 },
195 {
196 GET_BUNDLE_MANAGER_SERVICE_FAILED,
197 "error: get bundle manager service failed.",
198 },
199 {
200 REMOVE_MISSION_FAILED,
201 "error: remove mission failed.",
202 },
203 {
204 INNER_ERR,
205 "error: inner err.",
206 },
207 {
208 GET_RECENT_MISSIONS_FAILED,
209 "error: get recent missions failed.",
210 },
211 {
212 REMOVE_STACK_LAUNCHER_DENIED,
213 "error: remove stack launcher denied.",
214 },
215 {
216 TARGET_ABILITY_NOT_SERVICE,
217 "error: target ability not service.",
218 },
219 {
220 TERMINATE_SERVICE_IS_CONNECTED,
221 "error: terminate service is connected.",
222 },
223 {
224 START_SERVICE_ABILITY_ACTIVATING,
225 "error: start service ability activating.",
226 },
227 {
228 KILL_PROCESS_FAILED,
229 "error: kill process failed.",
230 },
231 {
232 UNINSTALL_APP_FAILED,
233 "error: uninstall app failed.",
234 },
235 {
236 TERMINATE_ABILITY_RESULT_FAILED,
237 "error: terminate ability result failed.",
238 },
239 {
240 CHECK_PERMISSION_FAILED,
241 "error: check permission failed.",
242 },
243 {
244 NO_FOUND_ABILITY_BY_CALLER,
245 "error: no found ability by caller.",
246 },
247 {
248 ABILITY_VISIBLE_FALSE_DENY_REQUEST,
249 "error: ability visible false deny request.",
250 },
251 {
252 GET_BUNDLE_INFO_FAILED,
253 "error: get bundle info failed.",
254 },
255 {
256 KILL_PROCESS_KEEP_ALIVE,
257 "error: keep alive process can not be killed.",
258 },
259 };
260
261 return OHOS::ERR_OK;
262 }
263
init()264 ErrCode AbilityManagerShellCommand::init()
265 {
266 return AbilityManagerClient::GetInstance()->Connect();
267 }
268
RunAsHelpCommand()269 ErrCode AbilityManagerShellCommand::RunAsHelpCommand()
270 {
271 resultReceiver_.append(HELP_MSG);
272
273 return OHOS::ERR_OK;
274 }
275
RunAsScreenCommand()276 ErrCode AbilityManagerShellCommand::RunAsScreenCommand()
277 {
278 HILOG_INFO("enter");
279
280 int result = OHOS::ERR_OK;
281
282 int option = -1;
283 int counter = 0;
284
285 while (true) {
286 counter++;
287
288 option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
289
290 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
291
292 if (optind < 0 || optind > argc_) {
293 return OHOS::ERR_INVALID_VALUE;
294 }
295
296 if (option == -1) {
297 // When scanning the first argument
298 if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
299 // 'aa screen' with no option: aa screen
300 // 'aa screen' with a wrong argument: aa screen xxx
301 HILOG_INFO("'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
302 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
303 result = OHOS::ERR_INVALID_VALUE;
304 }
305 break;
306 }
307
308 if (option == '?') {
309 switch (optopt) {
310 case 'p': {
311 // 'aa screen -p' with no argument
312 HILOG_INFO("'aa %{public}s -p' with no argument.", cmd_.c_str());
313
314 resultReceiver_.append("error: option ");
315 resultReceiver_.append("requires a value.\n");
316
317 result = OHOS::ERR_INVALID_VALUE;
318 break;
319 }
320 case 0: {
321 // 'aa screen' with an unknown option: aa screen --x
322 // 'aa screen' with an unknown option: aa screen --xxx
323 std::string unknownOption = "";
324 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
325
326 HILOG_INFO("'aa screen' with an unknown option.");
327
328 resultReceiver_.append(unknownOptionMsg);
329 result = OHOS::ERR_INVALID_VALUE;
330 break;
331 }
332 default: {
333 // 'aa screen' with an unknown option: aa screen -x
334 // 'aa screen' with an unknown option: aa screen -xxx
335 std::string unknownOption = "";
336 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
337
338 HILOG_INFO("'aa screen' with an unknown option.");
339
340 resultReceiver_.append(unknownOptionMsg);
341 result = OHOS::ERR_INVALID_VALUE;
342 break;
343 }
344 }
345 break;
346 }
347
348 switch (option) {
349 case 'h': {
350 // 'aa screen -h'
351 // 'aa screen --help'
352 result = OHOS::ERR_INVALID_VALUE;
353 break;
354 }
355 case 0: {
356 break;
357 }
358 default: {
359 break;
360 }
361 }
362 }
363
364 if (result != OHOS::ERR_OK) {
365 resultReceiver_.append(HELP_MSG_SCREEN);
366 result = OHOS::ERR_INVALID_VALUE;
367 }
368
369 return result;
370 }
371
RunAsStartAbility()372 ErrCode AbilityManagerShellCommand::RunAsStartAbility()
373 {
374 Want want;
375 std::string windowMode;
376 ErrCode result = MakeWantFromCmd(want, windowMode);
377 if (result == OHOS::ERR_OK) {
378 int windowModeKey = std::atoi(windowMode.c_str());
379 if (windowModeKey > 0) {
380 auto setting = AbilityStartSetting::GetEmptySetting();
381 if (setting != nullptr) {
382 setting->AddProperty(AbilityStartSetting::WINDOW_MODE_KEY, windowMode);
383 result = AbilityManagerClient::GetInstance()->StartAbility(want, *(setting.get()), nullptr, -1);
384 }
385 } else {
386 result = AbilityManagerClient::GetInstance()->StartAbility(want);
387 }
388 if (result == OHOS::ERR_OK) {
389 HILOG_INFO("%{public}s", STRING_START_ABILITY_OK.c_str());
390 resultReceiver_ = STRING_START_ABILITY_OK + "\n";
391 } else {
392 HILOG_INFO("%{public}s result = %{public}d", STRING_START_ABILITY_NG.c_str(), result);
393 if (result != START_ABILITY_WAITING) {
394 resultReceiver_ = STRING_START_ABILITY_NG + "\n";
395 }
396 resultReceiver_.append(GetMessageFromCode(result));
397 }
398 } else {
399 resultReceiver_.append(HELP_MSG_START);
400 result = OHOS::ERR_INVALID_VALUE;
401 }
402
403 return result;
404 }
405
RunAsStopService()406 ErrCode AbilityManagerShellCommand::RunAsStopService()
407 {
408 ErrCode result = OHOS::ERR_OK;
409
410 Want want;
411 std::string windowMode;
412 result = MakeWantFromCmd(want, windowMode);
413 if (result == OHOS::ERR_OK) {
414 result = AbilityManagerClient::GetInstance()->StopServiceAbility(want);
415 if (result == OHOS::ERR_OK) {
416 HILOG_INFO("%{public}s", STRING_STOP_SERVICE_ABILITY_OK.c_str());
417 resultReceiver_ = STRING_STOP_SERVICE_ABILITY_OK + "\n";
418 } else {
419 HILOG_INFO("%{public}s result = %{public}d", STRING_STOP_SERVICE_ABILITY_NG.c_str(), result);
420 resultReceiver_ = STRING_STOP_SERVICE_ABILITY_NG + "\n";
421
422 resultReceiver_.append(GetMessageFromCode(result));
423 }
424 } else {
425 resultReceiver_.append(HELP_MSG_STOP_SERVICE);
426 result = OHOS::ERR_INVALID_VALUE;
427 }
428
429 return result;
430 }
431
RunAsDumpsysCommand()432 ErrCode AbilityManagerShellCommand::RunAsDumpsysCommand()
433 {
434 ErrCode result = OHOS::ERR_OK;
435 bool isUserID = false;
436 bool isClient = false;
437 int userID = DEFAULT_INVAL_VALUE;
438 bool isfirstCommand = false;
439 std::string args;
440 for (auto it = argList_.begin(); it != argList_.end(); it++) {
441 if (*it == "-c" || *it == "--client") {
442 if (isClient == false) {
443 isClient = true;
444 } else {
445 result = OHOS::ERR_INVALID_VALUE;
446 resultReceiver_.append(HELP_MSG_DUMPSYS);
447 return result;
448 }
449 } else if (*it == "-u" || *it == "--userId") {
450 if (it + 1 == argList_.end()) {
451 result = OHOS::ERR_INVALID_VALUE;
452 resultReceiver_.append(HELP_MSG_DUMPSYS);
453 return result;
454 }
455 (void)StrToInt(*(it + 1), userID);
456 if (userID == DEFAULT_INVAL_VALUE) {
457 result = OHOS::ERR_INVALID_VALUE;
458 resultReceiver_.append(HELP_MSG_DUMPSYS);
459 return result;
460 }
461 if (isUserID == false) {
462 isUserID = true;
463 } else {
464 result = OHOS::ERR_INVALID_VALUE;
465 resultReceiver_.append(HELP_MSG_DUMPSYS);
466 return result;
467 }
468 } else if (*it == std::to_string(userID)) {
469 continue;
470 } else {
471 args += *it;
472 args += " ";
473 }
474 }
475
476 while (true) {
477 int option = getopt_long(argc_, argv_, SHORT_OPTIONS_DUMPSYS.c_str(), LONG_OPTIONS_DUMPSYS, nullptr);
478
479 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
480
481 if (optind < 0 || optind > argc_) {
482 resultReceiver_.append(HELP_MSG_DUMPSYS);
483 return OHOS::ERR_INVALID_VALUE;
484 }
485
486 if (option == -1) {
487 break;
488 }
489
490 switch (option) {
491 case 'h': {
492 // 'aa dumpsys -h'
493 // 'aa dumpsys --help'
494 resultReceiver_.append(HELP_MSG_DUMPSYS);
495 result = OHOS::ERR_INVALID_VALUE;
496 return result;
497 }
498 case 'a': {
499 if (isfirstCommand == false) {
500 isfirstCommand = true;
501 } else {
502 result = OHOS::ERR_INVALID_VALUE;
503 resultReceiver_.append(HELP_MSG_DUMPSYS);
504 return result;
505 }
506 // 'aa dumpsys -a'
507 // 'aa dumpsys --all'
508 break;
509 }
510 case 'l': {
511 if (isfirstCommand == false) {
512 isfirstCommand = true;
513 } else {
514 // 'aa dump -i 10 -element -lastpage'
515 // 'aa dump -i 10 -render -lastpage'
516 // 'aa dump -i 10 -layer'
517 if ((optarg != nullptr) && strcmp(optarg, "astpage") && strcmp(optarg, "ayer")) {
518 result = OHOS::ERR_INVALID_VALUE;
519 resultReceiver_.append(HELP_MSG_DUMPSYS);
520 return result;
521 }
522 }
523 // 'aa dumpsys -l'
524 // 'aa dumpsys --mission-list'
525 break;
526 }
527 case 'i': {
528 if (isfirstCommand == false) {
529 isfirstCommand = true;
530 int abilityRecordId = DEFAULT_INVAL_VALUE;
531 (void)StrToInt(optarg, abilityRecordId);
532 if (abilityRecordId == DEFAULT_INVAL_VALUE) {
533 result = OHOS::ERR_INVALID_VALUE;
534 resultReceiver_.append(HELP_MSG_DUMPSYS);
535 return result;
536 }
537 } else {
538 // 'aa dumpsys -i 10 -inspector'
539 if ((optarg != nullptr) && strcmp(optarg, "nspector")) {
540 result = OHOS::ERR_INVALID_VALUE;
541 resultReceiver_.append(HELP_MSG_DUMPSYS);
542 return result;
543 }
544 }
545 // 'aa dumpsys -i'
546 // 'aa dumpsys --ability'
547 break;
548 }
549 case 'e': {
550 if (isfirstCommand == false && optarg == nullptr) {
551 isfirstCommand = true;
552 } else {
553 // 'aa dumpsys -i 10 -element'
554 if ((optarg != nullptr) && strcmp(optarg, "lement")) {
555 result = OHOS::ERR_INVALID_VALUE;
556 resultReceiver_.append(HELP_MSG_DUMPSYS);
557 return result;
558 }
559 }
560 // 'aa dumpsys -e'
561 // 'aa dumpsys --extension'
562 break;
563 }
564 case 'p': {
565 if (isfirstCommand == false && optarg == nullptr) {
566 isfirstCommand = true;
567 } else {
568 result = OHOS::ERR_INVALID_VALUE;
569 resultReceiver_.append(HELP_MSG_DUMPSYS);
570 return result;
571 }
572 // 'aa dumpsys -p'
573 // 'aa dumpsys --pending'
574 break;
575 }
576 case 'r': {
577 if (isfirstCommand == false && optarg == nullptr) {
578 isfirstCommand = true;
579 } else {
580 // 'aa dump -i 10 -render'
581 // 'aa dump -i 10 -rotation'
582 // 'aa dump -i 10 -frontend'
583 if ((optarg != nullptr) && strcmp(optarg, "ender") && strcmp(optarg, "otation") &&
584 strcmp(optarg, "ontend")) {
585 result = OHOS::ERR_INVALID_VALUE;
586 resultReceiver_.append(HELP_MSG_DUMPSYS);
587 return result;
588 }
589 }
590 // 'aa dumpsys -r'
591 // 'aa dumpsys --process'
592 break;
593 }
594 case 'd': {
595 if (isfirstCommand == false && optarg == nullptr) {
596 isfirstCommand = true;
597 } else {
598 result = OHOS::ERR_INVALID_VALUE;
599 resultReceiver_.append(HELP_MSG_DUMPSYS);
600 return result;
601 }
602 // 'aa dumpsys -d'
603 // 'aa dumpsys --data'
604 break;
605 }
606 case 'u': {
607 // 'aa dumpsys -u'
608 // 'aa dumpsys --userId'
609 break;
610 }
611 case 'c': {
612 // 'aa dumpsys -c'
613 // 'aa dumpsys --client'
614 break;
615 }
616 case '?': {
617 if (!isfirstCommand) {
618 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
619 std::string unknownOption = "";
620 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
621 resultReceiver_.append(unknownOptionMsg);
622 resultReceiver_.append(HELP_MSG_DUMPSYS);
623 result = OHOS::ERR_INVALID_VALUE;
624 return result;
625 }
626 break;
627 }
628 default: {
629 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
630 std::string unknownOption = "";
631 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
632 resultReceiver_.append(unknownOptionMsg);
633 result = OHOS::ERR_INVALID_VALUE;
634 break;
635 }
636 }
637 }
638
639 if (result != OHOS::ERR_OK) {
640 resultReceiver_.append(HELP_MSG_DUMPSYS);
641 } else {
642 if (isfirstCommand != true) {
643 result = OHOS::ERR_INVALID_VALUE;
644 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
645 resultReceiver_.append(HELP_MSG_DUMPSYS);
646 return result;
647 }
648
649 std::vector<std::string> dumpResults;
650 result = AbilityManagerClient::GetInstance()->DumpSysState(args, dumpResults, isClient, isUserID, userID);
651 if (result == OHOS::ERR_OK) {
652 for (auto it : dumpResults) {
653 resultReceiver_ += it + "\n";
654 }
655 } else {
656 HILOG_INFO("failed to dump state.");
657 }
658 }
659 return result;
660 }
661
RunAsForceStop()662 ErrCode AbilityManagerShellCommand::RunAsForceStop()
663 {
664 HILOG_INFO("[%{public}s(%{public}s)] enter", __FILE__, __FUNCTION__);
665 if (argList_.empty()) {
666 resultReceiver_.append(HELP_MSG_FORCE_STOP + "\n");
667 return OHOS::ERR_INVALID_VALUE;
668 }
669 HILOG_INFO("Bundle name : %{public}s", argList_[0].c_str());
670 ErrCode result = OHOS::ERR_OK;
671 result = AbilityManagerClient::GetInstance()->KillProcess(argList_[0]);
672 if (result == OHOS::ERR_OK) {
673 HILOG_INFO("%{public}s", STRING_FORCE_STOP_OK.c_str());
674 resultReceiver_ = STRING_FORCE_STOP_OK + "\n";
675 } else {
676 HILOG_INFO("%{public}s result = %{public}d", STRING_FORCE_STOP_NG.c_str(), result);
677 resultReceiver_ = STRING_FORCE_STOP_NG + "\n";
678 resultReceiver_.append(GetMessageFromCode(result));
679 }
680 return result;
681 }
682
RunAsProcessCommand()683 ErrCode AbilityManagerShellCommand::RunAsProcessCommand()
684 {
685 Want want;
686 ErrCode result = MakeWantForProcess(want);
687 if (result == OHOS::ERR_OK) {
688 auto appMgrClient = std::make_shared<AppMgrClient>();
689 result = appMgrClient->StartNativeProcessForDebugger(want);
690 if (result == OHOS::ERR_OK) {
691 HILOG_INFO("%{public}s", STRING_START_NATIVE_PROCESS_OK.c_str());
692 resultReceiver_ = STRING_START_NATIVE_PROCESS_OK;
693 } else {
694 HILOG_INFO("%{public}s result = %{public}d", STRING_START_NATIVE_PROCESS_NG.c_str(), result);
695 resultReceiver_ = STRING_START_NATIVE_PROCESS_NG;
696 }
697 } else {
698 resultReceiver_.append(HELP_MSG_PROCESS);
699 result = OHOS::ERR_INVALID_VALUE;
700 }
701
702 return result;
703 }
704
MatchOrderString(const std::regex & regexScript,const std::string & orderCmd)705 bool AbilityManagerShellCommand::MatchOrderString(const std::regex ®exScript, const std::string &orderCmd)
706 {
707 HILOG_DEBUG("order string is %{public}s", orderCmd.c_str());
708 if (orderCmd.empty()) {
709 HILOG_ERROR("input param order string is empty");
710 return false;
711 }
712
713 std::match_results<std::string::const_iterator> matchResults;
714 if (!std::regex_match(orderCmd, matchResults, regexScript)) {
715 HILOG_ERROR("the order not match");
716 return false;
717 }
718
719 return true;
720 }
721
CheckPerfCmdString(const char * optarg,const size_t paramLength,std::string & perfCmd)722 bool AbilityManagerShellCommand::CheckPerfCmdString(
723 const char* optarg, const size_t paramLength, std::string &perfCmd)
724 {
725 if (optarg == nullptr) {
726 HILOG_ERROR("input param optarg is nullptr");
727 return false;
728 }
729
730 if (strlen(optarg) >= paramLength) {
731 HILOG_ERROR("debuggablePipe aa start -p param length must be less than 1024.");
732 return false;
733 }
734
735 perfCmd = optarg;
736 const std::regex regexDumpHeapType(R"(^\s*(dumpheap)\s*$)");
737 const std::regex regexSleepType(R"(^\s*(sleep)((\s+\d*)|)\s*$)");
738 if (MatchOrderString(regexDumpHeapType, perfCmd) || MatchOrderString(regexSleepType, perfCmd)) {
739 return true;
740 }
741
742 HILOG_DEBUG("the command not match");
743 const std::regex regexProfileType(R"(^\s*(profile)\s+(nativeperf|jsperf)(\s+.*|$))");
744 if (!MatchOrderString(regexProfileType, perfCmd)) {
745 HILOG_ERROR("the command is invalid");
746 return false;
747 }
748
749 auto findPos = perfCmd.find("jsperf");
750 if (findPos != std::string::npos) {
751 const std::regex regexCmd(R"(^jsperf($|\s+($|((5000|([1-9]|[1-4]\d)\d\d)|)\s*($|nativeperf.*))))");
752 if (!MatchOrderString(regexCmd, perfCmd.substr(findPos, perfCmd.length() - findPos))) {
753 HILOG_ERROR("the order is invalid");
754 return false;
755 }
756 }
757 return true;
758 }
759
MakeWantForProcess(Want & want)760 ErrCode AbilityManagerShellCommand::MakeWantForProcess(Want& want)
761 {
762 int result = OHOS::ERR_OK;
763 int option = -1;
764 int counter = 0;
765 std::string deviceId = "";
766 std::string bundleName = "";
767 std::string abilityName = "";
768 std::string moduleName = "";
769 std::string perfCmd = "";
770 std::string debugCmd = "";
771 bool isPerf = false;
772 bool isSanboxApp = false;
773
774 while (true) {
775 counter++;
776
777 option = getopt_long(argc_, argv_, SHORT_OPTIONS_PROCESS.c_str(), LONG_OPTIONS_PROCESS, nullptr);
778
779 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
780
781 if (optind < 0 || optind > argc_) {
782 return OHOS::ERR_INVALID_VALUE;
783 }
784
785 if (option == -1) {
786 // When scanning the first argument
787 if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
788 // 'aa process' with no option: aa process
789 // 'aa process' with a wrong argument: aa process xxx
790 HILOG_INFO("'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
791
792 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
793 result = OHOS::ERR_INVALID_VALUE;
794 }
795 break;
796 }
797
798 if (option == '?') {
799 switch (optopt) {
800 case 'a': {
801 // 'aa process -a' with no argument
802 HILOG_INFO("'aa %{public}s -a' with no argument.", cmd_.c_str());
803
804 resultReceiver_.append("error: option ");
805 resultReceiver_.append("requires a value.\n");
806
807 result = OHOS::ERR_INVALID_VALUE;
808 break;
809 }
810 case 'b': {
811 // 'aa process -b' with no argument
812 HILOG_INFO("'aa %{public}s -b' with no argument.", cmd_.c_str());
813
814 resultReceiver_.append("error: option ");
815 resultReceiver_.append("requires a value.\n");
816
817 result = OHOS::ERR_INVALID_VALUE;
818 break;
819 }
820 case 'm': {
821 // 'aa process -m' with no argument
822 HILOG_INFO("'aa %{public}s -m' with no argument.", cmd_.c_str());
823
824 resultReceiver_.append("error: option ");
825 resultReceiver_.append("requires a value.\n");
826
827 result = OHOS::ERR_INVALID_VALUE;
828 break;
829 }
830 case 'p': {
831 // 'aa process -p' with no argument
832 HILOG_INFO("'aa %{public}s -p' with no argument.", cmd_.c_str());
833
834 resultReceiver_.append("error: option ");
835 resultReceiver_.append("requires a value.\n");
836
837 result = OHOS::ERR_INVALID_VALUE;
838 break;
839 }
840 case 'D': {
841 // 'aa process -D' with no argument
842 HILOG_INFO("'aa %{public}s -D' with no argument.", cmd_.c_str());
843
844 resultReceiver_.append("error: option ");
845 resultReceiver_.append("requires a value.\n");
846
847 result = OHOS::ERR_INVALID_VALUE;
848 break;
849 }
850 case 0: {
851 // 'aa process' with an unknown option: aa process --x
852 // 'aa process' with an unknown option: aa process --xxx
853 std::string unknownOption = "";
854 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
855
856 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
857
858 resultReceiver_.append(unknownOptionMsg);
859 result = OHOS::ERR_INVALID_VALUE;
860 break;
861 }
862 default: {
863 // 'aa process' with an unknown option: aa process -x
864 // 'aa process' with an unknown option: aa process -xxx
865 std::string unknownOption = "";
866 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
867
868 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
869
870 resultReceiver_.append(unknownOptionMsg);
871 result = OHOS::ERR_INVALID_VALUE;
872 break;
873 }
874 }
875 break;
876 }
877
878 switch (option) {
879 case 'h': {
880 // 'aa process -h'
881 // 'aa process --help'
882 result = OHOS::ERR_INVALID_VALUE;
883 break;
884 }
885 case 'a': {
886 // 'aa process -a xxx'
887 // save ability name
888 abilityName = optarg;
889 break;
890 }
891 case 'b': {
892 // 'aa process -b xxx'
893 // save bundle name
894 bundleName = optarg;
895 break;
896 }
897 case 'm': {
898 // 'aa process -m xxx'
899 // save module name
900 moduleName = optarg;
901 break;
902 }
903 case 'p': {
904 // 'aa process -p xxx'
905 // save perf cmd
906 if (strlen(optarg) < PARAM_LENGTH) {
907 perfCmd = optarg;
908 isPerf = true;
909 }
910 break;
911 }
912 case 'D': {
913 // 'aa process -D xxx'
914 // save debug cmd
915 if (!isPerf && strlen(optarg) < PARAM_LENGTH) {
916 HILOG_INFO("debug cmd.");
917 debugCmd = optarg;
918 }
919 break;
920 }
921 case 'S': {
922 // 'aa process -S'
923 // enter sanbox to perform app
924 isSanboxApp = true;
925 break;
926 }
927 case 0: {
928 break;
929 }
930 default: {
931 break;
932 }
933 }
934 }
935
936 if (result == OHOS::ERR_OK) {
937 if (perfCmd.empty() && debugCmd.empty()) {
938 HILOG_INFO("debuggablePipe aa process must contains -p or -D and param length must be less than 1024.");
939 return OHOS::ERR_INVALID_VALUE;
940 }
941
942 if (abilityName.size() == 0 || bundleName.size() == 0) {
943 // 'aa process -a <ability-name> -b <bundle-name> [-D]'
944 HILOG_INFO("'aa %{public}s' without enough options.", cmd_.c_str());
945
946 if (abilityName.size() == 0) {
947 resultReceiver_.append(HELP_MSG_NO_ABILITY_NAME_OPTION + "\n");
948 }
949
950 if (bundleName.size() == 0) {
951 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n");
952 }
953
954 result = OHOS::ERR_INVALID_VALUE;
955 } else {
956 ElementName element(deviceId, bundleName, abilityName, moduleName);
957 want.SetElement(element);
958
959 if (!perfCmd.empty()) {
960 want.SetParam("perfCmd", perfCmd);
961 }
962 if (!debugCmd.empty()) {
963 want.SetParam("debugCmd", debugCmd);
964 }
965 if (isSanboxApp) {
966 want.SetParam("sanboxApp", isSanboxApp);
967 }
968 }
969 }
970
971 return result;
972 }
973
974 #ifdef ABILITY_COMMAND_FOR_TEST
RunForceTimeoutForTest()975 ErrCode AbilityManagerShellCommand::RunForceTimeoutForTest()
976 {
977 HILOG_INFO("[%{public}s(%{public}s)] enter", __FILE__, __FUNCTION__);
978 if (argList_.empty()) {
979 resultReceiver_.append(HELP_MSG_FORCE_TIMEOUT + "\n");
980 return OHOS::ERR_INVALID_VALUE;
981 }
982
983 ErrCode result = OHOS::ERR_OK;
984 if (argList_.size() == NUMBER_ONE && argList_[0] == HELP_MSG_FORCE_TIMEOUT_CLEAN) {
985 HILOG_INFO("clear ability timeout flags.");
986 result = AbilityManagerClient::GetInstance()->ForceTimeoutForTest(argList_[0], "");
987 } else if (argList_.size() == NUMBER_TWO) {
988 HILOG_INFO("Ability name : %{public}s, state: %{public}s", argList_[0].c_str(), argList_[1].c_str());
989 result = AbilityManagerClient::GetInstance()->ForceTimeoutForTest(argList_[0], argList_[1]);
990 } else {
991 resultReceiver_.append(HELP_MSG_FORCE_TIMEOUT + "\n");
992 return OHOS::ERR_INVALID_VALUE;
993 }
994 if (result == OHOS::ERR_OK) {
995 HILOG_INFO("%{public}s", STRING_FORCE_TIMEOUT_OK.c_str());
996 resultReceiver_ = STRING_FORCE_TIMEOUT_OK + "\n";
997 } else {
998 HILOG_INFO("%{public}s result = %{public}d", STRING_FORCE_TIMEOUT_NG.c_str(), result);
999 resultReceiver_ = STRING_FORCE_TIMEOUT_NG + "\n";
1000 resultReceiver_.append(GetMessageFromCode(result));
1001 }
1002 return result;
1003 }
1004 #endif
1005
MakeWantFromCmd(Want & want,std::string & windowMode)1006 ErrCode AbilityManagerShellCommand::MakeWantFromCmd(Want& want, std::string& windowMode)
1007 {
1008 int result = OHOS::ERR_OK;
1009
1010 int option = -1;
1011 int counter = 0;
1012
1013 std::string deviceId = "";
1014 std::string bundleName = "";
1015 std::string abilityName = "";
1016 std::string moduleName;
1017 std::string perfCmd;
1018 bool isColdStart = false;
1019 bool isDebugApp = false;
1020 bool isContinuation = false;
1021 bool isSanboxApp = false;
1022 bool isNativeDebug = false;
1023
1024 while (true) {
1025 counter++;
1026
1027 option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
1028
1029 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
1030
1031 if (optind < 0 || optind > argc_) {
1032 return OHOS::ERR_INVALID_VALUE;
1033 }
1034
1035 if (option == -1) {
1036 // When scanning the first argument
1037 if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
1038 // 'aa start' with no option: aa start
1039 // 'aa start' with a wrong argument: aa start xxx
1040 // 'aa stop-service' with no option: aa stop-service
1041 // 'aa stop-service' with a wrong argument: aa stop-service xxx
1042 HILOG_INFO("'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
1043
1044 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
1045 result = OHOS::ERR_INVALID_VALUE;
1046 }
1047 break;
1048 }
1049
1050 if (option == '?') {
1051 switch (optopt) {
1052 case 'h': {
1053 // 'aa start -h'
1054 // 'aa stop-service -h'
1055 result = OHOS::ERR_INVALID_VALUE;
1056 break;
1057 }
1058 case 'd': {
1059 // 'aa start -d' with no argument
1060 // 'aa stop-service -d' with no argument
1061 HILOG_INFO("'aa %{public}s -d' with no argument.", cmd_.c_str());
1062
1063 resultReceiver_.append("error: option ");
1064 resultReceiver_.append("requires a value.\n");
1065
1066 result = OHOS::ERR_INVALID_VALUE;
1067 break;
1068 }
1069 case 'a': {
1070 // 'aa start -a' with no argument
1071 // 'aa stop-service -a' with no argument
1072 HILOG_INFO("'aa %{public}s -a' with no argument.", cmd_.c_str());
1073
1074 resultReceiver_.append("error: option ");
1075 resultReceiver_.append("requires a value.\n");
1076
1077 result = OHOS::ERR_INVALID_VALUE;
1078 break;
1079 }
1080 case 'b': {
1081 // 'aa start -b' with no argument
1082 // 'aa stop-service -b' with no argument
1083 HILOG_INFO("'aa %{public}s -b' with no argument.", cmd_.c_str());
1084
1085 resultReceiver_.append("error: option ");
1086 resultReceiver_.append("requires a value.\n");
1087
1088 result = OHOS::ERR_INVALID_VALUE;
1089 break;
1090 }
1091 case 's': {
1092 // 'aa start -s' with no argument
1093 // 'aa stop-service -s' with no argument
1094 HILOG_INFO("'aa %{public}s -s' with no argument.", cmd_.c_str());
1095
1096 resultReceiver_.append("error: option ");
1097 resultReceiver_.append(argv_[optind - 1]);
1098 resultReceiver_.append("' requires a value.\n");
1099
1100 result = OHOS::ERR_INVALID_VALUE;
1101 break;
1102 }
1103 case 'm': {
1104 // 'aa start -m' with no argument
1105 // 'aa stop-service -m' with no argument
1106 HILOG_INFO("'aa %{public}s -m' with no argument.", cmd_.c_str());
1107
1108 resultReceiver_.append("error: option ");
1109 resultReceiver_.append("requires a value.\n");
1110
1111 result = OHOS::ERR_INVALID_VALUE;
1112 break;
1113 }
1114 case 'p': {
1115 // 'aa start -p' with no argument
1116 // 'aa stop-service -p' with no argument
1117 HILOG_INFO("'aa %{public}s -p' with no argument.", cmd_.c_str());
1118
1119 resultReceiver_.append("error: option ");
1120 resultReceiver_.append("requires a value.\n");
1121
1122 result = OHOS::ERR_INVALID_VALUE;
1123 break;
1124 }
1125 case 0: {
1126 // 'aa start' with an unknown option: aa start --x
1127 // 'aa start' with an unknown option: aa start --xxx
1128 // 'aa stop-service' with an unknown option: aa stop-service --x
1129 // 'aa stop-service' with an unknown option: aa stop-service --xxx
1130 std::string unknownOption = "";
1131 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1132
1133 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
1134
1135 resultReceiver_.append(unknownOptionMsg);
1136 result = OHOS::ERR_INVALID_VALUE;
1137 break;
1138 }
1139 default: {
1140 // 'aa start' with an unknown option: aa start -x
1141 // 'aa start' with an unknown option: aa start -xxx
1142 // 'aa stop-service' with an unknown option: aa stop-service -x
1143 // 'aa stop-service' with an unknown option: aa stop-service -xxx
1144 std::string unknownOption = "";
1145 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1146
1147 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
1148
1149 resultReceiver_.append(unknownOptionMsg);
1150 result = OHOS::ERR_INVALID_VALUE;
1151 break;
1152 }
1153 }
1154 break;
1155 }
1156
1157 switch (option) {
1158 case 'h': {
1159 // 'aa start -h'
1160 // 'aa start --help'
1161 // 'aa stop-service -h'
1162 // 'aa stop-service --help'
1163 result = OHOS::ERR_INVALID_VALUE;
1164 break;
1165 }
1166 case 'd': {
1167 // 'aa start -d xxx'
1168 // 'aa stop-service -d xxx'
1169
1170 // save device ID
1171 if (optarg != nullptr) {
1172 deviceId = optarg;
1173 }
1174 break;
1175 }
1176 case 'a': {
1177 // 'aa start -a xxx'
1178 // 'aa stop-service -a xxx'
1179
1180 // save ability name
1181 abilityName = optarg;
1182 break;
1183 }
1184 case 'b': {
1185 // 'aa start -b xxx'
1186 // 'aa stop-service -b xxx'
1187
1188 // save bundle name
1189 bundleName = optarg;
1190 break;
1191 }
1192 case 's': {
1193 // 'aa start -s xxx'
1194 // save windowMode
1195 windowMode = optarg;
1196 break;
1197 }
1198 case 'm': {
1199 // 'aa start -m xxx'
1200 // 'aa stop-service -m xxx'
1201
1202 // save module name
1203 moduleName = optarg;
1204 break;
1205 }
1206 case 'p': {
1207 // 'aa start -p xxx'
1208 // 'aa stop-service -p xxx'
1209
1210 // save module name
1211 if (!CheckPerfCmdString(optarg, PARAM_LENGTH, perfCmd)) {
1212 HILOG_ERROR("input perfCmd is invalid %{public}s", perfCmd.c_str());
1213 result = OHOS::ERR_INVALID_VALUE;
1214 }
1215 break;
1216 }
1217 case 'C': {
1218 // 'aa start -C'
1219 // cold start app
1220 isColdStart = true;
1221 break;
1222 }
1223 case 'D': {
1224 // 'aa start -D'
1225 // debug app
1226 isDebugApp = true;
1227 break;
1228 }
1229 case 'S': {
1230 // 'aa start -b <bundleName> -a <abilityName> -p <perf-cmd> -S'
1231 // enter sanbox to perform app
1232 isSanboxApp = true;
1233 break;
1234 }
1235 case 'c': {
1236 // 'aa start -c'
1237 // set ability launch reason = continuation
1238 isContinuation = true;
1239 break;
1240 }
1241 case 'N': {
1242 // 'aa start -N'
1243 // wait for debug in appspawn
1244 isNativeDebug = true;
1245 break;
1246 }
1247 case 0: {
1248 break;
1249 }
1250 default: {
1251 break;
1252 }
1253 }
1254 }
1255
1256 if (result == OHOS::ERR_OK) {
1257 if (abilityName.size() == 0 || bundleName.size() == 0) {
1258 // 'aa start [-d <device-id>] -a <ability-name> -b <bundle-name> [-D]'
1259 // 'aa stop-service [-d <device-id>] -a <ability-name> -b <bundle-name>'
1260 HILOG_INFO("'aa %{public}s' without enough options.", cmd_.c_str());
1261
1262 if (abilityName.size() == 0) {
1263 resultReceiver_.append(HELP_MSG_NO_ABILITY_NAME_OPTION + "\n");
1264 }
1265
1266 if (bundleName.size() == 0) {
1267 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n");
1268 }
1269
1270 result = OHOS::ERR_INVALID_VALUE;
1271 } else {
1272 ElementName element(deviceId, bundleName, abilityName, moduleName);
1273 want.SetElement(element);
1274
1275 if (isColdStart) {
1276 want.SetParam("coldStart", isColdStart);
1277 }
1278 if (isDebugApp) {
1279 want.SetParam("debugApp", isDebugApp);
1280 }
1281 if (isContinuation) {
1282 want.AddFlags(Want::FLAG_ABILITY_CONTINUATION);
1283 }
1284 if (!perfCmd.empty()) {
1285 want.SetParam("perfCmd", perfCmd);
1286 }
1287 if (isSanboxApp) {
1288 want.SetParam("sanboxApp", isSanboxApp);
1289 }
1290 if (isNativeDebug) {
1291 want.SetParam("nativeDebug", isNativeDebug);
1292 }
1293 }
1294 }
1295
1296 return result;
1297 }
1298
RunAsTestCommand()1299 ErrCode AbilityManagerShellCommand::RunAsTestCommand()
1300 {
1301 HILOG_INFO("enter");
1302 std::map<std::string, std::string> params;
1303
1304 for (int i = USER_TEST_COMMAND_START_INDEX; i < argc_; i++) {
1305 HILOG_INFO("argv_[%{public}d]: %{public}s", i, argv_[i]);
1306 std::string opt = argv_[i];
1307 if ((opt == "-h") || (opt == "--help")) {
1308 resultReceiver_.append(HELP_MSG_TEST);
1309 return OHOS::ERR_OK;
1310 } else if ((opt == "-b") || (opt == "-p") || (opt == "-m")) {
1311 if (i >= argc_ - 1) {
1312 return TestCommandError("error: option [" + opt + "] requires a value.\n");
1313 }
1314 std::string argv = argv_[++i];
1315 params[opt] = argv;
1316 } else if (opt == "-w") {
1317 if (i >= argc_ - 1) {
1318 return TestCommandError("error: option [" + opt + "] requires a value.\n");
1319 }
1320
1321 std::string argv = argv_[++i];
1322 std::smatch sm;
1323 auto isNumber = std::regex_match(argv, sm, std::regex(STRING_TEST_REGEX_INTEGER_NUMBERS));
1324 if (!isNumber) {
1325 return TestCommandError("error: option [" + opt + "] only supports integer numbers.\n");
1326 }
1327
1328 params[opt] = argv;
1329 } else if (opt == "-s") {
1330 if (i >= argc_ - USER_TEST_COMMAND_PARAMS_NUM) {
1331 return TestCommandError("error: option [-s] is incorrect.\n");
1332 }
1333 std::string argKey = argv_[++i];
1334 std::string argValue = argv_[++i];
1335 params[opt + " " + argKey] = argValue;
1336 } else if (opt == "-D") {
1337 params[opt] = DEBUG_VALUE;
1338 } else if (opt.at(0) == '-') {
1339 return TestCommandError("error: unknown option: " + opt + "\n");
1340 }
1341 }
1342
1343 if (!IsTestCommandIntegrity(params)) {
1344 return OHOS::ERR_INVALID_VALUE;
1345 }
1346
1347 return StartUserTest(params);
1348 }
1349
IsTestCommandIntegrity(const std::map<std::string,std::string> & params)1350 bool AbilityManagerShellCommand::IsTestCommandIntegrity(const std::map<std::string, std::string>& params)
1351 {
1352 HILOG_INFO("enter");
1353
1354 std::vector<std::string> opts = { "-b", "-s unittest" };
1355 for (auto opt : opts) {
1356 auto it = params.find(opt);
1357 if (it == params.end()) {
1358 TestCommandError("error: the option [" + opt + "] is expected.\n");
1359 return false;
1360 }
1361 }
1362 return true;
1363 }
1364
TestCommandError(const std::string & info)1365 ErrCode AbilityManagerShellCommand::TestCommandError(const std::string& info)
1366 {
1367 resultReceiver_.append(info);
1368 resultReceiver_.append(HELP_MSG_TEST);
1369 return OHOS::ERR_INVALID_VALUE;
1370 }
1371
StartUserTest(const std::map<std::string,std::string> & params)1372 ErrCode AbilityManagerShellCommand::StartUserTest(const std::map<std::string, std::string>& params)
1373 {
1374 HILOG_INFO("enter");
1375
1376 Want want;
1377 for (auto param : params) {
1378 want.SetParam(param.first, param.second);
1379 }
1380
1381 auto dPos = params.find("-D");
1382 if (dPos != params.end() && dPos->second.compare(DEBUG_VALUE) == 0) {
1383 HILOG_INFO("Set Debug to want");
1384 want.SetParam("debugApp", true);
1385 }
1386
1387 sptr<TestObserver> observer = new (std::nothrow) TestObserver();
1388 if (!observer) {
1389 HILOG_ERROR("Failed: the TestObserver is null");
1390 return OHOS::ERR_INVALID_VALUE;
1391 }
1392
1393 int result = AbilityManagerClient::GetInstance()->StartUserTest(want, observer->AsObject());
1394 if (result != OHOS::ERR_OK) {
1395 HILOG_INFO("%{public}s result = %{public}d", STRING_START_USER_TEST_NG.c_str(), result);
1396 resultReceiver_ = STRING_START_USER_TEST_NG + "\n";
1397 resultReceiver_.append(GetMessageFromCode(result));
1398 return result;
1399 }
1400 HILOG_INFO("%{public}s", STRING_USER_TEST_STARTED.c_str());
1401
1402 std::signal(SIGCHLD, SIG_DFL);
1403
1404 int64_t timeMs = 0;
1405 if (!want.GetStringParam("-w").empty()) {
1406 auto time = std::stoi(want.GetStringParam("-w"));
1407 timeMs = time > 0 ? time * TIME_RATE_MS : 0;
1408 }
1409 if (!observer->WaitForFinish(timeMs)) {
1410 resultReceiver_ = "Timeout: user test is not completed within the specified time.\n";
1411 return OHOS::ERR_INVALID_VALUE;
1412 }
1413
1414 HILOG_INFO("%{public}s", STRING_USER_TEST_FINISHED.c_str());
1415 resultReceiver_ = STRING_USER_TEST_FINISHED + "\n";
1416
1417 return result;
1418 }
1419
GetAbilityManagerService()1420 sptr<IAbilityManager> AbilityManagerShellCommand::GetAbilityManagerService()
1421 {
1422 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1423 if (systemManager == nullptr) {
1424 HILOG_ERROR("Fail to get registry.");
1425 return nullptr;
1426 }
1427 sptr<IRemoteObject> remoteObject = systemManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
1428 return iface_cast<IAbilityManager>(remoteObject);
1429 }
1430
1431 #ifdef ABILITY_COMMAND_FOR_TEST
RunAsSendAppNotRespondingWithUnknownOption()1432 ErrCode AbilityManagerShellCommand::RunAsSendAppNotRespondingWithUnknownOption()
1433 {
1434 switch (optopt) {
1435 case 'h': {
1436 break;
1437 }
1438 case 'p': {
1439 HILOG_INFO("'aa ApplicationNotResponding -p' with no argument.");
1440 resultReceiver_.append("error: option -p ");
1441 resultReceiver_.append("' requires a value.\n");
1442 break;
1443 }
1444 default: {
1445 std::string unknownOption;
1446 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1447 HILOG_INFO("'aa ApplicationNotResponding' with an unknown option.");
1448 resultReceiver_.append(unknownOptionMsg);
1449 break;
1450 }
1451 }
1452 return OHOS::ERR_INVALID_VALUE;
1453 }
1454
RunAsSendAppNotRespondingWithOption(int32_t option,std::string & pid)1455 ErrCode AbilityManagerShellCommand::RunAsSendAppNotRespondingWithOption(int32_t option, std::string& pid)
1456 {
1457 ErrCode result = ERR_OK;
1458 switch (option) {
1459 case 'h': {
1460 result = OHOS::ERR_INVALID_VALUE;
1461 break;
1462 }
1463 case 'p': {
1464 HILOG_INFO("aa ApplicationNotResponding 'aa %{public}s' -p process.", cmd_.c_str());
1465 HILOG_INFO("aa ApplicationNotResponding 'aa optarg = %{public}s'.", optarg);
1466 pid = optarg;
1467 HILOG_INFO("aa ApplicationNotResponding 'aa pid = %{public}s'.", pid.c_str());
1468 break;
1469 }
1470 default: {
1471 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
1472 result = OHOS::ERR_INVALID_VALUE;
1473 break;
1474 }
1475 }
1476 return result;
1477 }
1478
RunAsSendAppNotRespondingProcessID()1479 ErrCode AbilityManagerShellCommand::RunAsSendAppNotRespondingProcessID()
1480 {
1481 static sptr<IAbilityManager> abilityMs_;
1482 std::string pid = "";
1483 int option = -1;
1484 ErrCode result = OHOS::ERR_OK;
1485 option = getopt_long(argc_, argv_, SHORT_OPTIONS_APPLICATION_NOT_RESPONDING.c_str(),
1486 LONG_OPTIONS_ApplicationNotResponding, nullptr);
1487 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
1488 if (optind < 0 || optind > argc_) {
1489 return OHOS::ERR_INVALID_VALUE;
1490 }
1491 if (option == -1) {
1492 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
1493 HILOG_INFO("'aa %{public}s' %{public}s", HELP_ApplicationNotResponding.c_str(), cmd_.c_str());
1494 result = OHOS::ERR_INVALID_VALUE;
1495 }
1496 } else if (option == '?') {
1497 result = RunAsSendAppNotRespondingWithUnknownOption();
1498 } else {
1499 result = RunAsSendAppNotRespondingWithOption(option, pid);
1500 }
1501
1502 if (result == OHOS::ERR_OK) {
1503 HILOG_INFO("'aa pid = %{public}d'.", atoi(pid.c_str()));
1504 abilityMs_ = GetAbilityManagerService();
1505 if (abilityMs_ == nullptr) {
1506 std::cout << "abilityMsObj is nullptr";
1507 } else {
1508 abilityMs_->SendANRProcessID(atoi(pid.c_str()));
1509 }
1510 } else {
1511 resultReceiver_.append(HELP_ApplicationNotResponding + "\n");
1512 result = OHOS::ERR_INVALID_VALUE;
1513 }
1514 return result;
1515 }
1516
RunAsBlockAbilityCommand()1517 ErrCode AbilityManagerShellCommand::RunAsBlockAbilityCommand()
1518 {
1519 HILOG_INFO("[%{public}s(%{public}s)] enter", __FILE__, __FUNCTION__);
1520 ErrCode result = OHOS::ERR_OK;
1521 if (argList_.size() > 0) {
1522 result = AbilityManagerClient::GetInstance()->BlockAbility(atoi(argList_[0].c_str()));
1523 } else {
1524 result = OHOS::ERR_INVALID_VALUE;
1525 }
1526
1527 if (result == OHOS::ERR_OK) {
1528 HILOG_INFO("%{public}s", STRING_BLOCK_ABILITY_OK.c_str());
1529 resultReceiver_ = STRING_BLOCK_ABILITY_OK + "\n";
1530 } else {
1531 HILOG_INFO("%{public}s result = %{public}d", STRING_BLOCK_ABILITY_NG.c_str(), result);
1532 resultReceiver_ = STRING_BLOCK_ABILITY_NG + "\n";
1533 resultReceiver_.append(GetMessageFromCode(result));
1534 }
1535 return result;
1536 }
1537
RunAsBlockAmsServiceCommand()1538 ErrCode AbilityManagerShellCommand::RunAsBlockAmsServiceCommand()
1539 {
1540 HILOG_INFO("[%{public}s(%{public}s)] enter", __FILE__, __FUNCTION__);
1541 ErrCode result = OHOS::ERR_OK;
1542 result = AbilityManagerClient::GetInstance()->BlockAmsService();
1543 if (result == OHOS::ERR_OK) {
1544 HILOG_INFO("%{public}s", STRING_BLOCK_AMS_SERVICE_OK.c_str());
1545 resultReceiver_ = STRING_BLOCK_AMS_SERVICE_OK + "\n";
1546 } else {
1547 HILOG_INFO("%{public}s result = %{public}d", STRING_BLOCK_AMS_SERVICE_NG.c_str(), result);
1548 resultReceiver_ = STRING_BLOCK_AMS_SERVICE_NG + "\n";
1549 resultReceiver_.append(GetMessageFromCode(result));
1550 }
1551 return result;
1552 }
1553
RunAsBlockAppServiceCommand()1554 ErrCode AbilityManagerShellCommand::RunAsBlockAppServiceCommand()
1555 {
1556 HILOG_INFO("[%{public}s(%{public}s)] enter", __FILE__, __FUNCTION__);
1557 ErrCode result = OHOS::ERR_OK;
1558 result = AbilityManagerClient::GetInstance()->BlockAppService();
1559 if (result == OHOS::ERR_OK) {
1560 HILOG_INFO("%{public}s", STRING_BLOCK_APP_SERVICE_OK.c_str());
1561 resultReceiver_ = STRING_BLOCK_APP_SERVICE_OK + "\n";
1562 } else {
1563 HILOG_INFO("%{public}s result = %{public}d", STRING_BLOCK_APP_SERVICE_NG.c_str(), result);
1564 resultReceiver_ = STRING_BLOCK_APP_SERVICE_NG + "\n";
1565 resultReceiver_.append(GetMessageFromCode(result));
1566 }
1567 return result;
1568 }
1569 #endif
1570 #ifdef ABILITY_FAULT_AND_EXIT_TEST
CovertExitReason(std::string & cmd)1571 Reason CovertExitReason(std::string &cmd)
1572 {
1573 if (cmd.empty()) {
1574 return Reason::REASON_UNKNOWN;
1575 }
1576
1577 if (cmd.compare("UNKNOWN") == 0) {
1578 return Reason::REASON_UNKNOWN;
1579 } else if (cmd.compare("NORMAL") == 0) {
1580 return Reason::REASON_NORMAL;
1581 } else if (cmd.compare("CPP_CRASH") == 0) {
1582 return Reason::REASON_CPP_CRASH;
1583 } else if (cmd.compare("JS_ERROR") == 0) {
1584 return Reason::REASON_JS_ERROR;
1585 } else if (cmd.compare("ABILITY_NOT_RESPONDING") == 0) {
1586 return Reason::REASON_APP_FREEZE;
1587 } else if (cmd.compare("APP_FREEZE") == 0) {
1588 return Reason::REASON_APP_FREEZE;
1589 } else if (cmd.compare("PERFORMANCE_CONTROL") == 0) {
1590 return Reason::REASON_PERFORMANCE_CONTROL;
1591 } else if (cmd.compare("RESOURCE_CONTROL") == 0) {
1592 return Reason::REASON_RESOURCE_CONTROL;
1593 } else if (cmd.compare("UPGRADE") == 0) {
1594 return Reason::REASON_UPGRADE;
1595 }
1596
1597 return Reason::REASON_UNKNOWN;
1598 }
1599
RunAsForceExitAppCommand()1600 ErrCode AbilityManagerShellCommand::RunAsForceExitAppCommand()
1601 {
1602 HILOG_DEBUG("enter");
1603 int result = OHOS::ERR_OK;
1604
1605 int option = -1;
1606 int counter = 0;
1607
1608 std::string pid;
1609 std::string reason;
1610
1611 while (true) {
1612 counter++;
1613 option = getopt_long(argc_, argv_, SHORT_OPTIONS_FORCE_EXIT_APP.c_str(), LONG_OPTIONS_FORCE_EXIT_APP, nullptr);
1614 HILOG_DEBUG("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
1615
1616 if (optind < 0 || optind > argc_) {
1617 return OHOS::ERR_INVALID_VALUE;
1618 }
1619
1620 if (option == -1) {
1621 if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
1622 HILOG_ERROR("'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
1623 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
1624 result = OHOS::ERR_INVALID_VALUE;
1625 }
1626 break;
1627 }
1628
1629 switch (option) {
1630 case 'h': {
1631 HILOG_INFO("'aa %{public}s -h' with no argument.", cmd_.c_str());
1632 // 'aa forceexitapp -h'
1633 // 'aa forceexitapp --help'
1634 result = OHOS::ERR_INVALID_VALUE;
1635 break;
1636 }
1637 case 'p': {
1638 HILOG_INFO("'aa %{public}s -p' pid.", cmd_.c_str());
1639 // 'aa forceexitapp -p pid'
1640 pid = optarg;
1641 break;
1642 }
1643 case 'r': {
1644 HILOG_INFO("'aa %{public}s -r' reason.", cmd_.c_str());
1645 // 'aa forceexitapp -r reason'
1646 reason = optarg;
1647 break;
1648 }
1649 case '?': {
1650 std::string unknownOption = "";
1651 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1652 HILOG_INFO("'aa notifyappfault' with an unknown option.");
1653 resultReceiver_.append(unknownOptionMsg);
1654 result = OHOS::ERR_INVALID_VALUE;
1655 break;
1656 }
1657 default: {
1658 break;
1659 }
1660 }
1661 }
1662
1663 if (result != OHOS::ERR_OK) {
1664 resultReceiver_.append(HELP_MSG_SCREEN);
1665 result = OHOS::ERR_INVALID_VALUE;
1666 }
1667
1668 result = AbilityManagerClient::GetInstance()->ForceExitApp(std::stoi(pid), CovertExitReason(reason));
1669 if (result == OHOS::ERR_OK) {
1670 resultReceiver_ = STRING_BLOCK_AMS_SERVICE_OK + "\n";
1671 } else {
1672 HILOG_INFO("%{public}s result = %{public}d", STRING_BLOCK_AMS_SERVICE_NG.c_str(), result);
1673 resultReceiver_ = STRING_BLOCK_AMS_SERVICE_NG + "\n";
1674 resultReceiver_.append(GetMessageFromCode(result));
1675 }
1676
1677 HILOG_DEBUG("pid: %{public}s, reason: %{public}s", pid.c_str(), reason.c_str());
1678 return result;
1679 }
1680
CovertFaultType(std::string & cmd)1681 FaultDataType CovertFaultType(std::string &cmd)
1682 {
1683 if (cmd.empty()) {
1684 return FaultDataType::UNKNOWN;
1685 }
1686
1687 if (cmd.compare("UNKNOWN") == 0) {
1688 return FaultDataType::UNKNOWN;
1689 } else if (cmd.compare("CPP_CRASH") == 0) {
1690 return FaultDataType::CPP_CRASH;
1691 } else if (cmd.compare("JS_ERROR") == 0) {
1692 return FaultDataType::JS_ERROR;
1693 } else if (cmd.compare("APP_FREEZE") == 0) {
1694 return FaultDataType::APP_FREEZE;
1695 } else if (cmd.compare("PERFORMANCE_CONTROL") == 0) {
1696 return FaultDataType::PERFORMANCE_CONTROL;
1697 } else if (cmd.compare("RESOURCE_CONTROL") == 0) {
1698 return FaultDataType::RESOURCE_CONTROL;
1699 }
1700
1701 return FaultDataType::UNKNOWN;
1702 }
1703
RunAsNotifyAppFaultCommand()1704 ErrCode AbilityManagerShellCommand::RunAsNotifyAppFaultCommand()
1705 {
1706 HILOG_DEBUG("called");
1707 int result = OHOS::ERR_OK;
1708 int option = -1;
1709 int counter = 0;
1710 std::string errorName = "";
1711 std::string errorMessage = "";
1712 std::string errorStack = "";
1713 std::string faultType = "";
1714 std::string pid = "";
1715 while (true) {
1716 counter++;
1717 option = getopt_long(
1718 argc_, argv_, SHORT_OPTIONS_NOTIFY_APP_FAULT.c_str(), LONG_OPTIONS_NOTIFY_APP_FAULT, nullptr);
1719 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
1720 if (optind < 0 || optind > argc_) {
1721 return OHOS::ERR_INVALID_VALUE;
1722 }
1723
1724 if (option == -1) {
1725 if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
1726 HILOG_INFO("'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
1727 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
1728 result = OHOS::ERR_INVALID_VALUE;
1729 }
1730 break;
1731 }
1732
1733 switch (option) {
1734 case 'h': {
1735 HILOG_INFO("'aa %{public}s -h' with no argument.", cmd_.c_str());
1736 // 'aa notifyappfault -h'
1737 // 'aa notifyappfault --help'
1738 result = OHOS::ERR_INVALID_VALUE;
1739 break;
1740 }
1741 case 'n': {
1742 HILOG_INFO("'aa %{public}s -n' errorName.", cmd_.c_str());
1743 // 'aa notifyappfault -n errorName'
1744 errorName = optarg;
1745 break;
1746 }
1747 case 'm': {
1748 HILOG_INFO("'aa %{public}s -m' errorMessage.", cmd_.c_str());
1749 // 'aa notifyappfault -m errorMessage'
1750 errorMessage = optarg;
1751 break;
1752 }
1753 case 's': {
1754 HILOG_INFO("'aa %{public}s -s' errorStack.", cmd_.c_str());
1755 // 'aa notifyappfault -s errorStack'
1756 errorStack = optarg;
1757 break;
1758 }
1759 case 't': {
1760 HILOG_INFO("'aa %{public}s -t' faultType.", cmd_.c_str());
1761 // 'aa notifyappfault -t faultType'
1762 faultType = optarg;
1763 break;
1764 }
1765 case 'p': {
1766 HILOG_INFO("'aa %{public}s -p' pid.", cmd_.c_str());
1767 // 'aa notifyappfault -p pid'
1768 pid = optarg;
1769 break;
1770 }
1771 case '?': {
1772 std::string unknownOption = "";
1773 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1774 HILOG_INFO("'aa notifyappfault' with an unknown option.");
1775 resultReceiver_.append(unknownOptionMsg);
1776 result = OHOS::ERR_INVALID_VALUE;
1777 break;
1778 }
1779 default: {
1780 break;
1781 }
1782 }
1783 }
1784
1785 if (result != OHOS::ERR_OK) {
1786 resultReceiver_.append(HELP_MSG_SCREEN);
1787 result = OHOS::ERR_INVALID_VALUE;
1788 }
1789
1790 HILOG_INFO("name: %{public}s, message: %{public}s, stack: %{public}s, type: %{public}s, pid: %{public}s",
1791 errorName.c_str(), errorMessage.c_str(), errorStack.c_str(), faultType.c_str(), pid.c_str());
1792
1793 AppFaultDataBySA faultData;
1794 faultData.errorObject.name = errorName;
1795 faultData.errorObject.message = errorMessage;
1796 faultData.errorObject.stack = errorStack;
1797 faultData.faultType = CovertFaultType(faultType);
1798 faultData.pid = std::stoi(pid);
1799 DelayedSingleton<AppMgrClient>::GetInstance()->NotifyAppFaultBySA(faultData);
1800 return result;
1801 }
1802 #endif
1803 } // namespace AAFwk
1804 } // namespace OHOS
1805