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