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