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