• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "component_input.h"
17 
18 #include "component_manager.h"
19 #include "input_factory.h"
20 #include "input_manager.h"
21 #include "input_msg_object.h"
22 #include "report.h"
23 #include "scene_delegate.h"
24 #include "tree_manager.h"
25 #include "wukong_define.h"
26 
27 namespace OHOS {
28 namespace WuKong {
29 namespace {
30 const uint32_t PAGE_BACK_COUNT_MAX = 3;
31 const uint32_t LANUCH_APP_COUNT_MAX = 5;
32 
LauncherApp(const std::string & bundleName)33 ErrCode LauncherApp(const std::string& bundleName)
34 {
35     auto appInput = InputFactory::GetInputAction(INPUTTYPE_APPSWITCHINPUT);
36     if (appInput == nullptr) {
37         ERROR_LOG("InputFactory::GetInputAction INPUTTYPE_APPSWITCHINPUT is null");
38         return OHOS::ERR_INVALID_VALUE;
39     }
40 
41     // launch app by AppSwitchInput function.
42     std::shared_ptr<AppSwitchParam> appSwitchParam = std::make_shared<AppSwitchParam>();
43     appSwitchParam->bundlename_ = bundleName;
44     std::shared_ptr<SpcialTestObject> sto = appSwitchParam;
45     auto result = appInput->OrderInput(sto);
46     if (result != OHOS::ERR_OK) {
47         ERROR_LOG("AppSwitchInput OrderInput failed");
48     }
49     return result;
50 }
51 
CheckLauncherApp(const std::shared_ptr<ComponentParam> & param)52 uint32_t CheckLauncherApp(const std::shared_ptr<ComponentParam>& param)
53 {
54     TRACK_LOG_STD();
55     std::vector<std::string> tempAllowList;
56     for (uint32_t i = 0; i < param->bundleName_.size(); i++) {
57         // do not launch app when bundle is running.
58         if (param->bundleRunning_[i] == true && param->bundleFinish_[i] == false) {
59             return i;
60         }
61         // launch app when the bundle is stop and not finish.
62         if (param->bundleRunning_[i] == false && param->bundleFinish_[i] == false) {
63             tempAllowList.clear();
64             tempAllowList.push_back(param->bundleName_[i]);
65             WuKongUtil::GetInstance()->SetTempAllowList(tempAllowList);
66             // launch app by AppSwitchInput function.
67             if (LauncherApp(param->bundleName_[i]) != OHOS::ERR_OK) {
68                 return param->bundleName_.size();
69             }
70             // init bundleRunning status to stop.
71             std::vector<bool> bundleRunning = param->bundleRunning_;
72             std::fill(bundleRunning.begin(), bundleRunning.end(), false);
73 
74             // set current launched bundle is running.
75             param->bundleRunning_[i] = true;
76             TRACK_LOG_STR("%s", param->toString().c_str());
77             TEST_RUN_LOG(param->bundleName_[i].c_str());
78             return i;
79         }
80     }
81     // not found bundle can be run, and return failed.
82     return param->bundleName_.size();
83 }
84 
CheckAbliltyFinished(const std::shared_ptr<AbilityTree> & abilityNode)85 bool CheckAbliltyFinished(const std::shared_ptr<AbilityTree>& abilityNode)
86 {
87     TRACK_LOG_STD();
88     bool abilityRunFinished = false;
89     if (abilityNode == nullptr) {
90         ERROR_LOG("abilityNode is nullptr");
91         return abilityRunFinished;
92     }
93     uint32_t allCount = abilityNode->GetAllComponentCount();
94     uint32_t inputCount = abilityNode->GetInputCount();
95     TRACK_LOG_STR("ability (%s) component count (%u), input count (%u)", abilityNode->GetBundleName().c_str(), allCount,
96                   inputCount);
97     if (inputCount >= allCount) {
98         abilityRunFinished = true;
99     }
100     TRACK_LOG_END();
101     return abilityRunFinished;
102 }
103 
CheckBundleFinished(const std::shared_ptr<WuKongTree> & parent)104 bool CheckBundleFinished(const std::shared_ptr<WuKongTree>& parent)
105 {
106     if (!CheckAbliltyFinished(std::static_pointer_cast<AbilityTree>(parent))) {
107         return false;
108     }
109     for (auto child : parent->GetChildren()) {
110         if (!CheckBundleFinished(std::static_pointer_cast<AbilityTree>(child))) {
111             return false;
112         }
113     }
114     return true;
115 }
116 
CheckInputFinished(const std::shared_ptr<ComponentParam> & param)117 bool CheckInputFinished(const std::shared_ptr<ComponentParam>& param)
118 {
119     TRACK_LOG_STD();
120     bool isFinished = false;
121     auto currentAbilityPtr = TreeManager::GetInstance()->GetCurrentAbility();
122     if (currentAbilityPtr == nullptr) {
123         ERROR_LOG("GetCurrentAbility abilityNode is nullptr");
124         return isFinished;
125     }
126 
127     // check app input event finished and set param is finished.
128     if (CheckBundleFinished(WuKongTree::GetRoot(currentAbilityPtr))) {
129         for (uint32_t i = 0; i < param->bundleRunning_.size(); i++) {
130             if (param->bundleRunning_[i] && param->bundleName_[i] == currentAbilityPtr->GetBundleName()) {
131                 param->bundleFinish_[i] = true;
132                 isFinished = true;
133                 break;
134             }
135         }
136     }
137 
138     TRACK_LOG_END();
139     return isFinished;
140 }
141 
JudgeBackResult(const std::shared_ptr<ComponentParam> & param,uint32_t launchIndex)142 ErrCode JudgeBackResult(const std::shared_ptr<ComponentParam>& param, uint32_t launchIndex)
143 {
144     TRACK_LOG_STD();
145     ErrCode result;
146     param->pageBack_[launchIndex]++;
147     TRACK_LOG_STR("back count: %d", param->pageBack_[launchIndex]);
148     if (param->pageBack_[launchIndex] > PAGE_BACK_COUNT_MAX) {
149         result = LauncherApp(param->bundleName_[launchIndex]);
150         if (result != OHOS::ERR_OK) {
151             return result;
152         }
153         param->pageBack_[launchIndex] = 0;
154         param->lanuchCount_[launchIndex]++;
155         TRACK_LOG_STR("lanuchCount_[%d] = %d", launchIndex, param->lanuchCount_[launchIndex]);
156         if (param->lanuchCount_[launchIndex] > LANUCH_APP_COUNT_MAX) {
157             param->bundleFinish_[launchIndex] = true;
158             ERROR_LOG("Failed to launch the app five times in a row and exit");
159             param->lanuchCount_[launchIndex] = 0;
160             return OHOS::ERR_INVALID_VALUE;
161         }
162     } else {
163         result = ComponentManager::GetInstance()->BackToPrePage();
164     }
165     TRACK_LOG_END();
166     return result;
167 }
168 }  // namespace
ComponentInput()169 ComponentInput::ComponentInput() : InputAction()
170 {
171 }
172 
~ComponentInput()173 ComponentInput::~ComponentInput()
174 {
175 }
176 
OrderInput(const std::shared_ptr<SpcialTestObject> & specialTestObject)177 ErrCode ComponentInput::OrderInput(const std::shared_ptr<SpcialTestObject>& specialTestObject)
178 {
179     auto componentPtr = std::static_pointer_cast<ComponentParam>(specialTestObject);
180     if (componentPtr == nullptr) {
181         ERROR_LOG("specialTestObject param is null");
182         return OHOS::ERR_INVALID_VALUE;
183     }
184     // launch app and check if app has been started
185     uint32_t launchIndex = CheckLauncherApp(componentPtr);
186     if (launchIndex >= componentPtr->bundleName_.size()) {
187         ERROR_LOG("launcher app failed, and stop run test");
188         componentPtr->isAllFinished_ = true;
189         ERROR_LOG(componentPtr->toString().c_str());
190         return OHOS::ERR_INVALID_VALUE;
191     }
192     auto treemanager = TreeManager::GetInstance();
193     auto delegate = SceneDelegate::GetInstance();
194     // update component information
195     ErrCode result = treemanager->UpdateComponentInfo();
196     DEBUG_LOG_STR("update componentinfo result (%d)", result);
197     if (result == OHOS::ERR_OK) {
198         // choose scene and set valid components
199         result = delegate->ChooseScene(false);
200         if (result != OHOS::ERR_OK) {
201             ERROR_LOG("choose scene failed");
202             return result;
203         }
204         // judge if is neccessnary to back to previous page
205         if (delegate->IsBackToPrePage()) {
206             result = JudgeBackResult(componentPtr, launchIndex);
207             if (result != OHOS::ERR_OK) {
208                 return result;
209             }
210         } else {
211             // get the component from tree manager to input action
212             auto elementInfo = treemanager->GetElementInfoByOrder();
213             if (elementInfo == nullptr) {
214                 ERROR_LOG("elementinfo is nullptr");
215                 return OHOS::ERR_INVALID_VALUE;
216             }
217             // get the actions of component
218             int actionType = JudgeComponentType(*(elementInfo.get()));
219             if (actionType == Accessibility::ACCESSIBILITY_ACTION_INVALID) {
220                 actionType = OHOS::Accessibility::ACCESSIBILITY_ACTION_CLICK;
221             }
222             // input action to component
223             result = ComponentManager::GetInstance()->ComponentEventInput(*(elementInfo.get()), actionType);
224             if (result == OHOS::ERR_OK) {
225                 // record index of inputted component
226                 treemanager->SetInputcomponentIndex(actionType);
227                 componentPtr->pageBack_[launchIndex] = 0;
228                 componentPtr->lanuchCount_[launchIndex] = 0;
229                 std::shared_ptr<ComponmentInputMsg> componentInputMsg = std::make_shared<ComponmentInputMsg>();
230                 componentInputMsg->pageComponments = delegate->GetComponentTypeList();
231                 componentInputMsg->pageId_ = delegate->GetCurrentPageId();
232                 componentInputMsg->componmentType_ = elementInfo->GetComponentType();
233                 Report::GetInstance()->SyncInputInfo(componentInputMsg);
234             }
235         }
236     }
237     // check current bundle finished state.
238     if (CheckInputFinished(componentPtr)) {
239         componentPtr->isAllFinished_ = true;
240         // confirm all bundle status.
241         std::vector<bool> bundleFinishList = componentPtr->bundleFinish_;
242         bool x = false;
243         if (std::any_of(bundleFinishList.begin(), bundleFinishList.end(), [x](int y) { return x == y; })) {
244             componentPtr->isAllFinished_ = false;
245         }
246     }
247     DEBUG_LOG_STR("component order input result (%d)", result);
248     return result;
249 }
250 
RandomInput()251 ErrCode ComponentInput::RandomInput()
252 {
253     auto treemanager = TreeManager::GetInstance();
254     ErrCode result = treemanager->UpdateComponentInfo();
255     DEBUG_LOG_STR("update componentinfo result (%d)", result);
256     if (result == OHOS::ERR_OK) {
257         auto delegate = SceneDelegate::GetInstance();
258         delegate->ChooseScene(true);
259         auto componentInfos = treemanager->GetActiveElementInfos();
260         DEBUG_LOG_STR("component list size (%d)", componentInfos.size());
261         DEBUG_LOG_STR("back: %d", delegate->IsBackToPrePage());
262         if (delegate->IsBackToPrePage()) {
263             result = ComponentManager::GetInstance()->BackToPrePage();
264         } else if (componentInfos.size() > 0) {
265             uint32_t index = (uint32_t)(rand()) % componentInfos.size();
266             DEBUG_LOG_STR("component input index (%d)", index);
267             int actionType = JudgeComponentType(*(componentInfos[index].get()));
268             if (actionType == Accessibility::ACCESSIBILITY_ACTION_INVALID) {
269                 actionType = OHOS::Accessibility::ACCESSIBILITY_ACTION_CLICK;
270             }
271             result = ComponentManager::GetInstance()->ComponentEventInput(*(componentInfos[index].get()), actionType);
272             if (result == OHOS::ERR_OK) {
273                 treemanager->SetInputcomponentIndex(actionType, index);
274                 std::shared_ptr<ComponmentInputMsg> componentInputMsg = std::make_shared<ComponmentInputMsg>();
275                 componentInputMsg->pageComponments = delegate->GetComponentTypeList();
276                 componentInputMsg->pageId_ = delegate->GetCurrentPageId();
277                 componentInputMsg->componmentType_ = componentInfos[index]->GetComponentType();
278                 Report::GetInstance()->SyncInputInfo(componentInputMsg);
279             }
280         } else {
281             ERROR_LOG("component list is null");
282             result = OHOS::ERR_NO_INIT;
283         }
284     }
285     DEBUG_LOG_STR("component random input result (%d)", result);
286     return result;
287 }
288 
GetInputInfo()289 ErrCode ComponentInput::GetInputInfo()
290 {
291     return OHOS::ERR_OK;
292 }
293 
JudgeComponentType(OHOS::Accessibility::AccessibilityElementInfo & elementInfo)294 int ComponentInput::JudgeComponentType(OHOS::Accessibility::AccessibilityElementInfo& elementInfo)
295 {
296     int actionType;
297     TRACK_LOG_STD();
298     // get action list of component
299     std::vector<OHOS::Accessibility::AccessibleAction> actionlist = elementInfo.GetActionList();
300     if (actionlist.empty()) {
301         std::string componentType = elementInfo.GetComponentType();
302         TRACK_LOG_STR("component type: %s", componentType.c_str());
303         if (componentType == "TextInput" || componentType == "TextArea" || componentType == "Text") {
304             actionType = Accessibility::ACCESSIBILITY_ACTION_SET_TEXT;
305         } else if (componentType == "GridContainer") {
306             actionType = Accessibility::ACCESSIBILITY_ACTION_SCROLL_FORWARD;
307         } else if (componentType == "Slider") {
308             actionType = COMPONENT_LEFT_SWAP;
309         } else {
310             actionType = Accessibility::ACCESSIBILITY_ACTION_CLICK;
311         }
312     } else {
313         TRACK_LOG_STR("action list size: %u", actionlist.size());
314         auto it = actionlist[(uint32_t)(rand()) % actionlist.size()];
315         actionType = (int)it.GetActionType();
316     }
317     TRACK_LOG_STR("action type: %d", actionType);
318     return actionType;
319 }
320 }  // namespace WuKong
321 }  // namespace OHOS
322