• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "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> &params)
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> &params, 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