From fd0b47f662a45036206f695e33697aaf072561b6 Mon Sep 17 00:00:00 2001 From: Wonki Kim Date: Mon, 8 Jun 2020 21:08:53 +0900 Subject: [PATCH] libaurum: refactor a flick command and implementation this patch refactor a flick command and its implementation it's designed like below. ^drag start ^drag stop |<----------------- 100ms minimum -------------->| ***-------++--------++++------++--------+++-------### |<------>|<------->|<------->|<------->|<------->| ^25ms minimum for each *:touch down +:touch move #:touch up Change-Id: Ibeebf61268177ae9ed5dfa368ee21a140381796b --- libaurum/inc/DeviceImpl/TizenImpl.h | 11 ++ libaurum/src/DeviceImpl/TizenImpl.cc | 119 ++++++++------------- .../inc/Commands/FlickCommand.h | 1 + .../src/Commands/FlickCommand.cc | 2 +- protocol/examples/python/testFeatures.py | 4 +- 5 files changed, 61 insertions(+), 76 deletions(-) diff --git a/libaurum/inc/DeviceImpl/TizenImpl.h b/libaurum/inc/DeviceImpl/TizenImpl.h index 136c669..0d5ed83 100644 --- a/libaurum/inc/DeviceImpl/TizenImpl.h +++ b/libaurum/inc/DeviceImpl/TizenImpl.h @@ -40,11 +40,22 @@ protected: bool pressKeyCode(std::string keycode, unsigned int intv); private: + void startTimer(void); + int stopTimer(void); + +private: efl_util_inputgen_h mFakeTouchHandle; efl_util_inputgen_h mFakeKeyboardHandle; efl_util_inputgen_h mFakeWheelHandle; static const unsigned int INTV_CLICK = 5; static const unsigned int INTV_KEYPRESS = 10; + static const unsigned int INTV_MINIMUM_DRAG_MS = 25; + static const unsigned int INTV_MINIMUM_USLEEP = 1000; + static const unsigned int MINIMUM_DURATION_DRAG = 100; + static const unsigned int MSEC_PER_SEC = 1000; + + struct timespec tStart; + bool isTimerStarted; }; #endif \ No newline at end of file diff --git a/libaurum/src/DeviceImpl/TizenImpl.cc b/libaurum/src/DeviceImpl/TizenImpl.cc index 7ad730f..1557f61 100644 --- a/libaurum/src/DeviceImpl/TizenImpl.cc +++ b/libaurum/src/DeviceImpl/TizenImpl.cc @@ -11,7 +11,7 @@ #include TizenImpl::TizenImpl() -: mFakeTouchHandle{0}, mFakeKeyboardHandle{0}, mFakeWheelHandle{0} +: mFakeTouchHandle{0}, mFakeKeyboardHandle{0}, mFakeWheelHandle{0}, isTimerStarted{false} { LOG_SCOPE_F(INFO, "device implementation init"); ecore_main_loop_thread_safe_call_sync([](void *data)->void*{ @@ -42,28 +42,17 @@ bool TizenImpl::click(const int x, const int y) bool TizenImpl::click(const int x, const int y, const unsigned int intv) { - LOG_SCOPE_F(INFO, "click at (%d, %d)", x, y); - auto args = std::make_tuple(this, x, y, intv); - ecore_main_loop_thread_safe_call_sync([](void *data)->void*{ - TizenImpl *obj; - int x, y; - unsigned int intv; - std::tie(obj, x, y, intv) = *static_cast*>(data); + touchDown(x, y); + usleep(intv * MSEC_PER_SEC); + touchUp(x, y); - efl_util_input_generate_touch(obj->mFakeTouchHandle, 0, - EFL_UTIL_INPUT_TOUCH_BEGIN, x, y); - usleep(intv*10000); - efl_util_input_generate_touch(obj->mFakeTouchHandle, 0, EFL_UTIL_INPUT_TOUCH_END, - x, y); - return NULL; - }, (void*)(&args)); return true; } bool TizenImpl::touchDown(const int x, const int y) { - LOG_F(INFO, "%d %d", x, y); + LOG_F(INFO, "touch down %d %d", x, y); auto args = std::make_tuple(this, x, y); ecore_main_loop_thread_safe_call_sync([](void *data)->void*{ TizenImpl *obj; @@ -79,7 +68,7 @@ bool TizenImpl::touchDown(const int x, const int y) bool TizenImpl::touchMove(const int x, const int y) { - LOG_F(INFO, "%d %d", x, y); + LOG_F(INFO, "touch move %d %d", x, y); auto args = std::make_tuple(this, x, y); ecore_main_loop_thread_safe_call_sync([](void *data)->void*{ TizenImpl *obj; @@ -104,10 +93,8 @@ bool TizenImpl::touchUp(const int x, const int y) std::tie(obj, x, y) = *static_cast*>(data); efl_util_input_generate_touch(obj->mFakeTouchHandle, 0, EFL_UTIL_INPUT_TOUCH_END, x, y); - return NULL; }, (void*)(&args)); - return true; } @@ -122,7 +109,7 @@ bool TizenImpl::wheelUp(int amount, const int durationMs) efl_util_input_generate_wheel(obj->mFakeWheelHandle, EFL_UTIL_INPUT_POINTER_WHEEL_HORZ, 1); return NULL; }, (void*)(&args)); - usleep(durationMs*1000/amount); + usleep(durationMs*MSEC_PER_SEC/amount); } return true; @@ -139,74 +126,60 @@ bool TizenImpl::wheelDown(int amount, const int durationMs) efl_util_input_generate_wheel(obj->mFakeWheelHandle, EFL_UTIL_INPUT_POINTER_WHEEL_HORZ, -1); return NULL; }, (void*)(&args)); - usleep(durationMs*1000/amount); + usleep(durationMs*MSEC_PER_SEC/amount); } return true; } +void TizenImpl::startTimer(void) +{ + isTimerStarted = true; + clock_gettime(CLOCK_MONOTONIC, &tStart); +} + +int TizenImpl::stopTimer(void) +{ + struct timespec tEnd; + if (!isTimerStarted) return 0; + isTimerStarted = false; + clock_gettime(CLOCK_MONOTONIC, &tEnd); + return ((tEnd.tv_sec + tEnd.tv_nsec/1000000000.0) - (tStart.tv_sec + tStart.tv_nsec/1000000000.0)) * 1000000; +} bool TizenImpl::drag(const int sx, const int sy, const int ex, const int ey, const int steps, const int durationMs) { - int i, j, stepX, stepY; - int dur, _steps; + int i, j; + int _durationUs, _steps, _stepUs; + int dur; + int consumptionUs; if (steps <= 0) _steps = 1; else _steps = steps; - dur = durationMs / _steps; - dur = dur - 3; + if (durationMs < MINIMUM_DURATION_DRAG) _durationUs = INTV_MINIMUM_DRAG_MS * MSEC_PER_SEC; + else _durationUs = durationMs * MSEC_PER_SEC; - if (dur < 10) dur = 10; - - stepX = (ex - sx)/_steps; - stepY = (ey - sy)/_steps; + _stepUs = _durationUs / (_steps +1); + if (_stepUs < (INTV_MINIMUM_DRAG_MS * MSEC_PER_SEC)) { + _steps = (int)(_durationUs / (INTV_MINIMUM_DRAG_MS * MSEC_PER_SEC)) - 1; + _stepUs = (INTV_MINIMUM_DRAG_MS * MSEC_PER_SEC); + } LOG_SCOPE_F(INFO, "flicking (%d, %d) -> (%d, %d) for (%d ms)", sx, sy, ex, ey, durationMs); - - auto args1 = std::make_tuple(this, sx, sy); - ecore_main_loop_thread_safe_call_sync([](void *data)->void*{ - TizenImpl *obj; - int i, j; - std::tie(obj, i, j) = *static_cast*>(data); - efl_util_input_generate_touch(obj->mFakeTouchHandle, 0, - EFL_UTIL_INPUT_TOUCH_BEGIN, i, j); - LOG_F(INFO, "flick begin (%d, %d)", i, j); - return NULL; - }, (void*)(&args1)); - - i = sx, j = sy; - do { - std::tuple args; - args = std::make_tuple(this, i, j); - ecore_main_loop_thread_safe_call_sync([](void *data)->void*{ - TizenImpl *obj; - int i, j; - std::tie(obj, i, j) = *static_cast*>(data); - LOG_F(INFO, "flick move (%d, %d)", i, j); - - efl_util_input_generate_touch(obj->mFakeTouchHandle, 0, - EFL_UTIL_INPUT_TOUCH_UPDATE, i, j); - return NULL; - }, (void*)(&args)); - - i += stepX; - j += stepY; - usleep(dur * 1000); - } while((sxvoid*{ - TizenImpl *obj; - int i, j; - std::tie(obj, i, j) = *static_cast*>(data); - efl_util_input_generate_touch(obj->mFakeTouchHandle, 0, EFL_UTIL_INPUT_TOUCH_END, - i, j); - LOG_SCOPE_F(INFO, "flick end: (%d, %d)", i, j); - return NULL; - }, (void*)(&args2)); - - ecore_main_loop_thread_safe_call_sync([](void *data)->void*{return NULL;}, NULL); + startTimer(); + touchDown(sx, sy); + consumptionUs = stopTimer(); + + for ( int s = 1; s <= _steps + 1; s++) { + usleep((_stepUs - consumptionUs)>INTV_MINIMUM_USLEEP?(_stepUs - consumptionUs):INTV_MINIMUM_USLEEP); + startTimer(); + touchMove(sx + (ex - sx) * s / (steps + 1), sy + (ey - sy) * s / (steps + 1)); + consumptionUs = stopTimer(); + } + usleep((_stepUs - consumptionUs)>INTV_MINIMUM_USLEEP?(_stepUs - consumptionUs):INTV_MINIMUM_USLEEP); + touchMove(ex, ey); + touchUp(ex, ey); return true; } diff --git a/org.tizen.aurum-bootstrap/inc/Commands/FlickCommand.h b/org.tizen.aurum-bootstrap/inc/Commands/FlickCommand.h index b3b62f9..4f8cb04 100644 --- a/org.tizen.aurum-bootstrap/inc/Commands/FlickCommand.h +++ b/org.tizen.aurum-bootstrap/inc/Commands/FlickCommand.h @@ -12,6 +12,7 @@ class FlickCommand : public Command { private: const ::aurum::ReqFlick* mRequest; ::aurum::RspFlick* mResponse; + const unsigned int MINIMUM_TOUCHEVENT_INTV_MS = 25; public: FlickCommand(const ::aurum::ReqFlick* request, ::aurum::RspFlick* response); diff --git a/org.tizen.aurum-bootstrap/src/Commands/FlickCommand.cc b/org.tizen.aurum-bootstrap/src/Commands/FlickCommand.cc index 6d0da2f..a1b58c6 100644 --- a/org.tizen.aurum-bootstrap/src/Commands/FlickCommand.cc +++ b/org.tizen.aurum-bootstrap/src/Commands/FlickCommand.cc @@ -18,7 +18,7 @@ FlickCommand::FlickCommand(const ::aurum::ReqFlick *request, int durationMs = mRequest->durationms(); UiDevice *device = UiDevice::getInstance(DeviceType::DEFAULT); - device->drag(startPoint.x(), startPoint.y(), endPoint.x(), endPoint.y(), durationMs/15, durationMs); + device->drag(startPoint.x(), startPoint.y(), endPoint.x(), endPoint.y(), durationMs/MINIMUM_TOUCHEVENT_INTV_MS, durationMs); mResponse->set_status(::aurum::RspStatus::OK); return grpc::Status::OK; diff --git a/protocol/examples/python/testFeatures.py b/protocol/examples/python/testFeatures.py index 1439e8e..8927469 100644 --- a/protocol/examples/python/testFeatures.py +++ b/protocol/examples/python/testFeatures.py @@ -170,9 +170,9 @@ def flickTest(stub): for tryCnt in range(10): print('Flick to bottom to find "Spinner" item @ tries:', tryCnt) - stub.flick(ReqFlick(startPoint=Point(x=160, y=350), endPoint=Point(x=160, y=10), durationMs=10)) + stub.flick(ReqFlick(startPoint=Point(x=160, y=359), endPoint=Point(x=160, y=1), durationMs=350)) response = stub.findElement(ReqFindElement(textField='Spinner.*')) - time.sleep(0.5) + time.sleep(0.01) print(response) if len(response.elements) > 0: return True -- 2.7.4