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_operator.h"
17 #include "accessibility_system_ability_client.h"
18
19 namespace OHOS {
20 namespace Accessibility {
21 std::map<int, sptr<IAccessibleAbilityChannel>> AccessibilityOperator::channels_ = {};
22 std::vector<sptr<AccessibilityOperator>> AccessibilityOperator::instances_ = {};
23 std::recursive_mutex AccessibilityOperator::mutex_ = {};
24
AccessibilityOperator()25 AccessibilityOperator::AccessibilityOperator()
26 {
27 executeActionResult_ = false;
28 }
29
~AccessibilityOperator()30 AccessibilityOperator::~AccessibilityOperator()
31 {
32 }
33
GetInstance()34 AccessibilityOperator &AccessibilityOperator::GetInstance()
35 {
36 std::thread::id tid = std::this_thread::get_id();
37 HILOG_DEBUG("threadId[%{public}u]", (*(uint32_t*)&tid));
38 std::lock_guard<std::recursive_mutex> lock(mutex_);
39 if (instances_.size() >= MAX_INSTANCE) {
40 for (auto iter = instances_.begin(); iter != instances_.end(); iter++) {
41 if (iter->GetRefPtr() != nullptr &&
42 iter->GetRefPtr()->asyncElementOperatorMng_.GetOperationStatus()) {
43 HILOG_DEBUG("complete instance is removed");
44 instances_.erase(iter);
45 break;
46 }
47 }
48 }
49
50 HILOG_DEBUG("new instance instanceSize[%{public}u]", instances_.size());
51 sptr<AccessibilityOperator> inst(new AccessibilityOperator());
52 instances_.push_back(inst);
53
54 HILOG_DEBUG("End instanceSize[%{public}u]", instances_.size());
55 return *(inst.GetRefPtr());
56 }
57
GetChannel(int channelId)58 sptr<IAccessibleAbilityChannel> AccessibilityOperator::GetChannel(int channelId)
59 {
60 auto channel = channels_.find(channelId);
61 if (channel != channels_.end()) {
62 HILOG_DEBUG("Find aams [channelId:%{public}d]", channelId);
63 return channel->second;
64 } else {
65 HILOG_ERROR("Failed to find aams [channelId:%{public}d]", channelId);
66 return nullptr;
67 }
68 }
69
AddChannel(const int channelId,const sptr<IAccessibleAbilityChannel> & channel)70 void AccessibilityOperator::AddChannel(const int channelId, const sptr<IAccessibleAbilityChannel> &channel)
71 {
72 HILOG_DEBUG("Add channel to aams [channelId:%{public}d]", channelId);
73 int tempId = *(const_cast<int *>(&channelId));
74 for (auto iter = channels_.begin(); iter != channels_.end(); iter++) {
75 if (iter->first == tempId) {
76 HILOG_ERROR("channel to aams [channelId:%{public}d] is exited", channelId);
77 return;
78 }
79 }
80 sptr<IAccessibleAbilityChannel> tempChanel = const_cast<sptr<IAccessibleAbilityChannel> &>(channel);
81 channels_.insert(std::pair<int, sptr<IAccessibleAbilityChannel>>(tempId, tempChanel));
82 }
83
RemoveChannel(int channelId)84 void AccessibilityOperator::RemoveChannel(int channelId)
85 {
86 HILOG_DEBUG("Remove channel to aams [channelId:%{public}d]", channelId);
87 auto iter = channels_.find(channelId);
88 if (iter != channels_.end()) {
89 channels_.erase(iter);
90 } else {
91 HILOG_DEBUG("Failed to remove channel with aams [channelId:%{public}d]", channelId);
92 }
93 }
94
GetRoot(int channelId,AccessibilityElementInfo & elementInfo)95 bool AccessibilityOperator::GetRoot(int channelId, AccessibilityElementInfo &elementInfo)
96 {
97 AccessibilityElementInfo element {};
98 std::vector<AccessibilityElementInfo> elementInfos {};
99 int activeWindow = AccessibilitySystemAbilityClient::GetInstance()->GetActiveWindow();
100 HILOG_DEBUG("activeWindow is %{public}d", activeWindow);
101 bool result = SearchElementInfosByAccessibilityId(channelId, activeWindow, NONE_ID, 0, elementInfos);
102 for (auto& info : elementInfos) {
103 HILOG_DEBUG("element [elementSize:%{public}d]", elementInfosResult_.size());
104 elementInfo = info;
105 break;
106 }
107 return result;
108 }
109
GetWindows(int channelId)110 std::vector<AccessibilityWindowInfo> AccessibilityOperator::GetWindows(int channelId)
111 {
112 auto channelService = GetChannel(channelId);
113 if (channelService != nullptr) {
114 auto windows = channelService->GetWindows();
115 for (auto &window : windows) {
116 window.SetChannelId(channelId);
117 }
118 return windows;
119 } else {
120 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId);
121 return windows_;
122 }
123 }
124
SearchElementInfosByAccessibilityId(int channelId,int accessibilityWindowId,int elementId,int mode,std::vector<AccessibilityElementInfo> & elementInfos)125 bool AccessibilityOperator::SearchElementInfosByAccessibilityId(int channelId,
126 int accessibilityWindowId, int elementId, int mode, std::vector<AccessibilityElementInfo>& elementInfos)
127 {
128 HILOG_DEBUG("[channelId:%{public}d] [windowId:%{public}d]", channelId, accessibilityWindowId);
129 bool result = false;
130 auto channelService = GetChannel(channelId);
131 if (channelService != nullptr) {
132 int sequenceNum = asyncElementOperatorMng_.RecordSearchSequence();
133 HILOG_DEBUG("search element info [channelId:%{public}d] [sequenceNum:%{public}d]",
134 channelId, sequenceNum);
135 result = channelService->SearchElementInfoByAccessibilityId(accessibilityWindowId, elementId, sequenceNum,
136 this, mode);
137 if (!result) {
138 return result;
139 }
140 HILOG_DEBUG("search element info End[channelId:%{public}d] [sequenceNum:%{public}d]",
141 channelId, sequenceNum);
142 if (!asyncElementOperatorMng_.SearchElementResultTimer(sequenceNum)) {
143 HILOG_ERROR("Failed to wait result");
144 result = false;
145 return result;
146 }
147 }
148 HILOG_DEBUG("search element info OK [channelId:%{public}d]", channelId);
149 for (auto& info : elementInfosResult_) {
150 info.SetChannelId(channelId);
151 }
152 asyncElementOperatorMng_.SetOperationStatus(true);
153 HILOG_DEBUG("search element info End[size:%{public}d]", elementInfosResult_.size());
154 elementInfos = elementInfosResult_;
155 return result;
156 }
157
SearchElementInfosByText(int channelId,int accessibilityWindowId,int elementId,const std::string & text,std::vector<AccessibilityElementInfo> & elementInfos)158 bool AccessibilityOperator::SearchElementInfosByText(int channelId, int accessibilityWindowId,
159 int elementId, const std::string &text, std::vector<AccessibilityElementInfo>& elementInfos)
160 {
161 HILOG_DEBUG("[channelId:%{public}d]", channelId);
162 bool result = false;
163 auto channelService = GetChannel(channelId);
164 if (channelService != nullptr) {
165 int sequenceNum = asyncElementOperatorMng_.RecordSearchSequence();
166 result = channelService->SearchElementInfosByText(accessibilityWindowId, elementId, text, sequenceNum,
167 this);
168 if (!result) {
169 return result;
170 }
171 if (!asyncElementOperatorMng_.SearchElementResultTimer(sequenceNum)) {
172 HILOG_ERROR("Failed to wait result");
173 result = false;
174 return result;
175 }
176 }
177
178 for (auto& info : elementInfosResult_) {
179 info.SetChannelId(channelId);
180 }
181 asyncElementOperatorMng_.SetOperationStatus(true);
182 HILOG_DEBUG("[size:%{public}d] end", elementInfosResult_.size());
183 elementInfos = elementInfosResult_;
184
185 return result;
186 }
187
FindFocusedElementInfo(int channelId,int accessibilityWindowId,int elementId,int focusType,AccessibilityElementInfo & elementInfo)188 bool AccessibilityOperator::FindFocusedElementInfo(int channelId, int accessibilityWindowId,
189 int elementId, int focusType, AccessibilityElementInfo& elementInfo)
190 {
191 HILOG_DEBUG("[channelId:%{public}d]", channelId);
192 bool result = false;
193 auto channelService = GetChannel(channelId);
194 if (channelService != nullptr) {
195 int sequenceNum = asyncElementOperatorMng_.RecordSearchSequence();
196 result = channelService->FindFocusedElementInfo(accessibilityWindowId, elementId,
197 focusType, sequenceNum, this);
198 if (!result) {
199 return result;
200 }
201
202 HILOG_DEBUG("FindFocusedElementInfo channelId[%{public}d] elementId[%{public}d],\
203 focusType[%{public}d] sequenceNum[%{public}d]",
204 channelId, accessibilityWindowId, elementId, focusType);
205 if (!asyncElementOperatorMng_.SearchElementResultTimer(sequenceNum)) {
206 HILOG_ERROR("Failed to wait result");
207 result = false;
208 return result;
209 }
210 }
211 accessibilityInfoResult_.SetChannelId(channelId);
212 asyncElementOperatorMng_.SetOperationStatus(true);
213 HILOG_DEBUG("[channelId:%{public}d] end", channelId);
214 if ((!accessibilityInfoResult_.GetWindowId()) && (!accessibilityInfoResult_.GetAccessibilityId())) {
215 HILOG_DEBUG("Can't find the component info");
216 result = false;
217 } else {
218 elementInfo = accessibilityInfoResult_;
219 result = true;
220 }
221
222 return result;
223 }
224
FocusMoveSearch(int channelId,int accessibilityWindowId,int elementId,int direction,AccessibilityElementInfo & elementInfo)225 bool AccessibilityOperator::FocusMoveSearch(int channelId, int accessibilityWindowId,
226 int elementId, int direction, AccessibilityElementInfo& elementInfo)
227 {
228 HILOG_DEBUG("[channelId:%{public}d]", channelId);
229 bool result = false;
230 auto channelService = GetChannel(channelId);
231 if (channelService != nullptr) {
232 int sequenceNum = asyncElementOperatorMng_.RecordSearchSequence();
233 result = channelService->FocusMoveSearch(accessibilityWindowId, elementId, direction, sequenceNum, this);
234 if (!result) {
235 return result;
236 }
237 if (!asyncElementOperatorMng_.SearchElementResultTimer(sequenceNum)) {
238 HILOG_ERROR("Failed to wait result");
239 result = false;
240 return result;
241 }
242 }
243
244 accessibilityInfoResult_.SetChannelId(channelId);
245 asyncElementOperatorMng_.SetOperationStatus(true);
246 HILOG_DEBUG("[channelId:%{public}d] end", channelId);
247 elementInfo = accessibilityInfoResult_;
248 if ((!accessibilityInfoResult_.GetWindowId()) && (!accessibilityInfoResult_.GetAccessibilityId())) {
249 HILOG_DEBUG("Can't find the component info");
250 result = false;
251 } else {
252 result = true;
253 }
254 return result;
255 }
256
ExecuteAction(int channelId,int accessibilityWindowId,int elementId,int action,std::map<std::string,std::string> & actionArguments)257 bool AccessibilityOperator::ExecuteAction(int channelId, int accessibilityWindowId,
258 int elementId, int action, std::map<std::string, std::string> &actionArguments)
259 {
260 HILOG_DEBUG("[channelId:%{public}d]", channelId);
261 auto channelService = GetChannel(channelId);
262 if (channelService != nullptr) {
263 int sequenceNum = asyncElementOperatorMng_.RecordSearchSequence();
264 bool result = channelService->ExecuteAction(
265 accessibilityWindowId, elementId, action, actionArguments,
266 sequenceNum, this);
267 if (!result) {
268 return result;
269 }
270
271 if (!asyncElementOperatorMng_.SearchElementResultTimer(sequenceNum)) {
272 HILOG_ERROR("Failed to wait result");
273 return false;
274 }
275 }
276 asyncElementOperatorMng_.SetOperationStatus(true);
277 HILOG_DEBUG("[channelId:%{public}d] end", channelId);
278 return executeActionResult_;
279 }
280
SetSearchElementInfoByAccessibilityIdResult(const std::vector<AccessibilityElementInfo> & infos,const int sequenceNum)281 void AccessibilityOperator::SetSearchElementInfoByAccessibilityIdResult(
282 const std::vector<AccessibilityElementInfo> &infos, const int sequenceNum)
283 {
284 HILOG_DEBUG("Response[elementInfoSize:%{public}d] [sequenceNum:%{public}d]",
285 infos.size(), sequenceNum);
286 for (auto iter = infos.begin(); iter != infos.end(); iter++) {
287 HILOG_DEBUG("Response");
288 elementInfosResult_.push_back(*iter);
289 }
290 asyncElementOperatorMng_.UpdateSearchFeedback(sequenceNum);
291 HILOG_DEBUG("Response [sequenceNum:%{public}d] end", sequenceNum);
292 }
293
SetSearchElementInfoByTextResult(const std::vector<AccessibilityElementInfo> & infos,const int sequenceNum)294 void AccessibilityOperator::SetSearchElementInfoByTextResult(const std::vector<AccessibilityElementInfo> &infos,
295 const int sequenceNum)
296 {
297 HILOG_DEBUG("Response [elementInfoSize:%{public}d] [sequenceNum:%{public}d]",
298 infos.size(), sequenceNum);
299 for (auto iter = infos.begin(); iter != infos.end(); iter++) {
300 elementInfosResult_.push_back(*iter);
301 }
302 asyncElementOperatorMng_.UpdateSearchFeedback(sequenceNum);
303 HILOG_DEBUG("Response [sequenceNum:%{public}d] end", sequenceNum);
304 }
305
SetFindFocusedElementInfoResult(const AccessibilityElementInfo & info,const int sequenceNum)306 void AccessibilityOperator::SetFindFocusedElementInfoResult(const AccessibilityElementInfo &info,
307 const int sequenceNum)
308 {
309 HILOG_DEBUG("Response [sequenceNum:%{public}d]", sequenceNum);
310 accessibilityInfoResult_ = info;
311 asyncElementOperatorMng_.UpdateSearchFeedback(sequenceNum);
312 HILOG_DEBUG("Response [sequenceNum:%{public}d] end", sequenceNum);
313 }
314
SetFocusMoveSearchResult(const AccessibilityElementInfo & info,const int sequenceNum)315 void AccessibilityOperator::SetFocusMoveSearchResult(const AccessibilityElementInfo &info, const int sequenceNum)
316 {
317 HILOG_DEBUG("Response [sequenceNum:%{public}d]", sequenceNum);
318 accessibilityInfoResult_ = info;
319 asyncElementOperatorMng_.UpdateSearchFeedback(sequenceNum);
320 HILOG_DEBUG("Response [sequenceNum:%{public}d] end", sequenceNum);
321 }
322
SetExecuteActionResult(const bool succeeded,const int sequenceNum)323 void AccessibilityOperator::SetExecuteActionResult(const bool succeeded, const int sequenceNum)
324 {
325 HILOG_DEBUG("Response [sequenceNum:%{public}d] result[%{public}d]", sequenceNum, succeeded);
326 executeActionResult_ = succeeded;
327 asyncElementOperatorMng_.UpdateSearchFeedback(sequenceNum);
328 HILOG_DEBUG("Response [sequenceNum:%{public}d] end", sequenceNum);
329 }
330
ExecuteCommonAction(const int channelId,const int action)331 bool AccessibilityOperator::ExecuteCommonAction(const int channelId, const int action)
332 {
333 HILOG_INFO("[channelId:%{public}d]", channelId);
334 auto channelService = GetChannel(channelId);
335 if (channelService != nullptr) {
336 return channelService->ExecuteCommonAction(action);
337 } else {
338 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId);
339 return false;
340 }
341 }
342
SetOnKeyPressEventResult(const int channelId,const bool handled,const int sequence)343 void AccessibilityOperator::SetOnKeyPressEventResult(const int channelId, const bool handled, const int sequence)
344 {
345 HILOG_INFO("[channelId:%{public}d]", channelId);
346 auto channelService = GetChannel(channelId);
347 if (channelService != nullptr) {
348 channelService->SetOnKeyPressEventResult(handled, sequence);
349 } else {
350 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId);
351 }
352 }
353
GetDisplayResizeScale(const int channelId,const int displayId)354 float AccessibilityOperator::GetDisplayResizeScale(const int channelId, const int displayId)
355 {
356 HILOG_INFO("[channelId:%{public}d]", channelId);
357 auto channelService = GetChannel(channelId);
358 if (channelService != nullptr) {
359 return channelService->GetDisplayResizeScale(displayId);
360 } else {
361 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId);
362 return 1;
363 }
364 }
365
GetDisplayResizeCenterX(const int channelId,const int displayId)366 float AccessibilityOperator::GetDisplayResizeCenterX(const int channelId, const int displayId)
367 {
368 HILOG_INFO("[channelId:%{public}d]", channelId);
369 auto channelService = GetChannel(channelId);
370 if (channelService != nullptr) {
371 return channelService->GetDisplayResizeCenterX(displayId);
372 } else {
373 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId);
374 return 1;
375 }
376 }
377
GetDisplayResizeCenterY(const int channelId,const int displayId)378 float AccessibilityOperator::GetDisplayResizeCenterY(const int channelId, const int displayId)
379 {
380 HILOG_INFO("[channelId:%{public}d]", channelId);
381 auto channelService = GetChannel(channelId);
382 if (channelService != nullptr) {
383 return channelService->GetDisplayResizeCenterY(displayId);
384 } else {
385 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId);
386 return 1;
387 }
388 }
389
GetDisplayResizeRect(const int channelId,const int displayId)390 Rect AccessibilityOperator::GetDisplayResizeRect(const int channelId, const int displayId)
391 {
392 HILOG_INFO("[channelId:%{public}d]", channelId);
393 auto channelService = GetChannel(channelId);
394 if (channelService != nullptr) {
395 return channelService->GetDisplayResizeRect(displayId);
396 } else {
397 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId);
398 Rect rect {};
399 return rect;
400 }
401 }
402
ResetDisplayResize(const int channelId,const int displayId,const bool animate)403 bool AccessibilityOperator::ResetDisplayResize(const int channelId, const int displayId, const bool animate)
404 {
405 HILOG_INFO("[channelId:%{public}d]", channelId);
406 auto channelService = GetChannel(channelId);
407 if (channelService != nullptr) {
408 return channelService->ResetDisplayResize(displayId, animate);
409 } else {
410 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId);
411 return false;
412 }
413 }
414
SetDisplayResizeScaleAndCenter(const int channelId,const int displayId,const float scale,const float centerX,const float centerY,const bool animate)415 bool AccessibilityOperator::SetDisplayResizeScaleAndCenter(const int channelId,
416 const int displayId, const float scale, const float centerX,
417 const float centerY, const bool animate)
418 {
419 HILOG_INFO("[channelId:%{public}d]", channelId);
420 auto channelService = GetChannel(channelId);
421 if (channelService != nullptr) {
422 return channelService->SetDisplayResizeScaleAndCenter(displayId, scale, centerX,
423 centerY, animate);
424 } else {
425 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId);
426 return false;
427 }
428 }
429
SendSimulateGesture(const int channelId,const int sequenceNum,const std::vector<GesturePathDefine> & gestureSteps)430 void AccessibilityOperator::SendSimulateGesture(const int channelId,
431 const int sequenceNum, const std::vector<GesturePathDefine> &gestureSteps)
432 {
433 HILOG_INFO("[channelId:%{public}d]", channelId);
434 auto channelService = GetChannel(channelId);
435 if (channelService != nullptr) {
436 channelService->SendSimulateGesture(sequenceNum, gestureSteps);
437 } else {
438 HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId);
439 }
440 }
441 } // namespace Accessibility
442 } // namespace OHOS