libaurum: Add window events for automate script
[platform/core/uifw/aurum.git] / libaurum / src / UiDevice.cc
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *               http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  */
17
18 #include "Aurum.h"
19
20 #ifdef TIZEN
21 #include "TizenDeviceImpl.h"
22 #endif
23 #include "MockDeviceImpl.h"
24 #include "AtspiAccessibleWatcher.h"
25 #include <unistd.h>
26 #include <utility>
27 #include <vector>
28 #include <chrono>
29 #include <thread>
30 #include <algorithm>
31 #include <iostream>
32 #include <unordered_set>
33 #include <unordered_map>
34
35 using namespace Aurum;
36 using namespace AurumInternal;
37
38 std::once_flag UiDevice::mOnceFlag;
39
40 #ifdef MQTT_ENABLED
41 std::shared_ptr<ScreenAnalyzerWatcher> UiDevice::mSAWatcher;
42 #endif
43
44 UiDevice::UiDevice() : UiDevice(nullptr) {}
45
46 UiDevice::UiDevice(IDevice *impl)
47     : mDeviceImpl(impl), mWaiter(new Waiter{this})
48 {
49     LOGI("UiDevice constructor");
50     mIsWithSA = false;
51 #ifdef MQTT_ENABLED
52     mSAWatcher = std::make_shared<ScreenAnalyzerWatcher>();
53 #endif
54     LOGI("UiDevice constructor finish");
55 }
56
57 UiDevice::~UiDevice()
58 {
59     delete mDeviceImpl;
60     delete mWaiter;
61 }
62
63 std::shared_ptr<UiDevice> UiDevice::getInstance(IDevice *deviceImpl)
64 {
65     static std::shared_ptr<UiDevice> device{nullptr};
66     std::call_once(mOnceFlag, [deviceImpl] {
67         if (deviceImpl) {
68             device.reset(new UiDevice(deviceImpl));
69         } else {
70 #ifdef TIZEN
71             device.reset(new UiDevice(new TizenDeviceImpl()));
72 #else
73             device.reset(new UiDevice(new MockDeviceImpl()));
74 #endif
75         }
76     });
77
78     return device;
79 }
80
81 std::vector<std::shared_ptr<AccessibleNode>> UiDevice::getWindowRoot() const
82 {
83     return mDeviceImpl->getWindowRoot();
84 }
85
86 bool UiDevice::hasObject(const std::shared_ptr<UiSelector> selector) const
87 {
88     auto rootNodes = getWindowRoot();
89     for (const auto &node : rootNodes) {
90         const std::shared_ptr<AccessibleNode> foundNode =
91             Comparer::findObject(getInstance(), selector, node);
92         if (foundNode) return true;
93     }
94
95     return false;
96 }
97
98 std::shared_ptr<UiObject> UiDevice::findObject(const std::shared_ptr<UiSelector> selector) const
99 {
100     auto rootNodes = getWindowRoot();
101     for (const auto &node : rootNodes) {
102         const std::shared_ptr<AccessibleNode> foundNode =
103             Comparer::findObject(getInstance(), selector, node);
104         if (foundNode)
105             return std::make_shared<UiObject>(getInstance(), selector, foundNode);
106     }
107     return std::shared_ptr<UiObject>{nullptr};
108 }
109
110
111 std::vector<std::shared_ptr<UiObject>> UiDevice::findObjects(
112     const std::shared_ptr<UiSelector> selector) const
113 {
114     std::vector<std::shared_ptr<UiObject>> ret{};
115     auto rootNodes = getWindowRoot();
116     for (const auto &window : rootNodes) {
117         std::vector<std::shared_ptr<AccessibleNode>> nodes{};
118         Comparer::findObjects(nodes, getInstance(), selector, window);
119
120         for (auto &node : nodes)
121             ret.push_back(std::make_shared<UiObject>(getInstance(), selector, node));
122     }
123     return ret;
124 }
125 bool UiDevice::waitFor(
126     const std::function<bool(const ISearchable *)> condition) const
127 {
128     return mWaiter->waitFor(condition);
129 }
130
131 std::shared_ptr<UiObject> UiDevice::waitFor(
132     const std::function<std::shared_ptr<UiObject>(const ISearchable *)>
133         condition) const
134 {
135     return mWaiter->waitFor(condition);
136 }
137 bool UiDevice::waitForIdle() const
138 {
139     std::this_thread::sleep_for(std::chrono::milliseconds{167});
140     return true;
141 }
142
143 bool UiDevice::waitForEvents(
144     const A11yEvent type, const int timeout) const
145 {
146     return executeAndWaitForEvents(NULL, type, timeout, std::string(), 0);
147 }
148
149 //FIXME: obj only need for idle event
150 bool UiDevice::executeAndWaitForEvents
151     (const Runnable *cmd, const A11yEvent type, const int timeout, const std::string packageName, const int count)  const
152 {
153     std::vector<std::shared_ptr<AccessibleNode>> wins;
154
155     //FIXME: Need to get top window
156     if (type != A11yEvent::EVENT_NONE &&  (A11yEvent::EVENT_WINDOW_RENDER_POST & type) == type)
157     {
158         wins = this->getWindowRoot();
159         return AccessibleWatcher::getInstance()->executeAndWaitForEvents(cmd, type, timeout, packageName, wins[0], count);
160     }
161
162     return AccessibleWatcher::getInstance()->executeAndWaitForEvents(cmd, type, timeout, packageName, NULL, count);
163 }
164
165 bool UiDevice::sendKeyAndWaitForEvents(
166     const std::string keycode, const A11yEvent type, const int timeout) const
167 {
168     std::unique_ptr<SendKeyRunnable> cmd = std::make_unique<SendKeyRunnable>(keycode);
169     return executeAndWaitForEvents(cmd.get(), type, timeout, std::string(), 0);
170 }
171
172 bool UiDevice::click(const int x, const int y)
173 {
174     bool result =  mDeviceImpl->click(x, y);
175     waitForIdle();
176     return result;
177 }
178
179 bool UiDevice::click(const int x, const int y, const unsigned int durationMs)
180 {
181     bool result = mDeviceImpl->click(x, y, durationMs);
182     waitForIdle();
183     return result;
184 }
185
186 bool UiDevice::drag(const int sx, const int sy, const int ex, const int ey,
187                     const int steps, const int durationMs)
188 {
189     bool result =  mDeviceImpl->drag(sx, sy, ex, ey, steps, durationMs);
190     waitForIdle();
191     return result;
192 }
193
194 int UiDevice::touchDown(const int x, const int y)
195 {
196     int seq =  mDeviceImpl->touchDown(x, y);
197     return seq;
198 }
199
200 bool UiDevice::touchMove(const int x, const int y, const int seq)
201 {
202     bool result =  mDeviceImpl->touchMove(x, y, seq);
203     return result;
204 }
205
206 bool UiDevice::touchUp(const int x, const int y, const int seq)
207 {
208     bool result =  mDeviceImpl->touchUp(x, y, seq);
209     waitForIdle();
210     return result;
211 }
212
213 bool UiDevice::wheelUp(int amount, const int durationMs)
214 {
215     bool result =  mDeviceImpl->wheelUp(amount, durationMs);
216     waitForIdle();
217     return result;
218 }
219
220 bool UiDevice::wheelDown(int amount, const int durationMs)
221 {
222     bool result =  mDeviceImpl->wheelDown(amount, durationMs);
223     waitForIdle();
224     return result;
225 }
226
227 bool UiDevice::pressBack(KeyRequestType type)
228 {
229     bool result =  mDeviceImpl->pressBack(type);
230     waitForIdle();
231     return result;
232 }
233
234 bool UiDevice::pressHome(KeyRequestType type)
235 {
236     bool result =  mDeviceImpl->pressHome(type);
237     waitForIdle();
238     return result;
239 }
240
241 bool UiDevice::pressMenu(KeyRequestType type)
242 {
243     bool result =  mDeviceImpl->pressMenu(type);
244     waitForIdle();
245     return result;
246 }
247
248 bool UiDevice::pressVolUp(KeyRequestType type)
249 {
250     bool result =  mDeviceImpl->pressVolUp(type);
251     waitForIdle();
252     return result;
253 }
254
255 bool UiDevice::pressVolDown(KeyRequestType type)
256 {
257     bool result =  mDeviceImpl->pressVolDown(type);
258     waitForIdle();
259     return result;
260 }
261
262 bool UiDevice::pressPower(KeyRequestType type)
263 {
264     bool result =  mDeviceImpl->pressPower(type);
265     waitForIdle();
266     return result;
267 }
268
269 bool UiDevice::pressKeyCode(std::string keycode, KeyRequestType type)
270 {
271     bool result =  mDeviceImpl->pressKeyCode(keycode, type);
272     return result;
273 }
274
275 bool UiDevice::repeatKeyCode(std::string keycode, int intervalMs, int durationMs)
276 {
277     bool result =  mDeviceImpl->repeatKeyCode(keycode, intervalMs, durationMs);
278     return result;
279 }
280
281 bool UiDevice::takeScreenshot(std::string path, bool asPixels, void **pixels)
282 {
283     return mDeviceImpl->takeScreenshot(path, asPixels, pixels);
284 }
285
286 long long UiDevice::getSystemTime(TimeRequestType type)
287 {
288     return mDeviceImpl->getSystemTime(type);
289 }
290
291 const Size2D<int> UiDevice::getScreenSize()
292 {
293     return mDeviceImpl->getScreenSize();
294 }
295
296 #ifdef MQTT_ENABLED
297 std::vector<std::shared_ptr<SaObject>> UiDevice::getSaObject()
298 {
299     return mSAWatcher->GetSaObjects();
300 }
301
302 std::shared_ptr<ScreenAnalyzerWatcher> UiDevice::getSAWatcher()
303 {
304     return mSAWatcher;
305 }
306 #endif
307
308 void UiDevice::RequestScreenAnalyze()
309 {
310 #ifdef MQTT_ENABLED
311     mSAWatcher->PublishData();
312 #endif
313 }
314
315 bool UiDevice::getExternalAppLaunched()
316 {
317     auto ret = this->getWindowRoot();
318     return (ret.size() > 0) ? false : true;
319 }
320
321 void UiDevice::setWithScreenAnalyzer(bool withScreenAnalyzer)
322 {
323     mIsWithSA = withScreenAnalyzer;
324 }
325
326 bool UiDevice::getWithScreenAnalyzer()
327 {
328     return mIsWithSA;
329 }
330
331 bool UiDevice::registerCallback(const A11yEvent type, EventHandler cb, void *data) const
332 {
333     return AccessibleWatcher::getInstance()->registerCallback(type, cb, data);
334 }