* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ui_input.h"
namespace OHOS::uitest {
using namespace std;
std::string opt;
ApiCallErr exception_ = ApiCallErr(NO_ERROR);
void CheckSwipeVelocityPps(UiOpArgs& args)
{
if (args.swipeVelocityPps_ < args.minSwipeVelocityPps_ || args.swipeVelocityPps_ > args.maxSwipeVelocityPps_) {
std::cout << "The swipe velocity out of range, the default value will be used. \n" << std::endl;
args.swipeVelocityPps_ = args.defaultSwipeVelocityPps_;
}
}
bool CheckParams(int32_t argc, size_t want)
{
if ((size_t)argc < want) {
std::cout << "Missing parameter. \n" << std::endl;
PrintInputMessage();
return false;
}
return true;
}
void PrintInputMessage()
{
const std::string usage =
"USAGE : \n"
"help print uiInput usage\n"
"dircFling <direction> [velocity] [stepLength] [displayId] fling in the specified direction\n"
" direction ranges from 0,1,2,3 (left, right, up, down)\n"
" velocity ranges from 200 to 40000, default 600\n"
" stepLength defaults to the width or height of the screen divided by 200\n"
" displayId defaults to the default display id\n"
"click/doubleClick/longClick <x> <y> [displayId] click on the target coordinates\n"
" displayId defaults to the default display id\n"
"swipe/drag <from_x> <from_y> <to_x> <to_y> [velocity] [displayId] \n"
" velocity ranges from 200 to 40000, default 600\n"
" displayId defaults to the default display id\n"
"fling <from_x> <from_y> <to_x> <to_y> [velocity] [stepLength] [displayId] \n"
" velocity ranges from 200 to 40000, default 600\n"
" stepLength defaults to the distance divided by 50\n"
" displayId defaults to the default display id\n"
"keyEvent <keyID/Back/Home/Power> [displayId] inject keyEvent\n"
" displayId defaults to the default display id\n"
"keyEvent <keyID_0> <keyID_1> [keyID_2] [displayId] keyID_2 defaults to None\n"
" displayId defaults to the default display id\n"
"inputText <x> <y> <text> [displayId] inputText at the target coordinate point\n"
" displayId defaults to the default display id\n"
"text <text> [displayId] input text at the location where is already focused\n"
" displayId defaults to the default display id\n";
std::cout << usage << std::endl;
}
bool ParameterRedundancy()
{
std::cout << " Too many parameters. \n" << std::endl;
PrintInputMessage();
return EXIT_FAILURE;
}
static bool CreateFlingPoint(Point &to, Point &from, Point screenSize, Direction direction)
{
to = Point(screenSize.px_ / INDEX_TWO, screenSize.py_ / INDEX_TWO);
switch (direction) {
case TO_LEFT:
from.px_ = to.px_ - screenSize.px_ / INDEX_FOUR;
from.py_ = to.py_;
return true;
case TO_RIGHT:
from.px_ = to.px_ + screenSize.px_ / INDEX_FOUR;
from.py_ = to.py_;
return true;
case TO_UP:
from.px_ = to.px_;
from.py_ = to.py_ - screenSize.py_ / INDEX_FOUR;
return true;
case TO_DOWN:
from.px_ = to.px_;
from.py_ = to.py_ + screenSize.py_ / INDEX_FOUR;
return true;
default:
std::cout << "Illegal argument: " + std::to_string(direction) << std::endl;
PrintInputMessage();
return false;
}
}
bool GetPoints(Point &to, Point &from, int32_t argc, char *argv[])
{
auto from_x = atoi(argv[THREE]);
auto from_y = atoi(argv[FOUR]);
auto to_x = atoi(argv[FIVE]);
auto to_y = atoi(argv[SIX]);
if (from_x <= 0 || from_y <= 0 || to_x <= 0 || to_y <= 0) {
std::cout << "Please confirm that the coordinate values are correct. \n" << std::endl;
PrintInputMessage();
return false;
}
from = Point(from_x, from_y);
to = Point(to_x, to_y);
return true;
}
bool GetPoint(Point &point, int32_t argc, char *argv[])
{
auto from_x = atoi(argv[THREE]);
auto from_y = atoi(argv[FOUR]);
if (from_x <= 0 || from_y <= 0) {
std::cout << "Please confirm that the coordinate values are correct. \n" << std::endl;
PrintInputMessage();
return false;
}
point = Point(from_x, from_y);
return true;
}
bool CheckStepLength(UiOpArgs &uiOpArgs, Point to, Point from, uint32_t stepLength)
{
const int32_t distanceX = to.px_ - from.px_;
const int32_t distanceY = to.py_ - from.py_;
const uint32_t distance = sqrt(distanceX * distanceX + distanceY * distanceY);
if (stepLength <= 0 || stepLength > distance) {
std::cout << "The stepLen is out of range" << std::endl;
return EXIT_FAILURE;
} else {
uiOpArgs.swipeStepsCounts_ = distance / stepLength;
return true;
}
}
static bool TryParseDisplayId(int32_t argc, char *argv[], size_t pos, int32_t &displayId)
{
if (static_cast<size_t>(argc) > pos + 1) {
return false;
}
if (static_cast<size_t>(argc) == pos + 1) {
displayId = atoi(argv[pos]);
}
return true;
}
int32_t FlingActionInput(int32_t argc, char *argv[], UiDriver &driver, UiOpArgs uiOpArgs)
{
Direction direction;
Point from;
Point to;
int32_t displayId = -1;
if (opt == "dircFling" && CheckParams(argc, INDEX_FOUR)) {
direction = (Direction)atoi(argv[THREE]);
if ((size_t)argc >= INDEX_FIVE) {
uiOpArgs.swipeVelocityPps_ = atoi(argv[FOUR]);
}
if ((size_t)argc >= INDEX_SIX) {
uiOpArgs.swipeStepsCounts_ = atoi(argv[FIVE]);
}
if (!TryParseDisplayId(argc, argv, SIX, displayId)) {
return ParameterRedundancy();
}
auto screenSize = driver.GetDisplaySize(exception_, displayId);
if (!CreateFlingPoint(to, from, screenSize, direction)) {
return EXIT_FAILURE;
}
} else if (opt == "fling" && CheckParams(argc, INDEX_SEVEN)) {
if (!GetPoints(to, from, argc, argv)) {
return EXIT_FAILURE;
}
if ((size_t)argc >= INDEX_EIGHT) {
uiOpArgs.swipeVelocityPps_ = (uint32_t)atoi(argv[SEVEN]);
}
if ((size_t)argc >= INDEX_NINE) {
auto stepLength = (uint32_t)atoi(argv[EIGHT]);
if (!CheckStepLength(uiOpArgs, to, from, stepLength)) {
return EXIT_FAILURE;
}
}
if (!TryParseDisplayId(argc, argv, INDEX_NINE, displayId)) {
return ParameterRedundancy();
}
} else {
return EXIT_FAILURE;
}
CheckSwipeVelocityPps(uiOpArgs);
if (displayId != -1) {
from.displayId_ = displayId;
to.displayId_ = displayId;
}
auto touch = GenericSwipe(TouchOp::SWIPE, from, to);
driver.PerformTouch(touch, uiOpArgs, exception_);
std::cout << exception_.message_ << std::endl;
return EXIT_SUCCESS;
}
int32_t SwipeActionInput(int32_t argc, char *argv[], UiDriver &driver, UiOpArgs uiOpArgs)
{
opt = argv[TWO];
TouchOp op = TouchOp::SWIPE;
if (opt == "drag") {
op = TouchOp::DRAG;
}
Point from;
Point to;
if (CheckParams(argc, INDEX_SEVEN)) {
if (!GetPoints(to, from, argc, argv)) {
return EXIT_FAILURE;
}
int32_t displayId = -1;
if ((size_t)argc == INDEX_EIGHT) {
uiOpArgs.swipeVelocityPps_ = (uint32_t)atoi(argv[SEVEN]);
} else if ((size_t)argc == INDEX_NINE) {
uiOpArgs.swipeVelocityPps_ = (uint32_t)atoi(argv[SEVEN]);
displayId = atoi(argv[EIGHT]);
} else if ((size_t)argc > INDEX_NINE) {
return ParameterRedundancy();
}
if (displayId != -1) {
from.displayId_ = displayId;
to.displayId_ = displayId;
}
} else {
return EXIT_FAILURE;
}
CheckSwipeVelocityPps(uiOpArgs);
auto touch = GenericSwipe(op, from, to);
driver.PerformTouch(touch, uiOpArgs, exception_);
std::cout << exception_.message_ << std::endl;
return EXIT_SUCCESS;
}
int32_t KeyEventActionInput(int32_t argc, char *argv[], UiDriver &driver, UiOpArgs uiOpArgs)
{
std::string key = argv[THREE];
int32_t displayId = -1;
if (key == "Home" || key == "Back" || key == "Power") {
if ((size_t)argc != INDEX_FIVE && (size_t)argc != INDEX_FOUR) {
return ParameterRedundancy();
}
displayId = (size_t)argc == INDEX_FIVE ? atoi(argv[FOUR]) : -1;
if (key == "Home") {
driver.TriggerKey(Home(), uiOpArgs, exception_, displayId);
} else if (key == "Back") {
driver.TriggerKey(Back(), uiOpArgs, exception_, displayId);
} else if (key == "Power") {
driver.TriggerKey(Power(), uiOpArgs, exception_, displayId);
}
} else if (atoi(argv[THREE]) != 0) {
int32_t codeZero = atoi(argv[THREE]);
int32_t codeOne = (size_t)argc >= INDEX_FIVE ? atoi(argv[FOUR]) : KEYCODE_NONE;
int32_t codeTwo = (size_t)argc >= INDEX_SIX ? atoi(argv[FIVE]) : KEYCODE_NONE;
displayId = (size_t)argc == INDEX_SEVEN ? atoi(argv[SIX]) : -1;
if ((size_t)argc == INDEX_FOUR) {
driver.TriggerKey(AnonymousSingleKey(codeZero), uiOpArgs, exception_, displayId);
} else if ((size_t)argc >= INDEX_FIVE && (size_t)argc <= INDEX_SEVEN) {
driver.TriggerKey(CombinedKeys(codeZero, codeOne, codeTwo), uiOpArgs, exception_, displayId);
} else {
return ParameterRedundancy();
}
} else {
std::cout << "Invalid parameters. \n" << std::endl;
PrintInputMessage();
return EXIT_FAILURE;
}
std::cout << exception_.message_ << std::endl;
return EXIT_SUCCESS;
}
int32_t TextActionInput(int32_t argc, char *argv[], UiDriver &driver, UiOpArgs uiOpArgs)
{
if ((size_t)argc != INDEX_FOUR && (size_t)argc != INDEX_FIVE) {
std::cout << "The number of parameters is incorrect. \n" << std::endl;
PrintInputMessage();
return EXIT_FAILURE;
}
auto text = argv[THREE];
int32_t displayId = -1;
if ((size_t)argc == INDEX_FIVE) {
displayId = atoi(argv[FOUR]);
}
driver.InputText(text, exception_, uiOpArgs, displayId);
std::cout << exception_.message_ << std::endl;
return EXIT_SUCCESS;
}
int32_t TextActionInputWithPoint(int32_t argc, char *argv[], UiDriver &driver, UiOpArgs uiOpArgs)
{
if ((size_t)argc != INDEX_SIX && (size_t)argc != INDEX_SEVEN) {
std::cout << "The number of parameters is incorrect. \n" << std::endl;
PrintInputMessage();
return EXIT_FAILURE;
}
Point point;
if (!GetPoint(point, argc, argv)) {
return EXIT_FAILURE;
}
auto text = argv[FIVE];
int32_t displayId = -1;
if ((size_t)argc == INDEX_SEVEN) {
displayId = atoi(argv[SIX]);
point.displayId_ = displayId;
}
auto touch = GenericClick(TouchOp::CLICK, point);
driver.PerformTouch(touch, uiOpArgs, exception_);
static constexpr uint32_t focusTimeMs = 500;
driver.DelayMs(focusTimeMs);
driver.InputText(text, exception_, uiOpArgs, displayId);
std::cout << exception_.message_ << std::endl;
return EXIT_SUCCESS;
}
int32_t ClickActionInput(int32_t argc, char *argv[], UiDriver &driver, UiOpArgs uiOpArgs)
{
if ((size_t)argc != INDEX_FIVE && (size_t)argc != INDEX_SIX) {
std::cout << "The number of parameters is incorrect. \n" << std::endl;
PrintInputMessage();
return EXIT_FAILURE;
}
TouchOp op = TouchOp::CLICK;
if (opt == "doubleClick") {
op = TouchOp::DOUBLE_CLICK_P;
} else if (opt == "longClick") {
op = TouchOp::LONG_CLICK;
}
Point point;
if (!GetPoint(point, argc, argv)) {
return EXIT_FAILURE;
}
if ((size_t)argc == INDEX_SIX) {
point.displayId_ = atoi(argv[FIVE]);
}
auto touch = GenericClick(op, point);
driver.PerformTouch(touch, uiOpArgs, exception_);
std::cout << exception_.message_ << std::endl;
return EXIT_SUCCESS;
}
int32_t UiActionInput(int32_t argc, char *argv[])
{
auto driver = UiDriver();
UiOpArgs uiOpArgs;
opt = argv[TWO];
if (!CheckParams(argc, INDEX_FOUR)) {
return EXIT_FAILURE;
}
if (opt == "keyEvent") {
return KeyEventActionInput(argc, argv, driver, uiOpArgs);
} else if (opt == "fling" || opt == "dircFling") {
return FlingActionInput(argc, argv, driver, uiOpArgs);
} else if (opt == "swipe" || opt == "drag") {
return SwipeActionInput(argc, argv, driver, uiOpArgs);
} else if (opt == "click" || opt == "longClick" || opt == "doubleClick") {
return ClickActionInput(argc, argv, driver, uiOpArgs);
} else if (opt == "inputText") {
return TextActionInputWithPoint(argc, argv, driver, uiOpArgs);
} else if (opt == "text") {
return TextActionInput(argc, argv, driver, uiOpArgs);
} else {
std::cout << "Invalid parameters. \n" << std::endl;
PrintInputMessage();
return EXIT_FAILURE;
}
}
}