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