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 <string> 19 #include <vector> 20 #include <map> 21 #include <set> 22 #include "ui_model.h" 23 #include "extern_api.h" 24 25 namespace OHOS::uitest { 26 // frequently used keys. 27 constexpr int32_t KEYCODE_NONE = 0; 28 constexpr int32_t KEYCODE_BACK = 2; 29 constexpr int32_t KEYCODE_CTRL = 2072; 30 constexpr int32_t KEYCODE_V = 2038; 31 constexpr char KEYNAME_BACK[] = "Back"; 32 constexpr char KEYNAME_PASTE[] = "Paste"; 33 34 enum ActionStage : uint8_t { 35 DOWN = 0, MOVE = 1, UP = 2 36 }; 37 38 struct TouchEvent { 39 ActionStage stage_; 40 Point point_; 41 uint32_t downTimeOffsetMs_; 42 uint32_t holdMs_; 43 uint32_t flags_; 44 }; 45 46 struct KeyEvent { 47 ActionStage stage_; 48 int32_t code_; 49 uint32_t holdMs_; 50 }; 51 52 /** 53 * Options of the UI manipulation. 54 **/ 55 class UiDriveOptions : public ExternApi<TypeId::OPTIONS> { 56 public: 57 uint32_t clickHoldMs_ = 200; 58 uint32_t longClickHoldMs_ = 1500; 59 uint32_t doubleClickIntervalMs_ = 200; 60 uint32_t keyHoldMs_ = 100; 61 uint32_t swipeVelocityPps_ = 600; 62 uint32_t uiSteadyThresholdMs_ = 1000; 63 uint32_t waitUiSteadyMaxMs_ = 3000; 64 65 void WriteIntoParcel(nlohmann::json &data) const override; 66 67 void ReadFromParcel(const nlohmann::json &data) override; 68 }; 69 70 /** 71 * Base type of all raw pointer click actions. 72 **/ 73 class GenericClick { 74 public: GenericClick(PointerOp type)75 explicit GenericClick(PointerOp type) : type_(type) {}; 76 77 /**Compute the touch event sequence that are needed to implement this action. 78 * @param point: the click location. 79 * */ 80 void Decompose(std::vector<TouchEvent> &recv, const Point &point, const UiDriveOptions &options) const; 81 82 ~GenericClick() = default; 83 84 private: 85 const PointerOp type_; 86 }; 87 88 /** 89 * Base type of all raw pointer swipe actions. 90 **/ 91 class GenericSwipe { 92 public: GenericSwipe(PointerOp type)93 explicit GenericSwipe(PointerOp type) : type_(type) {}; 94 95 /**Compute the touch event sequence that are needed to implement this action. 96 * @param fromPoint: the swipe start point. 97 * @param toPoint: the swipe end point. 98 * */ 99 void Decompose(std::vector<TouchEvent> &recv, const Point &fromPoint, const Point &toPoint, 100 const UiDriveOptions &options) const; 101 102 ~GenericSwipe() = default; 103 104 private: 105 const PointerOp type_; 106 }; 107 108 /** 109 * Base type of all key actions. 110 * */ 111 class KeyAction { 112 public: 113 /**Compute the key event sequence that are needed to implement this action.*/ 114 virtual void ComputeEvents(std::vector<KeyEvent> &recv, const UiDriveOptions &options) const = 0; 115 116 virtual ~KeyAction() = default; 117 118 /**Describes this key action.*/ 119 virtual std::string Describe() const = 0; 120 }; 121 122 /**Base type of named single-key actions with at most 1 ctrl key.*/ 123 template<CStr kName, uint32_t kCode, uint32_t kCtrlCode = KEYCODE_NONE> 124 class NamedPlainKey : public KeyAction { 125 public: 126 explicit NamedPlainKey() = default; 127 ComputeEvents(std::vector<KeyEvent> & recv,const UiDriveOptions & opt)128 void ComputeEvents(std::vector<KeyEvent> &recv, const UiDriveOptions &opt) const override 129 { 130 if (kCtrlCode != KEYCODE_NONE) { 131 recv.push_back(KeyEvent {ActionStage::DOWN, kCtrlCode, 0}); 132 } 133 recv.push_back(KeyEvent {ActionStage::DOWN, kCode, opt.keyHoldMs_}); 134 recv.push_back(KeyEvent {ActionStage::UP, kCode, 0}); 135 if (kCtrlCode != KEYCODE_NONE) { 136 recv.push_back(KeyEvent {ActionStage::UP, kCtrlCode, 0}); 137 } 138 } 139 Describe()140 std::string Describe() const override 141 { 142 if constexpr (kName != nullptr) { 143 return kName; 144 } 145 std::string desc = std::string("key_") + std::to_string(kCode); 146 if constexpr (kCtrlCode != KEYCODE_NONE) { 147 desc = desc + "(ctrlKey=" + std::to_string(kCtrlCode) + ")"; 148 } 149 return desc; 150 } 151 }; 152 153 /**Generic key actions without name and ctrl key.*/ 154 class AnonymousSingleKey final : public KeyAction { 155 public: AnonymousSingleKey(int32_t code)156 explicit AnonymousSingleKey(int32_t code) : code_(code) {}; 157 ComputeEvents(std::vector<KeyEvent> & recv,const UiDriveOptions & opt)158 void ComputeEvents(std::vector<KeyEvent> &recv, const UiDriveOptions &opt) const override 159 { 160 recv.push_back(KeyEvent {ActionStage::DOWN, code_, opt.keyHoldMs_}); 161 recv.push_back(KeyEvent {ActionStage::UP, code_, 0}); 162 } 163 Describe()164 std::string Describe() const override 165 { 166 return std::string("key_") + std::to_string(code_); 167 } 168 169 private: 170 const int32_t code_; 171 }; 172 173 using Back = NamedPlainKey<KEYNAME_BACK, KEYCODE_BACK>; 174 using Paste = NamedPlainKey<KEYNAME_PASTE, KEYCODE_V, KEYCODE_CTRL>; 175 } 176 177 #endif