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_proxy.h"
17 #include "accessibility_element_info_parcel.h"
18 #include "hilog_wrapper.h"
19
20 namespace OHOS {
21 namespace Accessibility {
22
23 constexpr int32_t IPC_MEMORY_SIZE = 500 * 1024; // default size is 200 * 1024B, batch query need more memory
24 constexpr int32_t SINGLE_TRANSMIT = -2;
25 constexpr int32_t MULTI_TRANSMIT_FINISH = -1;
26 constexpr int32_t DATA_NUMBER_ONE_TIME = 800;
27
AccessibilityElementOperatorCallbackProxy(const sptr<IRemoteObject> & impl)28 AccessibilityElementOperatorCallbackProxy::AccessibilityElementOperatorCallbackProxy(
29 const sptr<IRemoteObject> &impl) : IRemoteProxy<IAccessibilityElementOperatorCallback>(impl)
30 {}
31
~AccessibilityElementOperatorCallbackProxy()32 AccessibilityElementOperatorCallbackProxy::~AccessibilityElementOperatorCallbackProxy()
33 {}
34
WriteInterfaceToken(MessageParcel & data)35 bool AccessibilityElementOperatorCallbackProxy::WriteInterfaceToken(MessageParcel &data)
36 {
37 HILOG_DEBUG();
38 if (!data.WriteInterfaceToken(AccessibilityElementOperatorCallbackProxy::GetDescriptor())) {
39 HILOG_ERROR("write interface token failed");
40 return false;
41 }
42 return true;
43 }
44
SendTransactCmd(AccessibilityInterfaceCode code,MessageParcel & data,MessageParcel & reply,MessageOption & option)45 bool AccessibilityElementOperatorCallbackProxy::SendTransactCmd(AccessibilityInterfaceCode code,
46 MessageParcel &data, MessageParcel &reply, MessageOption &option)
47 {
48 HILOG_DEBUG();
49
50 sptr<IRemoteObject> remoteObj = Remote();
51 if (!remoteObj) {
52 HILOG_ERROR("fail to send transact cmd %{public}d due to remote object", code);
53 return false;
54 }
55 int32_t ret = remoteObj->SendRequest(static_cast<uint32_t>(code), data, reply, option);
56 if (ret != NO_ERROR) {
57 HILOG_ERROR("receive error transact code %{public}d in transact cmd %{public}d", ret, code);
58 return false;
59 }
60 return true;
61 }
62
GetTransmitFlag(int32_t time,int32_t leftSize)63 int32_t AccessibilityElementOperatorCallbackProxy::GetTransmitFlag(int32_t time, int32_t leftSize)
64 {
65 int32_t flag = time;
66 if (time == 0 && leftSize <= DATA_NUMBER_ONE_TIME) {
67 flag = SINGLE_TRANSMIT;
68 } else if (leftSize <= DATA_NUMBER_ONE_TIME) {
69 flag = MULTI_TRANSMIT_FINISH;
70 }
71
72 return flag;
73 }
74
SetSearchElementInfoByAccessibilityIdResult(const std::vector<AccessibilityElementInfo> & infos,const int32_t requestId)75 void AccessibilityElementOperatorCallbackProxy::SetSearchElementInfoByAccessibilityIdResult(
76 const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)
77 {
78 HILOG_DEBUG("infos size %{public}zu, resquestId %{public}d", infos.size(), requestId);
79 int32_t leftSize = static_cast<int32_t>(infos.size());
80 int32_t time = 0;
81 int32_t index = 0;
82 while (leftSize > 0) {
83 MessageParcel data;
84 MessageParcel reply;
85 MessageOption type = MessageOption::TF_SYNC;
86 if (leftSize <= DATA_NUMBER_ONE_TIME) {
87 type = MessageOption::TF_ASYNC;
88 }
89 MessageOption option(type);
90 data.SetMaxCapacity(IPC_MEMORY_SIZE);
91
92 if (!WriteInterfaceToken(data)) {
93 return;
94 }
95
96 int32_t flag = GetTransmitFlag(time, leftSize);
97 if (!data.WriteInt32(flag)) {
98 return;
99 }
100
101 int32_t writeSize = (leftSize <= DATA_NUMBER_ONE_TIME) ? leftSize : DATA_NUMBER_ONE_TIME;
102 if (!data.WriteInt32(writeSize)) {
103 return;
104 }
105
106 for (int32_t i = 0; i < writeSize; ++i) {
107 AccessibilityElementInfoParcel infoParcel(infos[index]);
108 index++;
109 if (!data.WriteParcelable(&infoParcel)) {
110 HILOG_ERROR("accessibility element info failed index %{public}d", index);
111 return;
112 }
113 }
114
115 if (!data.WriteInt32(requestId)) {
116 return;
117 }
118
119 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_BY_ACCESSIBILITY_ID, data, reply, option)) {
120 HILOG_ERROR("set search element info by accessibility id result failed");
121 return;
122 }
123
124 leftSize -= DATA_NUMBER_ONE_TIME;
125 time++;
126 if (static_cast<RetError>(reply.ReadInt32()) != RET_OK) {
127 return;
128 }
129 }
130 }
131
SetSearchElementInfoByTextResult(const std::vector<AccessibilityElementInfo> & infos,const int32_t requestId)132 void AccessibilityElementOperatorCallbackProxy::SetSearchElementInfoByTextResult(
133 const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)
134 {
135 HILOG_DEBUG();
136 MessageParcel data;
137 MessageParcel reply;
138 MessageOption option(MessageOption::TF_ASYNC);
139
140 if (!WriteInterfaceToken(data)) {
141 HILOG_ERROR("connection write token failed");
142 return;
143 }
144
145 if (!data.WriteInt32(infos.size())) {
146 HILOG_ERROR("write infos's size failed");
147 return;
148 }
149
150 for (auto &info : infos) {
151 AccessibilityElementInfoParcel infoParcel(info);
152 if (!data.WriteParcelable(&infoParcel)) {
153 HILOG_ERROR("write accessibility element info failed");
154 return;
155 }
156 }
157
158 if (!data.WriteInt32(requestId)) {
159 HILOG_ERROR("connection write request id failed");
160 return;
161 }
162
163 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_BY_TEXT,
164 data, reply, option)) {
165 HILOG_ERROR("set search element info by text result failed");
166 return;
167 }
168 }
169
SetFindFocusedElementInfoResult(const AccessibilityElementInfo & info,const int32_t requestId)170 void AccessibilityElementOperatorCallbackProxy::SetFindFocusedElementInfoResult(
171 const AccessibilityElementInfo &info, const int32_t requestId)
172 {
173 HILOG_DEBUG();
174 MessageParcel data;
175 MessageParcel reply;
176 MessageOption option(MessageOption::TF_ASYNC);
177 AccessibilityElementInfoParcel infoParcel(info);
178
179 if (!WriteInterfaceToken(data)) {
180 HILOG_ERROR("connection write token failed");
181 return;
182 }
183
184 if (!data.WriteParcelable(&infoParcel)) {
185 HILOG_ERROR("connection write info failed");
186 return;
187 }
188 if (!data.WriteInt32(requestId)) {
189 HILOG_ERROR("connection write request id failed");
190 return;
191 }
192
193 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_FOCUSED_INFO,
194 data, reply, option)) {
195 HILOG_ERROR("set find focused element info result failed");
196 return;
197 }
198 }
199
SetFocusMoveSearchResult(const AccessibilityElementInfo & info,const int32_t requestId)200 void AccessibilityElementOperatorCallbackProxy::SetFocusMoveSearchResult(const AccessibilityElementInfo &info,
201 const int32_t requestId)
202 {
203 HILOG_DEBUG();
204 MessageParcel data;
205 MessageParcel reply;
206 MessageOption option(MessageOption::TF_ASYNC);
207 AccessibilityElementInfoParcel infoParcel(info);
208
209 if (!WriteInterfaceToken(data)) {
210 HILOG_ERROR("connection write token failed");
211 return;
212 }
213
214 if (!data.WriteParcelable(&infoParcel)) {
215 HILOG_ERROR("connection write info failed");
216 return;
217 }
218
219 if (!data.WriteInt32(requestId)) {
220 HILOG_ERROR("connection write requestId failed");
221 return;
222 }
223
224 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_FOCUS_MOVE,
225 data, reply, option)) {
226 HILOG_ERROR("set focus move search result failed");
227 return;
228 }
229 }
230
SetExecuteActionResult(const bool succeeded,const int32_t requestId)231 void AccessibilityElementOperatorCallbackProxy::SetExecuteActionResult(const bool succeeded, const int32_t requestId)
232 {
233 HILOG_DEBUG();
234 MessageParcel data;
235 MessageParcel reply;
236 MessageOption option(MessageOption::TF_ASYNC);
237
238 if (!WriteInterfaceToken(data)) {
239 HILOG_ERROR("connection write token failed");
240 return;
241 }
242
243 if (!data.WriteBool(succeeded)) {
244 HILOG_ERROR("connection write failed");
245 return;
246 }
247
248 if (!data.WriteInt32(requestId)) {
249 HILOG_ERROR("connection write request id failed");
250 return;
251 }
252
253 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_PERFORM_ACTION,
254 data, reply, option)) {
255 HILOG_ERROR("set execute action result failed");
256 return;
257 }
258 }
259 } // namespace Accessibility
260 } // namespace OHOS