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