1886da342Sopenharmony_ci/* 2886da342Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3886da342Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4886da342Sopenharmony_ci * you may not use this file except in compliance with the License. 5886da342Sopenharmony_ci * You may obtain a copy of the License at 6886da342Sopenharmony_ci * 7886da342Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8886da342Sopenharmony_ci * 9886da342Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10886da342Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11886da342Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12886da342Sopenharmony_ci * See the License for the specific language governing permissions and 13886da342Sopenharmony_ci * limitations under the License. 14886da342Sopenharmony_ci */ 15886da342Sopenharmony_ci 16886da342Sopenharmony_ci#include "select_strategy.h" 17886da342Sopenharmony_cinamespace OHOS::uitest { 18886da342Sopenharmony_ci constexpr int32_t MAX_TRAVEL_TIMES = 20000; 19886da342Sopenharmony_ci void SelectStrategy::RegisterAnchorMatch(const WidgetMatchModel &matchModel) 20886da342Sopenharmony_ci { 21886da342Sopenharmony_ci anchorMatch_.emplace_back(matchModel); 22886da342Sopenharmony_ci } 23886da342Sopenharmony_ci 24886da342Sopenharmony_ci void SelectStrategy::RegisterMyselfMatch(const WidgetMatchModel &matchModel) 25886da342Sopenharmony_ci { 26886da342Sopenharmony_ci myselfMatch_.emplace_back(matchModel); 27886da342Sopenharmony_ci } 28886da342Sopenharmony_ci 29886da342Sopenharmony_ci void SelectStrategy::SetWantMulti(bool isWantMulti) 30886da342Sopenharmony_ci { 31886da342Sopenharmony_ci wantMulti_ = isWantMulti; 32886da342Sopenharmony_ci } 33886da342Sopenharmony_ci 34886da342Sopenharmony_ci void SelectStrategy::SetAndCalcSelectWindowRect(const Rect &windowBounds, const std::vector<Rect> &windowBoundsVec) 35886da342Sopenharmony_ci { 36886da342Sopenharmony_ci windowBounds_ = windowBounds; 37886da342Sopenharmony_ci overplayWindowBoundsVec_ = windowBoundsVec; 38886da342Sopenharmony_ci } 39886da342Sopenharmony_ci 40886da342Sopenharmony_ci SelectStrategy::~SelectStrategy() 41886da342Sopenharmony_ci { 42886da342Sopenharmony_ci anchorMatch_.clear(); 43886da342Sopenharmony_ci myselfMatch_.clear(); 44886da342Sopenharmony_ci } 45886da342Sopenharmony_ci 46886da342Sopenharmony_ci void SelectStrategy::CalcWidgetVisibleBounds(Widget &widget) 47886da342Sopenharmony_ci { 48886da342Sopenharmony_ci const auto noneZone = Rect{0, 0, 0, 0}; 49886da342Sopenharmony_ci // calc bounds with its window 50886da342Sopenharmony_ci Rect visibleRect{0, 0, 0, 0}; 51886da342Sopenharmony_ci if (!RectAlgorithm::ComputeIntersection(widget.GetBounds(), windowBounds_, visibleRect)) { 52886da342Sopenharmony_ci LOG_D("Widget %{public}s bounds is %{public}s, without window bounds %{public}s, widget info is %{public}s", 53886da342Sopenharmony_ci widget.GetAttr(UiAttr::ACCESSIBILITY_ID).data(), widget.GetBounds().Describe().data(), 54886da342Sopenharmony_ci windowBounds_.Describe().data(), widget.ToStr().data()); 55886da342Sopenharmony_ci widget.SetBounds(noneZone); 56886da342Sopenharmony_ci return; 57886da342Sopenharmony_ci } 58886da342Sopenharmony_ci widget.SetBounds(visibleRect); 59886da342Sopenharmony_ci 60886da342Sopenharmony_ci // calc bounds with its cliper 61886da342Sopenharmony_ci auto hier = widget.GetAttr(UiAttr::HIERARCHY); 62886da342Sopenharmony_ci while (WidgetHierarchyBuilder::GetParentWidgetHierarchy(hier) != "") { 63886da342Sopenharmony_ci std::string parentHie = WidgetHierarchyBuilder::GetParentWidgetHierarchy(hier); 64886da342Sopenharmony_ci auto find = clipers_.find(parentHie); 65886da342Sopenharmony_ci if (find != clipers_.end()) { 66886da342Sopenharmony_ci if (!RectAlgorithm::ComputeIntersection(widget.GetBounds(), find->second, visibleRect)) { 67886da342Sopenharmony_ci widget.SetBounds(noneZone); 68886da342Sopenharmony_ci return; 69886da342Sopenharmony_ci } 70886da342Sopenharmony_ci widget.SetBounds(visibleRect); 71886da342Sopenharmony_ci break; 72886da342Sopenharmony_ci } 73886da342Sopenharmony_ci hier = parentHie; 74886da342Sopenharmony_ci } 75886da342Sopenharmony_ci 76886da342Sopenharmony_ci // calc bounds with overplay windows 77886da342Sopenharmony_ci if (overplayWindowBoundsVec_.size() == 0) { 78886da342Sopenharmony_ci return; 79886da342Sopenharmony_ci } 80886da342Sopenharmony_ci if (!RectAlgorithm::ComputeMaxVisibleRegion(widget.GetBounds(), overplayWindowBoundsVec_, visibleRect)) { 81886da342Sopenharmony_ci LOG_D("widget %{public}s is hide by overplays, widget info is %{public}s", 82886da342Sopenharmony_ci widget.GetAttr(UiAttr::ACCESSIBILITY_ID).data(), widget.ToStr().data()); 83886da342Sopenharmony_ci widget.SetBounds(noneZone); 84886da342Sopenharmony_ci } 85886da342Sopenharmony_ci widget.SetBounds(visibleRect); 86886da342Sopenharmony_ci } 87886da342Sopenharmony_ci 88886da342Sopenharmony_ci std::string SelectStrategy::Describe() const 89886da342Sopenharmony_ci { 90886da342Sopenharmony_ci std::string strategy = "PLAIN"; 91886da342Sopenharmony_ci switch (GetStrategyType()) { 92886da342Sopenharmony_ci case StrategyEnum::PLAIN: 93886da342Sopenharmony_ci strategy = "PLAIN"; 94886da342Sopenharmony_ci break; 95886da342Sopenharmony_ci case StrategyEnum::WITH_IN: 96886da342Sopenharmony_ci strategy = "WITH_IN"; 97886da342Sopenharmony_ci break; 98886da342Sopenharmony_ci case StrategyEnum::IS_AFTER: 99886da342Sopenharmony_ci strategy = "IS_AFTER"; 100886da342Sopenharmony_ci break; 101886da342Sopenharmony_ci case StrategyEnum::IS_BEFORE: 102886da342Sopenharmony_ci strategy = "IS_BEFORE"; 103886da342Sopenharmony_ci break; 104886da342Sopenharmony_ci case StrategyEnum::COMPLEX: 105886da342Sopenharmony_ci strategy = "COMPLEX"; 106886da342Sopenharmony_ci break; 107886da342Sopenharmony_ci default: 108886da342Sopenharmony_ci LOG_I("Error StrategyType, use plain"); 109886da342Sopenharmony_ci strategy = "PLAIN"; 110886da342Sopenharmony_ci break; 111886da342Sopenharmony_ci } 112886da342Sopenharmony_ci stringstream ss; 113886da342Sopenharmony_ci ss << "{"; 114886da342Sopenharmony_ci ss << strategy; 115886da342Sopenharmony_ci if (!anchorMatch_.empty()) { 116886da342Sopenharmony_ci ss << "; anchorMatcher="; 117886da342Sopenharmony_ci for (auto &locator : anchorMatch_) { 118886da342Sopenharmony_ci ss << "[" << locator.Describe() << "]"; 119886da342Sopenharmony_ci } 120886da342Sopenharmony_ci } 121886da342Sopenharmony_ci if (!myselfMatch_.empty()) { 122886da342Sopenharmony_ci ss << "; myselfMatcher="; 123886da342Sopenharmony_ci for (auto &locator : myselfMatch_) { 124886da342Sopenharmony_ci ss << "[" << locator.Describe() << "]"; 125886da342Sopenharmony_ci } 126886da342Sopenharmony_ci } 127886da342Sopenharmony_ci ss << "}"; 128886da342Sopenharmony_ci return ss.str(); 129886da342Sopenharmony_ci } 130886da342Sopenharmony_ci 131886da342Sopenharmony_ci void SelectStrategy::RefreshWidgetBounds(Widget &widget) 132886da342Sopenharmony_ci { 133886da342Sopenharmony_ci CalcWidgetVisibleBounds(widget); 134886da342Sopenharmony_ci auto widgetVisibleBounds = widget.GetBounds(); 135886da342Sopenharmony_ci if (widgetVisibleBounds.GetHeight() <= 0 || widgetVisibleBounds.GetWidth() <= 0) { 136886da342Sopenharmony_ci widget.SetAttr(UiAttr::VISIBLE, "false"); 137886da342Sopenharmony_ci } else { 138886da342Sopenharmony_ci widget.SetAttr(UiAttr::VISIBLE, "true"); 139886da342Sopenharmony_ci } 140886da342Sopenharmony_ci if (widget.GetAttr(UiAttr::CLIP) == "true") { 141886da342Sopenharmony_ci clipers_.insert(make_pair(widget.GetAttr(UiAttr::HIERARCHY), widget.GetBounds())); 142886da342Sopenharmony_ci } 143886da342Sopenharmony_ci } 144886da342Sopenharmony_ci 145886da342Sopenharmony_ci class AfterSelectorStrategy : public SelectStrategy { 146886da342Sopenharmony_ci public: 147886da342Sopenharmony_ci AfterSelectorStrategy() = default; 148886da342Sopenharmony_ci void LocateNode(const Window &window, 149886da342Sopenharmony_ci ElementNodeIterator &elementNodeRef, 150886da342Sopenharmony_ci std::vector<Widget> &visitWidgets, 151886da342Sopenharmony_ci std::vector<int> &targetWidgets, 152886da342Sopenharmony_ci bool isRemoveInvisible = true) override 153886da342Sopenharmony_ci { 154886da342Sopenharmony_ci elementNodeRef.ClearDFSNext(); 155886da342Sopenharmony_ci SetAndCalcSelectWindowRect(window.bounds_, window.invisibleBoundsVec_); 156886da342Sopenharmony_ci while (true) { 157886da342Sopenharmony_ci Widget anchorWidget{"test"}; 158886da342Sopenharmony_ci if (!elementNodeRef.DFSNext(anchorWidget, window.id_)) { 159886da342Sopenharmony_ci return; 160886da342Sopenharmony_ci } 161886da342Sopenharmony_ci anchorWidget.SetAttr(UiAttr::HOST_WINDOW_ID, std::to_string(window.id_)); 162886da342Sopenharmony_ci if (anchorWidget.GetAttr(UiAttr::VISIBLE) == "false") { 163886da342Sopenharmony_ci LOG_D("Widget %{public}s is invisible", anchorWidget.GetAttr(UiAttr::ACCESSIBILITY_ID).data()); 164886da342Sopenharmony_ci elementNodeRef.RemoveInvisibleWidget(); 165886da342Sopenharmony_ci continue; 166886da342Sopenharmony_ci } 167886da342Sopenharmony_ci RefreshWidgetBounds(anchorWidget); 168886da342Sopenharmony_ci if (anchorWidget.GetAttr(UiAttr::VISIBLE) == "false") { 169886da342Sopenharmony_ci LOG_D("Widget %{public}s is invisible", anchorWidget.GetAttr(UiAttr::ACCESSIBILITY_ID).data()); 170886da342Sopenharmony_ci continue; 171886da342Sopenharmony_ci } 172886da342Sopenharmony_ci visitWidgets.emplace_back(move(anchorWidget)); 173886da342Sopenharmony_ci if (visitWidgets.size() > MAX_TRAVEL_TIMES) { 174886da342Sopenharmony_ci LOG_E("ElementInfos obtained from AAMS is abnormal, traversal node failed"); 175886da342Sopenharmony_ci visitWidgets.clear(); 176886da342Sopenharmony_ci return; 177886da342Sopenharmony_ci } 178886da342Sopenharmony_ci std::reference_wrapper<Widget const> tempAnchorWidget = visitWidgets.back(); 179886da342Sopenharmony_ci bool isAnchorMatch = true; 180886da342Sopenharmony_ci for (const auto &anchorIt : anchorMatch_) { 181886da342Sopenharmony_ci isAnchorMatch = tempAnchorWidget.get().MatchAttr(anchorIt) && isAnchorMatch; 182886da342Sopenharmony_ci if (!isAnchorMatch) { 183886da342Sopenharmony_ci break; 184886da342Sopenharmony_ci } 185886da342Sopenharmony_ci } 186886da342Sopenharmony_ci if (!isAnchorMatch) { 187886da342Sopenharmony_ci continue; 188886da342Sopenharmony_ci } 189886da342Sopenharmony_ci LocateNodeAfterAnchor(window, elementNodeRef, visitWidgets, targetWidgets); 190886da342Sopenharmony_ci } 191886da342Sopenharmony_ci } 192886da342Sopenharmony_ci 193886da342Sopenharmony_ci void LocateNodeAfterAnchor(const Window &window, 194886da342Sopenharmony_ci ElementNodeIterator &elementNodeRef, 195886da342Sopenharmony_ci std::vector<Widget> &visitWidgets, 196886da342Sopenharmony_ci std::vector<int> &targetWidgets) 197886da342Sopenharmony_ci { 198886da342Sopenharmony_ci while (true) { 199886da342Sopenharmony_ci Widget myselfWidget{"myselfWidget"}; 200886da342Sopenharmony_ci if (!elementNodeRef.DFSNext(myselfWidget, window.id_)) { 201886da342Sopenharmony_ci return; 202886da342Sopenharmony_ci } 203886da342Sopenharmony_ci myselfWidget.SetAttr(UiAttr::HOST_WINDOW_ID, std::to_string(window.id_)); 204886da342Sopenharmony_ci RefreshWidgetBounds(myselfWidget); 205886da342Sopenharmony_ci if (myselfWidget.GetAttr(UiAttr::VISIBLE) == "false") { 206886da342Sopenharmony_ci LOG_D("Widget %{public}s is invisible", myselfWidget.GetAttr(UiAttr::ACCESSIBILITY_ID).data()); 207886da342Sopenharmony_ci continue; 208886da342Sopenharmony_ci } 209886da342Sopenharmony_ci visitWidgets.emplace_back(move(myselfWidget)); 210886da342Sopenharmony_ci if (visitWidgets.size() > MAX_TRAVEL_TIMES) { 211886da342Sopenharmony_ci LOG_E("ElementInfos obtained from AAMS is abnormal, traversal node failed"); 212886da342Sopenharmony_ci visitWidgets.clear(); 213886da342Sopenharmony_ci return; 214886da342Sopenharmony_ci } 215886da342Sopenharmony_ci std::reference_wrapper<Widget const> tempWidget = visitWidgets.back(); 216886da342Sopenharmony_ci bool isMyselfMatch = true; 217886da342Sopenharmony_ci for (const auto &myselfIt : myselfMatch_) { 218886da342Sopenharmony_ci isMyselfMatch = tempWidget.get().MatchAttr(myselfIt) && isMyselfMatch; 219886da342Sopenharmony_ci if (!isMyselfMatch) { 220886da342Sopenharmony_ci break; 221886da342Sopenharmony_ci } 222886da342Sopenharmony_ci } 223886da342Sopenharmony_ci if (!isMyselfMatch) { 224886da342Sopenharmony_ci continue; 225886da342Sopenharmony_ci } 226886da342Sopenharmony_ci targetWidgets.emplace_back(visitWidgets.size() - 1); 227886da342Sopenharmony_ci if (!wantMulti_) { 228886da342Sopenharmony_ci return; 229886da342Sopenharmony_ci } 230886da342Sopenharmony_ci } 231886da342Sopenharmony_ci } 232886da342Sopenharmony_ci 233886da342Sopenharmony_ci StrategyEnum GetStrategyType() const override 234886da342Sopenharmony_ci { 235886da342Sopenharmony_ci return StrategyEnum::IS_AFTER; 236886da342Sopenharmony_ci } 237886da342Sopenharmony_ci ~AfterSelectorStrategy() override = default; 238886da342Sopenharmony_ci }; 239886da342Sopenharmony_ci 240886da342Sopenharmony_ci class BeforeSelectorStrategy : public SelectStrategy { 241886da342Sopenharmony_ci public: 242886da342Sopenharmony_ci BeforeSelectorStrategy() = default; 243886da342Sopenharmony_ci void LocateNode(const Window &window, 244886da342Sopenharmony_ci ElementNodeIterator &elementNodeRef, 245886da342Sopenharmony_ci std::vector<Widget> &visitWidgets, 246886da342Sopenharmony_ci std::vector<int> &targetWidgets, 247886da342Sopenharmony_ci bool isRemoveInvisible = true) override 248886da342Sopenharmony_ci { 249886da342Sopenharmony_ci elementNodeRef.ClearDFSNext(); 250886da342Sopenharmony_ci SetAndCalcSelectWindowRect(window.bounds_, window.invisibleBoundsVec_); 251886da342Sopenharmony_ci while (true) { 252886da342Sopenharmony_ci Widget anchorWidget{"anchorWidget"}; 253886da342Sopenharmony_ci if (!elementNodeRef.DFSNext(anchorWidget, window.id_)) { 254886da342Sopenharmony_ci return; 255886da342Sopenharmony_ci } 256886da342Sopenharmony_ci anchorWidget.SetAttr(UiAttr::HOST_WINDOW_ID, std::to_string(window.id_)); 257886da342Sopenharmony_ci if (anchorWidget.GetAttr(UiAttr::VISIBLE) == "false") { 258886da342Sopenharmony_ci LOG_D("Widget %{public}s is invisible", anchorWidget.GetAttr(UiAttr::ACCESSIBILITY_ID).data()); 259886da342Sopenharmony_ci elementNodeRef.RemoveInvisibleWidget(); 260886da342Sopenharmony_ci continue; 261886da342Sopenharmony_ci } 262886da342Sopenharmony_ci RefreshWidgetBounds(anchorWidget); 263886da342Sopenharmony_ci if (anchorWidget.GetAttr(UiAttr::VISIBLE) == "false") { 264886da342Sopenharmony_ci LOG_D("Widget %{public}s is invisible", anchorWidget.GetAttr(UiAttr::ACCESSIBILITY_ID).data()); 265886da342Sopenharmony_ci continue; 266886da342Sopenharmony_ci } 267886da342Sopenharmony_ci visitWidgets.emplace_back(move(anchorWidget)); 268886da342Sopenharmony_ci if (visitWidgets.size() > MAX_TRAVEL_TIMES) { 269886da342Sopenharmony_ci LOG_E("ElementInfos obtained from AAMS is abnormal, traversal node failed"); 270886da342Sopenharmony_ci visitWidgets.clear(); 271886da342Sopenharmony_ci return; 272886da342Sopenharmony_ci } 273886da342Sopenharmony_ci std::reference_wrapper<Widget const> tempAnchorWidget = visitWidgets.back(); 274886da342Sopenharmony_ci bool isAnchorMatch = true; 275886da342Sopenharmony_ci for (const auto &anchorIt : anchorMatch_) { 276886da342Sopenharmony_ci isAnchorMatch = tempAnchorWidget.get().MatchAttr(anchorIt) && isAnchorMatch; 277886da342Sopenharmony_ci if (!isAnchorMatch) { 278886da342Sopenharmony_ci break; 279886da342Sopenharmony_ci } 280886da342Sopenharmony_ci } 281886da342Sopenharmony_ci if (!isAnchorMatch) { 282886da342Sopenharmony_ci continue; 283886da342Sopenharmony_ci } 284886da342Sopenharmony_ci LocateNodeAfterBeforeAnchor(visitWidgets, targetWidgets); 285886da342Sopenharmony_ci if (!targetWidgets.empty() && !wantMulti_) { 286886da342Sopenharmony_ci return; 287886da342Sopenharmony_ci } 288886da342Sopenharmony_ci } 289886da342Sopenharmony_ci } 290886da342Sopenharmony_ci 291886da342Sopenharmony_ci void LocateNodeAfterBeforeAnchor(std::vector<Widget> &visitWidgets, 292886da342Sopenharmony_ci std::vector<int> &targetWidgets) 293886da342Sopenharmony_ci { 294886da342Sopenharmony_ci size_t index = 0; 295886da342Sopenharmony_ci if (targetWidgets.size() > 0) { 296886da342Sopenharmony_ci index = targetWidgets[targetWidgets.size() - 1] + 1; 297886da342Sopenharmony_ci } 298886da342Sopenharmony_ci for (; index < visitWidgets.size() - 1; ++index) { 299886da342Sopenharmony_ci bool isMyselfMatch = true; 300886da342Sopenharmony_ci for (const auto &myselfIt : myselfMatch_) { 301886da342Sopenharmony_ci isMyselfMatch = visitWidgets[index].MatchAttr(myselfIt) && isMyselfMatch; 302886da342Sopenharmony_ci } 303886da342Sopenharmony_ci if (!isMyselfMatch) { 304886da342Sopenharmony_ci continue; 305886da342Sopenharmony_ci } 306886da342Sopenharmony_ci targetWidgets.emplace_back(index); 307886da342Sopenharmony_ci if (!wantMulti_) { 308886da342Sopenharmony_ci return; 309886da342Sopenharmony_ci } 310886da342Sopenharmony_ci } 311886da342Sopenharmony_ci } 312886da342Sopenharmony_ci 313886da342Sopenharmony_ci StrategyEnum GetStrategyType() const override 314886da342Sopenharmony_ci { 315886da342Sopenharmony_ci return StrategyEnum::IS_BEFORE; 316886da342Sopenharmony_ci } 317886da342Sopenharmony_ci ~BeforeSelectorStrategy() override = default; 318886da342Sopenharmony_ci }; 319886da342Sopenharmony_ci 320886da342Sopenharmony_ci class WithInSelectorStrategy : public SelectStrategy { 321886da342Sopenharmony_ci public: 322886da342Sopenharmony_ci WithInSelectorStrategy() = default; 323886da342Sopenharmony_ci void LocateNode(const Window &window, 324886da342Sopenharmony_ci ElementNodeIterator &elementNodeRef, 325886da342Sopenharmony_ci std::vector<Widget> &visitWidgets, 326886da342Sopenharmony_ci std::vector<int> &targetWidgets, 327886da342Sopenharmony_ci bool isRemoveInvisible = true) override 328886da342Sopenharmony_ci { 329886da342Sopenharmony_ci elementNodeRef.ClearDFSNext(); 330886da342Sopenharmony_ci SetAndCalcSelectWindowRect(window.bounds_, window.invisibleBoundsVec_); 331886da342Sopenharmony_ci while (true) { 332886da342Sopenharmony_ci Widget anchorWidget{"withInWidget"}; 333886da342Sopenharmony_ci if (!elementNodeRef.DFSNext(anchorWidget, window.id_)) { 334886da342Sopenharmony_ci return; 335886da342Sopenharmony_ci } 336886da342Sopenharmony_ci anchorWidget.SetAttr(UiAttr::HOST_WINDOW_ID, std::to_string(window.id_)); 337886da342Sopenharmony_ci if (anchorWidget.GetAttr(UiAttr::VISIBLE) == "false") { 338886da342Sopenharmony_ci LOG_D("Widget %{public}s is invisible", anchorWidget.GetAttr(UiAttr::ACCESSIBILITY_ID).data()); 339886da342Sopenharmony_ci elementNodeRef.RemoveInvisibleWidget(); 340886da342Sopenharmony_ci continue; 341886da342Sopenharmony_ci } 342886da342Sopenharmony_ci RefreshWidgetBounds(anchorWidget); 343886da342Sopenharmony_ci if (anchorWidget.GetAttr(UiAttr::VISIBLE) == "false") { 344886da342Sopenharmony_ci LOG_D("Widget %{public}s is invisible", anchorWidget.GetAttr(UiAttr::ACCESSIBILITY_ID).data()); 345886da342Sopenharmony_ci continue; 346886da342Sopenharmony_ci } 347886da342Sopenharmony_ci visitWidgets.emplace_back(move(anchorWidget)); 348886da342Sopenharmony_ci if (visitWidgets.size() > MAX_TRAVEL_TIMES) { 349886da342Sopenharmony_ci LOG_E("ElementInfos obtained from AAMS is abnormal, traversal node failed"); 350886da342Sopenharmony_ci visitWidgets.clear(); 351886da342Sopenharmony_ci return; 352886da342Sopenharmony_ci } 353886da342Sopenharmony_ci std::reference_wrapper<Widget const> tempAnchorWidget = visitWidgets.back(); 354886da342Sopenharmony_ci bool isAnchorMatch = true; 355886da342Sopenharmony_ci for (const auto &anchorIt : anchorMatch_) { 356886da342Sopenharmony_ci isAnchorMatch = tempAnchorWidget.get().MatchAttr(anchorIt) && isAnchorMatch; 357886da342Sopenharmony_ci if (!isAnchorMatch) { 358886da342Sopenharmony_ci break; 359886da342Sopenharmony_ci } 360886da342Sopenharmony_ci } 361886da342Sopenharmony_ci if (!isAnchorMatch) { 362886da342Sopenharmony_ci continue; 363886da342Sopenharmony_ci } 364886da342Sopenharmony_ci LocateNodeWithInAnchor(window, elementNodeRef, visitWidgets, targetWidgets); 365886da342Sopenharmony_ci if (!targetWidgets.empty() && !wantMulti_) { 366886da342Sopenharmony_ci return; 367886da342Sopenharmony_ci } 368886da342Sopenharmony_ci } 369886da342Sopenharmony_ci } 370886da342Sopenharmony_ci 371886da342Sopenharmony_ci void LocateNodeWithInAnchor(const Window &window, 372886da342Sopenharmony_ci ElementNodeIterator &elementNodeRef, 373886da342Sopenharmony_ci std::vector<Widget> &visitWidgets, 374886da342Sopenharmony_ci std::vector<int> &targetWidgets) 375886da342Sopenharmony_ci { 376886da342Sopenharmony_ci // restore current index and set top to anchor index 377886da342Sopenharmony_ci elementNodeRef.RestoreNodeIndexByAnchor(); 378886da342Sopenharmony_ci while (true) { 379886da342Sopenharmony_ci Widget myselfWidget{"myselfWidget"}; 380886da342Sopenharmony_ci if (!elementNodeRef.DFSNextWithInTarget(myselfWidget)) { 381886da342Sopenharmony_ci break; 382886da342Sopenharmony_ci } 383886da342Sopenharmony_ci myselfWidget.SetAttr(UiAttr::HOST_WINDOW_ID, std::to_string(window.id_)); 384886da342Sopenharmony_ci RefreshWidgetBounds(myselfWidget); 385886da342Sopenharmony_ci 386886da342Sopenharmony_ci if (myselfWidget.GetAttr(UiAttr::VISIBLE) == "false") { 387886da342Sopenharmony_ci LOG_D("Widget %{public}s is invisible", myselfWidget.GetAttr(UiAttr::ACCESSIBILITY_ID).data()); 388886da342Sopenharmony_ci continue; 389886da342Sopenharmony_ci } 390886da342Sopenharmony_ci visitWidgets.emplace_back(move(myselfWidget)); 391886da342Sopenharmony_ci if (visitWidgets.size() > MAX_TRAVEL_TIMES) { 392886da342Sopenharmony_ci LOG_E("ElementInfos obtained from AAMS is abnormal, traversal node failed"); 393886da342Sopenharmony_ci visitWidgets.clear(); 394886da342Sopenharmony_ci return; 395886da342Sopenharmony_ci } 396886da342Sopenharmony_ci std::reference_wrapper<Widget const> tempWidget = visitWidgets.back(); 397886da342Sopenharmony_ci bool isMyselfMatch = true; 398886da342Sopenharmony_ci for (const auto &myselfIt : myselfMatch_) { 399886da342Sopenharmony_ci isMyselfMatch = tempWidget.get().MatchAttr(myselfIt) && isMyselfMatch; 400886da342Sopenharmony_ci if (!isMyselfMatch) { 401886da342Sopenharmony_ci break; 402886da342Sopenharmony_ci } 403886da342Sopenharmony_ci } 404886da342Sopenharmony_ci if (!isMyselfMatch) { 405886da342Sopenharmony_ci continue; 406886da342Sopenharmony_ci } 407886da342Sopenharmony_ci targetWidgets.emplace_back(visitWidgets.size() - 1); 408886da342Sopenharmony_ci if (!wantMulti_) { 409886da342Sopenharmony_ci return; 410886da342Sopenharmony_ci } 411886da342Sopenharmony_ci } 412886da342Sopenharmony_ci elementNodeRef.ResetNodeIndexToAnchor(); 413886da342Sopenharmony_ci } 414886da342Sopenharmony_ci 415886da342Sopenharmony_ci StrategyEnum GetStrategyType() const override 416886da342Sopenharmony_ci { 417886da342Sopenharmony_ci return StrategyEnum::WITH_IN; 418886da342Sopenharmony_ci } 419886da342Sopenharmony_ci ~WithInSelectorStrategy() override = default; 420886da342Sopenharmony_ci }; 421886da342Sopenharmony_ci 422886da342Sopenharmony_ci class PlainSelectorStrategy : public SelectStrategy { 423886da342Sopenharmony_ci public: 424886da342Sopenharmony_ci PlainSelectorStrategy() = default; 425886da342Sopenharmony_ci void LocateNode(const Window &window, 426886da342Sopenharmony_ci ElementNodeIterator &elementNodeRef, 427886da342Sopenharmony_ci std::vector<Widget> &visitWidgets, 428886da342Sopenharmony_ci std::vector<int> &targetWidgets, 429886da342Sopenharmony_ci bool isRemoveInvisible = true) override 430886da342Sopenharmony_ci { 431886da342Sopenharmony_ci elementNodeRef.ClearDFSNext(); 432886da342Sopenharmony_ci SetAndCalcSelectWindowRect(window.bounds_, window.invisibleBoundsVec_); 433886da342Sopenharmony_ci while (true) { 434886da342Sopenharmony_ci Widget myselfWidget{"myselfWidget"}; 435886da342Sopenharmony_ci if (!elementNodeRef.DFSNext(myselfWidget, window.id_)) { 436886da342Sopenharmony_ci return; 437886da342Sopenharmony_ci } 438886da342Sopenharmony_ci myselfWidget.SetAttr(UiAttr::HOST_WINDOW_ID, std::to_string(window.id_)); 439886da342Sopenharmony_ci if (isRemoveInvisible) { 440886da342Sopenharmony_ci if (myselfWidget.GetAttr(UiAttr::VISIBLE) == "false") { 441886da342Sopenharmony_ci LOG_D("Widget %{public}s is invisible", myselfWidget.GetAttr(UiAttr::ACCESSIBILITY_ID).data()); 442886da342Sopenharmony_ci elementNodeRef.RemoveInvisibleWidget(); 443886da342Sopenharmony_ci continue; 444886da342Sopenharmony_ci } 445886da342Sopenharmony_ci RefreshWidgetBounds(myselfWidget); 446886da342Sopenharmony_ci } 447886da342Sopenharmony_ci visitWidgets.emplace_back(move(myselfWidget)); 448886da342Sopenharmony_ci if (visitWidgets.size() > MAX_TRAVEL_TIMES) { 449886da342Sopenharmony_ci LOG_E("ElementInfos obtained from AAMS is abnormal, traversal node failed"); 450886da342Sopenharmony_ci visitWidgets.clear(); 451886da342Sopenharmony_ci return; 452886da342Sopenharmony_ci } 453886da342Sopenharmony_ci if (myselfWidget.GetAttr(UiAttr::VISIBLE) == "false") { 454886da342Sopenharmony_ci continue; 455886da342Sopenharmony_ci } 456886da342Sopenharmony_ci std::reference_wrapper<Widget const> tempWidget = visitWidgets.back(); 457886da342Sopenharmony_ci bool isMyselfMatch = true; 458886da342Sopenharmony_ci for (const auto &myselfIt : myselfMatch_) { 459886da342Sopenharmony_ci isMyselfMatch = tempWidget.get().MatchAttr(myselfIt) && isMyselfMatch; 460886da342Sopenharmony_ci if (!isMyselfMatch) { 461886da342Sopenharmony_ci break; 462886da342Sopenharmony_ci } 463886da342Sopenharmony_ci } 464886da342Sopenharmony_ci if (!isMyselfMatch) { 465886da342Sopenharmony_ci continue; 466886da342Sopenharmony_ci } 467886da342Sopenharmony_ci targetWidgets.emplace_back(visitWidgets.size() - 1); 468886da342Sopenharmony_ci if (!wantMulti_) { 469886da342Sopenharmony_ci return; 470886da342Sopenharmony_ci } 471886da342Sopenharmony_ci } 472886da342Sopenharmony_ci } 473886da342Sopenharmony_ci 474886da342Sopenharmony_ci StrategyEnum GetStrategyType() const override 475886da342Sopenharmony_ci { 476886da342Sopenharmony_ci return StrategyEnum::PLAIN; 477886da342Sopenharmony_ci } 478886da342Sopenharmony_ci ~PlainSelectorStrategy() override = default; 479886da342Sopenharmony_ci }; 480886da342Sopenharmony_ci 481886da342Sopenharmony_ci class ComplexSelectorStrategy : public SelectStrategy { 482886da342Sopenharmony_ci public: 483886da342Sopenharmony_ci ComplexSelectorStrategy() = default; 484886da342Sopenharmony_ci void LocateNode(const Window &window, 485886da342Sopenharmony_ci ElementNodeIterator &elementNodeRef, 486886da342Sopenharmony_ci std::vector<Widget> &visitWidgets, 487886da342Sopenharmony_ci std::vector<int> &targetWidgets, 488886da342Sopenharmony_ci bool isRemoveInvisible = true) override 489886da342Sopenharmony_ci { 490886da342Sopenharmony_ci elementNodeRef.ClearDFSNext(); 491886da342Sopenharmony_ci SetAndCalcSelectWindowRect(window.bounds_, window.invisibleBoundsVec_); 492886da342Sopenharmony_ci std::vector<int> fakeTargetWidgets; 493886da342Sopenharmony_ci while (true) { 494886da342Sopenharmony_ci Widget myselfWidget{"myselfWidget"}; 495886da342Sopenharmony_ci if (!elementNodeRef.DFSNext(myselfWidget, window.id_)) { 496886da342Sopenharmony_ci break; 497886da342Sopenharmony_ci } 498886da342Sopenharmony_ci myselfWidget.SetAttr(UiAttr::HOST_WINDOW_ID, std::to_string(window.id_)); 499886da342Sopenharmony_ci if (myselfWidget.GetAttr(UiAttr::VISIBLE) == "false") { 500886da342Sopenharmony_ci LOG_D("Widget %{public}s is invisible", myselfWidget.GetAttr(UiAttr::ACCESSIBILITY_ID).data()); 501886da342Sopenharmony_ci elementNodeRef.RemoveInvisibleWidget(); 502886da342Sopenharmony_ci continue; 503886da342Sopenharmony_ci } 504886da342Sopenharmony_ci RefreshWidgetBounds(myselfWidget); 505886da342Sopenharmony_ci if (myselfWidget.GetAttr(UiAttr::VISIBLE) == "false") { 506886da342Sopenharmony_ci continue; 507886da342Sopenharmony_ci } 508886da342Sopenharmony_ci visitWidgets.emplace_back(move(myselfWidget)); 509886da342Sopenharmony_ci if (visitWidgets.size() > MAX_TRAVEL_TIMES) { 510886da342Sopenharmony_ci LOG_E("ElementInfos obtained from AAMS is abnormal, traversal node failed"); 511886da342Sopenharmony_ci visitWidgets.clear(); 512886da342Sopenharmony_ci return; 513886da342Sopenharmony_ci } 514886da342Sopenharmony_ci std::reference_wrapper<Widget const> tempWidget = visitWidgets.back(); 515886da342Sopenharmony_ci bool isMyselfMatch = true; 516886da342Sopenharmony_ci for (const auto &myselfIt : myselfMatch_) { 517886da342Sopenharmony_ci isMyselfMatch = tempWidget.get().MatchAttr(myselfIt) && isMyselfMatch; 518886da342Sopenharmony_ci if (!isMyselfMatch) { 519886da342Sopenharmony_ci break; 520886da342Sopenharmony_ci } 521886da342Sopenharmony_ci } 522886da342Sopenharmony_ci if (!isMyselfMatch) { 523886da342Sopenharmony_ci continue; 524886da342Sopenharmony_ci } 525886da342Sopenharmony_ci fakeTargetWidgets.emplace_back(visitWidgets.size() - 1); 526886da342Sopenharmony_ci } 527886da342Sopenharmony_ci DoComplexSelect(visitWidgets, fakeTargetWidgets, targetWidgets); 528886da342Sopenharmony_ci } 529886da342Sopenharmony_ci 530886da342Sopenharmony_ci void RegisterMultiAfterAnchor(const std::vector<WidgetMatchModel> &afterAnchor) 531886da342Sopenharmony_ci { 532886da342Sopenharmony_ci multiAfterAnchorMatcher.emplace_back(afterAnchor); 533886da342Sopenharmony_ci } 534886da342Sopenharmony_ci 535886da342Sopenharmony_ci void RegisterMultiBeforeAnchor(const std::vector<WidgetMatchModel> &beforeAnchor) 536886da342Sopenharmony_ci { 537886da342Sopenharmony_ci multiBeforeAnchorMatcher.emplace_back(beforeAnchor); 538886da342Sopenharmony_ci } 539886da342Sopenharmony_ci 540886da342Sopenharmony_ci void RegisterMultiWithInAnchor(const std::vector<WidgetMatchModel> &withInAnchor) 541886da342Sopenharmony_ci { 542886da342Sopenharmony_ci multiWithInAnchorMatcher.emplace_back(withInAnchor); 543886da342Sopenharmony_ci } 544886da342Sopenharmony_ci 545886da342Sopenharmony_ci int CalcMaxAfterAnchorIndex(const std::vector<Widget> &visitWidgets) 546886da342Sopenharmony_ci { 547886da342Sopenharmony_ci int32_t startAfterIndex = -1; 548886da342Sopenharmony_ci for (auto &afterLocator : multiAfterAnchorMatcher) { 549886da342Sopenharmony_ci int32_t startIndex = 0; 550886da342Sopenharmony_ci for (; static_cast<size_t>(startIndex) < visitWidgets.size(); ++startIndex) { 551886da342Sopenharmony_ci bool isFrontMatch = true; 552886da342Sopenharmony_ci for (auto &attrModel : afterLocator) { 553886da342Sopenharmony_ci isFrontMatch = isFrontMatch && visitWidgets[startIndex].MatchAttr(attrModel); 554886da342Sopenharmony_ci } 555886da342Sopenharmony_ci if (isFrontMatch) { 556886da342Sopenharmony_ci startAfterIndex = startAfterIndex > startIndex ? startAfterIndex : startIndex; 557886da342Sopenharmony_ci break; 558886da342Sopenharmony_ci } 559886da342Sopenharmony_ci } 560886da342Sopenharmony_ci if (static_cast<size_t>(startIndex) == visitWidgets.size()) { 561886da342Sopenharmony_ci startAfterIndex = visitWidgets.size(); 562886da342Sopenharmony_ci } 563886da342Sopenharmony_ci } 564886da342Sopenharmony_ci return startAfterIndex; 565886da342Sopenharmony_ci } 566886da342Sopenharmony_ci 567886da342Sopenharmony_ci int CalcMinBeforeAnchorIndex(const std::vector<Widget> &visitWidgets) 568886da342Sopenharmony_ci { 569886da342Sopenharmony_ci int startBeforeIndex = visitWidgets.size(); 570886da342Sopenharmony_ci for (auto &beforeLocator : multiBeforeAnchorMatcher) { 571886da342Sopenharmony_ci int beforeIndex = visitWidgets.size() - 1; 572886da342Sopenharmony_ci for (; beforeIndex > 0; --beforeIndex) { 573886da342Sopenharmony_ci bool isRearMatch = true; 574886da342Sopenharmony_ci for (auto &attrModel : beforeLocator) { 575886da342Sopenharmony_ci isRearMatch = isRearMatch && visitWidgets[beforeIndex].MatchAttr(attrModel); 576886da342Sopenharmony_ci } 577886da342Sopenharmony_ci if (isRearMatch) { 578886da342Sopenharmony_ci startBeforeIndex = startBeforeIndex > beforeIndex ? beforeIndex : startBeforeIndex; 579886da342Sopenharmony_ci break; 580886da342Sopenharmony_ci } 581886da342Sopenharmony_ci } 582886da342Sopenharmony_ci if (beforeIndex == 0) { 583886da342Sopenharmony_ci startBeforeIndex = 0; 584886da342Sopenharmony_ci } 585886da342Sopenharmony_ci } 586886da342Sopenharmony_ci return startBeforeIndex; 587886da342Sopenharmony_ci } 588886da342Sopenharmony_ci 589886da342Sopenharmony_ci bool CheckTargetIdByParentSelect(const std::vector<int> &parentIndexVec, 590886da342Sopenharmony_ci const std::vector<Widget> &visitWidgets) 591886da342Sopenharmony_ci { 592886da342Sopenharmony_ci bool isAllLocatorMatch = true; 593886da342Sopenharmony_ci for (auto &parentLocator : multiWithInAnchorMatcher) { 594886da342Sopenharmony_ci bool hasValidParent = false; 595886da342Sopenharmony_ci for (auto &parentIndex : parentIndexVec) { 596886da342Sopenharmony_ci bool isMatch = true; 597886da342Sopenharmony_ci for (auto &selfMatch : parentLocator) { 598886da342Sopenharmony_ci isMatch = isMatch && visitWidgets[parentIndex].MatchAttr(selfMatch); 599886da342Sopenharmony_ci } 600886da342Sopenharmony_ci hasValidParent = hasValidParent || isMatch; 601886da342Sopenharmony_ci if (hasValidParent) { 602886da342Sopenharmony_ci break; 603886da342Sopenharmony_ci } 604886da342Sopenharmony_ci } 605886da342Sopenharmony_ci isAllLocatorMatch = isAllLocatorMatch && hasValidParent; 606886da342Sopenharmony_ci if (!isAllLocatorMatch) { 607886da342Sopenharmony_ci break; 608886da342Sopenharmony_ci } 609886da342Sopenharmony_ci } 610886da342Sopenharmony_ci return isAllLocatorMatch; 611886da342Sopenharmony_ci } 612886da342Sopenharmony_ci 613886da342Sopenharmony_ci void LocateNodeWithInComplexSelect(std::vector<int> &filterParentValidId, 614886da342Sopenharmony_ci const std::vector<Widget> &visitWidgets, 615886da342Sopenharmony_ci const std::vector<int> &myselfTargets) 616886da342Sopenharmony_ci { 617886da342Sopenharmony_ci for (int targetId : myselfTargets) { 618886da342Sopenharmony_ci const std::string &targetHie = visitWidgets[targetId].GetHierarchy(); 619886da342Sopenharmony_ci std::vector<int> parentIndexVec; 620886da342Sopenharmony_ci for (size_t index = 0; index < visitWidgets.size(); ++index) { 621886da342Sopenharmony_ci const std::string &visitHie = visitWidgets[index].GetHierarchy(); 622886da342Sopenharmony_ci if (targetHie.length() <= visitHie.length() || targetHie.find(visitHie) != 0) { 623886da342Sopenharmony_ci continue; 624886da342Sopenharmony_ci } 625886da342Sopenharmony_ci parentIndexVec.emplace_back(index); 626886da342Sopenharmony_ci } 627886da342Sopenharmony_ci bool isAllLocatorMatch = CheckTargetIdByParentSelect(parentIndexVec, visitWidgets); 628886da342Sopenharmony_ci if (isAllLocatorMatch) { 629886da342Sopenharmony_ci filterParentValidId.emplace_back(targetId); 630886da342Sopenharmony_ci } 631886da342Sopenharmony_ci } 632886da342Sopenharmony_ci } 633886da342Sopenharmony_ci 634886da342Sopenharmony_ci void DoComplexSelect(const std::vector<Widget> &visitWidgets, 635886da342Sopenharmony_ci std::vector<int> &fakeTargets, 636886da342Sopenharmony_ci std::vector<int> &myselfTargets) 637886da342Sopenharmony_ci { 638886da342Sopenharmony_ci int startAfterIndex = CalcMaxAfterAnchorIndex(visitWidgets); 639886da342Sopenharmony_ci int startBeforeIndex = CalcMinBeforeAnchorIndex(visitWidgets); 640886da342Sopenharmony_ci if (startBeforeIndex <= startAfterIndex) { 641886da342Sopenharmony_ci return; 642886da342Sopenharmony_ci } 643886da342Sopenharmony_ci for (auto index : fakeTargets) { 644886da342Sopenharmony_ci if (index > startAfterIndex && index < startBeforeIndex) { 645886da342Sopenharmony_ci myselfTargets.emplace_back(index); 646886da342Sopenharmony_ci } 647886da342Sopenharmony_ci } 648886da342Sopenharmony_ci 649886da342Sopenharmony_ci if (myselfTargets.empty()) { 650886da342Sopenharmony_ci return; 651886da342Sopenharmony_ci } 652886da342Sopenharmony_ci if (multiWithInAnchorMatcher.empty()) { 653886da342Sopenharmony_ci if (!wantMulti_) { 654886da342Sopenharmony_ci myselfTargets.erase(myselfTargets.begin() + 1, myselfTargets.end()); 655886da342Sopenharmony_ci } 656886da342Sopenharmony_ci return; 657886da342Sopenharmony_ci } 658886da342Sopenharmony_ci std::vector<int> filterParentValidId; 659886da342Sopenharmony_ci LocateNodeWithInComplexSelect(filterParentValidId, visitWidgets, myselfTargets); 660886da342Sopenharmony_ci if (filterParentValidId.empty()) { 661886da342Sopenharmony_ci myselfTargets.clear(); 662886da342Sopenharmony_ci return; 663886da342Sopenharmony_ci } 664886da342Sopenharmony_ci if (wantMulti_) { 665886da342Sopenharmony_ci myselfTargets = filterParentValidId; 666886da342Sopenharmony_ci } else { 667886da342Sopenharmony_ci myselfTargets.clear(); 668886da342Sopenharmony_ci myselfTargets.emplace_back(filterParentValidId.at(0)); 669886da342Sopenharmony_ci } 670886da342Sopenharmony_ci } 671886da342Sopenharmony_ci 672886da342Sopenharmony_ci StrategyEnum GetStrategyType() const override 673886da342Sopenharmony_ci { 674886da342Sopenharmony_ci return StrategyEnum::COMPLEX; 675886da342Sopenharmony_ci } 676886da342Sopenharmony_ci ~ComplexSelectorStrategy() override = default; 677886da342Sopenharmony_ci 678886da342Sopenharmony_ci private: 679886da342Sopenharmony_ci std::vector<std::vector<WidgetMatchModel>> multiAfterAnchorMatcher; 680886da342Sopenharmony_ci std::vector<std::vector<WidgetMatchModel>> multiBeforeAnchorMatcher; 681886da342Sopenharmony_ci std::vector<std::vector<WidgetMatchModel>> multiWithInAnchorMatcher; 682886da342Sopenharmony_ci }; 683886da342Sopenharmony_ci 684886da342Sopenharmony_ci static std::unique_ptr<SelectStrategy> BuildComplexStrategy(const StrategyBuildParam &buildParam, bool isWantMulti) 685886da342Sopenharmony_ci { 686886da342Sopenharmony_ci std::unique_ptr<ComplexSelectorStrategy> selectStrategy = std::make_unique<ComplexSelectorStrategy>(); 687886da342Sopenharmony_ci for (const auto &matchModel : buildParam.myselfMatcher) { 688886da342Sopenharmony_ci selectStrategy->RegisterMyselfMatch(matchModel); 689886da342Sopenharmony_ci } 690886da342Sopenharmony_ci for (const auto &afterWidgetAnchor : buildParam.afterAnchorMatcherVec) { 691886da342Sopenharmony_ci selectStrategy->RegisterMultiAfterAnchor(afterWidgetAnchor); 692886da342Sopenharmony_ci } 693886da342Sopenharmony_ci for (const auto &beforeWidgetAnchor : buildParam.beforeAnchorMatcherVec) { 694886da342Sopenharmony_ci selectStrategy->RegisterMultiBeforeAnchor(beforeWidgetAnchor); 695886da342Sopenharmony_ci } 696886da342Sopenharmony_ci for (const auto &withInWidgetAnchor : buildParam.withInAnchorMatcherVec) { 697886da342Sopenharmony_ci selectStrategy->RegisterMultiWithInAnchor(withInWidgetAnchor); 698886da342Sopenharmony_ci } 699886da342Sopenharmony_ci selectStrategy->SetWantMulti(isWantMulti); 700886da342Sopenharmony_ci return selectStrategy; 701886da342Sopenharmony_ci } 702886da342Sopenharmony_ci 703886da342Sopenharmony_ci static std::unique_ptr<SelectStrategy> BuildWithInStrategy(const StrategyBuildParam &buildParam, bool isWantMulti) 704886da342Sopenharmony_ci { 705886da342Sopenharmony_ci std::unique_ptr<SelectStrategy> selectStrategy = std::make_unique<WithInSelectorStrategy>(); 706886da342Sopenharmony_ci for (const auto &matchModel : buildParam.myselfMatcher) { 707886da342Sopenharmony_ci selectStrategy->RegisterMyselfMatch(matchModel); 708886da342Sopenharmony_ci } 709886da342Sopenharmony_ci for (const auto &anchorModel : buildParam.withInAnchorMatcherVec.at(0)) { 710886da342Sopenharmony_ci selectStrategy->RegisterAnchorMatch(anchorModel); 711886da342Sopenharmony_ci } 712886da342Sopenharmony_ci selectStrategy->SetWantMulti(isWantMulti); 713886da342Sopenharmony_ci return selectStrategy; 714886da342Sopenharmony_ci } 715886da342Sopenharmony_ci 716886da342Sopenharmony_ci static std::unique_ptr<SelectStrategy> BuildBeforeStrategy(const StrategyBuildParam &buildParam, bool isWantMulti) 717886da342Sopenharmony_ci { 718886da342Sopenharmony_ci std::unique_ptr<SelectStrategy> selectStrategy = std::make_unique<BeforeSelectorStrategy>(); 719886da342Sopenharmony_ci for (const auto &matchModel : buildParam.myselfMatcher) { 720886da342Sopenharmony_ci selectStrategy->RegisterMyselfMatch(matchModel); 721886da342Sopenharmony_ci } 722886da342Sopenharmony_ci for (const auto &anchorModel : buildParam.beforeAnchorMatcherVec.at(0)) { 723886da342Sopenharmony_ci selectStrategy->RegisterAnchorMatch(anchorModel); 724886da342Sopenharmony_ci } 725886da342Sopenharmony_ci selectStrategy->SetWantMulti(isWantMulti); 726886da342Sopenharmony_ci return selectStrategy; 727886da342Sopenharmony_ci } 728886da342Sopenharmony_ci 729886da342Sopenharmony_ci static std::unique_ptr<SelectStrategy> BuildAfterStrategy(const StrategyBuildParam &buildParam, bool isWantMulti) 730886da342Sopenharmony_ci { 731886da342Sopenharmony_ci std::unique_ptr<SelectStrategy> selectStrategy = std::make_unique<AfterSelectorStrategy>(); 732886da342Sopenharmony_ci for (const auto &matchModel : buildParam.myselfMatcher) { 733886da342Sopenharmony_ci selectStrategy->RegisterMyselfMatch(matchModel); 734886da342Sopenharmony_ci } 735886da342Sopenharmony_ci for (const auto &anchorModel : buildParam.afterAnchorMatcherVec.at(0)) { 736886da342Sopenharmony_ci selectStrategy->RegisterAnchorMatch(anchorModel); 737886da342Sopenharmony_ci } 738886da342Sopenharmony_ci selectStrategy->SetWantMulti(isWantMulti); 739886da342Sopenharmony_ci return selectStrategy; 740886da342Sopenharmony_ci } 741886da342Sopenharmony_ci 742886da342Sopenharmony_ci std::unique_ptr<SelectStrategy> SelectStrategy::BuildSelectStrategy(const StrategyBuildParam &buildParam, 743886da342Sopenharmony_ci bool isWantMulti) 744886da342Sopenharmony_ci { 745886da342Sopenharmony_ci if (buildParam.afterAnchorMatcherVec.empty() && buildParam.beforeAnchorMatcherVec.empty() && 746886da342Sopenharmony_ci buildParam.withInAnchorMatcherVec.empty()) { 747886da342Sopenharmony_ci std::unique_ptr<SelectStrategy> selectStrategy = std::make_unique<PlainSelectorStrategy>(); 748886da342Sopenharmony_ci for (const auto &matchModel : buildParam.myselfMatcher) { 749886da342Sopenharmony_ci selectStrategy->RegisterMyselfMatch(matchModel); 750886da342Sopenharmony_ci } 751886da342Sopenharmony_ci selectStrategy->SetWantMulti(isWantMulti); 752886da342Sopenharmony_ci return selectStrategy; 753886da342Sopenharmony_ci } else if (!buildParam.afterAnchorMatcherVec.empty() && (buildParam.afterAnchorMatcherVec.size() == 1) && 754886da342Sopenharmony_ci buildParam.beforeAnchorMatcherVec.empty() && buildParam.withInAnchorMatcherVec.empty()) { 755886da342Sopenharmony_ci return BuildAfterStrategy(buildParam, isWantMulti); 756886da342Sopenharmony_ci } else if (buildParam.afterAnchorMatcherVec.empty() && !buildParam.beforeAnchorMatcherVec.empty() && 757886da342Sopenharmony_ci (buildParam.beforeAnchorMatcherVec.size() == 1) && buildParam.withInAnchorMatcherVec.empty()) { 758886da342Sopenharmony_ci return BuildBeforeStrategy(buildParam, isWantMulti); 759886da342Sopenharmony_ci } else if (buildParam.afterAnchorMatcherVec.empty() && buildParam.beforeAnchorMatcherVec.empty() && 760886da342Sopenharmony_ci !buildParam.withInAnchorMatcherVec.empty() && (buildParam.withInAnchorMatcherVec.size() == 1)) { 761886da342Sopenharmony_ci return BuildWithInStrategy(buildParam, isWantMulti); 762886da342Sopenharmony_ci } else { 763886da342Sopenharmony_ci return BuildComplexStrategy(buildParam, isWantMulti); 764886da342Sopenharmony_ci } 765886da342Sopenharmony_ci } 766886da342Sopenharmony_ci} // namespace OHOS::uitest