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;
35 findObjects(ret, device, selector, root, true);
37 return std::move(ret[0]);
42 void Comparer::findObjects(std::vector<std::shared_ptr<AccessibleNode>> &ret,
43 const std::shared_ptr<UiDevice>& device,
44 const std::shared_ptr<UiSelector>& selector,
45 const std::shared_ptr<AccessibleNode>& root, bool earlyReturn)
47 Comparer comparer(device, selector, earlyReturn);
49 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);
50 if (selector->mParent) {
52 // TODO: Optimize findObjects() when selector has a parent
53 std::vector<std::shared_ptr<AccessibleNode>> ret;
54 Comparer::findObjects(ret, device, selector->mParent, root);
56 for (const auto &node : ret) {
57 comparer.findObjects(ret, node);
63 if (selector->mMatchXPath) {
64 std::string pkg = root->getPkg();
65 auto XMLDoc = AccessibleWatcher::getInstance()->getXMLDoc(pkg);
67 if (XMLDoc.get() == nullptr) return;
69 XMLDoc->findObjects(ret, selector->mXPath, earlyReturn);
74 comparer.findObjects(ret, root);
77 void Comparer::findObjects(std::vector<std::shared_ptr<AccessibleNode>> &ret,
78 const std::shared_ptr<AccessibleNode>& root)
80 std::list<std::shared_ptr<PartialMatch>> partialList{};
81 findObjects(ret, root, 0, 1, partialList);
82 LOGI("%d object(s) found", (int)ret.size());
85 void Comparer::findObjects(std::vector<std::shared_ptr<AccessibleNode>> &ret,
86 const std::shared_ptr<AccessibleNode>& root, const int &index, const int &depth,
87 std::list<std::shared_ptr<PartialMatch>> &partialMatches)
90 if (mSelector->mMatchShowing && !root->isShowing()) return;
92 for (auto &match : partialMatches)
93 match->update(root, index, depth, partialMatches);
95 std::shared_ptr<PartialMatch> currentMatch =
96 PartialMatch::accept(root, mSelector, index, depth);
97 if (currentMatch) partialMatches.push_front(currentMatch);
99 if (!(mSelector->mMaxDepth && (depth+1 > mSelector->mMaxDepth))) {
100 auto children = root->getChildren();
101 for (int i = 0; i < (int)children.size(); i++) {
102 auto child = children[i];
103 if (child->getRawHandler() == nullptr) continue;
105 findObjects(ret, child, i, depth + 1, partialMatches);
106 if (!ret.empty() && mEarlyReturn) {
107 LOGI("Object found and earlyReturn");
112 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);
115 if (currentMatch && currentMatch->finalizeMatch()){
116 LOGI("Found matched = %s with criteria %s", root->description().c_str(), currentMatch->debugPrint().c_str());