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