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