a8f40e7bb2c87b2bad2c0355c7597aa291b46e6d
[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     //FIXME: Need to get top window
154     auto wins = this->getWindowRoot();
155
156     return AccessibleWatcher::getInstance()->executeAndWaitForEvents(cmd, type, timeout, packageName, wins[0], count);
157 }
158
159 bool UiDevice::sendKeyAndWaitForEvents(
160     const std::string keycode, const A11yEvent type, const int timeout) const
161 {
162     std::unique_ptr<SendKeyRunnable> cmd = std::make_unique<SendKeyRunnable>(keycode);
163     return executeAndWaitForEvents(cmd.get(), type, timeout, std::string(), 0);
164 }
165
166 bool UiDevice::click(const int x, const int y)
167 {
168     bool result =  mDeviceImpl->click(x, y);
169     waitForIdle();
170     return result;
171 }
172
173 bool UiDevice::click(const int x, const int y, const unsigned int durationMs)
174 {
175     bool result = mDeviceImpl->click(x, y, durationMs);
176     waitForIdle();
177     return result;
178 }
179
180 bool UiDevice::drag(const int sx, const int sy, const int ex, const int ey,
181                     const int steps, const int durationMs)
182 {
183     bool result =  mDeviceImpl->drag(sx, sy, ex, ey, steps, durationMs);
184     waitForIdle();
185     return result;
186 }
187
188 int UiDevice::touchDown(const int x, const int y)
189 {
190     int seq =  mDeviceImpl->touchDown(x, y);
191     return seq;
192 }
193
194 bool UiDevice::touchMove(const int x, const int y, const int seq)
195 {
196     bool result =  mDeviceImpl->touchMove(x, y, seq);
197     return result;
198 }
199
200 bool UiDevice::touchUp(const int x, const int y, const int seq)
201 {
202     bool result =  mDeviceImpl->touchUp(x, y, seq);
203     waitForIdle();
204     return result;
205 }
206
207 bool UiDevice::wheelUp(int amount, const int durationMs)
208 {
209     bool result =  mDeviceImpl->wheelUp(amount, durationMs);
210     waitForIdle();
211     return result;
212 }
213
214 bool UiDevice::wheelDown(int amount, const int durationMs)
215 {
216     bool result =  mDeviceImpl->wheelDown(amount, durationMs);
217     waitForIdle();
218     return result;
219 }
220
221 bool UiDevice::pressBack(KeyRequestType type)
222 {
223     bool result =  mDeviceImpl->pressBack(type);
224     waitForIdle();
225     return result;
226 }
227
228 bool UiDevice::pressHome(KeyRequestType type)
229 {
230     bool result =  mDeviceImpl->pressHome(type);
231     waitForIdle();
232     return result;
233 }
234
235 bool UiDevice::pressMenu(KeyRequestType type)
236 {
237     bool result =  mDeviceImpl->pressMenu(type);
238     waitForIdle();
239     return result;
240 }
241
242 bool UiDevice::pressVolUp(KeyRequestType type)
243 {
244     bool result =  mDeviceImpl->pressVolUp(type);
245     waitForIdle();
246     return result;
247 }
248
249 bool UiDevice::pressVolDown(KeyRequestType type)
250 {
251     bool result =  mDeviceImpl->pressVolDown(type);
252     waitForIdle();
253     return result;
254 }
255
256 bool UiDevice::pressPower(KeyRequestType type)
257 {
258     bool result =  mDeviceImpl->pressPower(type);
259     waitForIdle();
260     return result;
261 }
262
263 bool UiDevice::pressKeyCode(std::string keycode, KeyRequestType type)
264 {
265     bool result =  mDeviceImpl->pressKeyCode(keycode, type);
266     return result;
267 }
268
269 bool UiDevice::repeatKeyCode(std::string keycode, int intervalMs, int durationMs)
270 {
271     bool result =  mDeviceImpl->repeatKeyCode(keycode, intervalMs, durationMs);
272     return result;
273 }
274
275 bool UiDevice::takeScreenshot(std::string path, bool asPixels, void **pixels)
276 {
277     return mDeviceImpl->takeScreenshot(path, asPixels, pixels);
278 }
279
280 long long UiDevice::getSystemTime(TimeRequestType type)
281 {
282     return mDeviceImpl->getSystemTime(type);
283 }
284
285 const Size2D<int> UiDevice::getScreenSize()
286 {
287     return mDeviceImpl->getScreenSize();
288 }
289
290 #ifdef MQTT_ENABLED
291 std::vector<std::shared_ptr<SaObject>> UiDevice::getSaObject()
292 {
293     return mSAWatcher->GetSaObjects();
294 }
295
296 std::shared_ptr<ScreenAnalyzerWatcher> UiDevice::getSAWatcher()
297 {
298     return mSAWatcher;
299 }
300 #endif
301
302 void UiDevice::RequestScreenAnalyze()
303 {
304 #ifdef MQTT_ENABLED
305     mSAWatcher->PublishData();
306 #endif
307 }
308
309 bool UiDevice::getExternalAppLaunched()
310 {
311     auto ret = this->getWindowRoot();
312     return (ret.size() > 0) ? false : true;
313 }
314
315 void UiDevice::setWithScreenAnalyzer(bool withScreenAnalyzer)
316 {
317     mIsWithSA = withScreenAnalyzer;
318 }
319
320 bool UiDevice::getWithScreenAnalyzer()
321 {
322     return mIsWithSA;
323 }
324
325 bool UiDevice::registerCallback(const A11yEvent type, EventHandler cb, void *data) const
326 {
327     return AccessibleWatcher::getInstance()->registerCallback(type, cb, data);
328 }