1 /* 2 * Copyright (c) 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 16 #include "wukong_command.h" 17 #include "wukong_app_manager.h" 18 #include "wukong_event_manager.h" 19 #include "wukong_exception_manager.h" 20 #include "bundle_mgr_proxy.h" 21 22 #include "ability_manager_client.h" 23 #include "system_ability_definition.h" 24 #include "iservice_registry.h" 25 #include "launcher_service.h" 26 27 #include <iostream> 28 #include <getopt.h> 29 #include <random> 30 #include <chrono> 31 #include <thread> 32 #include <unistd.h> 33 34 using namespace OHOS::AAFwk; 35 36 namespace OHOS { 37 namespace AppExecFwk { 38 namespace { 39 bool g_commandSEEDENABLE = false; 40 bool g_commandCOUNTENABLE = false; 41 bool g_commandBUNDLEENABLE = false; 42 bool g_commandHELPENABLE = false; 43 bool g_commandVERSIONENABLE = false; 44 bool g_commandAPPSWITCHENABLE = false; 45 bool g_commandTOUCHENABLE = false; 46 bool g_commandINSOMNIAENABLE = false; 47 bool g_commandMOTIONENABLE = false; 48 bool g_commandXENABLE = false; 49 bool g_commandYENABLE = false; 50 bool g_commandTouch = false; 51 52 53 const std::string SHORT_OPTIONS = "a:b:c:hi:s:t:vkl:x:y:m:n:"; 54 const struct option LONG_OPTIONS[] = { 55 {"appswitch", required_argument, nullptr, 'a'}, 56 {"bundle", required_argument, nullptr, 'b'}, 57 {"count", required_argument, nullptr, 'c'}, 58 {"help", no_argument, nullptr, 'h'}, 59 {"interval", required_argument, nullptr, 'i'}, 60 {"seed", required_argument, nullptr, 's'}, 61 {"touch", required_argument, nullptr, 't'}, 62 {"version", no_argument, nullptr, 'v'}, 63 {"spec_insomnia", no_argument, nullptr, 'k'}, 64 {"motion", required_argument, nullptr, 'l'}, 65 {"xSrc", required_argument, nullptr, 'x'}, 66 {"ySrc", required_argument, nullptr, 'y'}, 67 {"xDst", required_argument, nullptr, 'm'}, 68 {"yDst", required_argument, nullptr, 'n'}, 69 {"touch_pos", no_argument, nullptr, 'u'}, 70 }; 71 } 72 WuKongCommand(int argc,char * argv[])73 WuKongCommand::WuKongCommand(int argc, char *argv[]) : ShellCommand(argc, argv, WUKONG_TOOL_NAME) 74 {} 75 init()76 ErrCode WuKongCommand::init() 77 { 78 return OHOS::ERR_OK; 79 } 80 CreateCommandMap()81 ErrCode WuKongCommand::CreateCommandMap() 82 { 83 commandMap_ = { 84 {"-v", std::bind(&WuKongCommand::GetWuKongVersion, this)}, 85 {"help", std::bind(&WuKongCommand::RunAsHelpCommand, this)}, 86 {"exec", std::bind(&WuKongCommand::RunAsParseCommand, this)}, 87 {"appinfo", std::bind(&WuKongCommand::ShowAllAppInfo, this)}, 88 }; 89 return OHOS::ERR_OK; 90 } 91 CreateMessageMap()92 ErrCode WuKongCommand::CreateMessageMap() 93 { 94 messageMap_ = { 95 { ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR, "error: wukong internal error.", }, 96 }; 97 return OHOS::ERR_OK; 98 } 99 RunAsParseCommand()100 ErrCode WuKongCommand::RunAsParseCommand() 101 { 102 int result = OHOS::ERR_OK; 103 104 int counter = 0; 105 106 while (true) { 107 int option = -1; 108 counter++; 109 option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr); 110 111 // process error 112 if (optind < 0 || optind > argc_) { 113 return OHOS::ERR_INVALID_VALUE; 114 } 115 116 // process error 117 if (option == -1) { 118 if (counter == 1 && strcmp(argv_[optind], cmd_.c_str()) == 0) { 119 // 'wukong exec' with no option: wukong exec 120 // 'wukong exec' with a wrong argument: wukong exec xxx 121 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); 122 result = OHOS::ERR_INVALID_VALUE; 123 } 124 break; 125 } 126 127 // process error 128 if (option == '?') { 129 result = HandleUnknownOption(optopt); 130 break; 131 } 132 133 // process correct 134 result = HandleNormalOption(option); 135 } 136 137 if (result == OHOS::ERR_OK) { 138 result = RunAsExecCommand(); 139 resultReceiver_.append(STRING_WUKONG_INFO_OK); 140 } else { 141 resultReceiver_.append(STRING_WUKONG_INFO_NG); 142 } 143 return result; 144 } 145 HandleUnknownOption(const char optopt)146 ErrCode WuKongCommand::HandleUnknownOption(const char optopt) 147 { 148 int result = OHOS::ERR_OK; 149 switch (optopt) { 150 case 'a': 151 case 'b': 152 case 'c': 153 case 'i': 154 case 's': 155 case 't': 156 case 'x': 157 case 'y': 158 case 'u': 159 resultReceiver_.append("error: option '"); 160 resultReceiver_.append(argv_[optind - 1]); 161 resultReceiver_.append("' requires a value.\n"); 162 result = OHOS::ERR_INVALID_VALUE; 163 break; 164 case 'h': { 165 result = OHOS::ERR_INVALID_VALUE; 166 break; 167 } 168 default: { 169 // 'wukong exec' with a unknown option: wukong exec -x 170 std::cerr << "'wukong' with a unknown option" << std::endl; 171 result = OHOS::ERR_INVALID_VALUE; 172 break; 173 } 174 } 175 return result; 176 } 177 HandleNormalOption(const int option)178 ErrCode WuKongCommand::HandleNormalOption(const int option) 179 { 180 int result = OHOS::ERR_OK; 181 switch (option) { 182 case 'a': { 183 g_commandAPPSWITCHENABLE = true; 184 abilityPercent = std::stof(optarg); 185 break; 186 } 187 case 'b': { 188 bundleNameArgs = optarg; 189 g_commandBUNDLEENABLE = true; 190 break; 191 } 192 case 'c': { 193 countArgs = std::stoi(optarg); 194 g_commandCOUNTENABLE = true; 195 break; 196 } 197 case 'h': { 198 g_commandHELPENABLE = true; 199 break; 200 } 201 case 'i': { 202 intervalArgs = std::stoi(optarg); 203 break; 204 } 205 case 's': { 206 seedArgs = std::stoi(optarg); 207 g_commandSEEDENABLE = true; 208 break; 209 } 210 case 't': { 211 g_commandTOUCHENABLE = true; 212 touchPercent = std::stof(optarg); 213 break; 214 } 215 case 'v': { 216 g_commandVERSIONENABLE = true; 217 break; 218 } 219 case 'k': { 220 g_commandINSOMNIAENABLE = true; 221 break; 222 } 223 case 'l': { 224 g_commandMOTIONENABLE = true; 225 break; 226 } 227 case 'x': { 228 g_commandXENABLE = true; 229 xSrcPosi = std::stoi(optarg); 230 break; 231 } 232 case 'y': { 233 g_commandYENABLE = true; 234 ySrcPosi = std::stoi(optarg); 235 break; 236 } 237 case 'm': { 238 g_commandYENABLE = true; 239 xDstPosi = std::stoi(optarg); 240 break; 241 } 242 case 'n': { 243 g_commandYENABLE = true; 244 yDstPosi = std::stoi(optarg); 245 break; 246 } 247 case 'u': 248 g_commandTouch = true; 249 break; 250 } 251 return result; 252 } 253 ShowAllAppInfo()254 ErrCode WuKongCommand::ShowAllAppInfo() 255 { 256 int result = GetAllAppInfo(); 257 if (result == OHOS::ERR_OK) { 258 for (unsigned index = 0; index < bundleList.size(); index++) { 259 std::cout << "BundleName: " << bundleList[index] << std::endl; 260 std::cout << "AbilityName: " << abilityList[index] << std::endl; 261 } 262 } else { 263 result = OHOS::ERR_INVALID_VALUE; 264 } 265 return result; 266 } 267 GetAllAppInfo()268 ErrCode WuKongCommand::GetAllAppInfo() 269 { 270 LauncherService launcherservice; 271 int32_t userId = 100; 272 std::vector<LauncherAbilityInfo> launcherAbilityInfos; 273 launcherservice.GetAllLauncherAbilityInfos(userId, launcherAbilityInfos); 274 for (auto item : launcherAbilityInfos) { 275 bundleList.push_back(item.elementName.GetBundleName()); 276 abilityList.push_back(item.elementName.GetAbilityName()); 277 } 278 return OHOS::ERR_OK; 279 } 280 RunAsExecCommand()281 ErrCode WuKongCommand::RunAsExecCommand() 282 { 283 const int windowsWidth = 720; 284 const int windowsHeight = 1080; 285 286 if (g_commandHELPENABLE) { 287 int result = RunAsHelpCommand(); 288 return result; 289 } 290 291 if (g_commandVERSIONENABLE) { 292 int result = GetWuKongVersion(); 293 return result; 294 } 295 296 if (g_commandSEEDENABLE) { 297 srand(seedArgs); 298 } else { 299 srand((unsigned int)time(nullptr)); 300 seedArgs = (int)time(nullptr); 301 } 302 303 if (g_commandTouch) { 304 checkPosition(windowsWidth, windowsHeight); 305 int result = RunTouchCommand(); 306 return result; 307 } 308 int result = GetAllAppInfo(); 309 310 float randomPercent = -1.0; 311 int index = -1; 312 int touchX = -1; 313 int touchY = -1; 314 bool slideDirection = true; 315 316 std::cout << "seed:" << seedArgs << std::endl; 317 std::cout << "count:" << countArgs << std::endl; 318 std::cout << "interval:" << intervalArgs << std::endl; 319 320 int defaultMotionPressure = 5; 321 int sleepAwakeChangeInterval = 2; 322 int oneMs = 1000; 323 bool singleAppFlag = false; 324 325 bool startReuslt = WuKongExceptionManager::GetInstance()->StartCatching(); 326 if (!startReuslt) { 327 std::cerr << "[Error] failed to start catching" << std::endl; 328 return OHOS::ERR_NO_INIT; 329 } 330 for (int i = 1; i <= countArgs; i++) { 331 if (g_commandINSOMNIAENABLE) { 332 result = WuKongEventManager::GetInstance()->PowerOnAndOffEvent(); 333 usleep(intervalArgs * oneMs); 334 if (i % sleepAwakeChangeInterval == 1) { 335 std::cout << i << " sleep" << std::endl; 336 } else { 337 std::cout << i << " awake" << std::endl; 338 } 339 } else if (g_commandXENABLE && g_commandYENABLE) { 340 if (!g_commandCOUNTENABLE) { 341 result = WuKongEventManager::GetInstance()->MotionEvent(xSrcPosi, ySrcPosi, 342 xDstPosi, yDstPosi, 343 defaultMotionPressure); 344 break; 345 } 346 if (slideDirection) { 347 std::cout << "slideDirection:" << " come" << std::endl; 348 result = WuKongEventManager::GetInstance()->MotionEvent(xSrcPosi, ySrcPosi, 349 xDstPosi, yDstPosi, 350 defaultMotionPressure); 351 slideDirection = false; 352 } else { 353 std::cout << "slideDirection:" << " go" << std::endl; 354 result = WuKongEventManager::GetInstance()->MotionEvent(xDstPosi, yDstPosi, 355 xSrcPosi, ySrcPosi, 356 defaultMotionPressure); 357 slideDirection = true; 358 } 359 usleep(intervalArgs * oneMs); 360 } else { 361 int maxPercent = 100; 362 randomPercent = (float)(rand() % maxPercent) / maxPercent; 363 if ((randomPercent < touchPercent) || singleAppFlag) { 364 touchX = rand() % windowsWidth; 365 touchY = rand() % windowsHeight; 366 std::cout << "touch: (" << touchX << ", " << touchY << ")" << std::endl; 367 result = WuKongEventManager::GetInstance()->TouchEvent(touchX, touchY); 368 usleep(intervalArgs * oneMs); 369 continue; 370 } 371 singleAppFlag = g_commandBUNDLEENABLE; 372 index = getAbilityIndex(); 373 if (index == -1) { 374 std::cout << "Not Found " << bundleNameArgs << ", please check bundle name!" << std::endl; 375 result = OHOS::ERR_INVALID_VALUE; 376 break; 377 } 378 result = WuKongAppManager::GetInstance()->StartAbilityByBundleInfo(abilityList[index], 379 bundleList[index]); 380 result = PrintResultOfStartAbility(result, index); 381 usleep(intervalArgs * oneMs); 382 } 383 } 384 WuKongExceptionManager::GetInstance()->StopCatching(); 385 386 return result; 387 } 388 PrintResultOfStartAbility(const ErrCode result,int index)389 ErrCode WuKongCommand::PrintResultOfStartAbility(const ErrCode result, int index) 390 { 391 if (result == OHOS::ERR_OK) { 392 std::cout << "bundleName: " << bundleList[index] << " startup succeed" << std::endl; 393 } else { 394 std::cout << "bundleName: " << bundleList[index] << " startup fail" << std::endl; 395 } 396 return OHOS::ERR_OK; 397 } 398 checkPosition(int width,int height)399 void WuKongCommand::checkPosition(int width, int height) 400 { 401 if (xSrcPosi < 0) { 402 xSrcPosi = 0; 403 } 404 405 if (ySrcPosi < 0) { 406 ySrcPosi = 0; 407 } 408 409 if (xSrcPosi > width) { 410 xSrcPosi = width; 411 } 412 413 if (ySrcPosi > height) { 414 ySrcPosi = height; 415 } 416 } 417 getAbilityIndex()418 int WuKongCommand::getAbilityIndex() 419 { 420 int index; 421 if (g_commandBUNDLEENABLE) { 422 index = FindElement(bundleList, bundleNameArgs); 423 } else { 424 index = rand() % bundleList.size(); 425 } 426 return index; 427 } 428 RunTouchCommand()429 ErrCode WuKongCommand::RunTouchCommand() 430 { 431 int result = WuKongEventManager::GetInstance()->TouchEvent(xSrcPosi, ySrcPosi); 432 return result; 433 } 434 RunAsHelpCommand()435 ErrCode WuKongCommand::RunAsHelpCommand() 436 { 437 resultReceiver_ = WUKONG_HELP_MSG; 438 return OHOS::ERR_OK; 439 } 440 GetWuKongVersion()441 ErrCode WuKongCommand::GetWuKongVersion() 442 { 443 resultReceiver_ = WUKONG_TOOL_VERSION; 444 return OHOS::ERR_OK; 445 } 446 FindElement(std::vector<std::string> bundleList,std::string key)447 int WuKongCommand::FindElement(std::vector<std::string> bundleList, std::string key) 448 { 449 std::vector<std::string>::iterator it; 450 std::cout << "BundleName: " << key << std::endl; 451 it = find(bundleList.begin(), bundleList.end(), key); 452 if (it != bundleList.end()) { 453 return distance(bundleList.begin(), it); 454 } 455 return -1; 456 } 457 } 458 }