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