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