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
22 #define SWITCH_BEGIN(code) switch (code) {
23 #define SWITCH_CASE(case_code, func) case case_code:\
24 {\
25 result_code = func(data, reply);\
26 break;\
27 }
28
29 #define SWITCH_END() default:\
30 {\
31 result_code = ERR_CODE_DEFAULT;\
32 HILOG_WARN("AccessibilityElementOperatorCallbackStub::OnRemoteRequest, default case, need check.");\
33 break;\
34 }\
35 }
36
37 #define ACCESSIBILITY_ELEMENT_OPERATOR_CALLBACK_STUB_CASES() \
38 SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_BY_ACCESSIBILITY_ID, HandleSetSearchElementInfoByAccessibilityIdResult)\
39 SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_BY_TEXT, HandleSetSearchElementInfoByTextResult)\
40 SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_FOCUSED_INFO, HandleSetFindFocusedElementInfoResult)\
41 SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_FOCUS_MOVE, HandleSetFocusMoveSearchResult)\
42 SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_PERFORM_ACTION, HandleSetExecuteActionResult)\
43 SWITCH_CASE(AccessibilityInterfaceCode::SET_RESULT_CURSOR_RESULT, HandleSetCursorPositionResult)\
44
45 namespace OHOS {
46 namespace Accessibility {
47
48 constexpr int32_t SINGLE_TRANSMIT = -2;
49 constexpr int32_t MULTI_TRANSMIT_FINISH = -1;
50 constexpr int32_t ERR_CODE_DEFAULT = -1000;
51
WriteData(std::vector<AccessibilityElementInfo> & infos)52 void StoreElementData::WriteData(std::vector<AccessibilityElementInfo> &infos)
53 {
54 HILOG_DEBUG();
55 std::lock_guard<std::mutex> lock(mutex_);
56 storeData_.insert(storeData_.end(), infos.begin(), infos.end());
57 }
58
Clear()59 void StoreElementData::Clear()
60 {
61 HILOG_DEBUG();
62 std::lock_guard<std::mutex> lock(mutex_);
63 storeData_.clear();
64 }
65
ReadData()66 std::vector<AccessibilityElementInfo> StoreElementData::ReadData()
67 {
68 HILOG_DEBUG();
69 std::lock_guard<std::mutex> lock(mutex_);
70 return storeData_;
71 }
72
Size()73 size_t StoreElementData::Size()
74 {
75 HILOG_DEBUG();
76 std::lock_guard<std::mutex> lock(mutex_);
77 return storeData_.size();
78 }
79
AccessibilityElementOperatorCallbackStub()80 AccessibilityElementOperatorCallbackStub::AccessibilityElementOperatorCallbackStub()
81 {
82 memberFuncMap_[static_cast<uint32_t>(
83 AccessibilityInterfaceCode::SET_RESULT_BY_ACCESSIBILITY_ID)] =
84 &AccessibilityElementOperatorCallbackStub::HandleSetSearchElementInfoByAccessibilityIdResult;
85 memberFuncMap_[static_cast<uint32_t>(AccessibilityInterfaceCode::SET_RESULT_BY_TEXT)] =
86 &AccessibilityElementOperatorCallbackStub::HandleSetSearchElementInfoByTextResult;
87 memberFuncMap_[static_cast<uint32_t>(
88 AccessibilityInterfaceCode::SET_RESULT_FOCUSED_INFO)] =
89 &AccessibilityElementOperatorCallbackStub::HandleSetFindFocusedElementInfoResult;
90 memberFuncMap_[static_cast<uint32_t>(AccessibilityInterfaceCode::SET_RESULT_FOCUS_MOVE)] =
91 &AccessibilityElementOperatorCallbackStub::HandleSetFocusMoveSearchResult;
92 memberFuncMap_[static_cast<uint32_t>(
93 AccessibilityInterfaceCode::SET_RESULT_PERFORM_ACTION)] =
94 &AccessibilityElementOperatorCallbackStub::HandleSetExecuteActionResult;
95 memberFuncMap_[static_cast<uint32_t>(
96 AccessibilityInterfaceCode::SET_RESULT_CURSOR_RESULT)] =
97 &AccessibilityElementOperatorCallbackStub::HandleSetCursorPositionResult;
98 }
99
100 StoreElementData AccessibilityElementOperatorCallbackStub::storeElementData;
101
~AccessibilityElementOperatorCallbackStub()102 AccessibilityElementOperatorCallbackStub::~AccessibilityElementOperatorCallbackStub()
103 {
104 HILOG_DEBUG();
105 memberFuncMap_.clear();
106 }
107
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)108 int AccessibilityElementOperatorCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
109 MessageParcel &reply, MessageOption &option)
110 {
111 HILOG_DEBUG("cmd = %{public}u, flags= %{public}d", code, option.GetFlags());
112 std::u16string descriptor = AccessibilityElementOperatorCallbackStub::GetDescriptor();
113 std::u16string remoteDescriptor = data.ReadInterfaceToken();
114 if (descriptor != remoteDescriptor) {
115 HILOG_ERROR("AccessibilityElementOperatorCallbackStub::OnRemoteRequest"
116 "local descriptor is not equal to remote");
117 return ERR_INVALID_STATE;
118 }
119
120 ErrCode result_code = ERR_NONE;
121 SWITCH_BEGIN(code)
122 ACCESSIBILITY_ELEMENT_OPERATOR_CALLBACK_STUB_CASES()
123 SWITCH_END()
124
125 if (result_code != ERR_CODE_DEFAULT) {
126 return result_code;
127 }
128
129 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
130 }
131
HandleSetSearchElementInfoByAccessibilityIdResult(MessageParcel & data,MessageParcel & reply)132 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetSearchElementInfoByAccessibilityIdResult(
133 MessageParcel &data, MessageParcel &reply)
134 {
135 HILOG_DEBUG();
136 int32_t flag = data.ReadInt32();
137 if (flag == SINGLE_TRANSMIT || flag == 0) {
138 storeElementData.Clear();
139 }
140
141 int32_t accessibilityInfosize = data.ReadInt32();
142 std::vector<AccessibilityElementInfo> tmpData;
143 bool verifyResult = ContainerSecurityVerify(data, accessibilityInfosize, tmpData.max_size());
144 if (!verifyResult || accessibilityInfosize < 0 || accessibilityInfosize > INT32_MAX) {
145 return TRANSACTION_ERR;
146 }
147 for (int32_t i = 0; i < accessibilityInfosize; i++) {
148 sptr<AccessibilityElementInfoParcel> accessibilityInfo =
149 data.ReadStrongParcelable<AccessibilityElementInfoParcel>();
150 if (!accessibilityInfo) {
151 HILOG_ERROR("ReadStrongParcelable<accessibilityInfo> failed");
152 storeElementData.Clear();
153 reply.WriteInt32(RET_ERR_FAILED);
154 return TRANSACTION_ERR;
155 }
156 tmpData.push_back(*accessibilityInfo);
157 }
158
159 storeElementData.WriteData(tmpData); // get all data and push once
160 int32_t requestId = data.ReadInt32();
161 if (flag == SINGLE_TRANSMIT || flag == MULTI_TRANSMIT_FINISH) {
162 reply.WriteInt32(0);
163 HILOG_DEBUG("infos size %{public}zu, requestId %{public}d", storeElementData.Size(), requestId);
164 SetSearchElementInfoByAccessibilityIdResult(storeElementData.ReadData(), requestId);
165 return NO_ERROR;
166 }
167
168 reply.WriteInt32(0);
169 return NO_ERROR;
170 }
171
HandleSetSearchElementInfoByTextResult(MessageParcel & data,MessageParcel & reply)172 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetSearchElementInfoByTextResult(
173 MessageParcel &data, MessageParcel &reply)
174 {
175 HILOG_DEBUG();
176 std::vector<AccessibilityElementInfo> infos {};
177 int32_t accessibilityInfosize = data.ReadInt32();
178 bool verifyResult = ContainerSecurityVerify(data, accessibilityInfosize, infos.max_size());
179 if (!verifyResult || accessibilityInfosize < 0 || accessibilityInfosize > INT32_MAX) {
180 return TRANSACTION_ERR;
181 }
182 for (int32_t i = 0; i < accessibilityInfosize; i++) {
183 sptr<AccessibilityElementInfoParcel> accessibilityInfo =
184 data.ReadStrongParcelable<AccessibilityElementInfoParcel>();
185 if (!accessibilityInfo) {
186 HILOG_ERROR("ReadStrongParcelable<accessibilityInfo> failed");
187 return TRANSACTION_ERR;
188 }
189 infos.emplace_back(*accessibilityInfo);
190 }
191 int32_t requestId = data.ReadInt32();
192
193 SetSearchElementInfoByTextResult(infos, requestId);
194
195 return NO_ERROR;
196 }
197
HandleSetFindFocusedElementInfoResult(MessageParcel & data,MessageParcel & reply)198 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetFindFocusedElementInfoResult(MessageParcel &data,
199 MessageParcel &reply)
200 {
201 HILOG_DEBUG();
202 sptr<AccessibilityElementInfoParcel> info = data.ReadStrongParcelable<AccessibilityElementInfoParcel>();
203 if (!info) {
204 HILOG_ERROR("ReadStrongParcelable<AccessibilityElementInfo> failed");
205 return TRANSACTION_ERR;
206 }
207
208 int32_t requestId = data.ReadInt32();
209
210 SetFindFocusedElementInfoResult(*info, requestId);
211
212 return NO_ERROR;
213 }
214
HandleSetFocusMoveSearchResult(MessageParcel & data,MessageParcel & reply)215 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetFocusMoveSearchResult(MessageParcel &data,
216 MessageParcel &reply)
217 {
218 HILOG_DEBUG();
219 sptr<AccessibilityElementInfoParcel> info = data.ReadStrongParcelable<AccessibilityElementInfoParcel>();
220 if (!info) {
221 HILOG_ERROR("ReadStrongParcelable<AccessibilityElementInfo> failed");
222 return TRANSACTION_ERR;
223 }
224
225 int32_t requestId = data.ReadInt32();
226
227 SetFocusMoveSearchResult(*info, requestId);
228
229 return NO_ERROR;
230 }
231
HandleSetExecuteActionResult(MessageParcel & data,MessageParcel & reply)232 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetExecuteActionResult(MessageParcel &data,
233 MessageParcel &reply)
234 {
235 HILOG_DEBUG();
236
237 bool succeeded = data.ReadBool();
238 int32_t requestId = data.ReadInt32();
239
240 SetExecuteActionResult(succeeded, requestId);
241
242 return NO_ERROR;
243 }
244
HandleSetCursorPositionResult(MessageParcel & data,MessageParcel & reply)245 ErrCode AccessibilityElementOperatorCallbackStub::HandleSetCursorPositionResult(MessageParcel &data,
246 MessageParcel &reply)
247 {
248 HILOG_DEBUG();
249 int32_t cursorPosition = data.ReadInt32();
250 int32_t requestId = data.ReadInt32();
251 HILOG_INFO("[cursorPosition:%{public}d]", cursorPosition);
252 SetCursorPositionResult(cursorPosition, requestId);
253
254 return NO_ERROR;
255 }
256
257 } // namespace Accessibility
258 } // namespace OHOS