1 /*
2 * Copyright (c) 2021-2022 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 "hilog_wrapper.h"
23 #include "iservice_registry.h"
24 #include "mission_snapshot.h"
25 #include "bool_wrapper.h"
26 #include "sa_mgr_client.h"
27 #include "system_ability_definition.h"
28 #include "test_observer.h"
29
30 using namespace OHOS::AppExecFwk;
31
32 namespace OHOS {
33 namespace AAFwk {
34 namespace {
35 const std::string SHORT_OPTIONS = "ch:d:a:b:p:s:m:CD";
36 constexpr struct option LONG_OPTIONS[] = {
37 {"help", no_argument, nullptr, 'h'},
38 {"device", required_argument, nullptr, 'd'},
39 {"ability", required_argument, nullptr, 'a'},
40 {"bundle", required_argument, nullptr, 'b'},
41 {"power", required_argument, nullptr, 'p'},
42 {"setting", required_argument, nullptr, 's'},
43 {"module", required_argument, nullptr, 'm'},
44 {"cold-start", no_argument, nullptr, 'C'},
45 {"debug", no_argument, nullptr, 'D'},
46 {nullptr, 0, nullptr, 0},
47 };
48 const std::string SHORT_OPTIONS_APPLICATION_NOT_RESPONDING = "hp:";
49 #ifdef ABILITY_COMMAND_FOR_TEST
50 constexpr struct option LONG_OPTIONS_ApplicationNotResponding[] = {
51 {"help", no_argument, nullptr, 'h'},
52 {"pid", required_argument, nullptr, 'p'},
53 {nullptr, 0, nullptr, 0},
54 };
55 #endif
56 const std::string SHORT_OPTIONS_DUMPSYS = "hal::i:e::p::r::d::u:c";
57 constexpr struct option LONG_OPTIONS_DUMPSYS[] = {
58 {"help", no_argument, nullptr, 'h'},
59 {"all", no_argument, nullptr, 'a'},
60 {"mission-list", no_argument, nullptr, 'l'},
61 {"ability", required_argument, nullptr, 'i'},
62 {"extension", no_argument, nullptr, 'e'},
63 {"pending", no_argument, nullptr, 'p'},
64 {"process", no_argument, nullptr, 'r'},
65 {"data", no_argument, nullptr, 'd'},
66 {"userId", required_argument, nullptr, 'u'},
67 {"client", no_argument, nullptr, 'c'},
68 {nullptr, 0, nullptr, 0},
69 };
70 } // namespace
71
AbilityManagerShellCommand(int argc,char * argv[])72 AbilityManagerShellCommand::AbilityManagerShellCommand(int argc, char *argv[]) : ShellCommand(argc, argv, TOOL_NAME)
73 {
74 for (int i = 0; i < argc_; i++) {
75 HILOG_INFO("argv_[%{public}d]: %{public}s", i, argv_[i]);
76 }
77 }
78
CreateCommandMap()79 ErrCode AbilityManagerShellCommand::CreateCommandMap()
80 {
81 commandMap_ = {
82 {"help", std::bind(&AbilityManagerShellCommand::RunAsHelpCommand, this)},
83 {"screen", std::bind(&AbilityManagerShellCommand::RunAsScreenCommand, this)},
84 {"start", std::bind(&AbilityManagerShellCommand::RunAsStartAbility, this)},
85 {"stop-service", std::bind(&AbilityManagerShellCommand::RunAsStopService, this)},
86 {"dump", std::bind(&AbilityManagerShellCommand::RunAsDumpsysCommand, this)},
87 {"force-stop", std::bind(&AbilityManagerShellCommand::RunAsForceStop, this)},
88 {"test", std::bind(&AbilityManagerShellCommand::RunAsTestCommand, this)},
89 #ifdef ABILITY_COMMAND_FOR_TEST
90 {"force-timeout", std::bind(&AbilityManagerShellCommand::RunForceTimeoutForTest, this)},
91 {"ApplicationNotResponding", std::bind(&AbilityManagerShellCommand::RunAsSendAppNotRespondingProcessID, this)},
92 {"block-ability", std::bind(&AbilityManagerShellCommand::RunAsBlockAbilityCommand, this)},
93 {"block-ams-service", std::bind(&AbilityManagerShellCommand::RunAsBlockAmsServiceCommand, this)},
94 {"block-app-service", std::bind(&AbilityManagerShellCommand::RunAsBlockAppServiceCommand, this)},
95 #endif
96 };
97
98 return OHOS::ERR_OK;
99 }
100
CreateMessageMap()101 ErrCode AbilityManagerShellCommand::CreateMessageMap()
102 {
103 messageMap_ = {
104 // code + message
105 {
106 RESOLVE_ABILITY_ERR,
107 "error: resolve ability err.",
108 },
109 {
110 GET_ABILITY_SERVICE_FAILED,
111 "error: get ability service failed.",
112 },
113 {
114 ABILITY_SERVICE_NOT_CONNECTED,
115 "error: ability service not connected.",
116 },
117 {
118 RESOLVE_APP_ERR,
119 "error: resolve app err.",
120 },
121 {
122 ABILITY_EXISTED,
123 "error: ability existed.",
124 },
125 {
126 CREATE_MISSION_STACK_FAILED,
127 "error: create mission stack failed.",
128 },
129 {
130 CREATE_ABILITY_RECORD_FAILED,
131 "error: create ability record failed.",
132 },
133 {
134 START_ABILITY_WAITING,
135 "start ability successfully. waiting...",
136 },
137 {
138 TERMINATE_LAUNCHER_DENIED,
139 "error: terminate launcher denied.",
140 },
141 {
142 CONNECTION_NOT_EXIST,
143 "error: connection not exist.",
144 },
145 {
146 INVALID_CONNECTION_STATE,
147 "error: invalid connection state.",
148 },
149 {
150 LOAD_ABILITY_TIMEOUT,
151 "error: load ability timeout.",
152 },
153 {
154 CONNECTION_TIMEOUT,
155 "error: connection timeout.",
156 },
157 {
158 GET_BUNDLE_MANAGER_SERVICE_FAILED,
159 "error: get bundle manager service failed.",
160 },
161 {
162 REMOVE_MISSION_FAILED,
163 "error: remove mission failed.",
164 },
165 {
166 INNER_ERR,
167 "error: inner err.",
168 },
169 {
170 GET_RECENT_MISSIONS_FAILED,
171 "error: get recent missions failed.",
172 },
173 {
174 REMOVE_STACK_LAUNCHER_DENIED,
175 "error: remove stack launcher denied.",
176 },
177 {
178 TARGET_ABILITY_NOT_SERVICE,
179 "error: target ability not service.",
180 },
181 {
182 TERMINATE_SERVICE_IS_CONNECTED,
183 "error: terminate service is connected.",
184 },
185 {
186 START_SERVICE_ABILITY_ACTIVATING,
187 "error: start service ability activating.",
188 },
189 {
190 KILL_PROCESS_FAILED,
191 "error: kill process failed.",
192 },
193 {
194 UNINSTALL_APP_FAILED,
195 "error: uninstall app failed.",
196 },
197 {
198 TERMINATE_ABILITY_RESULT_FAILED,
199 "error: terminate ability result failed.",
200 },
201 {
202 CHECK_PERMISSION_FAILED,
203 "error: check permission failed.",
204 },
205 {
206 NO_FOUND_ABILITY_BY_CALLER,
207 "error: no found ability by caller.",
208 },
209 {
210 ABILITY_VISIBLE_FALSE_DENY_REQUEST,
211 "error: ability visible false deny request.",
212 },
213 {
214 GET_BUNDLE_INFO_FAILED,
215 "error: get bundle info failed.",
216 },
217 {
218 KILL_PROCESS_KEEP_ALIVE,
219 "error: keep alive process can not be killed.",
220 },
221 };
222
223 return OHOS::ERR_OK;
224 }
225
init()226 ErrCode AbilityManagerShellCommand::init()
227 {
228 return AbilityManagerClient::GetInstance()->Connect();
229 }
230
RunAsHelpCommand()231 ErrCode AbilityManagerShellCommand::RunAsHelpCommand()
232 {
233 resultReceiver_.append(HELP_MSG);
234
235 return OHOS::ERR_OK;
236 }
237
RunAsScreenCommand()238 ErrCode AbilityManagerShellCommand::RunAsScreenCommand()
239 {
240 HILOG_INFO("enter");
241
242 int result = OHOS::ERR_OK;
243
244 int option = -1;
245 int counter = 0;
246
247 while (true) {
248 counter++;
249
250 option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
251
252 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
253
254 if (optind < 0 || optind > argc_) {
255 return OHOS::ERR_INVALID_VALUE;
256 }
257
258 if (option == -1) {
259 // When scanning the first argument
260 if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
261 // 'aa screen' with no option: aa screen
262 // 'aa screen' with a wrong argument: aa screen xxx
263 HILOG_INFO("'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
264 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
265 result = OHOS::ERR_INVALID_VALUE;
266 }
267 break;
268 }
269
270 if (option == '?') {
271 switch (optopt) {
272 case 'p': {
273 // 'aa screen -p' with no argument
274 HILOG_INFO("'aa %{public}s -p' with no argument.", cmd_.c_str());
275
276 resultReceiver_.append("error: option ");
277 resultReceiver_.append("requires a value.\n");
278
279 result = OHOS::ERR_INVALID_VALUE;
280 break;
281 }
282 case 0: {
283 // 'aa screen' with an unknown option: aa screen --x
284 // 'aa screen' with an unknown option: aa screen --xxx
285 std::string unknownOption = "";
286 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
287
288 HILOG_INFO("'aa screen' with an unknown option.");
289
290 resultReceiver_.append(unknownOptionMsg);
291 result = OHOS::ERR_INVALID_VALUE;
292 break;
293 }
294 default: {
295 // 'aa screen' with an unknown option: aa screen -x
296 // 'aa screen' with an unknown option: aa screen -xxx
297 std::string unknownOption = "";
298 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
299
300 HILOG_INFO("'aa screen' with an unknown option.");
301
302 resultReceiver_.append(unknownOptionMsg);
303 result = OHOS::ERR_INVALID_VALUE;
304 break;
305 }
306 }
307 break;
308 }
309
310 switch (option) {
311 case 'h': {
312 // 'aa screen -h'
313 // 'aa screen --help'
314 result = OHOS::ERR_INVALID_VALUE;
315 break;
316 }
317 case 0: {
318 break;
319 }
320 default: {
321 break;
322 }
323 }
324 }
325
326 if (result != OHOS::ERR_OK) {
327 resultReceiver_.append(HELP_MSG_SCREEN);
328 result = OHOS::ERR_INVALID_VALUE;
329 }
330
331 return result;
332 }
333
RunAsStartAbility()334 ErrCode AbilityManagerShellCommand::RunAsStartAbility()
335 {
336 Want want;
337 std::string windowMode;
338 ErrCode result = MakeWantFromCmd(want, windowMode);
339 if (result == OHOS::ERR_OK) {
340 int windowModeKey = std::atoi(windowMode.c_str());
341 if (windowModeKey > 0) {
342 auto setting = AbilityStartSetting::GetEmptySetting();
343 if (setting != nullptr) {
344 setting->AddProperty(AbilityStartSetting::WINDOW_MODE_KEY, windowMode);
345 result = AbilityManagerClient::GetInstance()->StartAbility(want, *(setting.get()), nullptr, -1);
346 }
347 } else {
348 result = AbilityManagerClient::GetInstance()->StartAbility(want);
349 }
350 if (result == OHOS::ERR_OK) {
351 HILOG_INFO("%{public}s", STRING_START_ABILITY_OK.c_str());
352 resultReceiver_ = STRING_START_ABILITY_OK + "\n";
353 } else {
354 HILOG_INFO("%{public}s result = %{public}d", STRING_START_ABILITY_NG.c_str(), result);
355 if (result != START_ABILITY_WAITING) {
356 resultReceiver_ = STRING_START_ABILITY_NG + "\n";
357 }
358 resultReceiver_.append(GetMessageFromCode(result));
359 }
360 } else {
361 resultReceiver_.append(HELP_MSG_START);
362 result = OHOS::ERR_INVALID_VALUE;
363 }
364
365 return result;
366 }
367
RunAsStopService()368 ErrCode AbilityManagerShellCommand::RunAsStopService()
369 {
370 ErrCode result = OHOS::ERR_OK;
371
372 Want want;
373 std::string windowMode;
374 result = MakeWantFromCmd(want, windowMode);
375 if (result == OHOS::ERR_OK) {
376 result = AbilityManagerClient::GetInstance()->StopServiceAbility(want);
377 if (result == OHOS::ERR_OK) {
378 HILOG_INFO("%{public}s", STRING_STOP_SERVICE_ABILITY_OK.c_str());
379 resultReceiver_ = STRING_STOP_SERVICE_ABILITY_OK + "\n";
380 } else {
381 HILOG_INFO("%{public}s result = %{public}d", STRING_STOP_SERVICE_ABILITY_NG.c_str(), result);
382 resultReceiver_ = STRING_STOP_SERVICE_ABILITY_NG + "\n";
383
384 resultReceiver_.append(GetMessageFromCode(result));
385 }
386 } else {
387 resultReceiver_.append(HELP_MSG_STOP_SERVICE);
388 result = OHOS::ERR_INVALID_VALUE;
389 }
390
391 return result;
392 }
393
RunAsDumpsysCommand()394 ErrCode AbilityManagerShellCommand::RunAsDumpsysCommand()
395 {
396 ErrCode result = OHOS::ERR_OK;
397 bool isUserID = false;
398 bool isClient = false;
399 int userID = DEFAULT_INVAL_VALUE;
400 bool isfirstCommand = false;
401 std::string args;
402 for (auto it = argList_.begin(); it != argList_.end(); it++) {
403 if (*it == "-c" || *it == "--client") {
404 if (isClient == false) {
405 isClient = true;
406 } else {
407 result = OHOS::ERR_INVALID_VALUE;
408 resultReceiver_.append(HELP_MSG_DUMPSYS);
409 return result;
410 }
411 } else if (*it == "-u" || *it == "--userId") {
412 if (it + 1 == argList_.end()) {
413 result = OHOS::ERR_INVALID_VALUE;
414 resultReceiver_.append(HELP_MSG_DUMPSYS);
415 return result;
416 }
417 (void)StrToInt(*(it + 1), userID);
418 if (userID == DEFAULT_INVAL_VALUE) {
419 result = OHOS::ERR_INVALID_VALUE;
420 resultReceiver_.append(HELP_MSG_DUMPSYS);
421 return result;
422 }
423 if (isUserID == false) {
424 isUserID = true;
425 } else {
426 result = OHOS::ERR_INVALID_VALUE;
427 resultReceiver_.append(HELP_MSG_DUMPSYS);
428 return result;
429 }
430 } else if (*it == std::to_string(userID)) {
431 continue;
432 } else {
433 args += *it;
434 args += " ";
435 }
436 }
437
438 while (true) {
439 int option = getopt_long(argc_, argv_, SHORT_OPTIONS_DUMPSYS.c_str(), LONG_OPTIONS_DUMPSYS, nullptr);
440
441 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
442
443 if (optind < 0 || optind > argc_) {
444 resultReceiver_.append(HELP_MSG_DUMPSYS);
445 return OHOS::ERR_INVALID_VALUE;
446 }
447
448 if (option == -1) {
449 break;
450 }
451
452 switch (option) {
453 case 'h': {
454 // 'aa dumpsys -h'
455 // 'aa dumpsys --help'
456 resultReceiver_.append(HELP_MSG_DUMPSYS);
457 result = OHOS::ERR_INVALID_VALUE;
458 return result;
459 }
460 case 'a': {
461 if (isfirstCommand == false) {
462 isfirstCommand = true;
463 } else {
464 result = OHOS::ERR_INVALID_VALUE;
465 resultReceiver_.append(HELP_MSG_DUMPSYS);
466 return result;
467 }
468 // 'aa dumpsys -a'
469 // 'aa dumpsys --all'
470 break;
471 }
472 case 'l': {
473 if (isfirstCommand == false) {
474 isfirstCommand = true;
475 } else {
476 // 'aa dump -i 10 -element -lastpage'
477 // 'aa dump -i 10 -render -lastpage'
478 // 'aa dump -i 10 -layer'
479 if ((optarg != nullptr) && strcmp(optarg, "astpage") && strcmp(optarg, "ayer")) {
480 result = OHOS::ERR_INVALID_VALUE;
481 resultReceiver_.append(HELP_MSG_DUMPSYS);
482 return result;
483 }
484 }
485 // 'aa dumpsys -l'
486 // 'aa dumpsys --mission-list'
487 break;
488 }
489 case 'i': {
490 if (isfirstCommand == false) {
491 isfirstCommand = true;
492 int abilityRecordId = DEFAULT_INVAL_VALUE;
493 (void)StrToInt(optarg, abilityRecordId);
494 if (abilityRecordId == DEFAULT_INVAL_VALUE) {
495 result = OHOS::ERR_INVALID_VALUE;
496 resultReceiver_.append(HELP_MSG_DUMPSYS);
497 return result;
498 }
499 } else {
500 // 'aa dumpsys -i 10 -inspector'
501 if ((optarg != nullptr) && strcmp(optarg, "nspector")) {
502 result = OHOS::ERR_INVALID_VALUE;
503 resultReceiver_.append(HELP_MSG_DUMPSYS);
504 return result;
505 }
506 }
507 // 'aa dumpsys -i'
508 // 'aa dumpsys --ability'
509 break;
510 }
511 case 'e': {
512 if (isfirstCommand == false && optarg == nullptr) {
513 isfirstCommand = true;
514 } else {
515 // 'aa dumpsys -i 10 -element'
516 if ((optarg != nullptr) && strcmp(optarg, "lement")) {
517 result = OHOS::ERR_INVALID_VALUE;
518 resultReceiver_.append(HELP_MSG_DUMPSYS);
519 return result;
520 }
521 }
522 // 'aa dumpsys -e'
523 // 'aa dumpsys --extension'
524 break;
525 }
526 case 'p': {
527 if (isfirstCommand == false && optarg == nullptr) {
528 isfirstCommand = true;
529 } else {
530 result = OHOS::ERR_INVALID_VALUE;
531 resultReceiver_.append(HELP_MSG_DUMPSYS);
532 return result;
533 }
534 // 'aa dumpsys -p'
535 // 'aa dumpsys --pending'
536 break;
537 }
538 case 'r': {
539 if (isfirstCommand == false && optarg == nullptr) {
540 isfirstCommand = true;
541 } else {
542 // 'aa dump -i 10 -render'
543 // 'aa dump -i 10 -rotation'
544 // 'aa dump -i 10 -frontend'
545 if ((optarg != nullptr) && strcmp(optarg, "ender") && strcmp(optarg, "otation") &&
546 strcmp(optarg, "ontend")) {
547 result = OHOS::ERR_INVALID_VALUE;
548 resultReceiver_.append(HELP_MSG_DUMPSYS);
549 return result;
550 }
551 }
552 // 'aa dumpsys -r'
553 // 'aa dumpsys --process'
554 break;
555 }
556 case 'd': {
557 if (isfirstCommand == false && optarg == nullptr) {
558 isfirstCommand = true;
559 } else {
560 result = OHOS::ERR_INVALID_VALUE;
561 resultReceiver_.append(HELP_MSG_DUMPSYS);
562 return result;
563 }
564 // 'aa dumpsys -d'
565 // 'aa dumpsys --data'
566 break;
567 }
568 case 'u': {
569 // 'aa dumpsys -u'
570 // 'aa dumpsys --userId'
571 break;
572 }
573 case 'c': {
574 // 'aa dumpsys -c'
575 // 'aa dumpsys --client'
576 break;
577 }
578 case '?': {
579 if (!isfirstCommand) {
580 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
581 std::string unknownOption = "";
582 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
583 resultReceiver_.append(unknownOptionMsg);
584 resultReceiver_.append(HELP_MSG_DUMPSYS);
585 result = OHOS::ERR_INVALID_VALUE;
586 return result;
587 }
588 break;
589 }
590 default: {
591 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
592 std::string unknownOption = "";
593 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
594 resultReceiver_.append(unknownOptionMsg);
595 result = OHOS::ERR_INVALID_VALUE;
596 break;
597 }
598 }
599 }
600
601 if (result != OHOS::ERR_OK) {
602 resultReceiver_.append(HELP_MSG_DUMPSYS);
603 } else {
604 if (isfirstCommand != true) {
605 result = OHOS::ERR_INVALID_VALUE;
606 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
607 resultReceiver_.append(HELP_MSG_DUMPSYS);
608 return result;
609 }
610
611 std::vector<std::string> dumpResults;
612 result = AbilityManagerClient::GetInstance()->DumpSysState(args, dumpResults, isClient, isUserID, userID);
613 if (result == OHOS::ERR_OK) {
614 for (auto it : dumpResults) {
615 resultReceiver_ += it + "\n";
616 }
617 } else {
618 HILOG_INFO("failed to dump state.");
619 }
620 }
621 return result;
622 }
623
RunAsForceStop()624 ErrCode AbilityManagerShellCommand::RunAsForceStop()
625 {
626 HILOG_INFO("[%{public}s(%{public}s)] enter", __FILE__, __FUNCTION__);
627 if (argList_.empty()) {
628 resultReceiver_.append(HELP_MSG_FORCE_STOP + "\n");
629 return OHOS::ERR_INVALID_VALUE;
630 }
631 HILOG_INFO("Bundle name : %{public}s", argList_[0].c_str());
632 ErrCode result = OHOS::ERR_OK;
633 result = AbilityManagerClient::GetInstance()->KillProcess(argList_[0]);
634 if (result == OHOS::ERR_OK) {
635 HILOG_INFO("%{public}s", STRING_FORCE_STOP_OK.c_str());
636 resultReceiver_ = STRING_FORCE_STOP_OK + "\n";
637 } else {
638 HILOG_INFO("%{public}s result = %{public}d", STRING_FORCE_STOP_NG.c_str(), result);
639 resultReceiver_ = STRING_FORCE_STOP_NG + "\n";
640 resultReceiver_.append(GetMessageFromCode(result));
641 }
642 return result;
643 }
644
645 #ifdef ABILITY_COMMAND_FOR_TEST
RunForceTimeoutForTest()646 ErrCode AbilityManagerShellCommand::RunForceTimeoutForTest()
647 {
648 HILOG_INFO("[%{public}s(%{public}s)] enter", __FILE__, __FUNCTION__);
649 if (argList_.empty()) {
650 resultReceiver_.append(HELP_MSG_FORCE_TIMEOUT + "\n");
651 return OHOS::ERR_INVALID_VALUE;
652 }
653
654 ErrCode result = OHOS::ERR_OK;
655 if (argList_.size() == NUMBER_ONE && argList_[0] == HELP_MSG_FORCE_TIMEOUT_CLEAN) {
656 HILOG_INFO("clear ability timeout flags.");
657 result = AbilityManagerClient::GetInstance()->ForceTimeoutForTest(argList_[0], "");
658 } else if (argList_.size() == NUMBER_TWO) {
659 HILOG_INFO("Ability name : %{public}s, state: %{public}s", argList_[0].c_str(), argList_[1].c_str());
660 result = AbilityManagerClient::GetInstance()->ForceTimeoutForTest(argList_[0], argList_[1]);
661 } else {
662 resultReceiver_.append(HELP_MSG_FORCE_TIMEOUT + "\n");
663 return OHOS::ERR_INVALID_VALUE;
664 }
665 if (result == OHOS::ERR_OK) {
666 HILOG_INFO("%{public}s", STRING_FORCE_TIMEOUT_OK.c_str());
667 resultReceiver_ = STRING_FORCE_TIMEOUT_OK + "\n";
668 } else {
669 HILOG_INFO("%{public}s result = %{public}d", STRING_FORCE_TIMEOUT_NG.c_str(), result);
670 resultReceiver_ = STRING_FORCE_TIMEOUT_NG + "\n";
671 resultReceiver_.append(GetMessageFromCode(result));
672 }
673 return result;
674 }
675 #endif
676
MakeWantFromCmd(Want & want,std::string & windowMode)677 ErrCode AbilityManagerShellCommand::MakeWantFromCmd(Want &want, std::string &windowMode)
678 {
679 int result = OHOS::ERR_OK;
680
681 int option = -1;
682 int counter = 0;
683
684 std::string deviceId = "";
685 std::string bundleName = "";
686 std::string abilityName = "";
687 std::string moduleName;
688 bool isColdStart = false;
689 bool isDebugApp = false;
690 bool isContinuation = false;
691
692 while (true) {
693 counter++;
694
695 option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
696
697 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
698
699 if (optind < 0 || optind > argc_) {
700 return OHOS::ERR_INVALID_VALUE;
701 }
702
703 if (option == -1) {
704 // When scanning the first argument
705 if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
706 // 'aa start' with no option: aa start
707 // 'aa start' with a wrong argument: aa start xxx
708 // 'aa stop-service' with no option: aa stop-service
709 // 'aa stop-service' with a wrong argument: aa stop-service xxx
710 HILOG_INFO("'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
711
712 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
713 result = OHOS::ERR_INVALID_VALUE;
714 }
715 break;
716 }
717
718 if (option == '?') {
719 switch (optopt) {
720 case 'h': {
721 // 'aa start -h'
722 // 'aa stop-service -h'
723 result = OHOS::ERR_INVALID_VALUE;
724 break;
725 }
726 case 'd': {
727 // 'aa start -d' with no argument
728 // 'aa stop-service -d' with no argument
729 HILOG_INFO("'aa %{public}s -d' with no argument.", cmd_.c_str());
730
731 resultReceiver_.append("error: option ");
732 resultReceiver_.append("requires a value.\n");
733
734 result = OHOS::ERR_INVALID_VALUE;
735 break;
736 }
737 case 'a': {
738 // 'aa start -a' with no argument
739 // 'aa stop-service -a' with no argument
740 HILOG_INFO("'aa %{public}s -a' with no argument.", cmd_.c_str());
741
742 resultReceiver_.append("error: option ");
743 resultReceiver_.append("requires a value.\n");
744
745 result = OHOS::ERR_INVALID_VALUE;
746 break;
747 }
748 case 'b': {
749 // 'aa start -b' with no argument
750 // 'aa stop-service -b' with no argument
751 HILOG_INFO("'aa %{public}s -b' with no argument.", cmd_.c_str());
752
753 resultReceiver_.append("error: option ");
754 resultReceiver_.append("requires a value.\n");
755
756 result = OHOS::ERR_INVALID_VALUE;
757 break;
758 }
759 case 's': {
760 // 'aa start -s' with no argument
761 // 'aa stop-service -s' with no argument
762 HILOG_INFO("'aa %{public}s -s' with no argument.", cmd_.c_str());
763
764 resultReceiver_.append("error: option ");
765 resultReceiver_.append(argv_[optind - 1]);
766 resultReceiver_.append("' requires a value.\n");
767
768 result = OHOS::ERR_INVALID_VALUE;
769 break;
770 }
771 case 'm': {
772 // 'aa start -m' with no argument
773 // 'aa stop-service -m' with no argument
774 HILOG_INFO("'aa %{public}s -m' with no argument.", cmd_.c_str());
775
776 resultReceiver_.append("error: option ");
777 resultReceiver_.append("requires a value.\n");
778
779 result = OHOS::ERR_INVALID_VALUE;
780 break;
781 }
782 case 0: {
783 // 'aa start' with an unknown option: aa start --x
784 // 'aa start' with an unknown option: aa start --xxx
785 // 'aa stop-service' with an unknown option: aa stop-service --x
786 // 'aa stop-service' with an unknown option: aa stop-service --xxx
787 std::string unknownOption = "";
788 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
789
790 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
791
792 resultReceiver_.append(unknownOptionMsg);
793 result = OHOS::ERR_INVALID_VALUE;
794 break;
795 }
796 default: {
797 // 'aa start' with an unknown option: aa start -x
798 // 'aa start' with an unknown option: aa start -xxx
799 // 'aa stop-service' with an unknown option: aa stop-service -x
800 // 'aa stop-service' with an unknown option: aa stop-service -xxx
801 std::string unknownOption = "";
802 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
803
804 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
805
806 resultReceiver_.append(unknownOptionMsg);
807 result = OHOS::ERR_INVALID_VALUE;
808 break;
809 }
810 }
811 break;
812 }
813
814 switch (option) {
815 case 'h': {
816 // 'aa start -h'
817 // 'aa start --help'
818 // 'aa stop-service -h'
819 // 'aa stop-service --help'
820 result = OHOS::ERR_INVALID_VALUE;
821 break;
822 }
823 case 'd': {
824 // 'aa start -d xxx'
825 // 'aa stop-service -d xxx'
826
827 // save device ID
828 if (optarg != nullptr) {
829 deviceId = optarg;
830 }
831 break;
832 }
833 case 'a': {
834 // 'aa start -a xxx'
835 // 'aa stop-service -a xxx'
836
837 // save ability name
838 abilityName = optarg;
839 break;
840 }
841 case 'b': {
842 // 'aa start -b xxx'
843 // 'aa stop-service -b xxx'
844
845 // save bundle name
846 bundleName = optarg;
847 break;
848 }
849 case 's': {
850 // 'aa start -s xxx'
851 // save windowMode
852 windowMode = optarg;
853 break;
854 }
855 case 'm': {
856 // 'aa start -m xxx'
857 // 'aa stop-service -m xxx'
858
859 // save module name
860 moduleName = optarg;
861 break;
862 }
863 case 'C': {
864 // 'aa start -C'
865 // cold start app
866 isColdStart = true;
867 break;
868 }
869 case 'D': {
870 // 'aa start -D'
871 // debug app
872 isDebugApp = true;
873 break;
874 }
875 case 'c': {
876 // 'aa start -c'
877 // set ability launch reason = continuation
878 isContinuation = true;
879 break;
880 }
881 case 0: {
882 break;
883 }
884 default: {
885 break;
886 }
887 }
888 }
889
890 if (result == OHOS::ERR_OK) {
891 if (abilityName.size() == 0 || bundleName.size() == 0) {
892 // 'aa start [-d <device-id>] -a <ability-name> -b <bundle-name> [-D]'
893 // 'aa stop-service [-d <device-id>] -a <ability-name> -b <bundle-name>'
894 HILOG_INFO("'aa %{public}s' without enough options.", cmd_.c_str());
895
896 if (abilityName.size() == 0) {
897 resultReceiver_.append(HELP_MSG_NO_ABILITY_NAME_OPTION + "\n");
898 }
899
900 if (bundleName.size() == 0) {
901 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n");
902 }
903
904 result = OHOS::ERR_INVALID_VALUE;
905 } else {
906 ElementName element(deviceId, bundleName, abilityName, moduleName);
907 want.SetElement(element);
908
909 if (isColdStart) {
910 want.SetParam("coldStart", isColdStart);
911 }
912 if (isDebugApp) {
913 want.SetParam("debugApp", isDebugApp);
914 }
915 if (isContinuation) {
916 want.AddFlags(Want::FLAG_ABILITY_CONTINUATION);
917 }
918 }
919 }
920
921 return result;
922 }
923
RunAsTestCommand()924 ErrCode AbilityManagerShellCommand::RunAsTestCommand()
925 {
926 HILOG_INFO("enter");
927 std::map<std::string, std::string> params;
928
929 for (int i = USER_TEST_COMMAND_START_INDEX; i < argc_; i++) {
930 HILOG_INFO("argv_[%{public}d]: %{public}s", i, argv_[i]);
931 std::string opt = argv_[i];
932 if ((opt == "-h") || (opt == "--help")) {
933 resultReceiver_.append(HELP_MSG_TEST);
934 return OHOS::ERR_OK;
935 } else if ((opt == "-b") || (opt == "-p") || (opt == "-m")) {
936 if (i >= argc_ - 1) {
937 return TestCommandError("error: option [" + opt + "] requires a value.\n");
938 }
939 std::string argv = argv_[++i];
940 params[opt] = argv;
941 } else if (opt == "-w") {
942 if (i >= argc_ - 1) {
943 return TestCommandError("error: option [" + opt + "] requires a value.\n");
944 }
945
946 std::string argv = argv_[++i];
947 std::smatch sm;
948 auto isNumber = std::regex_match(argv, sm, std::regex(STRING_TEST_REGEX_INTEGER_NUMBERS));
949 if (!isNumber) {
950 return TestCommandError("error: option [" + opt + "] only supports integer numbers.\n");
951 }
952
953 params[opt] = argv;
954 } else if (opt == "-s") {
955 if (i >= argc_ - USER_TEST_COMMAND_PARAMS_NUM) {
956 return TestCommandError("error: option [-s] is incorrect.\n");
957 }
958 std::string argKey = argv_[++i];
959 std::string argValue = argv_[++i];
960 params[opt + " " + argKey] = argValue;
961 } else if (opt == "-D") {
962 params[opt] = DEBUG_VALUE;
963 } else if (opt.at(0) == '-') {
964 return TestCommandError("error: unknown option: " + opt + "\n");
965 }
966 }
967
968 if (!IsTestCommandIntegrity(params)) {
969 return OHOS::ERR_INVALID_VALUE;
970 }
971
972 return StartUserTest(params);
973 }
974
IsTestCommandIntegrity(const std::map<std::string,std::string> & params)975 bool AbilityManagerShellCommand::IsTestCommandIntegrity(const std::map<std::string, std::string> ¶ms)
976 {
977 HILOG_INFO("enter");
978
979 std::vector<std::string> opts = {"-b", "-s unittest"};
980 for (auto opt : opts) {
981 auto it = params.find(opt);
982 if (it == params.end()) {
983 TestCommandError("error: the option [" + opt + "] is expected.\n");
984 return false;
985 }
986 }
987 return true;
988 }
989
TestCommandError(const std::string & info)990 ErrCode AbilityManagerShellCommand::TestCommandError(const std::string &info)
991 {
992 resultReceiver_.append(info);
993 resultReceiver_.append(HELP_MSG_TEST);
994 return OHOS::ERR_INVALID_VALUE;
995 }
996
StartUserTest(const std::map<std::string,std::string> & params)997 ErrCode AbilityManagerShellCommand::StartUserTest(const std::map<std::string, std::string> ¶ms)
998 {
999 HILOG_INFO("enter");
1000
1001 Want want;
1002 for (auto param : params) {
1003 want.SetParam(param.first, param.second);
1004 }
1005
1006 auto dPos = params.find("-D");
1007 if (dPos != params.end() && dPos->second.compare(DEBUG_VALUE) == 0) {
1008 HILOG_INFO("Set Debug to want");
1009 want.SetParam("debugApp", true);
1010 }
1011
1012 sptr<TestObserver> observer = new (std::nothrow) TestObserver();
1013 if (!observer) {
1014 HILOG_ERROR("Failed: the TestObserver is null");
1015 return OHOS::ERR_INVALID_VALUE;
1016 }
1017
1018 int result = AbilityManagerClient::GetInstance()->StartUserTest(want, observer->AsObject());
1019 if (result != OHOS::ERR_OK) {
1020 HILOG_INFO("%{public}s result = %{public}d", STRING_START_USER_TEST_NG.c_str(), result);
1021 resultReceiver_ = STRING_START_USER_TEST_NG + "\n";
1022 resultReceiver_.append(GetMessageFromCode(result));
1023 return result;
1024 }
1025 HILOG_INFO("%{public}s", STRING_USER_TEST_STARTED.c_str());
1026
1027 std::signal(SIGCHLD, SIG_DFL);
1028
1029 int64_t timeMs = 0;
1030 if (!want.GetStringParam("-w").empty()) {
1031 auto time = std::stoi(want.GetStringParam("-w"));
1032 timeMs = time > 0 ? time * TIME_RATE_MS : 0;
1033 }
1034 if (!observer->WaitForFinish(timeMs)) {
1035 resultReceiver_ = "Timeout: user test is not completed within the specified time.\n";
1036 return OHOS::ERR_INVALID_VALUE;
1037 }
1038
1039 HILOG_INFO("%{public}s", STRING_USER_TEST_FINISHED.c_str());
1040 resultReceiver_ = STRING_USER_TEST_FINISHED + "\n";
1041
1042 return result;
1043 }
1044
GetAbilityManagerService()1045 sptr<IAbilityManager> AbilityManagerShellCommand::GetAbilityManagerService()
1046 {
1047 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1048 if (systemManager == nullptr) {
1049 HILOG_ERROR("Fail to get registry.");
1050 return nullptr;
1051 }
1052 sptr<IRemoteObject> remoteObject = systemManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
1053 return iface_cast<IAbilityManager>(remoteObject);
1054 }
1055
1056 #ifdef ABILITY_COMMAND_FOR_TEST
RunAsSendAppNotRespondingWithUnknownOption()1057 ErrCode AbilityManagerShellCommand::RunAsSendAppNotRespondingWithUnknownOption()
1058 {
1059 switch (optopt) {
1060 case 'h': {
1061 break;
1062 }
1063 case 'p': {
1064 HILOG_INFO("'aa ApplicationNotResponding -p' with no argument.");
1065 resultReceiver_.append("error: option -p ");
1066 resultReceiver_.append("' requires a value.\n");
1067 break;
1068 }
1069 default: {
1070 std::string unknownOption;
1071 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1072 HILOG_INFO("'aa ApplicationNotResponding' with an unknown option.");
1073 resultReceiver_.append(unknownOptionMsg);
1074 break;
1075 }
1076 }
1077 return OHOS::ERR_INVALID_VALUE;
1078 }
1079
RunAsSendAppNotRespondingWithOption(int32_t option,std::string & pid)1080 ErrCode AbilityManagerShellCommand::RunAsSendAppNotRespondingWithOption(int32_t option, std::string &pid)
1081 {
1082 ErrCode result = ERR_OK;
1083 switch (option) {
1084 case 'h': {
1085 result = OHOS::ERR_INVALID_VALUE;
1086 break;
1087 }
1088 case 'p': {
1089 HILOG_INFO("aa ApplicationNotResponding 'aa %{public}s' -p process.", cmd_.c_str());
1090 HILOG_INFO("aa ApplicationNotResponding 'aa optarg = %{public}s'.", optarg);
1091 pid = optarg;
1092 HILOG_INFO("aa ApplicationNotResponding 'aa pid = %{public}s'.", pid.c_str());
1093 break;
1094 }
1095 default: {
1096 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
1097 result = OHOS::ERR_INVALID_VALUE;
1098 break;
1099 }
1100 }
1101 return result;
1102 }
1103
RunAsSendAppNotRespondingProcessID()1104 ErrCode AbilityManagerShellCommand::RunAsSendAppNotRespondingProcessID()
1105 {
1106 static sptr<IAbilityManager> abilityMs_;
1107 std::string pid = "";
1108 int option = -1;
1109 ErrCode result = OHOS::ERR_OK;
1110 option = getopt_long(argc_, argv_, SHORT_OPTIONS_APPLICATION_NOT_RESPONDING.c_str(),
1111 LONG_OPTIONS_ApplicationNotResponding, nullptr);
1112 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
1113 if (optind < 0 || optind > argc_) {
1114 return OHOS::ERR_INVALID_VALUE;
1115 }
1116 if (option == -1) {
1117 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
1118 HILOG_INFO("'aa %{public}s' %{public}s", HELP_ApplicationNotResponding.c_str(), cmd_.c_str());
1119 result = OHOS::ERR_INVALID_VALUE;
1120 }
1121 } else if (option == '?') {
1122 result = RunAsSendAppNotRespondingWithUnknownOption();
1123 } else {
1124 result = RunAsSendAppNotRespondingWithOption(option, pid);
1125 }
1126
1127 if (result == OHOS::ERR_OK) {
1128 HILOG_INFO("'aa pid = %{public}d'.", atoi(pid.c_str()));
1129 abilityMs_ = GetAbilityManagerService();
1130 if (abilityMs_ == nullptr) {
1131 std::cout << "abilityMsObj is nullptr";
1132 } else {
1133 abilityMs_->SendANRProcessID(atoi(pid.c_str()));
1134 }
1135 } else {
1136 resultReceiver_.append(HELP_ApplicationNotResponding+ "\n");
1137 result = OHOS::ERR_INVALID_VALUE;
1138 }
1139 return result;
1140 }
1141
RunAsBlockAbilityCommand()1142 ErrCode AbilityManagerShellCommand::RunAsBlockAbilityCommand()
1143 {
1144 HILOG_INFO("[%{public}s(%{public}s)] enter", __FILE__, __FUNCTION__);
1145 ErrCode result = OHOS::ERR_OK;
1146 if (argList_.size() > 0) {
1147 result = AbilityManagerClient::GetInstance()->BlockAbility(atoi(argList_[0].c_str()));
1148 } else {
1149 result = OHOS::ERR_INVALID_VALUE;
1150 }
1151
1152 if (result == OHOS::ERR_OK) {
1153 HILOG_INFO("%{public}s", STRING_BLOCK_ABILITY_OK.c_str());
1154 resultReceiver_ = STRING_BLOCK_ABILITY_OK + "\n";
1155 } else {
1156 HILOG_INFO("%{public}s result = %{public}d", STRING_BLOCK_ABILITY_NG.c_str(), result);
1157 resultReceiver_ = STRING_BLOCK_ABILITY_NG + "\n";
1158 resultReceiver_.append(GetMessageFromCode(result));
1159 }
1160 return result;
1161 }
1162
RunAsBlockAmsServiceCommand()1163 ErrCode AbilityManagerShellCommand::RunAsBlockAmsServiceCommand()
1164 {
1165 HILOG_INFO("[%{public}s(%{public}s)] enter", __FILE__, __FUNCTION__);
1166 ErrCode result = OHOS::ERR_OK;
1167 result = AbilityManagerClient::GetInstance()->BlockAmsService();
1168 if (result == OHOS::ERR_OK) {
1169 HILOG_INFO("%{public}s", STRING_BLOCK_AMS_SERVICE_OK.c_str());
1170 resultReceiver_ = STRING_BLOCK_AMS_SERVICE_OK + "\n";
1171 } else {
1172 HILOG_INFO("%{public}s result = %{public}d", STRING_BLOCK_AMS_SERVICE_NG.c_str(), result);
1173 resultReceiver_ = STRING_BLOCK_AMS_SERVICE_NG + "\n";
1174 resultReceiver_.append(GetMessageFromCode(result));
1175 }
1176 return result;
1177 }
1178
RunAsBlockAppServiceCommand()1179 ErrCode AbilityManagerShellCommand::RunAsBlockAppServiceCommand()
1180 {
1181 HILOG_INFO("[%{public}s(%{public}s)] enter", __FILE__, __FUNCTION__);
1182 ErrCode result = OHOS::ERR_OK;
1183 result = AbilityManagerClient::GetInstance()->BlockAppService();
1184 if (result == OHOS::ERR_OK) {
1185 HILOG_INFO("%{public}s", STRING_BLOCK_APP_SERVICE_OK.c_str());
1186 resultReceiver_ = STRING_BLOCK_APP_SERVICE_OK + "\n";
1187 } else {
1188 HILOG_INFO("%{public}s result = %{public}d", STRING_BLOCK_APP_SERVICE_NG.c_str(), result);
1189 resultReceiver_ = STRING_BLOCK_APP_SERVICE_NG + "\n";
1190 resultReceiver_.append(GetMessageFromCode(result));
1191 }
1192 return result;
1193 }
1194 #endif
1195 } // namespace AAFwk
1196 } // namespace OHOS
1197