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