• 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 
49 namespace OHOS {
50 namespace Accessibility {
51 
52 constexpr int32_t SINGLE_TRANSMIT = -2;
53 constexpr int32_t MULTI_TRANSMIT_FINISH = -1;
54 constexpr int32_t ERR_CODE_DEFAULT = -1000;
55 constexpr int32_t MAX_RAWDATA_SIZE = 128 * 1024 * 1024; // RawData limit is 128M, limited by IPC
56 
GetData(size_t size,const void * data,void * & buffer)57 static bool GetData(size_t size, const void *data, void *&buffer)
58 {
59     if (data == nullptr || size == 0) {
60         return false;
61     }
62     if (size > MAX_RAWDATA_SIZE) {
63         return false;
64     }
65     buffer = malloc(size);
66     if (buffer == nullptr) {
67         return false;
68     }
69     if (memcpy_s(buffer, size, data, size) != EOK) {
70         free(buffer);
71         return false;
72     }
73     return true;
74 }
75 
AccessibilityElementOperatorCallbackStub()76 AccessibilityElementOperatorCallbackStub::AccessibilityElementOperatorCallbackStub()
77 {
78 }
79 
~AccessibilityElementOperatorCallbackStub()80 AccessibilityElementOperatorCallbackStub::~AccessibilityElementOperatorCallbackStub()
81 {
82 }
83 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)84 int AccessibilityElementOperatorCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
85     MessageParcel &reply, MessageOption &option)
86 {
87     HILOG_DEBUG("cmd = %{public}u, flags= %{public}d", code, option.GetFlags());
88     std::u16string descriptor = AccessibilityElementOperatorCallbackStub::GetDescriptor();
89     std::u16string remoteDescriptor = data.ReadInterfaceToken();
90     if (descriptor != remoteDescriptor) {
91         HILOG_ERROR("AccessibilityElementOperatorCallbackStub::OnRemoteRequest"
92             "local descriptor is not equal to remote");
93         return ERR_INVALID_STATE;
94     }
95 
96     ErrCode result_code = ERR_NONE;
97     SWITCH_BEGIN(code)
98     ACCESSIBILITY_ELEMENT_OPERATOR_CALLBACK_STUB_CASES()
99     SWITCH_END()
100 
101     if (result_code != ERR_CODE_DEFAULT) {
102         return result_code;
103     }
104 
105     return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
106 }
107 
HandleSetSearchElementInfoByAccessibilityIdResult(MessageParcel & data,MessageParcel & reply)108 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetSearchElementInfoByAccessibilityIdResult(
109     MessageParcel &data, MessageParcel &reply)
110 {
111     HILOG_DEBUG();
112     std::vector<AccessibilityElementInfo> storeData;
113     int32_t requestId = data.ReadInt32();
114     uint32_t infoSize = data.ReadUint32();
115     if (infoSize != 0) {
116         size_t rawDataSize = data.ReadUint32();
117         MessageParcel tmpParcel;
118         void *buffer = nullptr;
119         // memory alloced in GetData will be released when tmpParcel destruct
120         if (!GetData(rawDataSize, data.ReadRawData(rawDataSize), buffer)) {
121             reply.WriteInt32(RET_ERR_FAILED);
122             return TRANSACTION_ERR;
123         }
124 
125         if (!tmpParcel.ParseFrom(reinterpret_cast<uintptr_t>(buffer), rawDataSize)) {
126             free(buffer);
127             buffer = nullptr;
128             reply.WriteInt32(RET_ERR_FAILED);
129             return TRANSACTION_ERR;
130         }
131 
132         if (infoSize < 0 || infoSize > static_cast<uint32_t>(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             HILOG_ERROR("get data failed!");
166             reply.WriteInt32(RET_ERR_FAILED);
167             return TRANSACTION_ERR;
168         }
169 
170         if (!tmpParcel.ParseFrom(reinterpret_cast<uintptr_t>(buffer), rawDataSize)) {
171             HILOG_ERROR("parse data from buffer failed!");
172             free(buffer);
173             buffer = nullptr;
174             reply.WriteInt32(RET_ERR_FAILED);
175             return TRANSACTION_ERR;
176         }
177 
178         if (infoSize < 0 || infoSize > static_cast<uint32_t>(MAX_ALLOW_SIZE)) {
179             HILOG_ERROR("The infoSize is abnormal");
180             reply.WriteInt32(RET_ERR_FAILED);
181             return TRANSACTION_ERR;
182         }
183 
184         for (size_t i = 0; i < infoSize; i++) {
185             sptr<AccessibilityElementInfoParcel> info =
186                 tmpParcel.ReadStrongParcelable<AccessibilityElementInfoParcel>();
187             if (info == nullptr) {
188                 HILOG_ERROR("info is nullptr!");
189                 reply.WriteInt32(RET_ERR_FAILED);
190                 return TRANSACTION_ERR;
191             }
192             storeData.emplace_back(*info);
193         }
194     }
195     reply.WriteInt32(RET_OK);
196     SetSearchDefaultFocusByWindowIdResult(storeData, requestId);
197     return NO_ERROR;
198 }
199 
HandleSetSearchElementInfoByTextResult(MessageParcel & data,MessageParcel & reply)200 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetSearchElementInfoByTextResult(
201     MessageParcel &data, MessageParcel &reply)
202 {
203     HILOG_DEBUG();
204     std::vector<AccessibilityElementInfo> infos {};
205     int32_t accessibilityInfosize = data.ReadInt32();
206     bool verifyResult = ContainerSecurityVerify(data, accessibilityInfosize, infos.max_size());
207     if (!verifyResult) {
208         return TRANSACTION_ERR;
209     }
210     if (accessibilityInfosize < 0 || accessibilityInfosize > MAX_ALLOW_SIZE) {
211         return TRANSACTION_ERR;
212     }
213     for (int32_t i = 0; i < accessibilityInfosize; i++) {
214         sptr<AccessibilityElementInfoParcel> accessibilityInfo =
215             data.ReadStrongParcelable<AccessibilityElementInfoParcel>();
216         if (accessibilityInfo == nullptr) {
217             HILOG_ERROR("ReadStrongParcelable<accessibilityInfo> failed");
218             return TRANSACTION_ERR;
219         }
220         infos.emplace_back(*accessibilityInfo);
221     }
222     int32_t requestId = data.ReadInt32();
223 
224     SetSearchElementInfoByTextResult(infos, requestId);
225 
226     return NO_ERROR;
227 }
228 
HandleSetFindFocusedElementInfoResult(MessageParcel & data,MessageParcel & reply)229 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetFindFocusedElementInfoResult(MessageParcel &data,
230     MessageParcel &reply)
231 {
232     HILOG_DEBUG();
233     sptr<AccessibilityElementInfoParcel> info = data.ReadStrongParcelable<AccessibilityElementInfoParcel>();
234     if (info == nullptr) {
235         HILOG_ERROR("ReadStrongParcelable<AccessibilityElementInfo> failed");
236         return TRANSACTION_ERR;
237     }
238 
239     int32_t requestId = data.ReadInt32();
240 
241     SetFindFocusedElementInfoResult(*info, requestId);
242 
243     return NO_ERROR;
244 }
245 
HandleSetFocusMoveSearchResult(MessageParcel & data,MessageParcel & reply)246 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetFocusMoveSearchResult(MessageParcel &data,
247     MessageParcel &reply)
248 {
249     HILOG_DEBUG();
250     sptr<AccessibilityElementInfoParcel> info = data.ReadStrongParcelable<AccessibilityElementInfoParcel>();
251     if (info == nullptr) {
252         HILOG_ERROR("ReadStrongParcelable<AccessibilityElementInfo> failed");
253         return TRANSACTION_ERR;
254     }
255 
256     int32_t requestId = data.ReadInt32();
257 
258     SetFocusMoveSearchResult(*info, requestId);
259 
260     return NO_ERROR;
261 }
262 
HandleSetExecuteActionResult(MessageParcel & data,MessageParcel & reply)263 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetExecuteActionResult(MessageParcel &data,
264     MessageParcel &reply)
265 {
266     HILOG_DEBUG();
267 
268     bool succeeded = data.ReadBool();
269     int32_t requestId = data.ReadInt32();
270 
271     SetExecuteActionResult(succeeded, requestId);
272 
273     return NO_ERROR;
274 }
275 
HandleSetCursorPositionResult(MessageParcel & data,MessageParcel & reply)276 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetCursorPositionResult(MessageParcel &data,
277     MessageParcel &reply)
278 {
279     HILOG_DEBUG();
280     int32_t cursorPosition = data.ReadInt32();
281     int32_t requestId = data.ReadInt32();
282     HILOG_INFO("[cursorPosition:%{public}d]", cursorPosition);
283     SetCursorPositionResult(cursorPosition, requestId);
284 
285     return NO_ERROR;
286 }
287 
288 } // namespace Accessibility
289 } // namespace OHOS