2 * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 using namespace Aurum;
22 Comparer::Comparer(const std::shared_ptr<UiDevice> device, const std::shared_ptr<UiSelector> selector,
23 const bool &earlyReturn)
24 : mDevice(device), mSelector(selector), mEarlyReturn(earlyReturn)
28 Comparer::~Comparer() {}
30 std::shared_ptr<AccessibleNode> Comparer::findObject(const std::shared_ptr<UiDevice> device,
31 const std::shared_ptr<UiSelector> selector,
32 const std::shared_ptr<AccessibleNode> root)
34 std::vector<std::shared_ptr<AccessibleNode>> ret = findObjects(device, selector, root, true);
36 return std::move(ret[0]);
41 std::vector<std::shared_ptr<AccessibleNode>> Comparer::findObjects(const std::shared_ptr<UiDevice> device,
42 const std::shared_ptr<UiSelector> selector,
43 const std::shared_ptr<AccessibleNode> root, bool earlyReturn)
45 Comparer comparer(device, selector, earlyReturn);
47 LOGI("findObjects selector(%s) from (type:%s style:%s, role:%s, text:%s) earlyReturn:%d", selector->description().c_str(), root->getType().c_str(), root->getStyle().c_str(), root->getRole().c_str(), root->getText().c_str(), earlyReturn);
49 if (selector->mParent) {
50 auto ret = Comparer::findObjects(device, selector->mParent, root);
51 std::vector<std::shared_ptr<AccessibleNode>> merged{};
53 for (const auto &node : ret) {
54 auto tmp = comparer.findObjects(node);
55 std::move(std::begin(tmp), std::end(tmp), std::back_inserter(merged));
60 if (selector->mMatchXPath) {
61 std::vector<std::shared_ptr<AccessibleNode>> merged{};
63 auto XMLDocMap = AccessibleWatcher::getInstance()->getXMLDocMap();
64 std::string pkg = root->getPkg();
66 if (XMLDocMap.count(pkg) == 0) return merged;
68 auto XMLDoc = XMLDocMap[pkg];
70 auto tmp = XMLDoc->findObjects(selector->mXPath, earlyReturn);
71 std::move(std::begin(tmp), std::end(tmp), std::back_inserter(merged));
76 return comparer.findObjects(root);
79 std::vector<std::shared_ptr<AccessibleNode>> Comparer::findObjects(const std::shared_ptr<AccessibleNode> root)
81 std::list<std::shared_ptr<PartialMatch>> partialList{};
82 std::vector<std::shared_ptr<AccessibleNode>> ret = findObjects(root, 0, 1, partialList);
83 LOGI("%d object(s) found", (int)ret.size());
87 std::vector<std::shared_ptr<AccessibleNode>> Comparer::findObjects(
88 const std::shared_ptr<AccessibleNode> root, const int &index, const int &depth,
89 std::list<std::shared_ptr<PartialMatch>> &partialMatches)
91 std::vector<std::shared_ptr<AccessibleNode>> ret;
93 if (mSelector->mMatchShowing && !root->isShowing()) return ret;
95 for (auto &match : partialMatches)
96 match->update(root, index, depth, partialMatches);
98 std::shared_ptr<PartialMatch> currentMatch =
99 PartialMatch::accept(root, mSelector, index, depth);
100 if (currentMatch) partialMatches.push_front(currentMatch);
102 if (!(mSelector->mMaxDepth && (depth+1 > mSelector->mMaxDepth))) {
103 int childCnt = root->getChildCount();
104 for (int i = 0; i < childCnt; i++) {
105 std::shared_ptr<AccessibleNode> childNode = root->getChildAt(i);
106 if (childNode == nullptr) continue;
108 std::vector<std::shared_ptr<AccessibleNode>> childret =
109 findObjects(childNode, i, depth + 1, partialMatches);
110 std::move(std::begin(childret), std::end(childret), std::back_inserter(ret));
112 if (!ret.empty() && mEarlyReturn) {
113 LOGI("Object found and earlyReturn");
118 LOGI("Abort searching! No need to search children(maxDepth limit overflow, %d < %d < %d)", mSelector->mMinDepth? mSelector->mMinDepth: -1, depth, mSelector->mMaxDepth?(mSelector->mMaxDepth):9999999);
121 if (currentMatch && currentMatch->finalizeMatch()){
122 LOGI("Found matched = %s with criteria %s", root->description().c_str(), currentMatch->debugPrint().c_str());