• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &params)
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> &params)
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