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
25 #include "app_log_wrapper.h"
26 #include "bundle_death_recipient.h"
27 #include "bundle_mgr_client.h"
28 #include "clean_cache_callback_host.h"
29 #include "if_system_ability_manager.h"
30 #include "iservice_registry.h"
31 #include "os_account_info.h"
32 #include "os_account_manager.h"
33 #include "parameter.h"
34 #include "status_receiver_impl.h"
35 #include "system_ability_definition.h"
36
37 namespace OHOS {
38 namespace AppExecFwk {
39 namespace {
40 const std::string BUNDLE_NAME_EMPTY = "";
41 const int32_t INDEX_OFFSET = 2;
42 const int32_t MAX_WAITING_TIME = 3000;
43 const int32_t DEVICE_UDID_LENGTH = 65;
44 const int32_t MAX_ARGUEMENTS_NUMBER = 3;
45 const std::string SHORT_OPTIONS = "hp:rfn:m:a:cdu:";
46 const struct option LONG_OPTIONS[] = {
47 {"help", no_argument, nullptr, 'h'},
48 {"bundle-path", required_argument, nullptr, 'p'},
49 {"replace", no_argument, nullptr, 'r'},
50 {"bundle-name", required_argument, nullptr, 'n'},
51 {"module-name", required_argument, nullptr, 'm'},
52 {"ability-name", required_argument, nullptr, 'a'},
53 {"bundle-info", no_argument, nullptr, 'i'},
54 {"cache", no_argument, nullptr, 'c'},
55 {"data", no_argument, nullptr, 'd'},
56 {"user-id", required_argument, nullptr, 'u'},
57 {nullptr, 0, nullptr, 0},
58 };
59
60 const std::string SHORT_OPTIONS_DUMP = "hn:aisu:d:";
61 const struct option LONG_OPTIONS_DUMP[] = {
62 {"help", no_argument, nullptr, 'h'},
63 {"bundle-name", required_argument, nullptr, 'n'},
64 {"all", no_argument, nullptr, 'a'},
65 {"bundle-info", no_argument, nullptr, 'i'},
66 {"shortcut-info", no_argument, nullptr, 's'},
67 {"user-id", required_argument, nullptr, 'u'},
68 {"device-id", required_argument, nullptr, 'd'},
69 {nullptr, 0, nullptr, 0},
70 };
71
72 const std::string SHORT_OPTIONS_GET = "hu";
73 const struct option LONG_OPTIONS_GET[] = {
74 {"help", no_argument, nullptr, 'h'},
75 {"udid", no_argument, nullptr, 'u'},
76 {nullptr, 0, nullptr, 0},
77 };
78 } // namespace
79
80 class CleanCacheCallbackImpl : public CleanCacheCallbackHost {
81 public:
CleanCacheCallbackImpl()82 CleanCacheCallbackImpl()
83 {
84 signal_ = std::make_shared<std::promise<bool>>();
85 }
~CleanCacheCallbackImpl()86 virtual ~CleanCacheCallbackImpl() override
87 {}
88 virtual void OnCleanCacheFinished(bool error) override;
89 bool GetResultCode();
90 private:
91 std::shared_ptr<std::promise<bool>> signal_;
92 DISALLOW_COPY_AND_MOVE(CleanCacheCallbackImpl);
93 };
94
OnCleanCacheFinished(bool error)95 void CleanCacheCallbackImpl::OnCleanCacheFinished(bool error)
96 {
97 if (signal_ != nullptr) {
98 signal_->set_value(!error);
99 }
100 }
101
GetResultCode()102 bool CleanCacheCallbackImpl::GetResultCode()
103 {
104 if (signal_ != nullptr) {
105 auto future = signal_->get_future();
106 std::chrono::milliseconds span(MAX_WAITING_TIME);
107 if (future.wait_for(span) == std::future_status::timeout) {
108 return false;
109 }
110 return future.get();
111 }
112 return false;
113 }
114
BundleManagerShellCommand(int argc,char * argv[])115 BundleManagerShellCommand::BundleManagerShellCommand(int argc, char *argv[]) : ShellCommand(argc, argv, TOOL_NAME)
116 {}
117
CreateCommandMap()118 ErrCode BundleManagerShellCommand::CreateCommandMap()
119 {
120 commandMap_ = {
121 {"help", std::bind(&BundleManagerShellCommand::RunAsHelpCommand, this)},
122 {"install", std::bind(&BundleManagerShellCommand::RunAsInstallCommand, this)},
123 {"uninstall", std::bind(&BundleManagerShellCommand::RunAsUninstallCommand, this)},
124 {"dump", std::bind(&BundleManagerShellCommand::RunAsDumpCommand, this)},
125 {"clean", std::bind(&BundleManagerShellCommand::RunAsCleanCommand, this)},
126 {"enable", std::bind(&BundleManagerShellCommand::RunAsEnableCommand, this)},
127 {"disable", std::bind(&BundleManagerShellCommand::RunAsDisableCommand, this)},
128 {"get", std::bind(&BundleManagerShellCommand::RunAsGetCommand, this)},
129 };
130
131 return OHOS::ERR_OK;
132 }
133
CreateMessageMap()134 ErrCode BundleManagerShellCommand::CreateMessageMap()
135 {
136 messageMap_ = {
137 // error + message
138 {
139 IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR,
140 "error: install internal error.",
141 },
142 {
143 IStatusReceiver::ERR_INSTALL_HOST_INSTALLER_FAILED,
144 "error: install host installer failed.",
145 },
146 {
147 IStatusReceiver::ERR_INSTALL_PARSE_FAILED,
148 "error: install parse failed.",
149 },
150 {
151 IStatusReceiver::ERR_INSTALL_VERSION_DOWNGRADE,
152 "error: install version downgrade.",
153 },
154 {
155 IStatusReceiver::ERR_INSTALL_VERIFICATION_FAILED,
156 "error: install verification failed.",
157 },
158 {
159 IStatusReceiver::ERR_INSTALL_FAILED_INVALID_SIGNATURE_FILE_PATH,
160 "error: signature file path is invalid.",
161 },
162 {
163 IStatusReceiver::ERR_INSTALL_FAILED_BAD_BUNDLE_SIGNATURE_FILE,
164 "error: cannot open signature file.",
165 },
166 {
167 IStatusReceiver::ERR_INSTALL_FAILED_NO_BUNDLE_SIGNATURE,
168 "error: no signature file.",
169 },
170 {
171 IStatusReceiver::ERR_INSTALL_FAILED_VERIFY_APP_PKCS7_FAIL,
172 "error: fail to verify pkcs7 file.",
173 },
174 {
175 IStatusReceiver::ERR_INSTALL_FAILED_PROFILE_PARSE_FAIL,
176 "error: fail to parse signature file.",
177 },
178 {
179 IStatusReceiver::ERR_INSTALL_FAILED_APP_SOURCE_NOT_TRUESTED,
180 "error: signature verification failed due to not trusted app source.",
181 },
182 {
183 IStatusReceiver::ERR_INSTALL_FAILED_BAD_DIGEST,
184 "error: signature verification failed due to not bad digest.",
185 },
186 {
187 IStatusReceiver::ERR_INSTALL_FAILED_BUNDLE_INTEGRITY_VERIFICATION_FAILURE,
188 "error: signature verification failed due to out of integrity.",
189 },
190 {
191 IStatusReceiver::ERR_INSTALL_FAILED_FILE_SIZE_TOO_LARGE,
192 "error: signature verification failed due to oversize file.",
193 },
194 {
195 IStatusReceiver::ERR_INSTALL_FAILED_BAD_PUBLICKEY,
196 "error: signature verification failed due to bad public key.",
197 },
198 {
199 IStatusReceiver::ERR_INSTALL_FAILED_BAD_BUNDLE_SIGNATURE,
200 "error: signature verification failed due to bad bundle signature.",
201 },
202 {
203 IStatusReceiver::ERR_INSTALL_FAILED_NO_PROFILE_BLOCK_FAIL,
204 "error: signature verification failed due to no profile block.",
205 },
206 {
207 IStatusReceiver::ERR_INSTALL_FAILED_BUNDLE_SIGNATURE_VERIFICATION_FAILURE,
208 "error: verify signature failed.",
209 },
210 {
211 IStatusReceiver::ERR_INSTALL_FAILED_VERIFY_SOURCE_INIT_FAIL,
212 "error: signature verification failed due to init source failed.",
213 },
214 {
215 IStatusReceiver::ERR_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE,
216 "error: install incompatible signature info.",
217 },
218 {
219 IStatusReceiver::ERR_INSTALL_FAILED_INCONSISTENT_SIGNATURE,
220 "error: install sign info inconsistent.",
221 },
222 {
223 IStatusReceiver::ERR_INSTALL_PARAM_ERROR,
224 "error: install param error.",
225 },
226 {
227 IStatusReceiver::ERR_INSTALL_PERMISSION_DENIED,
228 "error: install permission denied.",
229 },
230 {
231 IStatusReceiver::ERR_INSTALL_ENTRY_ALREADY_EXIST,
232 "error: install entry already exist.",
233 },
234 {
235 IStatusReceiver::ERR_INSTALL_STATE_ERROR,
236 "error: install state error.",
237 },
238 {
239 IStatusReceiver::ERR_INSTALL_FILE_PATH_INVALID,
240 "error: install file path invalid.",
241 },
242 {
243 IStatusReceiver::ERR_INSTALL_INVALID_HAP_NAME,
244 "error: install invalid hap name.",
245 },
246 {
247 IStatusReceiver::ERR_INSTALL_INVALID_BUNDLE_FILE,
248 "error: install invalid bundle file.",
249 },
250 {
251 IStatusReceiver::ERR_INSTALL_INVALID_HAP_SIZE,
252 "error: install invalid hap size.",
253 },
254 {
255 IStatusReceiver::ERR_INSTALL_GENERATE_UID_ERROR,
256 "error: install generate uid error.",
257 },
258 {
259 IStatusReceiver::ERR_INSTALL_INSTALLD_SERVICE_ERROR,
260 "error: install installd service error.",
261 },
262 {
263 IStatusReceiver::ERR_INSTALL_BUNDLE_MGR_SERVICE_ERROR,
264 "error: install bundle mgr service error.",
265 },
266 {
267 IStatusReceiver::ERR_INSTALL_ALREADY_EXIST,
268 "error: install already exist.",
269 },
270 {
271 IStatusReceiver::ERR_INSTALL_BUNDLENAME_NOT_SAME,
272 "error: install bundle name not same",
273 },
274 {
275 IStatusReceiver::ERR_INSTALL_VERSIONCODE_NOT_SAME,
276 "error: install version code not same",
277 },
278 {
279 IStatusReceiver::ERR_INSTALL_VERSIONNAME_NOT_SAME,
280 "error: install version name not same",
281 },
282 {
283 IStatusReceiver::ERR_INSTALL_VENDOR_NOT_SAME,
284 "error: install vendor not same",
285 },
286 {
287 IStatusReceiver::ERR_INSTALL_RELEASETYPE_TARGET_NOT_SAME,
288 "error: install releaseType target not same",
289 },
290 {
291 IStatusReceiver::ERR_INSTALL_RELEASETYPE_COMPATIBLE_NOT_SAME,
292 "error: install releaseType compatible not same",
293 },
294 {
295 IStatusReceiver::ERR_INSTALL_VERSION_NOT_COMPATIBLE,
296 "error: install version not compatible",
297 },
298 {
299 IStatusReceiver::ERR_INSTALL_INVALID_NUMBER_OF_ENTRY_HAP,
300 "error: install invalid number of entry hap",
301 },
302 {
303 IStatusReceiver::ERR_INSTALL_DISK_MEM_INSUFFICIENT,
304 "error: install failed due to insufficient disk memory",
305 },
306 {
307 IStatusReceiver::ERR_INSTALL_GRANT_REQUEST_PERMISSIONS_FAILED,
308 "error: install failed due to grant request permissions failed",
309 },
310 {
311 IStatusReceiver::ERR_INSTALL_UPDATE_HAP_TOKEN_FAILED,
312 "error: install failed due to update hap token failed",
313 },
314 {
315 IStatusReceiver::ERR_INSTALL_SINGLETON_NOT_SAME,
316 "error: install failed due to singleton not same",
317 },
318 {
319 IStatusReceiver::ERR_INSTALL_ZERO_USER_WITH_NO_SINGLETON,
320 "error: install failed due to zero user can only install singleton app",
321 },
322 {
323 IStatusReceiver::ERR_INSTALL_CHECK_SYSCAP_FAILED,
324 "error: install failed due to check syscap filed",
325 },
326 {
327 IStatusReceiver::ERR_INSTALL_APPTYPE_NOT_SAME,
328 "error: install failed due to apptype not same",
329 },
330 {
331 IStatusReceiver::ERR_INSTALL_URI_DUPLICATE,
332 "error: install failed due to uri prefix duplicate",
333 },
334 {
335 IStatusReceiver::ERR_INSTALL_PARSE_UNEXPECTED,
336 "error: install parse unexpected.",
337 },
338 {
339 IStatusReceiver::ERR_INSTALL_PARSE_MISSING_BUNDLE,
340 "error: install parse missing bundle.",
341 },
342 {
343 IStatusReceiver::ERR_INSTALL_PARSE_MISSING_ABILITY,
344 "error: install parse missing ability.",
345 },
346 {
347 IStatusReceiver::ERR_INSTALL_PARSE_NO_PROFILE,
348 "error: install parse no profile.",
349 },
350 {
351 IStatusReceiver::ERR_INSTALL_PARSE_BAD_PROFILE,
352 "error: install parse bad profile.",
353 },
354 {
355 IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_PROP_TYPE_ERROR,
356 "error: install parse profile prop type error.",
357 },
358 {
359 IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_MISSING_PROP,
360 "error: install parse profile missing prop.",
361 },
362 {
363 IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_PROP_CHECK_ERROR,
364 "error: install parse profile prop check error.",
365 },
366 {
367 IStatusReceiver::ERR_INSTALL_PARSE_PERMISSION_ERROR,
368 "error: install parse permission error.",
369 },
370 {
371 IStatusReceiver::ERR_INSTALL_PARSE_RPCID_FAILED,
372 "error: install parse syscap error.",
373 },
374 {
375 IStatusReceiver::ERR_INSTALLD_PARAM_ERROR,
376 "error: installd param error.",
377 },
378 {
379 IStatusReceiver::ERR_INSTALLD_GET_PROXY_ERROR,
380 "error: installd get proxy error.",
381 },
382 {
383 IStatusReceiver::ERR_INSTALLD_CREATE_DIR_FAILED,
384 "error: installd create dir failed.",
385 },
386 {
387 IStatusReceiver::ERR_INSTALLD_CREATE_DIR_EXIST,
388 "error: installd create dir exist.",
389 },
390 {
391 IStatusReceiver::ERR_INSTALLD_CHOWN_FAILED,
392 "error: installd chown failed.",
393 },
394 {
395 IStatusReceiver::ERR_INSTALLD_REMOVE_DIR_FAILED,
396 "error: installd remove dir failed.",
397 },
398 {
399 IStatusReceiver::ERR_INSTALLD_EXTRACT_FILES_FAILED,
400 "error: installd extract files failed.",
401 },
402 {
403 IStatusReceiver::ERR_INSTALLD_RNAME_DIR_FAILED,
404 "error: installd rename dir failed.",
405 },
406 {
407 IStatusReceiver::ERR_INSTALLD_CLEAN_DIR_FAILED,
408 "error: installd clean dir failed.",
409 },
410
411 {
412 IStatusReceiver::ERR_UNINSTALL_SYSTEM_APP_ERROR,
413 "error: uninstall system app error.",
414 },
415 {
416 IStatusReceiver::ERR_UNINSTALL_KILLING_APP_ERROR,
417 "error: uninstall killing app error.",
418 },
419 {
420 IStatusReceiver::ERR_UNINSTALL_INVALID_NAME,
421 "error: uninstall invalid name.",
422 },
423 {
424 IStatusReceiver::ERR_UNINSTALL_PARAM_ERROR,
425 "error: uninstall param error.",
426 },
427 {
428 IStatusReceiver::ERR_UNINSTALL_PERMISSION_DENIED,
429 "error: uninstall permission denied.",
430 },
431 {
432 IStatusReceiver::ERR_UNINSTALL_BUNDLE_MGR_SERVICE_ERROR,
433 "error: uninstall bundle mgr service error.",
434 },
435 {
436 IStatusReceiver::ERR_UNINSTALL_MISSING_INSTALLED_BUNDLE,
437 "error: uninstall missing installed bundle.",
438 },
439 {
440 IStatusReceiver::ERR_UNINSTALL_MISSING_INSTALLED_MODULE,
441 "error: uninstall missing installed module.",
442 },
443 {
444 IStatusReceiver::ERR_FAILED_SERVICE_DIED,
445 "error: bundle manager service is died",
446 },
447 {
448 IStatusReceiver::ERR_FAILED_GET_INSTALLER_PROXY,
449 "error: failed to get installer proxy",
450 },
451 {
452 IStatusReceiver::ERR_USER_NOT_EXIST,
453 "error: user not exist.",
454 },
455 {
456 IStatusReceiver::ERR_USER_NOT_INSTALL_HAP,
457 "error: user does not install the hap.",
458 },
459 {
460 IStatusReceiver::ERR_OPERATION_TIME_OUT,
461 "error: operation time out.",
462 },
463 {
464 IStatusReceiver::ERR_INSTALL_NOT_UNIQUE_DISTRO_MODULE_NAME,
465 "error: moduleName is not unique.",
466 },
467 {
468 IStatusReceiver::ERR_INSTALL_INCONSISTENT_MODULE_NAME,
469 "error: moduleName is inconsistent.",
470 },
471 {
472 IStatusReceiver::ERR_UNKNOWN,
473 "error: unknown.",
474 }
475 };
476
477 return OHOS::ERR_OK;
478 }
479
init()480 ErrCode BundleManagerShellCommand::init()
481 {
482 ErrCode result = OHOS::ERR_OK;
483
484 if (!bundleMgrProxy_) {
485 bundleMgrProxy_ = GetBundleMgrProxy();
486 if (bundleMgrProxy_) {
487 if (!bundleInstallerProxy_) {
488 bundleInstallerProxy_ = bundleMgrProxy_->GetBundleInstaller();
489 }
490 }
491 }
492
493 if (!bundleMgrProxy_ || !bundleInstallerProxy_ || !bundleInstallerProxy_->AsObject()) {
494 result = OHOS::ERR_INVALID_VALUE;
495 }
496
497 return result;
498 }
499
GetBundleMgrProxy() const500 sptr<IBundleMgr> BundleManagerShellCommand::GetBundleMgrProxy() const
501 {
502 sptr<ISystemAbilityManager> systemAbilityManager =
503 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
504 if (!systemAbilityManager) {
505 APP_LOGE("failed to get system ability mgr.");
506 return nullptr;
507 }
508
509 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
510 if (!remoteObject) {
511 APP_LOGE("failed to get bundle manager proxy.");
512 return nullptr;
513 }
514
515 APP_LOGD("get bundle manager proxy success.");
516 return iface_cast<IBundleMgr>(remoteObject);
517 }
518
GetInstallerProxy() const519 sptr<IBundleInstaller> BundleManagerShellCommand::GetInstallerProxy() const
520 {
521 sptr<IBundleMgr> bundleMgrProxy = GetBundleMgrProxy();
522 if (!bundleMgrProxy) {
523 APP_LOGE("bundle mgr proxy is nullptr.");
524 return nullptr;
525 }
526
527 sptr<IBundleInstaller> installerProxy = bundleMgrProxy->GetBundleInstaller();
528 if (!installerProxy) {
529 APP_LOGE("failed to get bundle installer proxy.");
530 return nullptr;
531 }
532
533 APP_LOGD("get bundle installer proxy success.");
534 return installerProxy;
535 }
536
RunAsHelpCommand()537 ErrCode BundleManagerShellCommand::RunAsHelpCommand()
538 {
539 resultReceiver_.append(HELP_MSG);
540
541 return OHOS::ERR_OK;
542 }
543
RunAsInstallCommand()544 ErrCode BundleManagerShellCommand::RunAsInstallCommand()
545 {
546 int result = OHOS::ERR_OK;
547 InstallFlag installFlag = InstallFlag::NORMAL;
548 int option = -1;
549 int counter = 0;
550 std::vector<std::string> bundlePath;
551 int index = 0;
552 int32_t userId = Constants::ALL_USERID;
553 while (true) {
554 counter++;
555 option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
556 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
557 if (optind < 0 || optind > argc_) {
558 return OHOS::ERR_INVALID_VALUE;
559 }
560 if (option == -1) {
561 if (counter == 1) {
562 // When scanning the first argument
563 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
564 // 'bm install' with no option: bm install
565 // 'bm install' with a wrong argument: bm install xxx
566 APP_LOGD("'bm install' with no option.");
567 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
568 result = OHOS::ERR_INVALID_VALUE;
569 }
570 }
571 break;
572 }
573
574 if (option == '?') {
575 switch (optopt) {
576 case 'p': {
577 // 'bm install -p' with no argument: bm install -p
578 // 'bm install --bundle-path' with no argument: bm install --bundle-path
579 APP_LOGD("'bm install' with no argument.");
580 resultReceiver_.append("error: option ");
581 resultReceiver_.append("requires a value.\n");
582 result = OHOS::ERR_INVALID_VALUE;
583 break;
584 }
585 case 'u': {
586 // 'bm install -u' with no argument: bm install -u
587 // 'bm install --user-id' with no argument: bm install --user-id
588 APP_LOGD("'bm install -u' with no argument.");
589 resultReceiver_.append("error: option ");
590 resultReceiver_.append("requires a value.\n");
591 result = OHOS::ERR_INVALID_VALUE;
592 break;
593 }
594 default: {
595 // 'bm install' with an unknown option: bm install -x
596 // 'bm install' with an unknown option: bm install -xxx
597 std::string unknownOption = "";
598 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
599 APP_LOGD("'bm install' with an unknown option.");
600 resultReceiver_.append(unknownOptionMsg);
601 result = OHOS::ERR_INVALID_VALUE;
602 break;
603 }
604 }
605 break;
606 }
607
608 switch (option) {
609 case 'h': {
610 // 'bm install -h'
611 // 'bm install --help'
612 APP_LOGD("'bm install %{public}s'", argv_[optind - 1]);
613 result = OHOS::ERR_INVALID_VALUE;
614 break;
615 }
616 case 'p': {
617 // 'bm install -p <bundle-file-path>'
618 // 'bm install --bundle-path <bundle-file-path>'
619 APP_LOGD("'bm install %{public}s'", argv_[optind - 1]);
620 if (GetBundlePath(optarg, bundlePath) != OHOS::ERR_OK) {
621 APP_LOGD("'bm install' with no argument.");
622 resultReceiver_.append("error: option ");
623 resultReceiver_.append("requires a correct value.\n");
624 return OHOS::ERR_INVALID_VALUE;
625 }
626 index = optind;
627 break;
628 }
629 case 'r': {
630 // 'bm install -r'
631 // 'bm install --replace'
632 installFlag = InstallFlag::REPLACE_EXISTING;
633 break;
634 }
635 case 'u': {
636 // 'bm install -p <bundle-file-path> -u userId'
637 // 'bm install --bundle-path <bundle-file-path> --user-id userId'
638 APP_LOGD("'bm install %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg);
639 userId = atoi(optarg);
640 break;
641 }
642 default: {
643 result = OHOS::ERR_INVALID_VALUE;
644 break;
645 }
646 }
647 }
648
649 for (; index < argc_ && index >= INDEX_OFFSET; ++index) {
650 if (argList_[index - INDEX_OFFSET] == "-r" || argList_[index - INDEX_OFFSET] == "-f" ||
651 argList_[index - INDEX_OFFSET] == "--force" || argList_[index - INDEX_OFFSET] == "--replace" ||
652 argList_[index - INDEX_OFFSET] == "-p" || argList_[index - INDEX_OFFSET] == "--bundle-path" ||
653 argList_[index - INDEX_OFFSET] == "-u" || argList_[index - INDEX_OFFSET] == "--user-id") {
654 break;
655 }
656 if (GetBundlePath(argList_[index - INDEX_OFFSET], bundlePath) != OHOS::ERR_OK) {
657 bundlePath.clear();
658 APP_LOGD("'bm install' with error arguments.");
659 resultReceiver_.append("error value for the chosen option");
660 result = OHOS::ERR_INVALID_VALUE;
661 }
662 }
663
664 for (auto &path : bundlePath) {
665 APP_LOGD("install hap path %{public}s", path.c_str());
666 }
667
668 if (result == OHOS::ERR_OK) {
669 if (resultReceiver_ == "" && bundlePath.empty()) {
670 // 'bm install ...' with no bundle path option
671 APP_LOGD("'bm install' with no bundle path option.");
672 resultReceiver_.append(HELP_MSG_NO_BUNDLE_PATH_OPTION + "\n");
673 result = OHOS::ERR_INVALID_VALUE;
674 }
675 }
676
677 if (result != OHOS::ERR_OK) {
678 resultReceiver_.append(HELP_MSG_INSTALL);
679 } else {
680 InstallParam installParam;
681 installParam.installFlag = installFlag;
682 installParam.userId = userId;
683 int32_t installResult = InstallOperation(bundlePath, installParam);
684 if (installResult == OHOS::ERR_OK) {
685 resultReceiver_ = STRING_INSTALL_BUNDLE_OK + "\n";
686 } else {
687 resultReceiver_ = STRING_INSTALL_BUNDLE_NG + "\n";
688 resultReceiver_.append(GetMessageFromCode(installResult));
689 }
690 }
691
692 return result;
693 }
694
GetBundlePath(const std::string & param,std::vector<std::string> & bundlePaths) const695 ErrCode BundleManagerShellCommand::GetBundlePath(const std::string& param,
696 std::vector<std::string>& bundlePaths) const
697 {
698 if (param.empty()) {
699 return OHOS::ERR_INVALID_VALUE;
700 }
701 if (param == "-f" || param == "--force" || param == "-r" || param == "--replace" || param == "-p" ||
702 param == "--bundle-path" || param == "-u" || param == "--user-id") {
703 return OHOS::ERR_INVALID_VALUE;
704 }
705 bundlePaths.emplace_back(param);
706 return OHOS::ERR_OK;
707 }
708
RunAsUninstallCommand()709 ErrCode BundleManagerShellCommand::RunAsUninstallCommand()
710 {
711 int result = OHOS::ERR_OK;
712 int option = -1;
713 int counter = 0;
714 std::string bundleName = "";
715 std::string moduleName = "";
716 int32_t userId = Constants::ALL_USERID;
717 while (true) {
718 counter++;
719 option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
720 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
721 if (optind < 0 || optind > argc_) {
722 return OHOS::ERR_INVALID_VALUE;
723 }
724 if (option == -1) {
725 if (counter == 1) {
726 // When scanning the first argument
727 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
728 // 'bm uninstall' with no option: bm uninstall
729 // 'bm uninstall' with a wrong argument: bm uninstall xxx
730 APP_LOGD("'bm uninstall' %{public}s", HELP_MSG_NO_OPTION.c_str());
731 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
732 result = OHOS::ERR_INVALID_VALUE;
733 }
734 }
735 break;
736 }
737
738 if (option == '?') {
739 switch (optopt) {
740 case 'n': {
741 // 'bm uninstall -n' with no argument: bm uninstall -n
742 // 'bm uninstall --bundle-name' with no argument: bm uninstall --bundle-name
743 APP_LOGD("'bm uninstall -n' with no argument.");
744 resultReceiver_.append("error: option ");
745 resultReceiver_.append("requires a value.\n");
746 result = OHOS::ERR_INVALID_VALUE;
747 break;
748 }
749 case 'm': {
750 // 'bm uninstall -m' with no argument: bm uninstall -m
751 // 'bm uninstall --module-name' with no argument: bm uninstall --module-name
752 APP_LOGD("'bm uninstall -m' with no argument.");
753 resultReceiver_.append("error: option ");
754 resultReceiver_.append("requires a value.\n");
755 result = OHOS::ERR_INVALID_VALUE;
756 break;
757 }
758 case 'u': {
759 // 'bm uninstall -n <bundleName> -u userId'
760 // 'bm uninstall --bundle-name <bundleName> --user-id userId'
761 APP_LOGD("'bm uninstall -u' with no argument.");
762 resultReceiver_.append("error: option ");
763 resultReceiver_.append("requires a value.\n");
764 result = OHOS::ERR_INVALID_VALUE;
765 break;
766 }
767 default: {
768 // 'bm uninstall' with an unknown option: bm uninstall -x
769 // 'bm uninstall' with an unknown option: bm uninstall -xxx
770 std::string unknownOption = "";
771 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
772 APP_LOGD("'bm uninstall' with an unknown option.");
773 resultReceiver_.append(unknownOptionMsg);
774 result = OHOS::ERR_INVALID_VALUE;
775 break;
776 }
777 }
778 break;
779 }
780
781 switch (option) {
782 case 'h': {
783 // 'bm uninstall -h'
784 // 'bm uninstall --help'
785 APP_LOGD("'bm uninstall %{public}s'", argv_[optind - 1]);
786 result = OHOS::ERR_INVALID_VALUE;
787 break;
788 }
789 case 'n': {
790 // 'bm uninstall -n xxx'
791 // 'bm uninstall --bundle-name xxx'
792 APP_LOGD("'bm uninstall %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg);
793 bundleName = optarg;
794 break;
795 }
796 case 'm': {
797 // 'bm uninstall -m xxx'
798 // 'bm uninstall --module-name xxx'
799 APP_LOGD("'bm uninstall %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg);
800 moduleName = optarg;
801 break;
802 }
803 case 'u': {
804 // 'bm uninstall -n <bundleName> -u userId'
805 // 'bm uninstall --bundle-name <bundleName> --user-id userId'
806 APP_LOGD("'bm uninstall %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg);
807 userId = atoi(optarg);
808 break;
809 }
810 default: {
811 result = OHOS::ERR_INVALID_VALUE;
812 break;
813 }
814 }
815 }
816
817 if (result == OHOS::ERR_OK) {
818 if (resultReceiver_ == "" && bundleName.size() == 0) {
819 // 'bm uninstall ...' with no bundle name option
820 APP_LOGD("'bm uninstall' with bundle name option.");
821 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n");
822 result = OHOS::ERR_INVALID_VALUE;
823 }
824 }
825
826 if (result != OHOS::ERR_OK) {
827 resultReceiver_.append(HELP_MSG_UNINSTALL);
828 } else {
829 InstallParam installParam;
830 installParam.userId = userId;
831 int32_t uninstallResult = UninstallOperation(bundleName, moduleName, installParam);
832 if (uninstallResult == OHOS::ERR_OK) {
833 resultReceiver_ = STRING_UNINSTALL_BUNDLE_OK + "\n";
834 } else {
835 resultReceiver_ = STRING_UNINSTALL_BUNDLE_NG + "\n";
836 resultReceiver_.append(GetMessageFromCode(uninstallResult));
837 }
838 }
839
840 return result;
841 }
842
RunAsDumpCommand()843 ErrCode BundleManagerShellCommand::RunAsDumpCommand()
844 {
845 int result = OHOS::ERR_OK;
846 int option = -1;
847 int counter = 0;
848 std::string dumpResults = "";
849 std::string bundleName = "";
850 bool bundleDumpAll = false;
851 bool bundleDumpInfos = false;
852 bool bundleDumpInfo = false;
853 bool bundleDumpShortcut = false;
854 bool bundleDumpDistributedBundleInfo = false;
855 std::string deviceId = "";
856 int32_t userId = Constants::ALL_USERID;
857 while (true) {
858 counter++;
859 option = getopt_long(argc_, argv_, SHORT_OPTIONS_DUMP.c_str(), LONG_OPTIONS_DUMP, nullptr);
860 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
861 if (optind < 0 || optind > argc_) {
862 return OHOS::ERR_INVALID_VALUE;
863 }
864 if (option == -1) {
865 if (counter == 1) {
866 // When scanning the first argument
867 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
868 // 'bm dump' with no option: bm dump
869 // 'bm dump' with a wrong argument: bm dump xxx
870 APP_LOGD("'bm dump' %{public}s", HELP_MSG_NO_OPTION.c_str());
871 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
872 result = OHOS::ERR_INVALID_VALUE;
873 }
874 }
875 break;
876 }
877 if (option == '?') {
878 switch (optopt) {
879 case 'n': {
880 // 'bm dump -n' with no argument: bm dump -n
881 // 'bm dump --bundle-name' with no argument: bm dump --bundle-name
882 APP_LOGD("'bm dump -n' with no argument.");
883 resultReceiver_.append("error: option ");
884 resultReceiver_.append("requires a value.\n");
885 result = OHOS::ERR_INVALID_VALUE;
886 break;
887 }
888 case 'u': {
889 // 'bm dump -u' with no argument: bm dump -u
890 // 'bm dump --user-id' with no argument: bm dump --user-id
891 APP_LOGD("'bm dump -u' with no argument.");
892 resultReceiver_.append("error: option ");
893 resultReceiver_.append("requires a value.\n");
894 result = OHOS::ERR_INVALID_VALUE;
895 break;
896 }
897 case 'd': {
898 // 'bm dump -d' with no argument: bm dump -d
899 // 'bm dump --device-id' with no argument: bm dump --device-id
900 APP_LOGD("'bm dump -d' with no argument.");
901 resultReceiver_.append("error: option ");
902 resultReceiver_.append("requires a value.\n");
903 result = OHOS::ERR_INVALID_VALUE;
904 break;
905 }
906 default: {
907 // 'bm dump' with an unknown option: bm dump -x
908 // 'bm dump' with an unknown option: bm dump -xxx
909 std::string unknownOption = "";
910 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
911 APP_LOGD("'bm dump' with an unknown option.");
912 resultReceiver_.append(unknownOptionMsg);
913 result = OHOS::ERR_INVALID_VALUE;
914 break;
915 }
916 }
917 break;
918 }
919 switch (option) {
920 case 'h': {
921 // 'bm dump -h'
922 // 'bm dump --help'
923 APP_LOGD("'bm dump %{public}s'", argv_[optind - 1]);
924 result = OHOS::ERR_INVALID_VALUE;
925 break;
926 }
927 case 'a': {
928 // 'bm dump -a'
929 // 'bm dump --all'
930 APP_LOGD("'bm dump %{public}s'", argv_[optind - 1]);
931 bundleDumpAll = true;
932 break;
933 }
934 case 'i': {
935 // 'bm dump -i'
936 // 'bm dump --bundle-info'
937 APP_LOGD("'bm dump %{public}s'", argv_[optind - 1]);
938 bundleDumpInfos = true;
939 break;
940 }
941 case 'n': {
942 // 'bm dump -n xxx'
943 // 'bm dump --bundle-name xxx'
944 APP_LOGD("'bm dump %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg);
945 bundleName = optarg;
946 bundleDumpInfo = true;
947 break;
948 }
949 case 's': {
950 // 'bm dump -n xxx -s'
951 // 'bm dump --bundle-name xxx --shortcut-info'
952 APP_LOGD("'bm dump %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg);
953 bundleDumpShortcut = true;
954 break;
955 }
956 case 'u': {
957 // 'bm dump -n <bundleName> -u userId'
958 // 'bm dump --bundle-name <bundleName> --user-id userId'
959 APP_LOGD("'bm dump %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg);
960 userId = atoi(optarg);
961 break;
962 }
963 case 'd': {
964 // 'bm dump -n <bundleName> -d deviceId'
965 // 'bm dump --bundle-name <bundleName> --device-id deviceId'
966 APP_LOGD("'bm dump %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg);
967 deviceId = optarg;
968 bundleDumpDistributedBundleInfo = true;
969 break;
970 }
971 default: {
972 result = OHOS::ERR_INVALID_VALUE;
973 break;
974 }
975 }
976 }
977 if (result == OHOS::ERR_OK) {
978 if ((resultReceiver_ == "") && bundleDumpShortcut && (bundleName.size() == 0)) {
979 // 'bm dump -s ...' with no bundle name option
980 APP_LOGD("'bm dump -s' with no bundle name option.");
981 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n");
982 result = OHOS::ERR_INVALID_VALUE;
983 }
984 if ((resultReceiver_ == "") && bundleDumpDistributedBundleInfo && (bundleName.size() == 0)) {
985 // 'bm dump d ...' with no bundle name option
986 APP_LOGD("'bm dump -d' with no bundle name option.");
987 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n");
988 result = OHOS::ERR_INVALID_VALUE;
989 }
990 }
991 if (result != OHOS::ERR_OK) {
992 resultReceiver_.append(HELP_MSG_DUMP);
993 } else {
994 APP_LOGD("dumpResults: %{public}s", dumpResults.c_str());
995 if (bundleDumpShortcut) {
996 dumpResults = DumpShortcutInfos(bundleName, userId);
997 } else if (bundleDumpDistributedBundleInfo) {
998 dumpResults = DumpDistributedBundleInfo(deviceId, userId, bundleName);
999 } else if (bundleDumpAll) {
1000 dumpResults = DumpBundleList(userId);
1001 } else if (bundleDumpInfos) {
1002 dumpResults = DumpBundleInfos(userId);
1003 } else if (bundleDumpInfo) {
1004 dumpResults = DumpBundleInfo(bundleName, userId);
1005 }
1006 if (dumpResults.empty() || (dumpResults == "")) {
1007 dumpResults = HELP_MSG_DUMP_FAILED + "\n";
1008 }
1009 resultReceiver_.append(dumpResults);
1010 }
1011
1012 return result;
1013 }
1014
RunAsCleanCommand()1015 ErrCode BundleManagerShellCommand::RunAsCleanCommand()
1016 {
1017 int32_t result = OHOS::ERR_OK;
1018 int32_t option = -1;
1019 int32_t counter = 0;
1020 int32_t userId = Constants::UNSPECIFIED_USERID;
1021 bool cleanCache = false;
1022 bool cleanData = false;
1023 std::string bundleName = "";
1024 while (true) {
1025 counter++;
1026 option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
1027 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
1028 if (optind < 0 || optind > argc_) {
1029 return OHOS::ERR_INVALID_VALUE;
1030 }
1031 if (option == -1) {
1032 if (counter == 1) {
1033 // When scanning the first argument
1034 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
1035 // 'bm clean' with no option: bm clean
1036 // 'bm clean' with a wrong argument: bm clean xxx
1037 APP_LOGD("'bm clean' %{public}s", HELP_MSG_NO_OPTION.c_str());
1038
1039 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
1040 result = OHOS::ERR_INVALID_VALUE;
1041 }
1042 }
1043 break;
1044 }
1045
1046 if (option == '?') {
1047 switch (optopt) {
1048 case 'n': {
1049 // 'bm clean -n' with no argument: bm clean -n
1050 // 'bm clean --bundle-name' with no argument: bm clean --bundle-name
1051 APP_LOGD("'bm clean -n' with no argument.");
1052 resultReceiver_.append("error: option ");
1053 resultReceiver_.append("requires a value.\n");
1054 result = OHOS::ERR_INVALID_VALUE;
1055 break;
1056 }
1057 case 'u': {
1058 // 'bm clean -u' with no argument: bm clean -u
1059 // 'bm clean --user-id' with no argument: bm clean --user-id
1060 APP_LOGD("'bm clean -u' with no argument.");
1061 resultReceiver_.append("error: option ");
1062 resultReceiver_.append("requires a value.\n");
1063 result = OHOS::ERR_INVALID_VALUE;
1064 break;
1065 }
1066 default: {
1067 // 'bm clean' with an unknown option: bm clear -x
1068 // 'bm clean' with an unknown option: bm clear -xxx
1069 std::string unknownOption = "";
1070 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1071 APP_LOGD("'bm clean' with an unknown option.");
1072 resultReceiver_.append(unknownOptionMsg);
1073 result = OHOS::ERR_INVALID_VALUE;
1074 break;
1075 }
1076 }
1077 break;
1078 }
1079
1080 switch (option) {
1081 case 'h': {
1082 // 'bm clean -h'
1083 // 'bm clean --help'
1084 APP_LOGD("'bm clean %{public}s'", argv_[optind - 1]);
1085 result = OHOS::ERR_INVALID_VALUE;
1086 break;
1087 }
1088 case 'n': {
1089 // 'bm clean -n xxx'
1090 // 'bm clean --bundle-name xxx'
1091 APP_LOGD("'bm clean %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg);
1092 bundleName = optarg;
1093 break;
1094 }
1095 case 'c': {
1096 // 'bm clean -c'
1097 // 'bm clean --cache'
1098 APP_LOGD("'bm clean %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT]);
1099 cleanCache = (cleanData == true) ? false : true;
1100 break;
1101 }
1102 case 'd': {
1103 // 'bm clean -d'
1104 // 'bm clean --data'
1105 APP_LOGD("'bm clean %{public}s '", argv_[optind - OFFSET_REQUIRED_ARGUMENT]);
1106 cleanData = (cleanCache == true) ? false : true;
1107 break;
1108 }
1109 case 'u': {
1110 // 'bm clean -u userId'
1111 // 'bm clean --user-id userId'
1112 APP_LOGD("'bm install %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg);
1113 userId = atoi(optarg);
1114 break;
1115 }
1116 default: {
1117 result = OHOS::ERR_INVALID_VALUE;
1118 break;
1119 }
1120 }
1121 }
1122
1123 if (result == OHOS::ERR_OK) {
1124 if (resultReceiver_ == "" && bundleName.size() == 0) {
1125 // 'bm clean ...' with no bundle name option
1126 APP_LOGD("'bm clean' with no bundle name option.");
1127 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n");
1128 result = OHOS::ERR_INVALID_VALUE;
1129 }
1130 if (!cleanCache && !cleanData) {
1131 APP_LOGD("'bm clean' with no '-c' or '-d' option.");
1132 resultReceiver_.append(HELP_MSG_NO_DATA_OR_CACHE_OPTION + "\n");
1133 result = OHOS::ERR_INVALID_VALUE;
1134 }
1135 }
1136
1137 if (result != OHOS::ERR_OK) {
1138 resultReceiver_.append(HELP_MSG_CLEAN);
1139 } else {
1140 // bm clean -c
1141 if (cleanCache) {
1142 if (CleanBundleCacheFilesOperation(bundleName, userId)) {
1143 resultReceiver_ = STRING_CLEAN_CACHE_BUNDLE_OK + "\n";
1144 } else {
1145 resultReceiver_ = STRING_CLEAN_CACHE_BUNDLE_NG + "\n";
1146 }
1147 }
1148 // bm clean -d
1149 if (cleanData) {
1150 if (CleanBundleDataFilesOperation(bundleName, userId)) {
1151 resultReceiver_.append(STRING_CLEAN_DATA_BUNDLE_OK + "\n");
1152 } else {
1153 resultReceiver_.append(STRING_CLEAN_DATA_BUNDLE_NG + "\n");
1154 }
1155 }
1156 }
1157 return result;
1158 }
1159
RunAsEnableCommand()1160 ErrCode BundleManagerShellCommand::RunAsEnableCommand()
1161 {
1162 int result = OHOS::ERR_OK;
1163 int option = -1;
1164 int counter = 0;
1165 std::string bundleName = "";
1166 std::string abilityName = "";
1167 int32_t userId = Constants::UNSPECIFIED_USERID;
1168 while (true) {
1169 counter++;
1170 option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
1171 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
1172 if (optind < 0 || optind > argc_) {
1173 return OHOS::ERR_INVALID_VALUE;
1174 }
1175
1176 if (option == -1) {
1177 if (counter == 1) {
1178 // When scanning the first argument
1179 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
1180 // 'bm enable' with no option: bm enable
1181 // 'bm enable' with a wrong argument: bm enable xxx
1182 APP_LOGD("'bm enable' with no option.");
1183 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
1184 result = OHOS::ERR_INVALID_VALUE;
1185 }
1186 }
1187 break;
1188 }
1189
1190 if (option == '?') {
1191 switch (optopt) {
1192 case 'n': {
1193 // 'bm enable -n' with no argument: bm enable -n
1194 // 'bm enable --bundle-name' with no argument: bm enable --bundle-name
1195 APP_LOGD("'bm enable -n' with no argument.");
1196 resultReceiver_.append("error: option ");
1197 resultReceiver_.append("requires a value.\n");
1198 result = OHOS::ERR_INVALID_VALUE;
1199 break;
1200 }
1201 case 'a': {
1202 // 'bm enable -a' with no argument: bm enable -a
1203 // 'bm enable --ability-name' with no argument: bm enable --ability-name
1204 APP_LOGD("'bm enable -a' with no argument.");
1205 resultReceiver_.append("error: option ");
1206 resultReceiver_.append("requires a value.\n");
1207 result = OHOS::ERR_INVALID_VALUE;
1208 break;
1209 }
1210 case 'u': {
1211 // 'bm enable -u' with no argument: bm enable -u
1212 // 'bm enable --user-id' with no argument: bm enable --user-id
1213 APP_LOGD("'bm enable -u' with no argument.");
1214 resultReceiver_.append("error: option ");
1215 resultReceiver_.append("requires a value.\n");
1216 result = OHOS::ERR_INVALID_VALUE;
1217 break;
1218 }
1219 default: {
1220 // 'bm enable' with an unknown option: bm enable -x
1221 // 'bm enable' with an unknown option: bm enable -xxx
1222 std::string unknownOption = "";
1223 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1224 APP_LOGD("'bm enable' with an unknown option.");
1225 resultReceiver_.append(unknownOptionMsg);
1226 result = OHOS::ERR_INVALID_VALUE;
1227 break;
1228 }
1229 }
1230 break;
1231 }
1232
1233 switch (option) {
1234 case 'h': {
1235 // 'bm enable-h'
1236 // 'bm enable --help'
1237 APP_LOGD("'bm enable %{public}s'", argv_[optind - 1]);
1238 result = OHOS::ERR_INVALID_VALUE;
1239 break;
1240 }
1241 case 'n': {
1242 // 'bm enable -n <bundle-name>'
1243 // 'bm enable --bundle-name <bundle-name>'
1244 bundleName = optarg;
1245 break;
1246 }
1247 case 'a': {
1248 // 'bm enable -a <ability-name>'
1249 // 'bm enable --ability-name <ability-name>'
1250 abilityName = optarg;
1251 break;
1252 }
1253 case 'u': {
1254 // 'bm enable -u userId'
1255 // 'bm enable --user-id userId'
1256 APP_LOGD("'bm enable %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg);
1257 userId = atoi(optarg);
1258 break;
1259 }
1260 default: {
1261 result = OHOS::ERR_INVALID_VALUE;
1262 break;
1263 }
1264 }
1265 }
1266
1267 if (result == OHOS::ERR_OK) {
1268 if (resultReceiver_ == "" && bundleName.size() == 0) {
1269 // 'bm enable ...' with no bundle name option
1270 APP_LOGD("'bm enable' with no bundle name option.");
1271
1272 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n");
1273 result = OHOS::ERR_INVALID_VALUE;
1274 }
1275 }
1276
1277 if (result != OHOS::ERR_OK) {
1278 resultReceiver_.append(HELP_MSG_ENABLE);
1279 } else {
1280 AbilityInfo abilityInfo;
1281 abilityInfo.name = abilityName;
1282 abilityInfo.bundleName = bundleName;
1283 bool enableResult = SetApplicationEnabledOperation(abilityInfo, true, userId);
1284 if (enableResult == true) {
1285 resultReceiver_ = STRING_ENABLE_BUNDLE_OK + "\n";
1286 } else {
1287 resultReceiver_ = STRING_ENABLE_BUNDLE_NG + "\n";
1288 }
1289 }
1290 return result;
1291 }
1292
RunAsDisableCommand()1293 ErrCode BundleManagerShellCommand::RunAsDisableCommand()
1294 {
1295 int result = OHOS::ERR_OK;
1296 int option = -1;
1297 int counter = 0;
1298 std::string bundleName = "";
1299 std::string abilityName = "";
1300 int32_t userId = Constants::UNSPECIFIED_USERID;
1301 while (true) {
1302 counter++;
1303 option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
1304 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
1305 if (optind < 0 || optind > argc_) {
1306 return OHOS::ERR_INVALID_VALUE;
1307 }
1308 if (option == -1) {
1309 if (counter == 1) {
1310 // When scanning the first argument
1311 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
1312 // 'bm disable' with no option: bm disable
1313 // 'bm disable' with a wrong argument: bm disable xxx
1314 APP_LOGD("'bm disable' with no option.");
1315 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
1316 result = OHOS::ERR_INVALID_VALUE;
1317 }
1318 }
1319 break;
1320 }
1321 if (option == '?') {
1322 switch (optopt) {
1323 case 'n': {
1324 // 'bm disable -n' with no argument: bm disable -n
1325 // 'bm disable --bundle-name' with no argument: bm disable --bundle-name
1326 APP_LOGD("'bm disable' with no argument.");
1327 resultReceiver_.append("error: option ");
1328 resultReceiver_.append("requires a value.\n");
1329 result = OHOS::ERR_INVALID_VALUE;
1330 break;
1331 }
1332 case 'a': {
1333 // 'bm disable -a' with no argument: bm disable -a
1334 // 'bm disable --ability-name' with no argument: bm disable --ability-name
1335 APP_LOGD("'bm disable -a' with no argument.");
1336 resultReceiver_.append("error: option ");
1337 resultReceiver_.append("requires a value.\n");
1338 result = OHOS::ERR_INVALID_VALUE;
1339 break;
1340 }
1341 case 'u': {
1342 // 'bm disable -u' with no argument: bm disable -u
1343 // 'bm disable --user-id' with no argument: bm disable --user-id
1344 APP_LOGD("'bm disable -u' with no argument.");
1345 resultReceiver_.append("error: option ");
1346 resultReceiver_.append("requires a value.\n");
1347 result = OHOS::ERR_INVALID_VALUE;
1348 break;
1349 }
1350 default: {
1351 // 'bm disable' with an unknown option: bm disable -x
1352 // 'bm disable' with an unknown option: bm disable -xxx
1353 std::string unknownOption = "";
1354 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1355 APP_LOGD("'bm disable' with an unknown option.");
1356 resultReceiver_.append(unknownOptionMsg);
1357 result = OHOS::ERR_INVALID_VALUE;
1358 break;
1359 }
1360 }
1361 break;
1362 }
1363 switch (option) {
1364 case 'h': {
1365 // 'bm disable -h'
1366 // 'bm disable --help'
1367 APP_LOGD("'bm disable %{public}s'", argv_[optind - 1]);
1368 result = OHOS::ERR_INVALID_VALUE;
1369 break;
1370 }
1371 case 'n': {
1372 // 'bm disable -n <bundle-name>'
1373 // 'bm disable --bundle-name <bundle-name>'
1374 bundleName = optarg;
1375 break;
1376 }
1377 case 'a': {
1378 // 'bm disable -a <ability-name>'
1379 // 'bm disable --ability-name <ability-name>'
1380 abilityName = optarg;
1381 break;
1382 }
1383 case 'u': {
1384 // 'bm disable -u userId'
1385 // 'bm disable --user-id userId'
1386 APP_LOGD("'bm disable %{public}s %{public}s'", argv_[optind - OFFSET_REQUIRED_ARGUMENT], optarg);
1387 userId = atoi(optarg);
1388 break;
1389 }
1390 default: {
1391 result = OHOS::ERR_INVALID_VALUE;
1392 break;
1393 }
1394 }
1395 }
1396 if (result == OHOS::ERR_OK) {
1397 if (resultReceiver_ == "" && bundleName.size() == 0) {
1398 // 'bm disable ...' with no bundle name option
1399 APP_LOGD("'bm disable' with no bundle name option.");
1400 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n");
1401 result = OHOS::ERR_INVALID_VALUE;
1402 }
1403 }
1404 if (result != OHOS::ERR_OK) {
1405 resultReceiver_.append(HELP_MSG_DISABLE);
1406 } else {
1407 AbilityInfo abilityInfo;
1408 abilityInfo.name = abilityName;
1409 abilityInfo.bundleName = bundleName;
1410 bool enableResult = SetApplicationEnabledOperation(abilityInfo, false, userId);
1411 if (enableResult == true) {
1412 resultReceiver_ = STRING_DISABLE_BUNDLE_OK + "\n";
1413 } else {
1414 resultReceiver_ = STRING_DISABLE_BUNDLE_NG + "\n";
1415 }
1416 }
1417 return result;
1418 }
1419
RunAsGetCommand()1420 ErrCode BundleManagerShellCommand::RunAsGetCommand()
1421 {
1422 int result = OHOS::ERR_OK;
1423 int option = -1;
1424 int counter = 0;
1425 while (true) {
1426 counter++;
1427 if (argc_ > MAX_ARGUEMENTS_NUMBER) {
1428 resultReceiver_.append(HELP_MSG_GET);
1429 return OHOS::ERR_INVALID_VALUE;
1430 }
1431 option = getopt_long(argc_, argv_, SHORT_OPTIONS_GET.c_str(), LONG_OPTIONS_GET, nullptr);
1432 APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
1433 if (optind < 0 || optind > argc_) {
1434 return OHOS::ERR_INVALID_VALUE;
1435 }
1436 if (option == -1) {
1437 if (counter == 1) {
1438 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
1439 // 1.'bm get' with no option: bm get
1440 // 2.'bm get' with a wrong argument: bm get -xxx
1441 APP_LOGD("'bm get' %{public}s", HELP_MSG_NO_OPTION.c_str());
1442 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
1443 result = OHOS::ERR_INVALID_VALUE;
1444 }
1445 }
1446 break;
1447 }
1448 switch (option) {
1449 case 'h': {
1450 result = OHOS::ERR_INVALID_VALUE;
1451 break;
1452 }
1453 case 'u': {
1454 break;
1455 }
1456 default: {
1457 result = OHOS::ERR_INVALID_VALUE;
1458 resultReceiver_.append(STRING_INCORRECT_OPTION + "\n");
1459 break;
1460 }
1461 }
1462 }
1463 if (result != OHOS::ERR_OK) {
1464 resultReceiver_.append(HELP_MSG_GET);
1465 return result;
1466 }
1467 resultReceiver_.append(STRING_GET_UDID_OK + "\n");
1468 resultReceiver_.append(GetUdid() + "\n");
1469 return result;
1470 }
1471
GetUdid() const1472 std::string BundleManagerShellCommand::GetUdid() const
1473 {
1474 char innerUdid[DEVICE_UDID_LENGTH] = { 0 };
1475 int ret = GetDevUdid(innerUdid, DEVICE_UDID_LENGTH);
1476 if (ret != 0) {
1477 APP_LOGE("GetUdid failed! ret = %{public}d.", ret);
1478 return STRING_GET_UDID_NG;
1479 }
1480 std::string udid = innerUdid;
1481 return udid;
1482 }
1483
DumpBundleList(int32_t userId) const1484 std::string BundleManagerShellCommand::DumpBundleList(int32_t userId) const
1485 {
1486 std::string dumpResults;
1487 bool dumpRet = bundleMgrProxy_->DumpInfos(
1488 DumpFlag::DUMP_BUNDLE_LIST, BUNDLE_NAME_EMPTY, userId, dumpResults);
1489 if (!dumpRet) {
1490 APP_LOGE("failed to dump bundle list.");
1491 }
1492 return dumpResults;
1493 }
1494
DumpBundleInfos(int32_t userId) const1495 std::string BundleManagerShellCommand::DumpBundleInfos(int32_t userId) const
1496 {
1497 std::string dumpResults;
1498 bool dumpRet = bundleMgrProxy_->DumpInfos(
1499 DumpFlag::DUMP_ALL_BUNDLE_INFO, BUNDLE_NAME_EMPTY, userId, dumpResults);
1500 if (!dumpRet) {
1501 APP_LOGE("failed to dump bundle infos.");
1502 }
1503 return dumpResults;
1504 }
1505
DumpBundleInfo(const std::string & bundleName,int32_t userId) const1506 std::string BundleManagerShellCommand::DumpBundleInfo(const std::string &bundleName, int32_t userId) const
1507 {
1508 std::string dumpResults;
1509 bool dumpRet = bundleMgrProxy_->DumpInfos(
1510 DumpFlag::DUMP_BUNDLE_INFO, bundleName, userId, dumpResults);
1511 if (!dumpRet) {
1512 APP_LOGE("failed to dump bundle info.");
1513 }
1514 return dumpResults;
1515 }
1516
DumpShortcutInfos(const std::string & bundleName,int32_t userId) const1517 std::string BundleManagerShellCommand::DumpShortcutInfos(const std::string &bundleName, int32_t userId) const
1518 {
1519 std::string dumpResults;
1520 bool dumpRet = bundleMgrProxy_->DumpInfos(
1521 DumpFlag::DUMP_SHORTCUT_INFO, bundleName, userId, dumpResults);
1522 if (!dumpRet) {
1523 APP_LOGE("failed to dump shortcut infos.");
1524 }
1525 return dumpResults;
1526 }
1527
DumpDistributedBundleInfo(const std::string & deviceId,int32_t userId,const std::string & bundleName)1528 std::string BundleManagerShellCommand::DumpDistributedBundleInfo(const std::string &deviceId,
1529 int32_t userId, const std::string &bundleName)
1530 {
1531 std::string dumpResults = "";
1532 DistributedBundleInfo bundleInfo;
1533 bool dumpRet = bundleMgrProxy_->GetDistributedBundleInfo(deviceId, userId, bundleName, bundleInfo);
1534 if (!dumpRet) {
1535 APP_LOGE("failed to dump distributed bundleInfo.");
1536 } else {
1537 dumpResults.append("distributed bundleInfo");
1538 dumpResults.append(":\n");
1539 dumpResults.append(bundleInfo.ToString());
1540 dumpResults.append("\n");
1541 }
1542 return dumpResults;
1543 }
1544
InstallOperation(const std::vector<std::string> & bundlePaths,InstallParam & installParam) const1545 int32_t BundleManagerShellCommand::InstallOperation(const std::vector<std::string> &bundlePaths,
1546 InstallParam &installParam) const
1547 {
1548 std::vector<std::string> realPathVec;
1549 for (auto &bundlePath : bundlePaths) {
1550 std::string absoluteBundlePath = "";
1551 if (bundlePath.empty()) {
1552 continue;
1553 }
1554 if (bundlePath.at(0) == '/') {
1555 // absolute path
1556 absoluteBundlePath.append(bundlePath);
1557 } else {
1558 // relative path
1559 char *currentPathPtr = getcwd(nullptr, 0);
1560
1561 if (currentPathPtr != nullptr) {
1562 absoluteBundlePath.append(currentPathPtr);
1563 absoluteBundlePath.append('/' + bundlePath);
1564
1565 free(currentPathPtr);
1566 currentPathPtr = nullptr;
1567 }
1568 }
1569 realPathVec.emplace_back(absoluteBundlePath);
1570 }
1571
1572 sptr<StatusReceiverImpl> statusReceiver(new (std::nothrow) StatusReceiverImpl());
1573 if (statusReceiver == nullptr) {
1574 APP_LOGE("statusReceiver is null");
1575 return IStatusReceiver::ERR_UNKNOWN;
1576 }
1577 sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(statusReceiver));
1578 if (recipient == nullptr) {
1579 APP_LOGE("recipient is null");
1580 return IStatusReceiver::ERR_UNKNOWN;
1581 }
1582 bundleInstallerProxy_->AsObject()->AddDeathRecipient(recipient);
1583 bundleInstallerProxy_->Install(realPathVec, installParam, statusReceiver);
1584 return statusReceiver->GetResultCode();
1585 }
1586
UninstallOperation(const std::string & bundleName,const std::string & moduleName,InstallParam & installParam) const1587 int32_t BundleManagerShellCommand::UninstallOperation(
1588 const std::string &bundleName, const std::string &moduleName, InstallParam &installParam) const
1589 {
1590 sptr<StatusReceiverImpl> statusReceiver(new (std::nothrow) StatusReceiverImpl());
1591 if (statusReceiver == nullptr) {
1592 APP_LOGE("statusReceiver is null");
1593 return IStatusReceiver::ERR_UNKNOWN;
1594 }
1595
1596 APP_LOGD("bundleName: %{public}s", bundleName.c_str());
1597 APP_LOGD("moduleName: %{public}s", moduleName.c_str());
1598
1599 sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(statusReceiver));
1600 if (recipient == nullptr) {
1601 APP_LOGE("recipient is null");
1602 return IStatusReceiver::ERR_UNKNOWN;
1603 }
1604 bundleInstallerProxy_->AsObject()->AddDeathRecipient(recipient);
1605 if (moduleName.size() != 0) {
1606 bundleInstallerProxy_->Uninstall(bundleName, moduleName, installParam, statusReceiver);
1607 } else {
1608 bundleInstallerProxy_->Uninstall(bundleName, installParam, statusReceiver);
1609 }
1610
1611 return statusReceiver->GetResultCode();
1612 }
1613
CleanBundleCacheFilesOperation(const std::string & bundleName,int32_t userId) const1614 bool BundleManagerShellCommand::CleanBundleCacheFilesOperation(const std::string &bundleName, int32_t userId) const
1615 {
1616 userId = GetCurrentUserId(userId);
1617 sptr<CleanCacheCallbackImpl> cleanCacheCallBack(new (std::nothrow) CleanCacheCallbackImpl());
1618 if (cleanCacheCallBack == nullptr) {
1619 APP_LOGE("cleanCacheCallBack is null");
1620 return false;
1621 }
1622 bool cleanRet = bundleMgrProxy_->CleanBundleCacheFiles(bundleName, cleanCacheCallBack, userId);
1623 if (cleanRet) {
1624 return cleanCacheCallBack->GetResultCode();
1625 }
1626 APP_LOGE("clean bundle cache files operation failed");
1627 return cleanRet;
1628 }
1629
CleanBundleDataFilesOperation(const std::string & bundleName,int32_t userId) const1630 bool BundleManagerShellCommand::CleanBundleDataFilesOperation(const std::string &bundleName, int32_t userId) const
1631 {
1632 APP_LOGD("bundleName: %{public}s, userId:%{public}d", bundleName.c_str(), userId);
1633 userId = GetCurrentUserId(userId);
1634 bool cleanRet = bundleMgrProxy_->CleanBundleDataFiles(bundleName, userId);
1635 if (!cleanRet) {
1636 APP_LOGE("clean bundle data files operation failed");
1637 }
1638 return cleanRet;
1639 }
1640
SetApplicationEnabledOperation(const AbilityInfo & abilityInfo,bool isEnable,int32_t userId) const1641 bool BundleManagerShellCommand::SetApplicationEnabledOperation(const AbilityInfo &abilityInfo,
1642 bool isEnable, int32_t userId) const
1643 {
1644 APP_LOGD("bundleName: %{public}s", abilityInfo.bundleName.c_str());
1645 userId = GetCurrentUserId(userId);
1646 bool ret = false;
1647 if (abilityInfo.name.size() == 0) {
1648 ret = bundleMgrProxy_->SetApplicationEnabled(abilityInfo.bundleName, isEnable, userId);
1649 } else {
1650 ret = bundleMgrProxy_->SetAbilityEnabled(abilityInfo, isEnable, userId);
1651 }
1652 if (!ret) {
1653 if (isEnable) {
1654 APP_LOGE("enable bundle failed");
1655 } else {
1656 APP_LOGE("disable bundle failed");
1657 }
1658 }
1659 return ret;
1660 }
1661
GetCurrentUserId(int32_t userId) const1662 int32_t BundleManagerShellCommand::GetCurrentUserId(int32_t userId) const
1663 {
1664 if (userId == Constants::UNSPECIFIED_USERID) {
1665 std::vector<int> activeIds;
1666 int32_t ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeIds);
1667 if (ret != 0) {
1668 APP_LOGE("QueryActiveOsAccountIds failed! ret = %{public}d.", ret);
1669 return userId;
1670 }
1671 if (activeIds.empty()) {
1672 APP_LOGE("QueryActiveOsAccountIds activeIds empty");
1673 return userId;
1674 }
1675 return activeIds[0];
1676 }
1677 return userId;
1678 }
1679 } // namespace AppExecFwk
1680 } // namespace OHOS
1681