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#include "tree_manager.h"
16
17#include "accessibility_ui_test_ability.h"
18#include "ability_manager_client.h"
19#include "component_manager.h"
20#include "touch_input.h"
21#include "report.h"
22#include "wukong_util.h"
23
24namespace OHOS {
25namespace WuKong {
26namespace {
27const int TWOSECONDS = 2000000;
28const int MAXRECURSION = 5000;
29class ComponentManagerMonitor : public ComponentManagerListener {
30    void OnStatusUpdated(ComponentStatus status) override
31    {
32    }
33    void OnScreenUpdated() override
34    {
35    }
36    void OnPermissionScreenShown() override
37    {
38    }
39};
40}  // namespace
41
42TreeManager::TreeManager() : isUpdateComponentFinished_(false), isNewAbility_(false)
43{
44}
45TreeManager::~TreeManager()
46{
47    TRACK_LOG_STD();
48}
49
50bool TreeManager::RecursGetChildElementInfo(
51    const std::shared_ptr<OHOS::Accessibility::AccessibilityElementInfo>& parent,
52    const std::shared_ptr<ComponentTree>& componentParent)
53{
54    auto res = Accessibility::RET_OK;
55    if (componentParent == nullptr) {
56        ERROR_LOG("tree parent is null!");
57        return false;
58    }
59    // identify whether has top components
60    if (parent->GetComponentType() == "Dialog") {
61        hasDialog_ = true;
62        dialogComponent_ = componentParent;
63    }
64    for (int32_t i = 0; i < parent->GetChildCount(); i++) {
65        auto elementChild = std::make_shared<OHOS::Accessibility::AccessibilityElementInfo>();
66        // Get child AccessibilityElementInfo from Accessibility.
67        res = OHOS::Accessibility::AccessibilityUITestAbility::GetInstance()->GetChildElementInfo(
68            i, *(parent.get()), *(elementChild.get()));
69        if (res != Accessibility::RET_OK) {
70            ERROR_LOG_STR("GetChildElementInfo failed! Errorcode : (%d) ", res);
71            return false;
72        }
73        TRACK_LOG_STR("GetChildElementInfo child ID (%d), child count (%d), Type (%s)",
74                      elementChild->GetAccessibilityId(), elementChild->GetChildCount(),
75                      elementChild->GetComponentType().c_str());
76
77        // save child AccessibilityElementInfo.
78        newElementInfoList_.push_back(elementChild);
79
80        // Generate ComponentTree.
81        std::shared_ptr<ComponentTree> componentChild = std::make_shared<ComponentTree>();
82        componentChild->SetIndex(newElementInfoList_.size() - 1);
83        TRACK_LOG_STR("componentChild->GetIndex() is (%d)", componentChild->GetIndex());
84        if (MAXRECURSION < componentChild->GetIndex()) {
85            auto elementName = AAFwk::AbilityManagerClient::GetInstance()->GetTopAbility();
86            auto curBundleName = elementName.GetBundleName();
87            ERROR_LOG("The recursion GetChildElementInfo is too deep. Please check the application.");
88            ERROR_LOG_STR("Now BundleName is (%s) , Deep is (%d)", curBundleName.c_str(), componentChild->GetIndex());
89            return false;
90        }
91        // set ComponentTree parent
92        componentChild->SetParent(componentParent);
93        componentParent->AddChild(componentChild);
94        // Recurs get child AccessibilityElementInfo.
95        auto result = RecursGetChildElementInfo(elementChild, componentChild);
96        if (!result) {
97            return false;
98        }
99    }
100
101    componentParent->SetNodeId();
102    return res == Accessibility::RET_OK ? true : false;
103}
104bool TreeManager::RecursComponent(const std::shared_ptr<ComponentTree>& componentTree)
105{
106    if (LOG_LEVEL_TRACK < WuKongLogger::GetInstance()->GetLogLevel()) {
107        return false;
108    }
109    if (componentTree == nullptr) {
110        return false;
111    }
112    auto children = componentTree->GetChildren();
113
114    auto elementInfo = GetNewElementInfoList(componentTree->GetIndex());
115    if (elementInfo != nullptr) {
116        TRACK_LOG_STR("Component Node Indxe:(%d), NodeId:(0x%016llX), input count:(%u), Element ID(%d), Type(%s)",
117                      componentTree->GetIndex(), componentTree->GetNodeId(), componentTree->GetInputCount(),
118                      elementInfo->GetAccessibilityId(), elementInfo->GetComponentType().c_str());
119    } else {
120        TRACK_LOG_STR("Component Node Indxe:(%d), NodeId:(0x%016llX), input count:(%u)", componentTree->GetIndex(),
121                      componentTree->GetNodeId(), componentTree->GetInputCount());
122    }
123
124    for (auto tree : children) {
125        RecursComponent(std::static_pointer_cast<ComponentTree>(tree));
126    }
127    return true;
128}
129
130void TreeManager::RecursSetDialog(const std::shared_ptr<ComponentTree>& componentTree)
131{
132    if (componentTree == nullptr) {
133        return;
134    }
135    componentTree->SetTopComponent();
136    DEBUG_LOG_STR("Component Node Index:(%d), NodeId:(0x%016llX), input count:(%u)", componentTree->GetIndex(),
137                  componentTree->GetNodeId(), componentTree->GetInputCount());
138    auto children = componentTree->GetChildren();
139    for (auto tree : children) {
140        RecursSetDialog(std::static_pointer_cast<ComponentTree>(tree));
141    }
142}
143
144bool TreeManager::FindAbility(const std::shared_ptr<AbilityTree>& abilityNode)
145{
146    if (newAbilityNode_->IsEqual(abilityNode)) {
147        DEBUG_LOG("Found same old ability");
148        currentAbilityNode_ = abilityNode;
149        return true;
150    } else {
151        for (auto child : abilityNode->GetChildren()) {
152            if (FindAbility(std::static_pointer_cast<AbilityTree>(child))) {
153                return true;
154            }
155        }
156        return false;
157    }
158}
159
160ErrCode TreeManager::MakeAndCheckNewAbility()
161{
162    // Check ability state
163    newAbilityNode_ = std::make_shared<AbilityTree>();
164    newAbilityNode_->SetNodeId();
165    // check same abiliby as current ability
166    if (currentAbilityNode_ != nullptr) {
167        if (newAbilityNode_->IsEqual(currentAbilityNode_)) {
168            DEBUG_LOG("Ability not change");
169            return OHOS::ERR_OK;
170        }
171    } else if (currentAbilityNode_ == nullptr) {
172        return OHOS::ERR_INVALID_OPERATION;
173    }
174
175    DEBUG_LOG("Ability changed");
176    bool isNewBundle = true;
177    bool isNewAbility = false;
178    for (auto abilityTree : abilityTreeList_) {
179        TRACK_LOG_STR("NewAbility Bundle: (%s), Bundle List Name: (%s)", newAbilityNode_->bundleName_.c_str(),
180                      abilityTree->bundleName_.c_str());
181        // check is new bundle.
182        if (abilityTree->bundleName_ == newAbilityNode_->bundleName_) {
183            isNewBundle = false;
184            // find new ability in ability tree.
185            if (!FindAbility(abilityTree)) {
186                currentAbilityNode_->AddChild(newAbilityNode_);
187                newAbilityNode_->SetParent(currentAbilityNode_);
188                currentAbilityNode_ = newAbilityNode_;
189                isNewAbility = true;
190            }
191        }
192    }
193    // save new bundle for launch multi-application
194    if (isNewBundle) {
195        InitContainer();
196        abilityTreeList_.push_back(newAbilityNode_);
197        currentAbilityNode_ = newAbilityNode_;
198    }
199    // clear current screen data when it is new ability.
200    if (isNewBundle || isNewAbility) {
201        currentComponentNode_ = nullptr;
202        currentPageNode_ = nullptr;
203        isNewAbility_ = true;
204    } else {
205        // set old screen to current screen data when it is old ability.
206        if (pageTreeList_.find(currentAbilityNode_->GetIndex()) == pageTreeList_.end()) {
207            ERROR_LOG_STR("ability index (%d) more than pageTreeList count (%d)", currentAbilityNode_->GetIndex(),
208                          pageTreeList_.size());
209            return OHOS::ERR_INVALID_OPERATION;
210        }
211        currentPageNode_ = pageTreeList_[currentAbilityNode_->GetIndex()];
212        if (componentTreeList_.find(currentPageNode_->GetIndex()) == componentTreeList_.end()) {
213            ERROR_LOG_STR("page index (%d) more than componentTreeList count (%d)", currentPageNode_->GetIndex(),
214                          componentTreeList_.size());
215            return OHOS::ERR_INVALID_OPERATION;
216        }
217        currentComponentNode_ = componentTreeList_[currentPageNode_->GetIndex()];
218    }
219    return OHOS::ERR_OK;
220}
221
222void TreeManager::ReconnectAccessibility()
223{
224    usleep(TWOSECONDS);
225    ERROR_LOG("Start ReconnectAccessibility");
226    auto cm = ComponentManager::GetInstance();
227    if (cm == nullptr) {
228        ERROR_LOG("cm is nullptr");
229        return;
230    }
231    cm->Disconnect();
232    if (!cm->Connect()) {
233        ERROR_LOG("ComponentManager Connect failed");
234    } else {
235        DEBUG_LOG("ComponentManager connect successfully");
236    }
237}
238
239ErrCode TreeManager::UpdateComponentInfo()
240{
241    TRACK_LOG_STD();
242    ErrCode result = OHOS::ERR_OK;
243    // start update component tree.
244    isUpdateComponentFinished_ = false;
245    isNewAbility_ = false;
246    newElementInfoList_.clear();
247    if (WuKongLogger::GetInstance()->GetLogLevel() == LOG_LEVEL_TRACK) {
248        DEBUG_LOG_STR("CompoentNode shared  new (%p) count = (%ld) unique (%d)", newComponentNode_.get(),
249                      newComponentNode_.use_count(), newComponentNode_.unique());
250        DEBUG_LOG_STR("CompoentNode shared (%p) count = (%ld) unique (%d)", currentComponentNode_.get(),
251                      currentComponentNode_.use_count(), currentComponentNode_.unique());
252    }
253    // Generate Ability Node
254    MakeAndCheckNewAbility();
255
256    auto root = std::make_shared<OHOS::Accessibility::AccessibilityElementInfo>();
257    auto aacPtr = OHOS::Accessibility::AccessibilityUITestAbility::GetInstance();
258    hasDialog_ = false;
259    dialogComponent_ = nullptr;
260    // Get root AccessibilityElementInfo from Accessibility,
261    auto bResult = aacPtr->GetRoot(*(root.get()));
262    if (bResult != Accessibility::RET_OK) {
263        ERROR_LOG_STR("Accessibility Ability get root element info failed! ErrCode : (%d) ", bResult);
264        if (bResult == Accessibility::RET_ERR_NO_CONNECTION) {
265            ReconnectAccessibility();
266        }
267        return OHOS::ERR_INVALID_OPERATION;
268    } else {
269        // save root AccessibilityElementInfo.
270        newElementInfoList_.push_back(root);
271        uint32_t count = newElementInfoList_.size();
272        DEBUG_LOG_STR("New Element Info count (%d), Type (%s)", root->GetChildCount(),
273                      root->GetComponentType().c_str());
274
275        // Generate new ComponentTree.
276        newComponentNode_ = std::make_shared<ComponentTree>();
277        newComponentNode_->SetIndex(count - 1);
278
279        // Recurs get all children AccessibilityElementInfo.
280        auto cResult = RecursGetChildElementInfo(root, newComponentNode_);
281        if (!cResult) {
282            return OHOS::ERR_INVALID_OPERATION;
283        }
284        RecursComponent(newComponentNode_);
285        RecursSetDialog(dialogComponent_);
286    }
287    // Generate Page Node
288    newPageNode_ = std::make_shared<PageTree>();
289    newPageNode_->SetNodeId();
290
291    TRACK_LOG_END();
292    return result;
293}
294
295void TreeManager::SetInputcomponentIndex(int actionType, uint32_t index)
296{
297    DEBUG_LOG_STR("Input: (%d), Input Type: (%d)", index, actionType);
298    if (currentPageNode_ == nullptr) {
299        ERROR_LOG("current page is null!");
300        return;
301    }
302
303    // component input count statistics
304    if (index != INVALIDED_INPUT_INDEX) {
305        if (inputComponentList_.size() <= 0) {
306            ERROR_LOG("input component list is null!");
307            return;
308        }
309        if (index >= inputComponentList_.size()) {
310            ERROR_LOG("index argument is invalided");
311            return;
312        }
313        inputComponentList_[index]->AddInputCount();
314        inputComponentList_[index]->AddTypeInputCount(actionType);
315        DEBUG_LOG_STR("inputComponent: GetNodeId (0x%016llX)", inputComponentList_[index]->GetNodeId());
316    } else {
317        if (inputComponent_ == nullptr) {
318            ERROR_LOG("inputComponent_ is nullptr");
319            return;
320        }
321        inputComponent_->AddInputCount();
322        inputComponent_->AddTypeInputCount(actionType);
323        DEBUG_LOG_STR("inputComponent: GetNodeId (0x%016llX)", inputComponent_->GetNodeId());
324    }
325    RecursComponent(currentComponentNode_);
326    // ability input count statistics
327    currentAbilityNode_->AddInputCount();
328
329    // page input count statistics
330    currentPageNode_->AddInputCount();
331    if (index != INVALIDED_INPUT_INDEX) {
332        currentPageNode_->SetCurrentComponentNode(inputComponentList_[index]);
333    } else {
334        currentPageNode_->SetCurrentComponentNode(inputComponent_);
335    }
336}
337
338void TreeManager::SetActiveComponent(const std::vector<std::shared_ptr<ComponentTree>>& inputComponentList)
339{
340    DEBUG_LOG_STR("Active component list: size (%d)", inputComponentList.size());
341    // Clear old input data
342    inputElementInfoList_.clear();
343    inputComponentList_.clear();
344    uint32_t count = elementInfoList_.size();
345    for (auto componentNode : inputComponentList) {
346        if (count > componentNode->GetIndex()) {
347            // Save input pointer list
348            inputElementInfoList_.push_back(elementInfoList_[componentNode->GetIndex()]);
349            inputComponentList_.push_back(componentNode);
350        } else {
351            ERROR_LOG_STR("component index (%d) more than elementInfoList count (%d)", componentNode->GetIndex(),
352                          count);
353            break;
354        }
355    }
356}
357
358void TreeManager::SetActiveComponent(const std::shared_ptr<ComponentTree>& inputComponent)
359{
360    // Save one input pointer.
361    if (inputComponent == nullptr) {
362        ERROR_LOG("argument failed inputComponent is nullptr");
363        return;
364    }
365    DEBUG_LOG_STR("Active component: GetNodeId (0x%016llX)", inputComponent->GetNodeId());
366    inputComponent_ = inputComponent;
367    if (elementInfoList_.size() > inputComponent->GetIndex()) {
368        inputElementInfo_ = elementInfoList_[inputComponent->GetIndex()];
369    } else {
370        ERROR_LOG_STR("component index (%d) more than elementInfoList count (%d)", inputComponent->GetIndex(),
371                      elementInfoList_.size());
372    }
373}
374
375bool TreeManager::AddPage()
376{
377    TRACK_LOG_STD();
378    // save new component tree, and change current conmponent tree.
379    UpdateCurrentPage(true);
380
381    // page tree growth
382    if (newPageNode_ == nullptr) {
383        ERROR_LOG("the new Page Node is null");
384        return false;
385    }
386
387    uint32_t key = componentTreeList_.size();
388    componentTreeList_[key] = currentComponentNode_;
389    newPageNode_->SetIndex(key);
390    if (!isNewAbility_) {
391        if (currentPageNode_ != nullptr) {
392            newPageNode_->SetParent(currentPageNode_);
393            currentPageNode_->AddChild(newPageNode_);
394        }
395    } else {
396        // ability tree growth
397        key = pageTreeList_.size();
398        pageTreeList_[key] = newPageNode_;
399        currentAbilityNode_->SetIndex(key);
400    }
401    currentPageNode_ = newPageNode_;
402    currentAbilityNode_->AddAllComponentCount(currentPageNode_->GetAllComponentCount());
403
404    TRACK_LOG_END();
405    return SamePage();
406}
407
408bool TreeManager::SamePage()
409{
410    TRACK_LOG_STD();
411    isUpdateComponentFinished_ = true;
412    newElementInfoList_.clear();
413    if (WuKongLogger::GetInstance()->GetLogLevel() == LOG_LEVEL_TRACK) {
414        DEBUG_LOG_STR("CompoentNode shared  new (%p) count = (%ld) unique (%d)", newComponentNode_.get(),
415                      newComponentNode_.use_count(), newComponentNode_.unique());
416    }
417    newComponentNode_.reset();
418    newPageNode_.reset();
419    newAbilityNode_.reset();
420    TRACK_LOG_END();
421    return true;
422}
423
424bool TreeManager::UpdatePage(int layer, uint32_t index)
425{
426    TRACK_LOG_STD();
427    DEBUG_LOG_STR("UpdatePage: layer (%d), index (%u)", layer, index);
428    std::shared_ptr<WuKongTree> pageNode = currentPageNode_;
429    if (layer > 0) {
430        if (pageNode->GetChildren().size() <= index) {
431            ERROR_LOG_STR("UpdatePage child index (%d) more than elementInfoList_ GetChildren() size (%u)", index,
432                          pageNode->GetChildren().size());
433            return false;
434        }
435        currentPageNode_ = std::static_pointer_cast<PageTree>(pageNode->GetChildren()[index]);
436    } else {
437        while (layer < 0) {
438            layer++;
439            pageNode = pageNode->GetParent();
440            if (pageNode == nullptr) {
441                ERROR_LOG_STR("UpdatePage back layer (%d) more than currentPageNode_ parent (%p)", layer,
442                              pageNode.get());
443                return false;
444            }
445        }
446        currentPageNode_ = std::static_pointer_cast<PageTree>(pageNode);
447    }
448
449    if (componentTreeList_.find(currentPageNode_->GetIndex()) == componentTreeList_.end()) {
450        ERROR_LOG_STR("currentPageNode_ index (%u) more than componentTreeList_ size (%u)",
451                      currentPageNode_->GetIndex(), componentTreeList_.size());
452        return false;
453    }
454
455    TRACK_LOG_STR("currentPageNode_->GetIndex(): %d", currentPageNode_->GetIndex());
456    currentComponentNode_ = componentTreeList_[currentPageNode_->GetIndex()];
457
458    if (!UpdateCurrentPage()) {
459        return false;
460    }
461    TRACK_LOG_END();
462    return SamePage();
463}
464
465bool TreeManager::RemovePage()
466{
467    TRACK_LOG_STD();
468    uint32_t componentNodeIndex = currentPageNode_->GetIndex();
469    uint32_t componentTreeListCount = componentTreeList_.size();
470    if (componentNodeIndex >= componentTreeListCount) {
471        ERROR_LOG_STR("currentPageNode index (%u) more than componentTreeList_ size (%u)", componentNodeIndex,
472                      componentTreeListCount);
473        return false;
474    }
475    if (WuKongLogger::GetInstance()->GetLogLevel() == LOG_LEVEL_TRACK) {
476        DEBUG_LOG_STR("CompoentNode shared (%p) count = (%ld) unique (%d)",
477                      componentTreeList_[componentNodeIndex].get(), componentTreeList_[componentNodeIndex].use_count(),
478                      componentTreeList_[componentNodeIndex].unique());
479    }
480    auto componentNode = componentTreeList_[componentNodeIndex];
481    if (componentNode == nullptr) {
482        ERROR_LOG("componentNode point is nullptr of currentPageNode");
483        return false;
484    }
485    uint32_t startIndex = componentNode->GetIndex();
486    componentTreeList_[componentNodeIndex].reset();
487    uint32_t endIndex = startIndex + currentPageNode_->count_ - 1;
488    uint32_t elementInfoListCount = elementInfoList_.size();
489    DEBUG_LOG_STR(
490        "currentPageNode StartIndex (%u) EndIndex (%u) componentTreeList_ size (%u) elementInfoList_ size (%u)",
491        startIndex, endIndex, componentTreeListCount, elementInfoListCount);
492    if (startIndex >= elementInfoListCount || endIndex >= elementInfoListCount) {
493        ERROR_LOG_STR("currentPageNode StartIndex (%u) EndIndex (%u) more than elementInfoList_ size (%u)", startIndex,
494                      endIndex, elementInfoListCount);
495        return false;
496    }
497    elementInfoList_.erase(elementInfoList_.begin() + startIndex, elementInfoList_.begin() + endIndex);
498    TRACK_LOG_END();
499    return true;
500}
501
502bool TreeManager::UpdateCurrentPage(bool isAdd)
503{
504    TRACK_LOG_STD();
505    uint32_t count = elementInfoList_.size();
506    DEBUG_LOG_STR("elementInfoList_: %d", count);
507    for (auto elementInfo : newElementInfoList_) {
508        elementInfoList_.push_back(elementInfo);
509    }
510    if (WuKongLogger::GetInstance()->GetLogLevel() == LOG_LEVEL_TRACK) {
511        DEBUG_LOG_STR("CompoentNode shared  new (%p) count = (%ld) unique (%d)", newComponentNode_.get(),
512                      newComponentNode_.use_count(), newComponentNode_.unique());
513        DEBUG_LOG_STR("CompoentNode shared (%p) count = (%ld) unique (%d)", currentComponentNode_.get(),
514                      currentComponentNode_.use_count(), currentComponentNode_.unique());
515    }
516    // update component tree index
517    newComponentNode_->RecursUpdateNodeIndex(count);
518    if (!isAdd) {
519        newComponentNode_->RecursUpdateInfo(currentComponentNode_);
520    }
521    // set current sreen componentNode to new screen
522    currentComponentNode_ = newComponentNode_;
523    if (WuKongLogger::GetInstance()->GetLogLevel() == LOG_LEVEL_TRACK) {
524        DEBUG_LOG_STR("CompoentNode shared (%p) count = (%ld) unique (%d)", currentComponentNode_.get(),
525                      currentComponentNode_.use_count(), currentComponentNode_.unique());
526        if (currentPageNode_ != nullptr) {
527            DEBUG_LOG_STR("CompoentNode shared (%p) index (%u) count = (%ld) unique (%d)",
528                          componentTreeList_[currentPageNode_->GetIndex()].get(), currentPageNode_->GetIndex(),
529                          componentTreeList_[currentPageNode_->GetIndex()].use_count(),
530                          componentTreeList_[currentPageNode_->GetIndex()].unique());
531        }
532    }
533
534    if (!isAdd) {
535        componentTreeList_[currentPageNode_->GetIndex()] = currentComponentNode_;
536        currentAbilityNode_->allComponentCount_ -= currentPageNode_->GetAllComponentCount();
537        currentAbilityNode_->allComponentCount_ += newPageNode_->GetAllComponentCount();
538        currentPageNode_->nodeId_ = newPageNode_->nodeId_;
539        currentPageNode_->allComponentCount_ = newPageNode_->allComponentCount_;
540    }
541    TRACK_LOG_END();
542    return true;
543}
544
545std::uint32_t TreeManager::FindInputComponentIndex(bool shouldScreenCap)
546{
547    if (page2inputCount_.find(pagePath_) == page2inputCount_.end()) {
548        page2inputCount_[pagePath_] = 1;
549        page2componentIndex_[pagePath_] = (std::uint32_t) rand();
550        ScreenCapture(shouldScreenCap);
551        return page2componentIndex_[pagePath_];
552    }
553    if (NeedFocus(componmentType_)) {
554        if (page2inputCount_[pagePath_] % (focusNum_ + 1) == 0) {
555            page2componentIndex_[pagePath_] = (std::uint32_t) rand();
556            page2inputCount_[pagePath_] = 0;
557            ScreenCapture(shouldScreenCap);
558        }
559        page2inputCount_[pagePath_]++;
560    } else {
561        page2inputCount_[pagePath_] = 1;
562        page2componentIndex_[pagePath_] = (std::uint32_t) rand();
563    }
564    return page2componentIndex_[pagePath_];
565}
566
567void TreeManager::ScreenCapture(bool shouldScreenCap)
568{
569    if (!shouldScreenCap) {
570        return;
571    }
572    std::string screenStorePath;
573    ErrCode result = WuKongUtil::GetInstance()->WukongScreenCap(screenStorePath, false);
574    if (result == OHOS::ERR_OK) {
575        Report::GetInstance()->RecordScreenPath(screenStorePath);
576    }
577}
578}  // namespace WuKong
579}  // namespace OHOS
580