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 "accessible_ability_channel_client.h"
17 
18 #include <cinttypes>
19 #ifdef OHOS_BUILD_ENABLE_HITRACE
20 #include <hitrace_meter.h>
21 #endif // OHOS_BUILD_ENABLE_HITRACE
22 #include "accessibility_element_operator_callback_impl.h"
23 #include "hilog_wrapper.h"
24 
25 namespace OHOS {
26 namespace Accessibility {
27 namespace {
28     constexpr uint32_t TIME_OUT_OPERATOR = 5000;
29     constexpr int32_t REQUEST_ID_MAX = 0x0000FFFF;
30 } // namespace
31 
GenerateRequestId()32 int32_t AccessibleAbilityChannelClient::GenerateRequestId()
33 {
34     int32_t requestId = requestId_++;
35     requestId = requestId % REQUEST_ID_MAX;
36 
37     return requestId;
38 }
39 
GetRemote()40 sptr<IRemoteObject> AccessibleAbilityChannelClient::GetRemote()
41 {
42     return proxy_->AsObject();
43 }
44 
SetOnKeyPressEventResult(const bool handled, const int32_t sequence)45 void AccessibleAbilityChannelClient::SetOnKeyPressEventResult(const bool handled, const int32_t sequence)
46 {
47     HILOG_INFO("[channelId:%{public}d]", channelId_);
48     if (proxy_) {
49         proxy_->SetOnKeyPressEventResult(handled, sequence);
50     } else {
51         HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
52     }
53 }
54 
FindFocusedElementInfo(int32_t accessibilityWindowId, int64_t elementId, int32_t focusType, AccessibilityElementInfo &elementInfo)55 RetError AccessibleAbilityChannelClient::FindFocusedElementInfo(int32_t accessibilityWindowId,
56     int64_t elementId, int32_t focusType, AccessibilityElementInfo &elementInfo)
57 {
58     HILOG_DEBUG("[channelId:%{public}d]", channelId_);
59 #ifdef OHOS_BUILD_ENABLE_HITRACE
60     HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "FindFocusedElement");
61 #endif // OHOS_BUILD_ENABLE_HITRACE
62     if (proxy_ == nullptr) {
63         HILOG_ERROR("FindFocusedElementInfo Failed to connect to aams [channelId:%{public}d]",
64             channelId_);
65         return RET_ERR_SAMGR;
66     }
67 
68     int32_t requestId = GenerateRequestId();
69     sptr<AccessibilityElementOperatorCallbackImpl> elementOperator =
70         new(std::nothrow) AccessibilityElementOperatorCallbackImpl();
71     if (elementOperator == nullptr) {
72         HILOG_ERROR("FindFocusedElementInfo Failed to create elementOperator.");
73         return RET_ERR_NULLPTR;
74     }
75     ffrt::future<void> promiseFuture = elementOperator->promise_.get_future();
76 
77     int32_t windowId = accessibilityWindowId;
78     if (accessibilityWindowId == ANY_WINDOW_ID && focusType == FOCUS_TYPE_ACCESSIBILITY &&
79         accessibilityFocusedWindowId_ != INVALID_WINDOW_ID) {
80         windowId = accessibilityFocusedWindowId_;
81         HILOG_INFO("Convert into accessibility focused window id[%{public}d]", windowId);
82     }
83 
84     RetError ret = proxy_->FindFocusedElementInfo(windowId,
85         elementId, focusType, requestId, elementOperator);
86     if (ret != RET_OK) {
87         HILOG_ERROR("FindFocusedElementInfo failed. ret[%{public}d]", ret);
88         return ret;
89     }
90     HILOG_DEBUG("channelId:%{public}d, windowId:%{public}d, elementId:%{public}" PRId64 ", focusType:%{public}d",
91         channelId_, windowId, elementId, focusType);
92 
93     ffrt::future_status wait = promiseFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
94     if (wait != ffrt::future_status::ready) {
95         HILOG_ERROR("FindFocusedElementInfo Failed to wait result");
96         return RET_ERR_TIME_OUT;
97     }
98 
99     if (elementOperator->accessibilityInfoResult_.GetAccessibilityId() ==
100         AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID) {
101         HILOG_ERROR("FindFocusedElementInfo The elementInfo from ace is wrong");
102         return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
103     }
104     HILOG_INFO("Get result successfully from ace.");
105 
106     elementInfo = elementOperator->accessibilityInfoResult_;
107     return RET_OK;
108 }
109 
SendSimulateGesture( const std::shared_ptr<AccessibilityGestureInjectPath> &gesturePath)110 RetError AccessibleAbilityChannelClient::SendSimulateGesture(
111     const std::shared_ptr<AccessibilityGestureInjectPath> &gesturePath)
112 {
113     HILOG_INFO("[channelId:%{public}d]", channelId_);
114     if (proxy_) {
115         return proxy_->SendSimulateGesture(gesturePath);
116     } else {
117         HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
118         return RET_ERR_SAMGR;
119     }
120 }
121 
GetCursorPosition( int32_t accessibilityWindowId, int64_t elementId, int32_t &position)122 RetError AccessibleAbilityChannelClient::GetCursorPosition(
123     int32_t accessibilityWindowId, int64_t elementId, int32_t &position)
124 {
125 #ifdef OHOS_BUILD_ENABLE_HITRACE
126     HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "GetCursorPosition");
127 #endif // OHOS_BUILD_ENABLE_HITRACE
128     if (proxy_ == nullptr) {
129         HILOG_ERROR("GetCursorPosition Failed to connect to aams [channelId:%{public}d]",
130             channelId_);
131         return RET_ERR_SAMGR;
132     }
133 
134     int32_t requestId = GenerateRequestId();
135     sptr<AccessibilityElementOperatorCallbackImpl> elementOperator =
136         new(std::nothrow) AccessibilityElementOperatorCallbackImpl();
137     if (elementOperator == nullptr) {
138         HILOG_ERROR("GetCursorPosition Failed to create elementOperator.");
139         return RET_ERR_NULLPTR;
140     }
141     ffrt::future<void> promiseFuture = elementOperator->promise_.get_future();
142 
143     RetError ret = proxy_->GetCursorPosition(accessibilityWindowId, elementId, requestId, elementOperator);
144     if (ret != RET_OK) {
145         HILOG_ERROR("ExecuteAction failed. ret[%{public}d]", ret);
146         return ret;
147     }
148 
149     ffrt::future_status wait = promiseFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
150     if (wait != ffrt::future_status::ready) {
151         HILOG_ERROR("GetCursorPosition Failed to wait result");
152         return RET_ERR_TIME_OUT;
153     }
154 
155     position = elementOperator->CursorPosition_;
156     HILOG_INFO("position%{public}d", position);
157     return RET_OK;
158 }
159 
ExecuteAction(int32_t accessibilityWindowId, int64_t elementId, int32_t action, const std::map<std::string, std::string> &actionArguments)160 RetError AccessibleAbilityChannelClient::ExecuteAction(int32_t accessibilityWindowId,
161     int64_t elementId, int32_t action, const std::map<std::string, std::string> &actionArguments)
162 {
163     HILOG_DEBUG("execute action:%{public}d, elementId:%{public}" PRId64 "", action, elementId);
164 #ifdef OHOS_BUILD_ENABLE_HITRACE
165     HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "ExecuteAction");
166 #endif // OHOS_BUILD_ENABLE_HITRACE
167     if (proxy_ == nullptr) {
168         HILOG_ERROR("ExecuteAction Failed to connect to aams [channelId:%{public}d]", channelId_);
169         return RET_ERR_SAMGR;
170     }
171     if (action == ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS &&
172         accessibilityFocusedElementId_ != INVALID_WINDOW_ID && accessibilityFocusedWindowId_ != INVALID_WINDOW_ID) {
173         ExecuteAction(accessibilityFocusedWindowId_, accessibilityFocusedElementId_,
174             ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS, actionArguments);
175     }
176 
177     int32_t requestId = GenerateRequestId();
178     sptr<AccessibilityElementOperatorCallbackImpl> elementOperator =
179         new(std::nothrow) AccessibilityElementOperatorCallbackImpl();
180     if (elementOperator == nullptr) {
181         HILOG_ERROR("ExecuteAction Failed to create elementOperator.");
182         return RET_ERR_NULLPTR;
183     }
184     ffrt::future<void> promiseFuture = elementOperator->promise_.get_future();
185 
186     RetError ret = proxy_->ExecuteAction(accessibilityWindowId,
187         elementId, action, actionArguments, requestId, elementOperator);
188     if (ret != RET_OK) {
189         HILOG_ERROR("ExecuteAction failed. action[%{public}d], ret[%{public}d]", action, ret);
190         return ret;
191     }
192 
193     ffrt::future_status wait = promiseFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
194     if (wait != ffrt::future_status::ready) {
195         HILOG_ERROR("execute action: %{public}d failed to wait result", action);
196         return RET_ERR_TIME_OUT;
197     }
198     HILOG_INFO("action:[%{public}d], executeActionResult_[%{public}d]", action, elementOperator->executeActionResult_);
199 
200     if (elementOperator->executeActionResult_) {
201         switch (action) {
202             case ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS:
203                 accessibilityFocusedWindowId_ = accessibilityWindowId;
204                 accessibilityFocusedElementId_ = elementId;
205                 break;
206             case ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS:
207                 accessibilityFocusedWindowId_ = INVALID_WINDOW_ID;
208                 accessibilityFocusedElementId_ = INVALID_WINDOW_ID;
209                 break;
210             default:
211                 break;
212         }
213     }
214     return elementOperator->executeActionResult_ ? RET_OK : RET_ERR_PERFORM_ACTION_FAILED_BY_ACE;
215 }
216 
EnableScreenCurtain(bool isEnable)217 RetError AccessibleAbilityChannelClient::EnableScreenCurtain(bool isEnable)
218 {
219     HILOG_INFO("[channelId:%{public}d]", channelId_);
220     if (proxy_ == nullptr) {
221         HILOG_ERROR("EnableScreenCurtain Failed to connect to aams [channelId:%{public}d]", channelId_);
222         return RET_ERR_SAMGR;
223     }
224     return  proxy_->EnableScreenCurtain(isEnable) ? RET_OK : RET_ERR_PERFORM_ACTION_FAILED_BY_ACE;
225 }
226 
SearchElementInfosByAccessibilityId(int32_t accessibilityWindowId, int64_t elementId, int32_t mode, std::vector<AccessibilityElementInfo> &elementInfos, int32_t treeId, bool isFilter)227 RetError AccessibleAbilityChannelClient::SearchElementInfosByAccessibilityId(int32_t accessibilityWindowId,
228     int64_t elementId, int32_t mode, std::vector<AccessibilityElementInfo> &elementInfos, int32_t treeId,
229     bool isFilter)
230 {
231     int32_t requestId = GenerateRequestId();
232     HILOG_DEBUG("channelId:%{public}d, elementId:%{public}" PRId64 ", windowId:%{public}d, requestId:%{public}d",
233         channelId_, elementId, accessibilityWindowId, requestId);
234 #ifdef OHOS_BUILD_ENABLE_HITRACE
235     HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "SearchElementById");
236 #endif // OHOS_BUILD_ENABLE_HITRACE
237     if (proxy_ == nullptr) {
238         HILOG_ERROR("SearchElementInfosByAccessibilityId Failed to connect to aams [channelId:%{public}d]",
239             channelId_);
240         return RET_ERR_SAMGR;
241     }
242 
243     sptr<AccessibilityElementOperatorCallbackImpl> elementOperator =
244         new(std::nothrow) AccessibilityElementOperatorCallbackImpl();
245     if (elementOperator == nullptr) {
246         HILOG_ERROR("SearchElementInfosByAccessibilityId Failed to create elementOperator.");
247         return RET_ERR_NULLPTR;
248     }
249     ffrt::future<void> promiseFuture = elementOperator->promise_.get_future();
250     ElementBasicInfo elementBasicInfo {};
251     elementBasicInfo.windowId = accessibilityWindowId;
252     elementBasicInfo.treeId = treeId;
253     elementBasicInfo.elementId = elementId;
254 
255     RetError ret = proxy_->SearchElementInfoByAccessibilityId(elementBasicInfo, requestId,
256         elementOperator, mode, isFilter);
257     if (ret != RET_OK) {
258         HILOG_ERROR("SearchElementInfosByAccessibilityId windowId :[%{pubic}d] Failed to wait result, Time out",
259             accessibilityWindowId);
260         return ret;
261     }
262 
263     ffrt::future_status wait = promiseFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
264     if (wait != ffrt::future_status::ready) {
265         HILOG_ERROR("SearchElementInfosByAccessibilityId Failed to wait result");
266         return RET_ERR_TIME_OUT;
267     }
268 
269     for (auto &info : elementOperator->elementInfosResult_) {
270         if (info.GetAccessibilityId() == AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID) {
271             HILOG_ERROR("SearchElementInfosByAccessibilityId The elementInfo from ace is wrong");
272             return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
273         }
274     }
275     HILOG_DEBUG("Get result successfully from ace. size[%{public}zu]", elementOperator->elementInfosResult_.size());
276     elementInfos = elementOperator->elementInfosResult_;
277     return RET_OK;
278 }
279 
GetWindow(const int32_t windowId, AccessibilityWindowInfo &windowInfo)280 RetError AccessibleAbilityChannelClient::GetWindow(const int32_t windowId, AccessibilityWindowInfo &windowInfo)
281 {
282     HILOG_DEBUG("[channelId:%{public}d] [windowId:%{public}d]", channelId_, windowId);
283 #ifdef OHOS_BUILD_ENABLE_HITRACE
284     HITRACE_METER(HITRACE_TAG_ACCESSIBILITY_MANAGER);
285 #endif // OHOS_BUILD_ENABLE_HITRACE
286     if (proxy_ == nullptr) {
287         HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
288         return RET_ERR_SAMGR;
289     }
290     return proxy_->GetWindow(windowId, windowInfo);
291 }
292 
GetWindows(std::vector<AccessibilityWindowInfo> &windows)293 RetError AccessibleAbilityChannelClient::GetWindows(std::vector<AccessibilityWindowInfo> &windows)
294 {
295     HILOG_DEBUG("[channelId:%{public}d]", channelId_);
296 #ifdef OHOS_BUILD_ENABLE_HITRACE
297     HITRACE_METER(HITRACE_TAG_ACCESSIBILITY_MANAGER);
298 #endif // OHOS_BUILD_ENABLE_HITRACE
299     if (proxy_) {
300         return proxy_->GetWindows(windows);
301     } else {
302         HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
303         return RET_ERR_SAMGR;
304     }
305 }
306 
GetWindows(const uint64_t displayId, std::vector<AccessibilityWindowInfo> &windows) const307 RetError AccessibleAbilityChannelClient::GetWindows(const uint64_t displayId,
308     std::vector<AccessibilityWindowInfo> &windows) const
309 {
310     HILOG_DEBUG("[channelId:%{public}d] [displayId:%{public}" PRIu64 "]", channelId_, displayId);
311 #ifdef OHOS_BUILD_ENABLE_HITRACE
312     HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "GetWindowsByDisplayId");
313 #endif // OHOS_BUILD_ENABLE_HITRACE
314     if (proxy_) {
315         return proxy_->GetWindowsByDisplayId(displayId, windows);
316     } else {
317         HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
318         return RET_ERR_SAMGR;
319     }
320 }
321 
SearchElementInfosByText(int32_t accessibilityWindowId, int64_t elementId, const std::string &text, std::vector<AccessibilityElementInfo> &elementInfos)322 RetError AccessibleAbilityChannelClient::SearchElementInfosByText(int32_t accessibilityWindowId,
323     int64_t elementId, const std::string &text, std::vector<AccessibilityElementInfo> &elementInfos)
324 {
325     HILOG_DEBUG("[channelId:%{public}d]", channelId_);
326 #ifdef OHOS_BUILD_ENABLE_HITRACE
327     HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "SearchElementByText");
328 #endif // OHOS_BUILD_ENABLE_HITRACE
329     if (proxy_ == nullptr) {
330         HILOG_ERROR("SearchElementInfosByText Failed to connect to aams [channelId:%{public}d]",
331             channelId_);
332         return RET_ERR_SAMGR;
333     }
334 
335     int32_t requestId = GenerateRequestId();
336     sptr<AccessibilityElementOperatorCallbackImpl> elementOperator =
337         new(std::nothrow) AccessibilityElementOperatorCallbackImpl();
338     if (elementOperator == nullptr) {
339         HILOG_ERROR("SearchElementInfosByText Failed to create elementOperator.");
340         return RET_ERR_NULLPTR;
341     }
342     ffrt::future<void> promiseFuture = elementOperator->promise_.get_future();
343 
344     RetError ret = proxy_->SearchElementInfosByText(accessibilityWindowId,
345         elementId, text, requestId, elementOperator);
346     if (ret != RET_OK) {
347         HILOG_ERROR("SearchElementInfosByText failed. ret[%{public}d]", ret);
348         return ret;
349     }
350 
351     ffrt::future_status wait = promiseFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
352     if (wait != ffrt::future_status::ready) {
353         HILOG_ERROR("SearchElementInfosByText Failed to wait result");
354         return RET_ERR_TIME_OUT;
355     }
356 
357     for (auto &info : elementOperator->elementInfosResult_) {
358         if (info.GetAccessibilityId() == AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID) {
359             HILOG_ERROR("SearchElementInfosByText The elementInfo from ace is wrong");
360             return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
361         }
362     }
363     HILOG_INFO("Get result successfully from ace. size[%{public}zu]", elementOperator->elementInfosResult_.size());
364     elementInfos = elementOperator->elementInfosResult_;
365     return RET_OK;
366 }
367 
FocusMoveSearch(int32_t accessibilityWindowId, int64_t elementId, int32_t direction, AccessibilityElementInfo &elementInfo)368 RetError AccessibleAbilityChannelClient::FocusMoveSearch(int32_t accessibilityWindowId,
369     int64_t elementId, int32_t direction, AccessibilityElementInfo &elementInfo)
370 {
371     HILOG_DEBUG("[channelId:%{public}d]", channelId_);
372     if (proxy_ == nullptr) {
373         HILOG_ERROR("FocusMoveSearch Failed to connect to aams [channelId:%{public}d]", channelId_);
374         return RET_ERR_SAMGR;
375     }
376 
377     int32_t requestId = GenerateRequestId();
378     sptr<AccessibilityElementOperatorCallbackImpl> elementOperator =
379         new(std::nothrow) AccessibilityElementOperatorCallbackImpl();
380     if (elementOperator == nullptr) {
381         HILOG_ERROR("FocusMoveSearch Failed to create elementOperator.");
382         return RET_ERR_NULLPTR;
383     }
384     ffrt::future<void> promiseFuture = elementOperator->promise_.get_future();
385 
386     RetError ret = proxy_->FocusMoveSearch(accessibilityWindowId, elementId, direction, requestId, elementOperator);
387     if (ret != RET_OK) {
388         HILOG_ERROR("FocusMoveSearch failed. ret[%{public}d]", ret);
389         return ret;
390     }
391 
392     ffrt::future_status wait = promiseFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
393     if (wait != ffrt::future_status::ready) {
394         HILOG_ERROR("FocusMoveSearch Failed to wait result");
395         return RET_ERR_TIME_OUT;
396     }
397 
398     if (elementOperator->accessibilityInfoResult_.GetAccessibilityId() ==
399         AccessibilityElementInfo::UNDEFINED_ACCESSIBILITY_ID) {
400         HILOG_ERROR("FocusMoveSearch The elementInfo from ace is wrong");
401         return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
402     }
403 
404     HILOG_INFO("Get result successfully from ace");
405     elementInfo = elementOperator->accessibilityInfoResult_;
406     return RET_OK;
407 }
408 
SetTargetBundleName(const std::vector<std::string> &targetBundleNames)409 RetError AccessibleAbilityChannelClient::SetTargetBundleName(const std::vector<std::string> &targetBundleNames)
410 {
411     HILOG_INFO("[channelId:%{public}d]", channelId_);
412     if (proxy_) {
413         return proxy_->SetTargetBundleName(targetBundleNames);
414     } else {
415         HILOG_ERROR("Failed to connect to aams [channelId:%{public}d]", channelId_);
416         return RET_ERR_SAMGR;
417     }
418 }
419 } // namespace Accessibility
420 } // namespace OHOS
421