• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <cmath>
17 #include "ui_action.h"
18 
19 namespace OHOS::uitest {
20     using namespace std;
21     using namespace nlohmann;
22 
DecomposeClick(PointerMatrix & recv,const Point & point,const UiOpArgs & options)23     static void DecomposeClick(PointerMatrix &recv, const Point &point, const UiOpArgs &options)
24     {
25         constexpr uint32_t fingers = 1;
26         constexpr uint32_t steps = 2;
27         PointerMatrix pointer(fingers, steps);
28         pointer.PushAction(TouchEvent {ActionStage::DOWN, point, 0, options.clickHoldMs_});
29         pointer.PushAction(TouchEvent {ActionStage::UP, point, options.clickHoldMs_, 0});
30         recv = move(pointer);
31     }
32 
DecomposeLongClick(PointerMatrix & recv,const Point & point,const UiOpArgs & options)33     static void DecomposeLongClick(PointerMatrix &recv, const Point &point, const UiOpArgs &options)
34     {
35         // should sleep after touch-down to make long-click duration
36         constexpr uint32_t fingers = 1;
37         constexpr uint32_t steps = 2;
38         PointerMatrix pointer(fingers, steps);
39         pointer.PushAction(TouchEvent {ActionStage::DOWN, point, 0, options.longClickHoldMs_});
40         pointer.PushAction(TouchEvent {ActionStage::UP, point, options.longClickHoldMs_, 0});
41         recv = move(pointer);
42     }
43 
DecomposeDoubleClick(PointerMatrix & recv,const Point & point,const UiOpArgs & options)44     static void DecomposeDoubleClick(PointerMatrix &recv, const Point &point, const UiOpArgs &options)
45     {
46         const auto msInterval = options.doubleClickIntervalMs_;
47         constexpr uint32_t fingers = 1;
48         constexpr uint32_t steps = 4;
49         PointerMatrix pointer(fingers, steps);
50         pointer.PushAction(TouchEvent {ActionStage::DOWN, point, 0, options.clickHoldMs_});
51         pointer.PushAction(TouchEvent {ActionStage::UP, point, options.clickHoldMs_, msInterval});
52 
53         pointer.PushAction(TouchEvent {ActionStage::DOWN, point, 0, options.clickHoldMs_});
54         pointer.PushAction(TouchEvent {ActionStage::UP, point, options.clickHoldMs_, 0});
55         recv = move(pointer);
56     }
57 
DecomposeComputeSwipe(PointerMatrix & recv,const Point & from,const Point & to,bool drag,const UiOpArgs & options)58     static void DecomposeComputeSwipe(PointerMatrix &recv, const Point &from, const Point &to, bool drag,
59                                       const UiOpArgs &options)
60     {
61         const int32_t distanceX = to.px_ - from.px_;
62         const int32_t distanceY = to.py_ - from.py_;
63         const uint32_t distance = sqrt(distanceX * distanceX + distanceY * distanceY);
64         const uint32_t timeCostMs = (distance * 1000) / options.swipeVelocityPps_;
65         if (distance < 1) {
66             // do not need to execute swipe
67             return;
68         }
69         const auto steps = options.swipeStepsCounts_;
70         const uint32_t intervalMs = timeCostMs / steps + 1;
71         constexpr uint32_t fingers = 1;
72         PointerMatrix pointer(fingers, steps + 1);
73 
74         pointer.PushAction(TouchEvent {ActionStage::DOWN, {from.px_, from.py_}, 0, intervalMs});
75         for (uint16_t step = 1; step < steps; step++) {
76             const int32_t pointX = from.px_ + (distanceX * step) / steps;
77             const int32_t pointY = from.py_ + (distanceY * step) / steps;
78             const uint32_t timeOffsetMs = (timeCostMs * step) / steps;
79             pointer.PushAction(TouchEvent {ActionStage::MOVE, {pointX, pointY}, timeOffsetMs, intervalMs});
80         }
81 
82         pointer.PushAction(TouchEvent {ActionStage::UP, {to.px_, to.py_}, timeCostMs, intervalMs});
83         if (drag) {
84             // drag needs longPressDown firstly
85             pointer.At(fingers - 1, 0).holdMs_ += options.longClickHoldMs_;
86             for (uint32_t idx = 1; idx < pointer.GetSize(); idx++) {
87                 pointer.At(fingers - 1, idx).downTimeOffsetMs_ += options.longClickHoldMs_;
88             }
89         }
90         recv = move(pointer);
91     }
92 
Decompose(PointerMatrix & recv,const UiOpArgs & options) const93     void GenericClick::Decompose(PointerMatrix &recv, const UiOpArgs &options) const
94     {
95         DCHECK(type_ >= TouchOp::CLICK && type_ <= TouchOp::DOUBLE_CLICK_P);
96         switch (type_) {
97             case CLICK:
98                 DecomposeClick(recv, point_, options);
99                 break;
100             case LONG_CLICK:
101                 DecomposeLongClick(recv, point_, options);
102                 break;
103             case DOUBLE_CLICK_P:
104                 DecomposeDoubleClick(recv, point_, options);
105                 break;
106             default:
107                 break;
108         }
109         for (uint32_t index = 0; index < recv.GetSize(); index++) {
110             recv.At(recv.GetFingers() - 1, index).flags_ = type_;
111         }
112     }
113 
Decompose(PointerMatrix & recv,const UiOpArgs & options) const114     void GenericSwipe::Decompose(PointerMatrix &recv, const UiOpArgs &options) const
115     {
116         DCHECK(type_ >= TouchOp::SWIPE && type_ <= TouchOp::DRAG);
117         DecomposeComputeSwipe(recv, from_, to_, type_ == TouchOp::DRAG, options);
118         for (uint32_t index = 0; index < recv.GetSize(); index++) {
119             recv.At(recv.GetFingers() - 1, index).flags_ = type_;
120         }
121     }
122 
Decompose(PointerMatrix & recv,const UiOpArgs & options) const123     void GenericPinch::Decompose(PointerMatrix &recv, const UiOpArgs &options) const
124     {
125         const int32_t distanceX0 = abs(rect_.GetCenterX() - rect_.left_) * abs(scale_ - 1);
126         PointerMatrix pointer1;
127         PointerMatrix pointer2;
128         if (scale_ > 1) {
129             auto fromPoint0 = Point(rect_.GetCenterX() - options.scrollWidgetDeadZone_, rect_.GetCenterY());
130             auto toPoint0 = Point((rect_.GetCenterX() - distanceX0), rect_.GetCenterY());
131             auto fromPoint1 = Point(rect_.GetCenterX() + options.scrollWidgetDeadZone_, rect_.GetCenterY());
132             auto toPoint1 = Point((rect_.GetCenterX() + distanceX0), rect_.GetCenterY());
133             DecomposeComputeSwipe(pointer1, fromPoint0, toPoint0, false, options);
134             DecomposeComputeSwipe(pointer2, fromPoint1, toPoint1, false, options);
135         } else if (scale_ < 1) {
136             auto fromPoint0 = Point(rect_.left_ + options.scrollWidgetDeadZone_, rect_.GetCenterY());
137             auto toPoint0 = Point((rect_.left_ + distanceX0), rect_.GetCenterY());
138             auto fromPoint1 = Point(rect_.right_ - options.scrollWidgetDeadZone_, rect_.GetCenterY());
139             auto toPoint1 = Point((rect_.right_ - distanceX0), rect_.GetCenterY());
140             DecomposeComputeSwipe(pointer1, fromPoint0, toPoint0, false, options);
141             DecomposeComputeSwipe(pointer2, fromPoint1, toPoint1, false, options);
142         }
143 
144         PointerMatrix pointer3(pointer1.GetFingers() + pointer2.GetFingers(), pointer1.GetSteps());
145         for (uint32_t index = 0; index < pointer1.GetSize(); index++) {
146             pointer3.PushAction(pointer1.At(0, index));
147         }
148         for (uint32_t index = 0; index < pointer2.GetSize(); index++) {
149             pointer3.PushAction(pointer2.At(0, index));
150         }
151         recv = move(pointer3);
152     }
153 
Decompose(PointerMatrix & recv,const UiOpArgs & options) const154     void MultiPointerAction::Decompose(PointerMatrix &recv, const UiOpArgs &options) const
155     {
156         PointerMatrix matrix(pointers_.GetFingers(), pointers_.GetSteps());
157         for (uint32_t finger = 0; finger < pointers_.GetFingers(); finger++) {
158             uint32_t timeOffsetMs = 0;
159             uint32_t intervalMs = 0;
160             constexpr uint32_t unitConversionConstant = 1000;
161             for (uint32_t step = 0; step < pointers_.GetSteps() - 1; step++) {
162                 const int32_t pxTo = pointers_.At(finger, step + 1).point_.px_;
163                 const int32_t pxFrom = pointers_.At(finger, step).point_.px_;
164                 const int32_t distanceX = pxTo - pxFrom;
165                 const int32_t pyTo = pointers_.At(finger, step + 1).point_.py_;
166                 const int32_t pyFrom = pointers_.At(finger, step).point_.py_;
167                 const int32_t distanceY = pyTo - pyFrom;
168                 const uint32_t distance = sqrt(distanceX * distanceX + distanceY * distanceY);
169                 intervalMs = (distance * unitConversionConstant) / options.swipeVelocityPps_;
170                 if (distance < 1) {
171                     return;
172                 }
173                 if (step == 0) {
174                     matrix.PushAction(TouchEvent {ActionStage::DOWN, {pxFrom, pyFrom}, 0, intervalMs});
175                 } else {
176                     timeOffsetMs += intervalMs;
177                     matrix.PushAction(TouchEvent {ActionStage::MOVE, {pxFrom, pyFrom}, timeOffsetMs, intervalMs});
178                 }
179             }
180             auto endPx = pointers_.At(finger, pointers_.GetSteps() - 1).point_.px_;
181             auto endPy = pointers_.At(finger, pointers_.GetSteps() - 1).point_.py_;
182             matrix.PushAction(TouchEvent {ActionStage::UP, {endPx, endPy}, timeOffsetMs, intervalMs});
183         }
184         recv = move(matrix);
185     }
186 
PointerMatrix()187     PointerMatrix::PointerMatrix() {};
188 
PointerMatrix(uint32_t fingersNum,uint32_t stepsNum)189     PointerMatrix::PointerMatrix(uint32_t fingersNum, uint32_t stepsNum)
190     {
191         this->fingerNum_ = fingersNum;
192         this->stepNum_ = stepsNum;
193         this->capacity_ = this->fingerNum_ * this->stepNum_;
194         this->size_ = 0;
195         this->data_ = std::make_unique<TouchEvent[]>(this->capacity_);
196     }
197 
operator =(PointerMatrix && other)198     PointerMatrix& PointerMatrix::operator=(PointerMatrix&& other)
199     {
200         this->data_ = move(other.data_);
201         this->fingerNum_ = other.fingerNum_;
202         this->stepNum_ = other.stepNum_;
203         this->capacity_ = other.capacity_;
204         this->size_ = other.size_;
205         other.fingerNum_ = 0;
206         other.stepNum_ = 0;
207         other.capacity_ = 0;
208         other.size_ = 0;
209         return *this;
210     }
211 
~PointerMatrix()212     PointerMatrix::~PointerMatrix() {}
213 
PushAction(const TouchEvent & ptr)214     void PointerMatrix::PushAction(const TouchEvent& ptr)
215     {
216         if (this->capacity_ == this->size_) {
217             return;
218         }
219         *(this->data_.get() + this->size_) = ptr;
220         this->size_++;
221     }
222 
Empty() const223     bool PointerMatrix::Empty() const
224     {
225         if (this->size_ == 0) {
226             return true;
227         }
228         return false;
229     }
230 
At(uint32_t fingerIndex,uint32_t stepIndex) const231     TouchEvent& PointerMatrix::At(uint32_t fingerIndex, uint32_t stepIndex) const
232     {
233         return *(this->data_.get() + (fingerIndex * this->stepNum_ + stepIndex));
234     }
235 
GetCapacity() const236     uint32_t PointerMatrix::GetCapacity() const
237     {
238         return this->capacity_;
239     }
240 
GetSize() const241     uint32_t PointerMatrix::GetSize() const
242     {
243         return this->size_;
244     }
245 
GetSteps() const246     uint32_t PointerMatrix::GetSteps() const
247     {
248         return this->stepNum_;
249     }
250 
GetFingers() const251     uint32_t PointerMatrix::GetFingers() const
252     {
253         return this->fingerNum_;
254     }
255 }
256