Added callback to notify, that activity and it's direct side effects are done 66/163866/8
authorRadoslaw Cybulski <r.cybulski@partner.samsung.com>
Wed, 13 Dec 2017 18:02:33 +0000 (19:02 +0100)
committerRadoslaw Cybulski <r.cybulski@partner.samsung.com>
Wed, 10 Jan 2018 11:26:49 +0000 (12:26 +0100)
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

32 files changed:
src/Activity.hpp
src/AppControlActivity.cpp
src/CallActivity.cpp
src/ChangeIntTypeVconfKeyActivity.cpp
src/ChangeSoundProfileActivity.cpp
src/ChangeSpeedAutoScanActivity.cpp
src/ChangeValueActivity.cpp
src/DoneCallback.cpp [new file with mode: 0644]
src/DoneCallback.hpp [new file with mode: 0644]
src/DragActivity.cpp
src/EditTextActivity.cpp
src/GestureActivity.cpp
src/HardwareKeyActivity.cpp
src/MoveElementActivity.cpp
src/PowerKeyMenuActivity.cpp
src/QuickpanelActivity.cpp
src/RotateActivity.cpp
src/RowScanner.cpp
src/ScreenshotActivity.cpp
src/ScrollActivities.cpp
src/SelectActivity.cpp
src/SwitchManager.cpp
src/TapActivity.cpp
src/ToggleAutoScanActivity.cpp
src/ToggleBoolVconfKeyActivity.cpp
src/UIElement.cpp
src/UIElement.hpp
src/UniversalSwitch.hpp
src/VolumeControlActivity.cpp
src/utils.cpp
src/utils.hpp
tests/ui-scenarios/ConfigurationTests.hpp

index 4d4c62d..4bd222e 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "ActivityChangeRequest.hpp"
 #include "Subject.hpp"
+#include "DoneCallback.hpp"
 
 #include <memory>
 
@@ -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;
 
index 8936d92..cb7d6a0 100644 (file)
@@ -38,7 +38,7 @@ public:
                }
        }
 
-       void process() override
+       void process(DoneCallback) override
        {
                launch();
                markAsCompleted();
index c58a7d4..f2146ac 100644 (file)
@@ -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<int(int)>("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<int()>("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<int(unsigned, int)>("EndCall").call(0, CM_TEL_CALL_RELEASE_TYPE_ALL_CALLS);
index a1f91d7..d5b0254 100644 (file)
@@ -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<VConfInterface>::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
+};
index 87d18e4..7daf27d 100644 (file)
@@ -27,7 +27,7 @@ public:
                : Activity(activityType)
        {}
 
-       void process() override
+       void process(DoneCallback) override
        {
                auto sound = Singleton<VConfInterface>::instance().get(VCONF_KEY_SOUND_ENABLED, true) ? 1 : 0;
                auto vibration = Singleton<VConfInterface>::instance().get(VCONF_KEY_VIBRATION_ENABLED, false) ? 1 : 0;
index 86e3d09..07a82f8 100644 (file)
@@ -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;
                });
index 710a473..21f4189 100644 (file)
@@ -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 (file)
index 0000000..77caab7
--- /dev/null
@@ -0,0 +1,54 @@
+#include "DoneCallback.hpp"
+#include "ecore.hpp"
+
+class DoneCallback::Data : public std::enable_shared_from_this<DoneCallback::Data>
+{
+public:
+       Data(std::function<void()> 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<void()> doneCb;
+       ecore::Timer timer;
+};
+
+DoneCallback::DoneCallback(std::function<void()> doneCb)
+{
+       if (doneCb) {
+               dataPtr = std::make_shared<DoneCallback::Data>(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<std::chrono::milliseconds>(tm - now) : 0ms);
+       }
+}
diff --git a/src/DoneCallback.hpp b/src/DoneCallback.hpp
new file mode 100644 (file)
index 0000000..3d71cd1
--- /dev/null
@@ -0,0 +1,89 @@
+#ifndef DONE_CALLBACK_HPP
+#define DONE_CALLBACK_HPP
+
+#include <chrono>
+#include <memory>
+#include <functional>
+
+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<void()> 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<Data> dataPtr;
+};
+
+#endif
index b0e544d..004dc86 100644 (file)
@@ -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<void(int, int, int, int, int, double)>("DispatchDragEvent").
                call(from.x, from.y, to.x, to.y, MIDDLE_STEPS_COUNT, pressTime);
+               doneCb.callAfterTimeElapsed(sideEffectDelays::eModDrag);
        }
 private:
        std::vector<std::shared_ptr<UIElement>> uiElements;
@@ -76,7 +77,7 @@ public:
        CancelActivity() : Activity(activityType)
        {}
 
-       void process() override
+       void process(DoneCallback) override
        {
                markAsCompleted();
                DEBUG("cancelled");
index aa9ef82..a23c263 100644 (file)
@@ -57,7 +57,7 @@ class CopyActivity : public EditTextActivity<CopyActivity>
 public:
        constexpr static const char *activityType = "COPY";
 
-       void process() override
+       void process(DoneCallback) override
        {
                getAtspiInterfaces();
 
@@ -74,7 +74,7 @@ class CutActivity : public EditTextActivity<CutActivity>
 public:
        constexpr static const char *activityType = "CUT";
 
-       void process() override
+       void process(DoneCallback) override
        {
                getAtspiInterfaces();
 
@@ -92,7 +92,7 @@ class PasteActivity : public EditTextActivity<PasteActivity>
 public:
        constexpr static const char *activityType = "PASTE";
 
-       void process() override
+       void process(DoneCallback) override
        {
                getAtspiInterfaces();
 
@@ -109,7 +109,7 @@ class SelectAllActivity : public EditTextActivity<SelectAllActivity>
 public:
        constexpr static const char *activityType = "SELECT_ALL";
 
-       void process() override
+       void process(DoneCallback) override
        {
                getAtspiInterfaces();
 
@@ -139,7 +139,7 @@ public:
        using EditTextActivity<DerivedType>::getAtspiInterfaces;
        using EditTextActivity<DerivedType>::markAsCompleted;
 
-       void process() override
+       void process(DoneCallback) override
        {
                getAtspiInterfaces();
                move(DerivedType::DIRECTION, getGranularity(), getMode());
index 92d9c9a..e29023d 100644 (file)
@@ -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 <typename DerivedType>
 class DispatchGestureEventActivity : public GestureActivity<DerivedType>
 {
 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<void(int, int, int)>("DispatchGestureEvent").call(swipeType, point.x, point.y);
+               doneCb.callAfterTimeElapsed(sideEffectDelays::eModGesture);
        }
 };
 
@@ -115,7 +116,7 @@ template <typename DerivedType>
 class DispatchCustomGestureEventActivity : public GestureActivity<DerivedType>
 {
 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<UniversalSwitch>::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<void(int, int, int, int, int, double)>("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<Custom
 public:
        static constexpr const char *activityType = "RIGHT_PAGE";
        static constexpr SwipeType swipeType = SWIPE_LEFT;
-};
\ No newline at end of file
+};
index 8f27ac8..0617845 100644 (file)
@@ -28,9 +28,9 @@ public:
                : Activity(activityType)
        {}
 
-       void process() override
+       void process(DoneCallback doneCb) override
        {
-               utils::EventGenerator::generateKeyPress(DerivedType::buttonCode, DerivedType::multiplicity);
+               utils::EventGenerator::generateKeyPress(DerivedType::buttonCode, std::move(doneCb), DerivedType::multiplicity);
                markAsCompleted();
        }
 };
@@ -65,4 +65,4 @@ public:
        static constexpr const char *activityType = "HOME_BUTTON_X3";
        static constexpr const char *buttonCode = "XF86Home";
        static constexpr unsigned multiplicity = 3;
-};
\ No newline at end of file
+};
index ee600c7..436ac2e 100644 (file)
@@ -29,10 +29,10 @@ public:
        constexpr static const char *activityType = DerivedType::activityType;
        MoveElementActivity() : Activity(activityType) {}
 
-       void process() override
+       void process(DoneCallback doneCb) override
        {
                auto s = Singleton<UniversalSwitch>::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<NextElementActivity>
 {
 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<PrevElementActivity>
 {
 public:
        constexpr static const char *activityType = "MOVE_TO_PREV_ITEM";
-       static void move(auto scannerManager)
+       static void move(auto scannerManager, DoneCallback)
        {
                scannerManager->prev();
        }
index b41122d..0f7fe31 100644 (file)
@@ -30,7 +30,7 @@ public:
        PowerKeyMenuActivity()
                : Activity(activityType) {}
 
-       void process() override
+       void process(DoneCallback doneCb) override
        {
                auto bundleHandle = std::unique_ptr<bundle, int(*)(bundle *)>(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
+};
index 4d2d059..e78c3a2 100644 (file)
@@ -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<OpenQuickpanelActivity,
 public:
        static constexpr const char *activityType = "OPEN_QUICKPANEL";
 
-       static void changeQuickpanelState()
+       static void changeQuickpanelState(DoneCallback doneCb)
        {
                Singleton<UniversalSwitch>::instance().getMainWindow()->getQuickpanel()->show();
+               doneCb.callAfterTimeElapsed(sideEffectDelays::openQuickPanel);
        }
 };
 
@@ -54,12 +55,13 @@ class ToggleQuickpanelActivity : public QuickpanelActivity<ToggleQuickpanelActiv
 public:
        static constexpr const char *activityType = "TOGGLE_QUICKPANEL";
 
-       static void changeQuickpanelState()
+       static void changeQuickpanelState(DoneCallback doneCb)
        {
                auto quickpanel = Singleton<UniversalSwitch>::instance().getMainWindow()->getQuickpanel();
                if (quickpanel->isVisible())
                        quickpanel->hide();
                else
                        quickpanel->show();
+               doneCb.callAfterTimeElapsed(sideEffectDelays::toggleQuickPanel);
        }
-};
\ No newline at end of file
+};
index 75967cc..c44e4e7 100644 (file)
@@ -15,7 +15,7 @@ public:
        RotateActivity() : Activity(activityType)
        {}
 
-       void process() override
+       void process(DoneCallback doneCb) override
        {
                Singleton<VConfInterface>::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<void(int)>("DispatchRotationEvent").call(rotation);
                markAsCompleted();
+               doneCb.callAfterTimeElapsed(sideEffectDelays::eModRotationGesture);
        }
 };
 
@@ -47,4 +48,4 @@ class RotateLeftActivity : public RotateActivity<RotateLeftActivity>
 public:
        static constexpr const char *activityType = "ROTATE_LEFT";
        static constexpr int ROTATION = 270;
-};
\ No newline at end of file
+};
index 19bc285..a0fe17e 100644 (file)
@@ -26,6 +26,7 @@
 #include "Window.hpp"
 #include "utils.hpp"
 #include "Atspi.hpp"
+#include "DoneCallback.hpp"
 
 #include <Elementary.h>
 
@@ -191,7 +192,10 @@ void RowScannerImpl::acceptAutoscanningPhase(std::function<void(Optional<std::sh
                if (!currentNavState.childIndex) {
                        if (currentNavState.parent == rootNavigationElement) {
                                if (properties.isEscapeFrameEnabled()) {
-                                       utils::EventGenerator::generateKeyPress(BACK_BUTTON_CODE);
+                                       utils::EventGenerator::generateKeyPress(BACK_BUTTON_CODE,
+                                       DoneCallback{[callback = std::move(callback)] {
+                                                       callback({});
+                                               } });
                                        eraseFrame();
                                        state = State::END;
                                } else {
index 36a83a4..e570f3a 100644 (file)
@@ -39,12 +39,12 @@ class ScreenshotActivity : public UIActivity, private RegisterActivity<Screensho
 {
 public:
        ScreenshotActivity();
-       void process() override;
+       void process(DoneCallback doneCb) override;
 
        constexpr static const char *activityType = "SCREENSHOT";
 
 private:
-       static void capture(const std::string &, Size);
+       static void capture(const std::string &, Size, DoneCallback);
        static std::string generateFileName();
 
        ecore::Timer timer;
@@ -53,7 +53,7 @@ private:
 
 ScreenshotActivity::ScreenshotActivity() : UIActivity(activityType) {}
 
-void ScreenshotActivity::process()
+void ScreenshotActivity::process(DoneCallback doneCb)
 {
        char *path = nullptr;
        storage_get_directory(STORAGE_TYPE_INTERNAL, STORAGE_DIRECTORY_IMAGES, &path);
@@ -67,10 +67,10 @@ void ScreenshotActivity::process()
        }
 
        auto filename = directory + "/" + generateFileName();
-       timer.reset(DELAY, [this, filename]() {
+       timer.reset(DELAY, [this, filename, doneCb]() {
                auto mainWindow = Singleton<UniversalSwitch>::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
+}
index dde4c66..c3bf96c 100644 (file)
@@ -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<UniversalSwitch>::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<UniversalSwitch>::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<UniversalSwitch>::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<UniversalSwitch>::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<UniversalSwitch>::instance().getScrollActivitiesData();
                if (sd)
index 7a9a4d3..552256a 100644 (file)
@@ -53,7 +53,7 @@ public:
        ~SelectActivity();
        SelectActivity(SelectActivity &&) = delete;
 
-       void process() override;
+       void process(DoneCallback) override;
        void update(const std::shared_ptr<UIElement> &elem) override;
        void update(const std::shared_ptr<MenuItem> &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<UniversalSwitch>::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<UIElement> &elem)
@@ -155,7 +159,7 @@ void SelectActivity::update(const std::shared_ptr<UIElement> &elem)
                screenScannerManager->cancelForcingScanningMethod();
        if (isMenuShown()) {
                ASSERT(!realUiElements.empty());
-               elem->activate(); /*elem is popup menu item*/
+               elem->activate({}); /*elem is popup menu item*/
                return;
        }
 
index 9bfc921..cb1bfa9 100644 (file)
@@ -236,6 +236,6 @@ void SwitchManager::changeActivity(const std::shared_ptr<ActivityChangeRequest>
                return;
        }
 
-       activities.top()->process();
+       activities.top()->process({});
        //TODO: check if activity change request observers are properly detached from activity object removed from activity stack
 }
index 7adcb20..37274c7 100644 (file)
@@ -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();
        }
 
index c379350..cfd93aa 100644 (file)
@@ -27,7 +27,7 @@ public:
                : Activity(activityType)
        {}
 
-       void process() override
+       void process(DoneCallback) override
        {
                Singleton<VConfInterface>::instance().set(VCONF_KEY_AUTO_SCAN_ENABLED, true);
                markAsCompleted();
@@ -42,7 +42,7 @@ public:
                : Activity(activityType)
        {}
 
-       void process() override
+       void process(DoneCallback) override
        {
                Singleton<VConfInterface>::instance().set(VCONF_KEY_AUTO_SCAN_ENABLED, false);
                markAsCompleted();
index da113c9..e97c4d1 100644 (file)
@@ -39,7 +39,7 @@ public:
        {
                return Singleton<VConfInterface>::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);
index 6ed8491..76b5ed6 100644 (file)
@@ -17,6 +17,7 @@
 #include "UIElement.hpp"
 #include "UniversalSwitch.hpp"
 #include "UniversalSwitchLog.hpp"
+#include "DoneCallback.hpp"
 
 #include <thread>
 #include <chrono>
@@ -99,71 +100,73 @@ Point UIElement::getScanningCoordinates() const
 
 namespace
 {
-       void doSelect(std::shared_ptr<Atspi> atspi, const std::shared_ptr<AtspiAccessible> &obj)
+       void doSelect(std::shared_ptr<Atspi> atspi, const std::shared_ptr<AtspiAccessible> &obj, DoneCallback doneCb)
        {
                atspi->getParent(obj,
-               [ = ](DBus::ValueOrError<std::shared_ptr<AtspiAccessible>> parent) {
+               [ =, doneCb = std::move(doneCb)](DBus::ValueOrError<std::shared_ptr<AtspiAccessible>> parent) {
                        if (!parent) {
                                DEBUG("no parent");
                                return;
                        }
 
                        atspi->getIndexInParent(obj,
-                       [ = ](DBus::ValueOrError<int> index) {
+                       [ =, doneCb = std::move(doneCb)](DBus::ValueOrError<int> index) {
                                if (!index) {
                                        DEBUG("cant get index in parent");
                                        return;
                                }
 
                                atspi->getSelectionInterface(std::get<0>(parent),
-                               [ = ](DBus::ValueOrError<std::shared_ptr<AtspiSelection>> sel) {
+                               [ =, doneCb = std::move(doneCb)](DBus::ValueOrError<std::shared_ptr<AtspiSelection>> sel) {
                                        if (!sel) {
                                                DEBUG("no selection interface");
                                                return;
                                        }
 
                                        atspi->selectChild(std::get<0>(sel), std::get<0>(index),
-                                       [](DBus::ValueOrError<void> isSuccessful) {
+                                       [doneCb = std::move(doneCb)](DBus::ValueOrError<void> isSuccessful) {
                                                if (!isSuccessful) {
                                                        DEBUG("failed to select");
                                                        return;
                                                }
                                                DEBUG("selected");
+                                               doneCb.callAfterTimeElapsed(sideEffectDelays::activate);
                                        });
                                });
                        });
                });
        }
 
-       void doActivate(std::shared_ptr<Atspi> atspi, const std::shared_ptr<AtspiAccessible> obj)
+       void doActivate(std::shared_ptr<Atspi> atspi, const std::shared_ptr<AtspiAccessible> obj, DoneCallback doneCb)
        {
                atspi->getActionInterface(obj,
-               [atspi, obj](DBus::ValueOrError<std::shared_ptr<AtspiAction>> action) {
+               [atspi, obj, doneCb = std::move(doneCb)](DBus::ValueOrError<std::shared_ptr<AtspiAction>> action) {
                        if (!action) {
-                               doSelect(atspi, obj);
+                               doSelect(atspi, obj, std::move(doneCb));
                                return;
                        }
 
                        atspi->doActionName(std::get<0>(action), "activate",
-                       [atspi, obj](DBus::ValueOrError<bool> status) {
+                       [atspi, obj, doneCb = std::move(doneCb)](DBus::ValueOrError<bool> 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> &atspi, std::shared_ptr<AtspiAccessible> obj, ChangeDirection change)
+       void changeValue(const std::shared_ptr<Atspi> &atspi, std::shared_ptr<AtspiAccessible> 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<void> isSuccessful) {
-                               if (!isSuccessful)
+                       [doneCb = std::move(doneCb)](DBus::ValueOrError<void> 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()
index 7cf0183..148ed81 100644 (file)
@@ -25,6 +25,8 @@
 #include <vector>
 #include <utility>
 
+class DoneCallback;
+
 class UIElement : public std::enable_shared_from_this<UIElement>
 {
 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();
 
index 5d10d2a..6b44a50 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <memory>
 
-
 class Atspi;
 class CompositeSwitchProvider;
 class Configuration;
@@ -55,6 +54,10 @@ public:
        std::shared_ptr<ScrollActivitiesData> getScrollActivitiesData() const;
        void setScrollActivitiesData(std::shared_ptr<ScrollActivitiesData>);
 
+       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
index 3c5e8a1..ddbe123 100644 (file)
@@ -30,7 +30,7 @@ public:
                : Activity(activityType)
        {}
 
-       void process() override
+       void process(DoneCallback) override
        {
                setVolume();
                markAsCompleted();
index 1a431aa..7a63608 100644 (file)
@@ -17,6 +17,7 @@
 #include "utils.hpp"
 
 #include "UniversalSwitchLog.hpp"
+#include "DoneCallback.hpp"
 
 #include <efl_util.h>
 
@@ -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;
index ef12ce6..2b5f268 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <string>
 
+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;
 
index 103c3e7..3c11d9f 100644 (file)
@@ -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_, []() {