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