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