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