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