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 
16 #include "accessibility_element_operator_impl.h"
17 #include "accessibility_element_operator.h"
18 #include "accessibility_system_ability_client.h"
19 #include "hilog_wrapper.h"
20 #include <cinttypes>
21 namespace OHOS {
22 namespace Accessibility {
23 std::unordered_map<int32_t,
24     sptr<IAccessibilityElementOperatorCallback>> AccessibilityElementOperatorImpl::requests_ = {};
25 ffrt::mutex AccessibilityElementOperatorImpl::requestsMutex_;
26 
AccessibilityElementOperatorImpl(int32_t windowId,const std::shared_ptr<AccessibilityElementOperator> & operation,AccessibilityElementOperatorCallback & callback)27 AccessibilityElementOperatorImpl::AccessibilityElementOperatorImpl(int32_t windowId,
28     const std::shared_ptr<AccessibilityElementOperator> &operation,
29     AccessibilityElementOperatorCallback &callback)
30     : windowId_(windowId), operatorCallback_(callback), operator_(operation)
31 {
32     HILOG_DEBUG();
33 }
34 
~AccessibilityElementOperatorImpl()35 AccessibilityElementOperatorImpl::~AccessibilityElementOperatorImpl()
36 {
37     HILOG_DEBUG();
38 }
39 
SearchElementInfoByAccessibilityId(const int64_t elementId,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback,const int32_t mode,bool isFilter)40 void AccessibilityElementOperatorImpl::SearchElementInfoByAccessibilityId(const int64_t elementId,
41     const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback, const int32_t mode,
42     bool isFilter)
43 {
44     int32_t mRequestId = AddRequest(requestId, callback);
45     HILOG_DEBUG("search element add requestId[%{public}d], elementId[%{public}" PRId64 "], requestId[%{public}d]",
46         mRequestId, elementId, requestId);
47     callback->SetIsFilter(isFilter);
48     if (operator_) {
49         operator_->SearchElementInfoByAccessibilityId(elementId, mRequestId, operatorCallback_, mode);
50     } else {
51         HILOG_ERROR("Operator is nullptr");
52     }
53 }
54 
SearchElementInfosByText(const int64_t elementId,const std::string & text,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)55 void AccessibilityElementOperatorImpl::SearchElementInfosByText(const int64_t elementId,
56     const std::string &text, const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback)
57 {
58     HILOG_DEBUG();
59     int32_t mRequestId = AddRequest(requestId, callback);
60     HILOG_DEBUG("add requestId[%{public}d]", mRequestId);
61     if (operator_) {
62         operator_->SearchElementInfosByText(elementId, text, mRequestId, operatorCallback_);
63     } else {
64         HILOG_DEBUG("Can not find interaction object");
65     }
66 }
67 
FindFocusedElementInfo(const int64_t elementId,const int32_t focusType,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)68 void AccessibilityElementOperatorImpl::FindFocusedElementInfo(const int64_t elementId,
69     const int32_t focusType, const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback)
70 {
71     HILOG_DEBUG();
72     int32_t mRequestId = AddRequest(requestId, callback);
73     HILOG_DEBUG("add requestId[%{public}d]", mRequestId);
74     if (operator_) {
75         operator_->FindFocusedElementInfo(elementId, focusType, mRequestId, operatorCallback_);
76     } else {
77         HILOG_DEBUG("Can not find interaction object");
78     }
79 }
80 
FocusMoveSearch(const int64_t elementId,const int32_t direction,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)81 void AccessibilityElementOperatorImpl::FocusMoveSearch(const int64_t elementId,
82     const int32_t direction, const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback)
83 {
84     HILOG_DEBUG();
85     int32_t mRequestId = AddRequest(requestId, callback);
86     HILOG_DEBUG("add requestId[%{public}d]", mRequestId);
87     if (operator_) {
88         operator_->FocusMoveSearch(elementId, direction, mRequestId, operatorCallback_);
89     } else {
90         HILOG_DEBUG("Can not find interaction object");
91     }
92 }
93 
ExecuteAction(const int64_t elementId,const int32_t action,const std::map<std::string,std::string> & actionArguments,int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)94 void AccessibilityElementOperatorImpl::ExecuteAction(const int64_t elementId,
95     const int32_t action, const std::map<std::string, std::string> &actionArguments,
96     int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback)
97 {
98     HILOG_DEBUG();
99     int32_t mRequestId = AddRequest(requestId, callback);
100     HILOG_DEBUG("add requestId[%{public}d]", mRequestId);
101     if (operator_) {
102         operator_->ExecuteAction(elementId, action, actionArguments, mRequestId, operatorCallback_);
103     } else {
104         HILOG_DEBUG("Can not find interaction object");
105     }
106 }
107 
GetCursorPosition(const int64_t elementId,int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)108 void AccessibilityElementOperatorImpl::GetCursorPosition(const int64_t elementId,
109     int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback)
110 {
111     HILOG_DEBUG();
112     int32_t mRequestId = AddRequest(requestId, callback);
113     HILOG_DEBUG("add requestId[%{public}d]", mRequestId);
114     if (operator_) {
115         operator_->GetCursorPosition(elementId, mRequestId, operatorCallback_);
116     } else {
117         HILOG_DEBUG("Can not find interaction object");
118     }
119 }
120 
ClearFocus()121 void AccessibilityElementOperatorImpl::ClearFocus()
122 {
123     HILOG_DEBUG();
124     if (operator_) {
125         operator_->ClearFocus();
126     } else {
127         HILOG_DEBUG("Can not find interaction object");
128     }
129 }
130 
OutsideTouch()131 void AccessibilityElementOperatorImpl::OutsideTouch()
132 {
133     HILOG_DEBUG();
134     if (operator_ != nullptr) {
135         operator_->OutsideTouch();
136     } else {
137         HILOG_DEBUG("Can not find interaction object");
138     }
139 }
140 
GetWindowId()141 int32_t AccessibilityElementOperatorImpl::GetWindowId()
142 {
143     return windowId_;
144 }
145 
SetChildTreeIdAndWinId(const int64_t elementId,const int32_t childTreeId,const int32_t childWindowId)146 void AccessibilityElementOperatorImpl::SetChildTreeIdAndWinId(const int64_t elementId,
147     const int32_t childTreeId, const int32_t childWindowId)
148 {
149     HILOG_DEBUG("elementId:%{public}" PRId64 ", childTreeId:%{public}d, childWind:%{public}d",
150         elementId, childTreeId, childWindowId);
151     operator_->SetChildTreeIdAndWinId(elementId, childTreeId, childWindowId);
152 }
153 
SetBelongTreeId(const int32_t treeId)154 void AccessibilityElementOperatorImpl::SetBelongTreeId(const int32_t treeId)
155 {
156     HILOG_DEBUG("treeId:[%{public}d]", treeId);
157     operator_->SetBelongTreeId(treeId);
158 }
159 
SetParentWindowId(const int32_t parentWindowId)160 void AccessibilityElementOperatorImpl::SetParentWindowId(const int32_t parentWindowId)
161 {
162     HILOG_DEBUG("parentWindowId:[%{public}d]", parentWindowId);
163     operator_->SetParentWindowId(parentWindowId);
164 }
165 
AddRequest(int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)166 int32_t AccessibilityElementOperatorImpl::AddRequest(int32_t requestId,
167     const sptr<IAccessibilityElementOperatorCallback> &callback)
168 {
169     std::lock_guard<ffrt::mutex> lock(requestsMutex_);
170 
171     auto iter = requests_.find(requestId);
172     if (iter == requests_.end()) {
173         requests_[requestId] = callback;
174     }
175     return requestId;
176 }
177 
SetSearchElementInfoByAccessibilityIdResult(const std::list<AccessibilityElementInfo> & infos,const int32_t requestId)178 void AccessibilityElementOperatorImpl::SetSearchElementInfoByAccessibilityIdResult(
179     const std::list<AccessibilityElementInfo> &infos, const int32_t requestId)
180 {
181     HILOG_DEBUG("requestId is %{public}d", requestId);
182     std::lock_guard<ffrt::mutex> lock(requestsMutex_);
183     std::vector<AccessibilityElementInfo> filterInfos(infos.begin(), infos.end());
184     auto iter = requests_.find(requestId);
185     if (iter != requests_.end()) {
186         if (iter->second != nullptr) {
187             HILOG_DEBUG("isFilter %{public}d", iter->second->GetFilter());
188             if (iter->second->GetFilter()) {
189                 SetFiltering(filterInfos);
190             }
191             iter->second->SetSearchElementInfoByAccessibilityIdResult(filterInfos, requestId);
192         }
193         requests_.erase(iter);
194     } else {
195         HILOG_DEBUG("Can't find the callback [requestId:%d]", requestId);
196     }
197 }
198 
SetFiltering(std::vector<AccessibilityElementInfo> & filterInfos)199 void AccessibilityElementOperatorImpl::SetFiltering(std::vector<AccessibilityElementInfo> &filterInfos)
200 {
201     for (auto &info : filterInfos) {
202         info.SetAccessibilityText("");
203         info.SetComponentResourceId("");
204         info.SetPagePath("");
205         info.SetError("");
206         info.SetLatestContent("");
207         info.SetContentList({});
208     }
209 }
210 
SetSearchElementInfoByTextResult(const std::list<AccessibilityElementInfo> & infos,const int32_t requestId)211 void AccessibilityElementOperatorImpl::SetSearchElementInfoByTextResult(
212     const std::list<AccessibilityElementInfo> &infos, const int32_t requestId)
213 {
214     HILOG_DEBUG();
215     std::lock_guard<ffrt::mutex> lock(requestsMutex_);
216     std::vector<AccessibilityElementInfo> myInfos(infos.begin(), infos.end());
217     auto iter = requests_.find(requestId);
218     if (iter != requests_.end()) {
219         if (iter->second != nullptr) {
220             iter->second->SetSearchElementInfoByTextResult(myInfos, requestId);
221         }
222         requests_.erase(iter);
223     } else {
224         HILOG_DEBUG("Can't find the callback [requestId:%d]", requestId);
225     }
226 }
227 
SetFindFocusedElementInfoResult(const AccessibilityElementInfo & info,const int32_t requestId)228 void AccessibilityElementOperatorImpl::SetFindFocusedElementInfoResult(
229     const AccessibilityElementInfo &info, const int32_t requestId)
230 {
231     HILOG_DEBUG();
232     std::lock_guard<ffrt::mutex> lock(requestsMutex_);
233     auto iter = requests_.find(requestId);
234     if (iter != requests_.end()) {
235         if (iter->second != nullptr) {
236             iter->second->SetFindFocusedElementInfoResult(info, requestId);
237         }
238         requests_.erase(iter);
239     } else {
240         HILOG_DEBUG("Can't find the callback [requestId:%d]", requestId);
241     }
242 }
243 
SetFocusMoveSearchResult(const AccessibilityElementInfo & info,const int32_t requestId)244 void AccessibilityElementOperatorImpl::SetFocusMoveSearchResult(
245     const AccessibilityElementInfo &info, const int32_t requestId)
246 {
247     HILOG_DEBUG();
248     std::lock_guard<ffrt::mutex> lock(requestsMutex_);
249     auto iter = requests_.find(requestId);
250     if (iter != requests_.end()) {
251         if (iter->second != nullptr) {
252             iter->second->SetFocusMoveSearchResult(info, requestId);
253         }
254         requests_.erase(iter);
255     } else {
256         HILOG_DEBUG("Can't find the callback [requestId:%d]", requestId);
257     }
258 }
259 
SetExecuteActionResult(const bool succeeded,const int32_t requestId)260 void AccessibilityElementOperatorImpl::SetExecuteActionResult(
261     const bool succeeded, const int32_t requestId)
262 {
263     HILOG_DEBUG();
264     std::lock_guard<ffrt::mutex> lock(requestsMutex_);
265     auto iter = requests_.find(requestId);
266     if (iter != requests_.end()) {
267         if (iter->second != nullptr) {
268             iter->second->SetExecuteActionResult(succeeded, requestId);
269         }
270         requests_.erase(iter);
271     } else {
272         HILOG_DEBUG("Can't find the callback [requestId:%d]", requestId);
273     }
274 }
275 
276 
SetCursorPositionResult(const int32_t cursorPosition,const int32_t requestId)277 void AccessibilityElementOperatorImpl::SetCursorPositionResult(const int32_t cursorPosition, const int32_t requestId)
278 {
279     HILOG_DEBUG();
280     std::lock_guard<ffrt::mutex> lock(requestsMutex_);
281     auto iter = requests_.find(requestId);
282     if (iter != requests_.end()) {
283         if (iter->second != nullptr) {
284             iter->second->SetCursorPositionResult(cursorPosition, requestId);
285         }
286         requests_.erase(iter);
287     } else {
288         HILOG_DEBUG("Can't find the callback [requestId:%d]", requestId);
289     }
290 }
291 
GetCallbackByRequestId(const int32_t requestId)292 sptr<IAccessibilityElementOperatorCallback> AccessibilityElementOperatorImpl::GetCallbackByRequestId(
293     const int32_t requestId)
294 {
295     std::lock_guard<ffrt::mutex> lock(requestsMutex_);
296     auto iter = requests_.find(requestId);
297     if (iter == requests_.end()) {
298         return nullptr;
299     }
300     return iter->second;
301 }
302 
EraseCallback(const int32_t requestId)303 void AccessibilityElementOperatorImpl::EraseCallback(const int32_t requestId)
304 {
305     std::lock_guard<ffrt::mutex> lock(requestsMutex_);
306     auto iter = requests_.find(requestId);
307     if (iter != requests_.end()) {
308         requests_.erase(iter);
309     } else {
310         HILOG_DEBUG("Can't find the callback [requestId:%{public}d]", requestId);
311     }
312 }
313 } // namespace Accessibility
314 } // namespace OHOS