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