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