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 "ability_command.h"
16
17 #include <cstdlib>
18 #include <getopt.h>
19 #include "ability_manager_client.h"
20 #include "hilog_wrapper.h"
21 #include "iservice_registry.h"
22 #include "mission_snapshot.h"
23 #include "ohos/aafwk/base/bool_wrapper.h"
24 #include "sa_mgr_client.h"
25 #include "system_ability_definition.h"
26 #include "test_observer.h"
27
28 using namespace OHOS::AppExecFwk;
29
30 namespace OHOS {
31 namespace AAFwk {
32 namespace {
33 const std::string SHORT_OPTIONS = "ch:d:a:b:p:s:CD";
34 constexpr struct option LONG_OPTIONS[] = {
35 {"help", no_argument, nullptr, 'h'},
36 {"device", required_argument, nullptr, 'd'},
37 {"ability", required_argument, nullptr, 'a'},
38 {"bundle", required_argument, nullptr, 'b'},
39 {"power", required_argument, nullptr, 'p'},
40 {"setting", required_argument, nullptr, 's'},
41 {"cold-start", no_argument, nullptr, 'C'},
42 {"debug", no_argument, nullptr, 'D'},
43 {nullptr, 0, nullptr, 0},
44 };
45 const std::string SHORT_OPTIONS_DUMP = "has:m:lud::e::LS";
46 constexpr struct option LONG_OPTIONS_DUMP[] = {
47 {"help", no_argument, nullptr, 'h'},
48 {"all", no_argument, nullptr, 'a'},
49 {"stack", required_argument, nullptr, 's'},
50 {"mission", required_argument, nullptr, 'm'},
51 {"stack-list", no_argument, nullptr, 'l'},
52 {"ui", no_argument, nullptr, 'u'},
53 {"data", no_argument, nullptr, 'd'},
54 {"serv", no_argument, nullptr, 'e'},
55 {"mission-list", no_argument, nullptr, 'L'},
56 {"mission-infos", no_argument, nullptr, 'S'},
57 {nullptr, 0, nullptr, 0},
58 };
59 const std::string SHORT_OPTIONS_DUMPSYS = "hal::i:e::p::r::d::u:c";
60 constexpr struct option LONG_OPTIONS_DUMPSYS[] = {
61 {"help", no_argument, nullptr, 'h'},
62 {"all", no_argument, nullptr, 'a'},
63 {"mission-list", no_argument, nullptr, 'l'},
64 {"ability", required_argument, nullptr, 'i'},
65 {"extension", no_argument, nullptr, 'e'},
66 {"pending", no_argument, nullptr, 'p'},
67 {"process", no_argument, nullptr, 'r'},
68 {"data", no_argument, nullptr, 'd'},
69 {"userId", required_argument, nullptr, 'u'},
70 {"client", no_argument, nullptr, 'c'},
71 {nullptr, 0, nullptr, 0},
72 };
73 } // namespace
74
AbilityManagerShellCommand(int argc,char * argv[])75 AbilityManagerShellCommand::AbilityManagerShellCommand(int argc, char *argv[]) : ShellCommand(argc, argv, TOOL_NAME)
76 {
77 for (int i = 0; i < argc_; i++) {
78 HILOG_INFO("argv_[%{public}d]: %{public}s", i, argv_[i]);
79 }
80 }
81
CreateCommandMap()82 ErrCode AbilityManagerShellCommand::CreateCommandMap()
83 {
84 commandMap_ = {
85 {"help", std::bind(&AbilityManagerShellCommand::RunAsHelpCommand, this)},
86 {"screen", std::bind(&AbilityManagerShellCommand::RunAsScreenCommand, this)},
87 {"start", std::bind(&AbilityManagerShellCommand::RunAsStartAbility, this)},
88 {"stop-service", std::bind(&AbilityManagerShellCommand::RunAsStopService, this)},
89 {"dump", std::bind(&AbilityManagerShellCommand::RunAsDumpsysCommand, this)},
90 {"force-stop", std::bind(&AbilityManagerShellCommand::RunAsForceStop, this)},
91 {"test", std::bind(&AbilityManagerShellCommand::RunAsTestCommand, this)},
92 };
93
94 return OHOS::ERR_OK;
95 }
96
CreateMessageMap()97 ErrCode AbilityManagerShellCommand::CreateMessageMap()
98 {
99 messageMap_ = {
100 // code + message
101 {
102 RESOLVE_ABILITY_ERR,
103 "error: resolve ability err.",
104 },
105 {
106 GET_ABILITY_SERVICE_FAILED,
107 "error: get ability service failed.",
108 },
109 {
110 ABILITY_SERVICE_NOT_CONNECTED,
111 "error: ability service not connected.",
112 },
113 {
114 RESOLVE_APP_ERR,
115 "error: resolve app err.",
116 },
117 {
118 STACK_MANAGER_NOT_EXIST,
119 "error: stack manager not exist.",
120 },
121 {
122 ABILITY_EXISTED,
123 "error: ability existed.",
124 },
125 {
126 CREATE_MISSION_STACK_FAILED,
127 "error: create mission stack failed.",
128 },
129 {
130 CREATE_MISSION_RECORD_FAILED,
131 "error: create mission record failed.",
132 },
133 {
134 CREATE_ABILITY_RECORD_FAILED,
135 "error: create ability record failed.",
136 },
137 {
138 START_ABILITY_WAITING,
139 "start ability successfully. waiting...",
140 },
141 {
142 TERMINATE_LAUNCHER_DENIED,
143 "error: terminate launcher denied.",
144 },
145 {
146 CONNECTION_NOT_EXIST,
147 "error: connection not exist.",
148 },
149 {
150 INVALID_CONNECTION_STATE,
151 "error: invalid connection state.",
152 },
153 {
154 LOAD_ABILITY_TIMEOUT,
155 "error: load ability timeout.",
156 },
157 {
158 CONNECTION_TIMEOUT,
159 "error: connection timeout.",
160 },
161 {
162 GET_BUNDLE_MANAGER_SERVICE_FAILED,
163 "error: get bundle manager service failed.",
164 },
165 {
166 REMOVE_MISSION_ID_NOT_EXIST,
167 "error: remove mission id not exist.",
168 },
169 {
170 REMOVE_MISSION_LAUNCHER_DENIED,
171 "error: remove mission launcher denied.",
172 },
173 {
174 REMOVE_MISSION_ACTIVE_DENIED,
175 "error: remove mission active denied.",
176 },
177 {
178 REMOVE_MISSION_FAILED,
179 "error: remove mission failed.",
180 },
181 {
182 INNER_ERR,
183 "error: inner err.",
184 },
185 {
186 GET_RECENT_MISSIONS_FAILED,
187 "error: get recent missions failed.",
188 },
189 {
190 REMOVE_STACK_LAUNCHER_DENIED,
191 "error: remove stack launcher denied.",
192 },
193 {
194 REMOVE_STACK_FAILED,
195 "error: remove stack failed.",
196 },
197 {
198 MISSION_STACK_LIST_IS_EMPTY,
199 "error: mission stack list is empty.",
200 },
201 {
202 REMOVE_STACK_ID_NOT_EXIST,
203 "error: remove stack id not exist.",
204 },
205 {
206 TARGET_ABILITY_NOT_SERVICE,
207 "error: target ability not service.",
208 },
209 {
210 TERMINATE_SERVICE_IS_CONNECTED,
211 "error: terminate service is connected.",
212 },
213 {
214 START_SERVICE_ABILITY_ACTIVING,
215 "error: start service ability activing.",
216 },
217 {
218 MOVE_MISSION_FAILED,
219 "error: move mission failed.",
220 },
221 {
222 KILL_PROCESS_FAILED,
223 "error: kill process failed.",
224 },
225 {
226 UNINSTALL_APP_FAILED,
227 "error: uninstall app failed.",
228 },
229 {
230 TERMINATE_ABILITY_RESULT_FAILED,
231 "error: terminate ability result failed.",
232 },
233 {
234 CHECK_PERMISSION_FAILED,
235 "error: check permission failed.",
236 },
237 {
238 POWER_OFF_WAITING,
239 "error: power off waiting.",
240 },
241 {
242 POWER_OFF_FAILED,
243 "error: power off failed.",
244 },
245 {
246 POWER_ON_FAILED,
247 "error: power on failed.",
248 },
249 {
250 NO_FIRST_IN_MISSION,
251 "error: no first in mission.",
252 },
253 {
254 LOCK_MISSION_DENY_FAILED,
255 "error: lock mission deny failed.",
256 },
257 {
258 UNLOCK_MISSION_DENY_FAILED,
259 "error: unlock mission deny failed.",
260 },
261 {
262 SET_MISSION_INFO_FAILED,
263 "error: set mission info failed.",
264 },
265 {
266 LOCK_MISSION_STATE_DENY_REQUEST,
267 "error: lock mission state deny request.",
268 },
269 {
270 MOVE_MISSION_TO_STACK_OUT_OF_SIZE,
271 "error: move mission to stack out of size.",
272 },
273 {
274 MOVE_MISSION_TO_STACK_NOT_SAME_WIN_MODE,
275 "error: move mission to stack not same win mode.",
276 },
277 {
278 MOVE_MISSION_TO_STACK_NOT_EXIST_MISSION,
279 "error: move mission to stack not exist mission.",
280 },
281 {
282 MOVE_MISSION_TO_STACK_NOT_SUPPORT_MULTI_WIN,
283 "error: move mission to stack not support multi win.",
284 },
285 {
286 MOVE_MISSION_TO_STACK_TARGET_STACK_OVERFLOW,
287 "error: move mission to stack target stack overflow.",
288 },
289 {
290 MOVE_MISSION_TO_STACK_MOVING_DENIED,
291 "error: move mission to stack moving denied.",
292 },
293 {
294 MINIMIZE_MULTI_WINDOW_FAILED,
295 "error: minimize multi window failed.",
296 },
297 {
298 MAXIMIZE_MULTIWINDOW_NOT_EXIST,
299 "error: maximize multiwindow not exist.",
300 },
301 {
302 MAXIMIZE_MULTIWINDOW_FAILED,
303 "error: maximize multiwindow failed.",
304 },
305 {
306 CHANGE_FOCUS_ABILITY_FAILED,
307 "error: change focus ability failed.",
308 },
309 {
310 GET_FLOATING_STACK_FAILED,
311 "error: get floating stack failed.",
312 },
313 {
314 CLOSE_MULTI_WINDOW_FAILED,
315 "error: close multi window failed.",
316 },
317 {
318 START_ABILITY_SETTING_FAILED,
319 "error: start ability setting failed.",
320 },
321 {
322 START_ABILITY_SETTING_NOT_SUPPORT_MULTI_WIN,
323 "error: start ability setting not support multi win.",
324 },
325 {
326 NO_FOUND_ABILITY_BY_CALLER,
327 "error: no found ability by caller.",
328 },
329 {
330 ABILITY_VISIBLE_FALSE_DENY_REQUEST,
331 "error: ability visible false deny request.",
332 },
333 {
334 GET_BUNDLE_INFO_FAILED,
335 "error: get bundle info failed.",
336 },
337 {
338 KILL_PROCESS_KEEP_ALIVE,
339 "error: keep alive process can not be killed.",
340 },
341 };
342
343 return OHOS::ERR_OK;
344 }
345
init()346 ErrCode AbilityManagerShellCommand::init()
347 {
348 return AbilityManagerClient::GetInstance()->Connect();
349 }
350
RunAsHelpCommand()351 ErrCode AbilityManagerShellCommand::RunAsHelpCommand()
352 {
353 resultReceiver_.append(HELP_MSG);
354
355 return OHOS::ERR_OK;
356 }
357
RunAsScreenCommand()358 ErrCode AbilityManagerShellCommand::RunAsScreenCommand()
359 {
360 HILOG_INFO("enter");
361
362 int result = OHOS::ERR_OK;
363
364 int option = -1;
365 int counter = 0;
366
367 std::string powerState = "";
368
369 while (true) {
370 counter++;
371
372 option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
373
374 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
375
376 if (optind < 0 || optind > argc_) {
377 return OHOS::ERR_INVALID_VALUE;
378 }
379
380 if (option == -1) {
381 // When scanning the first argument
382 if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
383 // 'aa screen' with no option: aa screen
384 // 'aa screen' with a wrong argument: aa screen xxx
385 HILOG_INFO("'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
386 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
387 result = OHOS::ERR_INVALID_VALUE;
388 }
389 break;
390 }
391
392 if (option == '?') {
393 switch (optopt) {
394 case 'p': {
395 // 'aa screen -p' with no argument
396 HILOG_INFO("'aa %{public}s -p' with no argument.", cmd_.c_str());
397
398 resultReceiver_.append("error: option ");
399 resultReceiver_.append("requires a value.\n");
400
401 result = OHOS::ERR_INVALID_VALUE;
402 break;
403 }
404 case 0: {
405 // 'aa screen' with an unknown option: aa screen --x
406 // 'aa screen' with an unknown option: aa screen --xxx
407 std::string unknownOption = "";
408 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
409
410 HILOG_INFO("'aa screen' with an unknown option.");
411
412 resultReceiver_.append(unknownOptionMsg);
413 result = OHOS::ERR_INVALID_VALUE;
414 break;
415 }
416 default: {
417 // 'aa screen' with an unknown option: aa screen -x
418 // 'aa screen' with an unknown option: aa screen -xxx
419 std::string unknownOption = "";
420 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
421
422 HILOG_INFO("'aa screen' with an unknown option.");
423
424 resultReceiver_.append(unknownOptionMsg);
425 result = OHOS::ERR_INVALID_VALUE;
426 break;
427 }
428 }
429 break;
430 }
431
432 switch (option) {
433 case 'h': {
434 // 'aa screen -h'
435 // 'aa screen --help'
436 result = OHOS::ERR_INVALID_VALUE;
437 break;
438 }
439 case 'p': {
440 // 'aa screen -p xxx'
441
442 // save powerState
443 if (optarg != nullptr) {
444 powerState = optarg;
445 }
446 break;
447 }
448 case 0: {
449 break;
450 }
451 default: {
452 break;
453 }
454 }
455 }
456
457 if (result == OHOS::ERR_OK) {
458 HILOG_INFO("powerState: %{public}s", powerState.c_str());
459
460 if (powerState == STRING_SCREEN_POWER_ON) {
461 result = AbilityManagerClient::GetInstance()->PowerOn();
462 if (result == OHOS::ERR_OK) {
463 HILOG_INFO("%{public}s", STRING_SCREEN_POWER_ON_OK.c_str());
464 resultReceiver_ = STRING_SCREEN_POWER_ON_OK + "\n";
465 } else {
466 HILOG_INFO("%{public}s result = %{public}d", STRING_SCREEN_POWER_ON_NG.c_str(), result);
467 resultReceiver_ = STRING_SCREEN_POWER_ON_NG + "\n";
468
469 resultReceiver_.append(GetMessageFromCode(result));
470 }
471 } else {
472 result = AbilityManagerClient::GetInstance()->PowerOff();
473 if (result == OHOS::ERR_OK) {
474 HILOG_INFO("%{public}s", STRING_SCREEN_POWER_OFF_OK.c_str());
475 resultReceiver_ = STRING_SCREEN_POWER_OFF_OK + "\n";
476 } else {
477 HILOG_INFO("%{public}s result = %{public}d", STRING_SCREEN_POWER_OFF_NG.c_str(), result);
478 resultReceiver_ = STRING_SCREEN_POWER_OFF_NG + "\n";
479
480 resultReceiver_.append(GetMessageFromCode(result));
481 }
482 }
483 } else {
484 resultReceiver_.append(HELP_MSG_SCREEN);
485 result = OHOS::ERR_INVALID_VALUE;
486 }
487
488 return result;
489 }
490
RunAsStartAbility()491 ErrCode AbilityManagerShellCommand::RunAsStartAbility()
492 {
493 Want want;
494 std::string windowMode;
495 ErrCode result = MakeWantFromCmd(want, windowMode);
496 if (result == OHOS::ERR_OK) {
497 int windowModeKey = std::atoi(windowMode.c_str());
498 if (windowModeKey > 0) {
499 auto setting = AbilityStartSetting::GetEmptySetting();
500 if (setting != nullptr) {
501 setting->AddProperty(AbilityStartSetting::WINDOW_MODE_KEY, windowMode);
502 result = AbilityManagerClient::GetInstance()->StartAbility(want, *(setting.get()), nullptr, -1);
503 }
504 } else {
505 result = AbilityManagerClient::GetInstance()->StartAbility(want);
506 }
507 if (result == OHOS::ERR_OK) {
508 HILOG_INFO("%{public}s", STRING_START_ABILITY_OK.c_str());
509 resultReceiver_ = STRING_START_ABILITY_OK + "\n";
510 } else {
511 HILOG_INFO("%{public}s result = %{public}d", STRING_START_ABILITY_NG.c_str(), result);
512 if (result != START_ABILITY_WAITING) {
513 resultReceiver_ = STRING_START_ABILITY_NG + "\n";
514 }
515 resultReceiver_.append(GetMessageFromCode(result));
516 }
517 } else {
518 resultReceiver_.append(HELP_MSG_START);
519 result = OHOS::ERR_INVALID_VALUE;
520 }
521
522 return result;
523 }
524
RunAsStopService()525 ErrCode AbilityManagerShellCommand::RunAsStopService()
526 {
527 ErrCode result = OHOS::ERR_OK;
528
529 Want want;
530 std::string windowMode;
531 result = MakeWantFromCmd(want, windowMode);
532 if (result == OHOS::ERR_OK) {
533 result = AbilityManagerClient::GetInstance()->StopServiceAbility(want);
534 if (result == OHOS::ERR_OK) {
535 HILOG_INFO("%{public}s", STRING_STOP_SERVICE_ABILITY_OK.c_str());
536 resultReceiver_ = STRING_STOP_SERVICE_ABILITY_OK + "\n";
537 } else {
538 HILOG_INFO("%{public}s result = %{public}d", STRING_STOP_SERVICE_ABILITY_NG.c_str(), result);
539 resultReceiver_ = STRING_STOP_SERVICE_ABILITY_NG + "\n";
540
541 resultReceiver_.append(GetMessageFromCode(result));
542 }
543 } else {
544 resultReceiver_.append(HELP_MSG_STOP_SERVICE);
545 result = OHOS::ERR_INVALID_VALUE;
546 }
547
548 return result;
549 }
550
RunAsDumpsysCommand()551 ErrCode AbilityManagerShellCommand::RunAsDumpsysCommand()
552 {
553 ErrCode result = OHOS::ERR_OK;
554 bool isUserID = false;
555 bool isClient = false;
556 int userID = DEFAULT_INVAL_VALUE;
557 bool isfirstCommand = false;
558 std::string args;
559 for (auto it = argList_.begin(); it != argList_.end(); it++) {
560 if (*it == "-c" || *it == "--client") {
561 if (isClient == false) {
562 isClient = true;
563 } else {
564 result = OHOS::ERR_INVALID_VALUE;
565 resultReceiver_.append(HELP_MSG_DUMPSYS);
566 return result;
567 }
568 } else if (*it == "-u" || *it == "--userId") {
569 if (it + 1 == argList_.end()) {
570 result = OHOS::ERR_INVALID_VALUE;
571 resultReceiver_.append(HELP_MSG_DUMPSYS);
572 return result;
573 }
574 (void)StrToInt(*(it + 1), userID);
575 if (userID == DEFAULT_INVAL_VALUE) {
576 result = OHOS::ERR_INVALID_VALUE;
577 resultReceiver_.append(HELP_MSG_DUMPSYS);
578 return result;
579 }
580 if (isUserID == false) {
581 isUserID = true;
582 } else {
583 result = OHOS::ERR_INVALID_VALUE;
584 resultReceiver_.append(HELP_MSG_DUMPSYS);
585 return result;
586 }
587 } else if (*it == std::to_string(userID)) {
588 continue;
589 } else {
590 args += *it;
591 args += " ";
592 }
593 }
594
595 while (true) {
596
597 int option = getopt_long(argc_, argv_, SHORT_OPTIONS_DUMPSYS.c_str(), LONG_OPTIONS_DUMPSYS, nullptr);
598
599 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
600
601 if (optind < 0 || optind > argc_) {
602 resultReceiver_.append(HELP_MSG_DUMPSYS);
603 return OHOS::ERR_INVALID_VALUE;
604 }
605
606 if (option == -1) {
607 break;
608 }
609
610 switch (option) {
611 case 'h': {
612 // 'aa dumpsys -h'
613 // 'aa dumpsys --help'
614 resultReceiver_.append(HELP_MSG_DUMPSYS);
615 result = OHOS::ERR_INVALID_VALUE;
616 return result;
617 }
618 case 'a': {
619 if (isfirstCommand == false) {
620 isfirstCommand = true;
621 } else {
622 result = OHOS::ERR_INVALID_VALUE;
623 resultReceiver_.append(HELP_MSG_DUMPSYS);
624 return result;
625 }
626 // 'aa dumpsys -a'
627 // 'aa dumpsys --all'
628 break;
629 }
630 case 'l': {
631 if (isfirstCommand == false) {
632 isfirstCommand = true;
633 } else {
634 // 'aa dumpsys -i 10 -element -lastpage'
635 // 'aa dumpsys -i 10 -render -lastpage'
636 if (strcmp(optarg, "astpage")) {
637 result = OHOS::ERR_INVALID_VALUE;
638 resultReceiver_.append(HELP_MSG_DUMPSYS);
639 return result;
640 }
641 }
642 // 'aa dumpsys -l'
643 // 'aa dumpsys --mission-list'
644 break;
645 }
646 case 'i': {
647 if (isfirstCommand == false) {
648 isfirstCommand = true;
649 int abilityRecordId = DEFAULT_INVAL_VALUE;
650 (void)StrToInt(optarg, abilityRecordId);
651 if (abilityRecordId == DEFAULT_INVAL_VALUE) {
652 result = OHOS::ERR_INVALID_VALUE;
653 resultReceiver_.append(HELP_MSG_DUMPSYS);
654 return result;
655 }
656 } else {
657 // 'aa dumpsys -i 10 -inspector'
658 if (strcmp(optarg, "nspector")) {
659 result = OHOS::ERR_INVALID_VALUE;
660 resultReceiver_.append(HELP_MSG_DUMPSYS);
661 return result;
662 }
663 }
664 // 'aa dumpsys -i'
665 // 'aa dumpsys --ability'
666 break;
667 }
668 case 'e': {
669 if (isfirstCommand == false && optarg == nullptr) {
670 isfirstCommand = true;
671 } else {
672 // 'aa dumpsys -i 10 -element'
673 if (strcmp(optarg, "lement")) {
674 result = OHOS::ERR_INVALID_VALUE;
675 resultReceiver_.append(HELP_MSG_DUMPSYS);
676 return result;
677 }
678 }
679 // 'aa dumpsys -e'
680 // 'aa dumpsys --extension'
681 break;
682 }
683 case 'p': {
684 if (isfirstCommand == false && optarg == nullptr) {
685 isfirstCommand = true;
686 } else {
687 result = OHOS::ERR_INVALID_VALUE;
688 resultReceiver_.append(HELP_MSG_DUMPSYS);
689 return result;
690 }
691 // 'aa dumpsys -p'
692 // 'aa dumpsys --pending'
693 break;
694 }
695 case 'r': {
696 if (isfirstCommand == false && optarg == nullptr) {
697 isfirstCommand = true;
698 } else {
699 // 'aa dumpsys -i 10 -render'
700 if (strcmp(optarg, "ender")) {
701 result = OHOS::ERR_INVALID_VALUE;
702 resultReceiver_.append(HELP_MSG_DUMPSYS);
703 return result;
704 }
705 }
706 // 'aa dumpsys -r'
707 // 'aa dumpsys --process'
708 break;
709 }
710 case 'd': {
711 if (isfirstCommand == false && optarg == nullptr) {
712 isfirstCommand = true;
713 } else {
714 result = OHOS::ERR_INVALID_VALUE;
715 resultReceiver_.append(HELP_MSG_DUMPSYS);
716 return result;
717 }
718 // 'aa dumpsys -d'
719 // 'aa dumpsys --data'
720 break;
721 }
722 case 'u': {
723 // 'aa dumpsys -u'
724 // 'aa dumpsys --userId'
725 break;
726 }
727 case 'c': {
728 // 'aa dumpsys -c'
729 // 'aa dumpsys --client'
730 break;
731 }
732 case '?': {
733 result = OHOS::ERR_INVALID_VALUE;
734 resultReceiver_.append(HELP_MSG_DUMPSYS);
735 return result;
736 break;
737 }
738 default: {
739 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
740 // 'aa dumpsys' with no option: aa dumpsys
741 // 'aa dumpsys' with a wrong argument: aa dumpsys xxx
742 HILOG_INFO("'aa dumpsys' with no option.");
743
744 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
745 result = OHOS::ERR_INVALID_VALUE;
746 }
747 break;
748 }
749 }
750 }
751
752 if (result != OHOS::ERR_OK) {
753 resultReceiver_.append(HELP_MSG_DUMPSYS);
754 } else {
755 if (isfirstCommand != true) {
756 result = OHOS::ERR_INVALID_VALUE;
757 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
758 resultReceiver_.append(HELP_MSG_DUMPSYS);
759 return result;
760 }
761
762 std::vector<std::string> dumpResults;
763 result = AbilityManagerClient::GetInstance()->DumpSysState(args, dumpResults, isClient, isUserID, userID);
764 if (result == OHOS::ERR_OK) {
765 for (auto it : dumpResults) {
766 resultReceiver_ += it + "\n";
767 }
768 } else {
769 HILOG_INFO("failed to dump state.");
770 }
771 }
772 return result;
773 }
774
RunAsDumpCommand()775 ErrCode AbilityManagerShellCommand::RunAsDumpCommand()
776 {
777 ErrCode result = OHOS::ERR_OK;
778
779 std::string args;
780 for (auto arg : argList_) {
781 args += arg;
782 args += " ";
783 }
784
785 int option = getopt_long(argc_, argv_, SHORT_OPTIONS_DUMP.c_str(), LONG_OPTIONS_DUMP, nullptr);
786
787 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
788
789 if (optind < 0 || optind > argc_) {
790 return OHOS::ERR_INVALID_VALUE;
791 }
792
793 switch (option) {
794 case 'h': {
795 // 'aa dump -h'
796 // 'aa dump --help'
797 result = OHOS::ERR_INVALID_VALUE;
798 break;
799 }
800 case 'a': {
801 // 'aa dump -a'
802 // 'aa dump --all'
803 break;
804 }
805 case 's': {
806 // 'aa dump -s xxx'
807 // 'aa dump --stack xxx'
808 break;
809 }
810 case 'm': {
811 // 'aa dump -m xxx'
812 // 'aa dump --mission xxx'
813 break;
814 }
815 case 'l': {
816 // 'aa dump -l'
817 // 'aa dump --stack-list'
818 break;
819 }
820 case 'd': {
821 // 'aa dump -d'
822 // 'aa dump --data'
823 break;
824 }
825 case 'e': {
826 // 'aa dump -e'
827 // 'aa dump --serv'
828 break;
829 }
830 case 'L': {
831 // 'aa dump -L'
832 // 'aa dump --mission-list'
833 break;
834 }
835 case 'S': {
836 // 'aa dump -S'
837 // 'aa dump --mission-infos'
838 break;
839 }
840 case '?': {
841 result = RunAsDumpCommandOptopt();
842 break;
843 }
844 default: {
845 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
846 // 'aa dump' with no option: aa dump
847 // 'aa dump' with a wrong argument: aa dump xxx
848 HILOG_INFO("'aa dump' with no option.");
849
850 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
851 result = OHOS::ERR_INVALID_VALUE;
852 }
853 break;
854 }
855 }
856
857 if (result != OHOS::ERR_OK) {
858 resultReceiver_.append(HELP_MSG_DUMP);
859 } else {
860 std::vector<std::string> dumpResults;
861 result = AbilityManagerClient::GetInstance()->DumpState(args, dumpResults);
862 if (result == OHOS::ERR_OK) {
863 for (auto it : dumpResults) {
864 resultReceiver_ += it + "\n";
865 }
866 } else {
867 HILOG_INFO("failed to dump state.");
868 }
869 }
870
871 return result;
872 }
873
RunAsForceStop()874 ErrCode AbilityManagerShellCommand::RunAsForceStop()
875 {
876 HILOG_INFO("[%{public}s(%{public}s)] enter", __FILE__, __FUNCTION__);
877 if (argList_.empty()) {
878 resultReceiver_.append(HELP_MSG_FORCE_STOP + "\n");
879 return OHOS::ERR_INVALID_VALUE;
880 }
881 HILOG_INFO("Bundle name : %{public}s", argList_[0].c_str());
882 ErrCode result = OHOS::ERR_OK;
883 result = AbilityManagerClient::GetInstance()->KillProcess(argList_[0]);
884 if (result == OHOS::ERR_OK) {
885 HILOG_INFO("%{public}s", STRING_FORCE_STOP_OK.c_str());
886 resultReceiver_ = STRING_FORCE_STOP_OK + "\n";
887 } else {
888 HILOG_INFO("%{public}s result = %{public}d", STRING_FORCE_STOP_NG.c_str(), result);
889 resultReceiver_ = STRING_FORCE_STOP_NG + "\n";
890 resultReceiver_.append(GetMessageFromCode(result));
891 }
892 return result;
893 }
894
RunAsDumpCommandOptopt()895 ErrCode AbilityManagerShellCommand::RunAsDumpCommandOptopt()
896 {
897 ErrCode result = OHOS::ERR_OK;
898
899 switch (optopt) {
900 case 's': {
901 // 'aa dump -s' with no argument: aa dump -s
902 // 'aa dump --stack' with no argument: aa dump --stack
903 HILOG_INFO("'aa dump -s' with no argument.");
904
905 resultReceiver_.append("error: option ");
906 resultReceiver_.append("requires a value.\n");
907 result = OHOS::ERR_INVALID_VALUE;
908 break;
909 }
910 case 'm': {
911 // 'aa dump -m' with no argument: aa dump -m
912 // 'aa dump --mission' with no argument: aa dump --mission
913 HILOG_INFO("'aa dump -m' with no argument.");
914
915 resultReceiver_.append("error: option ");
916 resultReceiver_.append("requires a value.\n");
917 result = OHOS::ERR_INVALID_VALUE;
918 break;
919 }
920 case 0: {
921 // 'aa dump' with an unknown option: aa dump --x
922 // 'aa dump' with an unknown option: aa dump --xxx
923 std::string unknownOption = "";
924 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
925
926 HILOG_INFO("'aa dump' with an unknown option.");
927
928 resultReceiver_.append(unknownOptionMsg);
929 result = OHOS::ERR_INVALID_VALUE;
930 break;
931 }
932 default: {
933 // 'aa dump' with an unknown option: aa dump -x
934 // 'aa dump' with an unknown option: aa dump -xxx
935 std::string unknownOption = "";
936 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
937
938 HILOG_INFO("'aa dump' with an unknown option.");
939
940 resultReceiver_.append(unknownOptionMsg);
941 result = OHOS::ERR_INVALID_VALUE;
942 break;
943 }
944 }
945
946 return result;
947 }
948
MakeWantFromCmd(Want & want,std::string & windowMode)949 ErrCode AbilityManagerShellCommand::MakeWantFromCmd(Want &want, std::string &windowMode)
950 {
951 int result = OHOS::ERR_OK;
952
953 int option = -1;
954 int counter = 0;
955
956 std::string deviceId = "";
957 std::string bundleName = "";
958 std::string abilityName = "";
959 bool isColdStart = false;
960 bool isDebugApp = false;
961 bool isContinuation = false;
962
963 while (true) {
964 counter++;
965
966 option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
967
968 HILOG_INFO("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
969
970 if (optind < 0 || optind > argc_) {
971 return OHOS::ERR_INVALID_VALUE;
972 }
973
974 if (option == -1) {
975 // When scanning the first argument
976 if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) {
977 // 'aa start' with no option: aa start
978 // 'aa start' with a wrong argument: aa start xxx
979 // 'aa stop-service' with no option: aa stop-service
980 // 'aa stop-service' with a wrong argument: aa stop-service xxx
981 HILOG_INFO("'aa %{public}s' %{public}s", HELP_MSG_NO_OPTION.c_str(), cmd_.c_str());
982
983 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
984 result = OHOS::ERR_INVALID_VALUE;
985 }
986 break;
987 }
988
989 if (option == '?') {
990 switch (optopt) {
991 case 'h': {
992 // 'aa start -h'
993 // 'aa stop-service -h'
994 result = OHOS::ERR_INVALID_VALUE;
995 break;
996 }
997 case 'd': {
998 // 'aa start -d' with no argument
999 // 'aa stop-service -d' with no argument
1000 HILOG_INFO("'aa %{public}s -d' with no argument.", cmd_.c_str());
1001
1002 resultReceiver_.append("error: option ");
1003 resultReceiver_.append("requires a value.\n");
1004
1005 result = OHOS::ERR_INVALID_VALUE;
1006 break;
1007 }
1008 case 'a': {
1009 // 'aa start -a' with no argument
1010 // 'aa stop-service -a' with no argument
1011 HILOG_INFO("'aa %{public}s -a' with no argument.", cmd_.c_str());
1012
1013 resultReceiver_.append("error: option ");
1014 resultReceiver_.append("requires a value.\n");
1015
1016 result = OHOS::ERR_INVALID_VALUE;
1017 break;
1018 }
1019 case 'b': {
1020 // 'aa start -b' with no argument
1021 // 'aa stop-service -b' with no argument
1022 HILOG_INFO("'aa %{public}s -b' with no argument.", cmd_.c_str());
1023
1024 resultReceiver_.append("error: option ");
1025 resultReceiver_.append("requires a value.\n");
1026
1027 result = OHOS::ERR_INVALID_VALUE;
1028 break;
1029 }
1030 case 's': {
1031 // 'aa start -s' with no argument
1032 // 'aa stop-service -s' with no argument
1033 HILOG_INFO("'aa %{public}s -s' with no argument.", cmd_.c_str());
1034
1035 resultReceiver_.append("error: option ");
1036 resultReceiver_.append(argv_[optind - 1]);
1037 resultReceiver_.append("' requires a value.\n");
1038
1039 result = OHOS::ERR_INVALID_VALUE;
1040 break;
1041 }
1042 case 0: {
1043 // 'aa start' with an unknown option: aa start --x
1044 // 'aa start' with an unknown option: aa start --xxx
1045 // 'aa stop-service' with an unknown option: aa stop-service --x
1046 // 'aa stop-service' with an unknown option: aa stop-service --xxx
1047 std::string unknownOption = "";
1048 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1049
1050 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
1051
1052 resultReceiver_.append(unknownOptionMsg);
1053 result = OHOS::ERR_INVALID_VALUE;
1054 break;
1055 }
1056 default: {
1057 // 'aa start' with an unknown option: aa start -x
1058 // 'aa start' with an unknown option: aa start -xxx
1059 // 'aa stop-service' with an unknown option: aa stop-service -x
1060 // 'aa stop-service' with an unknown option: aa stop-service -xxx
1061 std::string unknownOption = "";
1062 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
1063
1064 HILOG_INFO("'aa %{public}s' with an unknown option.", cmd_.c_str());
1065
1066 resultReceiver_.append(unknownOptionMsg);
1067 result = OHOS::ERR_INVALID_VALUE;
1068 break;
1069 }
1070 }
1071 break;
1072 }
1073
1074 switch (option) {
1075 case 'h': {
1076 // 'aa start -h'
1077 // 'aa start --help'
1078 // 'aa stop-service -h'
1079 // 'aa stop-service --help'
1080 result = OHOS::ERR_INVALID_VALUE;
1081 break;
1082 }
1083 case 'd': {
1084 // 'aa start -d xxx'
1085 // 'aa stop-service -d xxx'
1086
1087 // save device ID
1088 if (optarg != nullptr) {
1089 deviceId = optarg;
1090 }
1091 break;
1092 }
1093 case 'a': {
1094 // 'aa start -a xxx'
1095 // 'aa stop-service -a xxx'
1096
1097 // save ability name
1098 abilityName = optarg;
1099 break;
1100 }
1101 case 'b': {
1102 // 'aa start -b xxx'
1103 // 'aa stop-service -b xxx'
1104
1105 // save bundle name
1106 bundleName = optarg;
1107 break;
1108 }
1109 case 's': {
1110 // 'aa start -s xxx'
1111 // save windowMode
1112 windowMode = optarg;
1113 break;
1114 }
1115 case 'C': {
1116 // 'aa start -C'
1117 // cold start app
1118 isColdStart = true;
1119 break;
1120 }
1121 case 'D': {
1122 // 'aa start -D'
1123 // debug app
1124 isDebugApp = true;
1125 break;
1126 }
1127 case 'c': {
1128 // 'aa start -c'
1129 // set ability launch reason = continuation
1130 isContinuation = true;
1131 break;
1132 }
1133 case 0: {
1134 break;
1135 }
1136 default: {
1137 break;
1138 }
1139 }
1140 }
1141
1142 if (result == OHOS::ERR_OK) {
1143 if (abilityName.size() == 0 || bundleName.size() == 0) {
1144 // 'aa start [-d <device-id>] -a <ability-name> -b <bundle-name> [-D]'
1145 // 'aa stop-service [-d <device-id>] -a <ability-name> -b <bundle-name>'
1146 HILOG_INFO("'aa %{public}s' without enough options.", cmd_.c_str());
1147
1148 if (abilityName.size() == 0) {
1149 resultReceiver_.append(HELP_MSG_NO_ABILITY_NAME_OPTION + "\n");
1150 }
1151
1152 if (bundleName.size() == 0) {
1153 resultReceiver_.append(HELP_MSG_NO_BUNDLE_NAME_OPTION + "\n");
1154 }
1155
1156 result = OHOS::ERR_INVALID_VALUE;
1157 } else {
1158 ElementName element(deviceId, bundleName, abilityName);
1159 want.SetElement(element);
1160
1161 if (isColdStart) {
1162 WantParams wantParams;
1163 wantParams.SetParam("coldStart", Boolean::Box(isColdStart));
1164 want.SetParams(wantParams);
1165 }
1166 if (isDebugApp) {
1167 WantParams wantParams;
1168 wantParams.SetParam("debugApp", Boolean::Box(isDebugApp));
1169 want.SetParams(wantParams);
1170 }
1171 if (isContinuation) {
1172 want.AddFlags(Want::FLAG_ABILITY_CONTINUATION);
1173 }
1174 }
1175 }
1176
1177 return result;
1178 }
1179
RunAsTestCommand()1180 ErrCode AbilityManagerShellCommand::RunAsTestCommand()
1181 {
1182 HILOG_INFO("enter");
1183 std::map<std::string, std::string> params;
1184
1185 auto isDebug {false};
1186 for (int i = USER_TEST_COMMAND_START_INDEX; i < argc_; i++) {
1187 HILOG_INFO("argv_[%{public}d]: %{public}s", i, argv_[i]);
1188 std::string opt = argv_[i];
1189 if (opt == "-h" || opt == "--help") {
1190 resultReceiver_.append(HELP_MSG_TEST);
1191 return OHOS::ERR_OK;
1192 } else if (opt == "-b" || opt == "-w" || opt == "-p" || opt == "-m") {
1193 if (i >= argc_ - 1) {
1194 return TestCommandError("error: option [" + opt + "] requires a value.\n");
1195 }
1196 std::string argv = argv_[++i];
1197 params[opt] = argv;
1198 } else if (opt == "-s") {
1199 if (i >= argc_ - USER_TEST_COMMAND_PARAMS_NUM) {
1200 return TestCommandError("error: option [-s] is incorrect.\n");
1201 }
1202 std::string argKey = argv_[++i];
1203 std::string argValue = argv_[++i];
1204 params[opt + " " + argKey] = argValue;
1205 } else if (opt == "-D") {
1206 isDebug = true;
1207 params[opt] = DEBUG_VALUE;
1208 } else if (opt.at(0) == '-') {
1209 return TestCommandError("error: unknown option: " + opt + "\n");
1210 }
1211 }
1212
1213 if (!IsTestCommandIntegrity(params)) {
1214 return OHOS::ERR_INVALID_VALUE;
1215 }
1216
1217 return StartUserTest(params, isDebug);
1218 }
1219
IsTestCommandIntegrity(const std::map<std::string,std::string> & params)1220 bool AbilityManagerShellCommand::IsTestCommandIntegrity(const std::map<std::string, std::string> ¶ms)
1221 {
1222 HILOG_INFO("enter");
1223
1224 std::vector<std::string> opts = {"-b", "-s unittest"};
1225 for (auto opt : opts) {
1226 auto it = params.find(opt);
1227 if (it == params.end()) {
1228 TestCommandError("error: the option [" + opt + "] is expected.\n");
1229 return false;
1230 }
1231 }
1232 return true;
1233 }
1234
TestCommandError(const std::string & info)1235 ErrCode AbilityManagerShellCommand::TestCommandError(const std::string &info)
1236 {
1237 resultReceiver_.append(info);
1238 resultReceiver_.append(HELP_MSG_TEST);
1239 return OHOS::ERR_INVALID_VALUE;
1240 }
1241
StartUserTest(const std::map<std::string,std::string> & params,const bool isDebug)1242 ErrCode AbilityManagerShellCommand::StartUserTest(const std::map<std::string, std::string> ¶ms, const bool isDebug)
1243 {
1244 HILOG_INFO("enter, isDebug : %{public}s", (isDebug ? "true" : "false"));
1245
1246 Want want;
1247 for (auto param : params) {
1248 want.SetParam(param.first, param.second);
1249 }
1250
1251 if (isDebug) {
1252 HILOG_INFO("Set Debug to want");
1253 want.SetParam("debugApp", isDebug);
1254 }
1255
1256 sptr<TestObserver> observer = new (std::nothrow) TestObserver();
1257 if (!observer) {
1258 HILOG_ERROR("Failed: the TestObserver is null");
1259 return OHOS::ERR_INVALID_VALUE;
1260 }
1261
1262 int result = AbilityManagerClient::GetInstance()->StartUserTest(want, observer->AsObject());
1263 if (result != OHOS::ERR_OK) {
1264 HILOG_INFO("%{public}s result = %{public}d", STRING_START_USER_TEST_NG.c_str(), result);
1265 resultReceiver_ = STRING_START_USER_TEST_NG + "\n";
1266 resultReceiver_.append(GetMessageFromCode(result));
1267 return result;
1268 }
1269 HILOG_INFO("%{public}s", STRING_START_USER_TEST_OK.c_str());
1270
1271 int64_t timeMs = 0;
1272 if (!want.GetStringParam("-w").empty()) {
1273 int time = std::stoi(want.GetStringParam("-w"));
1274 timeMs = time * TIME_RATE_MS;
1275 }
1276 if (!observer->WaitForFinish(timeMs)) {
1277 resultReceiver_ = "Timeout: user test is not completed within the specified time.\n";
1278 return OHOS::ERR_INVALID_VALUE;
1279 }
1280 resultReceiver_ = STRING_START_USER_TEST_OK + "\n";
1281
1282 return result;
1283 }
1284
GetAbilityManagerService()1285 sptr<IAbilityManager> AbilityManagerShellCommand::GetAbilityManagerService()
1286 {
1287 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1288 if (systemManager == nullptr) {
1289 HILOG_ERROR("Fail to get registry.");
1290 return nullptr;
1291 }
1292 sptr<IRemoteObject> remoteObject = systemManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
1293 return iface_cast<IAbilityManager>(remoteObject);
1294 }
1295 } // namespace AAFwk
1296 } // namespace OHOS
1297