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