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