1/* 2 * Copyright (c) 2021-2022 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 "bundle_command.h" 16 17#include <chrono> 18#include <cstdlib> 19#include <cstring> 20#include <future> 21#include <getopt.h> 22#include <unistd.h> 23#include <vector> 24#include "app_log_wrapper.h" 25#include "appexecfwk_errors.h" 26#include "bundle_command_common.h" 27#include "bundle_death_recipient.h" 28#include "bundle_mgr_client.h" 29#include "bundle_mgr_proxy.h" 30#include "clean_cache_callback_host.h" 31#include "json_serializer.h" 32#include "nlohmann/json.hpp" 33#include "parameter.h" 34#include "parameters.h" 35#include "quick_fix_command.h" 36#include "quick_fix_status_callback_host_impl.h" 37#include "status_receiver_impl.h" 38#include "string_ex.h" 39#include "app_mgr_client.h" 40#include "directory_ex.h" 41 42namespace OHOS { 43namespace AppExecFwk { 44namespace { 45const std::string BUNDLE_NAME_EMPTY = ""; 46const std::string OVERLAY_MODULE_INFOS = "overlayModuleInfos"; 47const std::string OVERLAY_BUNDLE_INFOS = "overlayBundleInfos"; 48const std::string OVERLAY_MODULE_INFO = "overlayModuleInfo"; 49const std::string SHARED_BUNDLE_INFO = "sharedBundleInfo"; 50const std::string DEPENDENCIES = "dependencies"; 51const char* IS_ROOT_MODE_PARAM = "const.debuggable"; 52const std::string IS_DEVELOPER_MODE_PARAM = "const.security.developermode.state"; 53const int32_t ROOT_MODE = 1; 54const int32_t USER_MODE = 0; 55const int32_t INDEX_OFFSET = 2; 56const int32_t MAX_WAITING_TIME = 3000; 57const int32_t DEVICE_UDID_LENGTH = 65; 58const int32_t MAX_ARGUEMENTS_NUMBER = 3; 59const int32_t MAX_OVERLAY_ARGUEMENTS_NUMBER = 8; 60const int32_t MINIMUM_WAITTING_TIME = 180; // 3 mins 61const int32_t MAXIMUM_WAITTING_TIME = 600; // 10 mins 62const int32_t INITIAL_SANDBOX_APP_INDEX = 1000; 63 64const std::string SHORT_OPTIONS_COMPILE = "hm:r:"; 65const struct option LONG_OPTIONS_COMPILE[] = { 66 {"help", no_argument, nullptr, 'h'}, 67 {"mode", required_argument, nullptr, 'm'}, 68 {"reset", required_argument, nullptr, 'r'}, 69 {nullptr, 0, nullptr, 0}, 70}; 71 72const std::string SHORT_OPTIONS_COPY_AP = "hn:a"; 73const struct option LONG_OPTIONS_COPY_AP[] = { 74 {"help", no_argument, nullptr, 'h'}, 75 {"bundle-name", required_argument, nullptr, 'n'}, 76 {"all", no_argument, nullptr, 'a'}, 77 {nullptr, 0, nullptr, 0}, 78}; 79 80const std::string SHORT_OPTIONS = "hp:rn:m:a:cdu:w:s:i:"; 81const struct option LONG_OPTIONS[] = { 82 {"help", no_argument, nullptr, 'h'}, 83 {"bundle-path", required_argument, nullptr, 'p'}, 84 {"replace", no_argument, nullptr, 'r'}, 85 {"bundle-name", required_argument, nullptr, 'n'}, 86 {"module-name", required_argument, nullptr, 'm'}, 87 {"ability-name", required_argument, nullptr, 'a'}, 88 {"bundle-info", no_argument, nullptr, 'i'}, 89 {"cache", no_argument, nullptr, 'c'}, 90 {"data", no_argument, nullptr, 'd'}, 91 {"is-removable", required_argument, nullptr, 'i'}, 92 {"user-id", required_argument, nullptr, 'u'}, 93 {"waitting-time", required_argument, nullptr, 'w'}, 94 {"keep-data", no_argument, nullptr, 'k'}, 95 {"shared-bundle-dir-path", required_argument, nullptr, 's'}, 96 {"app-index", required_argument, nullptr, 'i'}, 97 {nullptr, 0, nullptr, 0}, 98}; 99 100const std::string UNINSTALL_OPTIONS = "hn:km:u:v:s"; 101const struct option UNINSTALL_LONG_OPTIONS[] = { 102 {"help", no_argument, nullptr, 'h'}, 103 {"bundle-name", required_argument, nullptr, 'n'}, 104 {"module-name", required_argument, nullptr, 'm'}, 105 {"user-id", required_argument, nullptr, 'u'}, 106 {"keep-data", no_argument, nullptr, 'k'}, 107 {"version", required_argument, nullptr, 'v'}, 108 {"shared", no_argument, nullptr, 's'}, 109 {nullptr, 0, nullptr, 0}, 110}; 111 112const std::string SHORT_OPTIONS_DUMP = "hn:aisu:d:"; 113const struct option LONG_OPTIONS_DUMP[] = { 114 {"help", no_argument, nullptr, 'h'}, 115 {"bundle-name", required_argument, nullptr, 'n'}, 116 {"all", no_argument, nullptr, 'a'}, 117 {"bundle-info", no_argument, nullptr, 'i'}, 118 {"shortcut-info", no_argument, nullptr, 's'}, 119 {"user-id", required_argument, nullptr, 'u'}, 120 {"device-id", required_argument, nullptr, 'd'}, 121 {nullptr, 0, nullptr, 0}, 122}; 123 124const std::string SHORT_OPTIONS_GET = "hu"; 125const struct option LONG_OPTIONS_GET[] = { 126 {"help", no_argument, nullptr, 'h'}, 127 {"udid", no_argument, nullptr, 'u'}, 128 {nullptr, 0, nullptr, 0}, 129}; 130 131const std::string SHORT_OPTIONS_OVERLAY = "hb:m:t:u:"; 132const struct option LONG_OPTIONS_OVERLAY[] = { 133 {"help", no_argument, nullptr, 'h'}, 134 {"bundle-name", required_argument, nullptr, 'b'}, 135 {"module-name", required_argument, nullptr, 'm'}, 136 {"target-module-name", required_argument, nullptr, 't'}, 137 {"user-id", required_argument, nullptr, 'u'}, 138 {nullptr, 0, nullptr, 0}, 139}; 140 141const std::string SHORT_OPTIONS_OVERLAY_TARGET = "hb:m:u:"; 142const struct option LONG_OPTIONS_OVERLAY_TARGET[] = { 143 {"help", no_argument, nullptr, 'h'}, 144 {"bundle-name", required_argument, nullptr, 'b'}, 145 {"module-name", required_argument, nullptr, 'm'}, 146 {"user-id", required_argument, nullptr, 'u'}, 147 {nullptr, 0, nullptr, 0}, 148}; 149 150const std::string SHORT_OPTIONS_DUMP_SHARED_DEPENDENCIES = "hn:m:"; 151const struct option LONG_OPTIONS_DUMP_SHARED_DEPENDENCIES[] = { 152 {"help", no_argument, nullptr, 'h'}, 153 {"bundle-name", required_argument, nullptr, 'n'}, 154 {"module-name", required_argument, nullptr, 'm'}, 155 {nullptr, 0, nullptr, 0}, 156}; 157 158const std::string SHORT_OPTIONS_DUMP_SHARED = "hn:a"; 159const struct option LONG_OPTIONS_DUMP_SHARED[] = { 160 {"help", no_argument, nullptr, 'h'}, 161 {"bundle-name", required_argument, nullptr, 'n'}, 162 {"all", no_argument, nullptr, 'a'}, 163 {nullptr, 0, nullptr, 0}, 164}; 165} // namespace 166 167class CleanCacheCallbackImpl : public CleanCacheCallbackHost { 168public: 169 CleanCacheCallbackImpl() : signal_(std::make_shared<std::promise<bool>>()) 170 {} 171 ~CleanCacheCallbackImpl() override 172 {} 173 void OnCleanCacheFinished(bool error) override; 174 bool GetResultCode(); 175private: 176 std::shared_ptr<std::promise<bool>> signal_; 177 DISALLOW_COPY_AND_MOVE(CleanCacheCallbackImpl); 178}; 179 180void CleanCacheCallbackImpl::OnCleanCacheFinished(bool error) 181{ 182 if (signal_ != nullptr) { 183 signal_->set_value(error); 184 } 185} 186 187bool CleanCacheCallbackImpl::GetResultCode() 188{ 189 if (signal_ != nullptr) { 190 auto future = signal_->get_future(); 191 std::chrono::milliseconds span(MAX_WAITING_TIME); 192 if (future.wait_for(span) == std::future_status::timeout) { 193 return false; 194 } 195 return future.get(); 196 } 197 return false; 198} 199 200BundleManagerShellCommand::BundleManagerShellCommand(int argc, char *argv[]) : ShellCommand(argc, argv, TOOL_NAME) 201{} 202 203ErrCode BundleManagerShellCommand::CreateCommandMap() 204{ 205 commandMap_ = { 206 {"help", [this] { return this->RunAsHelpCommand(); } }, 207 {"install", [this] { return this->RunAsInstallCommand(); } }, 208 {"uninstall", [this] { return this->RunAsUninstallCommand(); } }, 209 {"dump", [this] { return this->RunAsDumpCommand(); } }, 210 {"clean", [this] { return this->RunAsCleanCommand(); } }, 211 {"enable", [this] { return this->RunAsEnableCommand(); } }, 212 {"disable", [this] { return this->RunAsDisableCommand(); } }, 213 {"get", [this] { return this->RunAsGetCommand(); } }, 214 {"quickfix", [this] { return this->RunAsQuickFixCommand(); } }, 215 {"compile", [this] { return this->RunAsCompileCommand(); } }, 216 {"copy-ap", [this] { return this->RunAsCopyApCommand(); } }, 217 {"dump-overlay", [this] { return this->RunAsDumpOverlay(); } }, 218 {"dump-target-overlay", [this] { return this->RunAsDumpTargetOverlay(); } }, 219 {"dump-dependencies", [this] { return this->RunAsDumpSharedDependenciesCommand(); } }, 220 {"dump-shared", [this] { return this->RunAsDumpSharedCommand(); } }, 221 }; 222 223 return OHOS::ERR_OK; 224} 225 226ErrCode BundleManagerShellCommand::CreateMessageMap() 227{ 228 messageMap_ = BundleCommandCommon::bundleMessageMap_; 229 return OHOS::ERR_OK; 230} 231 232ErrCode BundleManagerShellCommand::Init() 233{ 234 ErrCode result = OHOS::ERR_OK; 235 236 if (bundleMgrProxy_ == nullptr) { 237 bundleMgrProxy_ = BundleCommandCommon::GetBundleMgrProxy(); 238 if (bundleMgrProxy_) { 239 if (bundleInstallerProxy_ == nullptr) { 240 bundleInstallerProxy_ = bundleMgrProxy_->GetBundleInstaller(); 241 } 242 } 243 } 244 245 if ((bundleMgrProxy_ == nullptr) || (bundleInstallerProxy_ == nullptr) || 246 (bundleInstallerProxy_->AsObject() == nullptr)) { 247 result = OHOS::ERR_INVALID_VALUE; 248 } 249 250 return result; 251} 252 253ErrCode BundleManagerShellCommand::RunAsHelpCommand() 254{ 255 resultReceiver_.append(HELP_MSG); 256 257 int32_t mode = GetIntParameter(IS_ROOT_MODE_PARAM, USER_MODE); 258 APP_LOGI("current mode is: %{public}d", mode); 259 if (mode == ROOT_MODE) { 260 resultReceiver_.append(ENABLE_DISABLE_HELP_MSG); 261 } 262 263 bool isDeveloperMode = system::GetBoolParameter(IS_DEVELOPER_MODE_PARAM, false); 264 APP_LOGD("current developer mode is: %{public}d", isDeveloperMode); 265 if (mode == ROOT_MODE || isDeveloperMode) { 266 resultReceiver_.append(CLEAN_HELP_MSG); 267 } 268 269 return OHOS::ERR_OK; 270} 271 272bool BundleManagerShellCommand::IsInstallOption(int index) const 273{ 274 if (index >= argc_ || index < INDEX_OFFSET) { 275 return false; 276 } 277 if (argList_[index - INDEX_OFFSET] == "-r" || argList_[index - INDEX_OFFSET] == "--replace" || 278 argList_[index - INDEX_OFFSET] == "-p" || argList_[index - INDEX_OFFSET] == "--bundle-path" || 279 argList_[index - INDEX_OFFSET] == "-u" || argList_[index - INDEX_OFFSET] == "--user-id" || 280 argList_[index - INDEX_OFFSET] == "-w" || argList_[index - INDEX_OFFSET] == "--waitting-time" || 281 argList_[index - INDEX_OFFSET] == "-s" || argList_[index - INDEX_OFFSET] == "--shared-bundle-dir-path") { 282 return true; 283 } 284 return false; 285} 286 287ErrCode BundleManagerShellCommand::RunAsCopyApCommand() 288{ 289 int32_t mode = GetIntParameter(IS_ROOT_MODE_PARAM, USER_MODE); 290 bool isDeveloperMode = system::GetBoolParameter(IS_DEVELOPER_MODE_PARAM, false); 291 if (mode != ROOT_MODE && !isDeveloperMode) { 292 APP_LOGI("in user mode but not in developer mode"); 293 return ERR_OK; 294 } 295 APP_LOGI("begin to RunAsCopyApCommand"); 296 int result = OHOS::ERR_OK; 297 int counter = 0; 298 std::string bundleName = ""; 299 bool isAllBundle = false; 300 int32_t option; 301 while ((option = getopt_long(argc_, argv_, SHORT_OPTIONS_COPY_AP.c_str(), 302 LONG_OPTIONS_COPY_AP, nullptr)) != -1) { 303 counter++; 304 if (optind < 0 || optind > argc_) { 305 return OHOS::ERR_INVALID_VALUE; 306 } 307 result = ParseCopyApCommand(option, bundleName, isAllBundle); 308 if (option == '?') { 309 break; 310 } 311 } 312 313 if ((option == -1) && (counter == 0)) { 314 if (optind < 0 || optind > argc_) { 315 return OHOS::ERR_INVALID_VALUE; 316 } 317 if (strcmp(argv_[optind], cmd_.c_str()) == 0) { 318 // 1.'bm copy-ap' with no option: bm copy-ap 319 // 2.'bm copy-ap' with a wrong argument: bm copy-ap -xxx 320 APP_LOGD("'bm copy-ap' %{public}s", HELP_MSG_NO_OPTION.c_str()); 321 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 322 result = OHOS::ERR_INVALID_VALUE; 323 } 324 } 325 326 if (result != OHOS::ERR_OK) { 327 resultReceiver_.append(HELP_MSG_COPY_AP); 328 } else { 329 std::string copyApResult = ""; 330 copyApResult = CopyAp(bundleName, isAllBundle); 331 if (copyApResult.empty() || (copyApResult == "")) { 332 copyApResult = "parameters may be wrong\n"; 333 } 334 resultReceiver_.append(copyApResult); 335 } 336 APP_LOGI("end to RunAsCopyApCommand"); 337 return result; 338} 339 340ErrCode BundleManagerShellCommand::ParseCopyApCommand(int32_t option, std::string &bundleName, bool &isAllBundle) 341{ 342 int32_t result = OHOS::ERR_OK; 343 if (option == '?') { 344 switch (optopt) { 345 case 'n': { 346 // 'bm copy-ap -n' with no argument: bm copy-ap -n 347 // 'bm copy-ap --bundle-name' with no argument: bm copy-ap --bundle-name 348 APP_LOGD("'bm copy-ap -n' with no argument."); 349 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 350 result = OHOS::ERR_INVALID_VALUE; 351 break; 352 } 353 default: { 354 // 'bm copy-ap' with an unknown option: bm copy-ap -x 355 // 'bm copy-ap' with an unknown option: bm copy-ap -xxx 356 std::string unknownOption = ""; 357 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); 358 APP_LOGE("'bm copy-ap' with an unknown option."); 359 resultReceiver_.append(unknownOptionMsg); 360 result = OHOS::ERR_INVALID_VALUE; 361 break; 362 } 363 } 364 } else { 365 switch (option) { 366 case 'h': { 367 // 'bm copy-ap -h' 368 // 'bm copy-ap --help' 369 APP_LOGD("'bm copy-ap %{public}s'", argv_[optind - 1]); 370 result = OHOS::ERR_INVALID_VALUE; 371 break; 372 } 373 case 'a': { 374 // 'bm copy-ap -a' 375 // 'bm copy-ap --all' 376 APP_LOGD("'bm copy-ap %{public}s'", argv_[optind - 1]); 377 isAllBundle = true; 378 break; 379 } 380 case 'n': { 381 // 'bm copy-ap -n xxx' 382 // 'bm copy-ap --bundle-name xxx' 383 APP_LOGD("'bm copy-ap %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg); 384 bundleName = optarg; 385 break; 386 } 387 default: { 388 APP_LOGD("'bm copy-ap %{public}s'", argv_[optind - 1]); 389 result = OHOS::ERR_INVALID_VALUE; 390 break; 391 } 392 } 393 } 394 return result; 395} 396 397ErrCode BundleManagerShellCommand::RunAsCompileCommand() 398{ 399 APP_LOGI("begin to RunAsCompileCommand"); 400 int result = OHOS::ERR_OK; 401 int counter = 0; 402 std::string compileMode = ""; 403 std::string bundleName = ""; 404 bool bundleCompile = false; 405 bool resetCompile = false; 406 bool isAllBundle = false; 407 while (true) { 408 counter++; 409 int32_t option = getopt_long(argc_, argv_, SHORT_OPTIONS_COMPILE.c_str(), LONG_OPTIONS_COMPILE, nullptr); 410 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind); 411 if (optind < 0 || optind > argc_) { 412 return OHOS::ERR_INVALID_VALUE; 413 } 414 if (option == -1) { 415 if (counter == 1) { 416 // When scanning the first argument 417 if (strcmp(argv_[optind], cmd_.c_str()) == 0) { 418 // 'bm compile' with no option: bm compile 419 // 'bm compile' with a wrong argument: bm compile xxx 420 APP_LOGD("'bm compile' %{public}s", HELP_MSG_NO_OPTION.c_str()); 421 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 422 result = OHOS::ERR_INVALID_VALUE; 423 } 424 } 425 break; 426 } 427 if (option == '?') { 428 switch (optopt) { 429 case 'a': { 430 // 'bm compile -m' with no argument: bm compile -m 431 // 'bm compile --mode' with no argument: bm compile --mode 432 APP_LOGD("'bm compile %{public}s'", argv_[optind - 1]); 433 isAllBundle = true; 434 break; 435 } 436 default: { 437 // 'bm compile' with an unknown option: bm compile -x 438 // 'bm compile' with an unknown option: bm compile -xxx 439 std::string unknownOption = ""; 440 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); 441 APP_LOGE("'bm compile' with an unknown option."); 442 resultReceiver_.append(unknownOptionMsg); 443 result = OHOS::ERR_INVALID_VALUE; 444 break; 445 } 446 } 447 break; 448 } 449 switch (option) { 450 case 'h': { 451 // 'bm compile -h' 452 // 'bm compile --help' 453 APP_LOGD("'bm compile %{public}s'", argv_[optind - 1]); 454 result = OHOS::ERR_INVALID_VALUE; 455 break; 456 } 457 case 'm': { 458 // 'bm compile -m xxx' 459 // 'bm compile --mode xxx' 460 APP_LOGD("'bm compile %{public}s %{public}s %{public}s'", 461 argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg, argv_[optind + 1]); 462 bundleCompile = true; 463 compileMode = optarg; 464 bundleName = argv_[optind + 1]; 465 break; 466 } 467 case 'r': { 468 // 'bm compile -r xxx' 469 // 'bm compile --reset xxx' 470 APP_LOGD("'bm compile %{public}s'", argv_[optind - 1]); 471 resetCompile = true; 472 bundleName = optarg; 473 if (bundleName == "-a") { 474 isAllBundle = true; 475 } 476 break; 477 } 478 default: { 479 APP_LOGD("'bm compile %{public}s'", argv_[optind - 1]); 480 result = OHOS::ERR_INVALID_VALUE; 481 break; 482 } 483 } 484 } 485 if (result != OHOS::ERR_OK) { 486 resultReceiver_.append(HELP_MSG_COMPILE); 487 } else { 488 std::string compileResults = ""; 489 APP_LOGD("compileResults: %{public}s", compileResults.c_str()); 490 if (bundleCompile) { 491 compileResults = CompileProcessAot(bundleName, compileMode, isAllBundle); 492 } else if (resetCompile) { 493 compileResults = CompileReset(bundleName, isAllBundle); 494 } 495 if (compileResults.empty() || (compileResults == "")) { 496 compileResults = HELP_MSG_COMPILE_FAILED + "\n"; 497 } 498 resultReceiver_.append(compileResults); 499 } 500 APP_LOGI("end"); 501 return result; 502} 503 504ErrCode BundleManagerShellCommand::RunAsInstallCommand() 505{ 506 APP_LOGI("begin to RunAsInstallCommand"); 507 int result = OHOS::ERR_OK; 508 InstallFlag installFlag = InstallFlag::REPLACE_EXISTING; 509 int counter = 0; 510 std::vector<std::string> bundlePath; 511 std::vector<std::string> sharedBundleDirPaths; 512 int index = 0; 513 int hspIndex = 0; 514 int32_t userId = BundleCommandCommon::GetCurrentUserId(Constants::UNSPECIFIED_USERID); 515 int32_t waittingTime = MINIMUM_WAITTING_TIME; 516 while (true) { 517 counter++; 518 int32_t option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr); 519 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind); 520 if (optind < 0 || optind > argc_) { 521 return OHOS::ERR_INVALID_VALUE; 522 } 523 if (option == -1) { 524 if (counter == 1) { 525 // When scanning the first argument 526 if (strcmp(argv_[optind], cmd_.c_str()) == 0) { 527 // 'bm install' with no option: bm install 528 // 'bm install' with a wrong argument: bm install xxx 529 APP_LOGD("'bm install' with no option."); 530 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 531 result = OHOS::ERR_INVALID_VALUE; 532 } 533 } 534 break; 535 } 536 537 if (option == '?') { 538 switch (optopt) { 539 case 'p': { 540 // 'bm install -p' with no argument: bm install -p 541 // 'bm install --bundle-path' with no argument: bm install --bundle-path 542 APP_LOGD("'bm install' with no argument."); 543 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 544 result = OHOS::ERR_INVALID_VALUE; 545 break; 546 } 547 case 'u': { 548 // 'bm install -u' with no argument: bm install -u 549 // 'bm install --user-id' with no argument: bm install --user-id 550 APP_LOGD("'bm install -u' with no argument."); 551 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 552 result = OHOS::ERR_INVALID_VALUE; 553 break; 554 } 555 case 'w': { 556 // 'bm install -w' with no argument: bm install -w 557 // 'bm install --waitting-time' with no argument: bm install --waitting-time 558 APP_LOGD("'bm install -w' with no argument."); 559 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 560 result = OHOS::ERR_INVALID_VALUE; 561 break; 562 } 563 default: { 564 // 'bm install' with an unknown option: bm install -x 565 // 'bm install' with an unknown option: bm install -xxx 566 std::string unknownOption = ""; 567 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); 568 APP_LOGD("'bm install' with an unknown option."); 569 resultReceiver_.append(unknownOptionMsg); 570 result = OHOS::ERR_INVALID_VALUE; 571 break; 572 } 573 } 574 break; 575 } 576 577 switch (option) { 578 case 'h': { 579 // 'bm install -h' 580 // 'bm install --help' 581 APP_LOGD("'bm install %{public}s'", argv_[optind - 1]); 582 result = OHOS::ERR_INVALID_VALUE; 583 break; 584 } 585 case 'p': { 586 // 'bm install -p <bundle-file-path>' 587 // 'bm install --bundle-path <bundle-file-path>' 588 APP_LOGD("'bm install %{public}s'", argv_[optind - 1]); 589 if (GetBundlePath(optarg, bundlePath) != OHOS::ERR_OK) { 590 APP_LOGD("'bm install' with no argument."); 591 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 592 return OHOS::ERR_INVALID_VALUE; 593 } 594 index = optind; 595 break; 596 } 597 case 'r': { 598 // 'bm install -r' 599 // 'bm install --replace' 600 installFlag = InstallFlag::REPLACE_EXISTING; 601 break; 602 } 603 case 'u': { 604 // 'bm install -p <bundle-file-path> -u userId' 605 // 'bm install --bundle-path <bundle-file-path> --user-id userId' 606 APP_LOGW("'bm install -u only support user 0'"); 607 if (!OHOS::StrToInt(optarg, userId) || userId < 0) { 608 APP_LOGE("bm install with error userId %{private}s", optarg); 609 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 610 return OHOS::ERR_INVALID_VALUE; 611 } 612 if (userId != Constants::DEFAULT_USERID) { 613 userId = BundleCommandCommon::GetCurrentUserId(Constants::UNSPECIFIED_USERID); 614 } 615 break; 616 } 617 case 'w': { 618 APP_LOGD("'bm install %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg); 619 if (!OHOS::StrToInt(optarg, waittingTime) || waittingTime < MINIMUM_WAITTING_TIME || 620 waittingTime > MAXIMUM_WAITTING_TIME) { 621 APP_LOGE("bm install with error waittingTime %{private}s", optarg); 622 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 623 return OHOS::ERR_INVALID_VALUE; 624 } 625 break; 626 } 627 case 's': { 628 // 'bm install -s <hsp-dir-path>' 629 // 'bm install --shared-bundle-dir-path <hsp-dir-path>' 630 APP_LOGD("'bm install %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg); 631 if (GetBundlePath(optarg, sharedBundleDirPaths) != OHOS::ERR_OK) { 632 APP_LOGD("'bm install -s' with no argument."); 633 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 634 return OHOS::ERR_INVALID_VALUE; 635 } 636 hspIndex = optind; 637 break; 638 } 639 default: { 640 result = OHOS::ERR_INVALID_VALUE; 641 break; 642 } 643 } 644 } 645 646 for (; index < argc_ && index >= INDEX_OFFSET; ++index) { 647 if (IsInstallOption(index)) { 648 break; 649 } 650 if (GetBundlePath(argList_[index - INDEX_OFFSET], bundlePath) != OHOS::ERR_OK) { 651 bundlePath.clear(); 652 APP_LOGD("'bm install' with error arguments."); 653 resultReceiver_.append("error value for the chosen option"); 654 result = OHOS::ERR_INVALID_VALUE; 655 } 656 } 657 658 // hsp list 659 for (; hspIndex < argc_ && hspIndex >= INDEX_OFFSET; ++hspIndex) { 660 if (IsInstallOption(hspIndex)) { 661 break; 662 } 663 if (GetBundlePath(argList_[hspIndex - INDEX_OFFSET], sharedBundleDirPaths) != OHOS::ERR_OK) { 664 sharedBundleDirPaths.clear(); 665 APP_LOGD("'bm install -s' with error arguments."); 666 resultReceiver_.append("error value for the chosen option"); 667 result = OHOS::ERR_INVALID_VALUE; 668 } 669 } 670 671 for (auto &path : bundlePath) { 672 APP_LOGD("install hap path %{private}s", path.c_str()); 673 } 674 675 for (auto &path : sharedBundleDirPaths) { 676 APP_LOGD("install hsp path %{private}s", path.c_str()); 677 } 678 679 if (result == OHOS::ERR_OK) { 680 if (resultReceiver_ == "" && bundlePath.empty() && sharedBundleDirPaths.empty()) { 681 // 'bm install ...' with no bundle path option 682 APP_LOGD("'bm install' with no bundle path option."); 683 resultReceiver_.append(HELP_MSG_NO_BUNDLE_PATH_OPTION + "\n"); 684 result = OHOS::ERR_INVALID_VALUE; 685 } 686 } 687 688 if (result != OHOS::ERR_OK) { 689 resultReceiver_.append(HELP_MSG_INSTALL); 690 } else { 691 InstallParam installParam; 692 installParam.installFlag = installFlag; 693 installParam.userId = userId; 694 installParam.sharedBundleDirPaths = sharedBundleDirPaths; 695 std::string resultMsg; 696 int32_t installResult = InstallOperation(bundlePath, installParam, waittingTime, resultMsg); 697 if (installResult == OHOS::ERR_OK) { 698 resultReceiver_ = STRING_INSTALL_BUNDLE_OK + "\n"; 699 } else { 700 resultReceiver_ = STRING_INSTALL_BUNDLE_NG + "\n"; 701 resultReceiver_.append(GetMessageFromCode(installResult)); 702 if (!resultMsg.empty() && resultMsg[0] != '[') { 703 resultReceiver_.append(resultMsg + "\n"); 704 } 705 } 706 } 707 APP_LOGI("end"); 708 return result; 709} 710 711ErrCode BundleManagerShellCommand::GetBundlePath(const std::string& param, 712 std::vector<std::string>& bundlePaths) const 713{ 714 if (param.empty()) { 715 return OHOS::ERR_INVALID_VALUE; 716 } 717 if (param == "-r" || param == "--replace" || param == "-p" || 718 param == "--bundle-path" || param == "-u" || param == "--user-id" || 719 param == "-w" || param == "--waitting-time") { 720 return OHOS::ERR_INVALID_VALUE; 721 } 722 bundlePaths.emplace_back(param); 723 return OHOS::ERR_OK; 724} 725 726ErrCode BundleManagerShellCommand::RunAsUninstallCommand() 727{ 728 APP_LOGI("begin to RunAsUninstallCommand"); 729 int result = OHOS::ERR_OK; 730 int counter = 0; 731 std::string bundleName = ""; 732 std::string moduleName = ""; 733 int32_t userId = BundleCommandCommon::GetCurrentUserId(Constants::UNSPECIFIED_USERID); 734 bool isKeepData = false; 735 bool isShared = false; 736 int32_t versionCode = Constants::ALL_VERSIONCODE; 737 while (true) { 738 counter++; 739 int32_t option = getopt_long(argc_, argv_, UNINSTALL_OPTIONS.c_str(), UNINSTALL_LONG_OPTIONS, nullptr); 740 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind); 741 if (optind < 0 || optind > argc_) { 742 return OHOS::ERR_INVALID_VALUE; 743 } 744 if (option == -1) { 745 if (counter == 1) { 746 // When scanning the first argument 747 if (strcmp(argv_[optind], cmd_.c_str()) == 0) { 748 // 'bm uninstall' with no option: bm uninstall 749 // 'bm uninstall' with a wrong argument: bm uninstall xxx 750 APP_LOGD("'bm uninstall' %{public}s", HELP_MSG_NO_OPTION.c_str()); 751 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 752 result = OHOS::ERR_INVALID_VALUE; 753 } 754 } 755 break; 756 } 757 758 if (option == '?') { 759 switch (optopt) { 760 case 'n': { 761 // 'bm uninstall -n' with no argument: bm uninstall -n 762 // 'bm uninstall --bundle-name' with no argument: bm uninstall --bundle-name 763 APP_LOGD("'bm uninstall -n' with no argument."); 764 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 765 result = OHOS::ERR_INVALID_VALUE; 766 break; 767 } 768 case 'm': { 769 // 'bm uninstall -m' with no argument: bm uninstall -m 770 // 'bm uninstall --module-name' with no argument: bm uninstall --module-name 771 APP_LOGD("'bm uninstall -m' with no argument."); 772 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 773 result = OHOS::ERR_INVALID_VALUE; 774 break; 775 } 776 case 'u': { 777 // 'bm uninstall -n <bundleName> -u userId' 778 // 'bm uninstall --bundle-name <bundleName> --user-id userId' 779 APP_LOGD("'bm uninstall -u' with no argument."); 780 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 781 result = OHOS::ERR_INVALID_VALUE; 782 break; 783 } 784 case 'k': { 785 // 'bm uninstall -n <bundleName> -k' 786 // 'bm uninstall --bundle-name <bundleName> --keep-data' 787 APP_LOGD("'bm uninstall -k'"); 788 isKeepData = true; 789 break; 790 } 791 case 's': { 792 APP_LOGD("'bm uninstall -s'"); 793 isShared = true; 794 break; 795 } 796 case 'v': { 797 APP_LOGD("'bm uninstall -v'"); 798 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 799 result = OHOS::ERR_INVALID_VALUE; 800 break; 801 } 802 default: { 803 // 'bm uninstall' with an unknown option: bm uninstall -x 804 // 'bm uninstall' with an unknown option: bm uninstall -xxx 805 std::string unknownOption = ""; 806 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); 807 APP_LOGD("'bm uninstall' with an unknown option."); 808 resultReceiver_.append(unknownOptionMsg); 809 result = OHOS::ERR_INVALID_VALUE; 810 break; 811 } 812 } 813 break; 814 } 815 816 switch (option) { 817 case 'h': { 818 // 'bm uninstall -h' 819 // 'bm uninstall --help' 820 APP_LOGD("'bm uninstall %{public}s'", argv_[optind - 1]); 821 result = OHOS::ERR_INVALID_VALUE; 822 break; 823 } 824 case 'n': { 825 // 'bm uninstall -n xxx' 826 // 'bm uninstall --bundle-name xxx' 827 APP_LOGD("'bm uninstall %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg); 828 bundleName = optarg; 829 break; 830 } 831 case 'm': { 832 // 'bm uninstall -m xxx' 833 // 'bm uninstall --module-name xxx' 834 APP_LOGD("'bm uninstall %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg); 835 moduleName = optarg; 836 break; 837 } 838 case 'u': { 839 // 'bm uninstall -n <bundleName> -u userId' 840 // 'bm uninstall --bundle-name <bundleName> --user-id userId' 841 APP_LOGW("'bm uninstall -u only support user 0'"); 842 if (!OHOS::StrToInt(optarg, userId) || userId < 0) { 843 APP_LOGE("bm uninstall with error userId %{private}s", optarg); 844 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 845 return OHOS::ERR_INVALID_VALUE; 846 } 847 if (userId != Constants::DEFAULT_USERID) { 848 userId = BundleCommandCommon::GetCurrentUserId(Constants::UNSPECIFIED_USERID); 849 } 850 break; 851 } 852 case 'k': { 853 // 'bm uninstall -n <bundleName> -k' 854 // 'bm uninstall --bundle-name <bundleName> --keep-data' 855 APP_LOGD("'bm uninstall %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT]); 856 isKeepData = true; 857 break; 858 } 859 case 's': { 860 APP_LOGD("'bm uninstall -s'"); 861 isShared = true; 862 break; 863 } 864 case 'v': { 865 APP_LOGD("'bm uninstall %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg); 866 if (!OHOS::StrToInt(optarg, versionCode) || versionCode < 0) { 867 APP_LOGE("bm uninstall with error versionCode %{private}s", optarg); 868 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 869 return OHOS::ERR_INVALID_VALUE; 870 } 871 break; 872 } 873 default: { 874 result = OHOS::ERR_INVALID_VALUE; 875 break; 876 } 877 } 878 } 879 880 if (result == OHOS::ERR_OK) { 881 if (resultReceiver_ == "" && bundleName.size() == 0) { 882 // 'bm uninstall ...' with no bundle name option 883 APP_LOGD("'bm uninstall' with bundle name option."); 884 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n"); 885 result = OHOS::ERR_INVALID_VALUE; 886 } 887 } 888 if (result != OHOS::ERR_OK) { 889 resultReceiver_.append(HELP_MSG_UNINSTALL); 890 return result; 891 } 892 893 if (isShared) { 894 UninstallParam uninstallParam; 895 uninstallParam.bundleName = bundleName; 896 uninstallParam.versionCode = versionCode; 897 APP_LOGE("version code is %{public}d", versionCode); 898 int32_t uninstallResult = UninstallSharedOperation(uninstallParam); 899 if (uninstallResult == OHOS::ERR_OK) { 900 resultReceiver_ = STRING_UNINSTALL_BUNDLE_OK + "\n"; 901 } else { 902 resultReceiver_ = STRING_UNINSTALL_BUNDLE_NG + "\n"; 903 resultReceiver_.append(GetMessageFromCode(uninstallResult)); 904 } 905 } else { 906 InstallParam installParam; 907 installParam.userId = userId; 908 installParam.isKeepData = isKeepData; 909 int32_t uninstallResult = UninstallOperation(bundleName, moduleName, installParam); 910 if (uninstallResult == OHOS::ERR_OK) { 911 resultReceiver_ = STRING_UNINSTALL_BUNDLE_OK + "\n"; 912 } else { 913 resultReceiver_ = STRING_UNINSTALL_BUNDLE_NG + "\n"; 914 resultReceiver_.append(GetMessageFromCode(uninstallResult)); 915 } 916 } 917 APP_LOGI("end"); 918 return result; 919} 920 921ErrCode BundleManagerShellCommand::RunAsDumpCommand() 922{ 923 APP_LOGI("begin to RunAsDumpCommand"); 924 int result = OHOS::ERR_OK; 925 int counter = 0; 926 std::string bundleName = ""; 927 bool bundleDumpAll = false; 928 bool bundleDumpInfo = false; 929 bool bundleDumpShortcut = false; 930 bool bundleDumpDistributedBundleInfo = false; 931 std::string deviceId = ""; 932 int32_t userId = BundleCommandCommon::GetCurrentUserId(Constants::UNSPECIFIED_USERID); 933 while (true) { 934 counter++; 935 int32_t option = getopt_long(argc_, argv_, SHORT_OPTIONS_DUMP.c_str(), LONG_OPTIONS_DUMP, nullptr); 936 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind); 937 if (optind < 0 || optind > argc_) { 938 return OHOS::ERR_INVALID_VALUE; 939 } 940 if (option == -1) { 941 if (counter == 1) { 942 // When scanning the first argument 943 if (strcmp(argv_[optind], cmd_.c_str()) == 0) { 944 // 'bm dump' with no option: bm dump 945 // 'bm dump' with a wrong argument: bm dump xxx 946 APP_LOGD("'bm dump' %{public}s", HELP_MSG_NO_OPTION.c_str()); 947 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 948 result = OHOS::ERR_INVALID_VALUE; 949 } 950 } 951 break; 952 } 953 if (option == '?') { 954 switch (optopt) { 955 case 'n': { 956 // 'bm dump -n' with no argument: bm dump -n 957 // 'bm dump --bundle-name' with no argument: bm dump --bundle-name 958 APP_LOGD("'bm dump -n' with no argument."); 959 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 960 result = OHOS::ERR_INVALID_VALUE; 961 break; 962 } 963 case 'u': { 964 // 'bm dump -u' with no argument: bm dump -u 965 // 'bm dump --user-id' with no argument: bm dump --user-id 966 APP_LOGD("'bm dump -u' with no argument."); 967 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 968 result = OHOS::ERR_INVALID_VALUE; 969 break; 970 } 971 case 'd': { 972 // 'bm dump -d' with no argument: bm dump -d 973 // 'bm dump --device-id' with no argument: bm dump --device-id 974 APP_LOGD("'bm dump -d' with no argument."); 975 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 976 result = OHOS::ERR_INVALID_VALUE; 977 break; 978 } 979 default: { 980 // 'bm dump' with an unknown option: bm dump -x 981 // 'bm dump' with an unknown option: bm dump -xxx 982 std::string unknownOption = ""; 983 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); 984 APP_LOGD("'bm dump' with an unknown option."); 985 resultReceiver_.append(unknownOptionMsg); 986 result = OHOS::ERR_INVALID_VALUE; 987 break; 988 } 989 } 990 break; 991 } 992 switch (option) { 993 case 'h': { 994 // 'bm dump -h' 995 // 'bm dump --help' 996 APP_LOGD("'bm dump %{public}s'", argv_[optind - 1]); 997 result = OHOS::ERR_INVALID_VALUE; 998 break; 999 } 1000 case 'a': { 1001 // 'bm dump -a' 1002 // 'bm dump --all' 1003 APP_LOGD("'bm dump %{public}s'", argv_[optind - 1]); 1004 bundleDumpAll = true; 1005 break; 1006 } 1007 case 'n': { 1008 // 'bm dump -n xxx' 1009 // 'bm dump --bundle-name xxx' 1010 APP_LOGD("'bm dump %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg); 1011 bundleName = optarg; 1012 bundleDumpInfo = true; 1013 break; 1014 } 1015 case 's': { 1016 // 'bm dump -n xxx -s' 1017 // 'bm dump --bundle-name xxx --shortcut-info' 1018 APP_LOGD("'bm dump %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg); 1019 bundleDumpShortcut = true; 1020 break; 1021 } 1022 case 'u': { 1023 // 'bm dump -n <bundleName> -u userId' 1024 // 'bm dump --bundle-name <bundleName> --user-id userId' 1025 APP_LOGW("'bm dump -u is not supported'"); 1026 break; 1027 } 1028 case 'd': { 1029 // 'bm dump -n <bundleName> -d deviceId' 1030 // 'bm dump --bundle-name <bundleName> --device-id deviceId' 1031 APP_LOGD("'bm dump %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg); 1032 deviceId = optarg; 1033 bundleDumpDistributedBundleInfo = true; 1034 break; 1035 } 1036 default: { 1037 result = OHOS::ERR_INVALID_VALUE; 1038 break; 1039 } 1040 } 1041 } 1042 if (result == OHOS::ERR_OK) { 1043 if ((resultReceiver_ == "") && bundleDumpShortcut && (bundleName.size() == 0)) { 1044 // 'bm dump -s ...' with no bundle name option 1045 APP_LOGD("'bm dump -s' with no bundle name option."); 1046 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n"); 1047 result = OHOS::ERR_INVALID_VALUE; 1048 } 1049 if ((resultReceiver_ == "") && bundleDumpDistributedBundleInfo && (bundleName.size() == 0)) { 1050 // 'bm dump d ...' with no bundle name option 1051 APP_LOGD("'bm dump -d' with no bundle name option."); 1052 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n"); 1053 result = OHOS::ERR_INVALID_VALUE; 1054 } 1055 } 1056 if (result != OHOS::ERR_OK) { 1057 resultReceiver_.append(HELP_MSG_DUMP); 1058 } else { 1059 std::string dumpResults = ""; 1060 APP_LOGD("dumpResults: %{public}s", dumpResults.c_str()); 1061 if (bundleDumpShortcut) { 1062 dumpResults = DumpShortcutInfos(bundleName, userId); 1063 } else if (bundleDumpDistributedBundleInfo) { 1064 dumpResults = DumpDistributedBundleInfo(deviceId, bundleName); 1065 } else if (bundleDumpAll) { 1066 dumpResults = DumpBundleList(userId); 1067 } else if (bundleDumpInfo) { 1068 dumpResults = DumpBundleInfo(bundleName, userId); 1069 } 1070 if (dumpResults.empty() || (dumpResults == "")) { 1071 dumpResults = HELP_MSG_DUMP_FAILED + "\n"; 1072 } 1073 resultReceiver_.append(dumpResults); 1074 } 1075 APP_LOGI("end"); 1076 return result; 1077} 1078 1079ErrCode BundleManagerShellCommand::RunAsCleanCommand() 1080{ 1081 int32_t mode = GetIntParameter(IS_ROOT_MODE_PARAM, USER_MODE); 1082 bool isDeveloperMode = system::GetBoolParameter(IS_DEVELOPER_MODE_PARAM, false); 1083 if (mode != ROOT_MODE && !isDeveloperMode) { 1084 APP_LOGI("in user mode but not in developer mode"); 1085 return ERR_OK; 1086 } 1087 1088 APP_LOGI("begin to RunAsCleanCommand"); 1089 int32_t result = OHOS::ERR_OK; 1090 int32_t counter = 0; 1091 int32_t userId = BundleCommandCommon::GetCurrentUserId(Constants::UNSPECIFIED_USERID); 1092 int32_t appIndex = 0; 1093 bool cleanCache = false; 1094 bool cleanData = false; 1095 std::string bundleName = ""; 1096 while (true) { 1097 counter++; 1098 int32_t option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr); 1099 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind); 1100 if (optind < 0 || optind > argc_) { 1101 return OHOS::ERR_INVALID_VALUE; 1102 } 1103 if (option == -1) { 1104 if (counter == 1) { 1105 // When scanning the first argument 1106 if (strcmp(argv_[optind], cmd_.c_str()) == 0) { 1107 // 'bm clean' with no option: bm clean 1108 // 'bm clean' with a wrong argument: bm clean xxx 1109 APP_LOGD("'bm clean' %{public}s", HELP_MSG_NO_OPTION.c_str()); 1110 1111 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 1112 result = OHOS::ERR_INVALID_VALUE; 1113 } 1114 } 1115 break; 1116 } 1117 1118 if (option == '?') { 1119 switch (optopt) { 1120 case 'n': { 1121 // 'bm clean -n' with no argument: bm clean -n 1122 // 'bm clean --bundle-name' with no argument: bm clean --bundle-name 1123 APP_LOGD("'bm clean -n' with no argument."); 1124 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1125 result = OHOS::ERR_INVALID_VALUE; 1126 break; 1127 } 1128 case 'u': { 1129 // 'bm clean -u' with no argument: bm clean -u 1130 // 'bm clean --user-id' with no argument: bm clean --user-id 1131 APP_LOGD("'bm clean -u' with no argument."); 1132 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1133 result = OHOS::ERR_INVALID_VALUE; 1134 break; 1135 } 1136 case 'i': { 1137 // 'bm clean -i' with no argument: bm clean -i 1138 // 'bm clean --app-index' with no argument: bm clean --app-index 1139 APP_LOGD("'bm clean -i' with no argument."); 1140 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1141 result = OHOS::ERR_INVALID_VALUE; 1142 break; 1143 } 1144 default: { 1145 // 'bm clean' with an unknown option: bm clear -x 1146 // 'bm clean' with an unknown option: bm clear -xxx 1147 std::string unknownOption = ""; 1148 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); 1149 APP_LOGD("'bm clean' with an unknown option."); 1150 resultReceiver_.append(unknownOptionMsg); 1151 result = OHOS::ERR_INVALID_VALUE; 1152 break; 1153 } 1154 } 1155 break; 1156 } 1157 1158 switch (option) { 1159 case 'h': { 1160 // 'bm clean -h' 1161 // 'bm clean --help' 1162 APP_LOGD("'bm clean %{public}s'", argv_[optind - 1]); 1163 result = OHOS::ERR_INVALID_VALUE; 1164 break; 1165 } 1166 case 'n': { 1167 // 'bm clean -n xxx' 1168 // 'bm clean --bundle-name xxx' 1169 APP_LOGD("'bm clean %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg); 1170 bundleName = optarg; 1171 break; 1172 } 1173 case 'c': { 1174 // 'bm clean -c' 1175 // 'bm clean --cache' 1176 APP_LOGD("'bm clean %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT]); 1177 cleanCache = cleanData ? false : true; 1178 break; 1179 } 1180 case 'd': { 1181 // 'bm clean -d' 1182 // 'bm clean --data' 1183 APP_LOGD("'bm clean %{public}s '", argv_[optind - OFFSET_REQUIRED_ARGUMENT]); 1184 cleanData = cleanCache ? false : true; 1185 break; 1186 } 1187 case 'u': { 1188 // 'bm clean -u userId' 1189 // 'bm clean --user-id userId' 1190 APP_LOGW("'bm clean -u is not supported'"); 1191 break; 1192 } 1193 case 'i': { 1194 if (!OHOS::StrToInt(optarg, appIndex) || (appIndex < 0 || appIndex > INITIAL_SANDBOX_APP_INDEX)) { 1195 APP_LOGE("bm clean with error appIndex %{private}s", optarg); 1196 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1197 return OHOS::ERR_INVALID_VALUE; 1198 } 1199 break; 1200 } 1201 default: { 1202 result = OHOS::ERR_INVALID_VALUE; 1203 break; 1204 } 1205 } 1206 } 1207 1208 if (result == OHOS::ERR_OK) { 1209 if (resultReceiver_ == "" && bundleName.size() == 0) { 1210 // 'bm clean ...' with no bundle name option 1211 APP_LOGD("'bm clean' with no bundle name option."); 1212 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n"); 1213 result = OHOS::ERR_INVALID_VALUE; 1214 } 1215 if (!cleanCache && !cleanData) { 1216 APP_LOGD("'bm clean' with no '-c' or '-d' option."); 1217 resultReceiver_.append(HELP_MSG_NO_DATA_OR_CACHE_OPTION + "\n"); 1218 result = OHOS::ERR_INVALID_VALUE; 1219 } 1220 } 1221 1222 if (result != OHOS::ERR_OK) { 1223 resultReceiver_.append(HELP_MSG_CLEAN); 1224 } else { 1225 // bm clean -c 1226 if (cleanCache) { 1227 if (CleanBundleCacheFilesOperation(bundleName, userId, appIndex)) { 1228 resultReceiver_ = STRING_CLEAN_CACHE_BUNDLE_OK + "\n"; 1229 } else { 1230 resultReceiver_ = STRING_CLEAN_CACHE_BUNDLE_NG + "\n"; 1231 } 1232 } 1233 // bm clean -d 1234 if (cleanData) { 1235 if (CleanBundleDataFilesOperation(bundleName, userId, appIndex)) { 1236 resultReceiver_.append(STRING_CLEAN_DATA_BUNDLE_OK + "\n"); 1237 } else { 1238 resultReceiver_.append(STRING_CLEAN_DATA_BUNDLE_NG + "\n"); 1239 } 1240 } 1241 } 1242 APP_LOGI("end"); 1243 return result; 1244} 1245 1246ErrCode BundleManagerShellCommand::RunAsEnableCommand() 1247{ 1248 int32_t mode = GetIntParameter(IS_ROOT_MODE_PARAM, USER_MODE); 1249 if (mode != ROOT_MODE) { 1250 APP_LOGI("in user mode"); 1251 return ERR_OK; 1252 } 1253 APP_LOGI("begin to RunAsEnableCommand"); 1254 int result = OHOS::ERR_OK; 1255 int counter = 0; 1256 std::string bundleName = ""; 1257 std::string abilityName = ""; 1258 int32_t userId = BundleCommandCommon::GetCurrentUserId(Constants::UNSPECIFIED_USERID); 1259 while (true) { 1260 counter++; 1261 int32_t option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr); 1262 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind); 1263 if (optind < 0 || optind > argc_) { 1264 return OHOS::ERR_INVALID_VALUE; 1265 } 1266 1267 if (option == -1) { 1268 if (counter == 1) { 1269 // When scanning the first argument 1270 if (strcmp(argv_[optind], cmd_.c_str()) == 0) { 1271 // 'bm enable' with no option: bm enable 1272 // 'bm enable' with a wrong argument: bm enable xxx 1273 APP_LOGD("'bm enable' with no option."); 1274 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 1275 result = OHOS::ERR_INVALID_VALUE; 1276 } 1277 } 1278 break; 1279 } 1280 1281 if (option == '?') { 1282 switch (optopt) { 1283 case 'n': { 1284 // 'bm enable -n' with no argument: bm enable -n 1285 // 'bm enable --bundle-name' with no argument: bm enable --bundle-name 1286 APP_LOGD("'bm enable -n' with no argument."); 1287 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1288 result = OHOS::ERR_INVALID_VALUE; 1289 break; 1290 } 1291 case 'a': { 1292 // 'bm enable -a' with no argument: bm enable -a 1293 // 'bm enable --ability-name' with no argument: bm enable --ability-name 1294 APP_LOGD("'bm enable -a' with no argument."); 1295 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1296 result = OHOS::ERR_INVALID_VALUE; 1297 break; 1298 } 1299 case 'u': { 1300 // 'bm enable -u' with no argument: bm enable -u 1301 // 'bm enable --user-id' with no argument: bm enable --user-id 1302 APP_LOGD("'bm enable -u' with no argument."); 1303 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1304 result = OHOS::ERR_INVALID_VALUE; 1305 break; 1306 } 1307 default: { 1308 // 'bm enable' with an unknown option: bm enable -x 1309 // 'bm enable' with an unknown option: bm enable -xxx 1310 std::string unknownOption = ""; 1311 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); 1312 APP_LOGD("'bm enable' with an unknown option."); 1313 resultReceiver_.append(unknownOptionMsg); 1314 result = OHOS::ERR_INVALID_VALUE; 1315 break; 1316 } 1317 } 1318 break; 1319 } 1320 1321 switch (option) { 1322 case 'h': { 1323 // 'bm enable-h' 1324 // 'bm enable --help' 1325 APP_LOGD("'bm enable %{public}s'", argv_[optind - 1]); 1326 result = OHOS::ERR_INVALID_VALUE; 1327 break; 1328 } 1329 case 'n': { 1330 // 'bm enable -n <bundle-name>' 1331 // 'bm enable --bundle-name <bundle-name>' 1332 bundleName = optarg; 1333 break; 1334 } 1335 case 'a': { 1336 // 'bm enable -a <ability-name>' 1337 // 'bm enable --ability-name <ability-name>' 1338 abilityName = optarg; 1339 break; 1340 } 1341 case 'u': { 1342 // 'bm enable -u userId' 1343 // 'bm enable --user-id userId' 1344 APP_LOGW("'bm enable -u is not supported'"); 1345 break; 1346 } 1347 default: { 1348 result = OHOS::ERR_INVALID_VALUE; 1349 break; 1350 } 1351 } 1352 } 1353 1354 if (result == OHOS::ERR_OK) { 1355 if (resultReceiver_ == "" && bundleName.size() == 0) { 1356 // 'bm enable ...' with no bundle name option 1357 APP_LOGD("'bm enable' with no bundle name option."); 1358 1359 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n"); 1360 result = OHOS::ERR_INVALID_VALUE; 1361 } 1362 } 1363 1364 if (result != OHOS::ERR_OK) { 1365 resultReceiver_.append(HELP_MSG_ENABLE); 1366 } else { 1367 AbilityInfo abilityInfo; 1368 abilityInfo.name = abilityName; 1369 abilityInfo.bundleName = bundleName; 1370 bool enableResult = SetApplicationEnabledOperation(abilityInfo, true, userId); 1371 if (enableResult) { 1372 resultReceiver_ = STRING_ENABLE_BUNDLE_OK + "\n"; 1373 } else { 1374 resultReceiver_ = STRING_ENABLE_BUNDLE_NG + "\n"; 1375 } 1376 } 1377 APP_LOGI("end"); 1378 return result; 1379} 1380 1381ErrCode BundleManagerShellCommand::RunAsDisableCommand() 1382{ 1383 int32_t mode = GetIntParameter(IS_ROOT_MODE_PARAM, USER_MODE); 1384 if (mode != ROOT_MODE) { 1385 APP_LOGI("in user mode"); 1386 return ERR_OK; 1387 } 1388 APP_LOGI("begin to RunAsDisableCommand"); 1389 int result = OHOS::ERR_OK; 1390 int counter = 0; 1391 std::string bundleName = ""; 1392 std::string abilityName = ""; 1393 int32_t userId = BundleCommandCommon::GetCurrentUserId(Constants::UNSPECIFIED_USERID); 1394 while (true) { 1395 counter++; 1396 int32_t option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr); 1397 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind); 1398 if (optind < 0 || optind > argc_) { 1399 return OHOS::ERR_INVALID_VALUE; 1400 } 1401 if (option == -1) { 1402 if (counter == 1) { 1403 // When scanning the first argument 1404 if (strcmp(argv_[optind], cmd_.c_str()) == 0) { 1405 // 'bm disable' with no option: bm disable 1406 // 'bm disable' with a wrong argument: bm disable xxx 1407 APP_LOGD("'bm disable' with no option."); 1408 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 1409 result = OHOS::ERR_INVALID_VALUE; 1410 } 1411 } 1412 break; 1413 } 1414 if (option == '?') { 1415 switch (optopt) { 1416 case 'n': { 1417 // 'bm disable -n' with no argument: bm disable -n 1418 // 'bm disable --bundle-name' with no argument: bm disable --bundle-name 1419 APP_LOGD("'bm disable' with no argument."); 1420 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1421 result = OHOS::ERR_INVALID_VALUE; 1422 break; 1423 } 1424 case 'a': { 1425 // 'bm disable -a' with no argument: bm disable -a 1426 // 'bm disable --ability-name' with no argument: bm disable --ability-name 1427 APP_LOGD("'bm disable -a' with no argument."); 1428 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1429 result = OHOS::ERR_INVALID_VALUE; 1430 break; 1431 } 1432 case 'u': { 1433 // 'bm disable -u' with no argument: bm disable -u 1434 // 'bm disable --user-id' with no argument: bm disable --user-id 1435 APP_LOGD("'bm disable -u' with no argument."); 1436 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1437 result = OHOS::ERR_INVALID_VALUE; 1438 break; 1439 } 1440 default: { 1441 // 'bm disable' with an unknown option: bm disable -x 1442 // 'bm disable' with an unknown option: bm disable -xxx 1443 std::string unknownOption = ""; 1444 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); 1445 APP_LOGD("'bm disable' with an unknown option."); 1446 resultReceiver_.append(unknownOptionMsg); 1447 result = OHOS::ERR_INVALID_VALUE; 1448 break; 1449 } 1450 } 1451 break; 1452 } 1453 switch (option) { 1454 case 'h': { 1455 // 'bm disable -h' 1456 // 'bm disable --help' 1457 APP_LOGD("'bm disable %{public}s'", argv_[optind - 1]); 1458 result = OHOS::ERR_INVALID_VALUE; 1459 break; 1460 } 1461 case 'n': { 1462 // 'bm disable -n <bundle-name>' 1463 // 'bm disable --bundle-name <bundle-name>' 1464 bundleName = optarg; 1465 break; 1466 } 1467 case 'a': { 1468 // 'bm disable -a <ability-name>' 1469 // 'bm disable --ability-name <ability-name>' 1470 abilityName = optarg; 1471 break; 1472 } 1473 case 'u': { 1474 // 'bm disable -u userId' 1475 // 'bm disable --user-id userId' 1476 APP_LOGW("'bm disable -u is not supported'"); 1477 break; 1478 } 1479 default: { 1480 result = OHOS::ERR_INVALID_VALUE; 1481 break; 1482 } 1483 } 1484 } 1485 if (result == OHOS::ERR_OK) { 1486 if (resultReceiver_ == "" && bundleName.size() == 0) { 1487 // 'bm disable ...' with no bundle name option 1488 APP_LOGD("'bm disable' with no bundle name option."); 1489 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n"); 1490 result = OHOS::ERR_INVALID_VALUE; 1491 } 1492 } 1493 if (result != OHOS::ERR_OK) { 1494 resultReceiver_.append(HELP_MSG_DISABLE); 1495 } else { 1496 AbilityInfo abilityInfo; 1497 abilityInfo.name = abilityName; 1498 abilityInfo.bundleName = bundleName; 1499 bool enableResult = SetApplicationEnabledOperation(abilityInfo, false, userId); 1500 if (enableResult) { 1501 resultReceiver_ = STRING_DISABLE_BUNDLE_OK + "\n"; 1502 } else { 1503 resultReceiver_ = STRING_DISABLE_BUNDLE_NG + "\n"; 1504 } 1505 } 1506 APP_LOGI("end"); 1507 return result; 1508} 1509 1510ErrCode BundleManagerShellCommand::RunAsGetCommand() 1511{ 1512 APP_LOGI("begin to RunAsGetCommand"); 1513 int result = OHOS::ERR_OK; 1514 int counter = 0; 1515 while (true) { 1516 counter++; 1517 if (argc_ > MAX_ARGUEMENTS_NUMBER) { 1518 resultReceiver_.append(HELP_MSG_GET); 1519 return OHOS::ERR_INVALID_VALUE; 1520 } 1521 int32_t option = getopt_long(argc_, argv_, SHORT_OPTIONS_GET.c_str(), LONG_OPTIONS_GET, nullptr); 1522 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind); 1523 if (optind < 0 || optind > argc_) { 1524 return OHOS::ERR_INVALID_VALUE; 1525 } 1526 if (option == -1) { 1527 if (counter == 1) { 1528 if (strcmp(argv_[optind], cmd_.c_str()) == 0) { 1529 // 1.'bm get' with no option: bm get 1530 // 2.'bm get' with a wrong argument: bm get -xxx 1531 APP_LOGD("'bm get' %{public}s", HELP_MSG_NO_OPTION.c_str()); 1532 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 1533 result = OHOS::ERR_INVALID_VALUE; 1534 } 1535 } 1536 break; 1537 } 1538 switch (option) { 1539 case 'h': { 1540 result = OHOS::ERR_INVALID_VALUE; 1541 break; 1542 } 1543 case 'u': { 1544 break; 1545 } 1546 default: { 1547 result = OHOS::ERR_INVALID_VALUE; 1548 resultReceiver_.append(STRING_INCORRECT_OPTION + "\n"); 1549 break; 1550 } 1551 } 1552 } 1553 if (result != OHOS::ERR_OK) { 1554 resultReceiver_.append(HELP_MSG_GET); 1555 return result; 1556 } 1557 resultReceiver_.append(STRING_GET_UDID_OK + "\n"); 1558 resultReceiver_.append(GetUdid() + "\n"); 1559 APP_LOGI("end"); 1560 return result; 1561} 1562 1563ErrCode BundleManagerShellCommand::RunAsQuickFixCommand() 1564{ 1565 APP_LOGI("begin to RunAsQuickFixCommand"); 1566 for (auto index = INDEX_OFFSET; index < argc_; ++index) { 1567 APP_LOGD("argv_[%{public}d]: %{public}s", index, argv_[index]); 1568 std::string opt = argv_[index]; 1569 if ((opt == "-h") || (opt == "--help")) { 1570 resultReceiver_.append(HELP_MSG_QUICK_FIX); 1571 APP_LOGI("end"); 1572 return ERR_OK; 1573 } else if ((opt == "-a") || (opt == "--apply")) { 1574 if (index >= argc_ - INDEX_OFFSET) { 1575 resultReceiver_.append("error: option [--apply] is incorrect.\n"); 1576 resultReceiver_.append(HELP_MSG_QUICK_FIX); 1577 APP_LOGI("end"); 1578 return ERR_INVALID_VALUE; 1579 } 1580 1581 std::string argKey = argv_[++index]; 1582 index++; 1583 if (argKey == "-f" || argKey == "--file-path") { 1584 std::vector<std::string> quickFixFiles; 1585 bool isDebug = false; 1586 std::string targetPath; 1587 // collect value of multi file-path. 1588 for (; index < argc_ && index >= INDEX_OFFSET; ++index) { 1589 if (argList_[index - INDEX_OFFSET] == "-q" || argList_[index - INDEX_OFFSET] == "--query" || 1590 argList_[index - INDEX_OFFSET] == "-b" || argList_[index - INDEX_OFFSET] == "--bundle-name" || 1591 argList_[index - INDEX_OFFSET] == "-a" || argList_[index - INDEX_OFFSET] == "--apply" || 1592 argList_[index - INDEX_OFFSET] == "-f" || argList_[index - INDEX_OFFSET] == "--file-path") { 1593 break; 1594 } else if (argList_[index - INDEX_OFFSET] == "-d" || argList_[index - INDEX_OFFSET] == "--debug") { 1595 isDebug = true; 1596 continue; 1597 } else if (argList_[index - INDEX_OFFSET] == "-t" || argList_[index - INDEX_OFFSET] == "--target") { 1598 if (index + 1 - INDEX_OFFSET >= static_cast<int32_t>(argList_.size())) { 1599 continue; 1600 } 1601 targetPath = argList_[index + 1 - INDEX_OFFSET]; 1602 index++; 1603 continue; 1604 } 1605 quickFixFiles.emplace_back(argList_[index - INDEX_OFFSET]); 1606 } 1607 APP_LOGI("end"); 1608 if (!targetPath.empty()) { 1609 std::shared_ptr<QuickFixResult> deployRes = nullptr; 1610 int32_t result = OHOS::ERR_OK; 1611 result = DeployQuickFixDisable(quickFixFiles, deployRes, isDebug, targetPath); 1612 resultReceiver_.append((result == OHOS::ERR_OK) ? "apply quickfix succeed.\n" : 1613 ("apply quickfix failed with errno: " + std::to_string(result) + ".\n")); 1614 return result; 1615 } 1616 return QuickFixCommand::ApplyQuickFix(quickFixFiles, resultReceiver_, isDebug); 1617 } 1618 } else if ((opt == "-q") || (opt == "--query")) { 1619 if (index >= argc_ - INDEX_OFFSET) { 1620 resultReceiver_.append("error: option [--query] is incorrect.\n"); 1621 resultReceiver_.append(HELP_MSG_QUICK_FIX); 1622 APP_LOGI("end"); 1623 return ERR_INVALID_VALUE; 1624 } 1625 1626 std::string bundleName; 1627 std::string argKey = argv_[++index]; 1628 std::string argValue = argv_[++index]; 1629 if (argKey == "-b" || argKey == "--bundle-name") { 1630 bundleName = argValue; 1631 } 1632 APP_LOGI("end"); 1633 return QuickFixCommand::GetApplyedQuickFixInfo(bundleName, resultReceiver_); 1634 } else if ((opt == "-r") || (opt == "--remove")) { 1635 if (index >= argc_ - INDEX_OFFSET) { 1636 resultReceiver_.append("error: option [--remove] is incorrect.\n"); 1637 resultReceiver_.append(HELP_MSG_QUICK_FIX); 1638 APP_LOGI("end"); 1639 return ERR_INVALID_VALUE; 1640 } 1641 1642 std::string bundleName; 1643 std::string argKey = argv_[++index]; 1644 std::string argValue = argv_[++index]; 1645 if (argKey == "-b" || argKey == "--bundle-name") { 1646 bundleName = argValue; 1647 } 1648 APP_LOGI("end"); 1649 std::shared_ptr<QuickFixResult> deleteRes = nullptr; 1650 int32_t result = OHOS::ERR_OK; 1651 result = DeleteQuickFix(bundleName, deleteRes); 1652 resultReceiver_ = (result == OHOS::ERR_OK) ? "delete quick fix successfully\n" : 1653 "delete quickfix failed with errno: " + std::to_string(result) + ".\n"; 1654 return result; 1655 } else { 1656 resultReceiver_.append("error: unknown option.\n"); 1657 resultReceiver_.append(HELP_MSG_QUICK_FIX); 1658 APP_LOGI("end"); 1659 return ERR_INVALID_VALUE; 1660 } 1661 } 1662 1663 resultReceiver_.append("error: parameter is not enough.\n"); 1664 resultReceiver_.append(HELP_MSG_QUICK_FIX); 1665 APP_LOGI("end"); 1666 return ERR_INVALID_VALUE; 1667} 1668 1669ErrCode BundleManagerShellCommand::RunAsDumpOverlay() 1670{ 1671 APP_LOGI("begin to RunAsDumpOverlay"); 1672 int result = OHOS::ERR_OK; 1673 int counter = 0; 1674 int32_t userId = BundleCommandCommon::GetCurrentUserId(Constants::UNSPECIFIED_USERID); 1675 std::string bundleName = ""; 1676 std::string moduleName = ""; 1677 std::string targetModuleName = ""; 1678 while (true) { 1679 counter++; 1680 if (argc_ > MAX_OVERLAY_ARGUEMENTS_NUMBER) { 1681 resultReceiver_.append(HELP_MSG_OVERLAY); 1682 return OHOS::ERR_INVALID_VALUE; 1683 } 1684 int32_t option = getopt_long(argc_, argv_, SHORT_OPTIONS_OVERLAY.c_str(), LONG_OPTIONS_OVERLAY, 1685 nullptr); 1686 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind); 1687 if (optind < 0 || optind > argc_) { 1688 return OHOS::ERR_INVALID_VALUE; 1689 } 1690 if (option == -1) { 1691 if (counter == 1) { 1692 if (strcmp(argv_[optind], cmd_.c_str()) == 0) { 1693 // 1.'bm dump-overlay' with no option: bm dump-overlay 1694 // 2.'bm dump-overlay' with a wrong argument: bm dump-overlay -xxx 1695 APP_LOGD("'bm dump-overlay' %{public}s", HELP_MSG_NO_OPTION.c_str()); 1696 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 1697 result = OHOS::ERR_INVALID_VALUE; 1698 } 1699 } 1700 break; 1701 } 1702 if (option == '?') { 1703 switch (optopt) { 1704 case 'b': { 1705 // 'bm dump-overlay -b' with no argument 1706 // 'bm dump-overlay --bundle-name' with no argument 1707 APP_LOGD("'bm dump-overlay -b' with no argument."); 1708 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1709 result = OHOS::ERR_INVALID_VALUE; 1710 break; 1711 } 1712 case 'm': { 1713 // 'bm dump-overlay -m' with no argument: bm enable -m 1714 // 'bm dump-overlay --bundle-name' with no argument: bm dump-overlay --bundle-name 1715 APP_LOGD("'bm dump-overlay -m' with no argument."); 1716 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1717 result = OHOS::ERR_INVALID_VALUE; 1718 break; 1719 } 1720 case 't': { 1721 // 'bm dump-overlay -t' with no argument 1722 // 'bm dump-overlay --target-module-name' with no argument 1723 APP_LOGD("'bm dump-overlay -t' with no argument."); 1724 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1725 result = OHOS::ERR_INVALID_VALUE; 1726 break; 1727 } 1728 case 'u': { 1729 // 'bm dump-overlay -u' with no argument: bm dump-overlay -u 1730 // 'bm dump-overlay --user-id' with no argument: bm dump-overlay --user-id 1731 APP_LOGD("'bm dump-overlay -u' with no argument."); 1732 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1733 result = OHOS::ERR_INVALID_VALUE; 1734 break; 1735 } 1736 default: { 1737 // 'bm dump-overlay' with an unknown option 1738 // 'bm dump-overlay' with an unknown option 1739 std::string unknownOption = ""; 1740 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); 1741 APP_LOGD("'bm dump-overlay' with an unknown option."); 1742 resultReceiver_.append(unknownOptionMsg); 1743 result = OHOS::ERR_INVALID_VALUE; 1744 break; 1745 } 1746 } 1747 break; 1748 } 1749 1750 switch (option) { 1751 case 'h': { 1752 // 'bm dump-overlay -h' 1753 // 'bm dump-overlay --help' 1754 APP_LOGD("'bm dump-overlay %{public}s'", argv_[optind - 1]); 1755 result = OHOS::ERR_INVALID_VALUE; 1756 break; 1757 } 1758 case 'b': { 1759 // 'bm dump-overlay -b <bundle-name>' 1760 // 'bm dump-overlay --bundle-name <bundle-name>' 1761 bundleName = optarg; 1762 break; 1763 } 1764 case 'm': { 1765 // 'bm dump-overlay -m <module-name>' 1766 // 'bm dump-overlay --module-name <module-name>' 1767 moduleName = optarg; 1768 break; 1769 } 1770 case 't': { 1771 // 'bm dump-overlay -t <target-module-name>' 1772 // 'bm dump-overlay --target-module-name <target-module-name>' 1773 targetModuleName = optarg; 1774 break; 1775 } 1776 case 'u': { 1777 APP_LOGW("'bm dump-overlay -u is not supported'"); 1778 break; 1779 } 1780 default: { 1781 result = OHOS::ERR_INVALID_VALUE; 1782 break; 1783 } 1784 } 1785 } 1786 if (result != OHOS::ERR_OK) { 1787 resultReceiver_.append(HELP_MSG_OVERLAY); 1788 return result; 1789 } 1790#ifdef BUNDLE_FRAMEWORK_OVERLAY_INSTALLATION 1791 auto res = DumpOverlayInfo(bundleName, moduleName, targetModuleName, userId); 1792 if (res.empty()) { 1793 resultReceiver_.append(STRING_DUMP_OVERLAY_NG + "\n"); 1794 } else { 1795 resultReceiver_.append(STRING_DUMP_OVERLAY_OK + "\n"); 1796 resultReceiver_.append(res + "\n"); 1797 } 1798#else 1799 resultReceiver_.append(MSG_ERR_BUNDLEMANAGER_OVERLAY_FEATURE_IS_NOT_SUPPORTED); 1800#endif 1801 APP_LOGI("end"); 1802 return result; 1803} 1804 1805ErrCode BundleManagerShellCommand::RunAsDumpTargetOverlay() 1806{ 1807 APP_LOGI("begin to RunAsDumpTargetOverlay"); 1808 int result = OHOS::ERR_OK; 1809 int counter = 0; 1810 int32_t userId = BundleCommandCommon::GetCurrentUserId(Constants::UNSPECIFIED_USERID); 1811 std::string bundleName = ""; 1812 std::string moduleName = ""; 1813 while (true) { 1814 counter++; 1815 if (argc_ > MAX_OVERLAY_ARGUEMENTS_NUMBER) { 1816 resultReceiver_.append(HELP_MSG_OVERLAY_TARGET); 1817 return OHOS::ERR_INVALID_VALUE; 1818 } 1819 int32_t option = getopt_long(argc_, argv_, SHORT_OPTIONS_OVERLAY_TARGET.c_str(), LONG_OPTIONS_OVERLAY_TARGET, 1820 nullptr); 1821 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind); 1822 if (optind < 0 || optind > argc_) { 1823 return OHOS::ERR_INVALID_VALUE; 1824 } 1825 if (option == -1) { 1826 if (counter == 1) { 1827 if (strcmp(argv_[optind], cmd_.c_str()) == 0) { 1828 // 1.'bm dump-target-overlay' with no option: bm dump-target-overlay 1829 // 2.'bm dump-target-overlay' with a wrong argument: bm dump-target-overlay -xxx 1830 APP_LOGD("'bm dump-target-overlay' %{public}s", HELP_MSG_NO_OPTION.c_str()); 1831 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 1832 result = OHOS::ERR_INVALID_VALUE; 1833 } 1834 } 1835 break; 1836 } 1837 if (option == '?') { 1838 switch (optopt) { 1839 case 'b': { 1840 // 'bm dump-target-overlay -b' with no argument 1841 // 'bm dump-target-overlay --bundle-name' with no argument 1842 APP_LOGD("'bm dump-target-overlay -b' with no argument."); 1843 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1844 result = OHOS::ERR_INVALID_VALUE; 1845 break; 1846 } 1847 case 'm': { 1848 // 'bm dump-target-overlay -m' with no argument: bm enable -m 1849 // 'bm dump-target-overlay --bundle-name' with no argument: bm dump-target-overlay --bundle-name 1850 APP_LOGD("'bm dump-target-overlay -m' with no argument."); 1851 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1852 result = OHOS::ERR_INVALID_VALUE; 1853 break; 1854 } 1855 case 'u': { 1856 // 'bm dump-target-overlay -u' with no argument: bm dump-target-overlay -u 1857 // 'bm dump-target-overlay --user-id' with no argument: bm dump-target-overlay --user-id 1858 APP_LOGD("'bm dump-target-overlay -u' with no argument."); 1859 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 1860 result = OHOS::ERR_INVALID_VALUE; 1861 break; 1862 } 1863 default: { 1864 // 'bm dump-target-overlay' with an unknown option 1865 // 'bm dump-target-overlay' with an unknown option 1866 std::string unknownOption = ""; 1867 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); 1868 APP_LOGD("'bm dump-target-overlay' with an unknown option."); 1869 resultReceiver_.append(unknownOptionMsg); 1870 result = OHOS::ERR_INVALID_VALUE; 1871 break; 1872 } 1873 } 1874 break; 1875 } 1876 1877 switch (option) { 1878 case 'h': { 1879 // 'bm dump-target-overlay -h' 1880 // 'bm dump-target-overlay --help' 1881 APP_LOGD("'bm dump-target-overlay %{public}s'", argv_[optind - 1]); 1882 result = OHOS::ERR_INVALID_VALUE; 1883 break; 1884 } 1885 case 'b': { 1886 // 'bm dump-target-overlay -b <bundle-name>' 1887 // 'bm dump-target-overlay --bundle-name <bundle-name>' 1888 bundleName = optarg; 1889 break; 1890 } 1891 case 'm': { 1892 // 'bm dump-target-overlay -m <module-name>' 1893 // 'bm dump-target-overlay --module-name <module-name>' 1894 moduleName = optarg; 1895 break; 1896 } 1897 case 'u': { 1898 APP_LOGW("'bm dump-target-overlay -u is not supported'"); 1899 break; 1900 } 1901 default: { 1902 result = OHOS::ERR_INVALID_VALUE; 1903 break; 1904 } 1905 } 1906 } 1907 if (result != OHOS::ERR_OK) { 1908 resultReceiver_.append(HELP_MSG_OVERLAY_TARGET); 1909 return result; 1910 } 1911#ifdef BUNDLE_FRAMEWORK_OVERLAY_INSTALLATION 1912 auto res = DumpTargetOverlayInfo(bundleName, moduleName, userId); 1913 if (res.empty()) { 1914 resultReceiver_.append(STRING_DUMP_TARGET_OVERLAY_NG + "\n"); 1915 } else { 1916 resultReceiver_.append(STRING_DUMP_TARGET_OVERLAY_OK + "\n"); 1917 resultReceiver_.append(res + "\n"); 1918 } 1919#else 1920 resultReceiver_.append(MSG_ERR_BUNDLEMANAGER_OVERLAY_FEATURE_IS_NOT_SUPPORTED); 1921#endif 1922 APP_LOGI("end"); 1923 return result; 1924} 1925 1926 1927std::string BundleManagerShellCommand::GetUdid() const 1928{ 1929 char innerUdid[DEVICE_UDID_LENGTH] = { 0 }; 1930 int ret = GetDevUdid(innerUdid, DEVICE_UDID_LENGTH); 1931 if (ret != 0) { 1932 APP_LOGE("GetUdid failed! ret = %{public}d.", ret); 1933 return STRING_GET_UDID_NG; 1934 } 1935 std::string udid = innerUdid; 1936 return udid; 1937} 1938 1939std::string BundleManagerShellCommand::CopyAp(const std::string &bundleName, bool isAllBundle) const 1940{ 1941 std::string result = ""; 1942 std::vector<std::string> copyApResults; 1943 ErrCode ret = bundleMgrProxy_->CopyAp(bundleName, isAllBundle, copyApResults); 1944 if (ret != ERR_OK) { 1945 APP_LOGE("failed to copy ap! ret = = %{public}d.", ret); 1946 return ""; 1947 } 1948 for (const auto ©ApResult : copyApResults) { 1949 result.append("\t"); 1950 result.append(copyApResult); 1951 result.append("\n"); 1952 } 1953 return result; 1954} 1955 1956std::string BundleManagerShellCommand::CompileProcessAot( 1957 const std::string &bundleName, const std::string &compileMode, bool isAllBundle) const 1958{ 1959 std::vector<std::string> compileResults; 1960 ErrCode CompileRet = bundleMgrProxy_->CompileProcessAOT(bundleName, compileMode, isAllBundle, compileResults); 1961 if (CompileRet != ERR_OK) { 1962 std::string result = "error: compile AOT:\n"; 1963 for (const auto &compileResult : compileResults) { 1964 result.append("\t"); 1965 result.append(compileResult); 1966 result.append("\n"); 1967 } 1968 return result; 1969 } 1970 return COMPILE_SUCCESS_OK; 1971} 1972 1973std::string BundleManagerShellCommand::CompileReset(const std::string &bundleName, bool isAllBundle) const 1974{ 1975 std::string ResetResults; 1976 ErrCode ResetRet = bundleMgrProxy_->CompileReset(bundleName, isAllBundle); 1977 if (ResetRet == ERR_APPEXECFWK_PARCEL_ERROR) { 1978 APP_LOGE("failed to reset AOT."); 1979 return ResetResults; 1980 } 1981 ResetResults = COMPILE_RESET; 1982 return ResetResults; 1983} 1984 1985std::string BundleManagerShellCommand::DumpBundleList(int32_t userId) const 1986{ 1987 std::string dumpResults; 1988 bool dumpRet = bundleMgrProxy_->DumpInfos( 1989 DumpFlag::DUMP_BUNDLE_LIST, BUNDLE_NAME_EMPTY, userId, dumpResults); 1990 if (!dumpRet) { 1991 APP_LOGE("failed to dump bundle list."); 1992 } 1993 return dumpResults; 1994} 1995 1996std::string BundleManagerShellCommand::DumpBundleInfo(const std::string &bundleName, int32_t userId) const 1997{ 1998 std::string dumpResults; 1999 bool dumpRet = bundleMgrProxy_->DumpInfos( 2000 DumpFlag::DUMP_BUNDLE_INFO, bundleName, userId, dumpResults); 2001 if (!dumpRet) { 2002 APP_LOGE("failed to dump bundle info."); 2003 } 2004 return dumpResults; 2005} 2006 2007std::string BundleManagerShellCommand::DumpShortcutInfos(const std::string &bundleName, int32_t userId) const 2008{ 2009 std::string dumpResults; 2010 bool dumpRet = bundleMgrProxy_->DumpInfos( 2011 DumpFlag::DUMP_SHORTCUT_INFO, bundleName, userId, dumpResults); 2012 if (!dumpRet) { 2013 APP_LOGE("failed to dump shortcut infos."); 2014 } 2015 return dumpResults; 2016} 2017 2018std::string BundleManagerShellCommand::DumpDistributedBundleInfo( 2019 const std::string &deviceId, const std::string &bundleName) 2020{ 2021 std::string dumpResults = ""; 2022 DistributedBundleInfo distributedBundleInfo; 2023 bool dumpRet = bundleMgrProxy_->GetDistributedBundleInfo(deviceId, bundleName, distributedBundleInfo); 2024 if (!dumpRet) { 2025 APP_LOGE("failed to dump distributed bundleInfo."); 2026 } else { 2027 dumpResults.append("distributed bundleInfo"); 2028 dumpResults.append(":\n"); 2029 dumpResults.append(distributedBundleInfo.ToString()); 2030 dumpResults.append("\n"); 2031 } 2032 return dumpResults; 2033} 2034 2035std::string BundleManagerShellCommand::DumpDependentModuleNames( 2036 const std::string &bundleName, 2037 const std::string &moduleName) const 2038{ 2039 APP_LOGD("DumpDependentModuleNames bundleName: %{public}s, moduleName: %{public}s", 2040 bundleName.c_str(), moduleName.c_str()); 2041 std::string dumpResults = ""; 2042 std::vector<std::string> dependentModuleNames; 2043 bool dumpRet = bundleMgrProxy_->GetAllDependentModuleNames(bundleName, moduleName, dependentModuleNames); 2044 if (!dumpRet) { 2045 APP_LOGE("failed to dump dependent module name."); 2046 } else { 2047 dumpResults.append("dependent moduleNames:"); 2048 for (const auto &name : dependentModuleNames) { 2049 dumpResults.append("\n"); 2050 dumpResults.append(name); 2051 } 2052 dumpResults.append("\n"); 2053 } 2054 return dumpResults; 2055} 2056 2057void BundleManagerShellCommand::GetAbsPaths( 2058 const std::vector<std::string> &paths, std::vector<std::string> &absPaths) const 2059{ 2060 std::vector<std::string> realPathVec; 2061 for (auto &bundlePath : paths) { 2062 std::string absoluteBundlePath = ""; 2063 if (bundlePath.empty()) { 2064 continue; 2065 } 2066 if (bundlePath.at(0) == '/') { 2067 // absolute path 2068 absoluteBundlePath.append(bundlePath); 2069 } else { 2070 // relative path 2071 char *currentPathPtr = getcwd(nullptr, 0); 2072 2073 if (currentPathPtr != nullptr) { 2074 absoluteBundlePath.append(currentPathPtr); 2075 absoluteBundlePath.append('/' + bundlePath); 2076 2077 free(currentPathPtr); 2078 currentPathPtr = nullptr; 2079 } 2080 } 2081 realPathVec.emplace_back(absoluteBundlePath); 2082 } 2083 2084 for (const auto &path : realPathVec) { 2085 if (std::find(absPaths.begin(), absPaths.end(), path) == absPaths.end()) { 2086 absPaths.emplace_back(path); 2087 } 2088 } 2089} 2090 2091int32_t BundleManagerShellCommand::InstallOperation(const std::vector<std::string> &bundlePaths, 2092 InstallParam &installParam, int32_t waittingTime, std::string &resultMsg) const 2093{ 2094 std::vector<std::string> pathVec; 2095 GetAbsPaths(bundlePaths, pathVec); 2096 2097 std::vector<std::string> hspPathVec; 2098 GetAbsPaths(installParam.sharedBundleDirPaths, hspPathVec); 2099 installParam.sharedBundleDirPaths = hspPathVec; 2100 2101 sptr<StatusReceiverImpl> statusReceiver(new (std::nothrow) StatusReceiverImpl(waittingTime)); 2102 if (statusReceiver == nullptr) { 2103 APP_LOGE("statusReceiver is null"); 2104 return IStatusReceiver::ERR_UNKNOWN; 2105 } 2106 sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(statusReceiver)); 2107 if (recipient == nullptr) { 2108 APP_LOGE("recipient is null"); 2109 return IStatusReceiver::ERR_UNKNOWN; 2110 } 2111 bundleInstallerProxy_->AsObject()->AddDeathRecipient(recipient); 2112 ErrCode res = bundleInstallerProxy_->StreamInstall(pathVec, installParam, statusReceiver); 2113 APP_LOGD("StreamInstall result is %{public}d", res); 2114 if (res == ERR_OK) { 2115 resultMsg = statusReceiver->GetResultMsg(); 2116 return statusReceiver->GetResultCode(); 2117 } 2118 if (res == ERR_APPEXECFWK_INSTALL_PARAM_ERROR) { 2119 APP_LOGE("install param error"); 2120 return IStatusReceiver::ERR_INSTALL_PARAM_ERROR; 2121 } 2122 if (res == ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR) { 2123 APP_LOGE("install internal error"); 2124 return IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR; 2125 } 2126 if (res == ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID) { 2127 APP_LOGE("install invalid path"); 2128 return IStatusReceiver::ERR_INSTALL_FILE_PATH_INVALID; 2129 } 2130 if (res == ERR_APPEXECFWK_INSTALL_DISK_MEM_INSUFFICIENT) { 2131 APP_LOGE("install failed due to no space left"); 2132 return IStatusReceiver::ERR_INSTALL_DISK_MEM_INSUFFICIENT; 2133 } 2134 2135 return res; 2136} 2137 2138int32_t BundleManagerShellCommand::UninstallOperation( 2139 const std::string &bundleName, const std::string &moduleName, InstallParam &installParam) const 2140{ 2141 sptr<StatusReceiverImpl> statusReceiver(new (std::nothrow) StatusReceiverImpl()); 2142 if (statusReceiver == nullptr) { 2143 APP_LOGE("statusReceiver is null"); 2144 return IStatusReceiver::ERR_UNKNOWN; 2145 } 2146 2147 APP_LOGD("bundleName: %{public}s", bundleName.c_str()); 2148 APP_LOGD("moduleName: %{public}s", moduleName.c_str()); 2149 2150 sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(statusReceiver)); 2151 if (recipient == nullptr) { 2152 APP_LOGE("recipient is null"); 2153 return IStatusReceiver::ERR_UNKNOWN; 2154 } 2155 bundleInstallerProxy_->AsObject()->AddDeathRecipient(recipient); 2156 if (moduleName.size() != 0) { 2157 bundleInstallerProxy_->Uninstall(bundleName, moduleName, installParam, statusReceiver); 2158 } else { 2159 bundleInstallerProxy_->Uninstall(bundleName, installParam, statusReceiver); 2160 } 2161 2162 return statusReceiver->GetResultCode(); 2163} 2164 2165int32_t BundleManagerShellCommand::UninstallSharedOperation(const UninstallParam &uninstallParam) const 2166{ 2167 sptr<StatusReceiverImpl> statusReceiver(new (std::nothrow) StatusReceiverImpl()); 2168 if (statusReceiver == nullptr) { 2169 APP_LOGE("statusReceiver is null"); 2170 return IStatusReceiver::ERR_UNKNOWN; 2171 } 2172 2173 sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(statusReceiver)); 2174 if (recipient == nullptr) { 2175 APP_LOGE("recipient is null"); 2176 return IStatusReceiver::ERR_UNKNOWN; 2177 } 2178 bundleInstallerProxy_->AsObject()->AddDeathRecipient(recipient); 2179 2180 bundleInstallerProxy_->Uninstall(uninstallParam, statusReceiver); 2181 return statusReceiver->GetResultCode(); 2182} 2183 2184bool BundleManagerShellCommand::CleanBundleCacheFilesOperation(const std::string &bundleName, int32_t userId, 2185 int32_t appIndex) const 2186{ 2187 userId = BundleCommandCommon::GetCurrentUserId(userId); 2188 APP_LOGD("bundleName: %{public}s, userId:%{public}d, appIndex:%{public}d", bundleName.c_str(), userId, appIndex); 2189 sptr<CleanCacheCallbackImpl> cleanCacheCallBack(new (std::nothrow) CleanCacheCallbackImpl()); 2190 if (cleanCacheCallBack == nullptr) { 2191 APP_LOGE("cleanCacheCallBack is null"); 2192 return false; 2193 } 2194 ErrCode cleanRet = bundleMgrProxy_->CleanBundleCacheFiles(bundleName, cleanCacheCallBack, userId, appIndex); 2195 if (cleanRet == ERR_OK) { 2196 return cleanCacheCallBack->GetResultCode(); 2197 } 2198 APP_LOGE("clean bundle cache files operation failed, cleanRet = %{public}d", cleanRet); 2199 return false; 2200} 2201 2202bool BundleManagerShellCommand::CleanBundleDataFilesOperation(const std::string &bundleName, int32_t userId, 2203 int32_t appIndex) const 2204{ 2205 userId = BundleCommandCommon::GetCurrentUserId(userId); 2206 APP_LOGD("bundleName: %{public}s, userId:%{public}d, appIndex:%{public}d", bundleName.c_str(), userId, appIndex); 2207 auto appMgrClient = std::make_unique<AppMgrClient>(); 2208 APP_LOGI("clear start"); 2209 ErrCode cleanRetAms = appMgrClient->ClearUpApplicationData(bundleName, appIndex, userId); 2210 APP_LOGI("clear end"); 2211 bool cleanRetBms = bundleMgrProxy_->CleanBundleDataFiles(bundleName, userId, appIndex); 2212 APP_LOGD("cleanRetAms: %{public}d, cleanRetBms: %{public}d", cleanRetAms, cleanRetBms); 2213 if ((cleanRetAms == ERR_OK) && cleanRetBms) { 2214 return true; 2215 } 2216 APP_LOGE("clean bundle data files operation failed"); 2217 return false; 2218} 2219 2220bool BundleManagerShellCommand::SetApplicationEnabledOperation(const AbilityInfo &abilityInfo, 2221 bool isEnable, int32_t userId) const 2222{ 2223 APP_LOGD("bundleName: %{public}s", abilityInfo.bundleName.c_str()); 2224 userId = BundleCommandCommon::GetCurrentUserId(userId); 2225 int32_t ret; 2226 if (abilityInfo.name.size() == 0) { 2227 ret = bundleMgrProxy_->SetApplicationEnabled(abilityInfo.bundleName, isEnable, userId); 2228 } else { 2229 ret = bundleMgrProxy_->SetAbilityEnabled(abilityInfo, isEnable, userId); 2230 } 2231 if (ret != 0) { 2232 if (isEnable) { 2233 APP_LOGE("enable bundle failed"); 2234 } else { 2235 APP_LOGE("disable bundle failed"); 2236 } 2237 return false; 2238 } 2239 return true; 2240} 2241 2242std::string BundleManagerShellCommand::DumpOverlayInfo(const std::string &bundleName, const std::string &moduleName, 2243 const std::string &targetModuleName, int32_t userId) 2244{ 2245 std::string res = ""; 2246 if ((bundleName.empty()) || (!moduleName.empty() && !targetModuleName.empty())) { 2247 APP_LOGE("error value of the dump-overlay command options"); 2248 return res; 2249 } 2250 2251 auto overlayManagerProxy = bundleMgrProxy_->GetOverlayManagerProxy(); 2252 if (overlayManagerProxy == nullptr) { 2253 APP_LOGE("overlayManagerProxy is null"); 2254 return res; 2255 } 2256 std::vector<OverlayModuleInfo> overlayModuleInfos; 2257 OverlayModuleInfo overlayModuleInfo; 2258 ErrCode ret = ERR_OK; 2259 userId = BundleCommandCommon::GetCurrentUserId(userId); 2260 if (moduleName.empty() && targetModuleName.empty()) { 2261 ret = overlayManagerProxy->GetAllOverlayModuleInfo(bundleName, overlayModuleInfos, userId); 2262 if (overlayModuleInfos.empty()) { 2263 ret = ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_NO_OVERLAY_MODULE_INFO; 2264 } 2265 } else if (!moduleName.empty()) { 2266 ret = overlayManagerProxy->GetOverlayModuleInfo(bundleName, moduleName, overlayModuleInfo, userId); 2267 } else { 2268 ret = overlayManagerProxy->GetOverlayModuleInfoForTarget(bundleName, targetModuleName, overlayModuleInfos, 2269 userId); 2270 if (overlayModuleInfos.empty()) { 2271 ret = ERR_BUNDLEMANAGER_OVERLAY_QUERY_FAILED_NO_OVERLAY_MODULE_INFO; 2272 } 2273 } 2274 if (ret != ERR_OK) { 2275 APP_LOGE("dump-overlay failed due to errcode %{public}d", ret); 2276 return res; 2277 } 2278 2279 nlohmann::json overlayInfoJson; 2280 if (!overlayModuleInfos.empty()) { 2281 overlayInfoJson = nlohmann::json {{OVERLAY_MODULE_INFOS, overlayModuleInfos}}; 2282 } else { 2283 overlayInfoJson = nlohmann::json {{OVERLAY_MODULE_INFO, overlayModuleInfo}}; 2284 } 2285 return overlayInfoJson.dump(Constants::DUMP_INDENT); 2286} 2287 2288std::string BundleManagerShellCommand::DumpTargetOverlayInfo(const std::string &bundleName, 2289 const std::string &moduleName, int32_t userId) 2290{ 2291 std::string res = ""; 2292 if (bundleName.empty()) { 2293 APP_LOGE("error value of the dump-target-overlay command options"); 2294 return res; 2295 } 2296 auto overlayManagerProxy = bundleMgrProxy_->GetOverlayManagerProxy(); 2297 if (overlayManagerProxy == nullptr) { 2298 APP_LOGE("overlayManagerProxy is null"); 2299 return res; 2300 } 2301 2302 userId = BundleCommandCommon::GetCurrentUserId(userId); 2303 ErrCode ret = ERR_OK; 2304 nlohmann::json overlayInfoJson; 2305 if (moduleName.empty()) { 2306 std::vector<OverlayBundleInfo> overlayBundleInfos; 2307 ret = overlayManagerProxy->GetOverlayBundleInfoForTarget(bundleName, overlayBundleInfos, userId); 2308 if (ret != ERR_OK || overlayBundleInfos.empty()) { 2309 APP_LOGE("dump-target-overlay failed due to errcode %{public}d", ret); 2310 return res; 2311 } 2312 overlayInfoJson = nlohmann::json {{OVERLAY_BUNDLE_INFOS, overlayBundleInfos}}; 2313 } else { 2314 std::vector<OverlayModuleInfo> overlayModuleInfos; 2315 ret = overlayManagerProxy->GetOverlayModuleInfoForTarget(bundleName, moduleName, overlayModuleInfos, userId); 2316 if (ret != ERR_OK || overlayModuleInfos.empty()) { 2317 APP_LOGE("dump-target-overlay failed due to errcode %{public}d", ret); 2318 return res; 2319 } 2320 overlayInfoJson = nlohmann::json {{OVERLAY_MODULE_INFOS, overlayModuleInfos}}; 2321 } 2322 return overlayInfoJson.dump(Constants::DUMP_INDENT); 2323} 2324 2325ErrCode BundleManagerShellCommand::RunAsDumpSharedDependenciesCommand() 2326{ 2327 APP_LOGI("begin to RunAsDumpSharedDependenciesCommand"); 2328 int32_t result = OHOS::ERR_OK; 2329 int32_t counter = 0; 2330 std::string bundleName; 2331 std::string moduleName; 2332 while (true) { 2333 counter++; 2334 int32_t option = getopt_long(argc_, argv_, SHORT_OPTIONS_DUMP_SHARED_DEPENDENCIES.c_str(), 2335 LONG_OPTIONS_DUMP_SHARED_DEPENDENCIES, nullptr); 2336 if (optind < 0 || optind > argc_) { 2337 return OHOS::ERR_INVALID_VALUE; 2338 } 2339 if (option == -1) { 2340 if (counter == 1) { 2341 // When scanning the first argument 2342 if (strcmp(argv_[optind], cmd_.c_str()) == 0) { 2343 // 'bm dump-dependencies' with no option: bm dump-dependencies 2344 // 'bm dump-dependencies' with a wrong argument: bm dump-dependencies xxx 2345 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 2346 result = OHOS::ERR_INVALID_VALUE; 2347 } 2348 } 2349 break; 2350 } 2351 result = ParseSharedDependenciesCommand(option, bundleName, moduleName); 2352 if (option == '?') { 2353 break; 2354 } 2355 } 2356 if (result == OHOS::ERR_OK) { 2357 if ((resultReceiver_ == "") && (bundleName.size() == 0 || moduleName.size() == 0)) { 2358 // 'bm dump-dependencies -n -m ...' with no bundle name option 2359 resultReceiver_.append(HELP_MSG_NO_REMOVABLE_OPTION); 2360 result = OHOS::ERR_INVALID_VALUE; 2361 } 2362 } 2363 if (result != OHOS::ERR_OK) { 2364 resultReceiver_.append(HELP_MSG_DUMP_SHARED_DEPENDENCIES); 2365 } else { 2366 std::string dumpResults = DumpSharedDependencies(bundleName, moduleName); 2367 if (dumpResults.empty() || (dumpResults == "")) { 2368 dumpResults = HELP_MSG_DUMP_FAILED + "\n"; 2369 } 2370 resultReceiver_.append(dumpResults); 2371 } 2372 APP_LOGI("end"); 2373 return result; 2374} 2375 2376ErrCode BundleManagerShellCommand::ParseSharedDependenciesCommand(int32_t option, std::string &bundleName, 2377 std::string &moduleName) 2378{ 2379 int32_t result = OHOS::ERR_OK; 2380 if (option == '?') { 2381 switch (optopt) { 2382 case 'n': { 2383 // 'bm dump-dependencies -n' with no argument: bm dump-dependencies -n 2384 // 'bm dump-dependencies --bundle-name' with no argument: bm dump-dependencies --bundle-name 2385 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 2386 result = OHOS::ERR_INVALID_VALUE; 2387 break; 2388 } 2389 case 'm': { 2390 // 'bm dump-dependencies -m' with no argument: bm dump-dependencies -m 2391 // 'bm dump-dependencies --module-name' with no argument: bm dump-dependencies --module-name 2392 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 2393 result = OHOS::ERR_INVALID_VALUE; 2394 break; 2395 } 2396 default: { 2397 // 'bm dump-dependencies' with an unknown option: bm dump-dependencies -x 2398 // 'bm dump-dependencies' with an unknown option: bm dump-dependencies -xxx 2399 std::string unknownOption = ""; 2400 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); 2401 resultReceiver_.append(unknownOptionMsg); 2402 result = OHOS::ERR_INVALID_VALUE; 2403 break; 2404 } 2405 } 2406 } else { 2407 switch (option) { 2408 case 'h': { 2409 // 'bm dump-dependencies -h' 2410 // 'bm dump-dependencies --help' 2411 result = OHOS::ERR_INVALID_VALUE; 2412 break; 2413 } 2414 case 'n': { 2415 // 'bm dump-dependencies -n xxx' 2416 // 'bm dump-dependencies --bundle-name xxx' 2417 bundleName = optarg; 2418 break; 2419 } 2420 case 'm': { 2421 // 'bm dump-dependencies -m xxx' 2422 // 'bm dump-dependencies --module-name xxx' 2423 moduleName = optarg; 2424 break; 2425 } 2426 default: { 2427 result = OHOS::ERR_INVALID_VALUE; 2428 break; 2429 } 2430 } 2431 } 2432 return result; 2433} 2434 2435std::string BundleManagerShellCommand::DumpSharedDependencies(const std::string &bundleName, 2436 const std::string &moduleName) const 2437{ 2438 APP_LOGD("DumpSharedDependencies bundleName: %{public}s, moduleName: %{public}s", 2439 bundleName.c_str(), moduleName.c_str()); 2440 std::vector<Dependency> dependencies; 2441 ErrCode ret = bundleMgrProxy_->GetSharedDependencies(bundleName, moduleName, dependencies); 2442 nlohmann::json dependenciesJson; 2443 if (ret != ERR_OK) { 2444 APP_LOGE("dump shared dependencies failed due to errcode %{public}d", ret); 2445 return std::string(); 2446 } else { 2447 dependenciesJson = nlohmann::json {{DEPENDENCIES, dependencies}}; 2448 } 2449 return dependenciesJson.dump(Constants::DUMP_INDENT); 2450} 2451 2452ErrCode BundleManagerShellCommand::RunAsDumpSharedCommand() 2453{ 2454 APP_LOGI("begin to RunAsDumpSharedCommand"); 2455 int32_t result = OHOS::ERR_OK; 2456 int32_t counter = 0; 2457 std::string bundleName; 2458 bool dumpSharedAll = false; 2459 while (true) { 2460 counter++; 2461 int32_t option = getopt_long(argc_, argv_, SHORT_OPTIONS_DUMP_SHARED.c_str(), 2462 LONG_OPTIONS_DUMP_SHARED, nullptr); 2463 if (optind < 0 || optind > argc_) { 2464 return OHOS::ERR_INVALID_VALUE; 2465 } 2466 if (option == -1) { 2467 if (counter == 1) { 2468 // When scanning the first argument 2469 if (strcmp(argv_[optind], cmd_.c_str()) == 0) { 2470 // 'bm dump-shared' with no option: bm dump-shared 2471 // 'bm dump-shared' with a wrong argument: bm dump-shared xxx 2472 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 2473 result = OHOS::ERR_INVALID_VALUE; 2474 } 2475 } 2476 break; 2477 } 2478 result = ParseSharedCommand(option, bundleName, dumpSharedAll); 2479 if (option == '?') { 2480 break; 2481 } 2482 } 2483 if (result != OHOS::ERR_OK) { 2484 resultReceiver_.append(HELP_MSG_DUMP_SHARED); 2485 } else if (dumpSharedAll) { 2486 std::string dumpResults = DumpSharedAll(); 2487 resultReceiver_.append(dumpResults); 2488 } else { 2489 if ((resultReceiver_ == "") && (bundleName.size() == 0)) { 2490 // 'bm dump-shared -n ...' with no bundle name option 2491 resultReceiver_.append(HELP_MSG_NO_REMOVABLE_OPTION); 2492 result = OHOS::ERR_INVALID_VALUE; 2493 return result; 2494 } 2495 std::string dumpResults = DumpShared(bundleName); 2496 if (dumpResults.empty() || (dumpResults == "")) { 2497 dumpResults = HELP_MSG_DUMP_FAILED + "\n"; 2498 } 2499 resultReceiver_.append(dumpResults); 2500 } 2501 APP_LOGI("end"); 2502 return result; 2503} 2504 2505ErrCode BundleManagerShellCommand::ParseSharedCommand(int32_t option, std::string &bundleName, bool &dumpSharedAll) 2506{ 2507 int32_t result = OHOS::ERR_OK; 2508 if (option == '?') { 2509 switch (optopt) { 2510 case 'n': { 2511 // 'bm dump-shared -n' with no argument: bm dump-shared -n 2512 // 'bm dump-shared --bundle-name' with no argument: bm dump-shared --bundle-name 2513 resultReceiver_.append(STRING_REQUIRE_CORRECT_VALUE); 2514 result = OHOS::ERR_INVALID_VALUE; 2515 break; 2516 } 2517 default: { 2518 // 'bm dump-shared' with an unknown option: bm dump-shared -x 2519 // 'bm dump-shared' with an unknown option: bm dump-shared -xxx 2520 std::string unknownOption = ""; 2521 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); 2522 resultReceiver_.append(unknownOptionMsg); 2523 result = OHOS::ERR_INVALID_VALUE; 2524 break; 2525 } 2526 } 2527 } else { 2528 switch (option) { 2529 case 'h': { 2530 // 'bm dump-shared -h' 2531 // 'bm dump-shared --help' 2532 result = OHOS::ERR_INVALID_VALUE; 2533 break; 2534 } 2535 case 'n': { 2536 // 'bm dump-shared -n xxx' 2537 // 'bm dump-shared --bundle-name xxx' 2538 bundleName = optarg; 2539 break; 2540 } 2541 case 'a': { 2542 // 'bm dump-shared -a' 2543 // 'bm dump-shared --all' 2544 dumpSharedAll = true; 2545 break; 2546 } 2547 default: { 2548 result = OHOS::ERR_INVALID_VALUE; 2549 break; 2550 } 2551 } 2552 } 2553 return result; 2554} 2555 2556std::string BundleManagerShellCommand::DumpShared(const std::string &bundleName) const 2557{ 2558 APP_LOGD("DumpShared bundleName: %{public}s", bundleName.c_str()); 2559 SharedBundleInfo sharedBundleInfo; 2560 ErrCode ret = bundleMgrProxy_->GetSharedBundleInfoBySelf(bundleName, sharedBundleInfo); 2561 nlohmann::json sharedBundleInfoJson; 2562 if (ret != ERR_OK) { 2563 APP_LOGE("dump-shared failed due to errcode %{public}d", ret); 2564 return std::string(); 2565 } else { 2566 sharedBundleInfoJson = nlohmann::json {{SHARED_BUNDLE_INFO, sharedBundleInfo}}; 2567 } 2568 return sharedBundleInfoJson.dump(Constants::DUMP_INDENT); 2569} 2570 2571std::string BundleManagerShellCommand::DumpSharedAll() const 2572{ 2573 APP_LOGD("DumpSharedAll"); 2574 std::string dumpResults = ""; 2575 std::vector<SharedBundleInfo> sharedBundleInfos; 2576 ErrCode ret = bundleMgrProxy_->GetAllSharedBundleInfo(sharedBundleInfos); 2577 if (ret != ERR_OK) { 2578 APP_LOGE("dump-shared all failed due to errcode %{public}d", ret); 2579 return dumpResults; 2580 } 2581 for (const auto& item : sharedBundleInfos) { 2582 dumpResults.append("\t"); 2583 dumpResults.append(item.name); 2584 dumpResults.append("\n"); 2585 } 2586 return dumpResults; 2587} 2588 2589ErrCode BundleManagerShellCommand::DeployQuickFixDisable(const std::vector<std::string> &quickFixFiles, 2590 std::shared_ptr<QuickFixResult> &quickFixRes, bool isDebug, const std::string &targetPath) const 2591{ 2592 std::set<std::string> realPathSet; 2593 for (const auto &quickFixPath : quickFixFiles) { 2594 std::string realPath; 2595 if (!PathToRealPath(quickFixPath, realPath)) { 2596 APP_LOGW("quickFixPath %{public}s is invalid", quickFixPath.c_str()); 2597 continue; 2598 } 2599 APP_LOGD("realPath is %{public}s", realPath.c_str()); 2600 realPathSet.insert(realPath); 2601 } 2602 std::vector<std::string> pathVec(realPathSet.begin(), realPathSet.end()); 2603 2604 sptr<QuickFixStatusCallbackHostlmpl> callback(new (std::nothrow) QuickFixStatusCallbackHostlmpl()); 2605 if (callback == nullptr || bundleMgrProxy_ == nullptr) { 2606 APP_LOGE("callback or bundleMgrProxy is null"); 2607 return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR; 2608 } 2609 sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(nullptr, callback)); 2610 if (recipient == nullptr) { 2611 APP_LOGE("recipient is null"); 2612 return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR; 2613 } 2614 bundleMgrProxy_->AsObject()->AddDeathRecipient(recipient); 2615 auto quickFixProxy = bundleMgrProxy_->GetQuickFixManagerProxy(); 2616 if (quickFixProxy == nullptr) { 2617 APP_LOGE("quickFixProxy is null"); 2618 return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR; 2619 } 2620 std::vector<std::string> destFiles; 2621 auto res = quickFixProxy->CopyFiles(pathVec, destFiles); 2622 if (res != ERR_OK) { 2623 APP_LOGE("Copy files failed with %{public}d.", res); 2624 return res; 2625 } 2626 res = quickFixProxy->DeployQuickFix(destFiles, callback, isDebug, targetPath); 2627 if (res != ERR_OK) { 2628 APP_LOGE("DeployQuickFix failed"); 2629 return res; 2630 } 2631 return callback->GetResultCode(quickFixRes); 2632} 2633 2634ErrCode BundleManagerShellCommand::DeleteQuickFix(const std::string &bundleName, 2635 std::shared_ptr<QuickFixResult> &quickFixRes) const 2636{ 2637 APP_LOGD("DeleteQuickFix bundleName: %{public}s", bundleName.c_str()); 2638 sptr<QuickFixStatusCallbackHostlmpl> callback(new (std::nothrow) QuickFixStatusCallbackHostlmpl()); 2639 if (callback == nullptr || bundleMgrProxy_ == nullptr) { 2640 APP_LOGE("callback or bundleMgrProxy is null"); 2641 return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR; 2642 } 2643 sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(nullptr, callback)); 2644 if (recipient == nullptr) { 2645 APP_LOGE("recipient is null"); 2646 return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR; 2647 } 2648 bundleMgrProxy_->AsObject()->AddDeathRecipient(recipient); 2649 auto quickFixProxy = bundleMgrProxy_->GetQuickFixManagerProxy(); 2650 if (quickFixProxy == nullptr) { 2651 APP_LOGE("quickFixProxy is null"); 2652 return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR; 2653 } 2654 auto res = quickFixProxy->DeleteQuickFix(bundleName, callback); 2655 if (res != ERR_OK) { 2656 APP_LOGE("DeleteQuickFix failed"); 2657 return res; 2658 } 2659 return callback->GetResultCode(quickFixRes); 2660} 2661} // namespace AppExecFwk 2662} // namespace OHOS 2663