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