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 constexpr int32_t KEYCODE_D = 2020; 32 constexpr int32_t KEYCODE_WIN = 2076; 33 constexpr int32_t KEYCODE_MOVETOEND = 2082; 34 35 /**Enumerates all the supported coordinate-based touch operations.*/ 36 enum TouchOp : uint8_t { CLICK, LONG_CLICK, DOUBLE_CLICK_P, SWIPE, DRAG, FLING}; 37 38 /**Enumerates the supported Key actions.*/ 39 enum UiKey : uint8_t { BACK, GENERIC }; 40 41 enum ActionStage : uint8_t { 42 NONE = 0, 43 DOWN = 1, 44 MOVE = 2, 45 UP = 3, 46 AXIS_UP = 4, 47 AXIS_DOWN = 5, 48 AXIS_STOP = 6, 49 PROXIMITY_IN = 7, 50 PROXIMITY_OUT = 8 51 }; 52 53 enum TouchToolType : uint8_t { FINGER = 0, PEN = 1 }; 54 55 enum ResizeDirection : uint8_t { 56 LEFT, 57 RIGHT, 58 D_UP, 59 D_DOWN, 60 LEFT_UP, 61 LEFT_DOWN, 62 RIGHT_UP, 63 RIGHT_DOWN 64 }; 65 66 enum DisplayRotation : uint32_t { 67 ROTATION_0, 68 ROTATION_90, 69 ROTATION_180, 70 ROTATION_270 71 }; 72 73 enum MouseButton : int32_t { 74 BUTTON_NONE = -1, 75 BUTTON_LEFT = 0, 76 BUTTON_RIGHT = 1, 77 BUTTON_MIDDLE = 2 78 }; 79 80 enum Direction : uint32_t { 81 TO_LEFT, 82 TO_RIGHT, 83 TO_UP, 84 TO_DOWN 85 }; 86 87 struct TouchEvent { 88 ActionStage stage_; 89 Point point_; 90 uint32_t downTimeOffsetMs_; 91 uint32_t holdMs_; 92 uint32_t flags_; 93 }; 94 95 struct KeyEvent { 96 ActionStage stage_; 97 int32_t code_; 98 uint32_t holdMs_; 99 }; 100 101 struct MouseEvent { 102 ActionStage stage_; 103 Point point_; 104 MouseButton button_; 105 vector<KeyEvent> keyEvents_; 106 uint32_t holdMs_; 107 }; 108 109 struct TouchPadEvent { 110 ActionStage stage; 111 Point point; 112 uint32_t fingerCount; 113 uint32_t holdMs; 114 }; 115 116 class PointerMatrix : public BackendClass { 117 public: 118 PointerMatrix(); 119 120 PointerMatrix(uint32_t fingersNum, uint32_t stepsNum); 121 122 PointerMatrix(PointerMatrix&& other); 123 124 PointerMatrix& operator=(PointerMatrix&& other); 125 126 ~PointerMatrix() override; 127 GetFrontendClassDef()128 const FrontEndClassDef &GetFrontendClassDef() const override 129 { 130 return POINTER_MATRIX_DEF; 131 } 132 133 void PushAction(const TouchEvent& ptr); 134 135 bool Empty() const; 136 137 TouchEvent& At(uint32_t fingerIndex, uint32_t stepIndex) const; 138 139 uint32_t GetCapacity() const; 140 141 uint32_t GetSize() const; 142 143 uint32_t GetSteps() const; 144 145 uint32_t GetFingers() const; 146 147 void SetToolType(const TouchToolType type); 148 149 TouchToolType GetToolType() const; 150 151 void SetTouchPressure(const float pressure); 152 153 float GetTouchPressure() const; 154 155 void ConvertToMouseEvents(vector<MouseEvent> &recv) const; 156 157 void ConvertToPenEvents(PointerMatrix &recv) const; 158 private: 159 std::unique_ptr<TouchEvent[]> data_ = nullptr; 160 uint32_t capacity_ = 0; 161 uint32_t stepNum_ = 0; 162 uint32_t fingerNum_ = 0; 163 uint32_t size_ = 0; 164 TouchToolType touchToolType_ = TouchToolType::FINGER; 165 float touchPressure_ = 1.0; 166 }; 167 168 /** 169 * Options of the UI operations, initialized with system default values. 170 **/ 171 class UiOpArgs { 172 public: 173 const uint32_t maxSwipeVelocityPps_ = 40000; 174 const uint32_t minSwipeVelocityPps_ = 200; 175 const uint32_t defaultSwipeVelocityPps_ = 600; 176 const uint32_t maxMultiTouchFingers = 10; 177 const uint32_t maxMultiTouchSteps = 1000; 178 const uint32_t defaultTouchPadSwipeVelocityPps_ = 2000; 179 uint32_t clickHoldMs_ = 100; 180 uint32_t longClickHoldMs_ = 1500; 181 uint32_t doubleClickIntervalMs_ = 200; 182 uint32_t keyHoldMs_ = 100; 183 uint32_t swipeVelocityPps_ = defaultSwipeVelocityPps_; 184 uint32_t uiSteadyThresholdMs_ = 1000; 185 uint32_t waitUiSteadyMaxMs_ = 3000; 186 uint32_t waitWidgetMaxMs_ = 5000; 187 int32_t scrollWidgetDeadZone_ = 80; // make sure the scrollWidget does not slide more than one page. 188 int32_t pinchWidgetDeadZone_ = 40; // pinching at the edges of the widget has no effect. 189 uint16_t swipeStepsCounts_ = 50; 190 float touchPressure_ = 1.0; 191 bool inputByPasteBoard_ = false; 192 bool inputAdditional_ = false; 193 }; 194 195 class TouchAction { 196 public: 197 /**Compute the touch event sequence that are needed to implement this action. 198 * @param recv: the event seqence receiver. 199 * @param options the ui operation agruments. 200 * */ 201 virtual void Decompose(PointerMatrix &recv, const UiOpArgs &options) const = 0; 202 }; 203 204 /** 205 * Base type of all raw pointer click actions. 206 **/ 207 class GenericClick : public TouchAction { 208 public: GenericClick(TouchOp type,const Point & point)209 GenericClick(TouchOp type, const Point &point) : type_(type), point_(point) {}; 210 211 void Decompose(PointerMatrix &recv, const UiOpArgs &options) const override; 212 213 ~GenericClick() = default; 214 215 private: 216 const TouchOp type_; 217 const Point point_; 218 }; 219 220 /** 221 * Base type of all raw pointer swipe actions. 222 **/ 223 class GenericSwipe : public TouchAction { 224 public: GenericSwipe(TouchOp type,const Point & from,const Point & to)225 explicit GenericSwipe(TouchOp type, const Point &from, const Point &to) : type_(type), from_(from), to_(to) {}; 226 227 void Decompose(PointerMatrix &recv, const UiOpArgs &options) const override; 228 229 ~GenericSwipe() = default; 230 231 private: 232 const TouchOp type_; 233 const Point from_; 234 const Point to_; 235 }; 236 237 /** 238 * Base type of all raw pointer pinch actions. 239 **/ 240 class GenericPinch : public TouchAction { 241 public: GenericPinch(const Rect & rect,float_t scale)242 explicit GenericPinch(const Rect &rect, float_t scale) : rect_(rect), scale_(scale) {}; 243 244 void Decompose(PointerMatrix &recv, const UiOpArgs &options) const override; 245 246 ~GenericPinch() = default; 247 248 private: 249 const Rect rect_; 250 const float_t scale_; 251 }; 252 253 /** 254 * Base type of multi pointer actions. 255 **/ 256 class MultiPointerAction : public TouchAction { 257 public: MultiPointerAction(const PointerMatrix & pointer)258 explicit MultiPointerAction(const PointerMatrix &pointer) : pointers_(pointer) {}; 259 260 void Decompose(PointerMatrix &recv, const UiOpArgs &options) const override; 261 262 ~MultiPointerAction() = default; 263 264 private: 265 const PointerMatrix& pointers_; 266 }; 267 268 /** 269 * Base type of touchpad gesture actions. 270 **/ 271 class TouchPadAction { 272 public: TouchPadAction(const int32_t fingers,const Direction direction,const bool stay)273 explicit TouchPadAction(const int32_t fingers, const Direction direction, const bool stay) 274 : fingers_(fingers), direction_(direction), stay_(stay) {}; 275 276 void Decompose(std::vector<TouchPadEvent> &recv, const UiOpArgs &options, const Point displaySize) const; 277 278 ~TouchPadAction() = default; 279 280 private: 281 const int32_t fingers_; 282 const Direction direction_; 283 const bool stay_; 284 }; 285 286 /** 287 * Base type of all key actions. 288 * */ 289 class KeyAction { 290 public: 291 /**Compute the key event sequence that are needed to implement this action.*/ 292 virtual void ComputeEvents(std::vector<KeyEvent> &recv, const UiOpArgs &options) const = 0; 293 294 virtual ~KeyAction() = default; 295 }; 296 297 class KeysForwarder : public KeyAction { 298 public: KeysForwarder(const vector<KeyEvent> & evetns)299 explicit KeysForwarder(const vector<KeyEvent> &evetns) : events_(evetns) {}; 300 ComputeEvents(vector<KeyEvent> & recv,const UiOpArgs & opt)301 void ComputeEvents(vector<KeyEvent> &recv, const UiOpArgs &opt) const override 302 { 303 recv = events_; 304 } 305 306 private: 307 const vector<KeyEvent> &events_; 308 }; 309 310 /**Base type of named single-key actions with at most 1 ctrl key.*/ 311 template<uint32_t kCode, uint32_t kCtrlCode = KEYCODE_NONE> 312 class NamedPlainKey : public KeyAction { 313 public: 314 explicit NamedPlainKey() = default; 315 ComputeEvents(std::vector<KeyEvent> & recv,const UiOpArgs & opt)316 void ComputeEvents(std::vector<KeyEvent> &recv, const UiOpArgs &opt) const override 317 { 318 if (kCtrlCode != KEYCODE_NONE) { 319 recv.push_back(KeyEvent {ActionStage::DOWN, kCtrlCode, 0}); 320 } 321 recv.push_back(KeyEvent {ActionStage::DOWN, kCode, opt.keyHoldMs_}); 322 if (kCtrlCode != KEYCODE_NONE) { 323 recv.push_back(KeyEvent {ActionStage::UP, kCtrlCode, 0}); 324 } 325 recv.push_back(KeyEvent {ActionStage::UP, kCode, 0}); 326 } 327 }; 328 329 /**Generic key actions without name and ctrl key.*/ 330 class AnonymousSingleKey final : public KeyAction { 331 public: AnonymousSingleKey(int32_t code)332 explicit AnonymousSingleKey(int32_t code) : code_(code) {}; 333 ComputeEvents(std::vector<KeyEvent> & recv,const UiOpArgs & opt)334 void ComputeEvents(std::vector<KeyEvent> &recv, const UiOpArgs &opt) const override 335 { 336 recv.push_back(KeyEvent {ActionStage::DOWN, code_, opt.keyHoldMs_}); 337 recv.push_back(KeyEvent {ActionStage::UP, code_, 0}); 338 } 339 340 private: 341 const int32_t code_; 342 }; 343 344 /**Generic Combinedkeys actions.*/ 345 class CombinedKeys final : public KeyAction { 346 public: CombinedKeys(int32_t codeZero,int32_t codeOne,int32_t codeTwo)347 CombinedKeys(int32_t codeZero, int32_t codeOne, int32_t codeTwo) 348 : codeZero_(codeZero), codeOne_(codeOne), codeTwo_(codeTwo) {}; 349 ComputeEvents(std::vector<KeyEvent> & recv,const UiOpArgs & opt)350 void ComputeEvents(std::vector<KeyEvent> &recv, const UiOpArgs &opt) const override 351 { 352 recv.push_back(KeyEvent {ActionStage::DOWN, codeZero_, 0}); 353 recv.push_back(KeyEvent {ActionStage::DOWN, codeOne_, 0}); 354 if (codeTwo_ != KEYCODE_NONE) { 355 recv.push_back(KeyEvent {ActionStage::DOWN, codeTwo_, opt.keyHoldMs_}); 356 } else { 357 recv.at(INDEX_ONE).holdMs_ = opt.keyHoldMs_; 358 } 359 recv.push_back(KeyEvent {ActionStage::UP, codeZero_, 0}); 360 recv.push_back(KeyEvent {ActionStage::UP, codeOne_, 0}); 361 if (codeTwo_ != KEYCODE_NONE) { 362 recv.push_back(KeyEvent {ActionStage::UP, codeTwo_, 0}); 363 } 364 } 365 366 private: 367 const int32_t codeZero_; 368 const int32_t codeOne_; 369 const int32_t codeTwo_; 370 }; 371 372 using Back = NamedPlainKey<KEYCODE_BACK>; 373 using Power = NamedPlainKey<KEYCODE_POWER>; 374 using Home = NamedPlainKey<KEYCODE_HOME>; 375 using Paste = NamedPlainKey<KEYCODE_V, KEYCODE_CTRL>; 376 using MoveToEnd = NamedPlainKey<KEYCODE_MOVETOEND>; 377 378 class MouseAction { 379 public: 380 /**Compute the mouse event sequence that are needed to implement this action. 381 * @param recv: the event seqence receiver. 382 * @param options the ui operation agruments. 383 * */ 384 virtual void Decompose(std::vector<MouseEvent> &recv, const UiOpArgs &opt) const = 0; 385 }; 386 387 class MouseMoveTo : public MouseAction { 388 public: MouseMoveTo(const Point & point)389 explicit MouseMoveTo(const Point &point) : point_(point) {}; 390 391 void Decompose(std::vector<MouseEvent> &recv, const UiOpArgs &opt) const override; 392 393 ~MouseMoveTo() = default; 394 395 private: 396 const Point point_; 397 }; 398 399 class MouseSwipe : public MouseAction { 400 public: MouseSwipe(TouchOp type,const Point & from,const Point & to)401 explicit MouseSwipe(TouchOp type, const Point &from, const Point &to) : type_(type), from_(from), to_(to) {}; 402 403 void Decompose(std::vector<MouseEvent> &recv, const UiOpArgs &opt) const override; 404 405 ~MouseSwipe() = default; 406 407 private: 408 const TouchOp type_; 409 const Point from_; 410 const Point to_; 411 }; 412 413 class MouseClick : public MouseAction { 414 public: MouseClick(TouchOp type,const Point & point,const MouseButton & button,int32_t & key1,int32_t & key2)415 explicit MouseClick(TouchOp type, const Point &point, const MouseButton &button, int32_t &key1, int32_t &key2) 416 : type_(type), point_(point), button_(button), key1_(key1), key2_(key2) {}; 417 418 void Decompose(std::vector<MouseEvent> &recv, const UiOpArgs &opt) const override; 419 420 ~MouseClick() = default; 421 422 private: 423 const TouchOp type_; 424 const Point point_; 425 const MouseButton button_; 426 const int32_t key1_; 427 const int32_t key2_; 428 }; 429 430 class MouseScroll : public MouseAction { 431 public: MouseScroll(const Point & point,int32_t scrollValue,int32_t key1,int32_t key2,uint32_t speed)432 explicit MouseScroll(const Point &point, int32_t scrollValue, int32_t key1, int32_t key2, uint32_t speed) 433 : point_(point), scrollValue_(scrollValue), key1_(key1), key2_(key2), speed_(speed) {}; 434 435 void Decompose(std::vector<MouseEvent> &recv, const UiOpArgs &opt) const override; 436 437 ~MouseScroll() = default; 438 439 private: 440 const Point point_; 441 const int32_t scrollValue_; 442 const int32_t key1_; 443 const int32_t key2_; 444 const uint32_t speed_; 445 }; 446 447 /** 448 * Base type of all atomic actions. 449 * */ 450 class GenericAtomicAction : public TouchAction { 451 public: GenericAtomicAction(const ActionStage stage,const Point point)452 explicit GenericAtomicAction(const ActionStage stage, const Point point) : stage_(stage), point_(point) {}; 453 454 void Decompose(PointerMatrix &recv, const UiOpArgs &options) const override; 455 456 ~GenericAtomicAction() = default; 457 458 private: 459 const ActionStage stage_; 460 const Point point_; 461 }; 462 463 /** 464 * Base type of all atomic mouse actions. 465 * */ 466 class GenericAtomicMouseAction : public MouseAction { 467 public: GenericAtomicMouseAction(const ActionStage stage,const Point point,const MouseButton btn)468 explicit GenericAtomicMouseAction(const ActionStage stage, const Point point, const MouseButton btn) 469 : stage_(stage), point_(point), btn_(btn) {}; 470 471 void Decompose(std::vector<MouseEvent> &recv, const UiOpArgs &options) const override; 472 473 ~GenericAtomicMouseAction() = default; 474 475 private: 476 const ActionStage stage_; 477 const Point point_; 478 const MouseButton btn_; 479 }; 480 } 481 482 #endif