From f330d033e8215ae7d9f4e435207fc7efbdb2a10d Mon Sep 17 00:00:00 2001 From: Radoslaw Cybulski Date: Wed, 13 Dec 2017 19:02:33 +0100 Subject: [PATCH] Added callback to notify, that activity and it's direct side effects are done Added callback functionality to all activities to notify, that activity and all it's direct side effects is done. Used mostly for batch processing. Note, that activity might report it's done before all side effects complete, for example in case of tapping an icon on homescreen application might complete launching long after activity will report being done. Change-Id: I8bec969bfbfe26097605ff030a65ba2c660c6e9a --- src/Activity.hpp | 5 +- src/AppControlActivity.cpp | 2 +- src/CallActivity.cpp | 6 +-- src/ChangeIntTypeVconfKeyActivity.cpp | 6 +-- src/ChangeSoundProfileActivity.cpp | 2 +- src/ChangeSpeedAutoScanActivity.cpp | 8 +-- src/ChangeValueActivity.cpp | 8 +-- src/DoneCallback.cpp | 54 +++++++++++++++++++ src/DoneCallback.hpp | 89 +++++++++++++++++++++++++++++++ src/DragActivity.cpp | 5 +- src/EditTextActivity.cpp | 10 ++-- src/GestureActivity.cpp | 12 +++-- src/HardwareKeyActivity.cpp | 6 +-- src/MoveElementActivity.cpp | 8 +-- src/PowerKeyMenuActivity.cpp | 5 +- src/QuickpanelActivity.cpp | 12 +++-- src/RotateActivity.cpp | 5 +- src/RowScanner.cpp | 6 ++- src/ScreenshotActivity.cpp | 14 ++--- src/ScrollActivities.cpp | 10 ++-- src/SelectActivity.cpp | 10 ++-- src/SwitchManager.cpp | 2 +- src/TapActivity.cpp | 4 +- src/ToggleAutoScanActivity.cpp | 4 +- src/ToggleBoolVconfKeyActivity.cpp | 4 +- src/UIElement.cpp | 47 +++++++++------- src/UIElement.hpp | 8 +-- src/UniversalSwitch.hpp | 6 ++- src/VolumeControlActivity.cpp | 2 +- src/utils.cpp | 19 +++---- src/utils.hpp | 9 ++-- tests/ui-scenarios/ConfigurationTests.hpp | 6 +-- 32 files changed, 284 insertions(+), 110 deletions(-) create mode 100644 src/DoneCallback.cpp create mode 100644 src/DoneCallback.hpp diff --git a/src/Activity.hpp b/src/Activity.hpp index 4d4c62d..4bd222e 100644 --- a/src/Activity.hpp +++ b/src/Activity.hpp @@ -19,6 +19,7 @@ #include "ActivityChangeRequest.hpp" #include "Subject.hpp" +#include "DoneCallback.hpp" #include @@ -33,13 +34,11 @@ public: virtual void initialize() {} - virtual void process() = 0; + virtual void process(DoneCallback) = 0; bool isCompleted() const; void markAsCompleted(); - - protected: bool completed; diff --git a/src/AppControlActivity.cpp b/src/AppControlActivity.cpp index 8936d92..cb7d6a0 100644 --- a/src/AppControlActivity.cpp +++ b/src/AppControlActivity.cpp @@ -38,7 +38,7 @@ public: } } - void process() override + void process(DoneCallback) override { launch(); markAsCompleted(); diff --git a/src/CallActivity.cpp b/src/CallActivity.cpp index c58a7d4..f2146ac 100644 --- a/src/CallActivity.cpp +++ b/src/CallActivity.cpp @@ -34,7 +34,7 @@ public: : Activity(activityType) {} - void process() override + void process(DoneCallback) override { DBus::DBusClient dbus{dbusLocators::callmgr::BUS, dbusLocators::callmgr::OBJ_PATH, dbusLocators::callmgr::INTERFACE, DBus::ConnectionType::SYSTEM}; dbus.method("AnswerCall").call(CM_TEL_CALL_ANSWER_TYPE_NORMAL); @@ -51,7 +51,7 @@ public: : Activity(activityType) {} - void process() override + void process(DoneCallback) override { DBus::DBusClient dbus{dbusLocators::callmgr::BUS, dbusLocators::callmgr::OBJ_PATH, dbusLocators::callmgr::INTERFACE, DBus::ConnectionType::SYSTEM}; dbus.method("RejectCall").call(); @@ -68,7 +68,7 @@ public: : Activity(activityType) {} - void process() override + void process(DoneCallback) override { DBus::DBusClient dbus{dbusLocators::callmgr::BUS, dbusLocators::callmgr::OBJ_PATH, dbusLocators::callmgr::INTERFACE, DBus::ConnectionType::SYSTEM}; dbus.method("EndCall").call(0, CM_TEL_CALL_RELEASE_TYPE_ALL_CALLS); diff --git a/src/ChangeIntTypeVconfKeyActivity.cpp b/src/ChangeIntTypeVconfKeyActivity.cpp index a1f91d7..d5b0254 100644 --- a/src/ChangeIntTypeVconfKeyActivity.cpp +++ b/src/ChangeIntTypeVconfKeyActivity.cpp @@ -41,7 +41,7 @@ public: constexpr static const char *activityType = DerivedType::activityType; ChangeIntTypeVconfKeysActivity() : Activity(activityType) {} - void process() override + void process(DoneCallback) override { static_assert(GET_SIZE(DerivedType::KEYS) == GET_SIZE(DerivedType::STATES), "Incorrect activity"); @@ -104,7 +104,7 @@ public: constexpr static const char *activityType = DerivedType::activityType; SetIntTypeVconfKeyActivity() : Activity(activityType) {} - void process() override + void process(DoneCallback) override { Singleton::instance().set(DerivedType::KEY, DerivedType::STATE); markAsCompleted(); @@ -141,4 +141,4 @@ public: static constexpr const char *activityType = "PARAGRAPH"; static constexpr const char *KEY = VCONF_KEY_GRANULARITY_UNIT; static constexpr int STATE = PARAGRAPH; -}; \ No newline at end of file +}; diff --git a/src/ChangeSoundProfileActivity.cpp b/src/ChangeSoundProfileActivity.cpp index 87d18e4..7daf27d 100644 --- a/src/ChangeSoundProfileActivity.cpp +++ b/src/ChangeSoundProfileActivity.cpp @@ -27,7 +27,7 @@ public: : Activity(activityType) {} - void process() override + void process(DoneCallback) override { auto sound = Singleton::instance().get(VCONF_KEY_SOUND_ENABLED, true) ? 1 : 0; auto vibration = Singleton::instance().get(VCONF_KEY_VIBRATION_ENABLED, false) ? 1 : 0; diff --git a/src/ChangeSpeedAutoScanActivity.cpp b/src/ChangeSpeedAutoScanActivity.cpp index 86e3d09..07a82f8 100644 --- a/src/ChangeSpeedAutoScanActivity.cpp +++ b/src/ChangeSpeedAutoScanActivity.cpp @@ -40,9 +40,9 @@ public: : Activity(activityType) {} - void process() override + void process(DoneCallback doneCb) override { - changeKeyValue([](double currentValue) { + changeKeyValue([doneCb = std::move(doneCb)](double currentValue) { auto newValue = currentValue - VCONF_KEY_AUTO_SCAN_INTERVAL_VALUE_INCREMENT; return newValue < VCONF_KEY_AUTO_SCAN_INTERVAL_VALUE_MIN ? VCONF_KEY_AUTO_SCAN_INTERVAL_VALUE_MIN : newValue; }); @@ -58,9 +58,9 @@ public: : Activity(activityType) {} - void process() override + void process(DoneCallback doneCb) override { - changeKeyValue([](double currentValue) { + changeKeyValue([doneCb = std::move(doneCb)](double currentValue) { auto newValue = currentValue + VCONF_KEY_AUTO_SCAN_INTERVAL_VALUE_INCREMENT; return newValue > VCONF_KEY_AUTO_SCAN_INTERVAL_VALUE_MAX ? VCONF_KEY_AUTO_SCAN_INTERVAL_VALUE_MAX : newValue; }); diff --git a/src/ChangeValueActivity.cpp b/src/ChangeValueActivity.cpp index 710a473..21f4189 100644 --- a/src/ChangeValueActivity.cpp +++ b/src/ChangeValueActivity.cpp @@ -28,10 +28,10 @@ public: : UIActivity(activityType) {} - void process() override + void process(DoneCallback doneCb) override { ASSERT(uiElement, "process invoked before uiElement initialization"); - uiElement->increment(); + uiElement->increment(std::move(doneCb)); markAsCompleted(); } }; @@ -44,10 +44,10 @@ public: : UIActivity(activityType) {} - void process() override + void process(DoneCallback doneCb) override { ASSERT(uiElement, "process invoked before uiElement initialization"); - uiElement->decrement(); + uiElement->decrement(std::move(doneCb)); markAsCompleted(); } }; diff --git a/src/DoneCallback.cpp b/src/DoneCallback.cpp new file mode 100644 index 0000000..77caab7 --- /dev/null +++ b/src/DoneCallback.cpp @@ -0,0 +1,54 @@ +#include "DoneCallback.hpp" +#include "ecore.hpp" + +class DoneCallback::Data : public std::enable_shared_from_this +{ +public: + Data(std::function doneCb) : doneCb(std::move(doneCb)) { } + + ~Data() + { + callAndReset(); + } + + void callAndReset() + { + if (doneCb) { + doneCb(); + doneCb = {}; + } + } + void callAfterTimeElapsed(std::chrono::milliseconds ms) + { + if (doneCb && !timer.isSet()) { + timer.reset(ms.count() / 1000.0, [self = shared_from_this()]() { + self->callAndReset(); + return ecore::TimerRepetitionPolicy::cancel; + }); + } + } +private: + std::function doneCb; + ecore::Timer timer; +}; + +DoneCallback::DoneCallback(std::function doneCb) +{ + if (doneCb) { + dataPtr = std::make_shared(std::move(doneCb)); + } +} + +void DoneCallback::callAfterTimeElapsed(std::chrono::milliseconds ms) const +{ + if (dataPtr) + dataPtr->callAfterTimeElapsed(ms); +} + +void DoneCallback::callAfterTimeElapsed(std::chrono::high_resolution_clock::time_point tm) const +{ + if (dataPtr) { + auto now = std::chrono::high_resolution_clock::now(); + dataPtr->callAfterTimeElapsed(now < tm ? std::chrono::duration_cast(tm - now) : 0ms); + } +} diff --git a/src/DoneCallback.hpp b/src/DoneCallback.hpp new file mode 100644 index 0000000..3d71cd1 --- /dev/null +++ b/src/DoneCallback.hpp @@ -0,0 +1,89 @@ +#ifndef DONE_CALLBACK_HPP +#define DONE_CALLBACK_HPP + +#include +#include +#include + +using namespace std::literals::chrono_literals; + +/** + * @brief Namespace with activities' delays + * + * Delays for activities, so any side effects will be completed before done callback is called + */ +namespace sideEffectDelays +{ + /** + * @brief delay for completion of TAP activity (either select in selection interface or activate action) + */ + static constexpr auto activate = 100ms; + /** + * @brief delay for completion of set current value atspi call + */ + static constexpr auto changeValue = 10ms; + /** + * @brief delay for completion of drag gestxure + */ + static constexpr auto eModDrag = 100ms; + /** + * @brief delay for completion of gesture executed via e-mod + */ + static constexpr auto eModGesture = 100ms; + /** + * @brief delay for completion of rotation executed via e-mod + */ + static constexpr auto eModRotationGesture = 100ms; + /** + * @brief delay for completion of power-key activity (summon of power off popup) + */ + static constexpr auto powerKey = 100ms; + /** + * @brief delay for completion of open quick panel activity (summon of quick panel) + */ + static constexpr auto openQuickPanel = 100ms; + /** + * @brief delay for completion of toggle quick panel activity + */ + static constexpr auto toggleQuickPanel = 100ms; +} + +/** + * @brief Notification object, which will execute functor once activity's side effects are done + * + * DoneCallback's functor will be executed, once activity's side effects are completed. + * Note, that for many activities this will be only an estimation. + */ +class DoneCallback +{ +public: + /** + * @brief Constructs default, empty object, no callback will be called + */ + DoneCallback() = default; + /** + * @brief Constructs callback with functor, which will be called after side effects are done + */ + DoneCallback(std::function doneCb); + + /** + * @brief Calls callback after given time from now + * + * Schedule completion callback to be called after given time from now. + * Only first call to callAfterTimeElapsed on the same object matters, next ones will be ignored. + */ + void callAfterTimeElapsed(std::chrono::milliseconds) const; + + /** + * @brief Calls callback at given point in time + * + * Schedule completion callback to be called at given point in time + * Only first call to callAfterTimeElapsed on the same object matters, next ones will be ignored. + */ + void callAfterTimeElapsed(std::chrono::high_resolution_clock::time_point) const; +private: + class Data; + std::shared_ptr dataPtr; +}; + +#endif diff --git a/src/DragActivity.cpp b/src/DragActivity.cpp index b0e544d..004dc86 100644 --- a/src/DragActivity.cpp +++ b/src/DragActivity.cpp @@ -24,7 +24,7 @@ public: uiElements.push_back(elem); } - void process() override + void process(DoneCallback doneCb) override { ASSERT(uiElements.size() == DerivedType::REQUIRED_UIELEMENTS); @@ -40,6 +40,7 @@ public: DEBUG("Drag %d, %d, %d, %d, %d, %f", from.x, from.y, to.x, to.y, MIDDLE_STEPS_COUNT, pressTime); dbus.method("DispatchDragEvent"). call(from.x, from.y, to.x, to.y, MIDDLE_STEPS_COUNT, pressTime); + doneCb.callAfterTimeElapsed(sideEffectDelays::eModDrag); } private: std::vector> uiElements; @@ -76,7 +77,7 @@ public: CancelActivity() : Activity(activityType) {} - void process() override + void process(DoneCallback) override { markAsCompleted(); DEBUG("cancelled"); diff --git a/src/EditTextActivity.cpp b/src/EditTextActivity.cpp index aa9ef82..a23c263 100644 --- a/src/EditTextActivity.cpp +++ b/src/EditTextActivity.cpp @@ -57,7 +57,7 @@ class CopyActivity : public EditTextActivity public: constexpr static const char *activityType = "COPY"; - void process() override + void process(DoneCallback) override { getAtspiInterfaces(); @@ -74,7 +74,7 @@ class CutActivity : public EditTextActivity public: constexpr static const char *activityType = "CUT"; - void process() override + void process(DoneCallback) override { getAtspiInterfaces(); @@ -92,7 +92,7 @@ class PasteActivity : public EditTextActivity public: constexpr static const char *activityType = "PASTE"; - void process() override + void process(DoneCallback) override { getAtspiInterfaces(); @@ -109,7 +109,7 @@ class SelectAllActivity : public EditTextActivity public: constexpr static const char *activityType = "SELECT_ALL"; - void process() override + void process(DoneCallback) override { getAtspiInterfaces(); @@ -139,7 +139,7 @@ public: using EditTextActivity::getAtspiInterfaces; using EditTextActivity::markAsCompleted; - void process() override + void process(DoneCallback) override { getAtspiInterfaces(); move(DerivedType::DIRECTION, getGranularity(), getMode()); diff --git a/src/GestureActivity.cpp b/src/GestureActivity.cpp index 92d9c9a..e29023d 100644 --- a/src/GestureActivity.cpp +++ b/src/GestureActivity.cpp @@ -46,13 +46,13 @@ public: : UIActivity(activityType) {} - void process() override + void process(DoneCallback doneCb) override { auto dbus = DBus::DBusClient {dbusLocators::accessibilityEMod::BUS, dbusLocators::accessibilityEMod::OBJ_PATH, dbusLocators::accessibilityEMod::INTERFACE, DBus::ConnectionType::SYSTEM}; - DerivedType::dispatchEvent(dbus, uiElement.get()); + DerivedType::dispatchEvent(dbus, uiElement.get(), std::move(doneCb)); markAsCompleted(); } }; @@ -61,11 +61,12 @@ template class DispatchGestureEventActivity : public GestureActivity { public: - static void dispatchEvent(DBus::DBusClient &dbus, const UIElement *uiElement) + static void dispatchEvent(DBus::DBusClient &dbus, const UIElement *uiElement, DoneCallback doneCb) { auto point = uiElement->getScanningCoordinates(); const auto swipeType = DerivedType::swipeType; dbus.method("DispatchGestureEvent").call(swipeType, point.x, point.y); + doneCb.callAfterTimeElapsed(sideEffectDelays::eModGesture); } }; @@ -115,7 +116,7 @@ template class DispatchCustomGestureEventActivity : public GestureActivity { public: - static void dispatchEvent(DBus::DBusClient &dbus, const UIElement *uiElement) + static void dispatchEvent(DBus::DBusClient &dbus, const UIElement *uiElement, DoneCallback doneCb) { //move: x in range 25% - 75% , and y = 50% of screen dimensions auto screenSize = Singleton::instance().getMainWindow()->getDimensions().size; @@ -136,6 +137,7 @@ public: } DEBUG("Swipe %d, %d, %d, %d, %d", startPoint.x, startPoint.y, endPoint.x, endPoint.y, DEFAULT_STEPS_NUMBER); dbus.method("DispatchDragEvent").call(startPoint.x, startPoint.y, endPoint.x, endPoint.y, DEFAULT_STEPS_NUMBER, DEFAULT_HOLD_TIME); + doneCb.callAfterTimeElapsed(sideEffectDelays::eModDrag); } }; @@ -151,4 +153,4 @@ class CustomSwipeLeftActivity : public DispatchCustomGestureEventActivity::instance().getScreenScannerManager(); - if (s) DerivedType::move(s); + if (s) DerivedType::move(s, std::move(doneCb)); else ERROR("ScreenScannerManager not found"); markAsCompleted(); } @@ -42,7 +42,7 @@ class NextElementActivity : public MoveElementActivity { public: constexpr static const char *activityType = "MOVE_TO_NEXT_ITEM"; - static void move(auto scannerManager) + static void move(auto scannerManager, DoneCallback) { scannerManager->next(); } @@ -52,7 +52,7 @@ class PrevElementActivity : public MoveElementActivity { public: constexpr static const char *activityType = "MOVE_TO_PREV_ITEM"; - static void move(auto scannerManager) + static void move(auto scannerManager, DoneCallback) { scannerManager->prev(); } diff --git a/src/PowerKeyMenuActivity.cpp b/src/PowerKeyMenuActivity.cpp index b41122d..0f7fe31 100644 --- a/src/PowerKeyMenuActivity.cpp +++ b/src/PowerKeyMenuActivity.cpp @@ -30,7 +30,7 @@ public: PowerKeyMenuActivity() : Activity(activityType) {} - void process() override + void process(DoneCallback doneCb) override { auto bundleHandle = std::unique_ptr(bundle_create(), bundle_free); if (!bundleHandle) { @@ -50,10 +50,11 @@ public: ERROR("Failed to launch popup, error: %d", ret); markAsCompleted(); + doneCb.callAfterTimeElapsed(sideEffectDelays::powerKey); } private: static constexpr const char *POPUP_CONTENT = "_SYSPOPUP_CONTENT_"; static constexpr const char *POPUP_NAME_POWERKEY = "powerkey"; static constexpr const char *POPUP_POWERKEY = "powerkey-syspopup"; -}; \ No newline at end of file +}; diff --git a/src/QuickpanelActivity.cpp b/src/QuickpanelActivity.cpp index 4d2d059..e78c3a2 100644 --- a/src/QuickpanelActivity.cpp +++ b/src/QuickpanelActivity.cpp @@ -31,9 +31,9 @@ public: : Activity(activityType) {} - void process() override + void process(DoneCallback doneCb) override { - DerivedType::changeQuickpanelState(); + DerivedType::changeQuickpanelState(std::move(doneCb)); markAsCompleted(); } }; @@ -43,9 +43,10 @@ class OpenQuickpanelActivity : public QuickpanelActivity::instance().getMainWindow()->getQuickpanel()->show(); + doneCb.callAfterTimeElapsed(sideEffectDelays::openQuickPanel); } }; @@ -54,12 +55,13 @@ class ToggleQuickpanelActivity : public QuickpanelActivity::instance().getMainWindow()->getQuickpanel(); if (quickpanel->isVisible()) quickpanel->hide(); else quickpanel->show(); + doneCb.callAfterTimeElapsed(sideEffectDelays::toggleQuickPanel); } -}; \ No newline at end of file +}; diff --git a/src/RotateActivity.cpp b/src/RotateActivity.cpp index 75967cc..c44e4e7 100644 --- a/src/RotateActivity.cpp +++ b/src/RotateActivity.cpp @@ -15,7 +15,7 @@ public: RotateActivity() : Activity(activityType) {} - void process() override + void process(DoneCallback doneCb) override { Singleton::instance().set(VCONF_KEY_AUTO_ROTATE, false); auto dbus = DBus::DBusClient {dbusLocators::accessibilityEMod::BUS, @@ -25,6 +25,7 @@ public: auto rotation = DerivedType::ROTATION; dbus.method("DispatchRotationEvent").call(rotation); markAsCompleted(); + doneCb.callAfterTimeElapsed(sideEffectDelays::eModRotationGesture); } }; @@ -47,4 +48,4 @@ class RotateLeftActivity : public RotateActivity public: static constexpr const char *activityType = "ROTATE_LEFT"; static constexpr int ROTATION = 270; -}; \ No newline at end of file +}; diff --git a/src/RowScanner.cpp b/src/RowScanner.cpp index 19bc285..a0fe17e 100644 --- a/src/RowScanner.cpp +++ b/src/RowScanner.cpp @@ -26,6 +26,7 @@ #include "Window.hpp" #include "utils.hpp" #include "Atspi.hpp" +#include "DoneCallback.hpp" #include @@ -191,7 +192,10 @@ void RowScannerImpl::acceptAutoscanningPhase(std::function::instance().getMainWindow(); if (mainWindow) - capture(filename, mainWindow->getDimensions().size); + capture(filename, mainWindow->getDimensions().size, std::move(doneCb)); else ERROR("No main window"); @@ -80,7 +80,7 @@ void ScreenshotActivity::process() } -void ScreenshotActivity::capture(const std::string &filename, Size size) +void ScreenshotActivity::capture(const std::string &filename, Size size, DoneCallback doneCb) { auto screenshotHandle = std::unique_ptr<_efl_util_screenshot_h, int (*)(_efl_util_screenshot_h *)> { efl_util_screenshot_initialize(size.width, size.height), efl_util_screenshot_deinitialize @@ -141,4 +141,4 @@ std::string ScreenshotActivity::generateFileName() std::stringstream ss; ss << std::put_time(std::localtime(&formated), "%Y%m%d-%H%M%S") << ".png"; return ss.str(); -} \ No newline at end of file +} diff --git a/src/ScrollActivities.cpp b/src/ScrollActivities.cpp index dde4c66..c3bf96c 100644 --- a/src/ScrollActivities.cpp +++ b/src/ScrollActivities.cpp @@ -163,7 +163,7 @@ public: constexpr static const char *activityType = "SCROLL_SPEED_UP"; ScrollSpeedUpActivity() : UIActivity(activityType) {} - void process() override + void process(DoneCallback) override { auto sd = Singleton::instance().getScrollActivitiesData(); if (sd) @@ -180,7 +180,7 @@ public: constexpr static const char *activityType = "SCROLL_SLOW_DOWN"; ScrollSlowDownActivity() : UIActivity(activityType) {} - void process() override + void process(DoneCallback) override { auto sd = Singleton::instance().getScrollActivitiesData(); if (sd) @@ -197,7 +197,7 @@ public: constexpr static const char *activityType = "SCROLL_PAGE_UP"; ScrollPageUpActivity() : UIActivity(activityType) {} - void process() override + void process(DoneCallback) override { auto sd = Singleton::instance().getScrollActivitiesData(); if (sd) @@ -214,7 +214,7 @@ public: constexpr static const char *activityType = "SCROLL_PAGE_DOWN"; ScrollPageDownActivity() : UIActivity(activityType) {} - void process() override + void process(DoneCallback) override { auto sd = Singleton::instance().getScrollActivitiesData(); if (sd) @@ -231,7 +231,7 @@ public: constexpr static const char *activityType = "SCROLL_TO_TOP"; ScrollToTopActivity() : UIActivity(activityType) {} - void process() override + void process(DoneCallback) override { auto sd = Singleton::instance().getScrollActivitiesData(); if (sd) diff --git a/src/SelectActivity.cpp b/src/SelectActivity.cpp index 7a9a4d3..552256a 100644 --- a/src/SelectActivity.cpp +++ b/src/SelectActivity.cpp @@ -53,7 +53,7 @@ public: ~SelectActivity(); SelectActivity(SelectActivity &&) = delete; - void process() override; + void process(DoneCallback) override; void update(const std::shared_ptr &elem) override; void update(const std::shared_ptr &menuitem) override; @@ -103,6 +103,7 @@ private: VConfInterface::CallbackHandle autoTapWaitingPeriodCallbackHandle; ecore::Timer timer; double autoTapWaitingPeriod; + DoneCallback activityDoneCallback; }; SelectActivity::SelectActivity(): UIActivity(activityType), popup(nullptr, evas_object_del), @@ -121,6 +122,7 @@ void SelectActivity::markAsCompleted() auto screenScannerManager = Singleton::instance().getScreenScannerManager(); if (screenScannerManager) screenScannerManager->cancelForcingScanningMethod(); + activityDoneCallback = {}; } void SelectActivity::deleteScrollActivitiesData() @@ -131,7 +133,7 @@ void SelectActivity::deleteScrollActivitiesData() scrollActivitiesData = {}; } -void SelectActivity::process() +void SelectActivity::process(DoneCallback callback) { DEBUG("Select - process called"); @@ -145,6 +147,8 @@ void SelectActivity::process() if (screenScannerManager) screenScannerManager->acceptAutoscanning(); + + activityDoneCallback = std::move(callback); } void SelectActivity::update(const std::shared_ptr &elem) @@ -155,7 +159,7 @@ void SelectActivity::update(const std::shared_ptr &elem) screenScannerManager->cancelForcingScanningMethod(); if (isMenuShown()) { ASSERT(!realUiElements.empty()); - elem->activate(); /*elem is popup menu item*/ + elem->activate({}); /*elem is popup menu item*/ return; } diff --git a/src/SwitchManager.cpp b/src/SwitchManager.cpp index 9bfc921..cb1bfa9 100644 --- a/src/SwitchManager.cpp +++ b/src/SwitchManager.cpp @@ -236,6 +236,6 @@ void SwitchManager::changeActivity(const std::shared_ptr return; } - activities.top()->process(); + activities.top()->process({}); //TODO: check if activity change request observers are properly detached from activity object removed from activity stack } diff --git a/src/TapActivity.cpp b/src/TapActivity.cpp index 7adcb20..37274c7 100644 --- a/src/TapActivity.cpp +++ b/src/TapActivity.cpp @@ -28,7 +28,7 @@ public: : UIActivity(activityType) {} - void process() override + void process(DoneCallback doneCb) override { if (!uiElement) { ERROR("process invoked before uiElement initialization"); @@ -36,7 +36,7 @@ public: return; } - uiElement->activate(); + uiElement->activate(std::move(doneCb)); markAsCompleted(); } diff --git a/src/ToggleAutoScanActivity.cpp b/src/ToggleAutoScanActivity.cpp index c379350..cfd93aa 100644 --- a/src/ToggleAutoScanActivity.cpp +++ b/src/ToggleAutoScanActivity.cpp @@ -27,7 +27,7 @@ public: : Activity(activityType) {} - void process() override + void process(DoneCallback) override { Singleton::instance().set(VCONF_KEY_AUTO_SCAN_ENABLED, true); markAsCompleted(); @@ -42,7 +42,7 @@ public: : Activity(activityType) {} - void process() override + void process(DoneCallback) override { Singleton::instance().set(VCONF_KEY_AUTO_SCAN_ENABLED, false); markAsCompleted(); diff --git a/src/ToggleBoolVconfKeyActivity.cpp b/src/ToggleBoolVconfKeyActivity.cpp index da113c9..e97c4d1 100644 --- a/src/ToggleBoolVconfKeyActivity.cpp +++ b/src/ToggleBoolVconfKeyActivity.cpp @@ -39,7 +39,7 @@ public: { return Singleton::instance().get(DerivedType::KEY, false); } - void process() override + void process(DoneCallback) override { toggleVconfKey(); markAsCompleted(); @@ -68,7 +68,7 @@ public: static constexpr const char *activityType = "TOGGLE_AUTO_SCROLL_ENABLED_ACTIVITY"; static constexpr const char *KEY = VCONF_KEY_AUTO_SCROLL_ENABLED; - void process() override + void process(DoneCallback) override { bool isEnabled = toggleVconfKey(); toggleAutoScroll(isEnabled); diff --git a/src/UIElement.cpp b/src/UIElement.cpp index 6ed8491..76b5ed6 100644 --- a/src/UIElement.cpp +++ b/src/UIElement.cpp @@ -17,6 +17,7 @@ #include "UIElement.hpp" #include "UniversalSwitch.hpp" #include "UniversalSwitchLog.hpp" +#include "DoneCallback.hpp" #include #include @@ -99,71 +100,73 @@ Point UIElement::getScanningCoordinates() const namespace { - void doSelect(std::shared_ptr atspi, const std::shared_ptr &obj) + void doSelect(std::shared_ptr atspi, const std::shared_ptr &obj, DoneCallback doneCb) { atspi->getParent(obj, - [ = ](DBus::ValueOrError> parent) { + [ =, doneCb = std::move(doneCb)](DBus::ValueOrError> parent) { if (!parent) { DEBUG("no parent"); return; } atspi->getIndexInParent(obj, - [ = ](DBus::ValueOrError index) { + [ =, doneCb = std::move(doneCb)](DBus::ValueOrError index) { if (!index) { DEBUG("cant get index in parent"); return; } atspi->getSelectionInterface(std::get<0>(parent), - [ = ](DBus::ValueOrError> sel) { + [ =, doneCb = std::move(doneCb)](DBus::ValueOrError> sel) { if (!sel) { DEBUG("no selection interface"); return; } atspi->selectChild(std::get<0>(sel), std::get<0>(index), - [](DBus::ValueOrError isSuccessful) { + [doneCb = std::move(doneCb)](DBus::ValueOrError isSuccessful) { if (!isSuccessful) { DEBUG("failed to select"); return; } DEBUG("selected"); + doneCb.callAfterTimeElapsed(sideEffectDelays::activate); }); }); }); }); } - void doActivate(std::shared_ptr atspi, const std::shared_ptr obj) + void doActivate(std::shared_ptr atspi, const std::shared_ptr obj, DoneCallback doneCb) { atspi->getActionInterface(obj, - [atspi, obj](DBus::ValueOrError> action) { + [atspi, obj, doneCb = std::move(doneCb)](DBus::ValueOrError> action) { if (!action) { - doSelect(atspi, obj); + doSelect(atspi, obj, std::move(doneCb)); return; } atspi->doActionName(std::get<0>(action), "activate", - [atspi, obj](DBus::ValueOrError status) { + [atspi, obj, doneCb = std::move(doneCb)](DBus::ValueOrError status) { if (!status || !std::get<0>(status)) { - doSelect(atspi, obj); + doSelect(atspi, obj, std::move(doneCb)); return; } DEBUG("activated"); + doneCb.callAfterTimeElapsed(sideEffectDelays::activate); }); }); } } -void UIElement::activate() +void UIElement::activate(DoneCallback doneCb) { if (!obj) { DEBUG("obj is nullptr"); return; } DEBUG("invoking object %s", atspi->getUniqueId(obj).c_str()); - doActivate(atspi, obj); + doActivate(atspi, obj, std::move(doneCb)); } namespace @@ -172,9 +175,10 @@ namespace INCREMENT, DECREMENT }; - void changeValue(const std::shared_ptr &atspi, std::shared_ptr obj, ChangeDirection change) + void changeValue(const std::shared_ptr &atspi, std::shared_ptr obj, + ChangeDirection change, DoneCallback doneCb) { - auto setCurrentValue = [atspi, change](auto valueInterface, auto currentValue, auto maximumValue, auto minimumValue) { + auto setCurrentValue = [atspi, change, doneCb = std::move(doneCb)](auto valueInterface, auto currentValue, auto maximumValue, auto minimumValue) { auto stepSize = (maximumValue - minimumValue) / NUMBER_OF_STEPS; auto newValue = 0.0; switch (change) { @@ -187,9 +191,12 @@ namespace } atspi->setCurrentValue(valueInterface, newValue, - [](DBus::ValueOrError isSuccessful) { - if (!isSuccessful) + [doneCb = std::move(doneCb)](DBus::ValueOrError isSuccessful) { + if (!isSuccessful) { DEBUG("Value change failed"); + } else { + doneCb.callAfterTimeElapsed(sideEffectDelays::changeValue); + } }); }; @@ -230,14 +237,14 @@ namespace } } -void UIElement::increment() +void UIElement::increment(DoneCallback doneCb) { - changeValue(atspi, obj, ChangeDirection::INCREMENT); + changeValue(atspi, obj, ChangeDirection::INCREMENT, std::move(doneCb)); } -void UIElement::decrement() +void UIElement::decrement(DoneCallback doneCb) { - changeValue(atspi, obj, ChangeDirection::DECREMENT); + changeValue(atspi, obj, ChangeDirection::DECREMENT, std::move(doneCb)); } void UIElement::printDebug() diff --git a/src/UIElement.hpp b/src/UIElement.hpp index 7cf0183..148ed81 100644 --- a/src/UIElement.hpp +++ b/src/UIElement.hpp @@ -25,6 +25,8 @@ #include #include +class DoneCallback; + class UIElement : public std::enable_shared_from_this { public: @@ -42,9 +44,9 @@ public: Point getScanningCoordinates() const; ApplicationCategory getApplicationCategory() const; - void activate(); - void increment(); - void decrement(); + void activate(DoneCallback); + void increment(DoneCallback); + void decrement(DoneCallback); void printDebug(); diff --git a/src/UniversalSwitch.hpp b/src/UniversalSwitch.hpp index 5d10d2a..6b44a50 100644 --- a/src/UniversalSwitch.hpp +++ b/src/UniversalSwitch.hpp @@ -24,7 +24,6 @@ #include - class Atspi; class CompositeSwitchProvider; class Configuration; @@ -55,6 +54,10 @@ public: std::shared_ptr getScrollActivitiesData() const; void setScrollActivitiesData(std::shared_ptr); + std::string getTestFilePath() const; + void setTestFilePath(const std::string &path); + void setTestOutputPath(const std::string &path); + void initialize(); void terminate(); @@ -84,6 +87,7 @@ private: VConfInterface::CallbackHandle callbackHandle; bool isScanningOn = false; bool isDisplayOn = false; + std::string testFilePath, testOutputPath; }; #endif diff --git a/src/VolumeControlActivity.cpp b/src/VolumeControlActivity.cpp index 3c5e8a1..ddbe123 100644 --- a/src/VolumeControlActivity.cpp +++ b/src/VolumeControlActivity.cpp @@ -30,7 +30,7 @@ public: : Activity(activityType) {} - void process() override + void process(DoneCallback) override { setVolume(); markAsCompleted(); diff --git a/src/utils.cpp b/src/utils.cpp index 1a431aa..7a63608 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -17,6 +17,7 @@ #include "utils.hpp" #include "UniversalSwitchLog.hpp" +#include "DoneCallback.hpp" #include @@ -63,7 +64,7 @@ namespace utils ecore::Timer EventGenerator::timer = {}; - void EventGenerator::generateKeyPress(const std::string &keyId, unsigned multiplicity, PressType type) + void EventGenerator::generateKeyPress(const std::string &keyId, DoneCallback doneCb, unsigned multiplicity, PressType type) { DEBUG("key: %s, multiplicity: %d", keyId.c_str(), multiplicity); @@ -83,26 +84,26 @@ namespace utils GeneratorData genData{keyId, multiplicity, delay}; - timer.reset(NO_DELAY, [genData]() { - return createKeyDownEvent(genData); + timer.reset(NO_DELAY, [genData, doneCb = std::move(doneCb)]() { + return createKeyDownEvent(genData, std::move(doneCb)); }); } - ecore::TimerRepetitionPolicy EventGenerator::createKeyDownEvent(GeneratorData genData) + ecore::TimerRepetitionPolicy EventGenerator::createKeyDownEvent(GeneratorData genData, DoneCallback doneCb) { DEBUG("invoked"); EflKeyInputGenerator inputgen; inputgen.generateKeyDown(genData.key); - timer.reset(genData.releaseDelay, [genData]() { - return createKeyUpEvent(genData); + timer.reset(genData.releaseDelay, [genData, doneCb = std::move(doneCb)]() { + return createKeyUpEvent(genData, std::move(doneCb)); }); return ecore::TimerRepetitionPolicy::cancel; } - ecore::TimerRepetitionPolicy EventGenerator::createKeyUpEvent(GeneratorData genData) + ecore::TimerRepetitionPolicy EventGenerator::createKeyUpEvent(GeneratorData genData, DoneCallback doneCb) { DEBUG("invoked"); @@ -111,8 +112,8 @@ namespace utils --(genData.multiplicity); if (genData.multiplicity > 0) - timer.reset(SHORT_DELAY, [genData]() { - return createKeyDownEvent(genData); + timer.reset(SHORT_DELAY, [genData, doneCb = std::move(doneCb)]() { + return createKeyDownEvent(genData, std::move(doneCb)); }); return ecore::TimerRepetitionPolicy::cancel; diff --git a/src/utils.hpp b/src/utils.hpp index ef12ce6..2b5f268 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -21,6 +21,8 @@ #include +class DoneCallback; + #define PRINT_ERROR_IF(condition) \ do { \ if (condition) \ @@ -70,11 +72,12 @@ namespace utils double releaseDelay; }; - static void generateKeyPress(const std::string &keyId, unsigned multiplicity = SINGLE_PRESS, PressType type = PressType::SHORT); + static void generateKeyPress(const std::string &keyId, DoneCallback doneCb, unsigned multiplicity = SINGLE_PRESS, + PressType type = PressType::SHORT); private: - static ecore::TimerRepetitionPolicy createKeyDownEvent(GeneratorData genData); - static ecore::TimerRepetitionPolicy createKeyUpEvent(GeneratorData genData); + static ecore::TimerRepetitionPolicy createKeyDownEvent(GeneratorData genData, DoneCallback doneCb); + static ecore::TimerRepetitionPolicy createKeyUpEvent(GeneratorData genData, DoneCallback doneCb); static ecore::Timer timer; diff --git a/tests/ui-scenarios/ConfigurationTests.hpp b/tests/ui-scenarios/ConfigurationTests.hpp index 103c3e7..3c11d9f 100644 --- a/tests/ui-scenarios/ConfigurationTests.hpp +++ b/tests/ui-scenarios/ConfigurationTests.hpp @@ -40,7 +40,7 @@ public: static constexpr const char *activityType = "TWO_STEP_PROCESS_ACTIVITY"; TwoStepProcessActivity(): Activity(activityType) {} - void process() override + void process(DoneCallback) override { if (++state > 1) markAsCompleted(); @@ -54,7 +54,7 @@ public: static constexpr const char *activityType = "THREE_STEP_PROCESS_ACTIVITY"; ThreeStepProcessActivity(): Activity(activityType) {} - void process() override + void process(DoneCallback) override { if (++state > 2) markAsCompleted(); @@ -85,7 +85,7 @@ public: void simulateKeyPress(const std::string &key) { eventTimer.reset(SMALL_DELAY_, [&key]() { - utils::EventGenerator::generateKeyPress(key); + utils::EventGenerator::generateKeyPress(key, {}); return ecore::TimerRepetitionPolicy::cancel; }); mainloopTimer.reset(ESTIMATED_TIME_REQUIRED_TO_SAFELY_PASSING_THROUGH_TESTS_, []() { -- 2.7.4