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 ®exScript, 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