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