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 NOT_REGISTERED = -1;
21 constexpr int32_t COPY_FAILED = -2;
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 }
70 }
AccessibilityProviderRegisterCallback(ArkUI_AccessibilityProviderCallbacks * callbacks)71 int32_t ArkUI_AccessibilityProvider::AccessibilityProviderRegisterCallback(
72     ArkUI_AccessibilityProviderCallbacks* callbacks)
73 {
74     if (!CheckProviderCallback(callbacks)) {
75         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "CheckProviderCallback failed.");
76         if (registerCallback_) {
77             registerCallback_(false);
78         }
79         return ARKUI_ACCESSIBILITY_NATIVE_RESULT_BAD_PARAMETER;
80     }
81 
82     accessibilityProviderCallbacks_ = callbacks;
83     if (registerCallback_) {
84         registerCallback_(true);
85     }
86     TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "AccessibilityProviderRegisterCallback success");
87     return ARKUI_ACCESSIBILITY_NATIVE_RESULT_SUCCESSFUL;
88 }
89 
FindAccessibilityNodeInfosById(const int64_t elementId,const int32_t mode,const int32_t requestId,std::vector<ArkUI_AccessibilityElementInfo> & infos)90 int32_t ArkUI_AccessibilityProvider::FindAccessibilityNodeInfosById(
91     const int64_t elementId, const int32_t mode, const int32_t requestId,
92     std::vector<ArkUI_AccessibilityElementInfo>& infos)
93 {
94     if (!accessibilityProviderCallbacks_ ||
95         !accessibilityProviderCallbacks_->findAccessibilityNodeInfosById) {
96         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosById is null");
97         return NOT_REGISTERED;
98     }
99 
100     ArkUI_AccessibilityElementInfoList* accessibilityElementInfoList
101         = new (std::nothrow) ArkUI_AccessibilityElementInfoList();
102     if (accessibilityElementInfoList == nullptr) {
103         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "accessibilityElementInfoList is null");
104         return NOT_REGISTERED;
105     }
106 
107     int32_t ret = accessibilityProviderCallbacks_->findAccessibilityNodeInfosById(
108         elementId, static_cast<ArkUI_AccessibilitySearchMode>(mode),
109         requestId, accessibilityElementInfoList);
110     if (!accessibilityElementInfoList->CopyAccessibilityElementInfo(infos)) {
111         ret = COPY_FAILED;
112     }
113 
114     delete accessibilityElementInfoList;
115     accessibilityElementInfoList = nullptr;
116     return ret;
117 }
118 
FindAccessibilityNodeInfosByText(const int64_t elementId,std::string text,const int32_t requestId,std::vector<ArkUI_AccessibilityElementInfo> & infos)119 int32_t ArkUI_AccessibilityProvider::FindAccessibilityNodeInfosByText(
120     const int64_t elementId, std::string text, const int32_t requestId,
121     std::vector<ArkUI_AccessibilityElementInfo>& infos)
122 {
123     if (!accessibilityProviderCallbacks_ ||
124         !accessibilityProviderCallbacks_->findAccessibilityNodeInfosByText) {
125         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findAccessibilityNodeInfosByText is null");
126         return NOT_REGISTERED;
127     }
128 
129     ArkUI_AccessibilityElementInfoList* accessibilityElementInfoList
130         = new (std::nothrow) ArkUI_AccessibilityElementInfoList();
131     if (accessibilityElementInfoList == nullptr) {
132         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "accessibilityElementInfoList is null");
133         return NOT_REGISTERED;
134     }
135 
136     int32_t ret = accessibilityProviderCallbacks_->findAccessibilityNodeInfosByText(
137         elementId, text.c_str(), requestId, accessibilityElementInfoList);
138     if (!accessibilityElementInfoList->CopyAccessibilityElementInfo(infos)) {
139         ret = COPY_FAILED;
140     }
141 
142     delete accessibilityElementInfoList;
143     accessibilityElementInfoList = nullptr;
144     return ret;
145 }
146 
FindFocusedAccessibilityNode(const int64_t elementId,int32_t focusType,const int32_t requestId,ArkUI_AccessibilityElementInfo & elementInfo)147 int32_t ArkUI_AccessibilityProvider::FindFocusedAccessibilityNode(
148     const int64_t elementId, int32_t focusType, const int32_t requestId,
149     ArkUI_AccessibilityElementInfo& elementInfo)
150 {
151     if (!accessibilityProviderCallbacks_ ||
152         !accessibilityProviderCallbacks_->findFocusedAccessibilityNode) {
153         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findFocusedAccessibilityNode is null");
154         return NOT_REGISTERED;
155     }
156 
157     return accessibilityProviderCallbacks_->findFocusedAccessibilityNode(elementId,
158         static_cast<ArkUI_AccessibilityFocusType>(focusType), requestId, &elementInfo);
159 }
160 
FindNextFocusAccessibilityNode(const int64_t elementId,int32_t direction,const int32_t requestId,ArkUI_AccessibilityElementInfo & elementInfo)161 int32_t ArkUI_AccessibilityProvider::FindNextFocusAccessibilityNode(
162     const int64_t elementId, int32_t direction, const int32_t requestId,
163     ArkUI_AccessibilityElementInfo& elementInfo)
164 {
165     if (!accessibilityProviderCallbacks_ ||
166         !accessibilityProviderCallbacks_->findNextFocusAccessibilityNode) {
167         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "findNextFocusAccessibilityNode is null");
168         return NOT_REGISTERED;
169     }
170 
171     return accessibilityProviderCallbacks_->findNextFocusAccessibilityNode(elementId,
172         static_cast<ArkUI_AccessibilityFocusMoveDirection>(direction), requestId, &elementInfo);
173 }
174 
ExecuteAccessibilityAction(const int64_t elementId,int32_t action,const int32_t requestId,const std::map<std::string,std::string> & actionArguments)175 int32_t ArkUI_AccessibilityProvider::ExecuteAccessibilityAction(
176     const int64_t elementId, int32_t action, const int32_t requestId,
177     const std::map<std::string, std::string>& actionArguments)
178 {
179     if (!accessibilityProviderCallbacks_ ||
180         !accessibilityProviderCallbacks_->executeAccessibilityAction) {
181         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "executeAccessibilityAction is null");
182         return NOT_REGISTERED;
183     }
184 
185     return accessibilityProviderCallbacks_->executeAccessibilityAction(
186         elementId,
187         static_cast<ArkUI_Accessibility_ActionType>(action),
188         new ArkUI_AccessibilityActionArguments(actionArguments),
189         requestId);
190     return NOT_REGISTERED;
191 }
192 
ClearFocusedAccessibilityNode()193 int32_t ArkUI_AccessibilityProvider::ClearFocusedAccessibilityNode()
194 {
195     if (!accessibilityProviderCallbacks_ ||
196         !accessibilityProviderCallbacks_->clearFocusedFocusAccessibilityNode) {
197         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "clearFocusedFocusAccessibilityNode is null");
198         return NOT_REGISTERED;
199     }
200 
201     return accessibilityProviderCallbacks_->clearFocusedFocusAccessibilityNode();
202 }
203 
GetAccessibilityNodeCursorPosition(const int64_t elementId,const int32_t requestId,int32_t & cursorPosition)204 int32_t ArkUI_AccessibilityProvider::GetAccessibilityNodeCursorPosition(
205     const int64_t elementId, const int32_t requestId, int32_t &cursorPosition)
206 {
207     if (!accessibilityProviderCallbacks_ ||
208         !accessibilityProviderCallbacks_->getAccessibilityNodeCursorPosition) {
209         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "getAccessibilityNodeCursorPosition is null");
210         return NOT_REGISTERED;
211     }
212 
213     return accessibilityProviderCallbacks_->getAccessibilityNodeCursorPosition(
214         elementId, requestId, &cursorPosition);
215 }
216 
SendAccessibilityAsyncEvent(ArkUI_AccessibilityEventInfo * accessibilityEvent,void (* callback)(int32_t errorCode))217 int32_t ArkUI_AccessibilityProvider::SendAccessibilityAsyncEvent(
218     ArkUI_AccessibilityEventInfo* accessibilityEvent,
219     void (*callback)(int32_t errorCode))
220 {
221     if (accessibilityEvent == nullptr) {
222         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "accessibilityEvent is null");
223         if (callback) {
224             callback(SEND_EVENT_FAILED);
225         }
226         return SEND_EVENT_FAILED;
227     }
228 
229     auto accessibilityProvider = accessibilityProvider_.Upgrade();
230     if (accessibilityProvider == nullptr) {
231         TAG_LOGW(AceLogTag::ACE_ACCESSIBILITY, "accessibilityProvider is null");
232         if (callback) {
233             callback(SEND_EVENT_FAILED);
234         }
235         return SEND_EVENT_FAILED;
236     }
237 
238     accessibilityProvider->SendAccessibilityAsyncEvent(*accessibilityEvent, callback);
239     return SEND_EVENT_SUCCESS;
240 }
241 
SetInnerAccessibilityProvider(const OHOS::Ace::WeakPtr<OHOS::Ace::AccessibilityProvider> & accessibilityProvider)242 void ArkUI_AccessibilityProvider::SetInnerAccessibilityProvider(
243     const OHOS::Ace::WeakPtr<OHOS::Ace::AccessibilityProvider>& accessibilityProvider)
244 {
245     accessibilityProvider_ = accessibilityProvider;
246 }
247 
IsRegister()248 bool ArkUI_AccessibilityProvider::IsRegister()
249 {
250     return accessibilityProviderCallbacks_ != nullptr;
251 }
252 
SetRegisterCallback(RegisterCallback callback)253 void ArkUI_AccessibilityProvider::SetRegisterCallback(RegisterCallback callback)
254 {
255     registerCallback_ = callback;
256 }
257