• 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 "focus_scene_delegate.h"
25 #include "tree_manager.h"
26 #include "wukong_define.h"
27 
28 namespace OHOS {
29 namespace WuKong {
30 namespace {
31 const uint32_t PAGE_BACK_COUNT_MAX = 3;
32 const uint32_t LANUCH_APP_COUNT_MAX = 5;
33 
PrepareApp()34 void PrepareApp()
35 {
36 	// Wait for the App to be launched successfully
37     bool isFirstStartApp = WuKongUtil::GetInstance()->GetIsFirstStartAppFlag();
38     if (isFirstStartApp) {
39         usleep(THREE_SECOND);
40         WuKongUtil::GetInstance()->SetIsFirstStartAppFlag(false);
41     }
42 }
43 
HandleAllBundleStatus(const std::shared_ptr<ComponentParam> & componentPtr)44 void HandleAllBundleStatus(const std::shared_ptr<ComponentParam>& componentPtr)
45 {
46     componentPtr->isAllFinished_ = true;
47 	// confirm all bundle status.
48     std::vector<bool> bundleFinishList = componentPtr->bundleFinish_;
49     bool x = false;
50     if (std::any_of(bundleFinishList.begin(), bundleFinishList.end(), [x](int y) { return x == y; })) {
51         componentPtr->isAllFinished_ = false;
52     }
53 }
54 
LauncherApp(const std::string & bundleName)55 ErrCode LauncherApp(const std::string& bundleName)
56 {
57     auto appInput = InputFactory::GetInputAction(INPUTTYPE_APPSWITCHINPUT);
58     if (appInput == nullptr) {
59         ERROR_LOG("InputFactory::GetInputAction INPUTTYPE_APPSWITCHINPUT is null");
60         return OHOS::ERR_INVALID_VALUE;
61     }
62 
63     // launch app by AppSwitchInput function.
64     std::shared_ptr<AppSwitchParam> appSwitchParam = std::make_shared<AppSwitchParam>();
65     appSwitchParam->bundlename_ = bundleName;
66     std::shared_ptr<SpcialTestObject> sto = appSwitchParam;
67     auto result = appInput->OrderInput(sto);
68     if (result != OHOS::ERR_OK) {
69         ERROR_LOG("AppSwitchInput OrderInput failed");
70     }
71     return result;
72 }
73 
CheckLauncherApp(const std::shared_ptr<ComponentParam> & param)74 uint32_t CheckLauncherApp(const std::shared_ptr<ComponentParam>& param)
75 {
76     TRACK_LOG_STD();
77     std::vector<std::string> tempAllowList;
78     for (uint32_t i = 0; i < param->bundleName_.size(); i++) {
79         // do not launch app when bundle is running.
80         if (param->bundleRunning_[i] == true && param->bundleFinish_[i] == false) {
81             return i;
82         }
83         // launch app when the bundle is stop and not finish.
84         if (param->bundleRunning_[i] == false && param->bundleFinish_[i] == false) {
85             tempAllowList.clear();
86             tempAllowList.push_back(param->bundleName_[i]);
87             WuKongUtil::GetInstance()->SetTempAllowList(tempAllowList);
88             // launch app by AppSwitchInput function.
89             if (LauncherApp(param->bundleName_[i]) != OHOS::ERR_OK) {
90                 return param->bundleName_.size();
91             }
92             // init bundleRunning status to stop.
93             std::vector<bool> bundleRunning = param->bundleRunning_;
94             std::fill(bundleRunning.begin(), bundleRunning.end(), false);
95 
96             // set current launched bundle is running.
97             param->bundleRunning_[i] = true;
98             TRACK_LOG_STR("%s", param->toString().c_str());
99             TEST_RUN_LOG(param->bundleName_[i].c_str());
100             return i;
101         }
102     }
103     // not found bundle can be run, and return failed.
104     return param->bundleName_.size();
105 }
106 
CheckAbliltyFinished(const std::shared_ptr<AbilityTree> & abilityNode)107 bool CheckAbliltyFinished(const std::shared_ptr<AbilityTree>& abilityNode)
108 {
109     TRACK_LOG_STD();
110     bool abilityRunFinished = false;
111     if (abilityNode == nullptr) {
112         ERROR_LOG("abilityNode is nullptr");
113         return abilityRunFinished;
114     }
115     uint32_t allCount = abilityNode->GetAllComponentCount();
116     uint32_t inputCount = abilityNode->GetInputCount();
117     TRACK_LOG_STR("ability (%s) component count (%u), input count (%u)", abilityNode->GetBundleName().c_str(), allCount,
118                   inputCount);
119     if (inputCount >= allCount) {
120         abilityRunFinished = true;
121     }
122     TRACK_LOG_END();
123     return abilityRunFinished;
124 }
125 
CheckBundleFinished(const std::shared_ptr<WuKongTree> & parent)126 bool CheckBundleFinished(const std::shared_ptr<WuKongTree>& parent)
127 {
128     if (!CheckAbliltyFinished(std::static_pointer_cast<AbilityTree>(parent))) {
129         return false;
130     }
131     for (auto child : parent->GetChildren()) {
132         if (!CheckBundleFinished(std::static_pointer_cast<AbilityTree>(child))) {
133             return false;
134         }
135     }
136     return true;
137 }
138 
CheckInputFinished(const std::shared_ptr<ComponentParam> & param)139 bool CheckInputFinished(const std::shared_ptr<ComponentParam>& param)
140 {
141     TRACK_LOG_STD();
142     bool isFinished = false;
143     auto currentAbilityPtr = TreeManager::GetInstance()->GetCurrentAbility();
144     if (currentAbilityPtr == nullptr) {
145         ERROR_LOG("GetCurrentAbility abilityNode is nullptr");
146         return isFinished;
147     }
148 
149     // check app input event finished and set param is finished.
150     if (CheckBundleFinished(WuKongTree::GetRoot(currentAbilityPtr))) {
151         for (uint32_t i = 0; i < param->bundleRunning_.size(); i++) {
152             if (param->bundleRunning_[i] && param->bundleName_[i] == currentAbilityPtr->GetBundleName()) {
153                 param->bundleFinish_[i] = true;
154                 isFinished = true;
155                 break;
156             }
157         }
158     }
159 
160     TRACK_LOG_END();
161     return isFinished;
162 }
163 
JudgeBackResult(const std::shared_ptr<ComponentParam> & param,uint32_t launchIndex)164 ErrCode JudgeBackResult(const std::shared_ptr<ComponentParam>& param, uint32_t launchIndex)
165 {
166     TRACK_LOG_STD();
167     ErrCode result;
168     param->pageBack_[launchIndex]++;
169     TRACK_LOG_STR("back count: %d", param->pageBack_[launchIndex]);
170     if (param->pageBack_[launchIndex] > PAGE_BACK_COUNT_MAX) {
171         result = LauncherApp(param->bundleName_[launchIndex]);
172         if (result != OHOS::ERR_OK) {
173             return result;
174         }
175         param->pageBack_[launchIndex] = 0;
176         param->lanuchCount_[launchIndex]++;
177         TRACK_LOG_STR("lanuchCount_[%d] = %d", launchIndex, param->lanuchCount_[launchIndex]);
178         if (param->lanuchCount_[launchIndex] > LANUCH_APP_COUNT_MAX) {
179             param->bundleFinish_[launchIndex] = true;
180             ERROR_LOG("Failed to launch the app five times in a row and exit");
181             param->lanuchCount_[launchIndex] = 0;
182             return OHOS::ERR_INVALID_VALUE;
183         }
184     } else {
185         result = ComponentManager::GetInstance()->BackToPrePage();
186     }
187     TRACK_LOG_END();
188     return result;
189 }
190 }  // namespace
ComponentInput()191 ComponentInput::ComponentInput() : InputAction()
192 {
193 }
194 
~ComponentInput()195 ComponentInput::~ComponentInput()
196 {
197 }
198 
OrderInput(const std::shared_ptr<SpcialTestObject> & specialTestObject)199 ErrCode ComponentInput::OrderInput(const std::shared_ptr<SpcialTestObject>& specialTestObject)
200 {
201     auto componentPtr = std::static_pointer_cast<ComponentParam>(specialTestObject);
202     if (componentPtr == nullptr) {
203         ERROR_LOG("specialTestObject param is null");
204         return OHOS::ERR_INVALID_VALUE;
205     }
206     // launch app and check if app has been started
207     uint32_t launchIndex = CheckLauncherApp(componentPtr);
208     if (launchIndex >= componentPtr->bundleName_.size()) {
209         ERROR_LOG("launcher app failed, and stop run test");
210         componentPtr->isAllFinished_ = true;
211         ERROR_LOG(componentPtr->toString().c_str());
212         return OHOS::ERR_INVALID_VALUE;
213     }
214     auto treemanager = TreeManager::GetInstance();
215     auto delegate = SceneDelegate::GetInstance();
216     PrepareApp();
217     // update component information
218     ErrCode result = treemanager->UpdateComponentInfo();
219     DEBUG_LOG_STR("update componentinfo result (%d)", result);
220     if (result == OHOS::ERR_OK) {
221         // choose scene and set valid components
222         result = delegate->ChooseScene(false);
223         if (result != OHOS::ERR_OK) {
224             ERROR_LOG("choose scene failed");
225             return result;
226         }
227         // judge if is neccessnary to back to previous page
228         if (delegate->IsBackToPrePage()) {
229             result = JudgeBackResult(componentPtr, launchIndex);
230             if (result != OHOS::ERR_OK) {
231                 return result;
232             }
233         } else {
234             // get the component from tree manager to input action
235             auto elementInfo = treemanager->GetElementInfoByOrder();
236             if (elementInfo == nullptr) {
237                 ERROR_LOG("elementinfo is nullptr");
238                 return OHOS::ERR_INVALID_VALUE;
239             }
240             // get the actions of component
241             int actionType = JudgeComponentType(*(elementInfo.get()));
242             if (actionType == Accessibility::ACCESSIBILITY_ACTION_INVALID) {
243                 actionType = OHOS::Accessibility::ACCESSIBILITY_ACTION_CLICK;
244             }
245             // input action to component
246             result = ComponentManager::GetInstance()->ComponentEventInput(*(elementInfo.get()), actionType);
247             if (result == OHOS::ERR_OK) {
248                 // record index of inputted component
249                 treemanager->SetInputcomponentIndex(actionType);
250                 componentPtr->pageBack_[launchIndex] = 0;
251                 componentPtr->lanuchCount_[launchIndex] = 0;
252                 std::shared_ptr<ComponmentInputMsg> componentInputMsg = std::make_shared<ComponmentInputMsg>();
253                 componentInputMsg->pageComponments = delegate->GetComponentTypeList();
254                 componentInputMsg->pageId_ = delegate->GetCurrentPageId();
255                 componentInputMsg->componmentType_ = elementInfo->GetComponentType();
256                 Report::GetInstance()->SyncInputInfo(componentInputMsg);
257             }
258         }
259     }
260     // check current bundle finished state.
261     if (CheckInputFinished(componentPtr)) {
262         HandleAllBundleStatus(componentPtr);
263     }
264     DEBUG_LOG_STR("component order input result (%d)", result);
265     return result;
266 }
267 
RandomInput()268 ErrCode ComponentInput::RandomInput()
269 {
270     auto treemanager = TreeManager::GetInstance();
271     ErrCode result = treemanager->UpdateComponentInfo();
272     DEBUG_LOG_STR("update componentinfo result (%d)", result);
273     if (result == OHOS::ERR_OK) {
274         auto delegate = SceneDelegate::GetInstance();
275         delegate->ChooseScene(true);
276         auto componentInfos = treemanager->GetActiveElementInfos();
277         auto wComponentInfos = treemanager->GetActiveComponentInfos();
278         DEBUG_LOG_STR("component list size (%d)", componentInfos.size());
279         DEBUG_LOG_STR("back: %d", delegate->IsBackToPrePage());
280         if (delegate->IsBackToPrePage()) {
281             DEBUG_LOG("componentInputBranch1");
282             result = ComponentManager::GetInstance()->BackToPrePage();
283             DEBUG_LOG("componentInputBranch1 end");
284         } else if (componentInfos.size() > 0) {
285             DEBUG_LOG("componentInputBranch2");
286             uint32_t index = (uint32_t)(rand()) % componentInfos.size();
287             DEBUG_LOG_STR("component input index (%d), NodeId (%d)", index,
288                 wComponentInfos[index]->GetNodeId());
289             int actionType = JudgeComponentType(*(componentInfos[index].get()));
290             if (actionType == Accessibility::ACCESSIBILITY_ACTION_INVALID) {
291                 actionType = OHOS::Accessibility::ACCESSIBILITY_ACTION_CLICK;
292             }
293             DEBUG_LOG("componentInputBranch2 before input");
294             result = ComponentManager::GetInstance()->ComponentEventInput(*(componentInfos[index].get()), actionType);
295             DEBUG_LOG("componentInputBranch2 after input");
296             if (result == OHOS::ERR_OK) {
297                 treemanager->SetInputcomponentIndex(actionType, index);
298                 std::shared_ptr<ComponmentInputMsg> componentInputMsg = std::make_shared<ComponmentInputMsg>();
299                 DEBUG_LOG("componentInputBranch2 after componentInputMsg");
300                 componentInputMsg->pageComponments = delegate->GetComponentTypeList();
301                 componentInputMsg->pageId_ = delegate->GetCurrentPageId();
302                 componentInputMsg->componmentType_ = componentInfos[index]->GetComponentType();
303                 DEBUG_LOG("componentInputBranch2 before SyncInputInfo");
304                 Report::GetInstance()->SyncInputInfo(componentInputMsg);
305                 DEBUG_LOG("componentInputBranch2 after SyncInputInfo");
306             }
307             DEBUG_LOG("componentInputBranch2 end");
308         } else {
309             DEBUG_LOG("componentInputBranch3");
310             ERROR_LOG("component list is null");
311             result = OHOS::ERR_NO_INIT;
312         }
313     }
314     DEBUG_LOG_STR("component random input result (%d)", result);
315     return result;
316 }
317 
FocusInput(bool shouldScreenCap)318 ErrCode ComponentInput::FocusInput(bool shouldScreenCap)
319 {
320     auto treemanager = TreeManager::GetInstance();
321     ErrCode result = treemanager->UpdateComponentInfo();
322     auto componentManager = ComponentManager::GetInstance();
323     DEBUG_LOG_STR("update componentinfo result (%d)", result);
324     if (result == OHOS::ERR_OK) {
325         auto delegate = FocusSceneDelegate::GetInstance();
326         delegate->ChooseScene(true);
327         auto componentInfos = treemanager->GetActiveElementInfos();
328         auto wComponentInfos = treemanager->GetActiveComponentInfos();
329         DEBUG_LOG_STR("component list size (%d)", componentInfos.size());
330         DEBUG_LOG_STR("back: %d", delegate->IsBackToPrePage());
331         if (delegate->IsBackToPrePage()) {
332             result = componentManager->BackToPrePage();
333         } else if (componentInfos.size() > 0) {
334             uint32_t index = ChooseRightComponentIndex(componentInfos, wComponentInfos, shouldScreenCap);
335             DEBUG_LOG_STR("after ChooseRightComponentIndex (%d), comp cnt (%d)index (%d)",
336                           componentInfos.size(), wComponentInfos.size(), index);
337             auto componentinfo = componentInfos[index];
338             DEBUG_LOG_STR("component input index (%d), NodeId (%d)", index,
339                           wComponentInfos[index]->GetNodeId());
340             int actionType = JudgeComponentType(*(componentinfo.get()));
341             if (actionType == Accessibility::ACCESSIBILITY_ACTION_INVALID) {
342                 actionType = OHOS::Accessibility::ACCESSIBILITY_ACTION_CLICK;
343             }
344 
345             result = componentManager->ComponentEventInput(*(componentinfo.get()), actionType);
346             DEBUG_LOG_STR("after ChooseRightComponentIndex3 (%d), index (%d)", componentInfos.size(), index);
347             DEBUG_LOG_STR("action type: %d, sequence input: %d", actionType, result);
348             if (result == OHOS::ERR_OK) {
349                 treemanager->SetInputcomponentIndex(actionType, index);
350                 std::shared_ptr<ComponmentInputMsg> componentInputMsg = std::make_shared<ComponmentInputMsg>();
351                 componentInputMsg->pageComponments = delegate->GetComponentTypeList();
352                 componentInputMsg->componmentType_ = componentinfo->GetComponentType();
353                 componentInputMsg->pagePath_ = componentinfo->GetPagePath();
354                 componentInputMsg->startX_ = componentManager->GetStartX();
355                 componentInputMsg->startY_ = componentManager->GetStartY();
356                 componentInputMsg->endX_ = componentManager->GetEndX();
357                 componentInputMsg->endY_ = componentManager->GetEndY();
358                 componentInputMsg->content_ = componentinfo->GetContent();
359                 TreeManager::GetInstance()->SetComponentType(componentinfo->GetComponentType());
360                 Report::GetInstance()->SyncInputInfo(componentInputMsg);
361             }
362         } else {
363             ERROR_LOG("component list is null");
364             result = OHOS::ERR_NO_INIT;
365         }
366     }
367     DEBUG_LOG_STR("component focus input result (%d)", result);
368     return result;
369 }
370 
ChooseRightComponentIndex(std::vector<std::shared_ptr<OHOS::Accessibility::AccessibilityElementInfo>> & componentInfos,std::vector<std::shared_ptr<ComponentTree>> & wComponentInfos,bool shouldScreenCap)371 uint32_t ComponentInput::ChooseRightComponentIndex(
372     std::vector<std::shared_ptr<OHOS::Accessibility::AccessibilityElementInfo>> &componentInfos,
373     std::vector<std::shared_ptr<ComponentTree>> &wComponentInfos, bool shouldScreenCap)
374 {
375     auto treemanager = TreeManager::GetInstance();
376     uint32_t index;
377     if (treemanager->HasDialog()) {
378         DEBUG_LOG("Has dialog");
379         std::vector<uint32_t> indexList;
380         int count = wComponentInfos.size();
381         for (int i = 0; i < count; i++) {
382             auto it = wComponentInfos[i];
383             if (it->IsTopComponent()) {
384                 indexList.push_back(i);
385             }
386         }
387         uint32_t randIndex = (std::uint32_t) rand() % indexList.size();
388         index = indexList[randIndex];
389     } else {
390         DEBUG_LOG("no dialog");
391         uint32_t randIndex = treemanager->FindInputComponentIndex(shouldScreenCap);
392         DEBUG_LOG_STR("ComponentInput::FocusInput START: randomIndex: %u", randIndex);
393         index = randIndex % componentInfos.size();
394     }
395     return index;
396 }
397 
GetInputInfo()398 ErrCode ComponentInput::GetInputInfo()
399 {
400     return OHOS::ERR_OK;
401 }
402 
JudgeComponentType(OHOS::Accessibility::AccessibilityElementInfo & elementInfo)403 int ComponentInput::JudgeComponentType(OHOS::Accessibility::AccessibilityElementInfo& elementInfo)
404 {
405     int actionType;
406     TRACK_LOG_STD();
407     // get action list of component
408     std::vector<OHOS::Accessibility::AccessibleAction> actionlist = elementInfo.GetActionList();
409     if (actionlist.empty()) {
410         std::string componentType = elementInfo.GetComponentType();
411         TRACK_LOG_STR("component type: %s", componentType.c_str());
412         if (componentType == "TextInput" || componentType == "TextArea" || componentType == "Text") {
413             actionType = Accessibility::ACCESSIBILITY_ACTION_SET_TEXT;
414         } else if (componentType == "GridContainer") {
415             actionType = Accessibility::ACCESSIBILITY_ACTION_SCROLL_FORWARD;
416         } else if (componentType == "Slider") {
417             actionType = COMPONENT_LEFT_SWAP;
418         } else {
419             actionType = Accessibility::ACCESSIBILITY_ACTION_CLICK;
420         }
421     } else {
422         TRACK_LOG_STR("action list size: %u", actionlist.size());
423         auto it = actionlist[(uint32_t)(rand()) % actionlist.size()];
424         actionType = (int)it.GetActionType();
425     }
426     TRACK_LOG_STR("action type: %d", actionType);
427     return actionType;
428 }
429 }  // namespace WuKong
430 }  // namespace OHOS
431