• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_element_operator_callback_stub.h"
17 #include "accessibility_element_info_parcel.h"
18 #include "accessibility_ipc_interface_code.h"
19 #include "hilog_wrapper.h"
20 #include "parcel_util.h"
21 #include <securec.h>
22 
23 #define SWITCH_BEGIN(code) switch (code) {
24 #define SWITCH_CASE(case_code, func)     \
25     case case_code: {                    \
26         result_code = func(data, reply); \
27         break;                           \
28     }
29 
30 #define SWITCH_END()                                                                                        \
31     default: {                                                                                              \
32         result_code = ERR_CODE_DEFAULT;                                                                     \
33         HILOG_WARN("AccessibilityElementOperatorCallbackStub::OnRemoteRequest, default case, need check."); \
34         break;                                                                                              \
35     }                                                                                                       \
36         }
37 
38 #define ACCESSIBILITY_ELEMENT_OPERATOR_CALLBACK_STUB_CASES()                                                \
39     SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_BY_ACCESSIBILITY_ID,                                 \
40         HandleSetSearchElementInfoByAccessibilityIdResult)                                                  \
41     SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_BY_TEXT, HandleSetSearchElementInfoByTextResult)     \
42     SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_FOCUSED_INFO, HandleSetFindFocusedElementInfoResult) \
43     SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_FOCUS_MOVE, HandleSetFocusMoveSearchResult)          \
44     SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_PERFORM_ACTION, HandleSetExecuteActionResult)        \
45     SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_CURSOR_RESULT, HandleSetCursorPositionResult)        \
46     SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_BY_WINDOW_ID,                                        \
47         HandleSetSearchDefaultFocusByWindowIdResult)                                                        \
48     SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_BY_SPECIFIC_PROPERTY,                                \
49         HandleSetSearchElementInfoBySpecificPropertyResult)
50 
51 namespace OHOS {
52 namespace Accessibility {
53 
54 constexpr int32_t SINGLE_TRANSMIT = -2;
55 constexpr int32_t MULTI_TRANSMIT_FINISH = -1;
56 constexpr int32_t ERR_CODE_DEFAULT = -1000;
57 constexpr int32_t MAX_RAWDATA_SIZE = 128 * 1024 * 1024; // RawData limit is 128M, limited by IPC
58 
GetData(size_t size,const void * data,void * & buffer)59 static bool GetData(size_t size, const void *data, void *&buffer)
60 {
61     if (data == nullptr || size == 0) {
62         return false;
63     }
64     if (size > MAX_RAWDATA_SIZE) {
65         return false;
66     }
67     buffer = malloc(size);
68     if (buffer == nullptr) {
69         return false;
70     }
71     if (memcpy_s(buffer, sizeof(char) * size, data, size) != EOK) {
72         free(buffer);
73         return false;
74     }
75     return true;
76 }
77 
AccessibilityElementOperatorCallbackStub()78 AccessibilityElementOperatorCallbackStub::AccessibilityElementOperatorCallbackStub()
79 {
80 }
81 
~AccessibilityElementOperatorCallbackStub()82 AccessibilityElementOperatorCallbackStub::~AccessibilityElementOperatorCallbackStub()
83 {
84 }
85 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)86 int AccessibilityElementOperatorCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
87     MessageParcel &reply, MessageOption &option)
88 {
89     HILOG_DEBUG("cmd = %{public}u, flags= %{public}d", code, option.GetFlags());
90     std::u16string descriptor = AccessibilityElementOperatorCallbackStub::GetDescriptor();
91     std::u16string remoteDescriptor = data.ReadInterfaceToken();
92     if (descriptor != remoteDescriptor) {
93         HILOG_ERROR("AccessibilityElementOperatorCallbackStub::OnRemoteRequest"
94             "local descriptor is not equal to remote");
95         return ERR_INVALID_STATE;
96     }
97 
98     ErrCode result_code = ERR_NONE;
99     SWITCH_BEGIN(code)
100     ACCESSIBILITY_ELEMENT_OPERATOR_CALLBACK_STUB_CASES()
101     SWITCH_END()
102 
103     if (result_code != ERR_CODE_DEFAULT) {
104         return result_code;
105     }
106 
107     return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
108 }
109 
HandleSetSearchElementInfoByAccessibilityIdResult(MessageParcel & data,MessageParcel & reply)110 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetSearchElementInfoByAccessibilityIdResult(
111     MessageParcel &data, MessageParcel &reply)
112 {
113     HILOG_DEBUG();
114     std::vector<AccessibilityElementInfo> storeData;
115     int32_t requestId = data.ReadInt32();
116     size_t infoSize = data.ReadUint32();
117     if (infoSize != 0) {
118         size_t rawDataSize = data.ReadUint32();
119         MessageParcel tmpParcel;
120         void *buffer = nullptr;
121         // memory alloced in GetData will be released when tmpParcel destruct
122         if (!GetData(rawDataSize, data.ReadRawData(rawDataSize), buffer)) {
123             reply.WriteInt32(RET_ERR_FAILED);
124             return TRANSACTION_ERR;
125         }
126 
127         if (!tmpParcel.ParseFrom(reinterpret_cast<uintptr_t>(buffer), rawDataSize)) {
128             reply.WriteInt32(RET_ERR_FAILED);
129             return TRANSACTION_ERR;
130         }
131 
132         if (infoSize < 0 || infoSize > MAX_ALLOW_SIZE) {
133             reply.WriteInt32(RET_ERR_FAILED);
134             return TRANSACTION_ERR;
135         }
136 
137         for (size_t i = 0; i < infoSize; i++) {
138             sptr<AccessibilityElementInfoParcel> info =
139                 tmpParcel.ReadStrongParcelable<AccessibilityElementInfoParcel>();
140             if (info == nullptr) {
141                 reply.WriteInt32(RET_ERR_FAILED);
142                 return TRANSACTION_ERR;
143             }
144             storeData.emplace_back(*info);
145         }
146     }
147     reply.WriteInt32(RET_OK);
148     SetSearchElementInfoByAccessibilityIdResult(storeData, requestId);
149     return NO_ERROR;
150 }
151 
HandleSetSearchDefaultFocusByWindowIdResult(MessageParcel & data,MessageParcel & reply)152 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetSearchDefaultFocusByWindowIdResult(
153     MessageParcel &data, MessageParcel &reply)
154 {
155     HILOG_DEBUG();
156     std::vector<AccessibilityElementInfo> storeData;
157     int32_t requestId = data.ReadInt32();
158     uint32_t infoSize = data.ReadUint32();
159     if (infoSize != 0) {
160         size_t rawDataSize = data.ReadUint32();
161         MessageParcel tmpParcel;
162         void *buffer = nullptr;
163         // memory alloced in GetData will be released when tmpParcel destruct
164         if (!GetData(rawDataSize, data.ReadRawData(rawDataSize), buffer)) {
165             reply.WriteInt32(RET_ERR_FAILED);
166             return TRANSACTION_ERR;
167         }
168 
169         if (!tmpParcel.ParseFrom(reinterpret_cast<uintptr_t>(buffer), rawDataSize)) {
170             free(buffer);
171             buffer = nullptr;
172             reply.WriteInt32(RET_ERR_FAILED);
173             return TRANSACTION_ERR;
174         }
175 
176         if (infoSize < 0 || infoSize > static_cast<uint32_t>(MAX_ALLOW_SIZE)) {
177             reply.WriteInt32(RET_ERR_FAILED);
178             return TRANSACTION_ERR;
179         }
180 
181         for (size_t i = 0; i < infoSize; i++) {
182             sptr<AccessibilityElementInfoParcel> info =
183                 tmpParcel.ReadStrongParcelable<AccessibilityElementInfoParcel>();
184             if (info == nullptr) {
185                 reply.WriteInt32(RET_ERR_FAILED);
186                 return TRANSACTION_ERR;
187             }
188             storeData.emplace_back(*info);
189         }
190     }
191     reply.WriteInt32(RET_OK);
192     SetSearchDefaultFocusByWindowIdResult(storeData, requestId);
193     return NO_ERROR;
194 }
195 
HandleSetSearchElementInfoByTextResult(MessageParcel & data,MessageParcel & reply)196 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetSearchElementInfoByTextResult(
197     MessageParcel &data, MessageParcel &reply)
198 {
199     HILOG_DEBUG();
200     std::vector<AccessibilityElementInfo> infos {};
201     int32_t accessibilityInfosize = data.ReadInt32();
202     bool verifyResult = ContainerSecurityVerify(data, accessibilityInfosize, infos.max_size());
203     if (!verifyResult) {
204         return TRANSACTION_ERR;
205     }
206     if (accessibilityInfosize < 0 || accessibilityInfosize > MAX_ALLOW_SIZE) {
207         return TRANSACTION_ERR;
208     }
209     for (int32_t i = 0; i < accessibilityInfosize; i++) {
210         sptr<AccessibilityElementInfoParcel> accessibilityInfo =
211             data.ReadStrongParcelable<AccessibilityElementInfoParcel>();
212         if (accessibilityInfo == nullptr) {
213             HILOG_ERROR("ReadStrongParcelable<accessibilityInfo> failed");
214             return TRANSACTION_ERR;
215         }
216         infos.emplace_back(*accessibilityInfo);
217     }
218     int32_t requestId = data.ReadInt32();
219 
220     SetSearchElementInfoByTextResult(infos, requestId);
221 
222     return NO_ERROR;
223 }
224 
HandleSetFindFocusedElementInfoResult(MessageParcel & data,MessageParcel & reply)225 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetFindFocusedElementInfoResult(MessageParcel &data,
226     MessageParcel &reply)
227 {
228     HILOG_DEBUG();
229     sptr<AccessibilityElementInfoParcel> info = data.ReadStrongParcelable<AccessibilityElementInfoParcel>();
230     if (info == nullptr) {
231         HILOG_ERROR("ReadStrongParcelable<AccessibilityElementInfo> failed");
232         return TRANSACTION_ERR;
233     }
234 
235     int32_t requestId = data.ReadInt32();
236 
237     SetFindFocusedElementInfoResult(*info, requestId);
238 
239     return NO_ERROR;
240 }
241 
HandleSetFocusMoveSearchResult(MessageParcel & data,MessageParcel & reply)242 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetFocusMoveSearchResult(MessageParcel &data,
243     MessageParcel &reply)
244 {
245     HILOG_DEBUG();
246     sptr<AccessibilityElementInfoParcel> info = data.ReadStrongParcelable<AccessibilityElementInfoParcel>();
247     if (info == nullptr) {
248         HILOG_ERROR("ReadStrongParcelable<AccessibilityElementInfo> failed");
249         return TRANSACTION_ERR;
250     }
251 
252     int32_t requestId = data.ReadInt32();
253 
254     SetFocusMoveSearchResult(*info, requestId);
255 
256     return NO_ERROR;
257 }
258 
HandleSetExecuteActionResult(MessageParcel & data,MessageParcel & reply)259 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetExecuteActionResult(MessageParcel &data,
260     MessageParcel &reply)
261 {
262     HILOG_DEBUG();
263 
264     bool succeeded = data.ReadBool();
265     int32_t requestId = data.ReadInt32();
266 
267     SetExecuteActionResult(succeeded, requestId);
268 
269     return NO_ERROR;
270 }
271 
HandleSetCursorPositionResult(MessageParcel & data,MessageParcel & reply)272 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetCursorPositionResult(MessageParcel &data,
273     MessageParcel &reply)
274 {
275     HILOG_DEBUG();
276     int32_t cursorPosition = data.ReadInt32();
277     int32_t requestId = data.ReadInt32();
278     HILOG_INFO("[cursorPosition:%{public}d]", cursorPosition);
279     SetCursorPositionResult(cursorPosition, requestId);
280 
281     return NO_ERROR;
282 }
283 
ReadAccessibilityElementInfoList(MessageParcel & data,MessageParcel & reply,int32_t infoSize,std::list<AccessibilityElementInfo> & infos)284 ErrCode AccessibilityElementOperatorCallbackStub::ReadAccessibilityElementInfoList(
285     MessageParcel &data, MessageParcel &reply, int32_t infoSize, std::list<AccessibilityElementInfo> &infos)
286 {
287     if (infoSize == 0) {
288         HILOG_INFO("infoSize is 0, no element info to read");
289         return NO_ERROR;
290     }
291     size_t rawDataSize = data.ReadUint32();
292     MessageParcel tmpParcel;
293     void *buffer = nullptr;
294     // memory alloced in GetData will be released when tmpParcel destruct
295     if (!GetData(rawDataSize, data.ReadRawData(rawDataSize), buffer)) {
296         reply.WriteInt32(RET_ERR_FAILED);
297         return TRANSACTION_ERR;
298     }
299     if (!tmpParcel.ParseFrom(reinterpret_cast<uintptr_t>(buffer), rawDataSize)) {
300         reply.WriteInt32(RET_ERR_FAILED);
301         return TRANSACTION_ERR;
302     }
303     if (infoSize < 0 || infoSize > MAX_ALLOW_SIZE) {
304         reply.WriteInt32(RET_ERR_FAILED);
305         return TRANSACTION_ERR;
306     }
307     for (size_t i = 0; i < static_cast<uint32_t>(infoSize); i++) {
308         sptr<AccessibilityElementInfoParcel> info =
309                 tmpParcel.ReadStrongParcelable<AccessibilityElementInfoParcel>();
310         if (info == nullptr) {
311             reply.WriteInt32(RET_ERR_FAILED);
312             return TRANSACTION_ERR;
313         }
314         infos.emplace_back(*info);
315     }
316     return NO_ERROR;
317 }
318 
HandleSetSearchElementInfoBySpecificPropertyResult(MessageParcel & data,MessageParcel & reply)319 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetSearchElementInfoBySpecificPropertyResult(
320     MessageParcel &data, MessageParcel &reply)
321 {
322     HILOG_DEBUG();
323     int32_t requestId = data.ReadInt32();
324     int32_t infoSize = data.ReadInt32();
325 
326     std::list<AccessibilityElementInfo> infos;
327     ErrCode result = ReadAccessibilityElementInfoList(data, reply, infoSize, infos);
328     if (result != NO_ERROR) {
329         return result;
330     }
331     int32_t treeInfoSize = data.ReadInt32();
332     std::list<AccessibilityElementInfo> treeInfos;
333     result = ReadAccessibilityElementInfoList(data, reply, treeInfoSize, treeInfos);
334     if (result != NO_ERROR) {
335         return result;
336     }
337     reply.WriteInt32(RET_OK);
338     SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId);
339     return NO_ERROR;
340 }
341 } // namespace Accessibility
342 } // namespace OHOS