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