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