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