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 #ifndef UI_ACTION_H 16 #define UI_ACTION_H 17 18 #include <vector> 19 #include "ui_model.h" 20 21 namespace OHOS::uitest { 22 // frequently used keys. 23 constexpr int32_t KEYCODE_NONE = 0; 24 constexpr int32_t KEYCODE_BACK = 2; 25 constexpr int32_t KEYCODE_DPAD_RIGHT = 2015; 26 constexpr int32_t KEYCODE_DEL = 2055; 27 constexpr int32_t KEYCODE_CTRL = 2072; 28 constexpr int32_t KEYCODE_V = 2038; 29 constexpr int32_t KEYCODE_POWER = 18; 30 constexpr int32_t KEYCODE_HOME = 1; 31 32 /**Enumerates all the supported coordinate-based touch operations.*/ 33 enum TouchOp : uint8_t { CLICK, LONG_CLICK, DOUBLE_CLICK_P, SWIPE, DRAG, FLING}; 34 35 /**Enumerates the supported Key actions.*/ 36 enum UiKey : uint8_t { BACK, GENERIC }; 37 38 enum ActionStage : uint8_t { 39 DOWN = 0, MOVE = 1, UP = 2 40 }; 41 42 enum MouseOp : int32_t { 43 UNDEFINE = -1, 44 M_MOVETO = 0, 45 M_CLICK = 1, 46 M_SCROLL = 2, 47 }; 48 49 enum MouseEventType : int32_t { 50 M_MOVE = 3, 51 AXIS_BEGIN = 5, 52 AXIS_END = 7, 53 BUTTON_DOWN = 8, 54 BUTTON_UP = 9 55 }; 56 57 enum ResizeDirection : uint8_t { 58 LEFT, 59 RIGHT, 60 D_UP, 61 D_DOWN, 62 LEFT_UP, 63 LEFT_DOWN, 64 RIGHT_UP, 65 RIGHT_DOWN 66 }; 67 68 enum DisplayRotation : uint32_t { 69 ROTATION_0, 70 ROTATION_90, 71 ROTATION_180, 72 ROTATION_270 73 }; 74 75 enum MouseButton : int32_t { 76 BUTTON_NONE = -1, 77 BUTTON_LEFT = 0, 78 BUTTON_RIGHT = 1, 79 BUTTON_MIDDLE = 2 80 }; 81 82 enum Direction : uint32_t { 83 TO_LEFT, 84 TO_RIGHT, 85 TO_UP, 86 TO_DOWN 87 }; 88 89 struct TouchEvent { 90 ActionStage stage_; 91 Point point_; 92 uint32_t downTimeOffsetMs_; 93 uint32_t holdMs_; 94 uint32_t flags_; 95 }; 96 97 struct KeyEvent { 98 ActionStage stage_; 99 int32_t code_; 100 uint32_t holdMs_; 101 }; 102 103 /** 104 * Options of the mouse operations, initialized with system default values. 105 **/ 106 class MouseOpArgs { 107 public: 108 Point point_ = Point(0, 0); 109 MouseButton button_ = MouseButton::BUTTON_NONE; 110 bool adown_ = true; 111 int32_t scrollValue_ = 0; 112 int32_t key1_ = KEYCODE_NONE; 113 int32_t key2_ = KEYCODE_NONE; 114 MouseOp action_ = MouseOp::UNDEFINE; 115 }; 116 117 class PointerMatrix : public BackendClass { 118 public: 119 PointerMatrix(); 120 121 PointerMatrix(uint32_t fingersNum, uint32_t stepsNum); 122 123 PointerMatrix(PointerMatrix&& other); 124 125 PointerMatrix& operator=(PointerMatrix&& other); 126 127 ~PointerMatrix() override; 128 GetFrontendClassDef()129 const FrontEndClassDef &GetFrontendClassDef() const override 130 { 131 return POINTER_MATRIX_DEF; 132 } 133 134 void PushAction(const TouchEvent& ptr); 135 136 bool Empty() const; 137 138 TouchEvent& At(uint32_t fingerIndex, uint32_t stepIndex) const; 139 140 uint32_t GetCapacity() const; 141 142 uint32_t GetSize() const; 143 144 uint32_t GetSteps() const; 145 146 uint32_t GetFingers() const; 147 private: 148 std::unique_ptr<TouchEvent[]> data_ = nullptr; 149 uint32_t capacity_ = 0; 150 uint32_t stepNum_ = 0; 151 uint32_t fingerNum_ = 0; 152 uint32_t size_ = 0; 153 }; 154 155 /** 156 * Options of the UI operations, initialized with system default values. 157 **/ 158 class UiOpArgs { 159 public: 160 const uint32_t maxSwipeVelocityPps_ = 40000; 161 const uint32_t minSwipeVelocityPps_ = 200; 162 const uint32_t defaultSwipeVelocityPps_ = 600; 163 const uint32_t maxMultiTouchFingers = 10; 164 const uint32_t maxMultiTouchSteps = 1000; 165 uint32_t clickHoldMs_ = 100; 166 uint32_t longClickHoldMs_ = 1500; 167 uint32_t doubleClickIntervalMs_ = 200; 168 uint32_t keyHoldMs_ = 100; 169 uint32_t swipeVelocityPps_ = defaultSwipeVelocityPps_; 170 uint32_t uiSteadyThresholdMs_ = 1000; 171 uint32_t waitUiSteadyMaxMs_ = 3000; 172 uint32_t waitWidgetMaxMs_ = 5000; 173 int32_t scrollWidgetDeadZone_ = 80; // make sure the scrollWidget does not slide more than one page. 174 int32_t pinchWidgetDeadZone_ = 80; // pinching at the edges of the widget has no effect. 175 uint16_t swipeStepsCounts_ = 50; 176 }; 177 178 class TouchAction { 179 public: 180 /**Compute the touch event sequence that are needed to implement this action. 181 * @param recv: the event seqence receiver. 182 * @param options the ui operation agruments. 183 * */ 184 virtual void Decompose(PointerMatrix &recv, const UiOpArgs &options) const = 0; 185 }; 186 187 /** 188 * Base type of all raw pointer click actions. 189 **/ 190 class GenericClick : public TouchAction { 191 public: GenericClick(TouchOp type,const Point & point)192 GenericClick(TouchOp type, const Point &point) : type_(type), point_(point) {}; 193 194 void Decompose(PointerMatrix &recv, const UiOpArgs &options) const override; 195 196 ~GenericClick() = default; 197 198 private: 199 const TouchOp type_; 200 const Point point_; 201 }; 202 203 /** 204 * Base type of all raw pointer swipe actions. 205 **/ 206 class GenericSwipe : public TouchAction { 207 public: GenericSwipe(TouchOp type,const Point & from,const Point & to)208 explicit GenericSwipe(TouchOp type, const Point &from, const Point &to) : type_(type), from_(from), to_(to) {}; 209 210 void Decompose(PointerMatrix &recv, const UiOpArgs &options) const override; 211 212 ~GenericSwipe() = default; 213 214 private: 215 const TouchOp type_; 216 const Point from_; 217 const Point to_; 218 }; 219 220 /** 221 * Base type of all raw pointer pinch actions. 222 **/ 223 class GenericPinch : public TouchAction { 224 public: GenericPinch(const Rect & rect,float_t scale)225 explicit GenericPinch(const Rect &rect, float_t scale) : rect_(rect), scale_(scale) {}; 226 227 void Decompose(PointerMatrix &recv, const UiOpArgs &options) const override; 228 229 ~GenericPinch() = default; 230 231 private: 232 const Rect rect_; 233 const float_t scale_; 234 }; 235 236 /** 237 * Base type of multi pointer actions. 238 **/ 239 class MultiPointerAction : public TouchAction { 240 public: MultiPointerAction(const PointerMatrix & pointer)241 explicit MultiPointerAction(const PointerMatrix &pointer) : pointers_(pointer) {}; 242 243 void Decompose(PointerMatrix &recv, const UiOpArgs &options) const override; 244 245 ~MultiPointerAction() = default; 246 247 private: 248 const PointerMatrix& pointers_; 249 }; 250 251 /** 252 * Base type of all key actions. 253 * */ 254 class KeyAction { 255 public: 256 /**Compute the key event sequence that are needed to implement this action.*/ 257 virtual void ComputeEvents(std::vector<KeyEvent> &recv, const UiOpArgs &options) const = 0; 258 259 virtual ~KeyAction() = default; 260 }; 261 262 /**Base type of named single-key actions with at most 1 ctrl key.*/ 263 template<uint32_t kCode, uint32_t kCtrlCode = KEYCODE_NONE> 264 class NamedPlainKey : public KeyAction { 265 public: 266 explicit NamedPlainKey() = default; 267 ComputeEvents(std::vector<KeyEvent> & recv,const UiOpArgs & opt)268 void ComputeEvents(std::vector<KeyEvent> &recv, const UiOpArgs &opt) const override 269 { 270 if (kCtrlCode != KEYCODE_NONE) { 271 recv.push_back(KeyEvent {ActionStage::DOWN, kCtrlCode, 0}); 272 } 273 recv.push_back(KeyEvent {ActionStage::DOWN, kCode, opt.keyHoldMs_}); 274 recv.push_back(KeyEvent {ActionStage::UP, kCode, 0}); 275 if (kCtrlCode != KEYCODE_NONE) { 276 recv.push_back(KeyEvent {ActionStage::UP, kCtrlCode, 0}); 277 } 278 } 279 }; 280 281 /**Generic key actions without name and ctrl key.*/ 282 class AnonymousSingleKey final : public KeyAction { 283 public: AnonymousSingleKey(int32_t code)284 explicit AnonymousSingleKey(int32_t code) : code_(code) {}; 285 ComputeEvents(std::vector<KeyEvent> & recv,const UiOpArgs & opt)286 void ComputeEvents(std::vector<KeyEvent> &recv, const UiOpArgs &opt) const override 287 { 288 recv.push_back(KeyEvent {ActionStage::DOWN, code_, opt.keyHoldMs_}); 289 recv.push_back(KeyEvent {ActionStage::UP, code_, 0}); 290 } 291 292 private: 293 const int32_t code_; 294 }; 295 296 /**Generic Combinedkeys actions.*/ 297 class CombinedKeys final : public KeyAction { 298 public: CombinedKeys(int32_t codeZero,int32_t codeOne,int32_t codeTwo)299 CombinedKeys(int32_t codeZero, int32_t codeOne, int32_t codeTwo) 300 : codeZero_(codeZero), codeOne_(codeOne), codeTwo_(codeTwo) {}; 301 ComputeEvents(std::vector<KeyEvent> & recv,const UiOpArgs & opt)302 void ComputeEvents(std::vector<KeyEvent> &recv, const UiOpArgs &opt) const override 303 { 304 recv.push_back(KeyEvent {ActionStage::DOWN, codeZero_, 0}); 305 recv.push_back(KeyEvent {ActionStage::DOWN, codeOne_, 0}); 306 if (codeTwo_ != KEYCODE_NONE) { 307 recv.push_back(KeyEvent {ActionStage::DOWN, codeTwo_, opt.keyHoldMs_}); 308 } else { 309 recv.at(INDEX_ONE).holdMs_ = opt.keyHoldMs_; 310 } 311 if (codeTwo_ != KEYCODE_NONE) { 312 recv.push_back(KeyEvent {ActionStage::UP, codeTwo_, 0}); 313 } 314 recv.push_back(KeyEvent {ActionStage::UP, codeOne_, 0}); 315 recv.push_back(KeyEvent {ActionStage::UP, codeZero_, 0}); 316 } 317 318 private: 319 const int32_t codeZero_; 320 const int32_t codeOne_; 321 const int32_t codeTwo_; 322 }; 323 324 using Back = NamedPlainKey<KEYCODE_BACK>; 325 using Power = NamedPlainKey<KEYCODE_POWER>; 326 using Home = NamedPlainKey<KEYCODE_HOME>; 327 using Paste = NamedPlainKey<KEYCODE_V, KEYCODE_CTRL>; 328 } 329 330 #endif