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