1 /*
2  * Copyright (c) 2021-2024 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_tag_wrapper.h"
24 #include "iservice_registry.h"
25 #include "mission_snapshot.h"
26 #include "bool_wrapper.h"
27 #include "parameters.h"
28 #include "sa_mgr_client.h"
29 #include "system_ability_definition.h"
30 #include "test_observer.h"
31 
32 using namespace OHOS::AppExecFwk;
33 
34 namespace OHOS {
35 namespace AAFwk {
36 namespace {
37 constexpr size_t PARAM_LENGTH = 1024;
38 constexpr int INDEX_OFFSET = 3;
39 constexpr int EXTRA_ARGUMENTS_FOR_KEY_VALUE_PAIR = 1;
40 constexpr int EXTRA_ARGUMENTS_FOR_NULL_STRING = 0;
41 constexpr int OPTION_PARAMETER_VALUE_OFFSET = 1;
42 
43 constexpr int OPTION_PARAMETER_INTEGER = 257;
44 constexpr int OPTION_PARAMETER_STRING = 258;
45 constexpr int OPTION_PARAMETER_BOOL = 259;
46 constexpr int OPTION_PARAMETER_NULL_STRING = 260;
47 constexpr int OPTION_WINDOW_LEFT = 261;
48 constexpr int OPTION_WINDOW_TOP = 262;
49 constexpr int OPTION_WINDOW_HEIGHT = 263;
50 constexpr int OPTION_WINDOW_WIDTH = 264;
51 
52 const std::string DEVELOPERMODE_STATE = "const.security.developermode.state";
53 
54 const std::string SHORT_OPTIONS = "ch:d:a:b:e:t:p:s:m:A:U:CDESNR";
55 constexpr struct option LONG_OPTIONS[] = {
56     {"help", no_argument, nullptr, 'h'},
57     {"device", required_argument, nullptr, 'd'},
58     {"ability", required_argument, nullptr, 'a'},
59     {"bundle", required_argument, nullptr, 'b'},
60     {"perf", required_argument, nullptr, 'p'},
61     {"setting", required_argument, nullptr, 's'},
62     {"module", required_argument, nullptr, 'm'},
63     {"cold-start", no_argument, nullptr, 'C'},
64     {"debug", no_argument, nullptr, 'D'},
65     {"error-info-enhance", no_argument, nullptr, 'E'},
66     {"native-debug", no_argument, nullptr, 'N'},
67     {"mutil-thread", no_argument, nullptr, 'R'},
68     {"action", required_argument, nullptr, 'A'},
69     {"URI", required_argument, nullptr, 'U'},
70     {"entity", required_argument, nullptr, 'e'},
71     {"type", required_argument, nullptr, 't'},
72     {"pi", required_argument, nullptr, OPTION_PARAMETER_INTEGER},
73     {"ps", required_argument, nullptr, OPTION_PARAMETER_STRING},
74     {"pb", required_argument, nullptr, OPTION_PARAMETER_BOOL},
75     {"psn", required_argument, nullptr, OPTION_PARAMETER_NULL_STRING},
76     {"wl", required_argument, nullptr, OPTION_WINDOW_LEFT},
77     {"wt", required_argument, nullptr, OPTION_WINDOW_TOP},
78     {"wh", required_argument, nullptr, OPTION_WINDOW_HEIGHT},
79     {"ww", required_argument, nullptr, OPTION_WINDOW_WIDTH},
80     {nullptr, 0, nullptr, 0},
81 };
82 const std::string SHORT_OPTIONS_APPLICATION_NOT_RESPONDING = "hp:";
83 #ifdef ABILITY_COMMAND_FOR_TEST
84 constexpr struct option LONG_OPTIONS_ApplicationNotResponding[] = {
85     {"help", no_argument, nullptr, 'h'},
86     {"pid", required_argument, nullptr, 'p'},
87     {nullptr, 0, nullptr, 0},
88 };
89 #endif
90 #ifdef ABILITY_FAULT_AND_EXIT_TEST
91 const std::string SHORT_OPTIONS_FORCE_EXIT_APP = "hp:r:";
92 constexpr struct option LONG_OPTIONS_FORCE_EXIT_APP[] = {
93     { "help", no_argument, nullptr, 'h' },
94     { "pid", required_argument, nullptr, 'p' },
95     { "reason", required_argument, nullptr, 'r' },
96     { nullptr, 0, nullptr, 0 },
97 };
98 const std::string SHORT_OPTIONS_NOTIFY_APP_FAULT = "hn:m:s:t:p:";
99 constexpr struct option LONG_OPTIONS_NOTIFY_APP_FAULT[] = {
100     {"help", no_argument, nullptr, 'h'},
101     {"errorName", required_argument, nullptr, 'n'},
102     {"errorMessage", required_argument, nullptr, 'm'},
103     {"errorStack", required_argument, nullptr, 's'},
104     {"faultType", required_argument, nullptr, 't'},
105     {"pid", required_argument, nullptr, 'p'},
106     {nullptr, 0, nullptr, 0},
107 };
108 #endif
109 const std::string SHORT_OPTIONS_DUMPSYS = "hal::i:e::p::r::d::u:c";
110 constexpr struct option LONG_OPTIONS_DUMPSYS[] = {
111     {"help", no_argument, nullptr, 'h'},
112     {"all", no_argument, nullptr, 'a'},
113     {"mission-list", no_argument, nullptr, 'l'},
114     {"ability", required_argument, nullptr, 'i'},
115     {"extension", no_argument, nullptr, 'e'},
116     {"pending", no_argument, nullptr, 'p'},
117     {"process", no_argument, nullptr, 'r'},
118     {"data", no_argument, nullptr, 'd'},
119     {"userId", required_argument, nullptr, 'u'},
120     {"client", no_argument, nullptr, 'c'},
121     {nullptr, 0, nullptr, 0},
122 };
123 const std::string SHORT_OPTIONS_PROCESS = "ha:b:p:m:D:S";
124 constexpr struct option LONG_OPTIONS_PROCESS[] = {
125     {"help", no_argument, nullptr, 'h'},
126     {"ability", required_argument, nullptr, 'a'},
127     {"bundle", required_argument, nullptr, 'b'},
128     {"perf", required_argument, nullptr, 'p'},
129     {"module", required_argument, nullptr, 'm'},
130     {"debug", required_argument, nullptr, 'D'},
131     {nullptr, 0, nullptr, 0},
132 };
133 const std::string SHORT_OPTIONS_APPDEBUG = "hb:p::c::g";
134 constexpr struct option LONG_OPTIONS_APPDEBUG[] = {
135     { "help", no_argument, nullptr, 'h' },
136     { "bundlename", required_argument, nullptr, 'b' },
137     { "persist", no_argument, nullptr, 'p' },
138     { "cancel", no_argument, nullptr, 'c' },
139     { "get", no_argument, nullptr, 'g' },
140     { nullptr, 0, nullptr, 0 },
141 };
142 const std::string SHORT_OPTIONS_ATTACH = "hb:";
143 constexpr struct option LONG_OPTIONS_ATTACH[] = {
144     {"help", no_argument, nullptr, 'h'},
145     {"bundle", required_argument, nullptr, 'b'},
146     {nullptr, 0, nullptr, 0},
147 };
148 }  // namespace
149 
AbilityManagerShellCommand(int argc,char * argv[])150 AbilityManagerShellCommand::AbilityManagerShellCommand(int argc, char* argv[]) : ShellCommand(argc, argv, TOOL_NAME)
151 {
152     for (int i = 0; i < argc_; i++) {
153         TAG_LOGI(AAFwkTag::AA_TOOL, "argv_[%{public}d]: %{public}s", i, argv_[i]);
154     }
155 }
156 
CreateCommandMap()157 ErrCode AbilityManagerShellCommand::CreateCommandMap()
158 {
159     commandMap_ = {
160         {"help", [this]() { return this->RunAsHelpCommand(); }},
161         {"start", [this]() { return this->RunAsStartAbility(); }},
162         {"stop-service", [this]() { return this->RunAsStopService(); }},
163         {"dump", [this]() { return this->RunAsDumpsysCommand(); }},
164         {"force-stop", [this]() { return this->RunAsForceStop(); }},
165         {"test", [this]() { return this->RunAsTestCommand(); }},
166         {"process", [this]() { return this->RunAsProcessCommand(); }},
167         {"attach", [this]() { return this->RunAsAttachDebugCommand(); }},
168         {"detach", [this]() { return this->RunAsDetachDebugCommand(); }},
169         {"appdebug", [this]() { return this->RunAsAppDebugDebugCommand(); }},
170 #ifdef ABILITY_COMMAND_FOR_TEST
171         {"force-timeout", [this]() { return this->RunForceTimeoutForTest(); }},
172 #endif
173 #ifdef ABILITY_FAULT_AND_EXIT_TEST
174         {"forceexitapp", [this]() { return this->RunAsForceExitAppCommand(); }},
175         {"notifyappfault", [this]() { return this->RunAsNotifyAppFaultCommand(); }},
176 #endif
177     };
178 
179     return OHOS::ERR_OK;
180 }
181 
CreateMessageMap()182 ErrCode AbilityManagerShellCommand::CreateMessageMap()
183 {
184     messageMap_[RESOLVE_ABILITY_ERR] = "error: resolve ability err.";
185     messageMap_[GET_ABILITY_SERVICE_FAILED] = "error: get ability service failed.";
186     messageMap_[ABILITY_SERVICE_NOT_CONNECTED] = "error: ability service not connected.";
187     messageMap_[RESOLVE_APP_ERR] = "error: resolve app err.";
188     messageMap_[ABILITY_EXISTED] = "error: ability existed.";
189     messageMap_[CREATE_MISSION_STACK_FAILED] = "error: create mission stack failed.";
190     messageMap_[CREATE_ABILITY_RECORD_FAILED] = "error: create ability record failed.";
191     messageMap_[START_ABILITY_WAITING] = "start ability successfully. waiting...";
192     messageMap_[TERMINATE_LAUNCHER_DENIED] = "error: terminate launcher denied.";
193     messageMap_[CONNECTION_NOT_EXIST] = "error: connection not exist.";
194     messageMap_[INVALID_CONNECTION_STATE] = "error: invalid connection state.";
195     messageMap_[LOAD_ABILITY_TIMEOUT] = "error: load ability timeout.";
196     messageMap_[CONNECTION_TIMEOUT] = "error: connection timeout.";
197     messageMap_[GET_BUNDLE_MANAGER_SERVICE_FAILED] = "error: get bundle manager service failed.";
198     messageMap_[REMOVE_MISSION_FAILED] = "error: remove mission failed.";
199     messageMap_[INNER_ERR] = "error: inner err.";
200     messageMap_[GET_RECENT_MISSIONS_FAILED] = "error: get recent missions failed.";
201     messageMap_[REMOVE_STACK_LAUNCHER_DENIED] = "error: remove stack launcher denied.";
202     messageMap_[TARGET_ABILITY_NOT_SERVICE] = "error: target ability not service.";
203     messageMap_[TERMINATE_SERVICE_IS_CONNECTED] = "error: terminate service is connected.";
204     messageMap_[START_SERVICE_ABILITY_ACTIVATING] = "error: start service ability activating.";
205     messageMap_[KILL_PROCESS_FAILED] = "error: kill process failed.";
206     messageMap_[UNINSTALL_APP_FAILED] = "error: uninstall app failed.";
207     messageMap_[TERMINATE_ABILITY_RESULT_FAILED] = "error: terminate ability result failed.";
208     messageMap_[CHECK_PERMISSION_FAILED] = "error: check permission failed.";
209     messageMap_[NO_FOUND_ABILITY_BY_CALLER] = "error: no found ability by caller.";
210     messageMap_[ABILITY_VISIBLE_FALSE_DENY_REQUEST] = "error: ability visible false deny request.";
211     messageMap_[GET_BUNDLE_INFO_FAILED] = "error: get bundle info failed.";
212     messageMap_[ERR_NOT_DEVELOPER_MODE] = "error: not developer mode.";
213     messageMap_[KILL_PROCESS_KEEP_ALIVE] = "error: keep alive process can not be killed.";
214     messageMap_[ERR_UNLOCK_SCREEN_FAILED_IN_DEVELOPER_MODE] = "error: unlock screen failed in developer mode.";
215     messageMap_[ERR_NOT_SUPPORTED_PRODUCT_TYPE] = "error: not supported in the current product type.";
216     messageMap_[ERR_NOT_IN_APP_PROVISION_MODE] = "error: not supported in non-app-provision mode.";
217     return OHOS::ERR_OK;
218 }
219 
init()220 ErrCode AbilityManagerShellCommand::init()
221 {
222     return AbilityManagerClient::GetInstance()->Connect();
223 }
224 
RunAsHelpCommand()225 ErrCode AbilityManagerShellCommand::RunAsHelpCommand()
226 {
227     resultReceiver_.append(HELP_MSG);
228 
229     return OHOS::ERR_OK;
230 }
231 
RunAsStartAbility()232 ErrCode AbilityManagerShellCommand::RunAsStartAbility()
233 {
234     Want want;
235     std::string windowMode;
236     ErrCode result = MakeWantFromCmd(want, windowMode);
237     if (result == OHOS::ERR_OK) {
238         int windowModeKey = std::atoi(windowMode.c_str());
239         if (windowModeKey > 0) {
240             auto setting = AbilityStartSetting::GetEmptySetting();
241             if (setting != nullptr) {
242                 setting->AddProperty(AbilityStartSetting::WINDOW_MODE_KEY, windowMode);
243                 result = AbilityManagerClient::GetInstance()->StartAbility(want, *(setting.get()), nullptr, -1);
244             }
245         } else {
246             result = AbilityManagerClient::GetInstance()->StartAbility(want);
247         }
248         if (result == OHOS::ERR_OK) {
249             TAG_LOGI(AAFwkTag::AA_TOOL, "%{public}s", STRING_START_ABILITY_OK.c_str());
250             resultReceiver_ = STRING_START_ABILITY_OK + "\n";
251         } else {
252             TAG_LOGI(AAFwkTag::AA_TOOL, "%{public}s result: %{public}d", STRING_START_ABILITY_NG.c_str(), result);
253             if (result != START_ABILITY_WAITING) {
254                 resultReceiver_ = STRING_START_ABILITY_NG + "\n";
255             }
256             resultReceiver_.append(GetMessageFromCode(result));
257         }
258     } else {
259         resultReceiver_.append(HELP_MSG_START);
260         result = OHOS::ERR_INVALID_VALUE;
261     }
262 
263     return result;
264 }
265 
RunAsStopService()266 ErrCode AbilityManagerShellCommand::RunAsStopService()
267 {
268     ErrCode result = OHOS::ERR_OK;
269 
270     Want want;
271     std::string windowMode;
272     result = MakeWantFromCmd(want, windowMode);
273     if (result == OHOS::ERR_OK) {
274         result = AbilityManagerClient::GetInstance()->StopServiceAbility(want);
275         if (result == OHOS::ERR_OK) {
276             TAG_LOGI(AAFwkTag::AA_TOOL, "%{public}s", STRING_STOP_SERVICE_ABILITY_OK.c_str());
277             resultReceiver_ = STRING_STOP_SERVICE_ABILITY_OK + "\n";
278         } else {
279             TAG_LOGI(
280                 AAFwkTag::AA_TOOL, "%{public}s result: %{public}d", STRING_STOP_SERVICE_ABILITY_NG.c_str(), result);
281             resultReceiver_ = STRING_STOP_SERVICE_ABILITY_NG + "\n";
282 
283             resultReceiver_.append(GetMessageFromCode(result));
284         }
285     } else {
286         resultReceiver_.append(HELP_MSG_STOP_SERVICE);
287         result = OHOS::ERR_INVALID_VALUE;
288     }
289 
290     return result;
291 }
292 
RunAsDumpsysCommand()293 ErrCode AbilityManagerShellCommand::RunAsDumpsysCommand()
294 {
295     ErrCode result = OHOS::ERR_OK;
296     bool isUserID = false;
297     bool isClient = false;
298     int userID = DEFAULT_INVAL_VALUE;
299     bool isfirstCommand = false;
300     std::string args;
301     for (auto it = argList_.begin(); it != argList_.end(); it++) {
302         if (*it == "-c" || *it == "--client") {
303             if (isClient == false) {
304                 isClient = true;
305             } else {
306                 result = OHOS::ERR_INVALID_VALUE;
307                 resultReceiver_.append(HELP_MSG_DUMPSYS);
308                 return result;
309             }
310         } else if (*it == "-u" || *it == "--userId") {
311             if (it + 1 == argList_.end()) {
312                 result = OHOS::ERR_INVALID_VALUE;
313                 resultReceiver_.append(HELP_MSG_DUMPSYS);
314                 return result;
315             }
316             (void)StrToInt(*(it + 1), userID);
317             if (userID == DEFAULT_INVAL_VALUE) {
318                 result = OHOS::ERR_INVALID_VALUE;
319                 resultReceiver_.append(HELP_MSG_DUMPSYS);
320                 return result;
321             }
322             if (isUserID == false) {
323                 isUserID = true;
324             } else {
325                 result = OHOS::ERR_INVALID_VALUE;
326                 resultReceiver_.append(HELP_MSG_DUMPSYS);
327                 return result;
328             }
329         } else if (*it == std::to_string(userID)) {
330             continue;
331         } else {
332             args += *it;
333             args += " ";
334         }
335     }
336 
337     while (true) {
338         int option = getopt_long(argc_, argv_, SHORT_OPTIONS_DUMPSYS.c_str(), LONG_OPTIONS_DUMPSYS, nullptr);
339 
340         TAG_LOGI(
341             AAFwkTag::AA_TOOL, "option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
342 
343         if (optind < 0 || optind > argc_) {
344             resultReceiver_.append(HELP_MSG_DUMPSYS);
345             return OHOS::ERR_INVALID_VALUE;
346         }
347 
348         if (option == -1) {
349             break;
350         }
351 
352         switch (option) {
353             case 'h': {
354                 // 'aa dumpsys -h'
355                 // 'aa dumpsys --help'
356                 resultReceiver_.append(HELP_MSG_DUMPSYS);
357                 result = OHOS::ERR_INVALID_VALUE;
358                 return result;
359             }
360             case 'a': {
361                 if (isfirstCommand == false) {
362                     isfirstCommand = true;
363                 } else {
364                     result = OHOS::ERR_INVALID_VALUE;
365                     resultReceiver_.append(HELP_MSG_DUMPSYS);
366                     return result;
367                 }
368                 // 'aa dumpsys -a'
369                 // 'aa dumpsys --all'
370                 break;
371             }
372             case 'l': {
373                 if (isfirstCommand == false) {
374                     isfirstCommand = true;
375                 } else {
376                     // 'aa dump -i 10 -element -lastpage'
377                     // 'aa dump -i 10 -render -lastpage'
378                     // 'aa dump -i 10 -layer'
379                     if ((optarg != nullptr) && strcmp(optarg, "astpage") && strcmp(optarg, "ayer")) {
380                         result = OHOS::ERR_INVALID_VALUE;
381                         resultReceiver_.append(HELP_MSG_DUMPSYS);
382                         return result;
383                     }
384                 }
385                 // 'aa dumpsys -l'
386                 // 'aa dumpsys --mission-list'
387                 break;
388             }
389             case 'i': {
390                 if (isfirstCommand == false) {
391                     isfirstCommand = true;
392                     int abilityRecordId = DEFAULT_INVAL_VALUE;
393                     (void)StrToInt(optarg, abilityRecordId);
394                     if (abilityRecordId == DEFAULT_INVAL_VALUE) {
395                         result = OHOS::ERR_INVALID_VALUE;
396                         resultReceiver_.append(HELP_MSG_DUMPSYS);
397                         return result;
398                     }
399                 } else {
400                     // 'aa dumpsys -i 10 -inspector'
401                     if ((optarg != nullptr) && strcmp(optarg, "nspector")) {
402                         result = OHOS::ERR_INVALID_VALUE;
403                         resultReceiver_.append(HELP_MSG_DUMPSYS);
404                         return result;
405                     }
406                 }
407                 // 'aa dumpsys -i'
408                 // 'aa dumpsys --ability'
409                 break;
410             }
411             case 'e': {
412                 if (isfirstCommand == false && optarg == nullptr) {
413                     isfirstCommand = true;
414                 } else {
415                     // 'aa dumpsys -i 10 -element'
416                     if ((optarg != nullptr) && strcmp(optarg, "lement")) {
417                         result = OHOS::ERR_INVALID_VALUE;
418                         resultReceiver_.append(HELP_MSG_DUMPSYS);
419                         return result;
420                     }
421                 }
422                 // 'aa dumpsys -e'
423                 // 'aa dumpsys --extension'
424                 break;
425             }
426             case 'p': {
427                 if (isfirstCommand == false && optarg == nullptr) {
428                     isfirstCommand = true;
429                 } else {
430                     result = OHOS::ERR_INVALID_VALUE;
431                     resultReceiver_.append(HELP_MSG_DUMPSYS);
432                     return result;
433                 }
434                 // 'aa dumpsys -p'
435                 // 'aa dumpsys --pending'
436                 break;
437             }
438             case 'r': {
439                 if (isfirstCommand == false && optarg == nullptr) {
440                     isfirstCommand = true;
441                 } else {
442                     // 'aa dump -i 10 -render'
443                     // 'aa dump -i 10 -rotation'
444                     // 'aa dump -i 10 -frontend'
445                     if ((optarg != nullptr) && strcmp(optarg, "ender") && strcmp(optarg, "otation") &&
446                         strcmp(optarg, "ontend")) {
447                         result = OHOS::ERR_INVALID_VALUE;
448                         resultReceiver_.append(HELP_MSG_DUMPSYS);
449                         return result;
450                     }
451                 }
452                 // 'aa dumpsys -r'
453                 // 'aa dumpsys --process'
454                 break;
455             }
456             case 'd': {
457                 if (isfirstCommand == false && optarg == nullptr) {
458                     isfirstCommand = true;
459                 } else {
460                     result = OHOS::ERR_INVALID_VALUE;
461                     resultReceiver_.append(HELP_MSG_DUMPSYS);
462                     return result;
463                 }
464                 // 'aa dumpsys -d'
465                 // 'aa dumpsys --data'
466                 break;
467             }
468             case 'u': {
469                 // 'aa dumpsys -u'
470                 // 'aa dumpsys --userId'
471                 break;
472             }
473             case 'c': {
474                 // 'aa dumpsys -c'
475                 // 'aa dumpsys --client'
476                 break;
477             }
478             case '?': {
479                 if (!isfirstCommand) {
480                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s' option unknown", cmd_.c_str());
481                     std::string unknownOption = "";
482                     std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
483                     resultReceiver_.append(unknownOptionMsg);
484                     resultReceiver_.append(HELP_MSG_DUMPSYS);
485                     result = OHOS::ERR_INVALID_VALUE;
486                     return result;
487                 }
488                 break;
489             }
490             default: {
491                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s' option unknown", cmd_.c_str());
492                 std::string unknownOption = "";
493                 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
494                 resultReceiver_.append(unknownOptionMsg);
495                 result = OHOS::ERR_INVALID_VALUE;
496                 break;
497             }
498         }
499     }
500 
501     if (result != OHOS::ERR_OK) {
502         resultReceiver_.append(HELP_MSG_DUMPSYS);
503     } else {
504         if (isfirstCommand != true) {
505             result = OHOS::ERR_INVALID_VALUE;
506             resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
507             resultReceiver_.append(HELP_MSG_DUMPSYS);
508             return result;
509         }
510 
511         std::vector<std::string> dumpResults;
512         result = AbilityManagerClient::GetInstance()->DumpSysState(args, dumpResults, isClient, isUserID, userID);
513         if (result == OHOS::ERR_OK) {
514             for (auto it : dumpResults) {
515                 resultReceiver_ += it + "\n";
516             }
517         } else {
518             TAG_LOGI(AAFwkTag::AA_TOOL, "dump state failed");
519         }
520     }
521     return result;
522 }
523 
RunAsForceStop()524 ErrCode AbilityManagerShellCommand::RunAsForceStop()
525 {
526     TAG_LOGI(AAFwkTag::AA_TOOL, "enter");
527     if (argList_.empty()) {
528         resultReceiver_.append(HELP_MSG_FORCE_STOP);
529         return OHOS::ERR_INVALID_VALUE;
530     }
531     std::string bundleName = argList_[0];
532     TAG_LOGI(AAFwkTag::AA_TOOL, "Bundle name %{public}s", bundleName.c_str());
533 
534     auto killReason = Reason::REASON_UNKNOWN;
535     pid_t pid = 0;
536     for (auto index = INDEX_OFFSET; index < argc_; ++index) {
537         TAG_LOGD(AAFwkTag::AA_TOOL, "argv_[%{public}d]: %{public}s.", index, argv_[index]);
538         std::string opt = argv_[index];
539         if (opt == "-p") {
540             index++;
541             if (index <= argc_) {
542                 TAG_LOGD(AAFwkTag::AA_TOOL, "argv_[%{public}d]: %{public}s.", index, argv_[index]);
543                 std::string inputPid = argv_[index];
544                 pid = ConvertPid(inputPid);
545             }
546         } else if (opt == "-r") {
547             index++;
548             if (index <= argc_) {
549                 TAG_LOGD(AAFwkTag::AA_TOOL, "argv_[%{public}d]: %{public}s.", index, argv_[index]);
550                 std::string inputReason = argv_[index];
551                 killReason = CovertExitReason(inputReason);
552             }
553         }
554     }
555 
556     TAG_LOGI(AAFwkTag::AA_TOOL, "pid %{public}d, reason %{public}d.", pid, killReason);
557     if (pid != 0 && killReason != Reason::REASON_UNKNOWN) {
558         ExitReason exitReason = {killReason, "aa force-stop"};
559         if (AbilityManagerClient::GetInstance()->RecordProcessExitReason(pid, exitReason) != ERR_OK) {
560             TAG_LOGE(AAFwkTag::AA_TOOL, "bundle %{public}s record reason %{public}d failed.",
561                 bundleName.c_str(), killReason);
562         }
563     }
564 
565     ErrCode result = OHOS::ERR_OK;
566     result = AbilityManagerClient::GetInstance()->KillProcess(bundleName);
567     if (result == OHOS::ERR_OK) {
568         TAG_LOGI(AAFwkTag::AA_TOOL, "%{public}s", STRING_FORCE_STOP_OK.c_str());
569         resultReceiver_ = STRING_FORCE_STOP_OK + "\n";
570     } else {
571         TAG_LOGI(AAFwkTag::AA_TOOL, "%{public}s result: %{public}d", STRING_FORCE_STOP_NG.c_str(), result);
572         resultReceiver_ = STRING_FORCE_STOP_NG + "\n";
573         resultReceiver_.append(GetMessageFromCode(result));
574     }
575     return result;
576 }
577 
CovertExitReason(std::string & reasonStr)578 Reason AbilityManagerShellCommand::CovertExitReason(std::string& reasonStr)
579 {
580     if (reasonStr.empty()) {
581         return Reason::REASON_UNKNOWN;
582     }
583 
584     if (reasonStr.compare("UNKNOWN") == 0) {
585         return Reason::REASON_UNKNOWN;
586     } else if (reasonStr.compare("NORMAL") == 0) {
587         return Reason::REASON_NORMAL;
588     } else if (reasonStr.compare("CPP_CRASH") == 0) {
589         return Reason::REASON_CPP_CRASH;
590     } else if (reasonStr.compare("JS_ERROR") == 0) {
591         return Reason::REASON_JS_ERROR;
592     } else if (reasonStr.compare("APP_FREEZE") == 0) {
593         return Reason::REASON_APP_FREEZE;
594     } else if (reasonStr.compare("PERFORMANCE_CONTROL") == 0) {
595         return Reason::REASON_PERFORMANCE_CONTROL;
596     } else if (reasonStr.compare("RESOURCE_CONTROL") == 0) {
597         return Reason::REASON_RESOURCE_CONTROL;
598     } else if (reasonStr.compare("UPGRADE") == 0) {
599         return Reason::REASON_UPGRADE;
600     }
601 
602     return Reason::REASON_UNKNOWN;
603 }
604 
ConvertPid(std::string & inputPid)605 pid_t AbilityManagerShellCommand::ConvertPid(std::string& inputPid)
606 {
607     pid_t pid = 0;
608     try {
609         pid = static_cast<pid_t>(std::stoi(inputPid));
610     } catch (...) {
611         TAG_LOGW(AAFwkTag::AA_TOOL, "pid stoi(%{public}s) failed.", inputPid.c_str());
612     }
613     return pid;
614 }
615 
RunAsAttachDebugCommand()616 ErrCode AbilityManagerShellCommand::RunAsAttachDebugCommand()
617 {
618     TAG_LOGD(AAFwkTag::AA_TOOL, "called");
619     std::string bundleName = "";
620     ParseBundleName(bundleName);
621     if (bundleName.empty()) {
622         resultReceiver_.append(HELP_MSG_ATTACH_APP_DEBUG + "\n");
623         return OHOS::ERR_INVALID_VALUE;
624     }
625 
626     auto result = AbilityManagerClient::GetInstance()->AttachAppDebug(bundleName);
627     if (result == OHOS::ERR_OK) {
628         resultReceiver_.append(STRING_ATTACH_APP_DEBUG_OK + "\n");
629         return result;
630     }
631 
632     TAG_LOGD(AAFwkTag::AA_TOOL, "%{public}s result: %{public}d", STRING_ATTACH_APP_DEBUG_NG.c_str(), result);
633     resultReceiver_.append(STRING_ATTACH_APP_DEBUG_NG + "\n");
634     return result;
635 }
636 
RunAsDetachDebugCommand()637 ErrCode AbilityManagerShellCommand::RunAsDetachDebugCommand()
638 {
639     TAG_LOGD(AAFwkTag::AA_TOOL, "called");
640     std::string bundleName = "";
641     ParseBundleName(bundleName);
642     if (bundleName.empty()) {
643         resultReceiver_.append(HELP_MSG_DETACH_APP_DEBUG + "\n");
644         return OHOS::ERR_INVALID_VALUE;
645     }
646 
647     auto result = AbilityManagerClient::GetInstance()->DetachAppDebug(bundleName);
648     if (result == OHOS::ERR_OK) {
649         resultReceiver_.append(STRING_DETACH_APP_DEBUG_OK + "\n");
650         return result;
651     }
652 
653     TAG_LOGD(AAFwkTag::AA_TOOL, "%{public}s result: %{public}d", STRING_DETACH_APP_DEBUG_NG.c_str(), result);
654     resultReceiver_.append(STRING_DETACH_APP_DEBUG_NG + "\n");
655     return result;
656 }
657 
SwitchOptionForAppDebug(int32_t option,std::string & bundleName,bool & isPersist,bool & isCancel,bool & isGet)658 bool AbilityManagerShellCommand::SwitchOptionForAppDebug(
659     int32_t option, std::string &bundleName, bool &isPersist, bool &isCancel, bool &isGet)
660 {
661     switch (option) {
662         case 'h': { // 'aa appdebug -h' or 'aa appdebug --help'
663             TAG_LOGD(AAFwkTag::AA_TOOL, "'aa %{public}s -h' help", cmd_.c_str());
664             return true;
665         }
666         case 'b': { // 'aa appdebug -b bundlename'
667             TAG_LOGD(AAFwkTag::AA_TOOL, "'aa %{public}s -b' bundle name", cmd_.c_str());
668             bundleName = optarg;
669             return false;
670         }
671         case 'p': { // 'aa appdebug -p persist'
672             TAG_LOGD(AAFwkTag::AA_TOOL, "'aa %{public}s -p' persist", cmd_.c_str());
673             isPersist = true;
674             return false;
675         }
676         case 'c': { // 'aa appdebug -c cancel'
677             TAG_LOGD(AAFwkTag::AA_TOOL, "'aa %{public}s -c' cancel", cmd_.c_str());
678             isCancel = true;
679             return true;
680         }
681         case 'g': { // 'aa appdebug -g get'
682             TAG_LOGD(AAFwkTag::AA_TOOL, "'aa %{public}s -g' get", cmd_.c_str());
683             isGet = true;
684             return true;
685         }
686         default: {
687             break;
688         }
689     }
690     return true;
691 }
692 
ParseAppDebugParameter(std::string & bundleName,bool & isPersist,bool & isCancel,bool & isGet)693 bool AbilityManagerShellCommand::ParseAppDebugParameter(
694     std::string &bundleName, bool &isPersist, bool &isCancel, bool &isGet)
695 {
696     int32_t option = -1;
697     int32_t counter = 0;
698     while (true) {
699         counter++;
700         option = getopt_long(argc_, argv_, SHORT_OPTIONS_APPDEBUG.c_str(), LONG_OPTIONS_APPDEBUG, nullptr);
701 
702         if (optind < 0 || optind > argc_) {
703             return false;
704         }
705 
706         if (option == -1) {
707             if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
708                 TAG_LOGE(AAFwkTag::AA_TOOL, "'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
709                 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
710                 return false;
711             }
712             return true;
713         }
714 
715         if (option == '?') {
716             switch (optopt) {
717                 case 'b': {
718                     // 'aa appdebug -b' with no argument
719                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -b' no arg", cmd_.c_str());
720                     resultReceiver_.append("error: option requires a valid value.\n");
721                     return false;
722                 }
723                 default: {
724                     // 'aa appdebug' with an unknown option: aa appdebug -x
725                     std::string unknownOption = "";
726                     std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
727                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa appdebug' option unknown");
728                     resultReceiver_.append(unknownOptionMsg);
729                     return false;
730                 }
731             }
732         }
733 
734         if (SwitchOptionForAppDebug(option, bundleName, isPersist, isCancel, isGet)) {
735             return true;
736         }
737     }
738     return false;
739 }
740 
RunAsAppDebugDebugCommand()741 ErrCode AbilityManagerShellCommand::RunAsAppDebugDebugCommand()
742 {
743     TAG_LOGD(AAFwkTag::AA_TOOL, "called");
744     std::string bundleName;
745     bool isPersist = false;
746     bool isCancel = false;
747     bool isGet = false;
748 
749     if (!system::GetBoolParameter(DEVELOPERMODE_STATE, false)) {
750         resultReceiver_ = STRING_APP_DEBUG_NG + "\n";
751         resultReceiver_.append(GetMessageFromCode(ERR_NOT_DEVELOPER_MODE));
752         return OHOS::ERR_INVALID_OPERATION;
753     }
754 
755     if (!ParseAppDebugParameter(bundleName, isPersist, isCancel, isGet)) {
756         resultReceiver_.append(HELP_MSG_APPDEBUG_APP_DEBUG + "\n");
757         return OHOS::ERR_INVALID_VALUE;
758     }
759 
760     int32_t result = OHOS::ERR_OK;
761     std::vector<std::string> debugInfoList;
762     if (isGet) {
763         result = DelayedSingleton<AppMgrClient>::GetInstance()->GetWaitingDebugApp(debugInfoList);
764     } else if (isCancel) {
765         result = DelayedSingleton<AppMgrClient>::GetInstance()->CancelAppWaitingDebug();
766     } else if (!bundleName.empty()) {
767         result = DelayedSingleton<AppMgrClient>::GetInstance()->SetAppWaitingDebug(bundleName, isPersist);
768     } else {
769         resultReceiver_.append(HELP_MSG_APPDEBUG_APP_DEBUG);
770         return OHOS::ERR_OK;
771     }
772 
773     if (result != OHOS::ERR_OK) {
774         TAG_LOGI(AAFwkTag::AA_TOOL, "%{public}s result: %{public}d", STRING_APP_DEBUG_NG.c_str(), result);
775         resultReceiver_ = STRING_APP_DEBUG_NG + "\n";
776         resultReceiver_.append(GetMessageFromCode(result));
777         return result;
778     }
779 
780     resultReceiver_ = STRING_APP_DEBUG_OK + "\n";
781     if (isGet && !debugInfoList.empty()) {
782         for (auto it : debugInfoList) {
783             resultReceiver_ += it + "\n";
784         }
785     }
786     return OHOS::ERR_OK;
787 }
788 
RunAsProcessCommand()789 ErrCode AbilityManagerShellCommand::RunAsProcessCommand()
790 {
791     Want want;
792     ErrCode result = MakeWantForProcess(want);
793     if (result == OHOS::ERR_OK) {
794         auto appMgrClient = std::make_shared<AppMgrClient>();
795         result = appMgrClient->StartNativeProcessForDebugger(want);
796         if (result == OHOS::ERR_OK) {
797             TAG_LOGI(AAFwkTag::AA_TOOL, "%{public}s", STRING_START_NATIVE_PROCESS_OK.c_str());
798             resultReceiver_ = STRING_START_NATIVE_PROCESS_OK;
799         } else {
800             TAG_LOGI(
801                 AAFwkTag::AA_TOOL, "%{public}s result:%{public}d", STRING_START_NATIVE_PROCESS_NG.c_str(), result);
802             resultReceiver_ = STRING_START_NATIVE_PROCESS_NG;
803         }
804     } else {
805         resultReceiver_.append(HELP_MSG_PROCESS);
806         result = OHOS::ERR_INVALID_VALUE;
807     }
808 
809     return result;
810 }
811 
MatchOrderString(const std::regex & regexScript,const std::string & orderCmd)812 bool AbilityManagerShellCommand::MatchOrderString(const std::regex &regexScript, const std::string &orderCmd)
813 {
814     TAG_LOGD(AAFwkTag::AA_TOOL, "orderCmd: %{public}s", orderCmd.c_str());
815     if (orderCmd.empty()) {
816         TAG_LOGE(AAFwkTag::AA_TOOL, "empty orderCmd");
817         return false;
818     }
819 
820     std::match_results<std::string::const_iterator> matchResults;
821     if (!std::regex_match(orderCmd, matchResults, regexScript)) {
822         TAG_LOGE(AAFwkTag::AA_TOOL, "order mismatch");
823         return false;
824     }
825 
826     return true;
827 }
828 
CheckPerfCmdString(const char * optarg,const size_t paramLength,std::string & perfCmd)829 bool AbilityManagerShellCommand::CheckPerfCmdString(
830     const char* optarg, const size_t paramLength, std::string &perfCmd)
831 {
832     if (optarg == nullptr) {
833         TAG_LOGE(AAFwkTag::AA_TOOL, "null optarg");
834         return false;
835     }
836 
837     if (strlen(optarg) >= paramLength) {
838         TAG_LOGE(AAFwkTag::AA_TOOL, "debuggablePipe aa start -p param length must <1024");
839         return false;
840     }
841 
842     perfCmd = optarg;
843     const std::regex regexDumpHeapType(R"(^\s*(dumpheap)\s*$)");
844     const std::regex regexSleepType(R"(^\s*(sleep)((\s+\d*)|)\s*$)");
845     if (MatchOrderString(regexDumpHeapType, perfCmd) || MatchOrderString(regexSleepType, perfCmd)) {
846         return true;
847     }
848 
849     TAG_LOGD(AAFwkTag::AA_TOOL, "command mismatch");
850     const std::regex regexProfileType(R"(^\s*(profile)\s+(nativeperf|jsperf)(\s+.*|$))");
851     if (!MatchOrderString(regexProfileType, perfCmd)) {
852         TAG_LOGE(AAFwkTag::AA_TOOL, "invalid command");
853         return false;
854     }
855 
856     auto findPos = perfCmd.find("jsperf");
857     if (findPos != std::string::npos) {
858         const std::regex regexCmd(R"(^jsperf($|\s+($|((5000|([1-9]|[1-4]\d)\d\d)|)\s*($|nativeperf.*))))");
859         if (!MatchOrderString(regexCmd, perfCmd.substr(findPos, perfCmd.length() - findPos))) {
860             TAG_LOGE(AAFwkTag::AA_TOOL, "invalid order");
861             return false;
862         }
863     }
864     return true;
865 }
866 
CheckParameters(int extraArguments)867 bool AbilityManagerShellCommand::CheckParameters(int extraArguments)
868 {
869     if (optind + extraArguments >= argc_) return false;
870     int index = optind + 1; // optind is the index of 'start' which is right behind optarg
871     int count = 0;
872     while (index < argc_ && argv_[index][0] != '-') {
873         count++;
874         index++;
875     }
876     return count == extraArguments;
877 }
878 
879 // parse integer parameters
ParseParam(ParametersInteger & pi)880 ErrCode AbilityManagerShellCommand::ParseParam(ParametersInteger& pi)
881 {
882     std::string key = optarg;
883     std::string intString = argv_[optind + OPTION_PARAMETER_VALUE_OFFSET];
884     if (!std::regex_match(intString, std::regex(STRING_TEST_REGEX_INTEGER_NUMBERS))) {
885         resultReceiver_.append("invalid parameter ");
886         resultReceiver_.append(intString);
887         resultReceiver_.append(" for integer option\n");
888 
889         return OHOS::ERR_INVALID_VALUE;
890     }
891     pi[key] = atoi(argv_[optind + OPTION_PARAMETER_VALUE_OFFSET]);
892     return OHOS::ERR_OK;
893 }
894 
895 // parse string parameters
ParseParam(ParametersString & ps,bool isNull=false)896 ErrCode AbilityManagerShellCommand::ParseParam(ParametersString& ps, bool isNull = false)
897 {
898     std::string key = optarg;
899     std::string value = "";
900     if (!isNull)
901         value = argv_[optind + OPTION_PARAMETER_VALUE_OFFSET];
902 
903     ps[key] = value;
904 
905     return OHOS::ERR_OK;
906 }
907 
908 // parse bool parameters
ParseParam(ParametersBool & pb)909 ErrCode AbilityManagerShellCommand::ParseParam(ParametersBool& pb)
910 {
911     std::string key = optarg;
912     std::string boolString = argv_[optind + OPTION_PARAMETER_VALUE_OFFSET];
913     std::transform(boolString.begin(), boolString.end(), boolString.begin(), ::tolower);
914     bool value;
915     if (boolString == "true" || boolString == "t") {
916         value = true;
917     } else if (boolString == "false" || boolString == "f") {
918         value = false;
919     } else {
920         resultReceiver_.append("invalid parameter ");
921         resultReceiver_.append(argv_[optind + OPTION_PARAMETER_VALUE_OFFSET]);
922         resultReceiver_.append(" for bool option\n");
923 
924         return OHOS::ERR_INVALID_VALUE;
925     }
926 
927     pb[key] = value;
928 
929     return OHOS::ERR_OK;
930 }
931 
SetParams(const ParametersInteger & pi,Want & want)932 void AbilityManagerShellCommand::SetParams(const ParametersInteger& pi, Want& want)
933 {
934     for (auto it = pi.begin(); it != pi.end(); it++) {
935         want.SetParam(it->first, it->second);
936     }
937 }
938 
SetParams(const ParametersString & ps,Want & want)939 void AbilityManagerShellCommand::SetParams(const ParametersString& ps, Want& want)
940 {
941     for (auto it = ps.begin(); it != ps.end(); it++) {
942         want.SetParam(it->first, it->second);
943     }
944 }
945 
SetParams(const ParametersBool & pb,Want & want)946 void AbilityManagerShellCommand::SetParams(const ParametersBool& pb, Want& want)
947 {
948     for (auto it = pb.begin(); it != pb.end(); it++) {
949         want.SetParam(it->first, it->second);
950     }
951 }
952 
AddEntities(const std::vector<std::string> & entities,Want & want)953 void AddEntities(const std::vector<std::string>& entities, Want& want)
954 {
955     for (auto entity : entities)
956         want.AddEntity(entity);
957 }
958 
MakeWantForProcess(Want & want)959 ErrCode AbilityManagerShellCommand::MakeWantForProcess(Want& want)
960 {
961     int result = OHOS::ERR_OK;
962     int option = -1;
963     int counter = 0;
964     std::string deviceId = "";
965     std::string bundleName = "";
966     std::string abilityName = "";
967     std::string moduleName = "";
968     std::string perfCmd = "";
969     std::string debugCmd = "";
970     bool isPerf = false;
971     bool isSandboxApp = false;
972 
973     while (true) {
974         counter++;
975 
976         option = getopt_long(argc_, argv_, SHORT_OPTIONS_PROCESS.c_str(), LONG_OPTIONS_PROCESS, nullptr);
977 
978         TAG_LOGI(
979             AAFwkTag::AA_TOOL, "option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
980 
981         if (optind < 0 || optind > argc_) {
982             return OHOS::ERR_INVALID_VALUE;
983         }
984 
985         if (option == -1) {
986             // When scanning the first argument
987             if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
988                 // 'aa process' with no option: aa process
989                 // 'aa process' with a wrong argument: aa process xxx
990                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s' %{public}s!", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
991 
992                 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
993                 result = OHOS::ERR_INVALID_VALUE;
994             }
995             break;
996         }
997 
998         if (option == '?') {
999             switch (optopt) {
1000                 case 'a': {
1001                     // 'aa process -a' with no argument
1002                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -a' no arg", cmd_.c_str());
1003 
1004                     resultReceiver_.append("error: option ");
1005                     resultReceiver_.append("requires a value.\n");
1006 
1007                     result = OHOS::ERR_INVALID_VALUE;
1008                     break;
1009                 }
1010                 case 'b': {
1011                     // 'aa process -b' with no argument
1012                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -b' no arg", cmd_.c_str());
1013 
1014                     resultReceiver_.append("error: option ");
1015                     resultReceiver_.append("requires a value.\n");
1016 
1017                     result = OHOS::ERR_INVALID_VALUE;
1018                     break;
1019                 }
1020                 case 'm': {
1021                     // 'aa process -m' with no argument
1022                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -m' no arg", cmd_.c_str());
1023 
1024                     resultReceiver_.append("error: option ");
1025                     resultReceiver_.append("requires a value.\n");
1026 
1027                     result = OHOS::ERR_INVALID_VALUE;
1028                     break;
1029                 }
1030                 case 'p': {
1031                     // 'aa process -p' with no argument
1032                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -p' no arg", cmd_.c_str());
1033 
1034                     resultReceiver_.append("error: option ");
1035                     resultReceiver_.append("requires a value.\n");
1036 
1037                     result = OHOS::ERR_INVALID_VALUE;
1038                     break;
1039                 }
1040                 case 'D': {
1041                     // 'aa process -D' with no argument
1042                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -D' no arg", cmd_.c_str());
1043 
1044                     resultReceiver_.append("error: option ");
1045                     resultReceiver_.append("requires a value.\n");
1046 
1047                     result = OHOS::ERR_INVALID_VALUE;
1048                     break;
1049                 }
1050                 case 0: {
1051                     // 'aa process' with an unknown option: aa process --x
1052                     // 'aa process' with an unknown option: aa process --xxx
1053                     std::string unknownOption = "";
1054                     std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1055 
1056                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s' opt unknown", cmd_.c_str());
1057 
1058                     resultReceiver_.append(unknownOptionMsg);
1059                     result = OHOS::ERR_INVALID_VALUE;
1060                     break;
1061                 }
1062                 default: {
1063                     // 'aa process' with an unknown option: aa process -x
1064                     // 'aa process' with an unknown option: aa process -xxx
1065                     std::string unknownOption = "";
1066                     std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1067 
1068                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s' opt unknown", cmd_.c_str());
1069 
1070                     resultReceiver_.append(unknownOptionMsg);
1071                     result = OHOS::ERR_INVALID_VALUE;
1072                     break;
1073                 }
1074             }
1075             break;
1076         }
1077 
1078         switch (option) {
1079             case 'h': {
1080                 // 'aa process -h'
1081                 // 'aa process --help'
1082                 result = OHOS::ERR_INVALID_VALUE;
1083                 break;
1084             }
1085             case 'a': {
1086                 // 'aa process -a xxx'
1087                 // save ability name
1088                 abilityName = optarg;
1089                 break;
1090             }
1091             case 'b': {
1092                 // 'aa process -b xxx'
1093                 // save bundle name
1094                 bundleName = optarg;
1095                 break;
1096             }
1097             case 'm': {
1098                 // 'aa process -m xxx'
1099                 // save module name
1100                 moduleName = optarg;
1101                 break;
1102             }
1103             case 'p': {
1104                 // 'aa process -p xxx'
1105                 // save perf cmd
1106                 if (strlen(optarg) < PARAM_LENGTH) {
1107                     perfCmd = optarg;
1108                     isPerf = true;
1109                 }
1110                 break;
1111             }
1112             case 'D': {
1113                 // 'aa process -D xxx'
1114                 // save debug cmd
1115                 if (!isPerf && strlen(optarg) < PARAM_LENGTH) {
1116                     TAG_LOGI(AAFwkTag::AA_TOOL, "debug cmd");
1117                     debugCmd = optarg;
1118                 }
1119                 break;
1120             }
1121             case 'S': {
1122                 // 'aa process -S'
1123                 // enter sandbox to perform app
1124                 isSandboxApp = true;
1125                 break;
1126             }
1127             case 0: {
1128                 break;
1129             }
1130             default: {
1131                 break;
1132             }
1133         }
1134     }
1135 
1136     if (result == OHOS::ERR_OK) {
1137         if (perfCmd.empty() && debugCmd.empty()) {
1138             TAG_LOGI(AAFwkTag::AA_TOOL,
1139                 "debuggablePipe aa process must contains -p or -D and param length must <1024");
1140             return OHOS::ERR_INVALID_VALUE;
1141         }
1142 
1143         if (abilityName.size() == 0 || bundleName.size() == 0) {
1144             // 'aa process -a <ability-name> -b <bundle-name> [-D]'
1145             TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s' without enough options", cmd_.c_str());
1146 
1147             if (abilityName.size() == 0) {
1148                 resultReceiver_.append(HELP_MSG_NO_ABILITY_NAME_OPTION + "\n");
1149             }
1150 
1151             if (bundleName.size() == 0) {
1152                 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n");
1153             }
1154 
1155             result = OHOS::ERR_INVALID_VALUE;
1156         } else {
1157             ElementName element(deviceId, bundleName, abilityName, moduleName);
1158             want.SetElement(element);
1159 
1160             if (!perfCmd.empty()) {
1161                 want.SetParam("perfCmd", perfCmd);
1162             }
1163             if (!debugCmd.empty()) {
1164                 want.SetParam("debugCmd", debugCmd);
1165             }
1166             if (isSandboxApp) {
1167                 want.SetParam("sandboxApp", isSandboxApp);
1168             }
1169         }
1170     }
1171 
1172     return result;
1173 }
1174 
ParseBundleName(std::string & bundleName)1175 void AbilityManagerShellCommand::ParseBundleName(std::string &bundleName)
1176 {
1177     int option = -1;
1178     int counter = 0;
1179 
1180     while (true) {
1181         counter++;
1182         option = getopt_long(argc_, argv_, SHORT_OPTIONS_ATTACH.c_str(), LONG_OPTIONS_ATTACH, nullptr);
1183         TAG_LOGD(AAFwkTag::AA_TOOL, "getopt_long option: %{public}d, optopt: %{public}d, optind: %{public}d", option,
1184             optopt, optind);
1185 
1186         if (optind < 0 || optind > argc_) {
1187             break;
1188         }
1189 
1190         if (option == -1) {
1191             // aa command without option
1192             if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
1193                 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
1194             }
1195             break;
1196         }
1197 
1198         if (option == '?') {
1199             switch (optopt) {
1200                 case 'b':
1201                 case 'h':
1202                     break;
1203                 default: {
1204                     // 'aa attach/detach' with an unknown option
1205                     std::string unknownOption = "";
1206                     std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1207                     resultReceiver_.append(unknownOptionMsg);
1208                     break;
1209                 }
1210             }
1211             break;
1212         }
1213 
1214         switch (option) {
1215             case 'b': {
1216                 bundleName = optarg;
1217                 break;
1218             }
1219             default:
1220                 break;
1221         }
1222     }
1223 }
1224 
1225 #ifdef ABILITY_COMMAND_FOR_TEST
RunForceTimeoutForTest()1226 ErrCode AbilityManagerShellCommand::RunForceTimeoutForTest()
1227 {
1228     TAG_LOGI(AAFwkTag::AA_TOOL, "[%{public}s(%{public}s)] enter", __FILE__, __FUNCTION__);
1229     if (argList_.empty()) {
1230         resultReceiver_.append(HELP_MSG_FORCE_TIMEOUT + "\n");
1231         return OHOS::ERR_INVALID_VALUE;
1232     }
1233 
1234     ErrCode result = OHOS::ERR_OK;
1235     if (argList_.size() == NUMBER_ONE && argList_[0] == HELP_MSG_FORCE_TIMEOUT_CLEAN) {
1236         TAG_LOGI(AAFwkTag::AA_TOOL, "clear ability timeout flags");
1237         result = AbilityManagerClient::GetInstance()->ForceTimeoutForTest(argList_[0], "");
1238     } else if (argList_.size() == NUMBER_TWO) {
1239         TAG_LOGI(AAFwkTag::AA_TOOL, "Ability name : %{public}s, state: %{public}s", argList_[0].c_str(),
1240             argList_[1].c_str());
1241         result = AbilityManagerClient::GetInstance()->ForceTimeoutForTest(argList_[0], argList_[1]);
1242     } else {
1243         resultReceiver_.append(HELP_MSG_FORCE_TIMEOUT + "\n");
1244         return OHOS::ERR_INVALID_VALUE;
1245     }
1246     if (result == OHOS::ERR_OK) {
1247         TAG_LOGI(AAFwkTag::AA_TOOL, "%{public}s", STRING_FORCE_TIMEOUT_OK.c_str());
1248         resultReceiver_ = STRING_FORCE_TIMEOUT_OK + "\n";
1249     } else {
1250         TAG_LOGI(AAFwkTag::AA_TOOL, "%{public}s result: %{public}d", STRING_FORCE_TIMEOUT_NG.c_str(), result);
1251         resultReceiver_ = STRING_FORCE_TIMEOUT_NG + "\n";
1252         resultReceiver_.append(GetMessageFromCode(result));
1253     }
1254     return result;
1255 }
1256 #endif
1257 
MakeWantFromCmd(Want & want,std::string & windowMode)1258 ErrCode AbilityManagerShellCommand::MakeWantFromCmd(Want& want, std::string& windowMode)
1259 {
1260     int result = OHOS::ERR_OK;
1261 
1262     int option = -1;
1263     int counter = 0;
1264 
1265     std::string deviceId = "";
1266     std::string bundleName = "";
1267     std::string abilityName = "";
1268     std::string moduleName;
1269     std::string perfCmd;
1270     ParametersInteger parametersInteger;
1271     ParametersString parametersString;
1272     ParametersBool parametersBool;
1273     std::string uri;
1274     std::string action;
1275     std::vector<std::string> entities;
1276     std::string typeVal;
1277     bool isColdStart = false;
1278     bool isDebugApp = false;
1279     bool isErrorInfoEnhance = false;
1280     bool isContinuation = false;
1281     bool isSandboxApp = false;
1282     bool isNativeDebug = false;
1283     bool isMultiThread = false;
1284     int windowLeft = 0;
1285     bool hasWindowLeft = false;
1286     int windowTop = 0;
1287     bool hasWindowTop = false;
1288     int windowHeight = 0;
1289     bool hasWindowHeight = false;
1290     int windowWidth = 0;
1291     bool hasWindowWidth = false;
1292 
1293     while (true) {
1294         counter++;
1295 
1296         option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
1297 
1298         TAG_LOGI(
1299             AAFwkTag::AA_TOOL, "option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
1300 
1301         if (optind < 0 || optind > argc_) {
1302             return OHOS::ERR_INVALID_VALUE;
1303         }
1304 
1305         if (option == -1) {
1306             // When scanning the first argument
1307             if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
1308                 // 'aa start' with no option: aa start
1309                 // 'aa start' with a wrong argument: aa start xxx
1310                 // 'aa stop-service' with no option: aa stop-service
1311                 // 'aa stop-service' with a wrong argument: aa stop-service xxx
1312                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
1313 
1314                 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
1315                 result = OHOS::ERR_INVALID_VALUE;
1316             }
1317             break;
1318         }
1319 
1320         if (option == '?') {
1321             switch (optopt) {
1322                 case 'h': {
1323                     // 'aa start -h'
1324                     // 'aa stop-service -h'
1325                     result = OHOS::ERR_INVALID_VALUE;
1326                     break;
1327                 }
1328                 case 'd': {
1329                     // 'aa start -d' with no argument
1330                     // 'aa stop-service -d' with no argument
1331                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -d' no arg", cmd_.c_str());
1332 
1333                     resultReceiver_.append("error: option ");
1334                     resultReceiver_.append("requires a value.\n");
1335 
1336                     result = OHOS::ERR_INVALID_VALUE;
1337                     break;
1338                 }
1339                 case 'a': {
1340                     // 'aa start -a' with no argument
1341                     // 'aa stop-service -a' with no argument
1342                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -a' no arg", cmd_.c_str());
1343 
1344                     resultReceiver_.append("error: option ");
1345                     resultReceiver_.append("requires a value.\n");
1346 
1347                     result = OHOS::ERR_INVALID_VALUE;
1348                     break;
1349                 }
1350                 case 'b': {
1351                     // 'aa start -b' with no argument
1352                     // 'aa stop-service -b' with no argument
1353                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -b' no arg", cmd_.c_str());
1354 
1355                     resultReceiver_.append("error: option ");
1356                     resultReceiver_.append("requires a value.\n");
1357 
1358                     result = OHOS::ERR_INVALID_VALUE;
1359                     break;
1360                 }
1361                 case 'e': {
1362                     // 'aa start -e' with no argument
1363                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -e no arg", cmd_.c_str());
1364 
1365                     resultReceiver_.append("error: option ");
1366                     resultReceiver_.append("requires a value.\n");
1367 
1368                     result = OHOS::ERR_INVALID_VALUE;
1369                     break;
1370                 }
1371                 case 't': {
1372                     // 'aa start -t' with no argument
1373                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -t no arg", cmd_.c_str());
1374 
1375                     resultReceiver_.append("error: option ");
1376                     resultReceiver_.append("requires a value.\n");
1377 
1378                     result = OHOS::ERR_INVALID_VALUE;
1379                     break;
1380                 }
1381                 case 's': {
1382                     // 'aa start -s' with no argument
1383                     // 'aa stop-service -s' with no argument
1384                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -s' no arg", cmd_.c_str());
1385 
1386                     resultReceiver_.append("error: option ");
1387                     resultReceiver_.append(argv_[optind - 1]);
1388                     resultReceiver_.append("' requires a value.\n");
1389 
1390                     result = OHOS::ERR_INVALID_VALUE;
1391                     break;
1392                 }
1393                 case 'm': {
1394                     // 'aa start -m' with no argument
1395                     // 'aa stop-service -m' with no argument
1396                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -m' no arg", cmd_.c_str());
1397 
1398                     resultReceiver_.append("error: option ");
1399                     resultReceiver_.append("requires a value.\n");
1400 
1401                     result = OHOS::ERR_INVALID_VALUE;
1402                     break;
1403                 }
1404                 case 'p': {
1405                     // 'aa start -p' with no argument
1406                     // 'aa stop-service -p' with no argument
1407                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -p' no arg", cmd_.c_str());
1408 
1409                     resultReceiver_.append("error: option ");
1410                     resultReceiver_.append("requires a value.\n");
1411 
1412                     result = OHOS::ERR_INVALID_VALUE;
1413                     break;
1414                 }
1415                 case OPTION_PARAMETER_INTEGER: {
1416                     // 'aa start --pi' with no argument
1417                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s --pi' no arg", cmd_.c_str());
1418 
1419                     resultReceiver_.append("error: option ");
1420                     resultReceiver_.append("requires a value.\n");
1421 
1422                     result = OHOS::ERR_INVALID_VALUE;
1423 
1424                     break;
1425                 }
1426                 case OPTION_PARAMETER_STRING: {
1427                     // 'aa start --ps' with no argument
1428                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s --ps' no arg", cmd_.c_str());
1429 
1430                     resultReceiver_.append("error: option ");
1431                     resultReceiver_.append("requires a value.\n");
1432 
1433                     result = OHOS::ERR_INVALID_VALUE;
1434 
1435                     break;
1436                 }
1437                 case OPTION_PARAMETER_BOOL: {
1438                     // 'aa start --pb' with no argument
1439                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -pb' no arg", cmd_.c_str());
1440 
1441                     resultReceiver_.append("error: option ");
1442                     resultReceiver_.append("requires a value.\n");
1443 
1444                     result = OHOS::ERR_INVALID_VALUE;
1445 
1446                     break;
1447                 }
1448                 case OPTION_PARAMETER_NULL_STRING: {
1449                     // 'aa start --psn' with no argument
1450                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s --psn' no arg", cmd_.c_str());
1451 
1452                     resultReceiver_.append("error: option ");
1453                     resultReceiver_.append("requires a value.\n");
1454 
1455                     result = OHOS::ERR_INVALID_VALUE;
1456 
1457                     break;
1458                 }
1459                 case OPTION_WINDOW_LEFT: {
1460                     // 'aa start --wl' with no argument
1461                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s --wl' no arg", cmd_.c_str());
1462 
1463                     resultReceiver_.append("error: option ");
1464                     resultReceiver_.append("requires a value.\n");
1465 
1466                     result = OHOS::ERR_INVALID_VALUE;
1467 
1468                     break;
1469                 }
1470                 case OPTION_WINDOW_TOP: {
1471                     // 'aa start --wt' with no argument
1472                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s --wt' no arg", cmd_.c_str());
1473 
1474                     resultReceiver_.append("error: option ");
1475                     resultReceiver_.append("requires a value.\n");
1476 
1477                     result = OHOS::ERR_INVALID_VALUE;
1478 
1479                     break;
1480                 }
1481                 case OPTION_WINDOW_HEIGHT: {
1482                     // 'aa start --wh' with no argument
1483                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s --wh' no arg", cmd_.c_str());
1484 
1485                     resultReceiver_.append("error: option ");
1486                     resultReceiver_.append("requires a value.\n");
1487 
1488                     result = OHOS::ERR_INVALID_VALUE;
1489 
1490                     break;
1491                 }
1492                 case OPTION_WINDOW_WIDTH: {
1493                     // 'aa start --ww' with no argument
1494                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s --ww' no arg", cmd_.c_str());
1495 
1496                     resultReceiver_.append("error: option ");
1497                     resultReceiver_.append("requires a value.\n");
1498 
1499                     result = OHOS::ERR_INVALID_VALUE;
1500 
1501                     break;
1502                 }
1503 
1504                 case 'A': {
1505                     // 'aa start -A' with no argument
1506                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -A' no arg", cmd_.c_str());
1507 
1508                     resultReceiver_.append("error: option ");
1509                     resultReceiver_.append("requires a value.\n");
1510 
1511                     result = OHOS::ERR_INVALID_VALUE;
1512 
1513                     break;
1514                 }
1515                 case 'U': {
1516                     // 'aa start -U' with no argument
1517                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -U' no arg", cmd_.c_str());
1518 
1519                     resultReceiver_.append("error: option ");
1520                     resultReceiver_.append("requires a value.\n");
1521 
1522                     result = OHOS::ERR_INVALID_VALUE;
1523 
1524                     break;
1525                 }
1526                 case 0: {
1527                     // 'aa start' with an unknown option: aa start --x
1528                     // 'aa start' with an unknown option: aa start --xxx
1529                     // 'aa stop-service' with an unknown option: aa stop-service --x
1530                     // 'aa stop-service' with an unknown option: aa stop-service --xxx
1531                     std::string unknownOption = "";
1532                     std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1533 
1534                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s' opt unknown", cmd_.c_str());
1535 
1536                     resultReceiver_.append(unknownOptionMsg);
1537                     result = OHOS::ERR_INVALID_VALUE;
1538                     break;
1539                 }
1540                 default: {
1541                     // 'aa start' with an unknown option: aa start -x
1542                     // 'aa start' with an unknown option: aa start -xxx
1543                     // 'aa stop-service' with an unknown option: aa stop-service -x
1544                     // 'aa stop-service' with an unknown option: aa stop-service -xxx
1545                     std::string unknownOption = "";
1546                     std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1547 
1548                     TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s' opt unknown", cmd_.c_str());
1549 
1550                     resultReceiver_.append(unknownOptionMsg);
1551                     result = OHOS::ERR_INVALID_VALUE;
1552                     break;
1553                 }
1554             }
1555             break;
1556         }
1557 
1558         switch (option) {
1559             case 'h': {
1560                 // 'aa start -h'
1561                 // 'aa start --help'
1562                 // 'aa stop-service -h'
1563                 // 'aa stop-service --help'
1564                 result = OHOS::ERR_INVALID_VALUE;
1565                 break;
1566             }
1567             case 'd': {
1568                 // 'aa start -d xxx'
1569                 // 'aa stop-service -d xxx'
1570 
1571                 // save device ID
1572                 if (optarg != nullptr) {
1573                     deviceId = optarg;
1574                 }
1575                 break;
1576             }
1577             case 'a': {
1578                 // 'aa start -a xxx'
1579                 // 'aa stop-service -a xxx'
1580 
1581                 // save ability name
1582                 abilityName = optarg;
1583                 break;
1584             }
1585             case 'b': {
1586                 // 'aa start -b xxx'
1587                 // 'aa stop-service -b xxx'
1588 
1589                 // save bundle name
1590                 bundleName = optarg;
1591                 break;
1592             }
1593             case 'e': {
1594                 // 'aa start -e xxx'
1595 
1596                 // save entity
1597                 entities.push_back(optarg);
1598                 break;
1599             }
1600             case 't': {
1601                 // 'aa start -t xxx'
1602 
1603                 // save type
1604                 typeVal = optarg;
1605                 break;
1606             }
1607             case 's': {
1608                 // 'aa start -s xxx'
1609                 // save windowMode
1610                 windowMode = optarg;
1611                 break;
1612             }
1613             case 'm': {
1614                 // 'aa start -m xxx'
1615                 // 'aa stop-service -m xxx'
1616 
1617                 // save module name
1618                 moduleName = optarg;
1619                 break;
1620             }
1621             case 'p': {
1622                 // 'aa start -p xxx'
1623                 // 'aa stop-service -p xxx'
1624 
1625                 // save module name
1626                 if (!CheckPerfCmdString(optarg, PARAM_LENGTH, perfCmd)) {
1627                     TAG_LOGE(AAFwkTag::AA_TOOL, "input perfCmd invalid %{public}s", perfCmd.c_str());
1628                     result = OHOS::ERR_INVALID_VALUE;
1629                 }
1630                 break;
1631             }
1632             case OPTION_PARAMETER_INTEGER: {
1633                 // 'aa start --pi xxx'
1634                 if (!CheckParameters(EXTRA_ARGUMENTS_FOR_KEY_VALUE_PAIR)) {
1635                     resultReceiver_.append("invalid number of parameters for option --pi\n");
1636                     result = OHOS::ERR_INVALID_VALUE;
1637                     break;
1638                 }
1639 
1640                 // parse option arguments into a key-value map
1641                 result = ParseParam(parametersInteger);
1642 
1643                 optind++;
1644 
1645                 break;
1646             }
1647             case OPTION_PARAMETER_STRING: {
1648                 // 'aa start --ps xxx'
1649                 if (!CheckParameters(EXTRA_ARGUMENTS_FOR_KEY_VALUE_PAIR)) {
1650                     resultReceiver_.append("invalid number of parameters for option --ps\n");
1651                     result = OHOS::ERR_INVALID_VALUE;
1652                     break;
1653                 }
1654 
1655                 // parse option arguments into a key-value map
1656                 result = ParseParam(parametersString);
1657 
1658                 optind++;
1659 
1660                 break;
1661             }
1662             case OPTION_PARAMETER_BOOL: {
1663                 // 'aa start --pb xxx'
1664                 if (!CheckParameters(EXTRA_ARGUMENTS_FOR_KEY_VALUE_PAIR)) {
1665                     resultReceiver_.append("invalid number of parameters for option --pb\n");
1666                     result = OHOS::ERR_INVALID_VALUE;
1667                     break;
1668                 }
1669 
1670                 // parse option arguments into a key-value map
1671                 result = ParseParam(parametersBool);
1672 
1673                 optind++;
1674 
1675                 break;
1676             }
1677             case OPTION_PARAMETER_NULL_STRING: {
1678                 // 'aa start --psn xxx'
1679                 if (!CheckParameters(EXTRA_ARGUMENTS_FOR_NULL_STRING)) {
1680                     resultReceiver_.append("invalid number of parameters for option --psn\n");
1681                     result = OHOS::ERR_INVALID_VALUE;
1682                     break;
1683                 }
1684 
1685                 // parse option arguments into a key-value map
1686                 result = ParseParam(parametersString, true);
1687 
1688                 break;
1689             }
1690             case OPTION_WINDOW_LEFT: {
1691                 // 'aa start --wl xxx'
1692                 if (!std::regex_match(optarg, std::regex(STRING_REGEX_ALL_NUMBERS))) {
1693                     resultReceiver_.append("invalid argument for option --wl\n");
1694                     result = OHOS::ERR_INVALID_VALUE;
1695                     break;
1696                 }
1697                 windowLeft = int(atof(optarg));
1698                 hasWindowLeft = true;
1699                 TAG_LOGI(AAFwkTag::AA_TOOL, "windowLeft=%{public}d", windowLeft);
1700 
1701                 break;
1702             }
1703             case OPTION_WINDOW_TOP: {
1704                 // 'aa start --wt xxx'
1705                 if (!std::regex_match(optarg, std::regex(STRING_REGEX_ALL_NUMBERS))) {
1706                     resultReceiver_.append("invalid argument for option --wt\n");
1707                     result = OHOS::ERR_INVALID_VALUE;
1708                     break;
1709                 }
1710                 windowTop = int(atof(optarg));
1711                 hasWindowTop = true;
1712                 TAG_LOGI(AAFwkTag::AA_TOOL, "windowTop=%{public}d", windowTop);
1713 
1714                 break;
1715             }
1716             case OPTION_WINDOW_HEIGHT: {
1717                 // 'aa start --wh xxx'
1718                 if (!std::regex_match(optarg, std::regex(STRING_REGEX_ALL_NUMBERS))) {
1719                     resultReceiver_.append("invalid argument for option --wh\n");
1720                     result = OHOS::ERR_INVALID_VALUE;
1721                     break;
1722                 }
1723                 windowHeight = int(atof(optarg));
1724                 hasWindowHeight = true;
1725                 TAG_LOGI(AAFwkTag::AA_TOOL, "windowHeight=%{public}d", windowHeight);
1726 
1727                 break;
1728             }
1729             case OPTION_WINDOW_WIDTH: {
1730                 // 'aa start --ww xxx'
1731                 if (!std::regex_match(optarg, std::regex(STRING_REGEX_ALL_NUMBERS))) {
1732                     resultReceiver_.append("invalid argument for option --ww\n");
1733                     result = OHOS::ERR_INVALID_VALUE;
1734                     break;
1735                 }
1736                 windowWidth = int(atof(optarg));
1737                 hasWindowWidth = true;
1738                 TAG_LOGI(AAFwkTag::AA_TOOL, "windowWidth=%{public}d", windowWidth);
1739 
1740                 break;
1741             }
1742             case 'U': {
1743                 // 'aa start -U xxx'
1744 
1745                 // save URI
1746                 uri = optarg;
1747                 break;
1748             }
1749             case 'A': {
1750                 // 'aa start -A xxx'
1751 
1752                 // save action
1753                 action = optarg;
1754                 break;
1755             }
1756             case 'C': {
1757                 // 'aa start -C'
1758                 // cold start app
1759                 isColdStart = true;
1760                 break;
1761             }
1762             case 'D': {
1763                 // 'aa start -D'
1764                 // debug app
1765                 isDebugApp = true;
1766                 break;
1767             }
1768             case 'E': {
1769                 // 'aa start -E'
1770                 // error info enhance
1771                 isErrorInfoEnhance = true;
1772                 TAG_LOGD(AAFwkTag::AA_TOOL, "isErrorInfoEnhance");
1773                 break;
1774             }
1775             case 'S': {
1776                 // 'aa start -b <bundleName> -a <abilityName> -p <perf-cmd> -S'
1777                 // enter sandbox to perform app
1778                 isSandboxApp = true;
1779                 break;
1780             }
1781             case 'c': {
1782                 // 'aa start -c'
1783                 // set ability launch reason = continuation
1784                 isContinuation = true;
1785                 break;
1786             }
1787             case 'N': {
1788                 // 'aa start -N'
1789                 // wait for debug in appspawn
1790                 isNativeDebug = true;
1791                 break;
1792             }
1793             case 'R': {
1794                 // 'aa start -R'
1795                 // app multi thread
1796                 isMultiThread = true;
1797                 TAG_LOGD(AAFwkTag::AA_TOOL, "isMultiThread");
1798             }
1799             case 0: {
1800                 break;
1801             }
1802             default: {
1803                 break;
1804             }
1805         }
1806     }
1807 
1808     if (result == OHOS::ERR_OK) {
1809         if (!abilityName.empty() && bundleName.empty()) {
1810             // explicitly start ability must have both ability and bundle names
1811 
1812             // 'aa start [-d <device-id>] -a <ability-name> -b <bundle-name> [-D]'
1813             // 'aa stop-service [-d <device-id>] -a <ability-name> -b <bundle-name>'
1814             TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s' without enough options", cmd_.c_str());
1815 
1816             resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n");
1817             result = OHOS::ERR_INVALID_VALUE;
1818         } else {
1819             ElementName element(deviceId, bundleName, abilityName, moduleName);
1820             want.SetElement(element);
1821 
1822             if (isColdStart) {
1823                 want.SetParam("coldStart", isColdStart);
1824             }
1825             if (isDebugApp) {
1826                 want.SetParam("debugApp", isDebugApp);
1827             }
1828             if (isContinuation) {
1829                 want.AddFlags(Want::FLAG_ABILITY_CONTINUATION);
1830             }
1831             if (!perfCmd.empty()) {
1832                 want.SetParam("perfCmd", perfCmd);
1833             }
1834             if (isSandboxApp) {
1835                 want.SetParam("sandboxApp", isSandboxApp);
1836             }
1837             if (isNativeDebug) {
1838                 want.SetParam("nativeDebug", isNativeDebug);
1839             }
1840             if (!parametersInteger.empty()) {
1841                 SetParams(parametersInteger, want);
1842             }
1843             if (!parametersBool.empty()) {
1844                 SetParams(parametersBool, want);
1845             }
1846             if (!parametersString.empty()) {
1847                 SetParams(parametersString, want);
1848             }
1849             if (!action.empty()) {
1850                 want.SetAction(action);
1851             }
1852             if (!uri.empty()) {
1853                 want.SetUri(uri);
1854             }
1855             if (!entities.empty()) {
1856                 AddEntities(entities, want);
1857             }
1858             if (!typeVal.empty()) {
1859                 want.SetType(typeVal);
1860             }
1861             if (isErrorInfoEnhance) {
1862                 want.SetParam("errorInfoEnhance", isErrorInfoEnhance);
1863             }
1864             if (isMultiThread) {
1865                 want.SetParam("multiThread", isMultiThread);
1866             }
1867             if (hasWindowLeft) {
1868                 want.SetParam(Want::PARAM_RESV_WINDOW_LEFT, windowLeft);
1869             }
1870             if (hasWindowTop) {
1871                 want.SetParam(Want::PARAM_RESV_WINDOW_TOP, windowTop);
1872             }
1873             if (hasWindowHeight) {
1874                 want.SetParam(Want::PARAM_RESV_WINDOW_HEIGHT, windowHeight);
1875             }
1876             if (hasWindowWidth) {
1877                 want.SetParam(Want::PARAM_RESV_WINDOW_WIDTH, windowWidth);
1878             }
1879         }
1880     }
1881 
1882     return result;
1883 }
1884 
RunAsTestCommand()1885 ErrCode AbilityManagerShellCommand::RunAsTestCommand()
1886 {
1887     TAG_LOGD(AAFwkTag::AA_TOOL, "enter");
1888     std::map<std::string, std::string> params;
1889 
1890     for (int i = USER_TEST_COMMAND_START_INDEX; i < argc_; i++) {
1891         TAG_LOGI(AAFwkTag::AA_TOOL, "argv_[%{public}d]: %{public}s", i, argv_[i]);
1892         std::string opt = argv_[i];
1893         if ((opt == "-h") || (opt == "--help")) {
1894             resultReceiver_.append(HELP_MSG_TEST);
1895             return OHOS::ERR_OK;
1896         } else if ((opt == "-b") || (opt == "-p") || (opt == "-m")) {
1897             if (i >= argc_ - 1) {
1898                 return TestCommandError("error: option [" + opt + "] requires a value.\n");
1899             }
1900             std::string argv = argv_[++i];
1901             params[opt] = argv;
1902         } else if (opt == "-w") {
1903             if (i >= argc_ - 1) {
1904                 return TestCommandError("error: option [" + opt + "] requires a value.\n");
1905             }
1906 
1907             std::string argv = argv_[++i];
1908             if (!std::regex_match(argv, std::regex(STRING_TEST_REGEX_INTEGER_NUMBERS))) {
1909                 return TestCommandError("error: option [" + opt + "] only supports integer numbers.\n");
1910             }
1911 
1912             params[opt] = argv;
1913         } else if (opt == "-s") {
1914             if (i >= argc_ - USER_TEST_COMMAND_PARAMS_NUM) {
1915                 return TestCommandError("error: option [-s] is incorrect.\n");
1916             }
1917             std::string argKey = argv_[++i];
1918             std::string argValue = argv_[++i];
1919             params[opt + " " + argKey] = argValue;
1920         } else if (opt == "-D") {
1921             params[opt] = DEBUG_VALUE;
1922         } else if (opt.at(0) == '-') {
1923             return TestCommandError("error: unknown option: " + opt + "\n");
1924         }
1925     }
1926 
1927     if (!IsTestCommandIntegrity(params)) {
1928         return OHOS::ERR_INVALID_VALUE;
1929     }
1930 
1931     return StartUserTest(params);
1932 }
1933 
IsTestCommandIntegrity(const std::map<std::string,std::string> & params)1934 bool AbilityManagerShellCommand::IsTestCommandIntegrity(const std::map<std::string, std::string>& params)
1935 {
1936     TAG_LOGD(AAFwkTag::AA_TOOL, "enter");
1937 
1938     std::vector<std::string> opts = { "-b", "-s unittest" };
1939     for (auto opt : opts) {
1940         auto it = params.find(opt);
1941         if (it == params.end()) {
1942             TestCommandError("error: the option [" + opt + "] is expected.\n");
1943             return false;
1944         }
1945     }
1946     return true;
1947 }
1948 
TestCommandError(const std::string & info)1949 ErrCode AbilityManagerShellCommand::TestCommandError(const std::string& info)
1950 {
1951     resultReceiver_.append(info);
1952     resultReceiver_.append(HELP_MSG_TEST);
1953     return OHOS::ERR_INVALID_VALUE;
1954 }
1955 
StartUserTest(const std::map<std::string,std::string> & params)1956 ErrCode AbilityManagerShellCommand::StartUserTest(const std::map<std::string, std::string>& params)
1957 {
1958     TAG_LOGD(AAFwkTag::AA_TOOL, "enter");
1959 
1960     Want want;
1961     for (auto param : params) {
1962         want.SetParam(param.first, param.second);
1963     }
1964 
1965     auto dPos = params.find("-D");
1966     if (dPos != params.end() && dPos->second.compare(DEBUG_VALUE) == 0) {
1967         TAG_LOGI(AAFwkTag::AA_TOOL, "Set Debug to want");
1968         want.SetParam("debugApp", true);
1969     }
1970 
1971     sptr<TestObserver> observer = new (std::nothrow) TestObserver();
1972     if (!observer) {
1973         TAG_LOGE(AAFwkTag::AA_TOOL, "Failed: the TestObserver is null");
1974         return OHOS::ERR_INVALID_VALUE;
1975     }
1976 
1977     int result = AbilityManagerClient::GetInstance()->StartUserTest(want, observer->AsObject());
1978     if (result != OHOS::ERR_OK) {
1979         TAG_LOGI(AAFwkTag::AA_TOOL, "%{public}s result: %{public}d", STRING_START_USER_TEST_NG.c_str(), result);
1980         resultReceiver_ = STRING_START_USER_TEST_NG + "\n";
1981         resultReceiver_.append(GetMessageFromCode(result));
1982         return result;
1983     }
1984     TAG_LOGI(AAFwkTag::AA_TOOL, "%{public}s", STRING_USER_TEST_STARTED.c_str());
1985 
1986     std::signal(SIGCHLD, SIG_DFL);
1987 
1988     int64_t timeMs = 0;
1989     if (!want.GetStringParam("-w").empty()) {
1990         auto time = std::stoi(want.GetStringParam("-w"));
1991         timeMs = time > 0 ? time * TIME_RATE_MS : 0;
1992     }
1993     if (!observer->WaitForFinish(timeMs)) {
1994         resultReceiver_ = "Timeout: user test is not completed within the specified time.\n";
1995         return OHOS::ERR_INVALID_VALUE;
1996     }
1997 
1998     TAG_LOGI(AAFwkTag::AA_TOOL, "%{public}s", STRING_USER_TEST_FINISHED.c_str());
1999     resultReceiver_ = STRING_USER_TEST_FINISHED + "\n";
2000 
2001     return result;
2002 }
2003 
GetAbilityManagerService()2004 sptr<IAbilityManager> AbilityManagerShellCommand::GetAbilityManagerService()
2005 {
2006     sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
2007     if (systemManager == nullptr) {
2008         TAG_LOGE(AAFwkTag::AA_TOOL, "Get registry failed");
2009         return nullptr;
2010     }
2011     sptr<IRemoteObject> remoteObject = systemManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
2012     return iface_cast<IAbilityManager>(remoteObject);
2013 }
2014 
2015 #ifdef ABILITY_COMMAND_FOR_TEST
RunAsSendAppNotRespondingWithUnknownOption()2016 ErrCode AbilityManagerShellCommand::RunAsSendAppNotRespondingWithUnknownOption()
2017 {
2018     switch (optopt) {
2019         case 'h': {
2020             break;
2021         }
2022         case 'p': {
2023             TAG_LOGI(AAFwkTag::AA_TOOL, "'aa ApplicationNotResponding -p' no arg");
2024             resultReceiver_.append("error: option -p ");
2025             resultReceiver_.append("' requires a value.\n");
2026             break;
2027         }
2028         default: {
2029             std::string unknownOption;
2030             std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
2031             TAG_LOGI(AAFwkTag::AA_TOOL, "'aa ApplicationNotResponding' opt unknown");
2032             resultReceiver_.append(unknownOptionMsg);
2033             break;
2034         }
2035     }
2036     return OHOS::ERR_INVALID_VALUE;
2037 }
2038 
RunAsSendAppNotRespondingWithOption(int32_t option,std::string & pid)2039 ErrCode AbilityManagerShellCommand::RunAsSendAppNotRespondingWithOption(int32_t option, std::string& pid)
2040 {
2041     ErrCode result = ERR_OK;
2042     switch (option) {
2043         case 'h': {
2044             result = OHOS::ERR_INVALID_VALUE;
2045             break;
2046         }
2047         case 'p': {
2048             TAG_LOGI(AAFwkTag::AA_TOOL, "aa ApplicationNotResponding 'aa %{public}s'  -p process", cmd_.c_str());
2049             TAG_LOGI(AAFwkTag::AA_TOOL, "aa ApplicationNotResponding 'aa optarg:  %{public}s'", optarg);
2050             pid = optarg;
2051             TAG_LOGI(AAFwkTag::AA_TOOL, "aa ApplicationNotResponding 'aa pid:  %{public}s'", pid.c_str());
2052             break;
2053         }
2054         default: {
2055             TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s' option unknown", cmd_.c_str());
2056             result = OHOS::ERR_INVALID_VALUE;
2057             break;
2058         }
2059     }
2060     return result;
2061 }
2062 #endif
2063 #ifdef ABILITY_FAULT_AND_EXIT_TEST
CovertExitReason(std::string & cmd)2064 Reason CovertExitReason(std::string &cmd)
2065 {
2066     if (cmd.empty()) {
2067         return Reason::REASON_UNKNOWN;
2068     }
2069 
2070     if (cmd.compare("UNKNOWN") == 0) {
2071         return Reason::REASON_UNKNOWN;
2072     } else if (cmd.compare("NORMAL") == 0) {
2073         return Reason::REASON_NORMAL;
2074     } else if (cmd.compare("CPP_CRASH") == 0) {
2075         return Reason::REASON_CPP_CRASH;
2076     } else if (cmd.compare("JS_ERROR") == 0) {
2077         return Reason::REASON_JS_ERROR;
2078     } else if (cmd.compare("ABILITY_NOT_RESPONDING") == 0) {
2079         return Reason::REASON_APP_FREEZE;
2080     } else if (cmd.compare("APP_FREEZE") == 0) {
2081         return Reason::REASON_APP_FREEZE;
2082     } else if (cmd.compare("PERFORMANCE_CONTROL") == 0) {
2083         return Reason::REASON_PERFORMANCE_CONTROL;
2084     } else if (cmd.compare("RESOURCE_CONTROL") == 0) {
2085         return Reason::REASON_RESOURCE_CONTROL;
2086     } else if (cmd.compare("UPGRADE") == 0) {
2087         return Reason::REASON_UPGRADE;
2088     }
2089 
2090     return Reason::REASON_UNKNOWN;
2091 }
2092 
RunAsForceExitAppCommand()2093 ErrCode AbilityManagerShellCommand::RunAsForceExitAppCommand()
2094 {
2095     TAG_LOGD(AAFwkTag::AA_TOOL, "enter");
2096     int result = OHOS::ERR_OK;
2097 
2098     int option = -1;
2099     int counter = 0;
2100 
2101     std::string pid;
2102     std::string reason;
2103 
2104     while (true) {
2105         counter++;
2106         option = getopt_long(argc_, argv_, SHORT_OPTIONS_FORCE_EXIT_APP.c_str(), LONG_OPTIONS_FORCE_EXIT_APP, nullptr);
2107         TAG_LOGD(
2108             AAFwkTag::AA_TOOL, "option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
2109 
2110         if (optind < 0 || optind > argc_) {
2111             return OHOS::ERR_INVALID_VALUE;
2112         }
2113 
2114         if (option == -1) {
2115             if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
2116                 TAG_LOGE(AAFwkTag::AA_TOOL, "'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
2117                 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
2118                 result = OHOS::ERR_INVALID_VALUE;
2119             }
2120             break;
2121         }
2122 
2123         switch (option) {
2124             case 'h': {
2125                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -h' no arg", cmd_.c_str());
2126                 // 'aa forceexitapp -h'
2127                 // 'aa forceexitapp --help'
2128                 result = OHOS::ERR_INVALID_VALUE;
2129                 break;
2130             }
2131             case 'p': {
2132                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -p' pid", cmd_.c_str());
2133                 // 'aa forceexitapp -p pid'
2134                 pid = optarg;
2135                 break;
2136             }
2137             case 'r': {
2138                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -r' reason", cmd_.c_str());
2139                 // 'aa forceexitapp -r reason'
2140                 reason = optarg;
2141                 break;
2142             }
2143             case '?': {
2144                 std::string unknownOption = "";
2145                 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
2146                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa notifyappfault' option unknown");
2147                 resultReceiver_.append(unknownOptionMsg);
2148                 result = OHOS::ERR_INVALID_VALUE;
2149                 break;
2150             }
2151             default: {
2152                 break;
2153             }
2154         }
2155     }
2156 
2157     if (result != OHOS::ERR_OK) {
2158         result = OHOS::ERR_INVALID_VALUE;
2159     }
2160 
2161     ExitReason exitReason = { CovertExitReason(reason), "Force exit app by aa." };
2162     result = AbilityManagerClient::GetInstance()->ForceExitApp(std::stoi(pid), exitReason);
2163     if (result == OHOS::ERR_OK) {
2164         resultReceiver_ = STRING_BLOCK_AMS_SERVICE_OK + "\n";
2165     } else {
2166         TAG_LOGI(AAFwkTag::AA_TOOL, "%{public}s result: %{public}d", STRING_BLOCK_AMS_SERVICE_NG.c_str(), result);
2167         resultReceiver_ = STRING_BLOCK_AMS_SERVICE_NG + "\n";
2168         resultReceiver_.append(GetMessageFromCode(result));
2169     }
2170 
2171     TAG_LOGD(AAFwkTag::AA_TOOL, "pid: %{public}s, reason: %{public}s", pid.c_str(), reason.c_str());
2172     return result;
2173 }
2174 
CovertFaultType(std::string & cmd)2175 FaultDataType CovertFaultType(std::string &cmd)
2176 {
2177     if (cmd.empty()) {
2178         return FaultDataType::UNKNOWN;
2179     }
2180 
2181     if (cmd.compare("UNKNOWN") == 0) {
2182         return FaultDataType::UNKNOWN;
2183     } else if (cmd.compare("CPP_CRASH") == 0) {
2184         return FaultDataType::CPP_CRASH;
2185     } else if (cmd.compare("JS_ERROR") == 0) {
2186         return FaultDataType::JS_ERROR;
2187     } else if (cmd.compare("APP_FREEZE") == 0) {
2188         return FaultDataType::APP_FREEZE;
2189     } else if (cmd.compare("PERFORMANCE_CONTROL") == 0) {
2190         return FaultDataType::PERFORMANCE_CONTROL;
2191     } else if (cmd.compare("RESOURCE_CONTROL") == 0) {
2192         return FaultDataType::RESOURCE_CONTROL;
2193     }
2194 
2195     return FaultDataType::UNKNOWN;
2196 }
2197 
RunAsNotifyAppFaultCommand()2198 ErrCode AbilityManagerShellCommand::RunAsNotifyAppFaultCommand()
2199 {
2200     TAG_LOGD(AAFwkTag::AA_TOOL, "called");
2201     int result = OHOS::ERR_OK;
2202     int option = -1;
2203     int counter = 0;
2204     std::string errorName = "";
2205     std::string errorMessage = "";
2206     std::string errorStack = "";
2207     std::string faultType = "";
2208     std::string pid = "";
2209     while (true) {
2210         counter++;
2211         option = getopt_long(
2212             argc_, argv_, SHORT_OPTIONS_NOTIFY_APP_FAULT.c_str(), LONG_OPTIONS_NOTIFY_APP_FAULT, nullptr);
2213         TAG_LOGI(
2214             AAFwkTag::AA_TOOL, "option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
2215         if (optind < 0 || optind > argc_) {
2216             return OHOS::ERR_INVALID_VALUE;
2217         }
2218 
2219         if (option == -1) {
2220             if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
2221                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
2222                 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
2223                 result = OHOS::ERR_INVALID_VALUE;
2224             }
2225             break;
2226         }
2227 
2228         switch (option) {
2229             case 'h': {
2230                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -h' no arg", cmd_.c_str());
2231                 // 'aa notifyappfault -h'
2232                 // 'aa notifyappfault --help'
2233                 result = OHOS::ERR_INVALID_VALUE;
2234                 break;
2235             }
2236             case 'n': {
2237                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -n' errorName", cmd_.c_str());
2238                 // 'aa notifyappfault -n errorName'
2239                 errorName = optarg;
2240                 break;
2241             }
2242             case 'm': {
2243                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -m' errorMessage", cmd_.c_str());
2244                 // 'aa notifyappfault -m errorMessage'
2245                 errorMessage = optarg;
2246                 break;
2247             }
2248             case 's': {
2249                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -s' errorStack", cmd_.c_str());
2250                 // 'aa notifyappfault -s errorStack'
2251                 errorStack = optarg;
2252                 break;
2253             }
2254             case 't': {
2255                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -t' faultType", cmd_.c_str());
2256                 // 'aa notifyappfault -t faultType'
2257                 faultType = optarg;
2258                 break;
2259             }
2260             case 'p': {
2261                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa %{public}s -p' pid", cmd_.c_str());
2262                 // 'aa notifyappfault -p pid'
2263                 pid = optarg;
2264                 break;
2265             }
2266             case '?': {
2267                 std::string unknownOption = "";
2268                 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
2269                 TAG_LOGI(AAFwkTag::AA_TOOL, "'aa notifyappfault' option unknown");
2270                 resultReceiver_.append(unknownOptionMsg);
2271                 result = OHOS::ERR_INVALID_VALUE;
2272                 break;
2273             }
2274             default: {
2275                 break;
2276             }
2277         }
2278     }
2279 
2280     if (result != OHOS::ERR_OK) {
2281         result = OHOS::ERR_INVALID_VALUE;
2282     }
2283 
2284     TAG_LOGI(AAFwkTag::AA_TOOL,
2285         "name: %{public}s, message: %{public}s, stack: %{public}s, type: %{public}s, pid: %{public}s",
2286         errorName.c_str(), errorMessage.c_str(), errorStack.c_str(), faultType.c_str(), pid.c_str());
2287 
2288     AppFaultDataBySA faultData;
2289     faultData.errorObject.name = errorName;
2290     faultData.errorObject.message = errorMessage;
2291     faultData.errorObject.stack = errorStack;
2292     faultData.faultType = CovertFaultType(faultType);
2293     faultData.pid = std::stoi(pid);
2294     DelayedSingleton<AppMgrClient>::GetInstance()->NotifyAppFaultBySA(faultData);
2295     return result;
2296 }
2297 #endif
2298 }  // namespace AAFwk
2299 }  // namespace OHOS
2300