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