1 /*
2 * Copyright (c) 2024 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 "core/accessibility/native_interface_accessibility_provider.h"
17
18 using namespace OHOS::Ace;
19 namespace {
20 constexpr int32_t SEND_EVENT_FAILED = -1;
21 constexpr int32_t SEND_EVENT_SUCCESS = 0;
22
CheckProviderCallback(ArkUI_AccessibilityProviderCallbacks * callbacks)23 bool CheckProviderCallback(ArkUI_AccessibilityProviderCallbacks* callbacks)
24 {
25 if (callbacks == nullptr) {
26 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "callbacks is null");
27 return false;
28 }
29
30 bool result = true;
31 if (callbacks->findAccessibilityNodeInfosById == nullptr) {
32 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosById is null");
33 result = false;
34 }
35
36 if (callbacks->findAccessibilityNodeInfosByText == nullptr) {
37 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosByText is null");
38 result = false;
39 }
40
41 if (callbacks->findFocusedAccessibilityNode == nullptr) {
42 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findFocusedAccessibilityNode is null");
43 result = false;
44 }
45
46 if (callbacks->findNextFocusAccessibilityNode == nullptr) {
47 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findNextFocusAccessibilityNode is null");
48 result = false;
49 }
50
51 if (callbacks->executeAccessibilityAction == nullptr) {
52 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "executeAccessibilityAction is null");
53 result = false;
54 }
55
56 if (callbacks->clearFocusedFocusAccessibilityNode == nullptr) {
57 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "clearFocusedFocusAccessibilityNode is null");
58 result = false;
59 }
60
61 if (callbacks->getAccessibilityNodeCursorPosition == nullptr) {
62 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "getAccessibilityNodeCursorPosition is null");
63 result = false;
64 }
65
66 return result;
67 }
68
CheckProviderCallbackWithInstance(ArkUI_AccessibilityProviderCallbacksWithInstance * callbacks)69 bool CheckProviderCallbackWithInstance(ArkUI_AccessibilityProviderCallbacksWithInstance* callbacks)
70 {
71 if (callbacks == nullptr) {
72 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "callbacks is null");
73 return false;
74 }
75
76 if (callbacks->findAccessibilityNodeInfosById == nullptr) {
77 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosById is null");
78 return false;
79 }
80
81 if (callbacks->findAccessibilityNodeInfosByText == nullptr) {
82 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosByText is null");
83 return false;
84 }
85
86 if (callbacks->findFocusedAccessibilityNode == nullptr) {
87 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findFocusedAccessibilityNode is null");
88 return false;
89 }
90
91 if (callbacks->findNextFocusAccessibilityNode == nullptr) {
92 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findNextFocusAccessibilityNode is null");
93 return false;
94 }
95
96 if (callbacks->executeAccessibilityAction == nullptr) {
97 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "executeAccessibilityAction is null");
98 return false;
99 }
100
101 if (callbacks->clearFocusedFocusAccessibilityNode == nullptr) {
102 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "clearFocusedFocusAccessibilityNode is null");
103 return false;
104 }
105
106 if (callbacks->getAccessibilityNodeCursorPosition == nullptr) {
107 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "getAccessibilityNodeCursorPosition is null");
108 return false;
109 }
110
111 return true;
112 }
113 }
AccessibilityProviderRegisterCallback(ArkUI_AccessibilityProviderCallbacks * callbacks)114 int32_t ArkUI_AccessibilityProvider::AccessibilityProviderRegisterCallback(
115 ArkUI_AccessibilityProviderCallbacks* callbacks)
116 {
117 if (!CheckProviderCallback(callbacks)) {
118 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "CheckProviderCallback failed.");
119 if (registerCallback_) {
120 registerCallback_(false);
121 }
122 return ARKUI_ACCESSIBILITY_NATIVE_RESULT_BAD_PARAMETER;
123 }
124
125 accessibilityProviderCallbacks_ = *callbacks;
126 if (registerCallback_) {
127 registerCallback_(true);
128 }
129 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "AccessibilityProviderRegisterCallback success");
130 return ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL;
131 }
132
AccessibilityProviderRegisterCallbackWithInstance(const char * instanceId,ArkUI_AccessibilityProviderCallbacksWithInstance * callbacks)133 int32_t ArkUI_AccessibilityProvider::AccessibilityProviderRegisterCallbackWithInstance(const char* instanceId,
134 ArkUI_AccessibilityProviderCallbacksWithInstance* callbacks)
135 {
136 if (!CheckProviderCallbackWithInstance(callbacks)) {
137 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "CheckProviderCallbackWithInstance failed.");
138 if (registerCallback_) {
139 registerCallback_(false);
140 }
141 return ARKUI_ACCESSIBILITY_NATIVE_RESULT_BAD_PARAMETER;
142 }
143 accessibilityProviderCallbacksWithInstance_ = *callbacks;
144 if (registerCallback_) {
145 registerCallback_(true);
146 }
147 instanceId_ = instanceId;
148 TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "AccessibilityProviderRegisterCallbackWithInstance success");
149 return ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL;
150 }
151
FindAccessibilityNodeInfosById(const int64_t elementId,const int32_t mode,const int32_t requestId,std::vector<ArkUI_AccessibilityElementInfo> & infos)152 int32_t ArkUI_AccessibilityProvider::FindAccessibilityNodeInfosById(
153 const int64_t elementId, const int32_t mode, const int32_t requestId,
154 std::vector<ArkUI_AccessibilityElementInfo>& infos)
155 {
156 auto accessibilityElementInfoList = std::make_unique<ArkUI_AccessibilityElementInfoList>();
157 int32_t ret = 0;
158 if (accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosById) {
159 ret = accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosById(instanceId_.c_str(),
160 elementId, static_cast<ArkUI_AccessibilitySearchMode>(mode),
161 requestId, accessibilityElementInfoList.get());
162 } else if (accessibilityProviderCallbacks_.findAccessibilityNodeInfosById) {
163 ret = accessibilityProviderCallbacks_.findAccessibilityNodeInfosById(
164 elementId, static_cast<ArkUI_AccessibilitySearchMode>(mode),
165 requestId, accessibilityElementInfoList.get());
166 } else {
167 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosById is null");
168 return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
169 }
170
171 if (!accessibilityElementInfoList->CopyAccessibilityElementInfo(infos)) {
172 ret = AccessibilityProviderOperatorErrorCode::COPY_FAILED;
173 }
174
175 return ret;
176 }
177
FindAccessibilityNodeInfosByText(const int64_t elementId,std::string text,const int32_t requestId,std::vector<ArkUI_AccessibilityElementInfo> & infos)178 int32_t ArkUI_AccessibilityProvider::FindAccessibilityNodeInfosByText(
179 const int64_t elementId, std::string text, const int32_t requestId,
180 std::vector<ArkUI_AccessibilityElementInfo>& infos)
181 {
182 auto accessibilityElementInfoList = std::make_unique<ArkUI_AccessibilityElementInfoList>();
183 int32_t ret = 0;
184 if (accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosByText) {
185 ret = accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosByText(instanceId_.c_str(),
186 elementId, text.c_str(), requestId, accessibilityElementInfoList.get());
187 } else if (accessibilityProviderCallbacks_.findAccessibilityNodeInfosByText) {
188 ret = accessibilityProviderCallbacks_.findAccessibilityNodeInfosByText(
189 elementId, text.c_str(), requestId, accessibilityElementInfoList.get());
190 } else {
191 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosByText is null");
192 return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
193 }
194
195 if (!accessibilityElementInfoList->CopyAccessibilityElementInfo(infos)) {
196 ret = AccessibilityProviderOperatorErrorCode::COPY_FAILED;
197 }
198
199 return ret;
200 }
201
FindFocusedAccessibilityNode(const int64_t elementId,int32_t focusType,const int32_t requestId,ArkUI_AccessibilityElementInfo & elementInfo)202 int32_t ArkUI_AccessibilityProvider::FindFocusedAccessibilityNode(
203 const int64_t elementId, int32_t focusType, const int32_t requestId,
204 ArkUI_AccessibilityElementInfo& elementInfo)
205 {
206 if (accessibilityProviderCallbacksWithInstance_.findFocusedAccessibilityNode) {
207 return accessibilityProviderCallbacksWithInstance_.findFocusedAccessibilityNode(instanceId_.c_str(),
208 elementId, static_cast<ArkUI_AccessibilityFocusType>(focusType), requestId, &elementInfo);
209 } else if (accessibilityProviderCallbacks_.findFocusedAccessibilityNode) {
210 return accessibilityProviderCallbacks_.findFocusedAccessibilityNode(elementId,
211 static_cast<ArkUI_AccessibilityFocusType>(focusType), requestId, &elementInfo);
212 } else {
213 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findFocusedAccessibilityNode is null");
214 return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
215 }
216 }
217
FindNextFocusAccessibilityNode(const int64_t elementId,int32_t direction,const int32_t requestId,ArkUI_AccessibilityElementInfo & elementInfo)218 int32_t ArkUI_AccessibilityProvider::FindNextFocusAccessibilityNode(
219 const int64_t elementId, int32_t direction, const int32_t requestId,
220 ArkUI_AccessibilityElementInfo& elementInfo)
221 {
222 if (accessibilityProviderCallbacksWithInstance_.findNextFocusAccessibilityNode) {
223 return accessibilityProviderCallbacksWithInstance_.findNextFocusAccessibilityNode(instanceId_.c_str(),
224 elementId, static_cast<ArkUI_AccessibilityFocusMoveDirection>(direction), requestId, &elementInfo);
225 } else if (accessibilityProviderCallbacks_.findNextFocusAccessibilityNode) {
226 return accessibilityProviderCallbacks_.findNextFocusAccessibilityNode(elementId,
227 static_cast<ArkUI_AccessibilityFocusMoveDirection>(direction), requestId, &elementInfo);
228 } else {
229 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findNextFocusAccessibilityNode is null");
230 return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
231 }
232 }
233
ExecuteAccessibilityAction(const int64_t elementId,int32_t action,const int32_t requestId,const std::map<std::string,std::string> & actionArguments)234 int32_t ArkUI_AccessibilityProvider::ExecuteAccessibilityAction(
235 const int64_t elementId, int32_t action, const int32_t requestId,
236 const std::map<std::string, std::string>& actionArguments)
237 {
238 auto actionArgumentsUnique = std::make_unique<ArkUI_AccessibilityActionArguments>(actionArguments);
239 if (accessibilityProviderCallbacksWithInstance_.executeAccessibilityAction) {
240 return accessibilityProviderCallbacksWithInstance_.executeAccessibilityAction(instanceId_.c_str(), elementId,
241 static_cast<ArkUI_Accessibility_ActionType>(action),
242 actionArgumentsUnique.get(),
243 requestId);
244 } else if (accessibilityProviderCallbacks_.executeAccessibilityAction) {
245 return accessibilityProviderCallbacks_.executeAccessibilityAction(
246 elementId, static_cast<ArkUI_Accessibility_ActionType>(action),
247 actionArgumentsUnique.get(), requestId);
248 } else {
249 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "executeAccessibilityAction is null");
250 return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
251 }
252 }
253
ClearFocusedAccessibilityNode()254 int32_t ArkUI_AccessibilityProvider::ClearFocusedAccessibilityNode()
255 {
256 if (accessibilityProviderCallbacksWithInstance_.clearFocusedFocusAccessibilityNode) {
257 return accessibilityProviderCallbacksWithInstance_.clearFocusedFocusAccessibilityNode(instanceId_.c_str());
258 } else if (accessibilityProviderCallbacks_.clearFocusedFocusAccessibilityNode) {
259 return accessibilityProviderCallbacks_.clearFocusedFocusAccessibilityNode();
260 } else {
261 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "clearFocusedFocusAccessibilityNode is null");
262 return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
263 }
264 }
265
GetAccessibilityNodeCursorPosition(const int64_t elementId,const int32_t requestId,int32_t & cursorPosition)266 int32_t ArkUI_AccessibilityProvider::GetAccessibilityNodeCursorPosition(
267 const int64_t elementId, const int32_t requestId, int32_t &cursorPosition)
268 {
269 if (accessibilityProviderCallbacksWithInstance_.getAccessibilityNodeCursorPosition) {
270 return accessibilityProviderCallbacksWithInstance_.getAccessibilityNodeCursorPosition(instanceId_.c_str(),
271 elementId, requestId, &cursorPosition);
272 } else if (accessibilityProviderCallbacks_.getAccessibilityNodeCursorPosition) {
273 return accessibilityProviderCallbacks_.getAccessibilityNodeCursorPosition(
274 elementId, requestId, &cursorPosition);
275 } else {
276 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "getAccessibilityNodeCursorPosition is null");
277 return AccessibilityProviderOperatorErrorCode::NOT_REGISTERED;
278 }
279 }
280
SendAccessibilityAsyncEvent(ArkUI_AccessibilityEventInfo * accessibilityEvent,void (* callback)(int32_t errorCode))281 int32_t ArkUI_AccessibilityProvider::SendAccessibilityAsyncEvent(
282 ArkUI_AccessibilityEventInfo* accessibilityEvent,
283 void (*callback)(int32_t errorCode))
284 {
285 if (accessibilityEvent == nullptr) {
286 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "accessibilityEvent is null");
287 if (callback) {
288 callback(SEND_EVENT_FAILED);
289 }
290 return SEND_EVENT_FAILED;
291 }
292
293 auto accessibilityProvider = accessibilityProvider_.Upgrade();
294 if (accessibilityProvider == nullptr) {
295 TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "accessibilityProvider is null");
296 if (callback) {
297 callback(SEND_EVENT_FAILED);
298 }
299 return SEND_EVENT_FAILED;
300 }
301
302 accessibilityProvider->SendAccessibilityAsyncEvent(*accessibilityEvent, callback);
303 return SEND_EVENT_SUCCESS;
304 }
305
SetInnerAccessibilityProvider(const OHOS::Ace::WeakPtr<OHOS::Ace::AccessibilityProvider> & accessibilityProvider)306 void ArkUI_AccessibilityProvider::SetInnerAccessibilityProvider(
307 const OHOS::Ace::WeakPtr<OHOS::Ace::AccessibilityProvider>& accessibilityProvider)
308 {
309 accessibilityProvider_ = accessibilityProvider;
310 }
311
IsRegister()312 bool ArkUI_AccessibilityProvider::IsRegister()
313 {
314 return accessibilityProviderCallbacks_.findAccessibilityNodeInfosById != nullptr ||
315 accessibilityProviderCallbacksWithInstance_.findAccessibilityNodeInfosById != nullptr;
316 }
317
SetRegisterCallback(RegisterCallback callback)318 void ArkUI_AccessibilityProvider::SetRegisterCallback(RegisterCallback callback)
319 {
320 registerCallback_ = callback;
321 }
322