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 "input_method_system_ability_stub.h"
17
18 #include <utils.h>
19
20 #include <memory>
21
22 #include "access_token.h"
23 #include "accesstoken_kit.h"
24 #include "ipc_skeleton.h"
25 #include "itypes_util.h"
26
27 namespace OHOS {
28 namespace MiscServices {
29 using namespace Security::AccessToken;
30 static const std::string PERMISSION_CONNECT_IME_ABILITY = "ohos.permission.CONNECT_IME_ABILITY";
31
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)32 int32_t InputMethodSystemAbilityStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
33 MessageOption &option)
34 {
35 IMSA_HILOGE("code:%{public}u, callingPid:%{public}d", code, IPCSkeleton::GetCallingPid());
36 std::u16string remoteDescriptor = data.ReadInterfaceToken();
37 if (remoteDescriptor != IInputMethodSystemAbility::GetDescriptor()) {
38 IMSA_HILOGE("%{public}s descriptor failed", __func__);
39 return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
40 }
41 if (code >= 0 && code < INPUT_SERVICE_CMD_LAST) {
42 return (this->*HANDLERS[code])(data, reply);
43 } else {
44 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
45 }
46 }
47
PrepareInputOnRemote(MessageParcel & data,MessageParcel & reply)48 int32_t InputMethodSystemAbilityStub::PrepareInputOnRemote(MessageParcel &data, MessageParcel &reply)
49 {
50 int32_t displayId = data.ReadInt32();
51 auto clientObject = data.ReadRemoteObject();
52 if (clientObject == nullptr) {
53 reply.WriteInt32(ErrorCode::ERROR_EX_NULL_POINTER);
54 IMSA_HILOGE("%{public}s nullptr", __func__);
55 return ErrorCode::ERROR_EX_NULL_POINTER;
56 }
57 auto channelObject = data.ReadRemoteObject();
58 if (channelObject == nullptr) {
59 reply.WriteInt32(ErrorCode::ERROR_EX_NULL_POINTER);
60 IMSA_HILOGE("%{public}s nullptr", __func__);
61 return ErrorCode::ERROR_EX_NULL_POINTER;
62 }
63 InputAttribute attribute;
64 if (!InputAttribute::Unmarshalling(attribute, data)) {
65 reply.WriteInt32(ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT);
66 IMSA_HILOGE("%{public}s illegal argument", __func__);
67 return ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT;
68 }
69 int32_t ret = PrepareInput(displayId, iface_cast<IInputClient>(clientObject),
70 iface_cast<IInputDataChannel>(channelObject), attribute);
71 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
72 }
73
StartInputOnRemote(MessageParcel & data,MessageParcel & reply)74 int32_t InputMethodSystemAbilityStub::StartInputOnRemote(MessageParcel &data, MessageParcel &reply)
75 {
76 auto clientObject = data.ReadRemoteObject();
77 if (clientObject == nullptr) {
78 reply.WriteInt32(ErrorCode::ERROR_EX_NULL_POINTER);
79 IMSA_HILOGE("%{public}s nullptr", __func__);
80 return ErrorCode::ERROR_EX_NULL_POINTER;
81 }
82 bool isShowKeyboard = data.ReadBool();
83 int32_t ret = StartInput(iface_cast<IInputClient>(clientObject), isShowKeyboard);
84 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
85 }
86
ShowCurrentInputOnRemote(MessageParcel & data,MessageParcel & reply)87 int32_t InputMethodSystemAbilityStub::ShowCurrentInputOnRemote(MessageParcel &data, MessageParcel &reply)
88 {
89 if (!CheckPermission(PERMISSION_CONNECT_IME_ABILITY)) {
90 reply.WriteInt32(ErrorCode::ERROR_STATUS_PERMISSION_DENIED);
91 IMSA_HILOGE("%{public}s Permission denied", __func__);
92 return ErrorCode::ERROR_STATUS_PERMISSION_DENIED;
93 }
94 int32_t ret = ShowCurrentInput();
95 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
96 }
97
HideCurrentInputOnRemote(MessageParcel & data,MessageParcel & reply)98 int32_t InputMethodSystemAbilityStub::HideCurrentInputOnRemote(MessageParcel &data, MessageParcel &reply)
99 {
100 if (!CheckPermission(PERMISSION_CONNECT_IME_ABILITY)) {
101 reply.WriteInt32(ErrorCode::ERROR_STATUS_PERMISSION_DENIED);
102 IMSA_HILOGE("%{public}s Permission denied", __func__);
103 return ErrorCode::ERROR_STATUS_PERMISSION_DENIED;
104 }
105 int32_t ret = HideCurrentInput();
106 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
107 }
108
StopInputSessionOnRemote(MessageParcel & data,MessageParcel & reply)109 int32_t InputMethodSystemAbilityStub::StopInputSessionOnRemote(MessageParcel &data, MessageParcel &reply)
110 {
111 int32_t ret = HideCurrentInput();
112 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
113 }
114
StopInputOnRemote(MessageParcel & data,MessageParcel & reply)115 int32_t InputMethodSystemAbilityStub::StopInputOnRemote(MessageParcel &data, MessageParcel &reply)
116 {
117 auto clientObject = data.ReadRemoteObject();
118 if (clientObject == nullptr) {
119 reply.WriteInt32(ErrorCode::ERROR_EX_NULL_POINTER);
120 IMSA_HILOGE("%{public}s nullptr", __func__);
121 return ErrorCode::ERROR_EX_NULL_POINTER;
122 }
123 int32_t ret = StopInput(iface_cast<IInputClient>(clientObject));
124 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
125 }
126
ReleaseInputOnRemote(MessageParcel & data,MessageParcel & reply)127 int32_t InputMethodSystemAbilityStub::ReleaseInputOnRemote(MessageParcel &data, MessageParcel &reply)
128 {
129 auto clientObject = data.ReadRemoteObject();
130 if (clientObject == nullptr) {
131 reply.WriteInt32(ErrorCode::ERROR_EX_NULL_POINTER);
132 IMSA_HILOGE("%{public}s nullptr", __func__);
133 return ErrorCode::ERROR_EX_NULL_POINTER;
134 }
135 int32_t ret = ReleaseInput(iface_cast<IInputClient>(clientObject));
136 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
137 }
138
DisplayOptionalInputMethodOnRemote(MessageParcel & data,MessageParcel & reply)139 int32_t InputMethodSystemAbilityStub::DisplayOptionalInputMethodOnRemote(MessageParcel &data, MessageParcel &reply)
140 {
141 if (!CheckPermission(PERMISSION_CONNECT_IME_ABILITY)) {
142 reply.WriteInt32(ErrorCode::ERROR_STATUS_PERMISSION_DENIED);
143 IMSA_HILOGE("%{public}s Permission denied", __func__);
144 return ErrorCode::ERROR_STATUS_PERMISSION_DENIED;
145 }
146 int32_t ret = DisplayOptionalInputMethod();
147 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
148 }
149
SetCoreAndAgentOnRemote(MessageParcel & data,MessageParcel & reply)150 int32_t InputMethodSystemAbilityStub::SetCoreAndAgentOnRemote(MessageParcel &data, MessageParcel &reply)
151 {
152 if (!CheckPermission(PERMISSION_CONNECT_IME_ABILITY)) {
153 reply.WriteInt32(ErrorCode::ERROR_STATUS_PERMISSION_DENIED);
154 IMSA_HILOGE("%{public}s Permission denied", __func__);
155 return ErrorCode::ERROR_STATUS_PERMISSION_DENIED;
156 }
157 auto coreObject = data.ReadRemoteObject();
158 if (coreObject == nullptr) {
159 reply.WriteInt32(ErrorCode::ERROR_EX_NULL_POINTER);
160 IMSA_HILOGE("%{public}s nullptr", __func__);
161 return ErrorCode::ERROR_EX_NULL_POINTER;
162 }
163 auto agentObject = data.ReadRemoteObject();
164 if (agentObject == nullptr) {
165 reply.WriteInt32(ErrorCode::ERROR_EX_NULL_POINTER);
166 IMSA_HILOGE("%{public}s nullptr", __func__);
167 return ErrorCode::ERROR_EX_NULL_POINTER;
168 }
169 int32_t ret = SetCoreAndAgent(iface_cast<IInputMethodCore>(coreObject), iface_cast<IInputMethodAgent>(agentObject));
170 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
171 }
172
GetCurrentInputMethodOnRemote(MessageParcel & data,MessageParcel & reply)173 int32_t InputMethodSystemAbilityStub::GetCurrentInputMethodOnRemote(MessageParcel &data, MessageParcel &reply)
174 {
175 auto property = GetCurrentInputMethod();
176 if (property == nullptr) {
177 reply.WriteInt32(ErrorCode::ERROR_EX_NULL_POINTER);
178 IMSA_HILOGE("%{public}s property is nullptr", __func__);
179 return ErrorCode::ERROR_EX_NULL_POINTER;
180 }
181 if (!ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, *property, ErrorCode::ERROR_EX_PARCELABLE)) {
182 IMSA_HILOGE("%{public}s parcel failed", __func__);
183 return ErrorCode::ERROR_EX_PARCELABLE;
184 }
185 return ErrorCode::NO_ERROR;
186 }
187
GetCurrentInputMethodSubtypeOnRemote(MessageParcel & data,MessageParcel & reply)188 int32_t InputMethodSystemAbilityStub::GetCurrentInputMethodSubtypeOnRemote(MessageParcel &data, MessageParcel &reply)
189 {
190 auto property = GetCurrentInputMethodSubtype();
191 if (property == nullptr) {
192 reply.WriteInt32(ErrorCode::ERROR_EX_NULL_POINTER);
193 IMSA_HILOGE("%{public}s property is nullptr", __func__);
194 return ErrorCode::ERROR_EX_NULL_POINTER;
195 }
196 if (!ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, *property, ErrorCode::ERROR_EX_PARCELABLE)) {
197 IMSA_HILOGE("%{public}s parcel failed", __func__);
198 return ErrorCode::ERROR_EX_PARCELABLE;
199 }
200 return ErrorCode::NO_ERROR;
201 }
202
ListInputMethodOnRemote(MessageParcel & data,MessageParcel & reply)203 int32_t InputMethodSystemAbilityStub::ListInputMethodOnRemote(MessageParcel &data, MessageParcel &reply)
204 {
205 uint32_t status;
206 if (!ITypesUtil::Unmarshal(data, status)) {
207 IMSA_HILOGE("read status failed");
208 }
209 std::vector<Property> properties = {};
210 auto ret = ListInputMethod(InputMethodStatus(status), properties);
211 if (ret != ErrorCode::NO_ERROR) {
212 IMSA_HILOGE("ListInputMethod failed");
213 return ret;
214 }
215 if (!ITypesUtil::Marshal(reply, ret, properties)) {
216 IMSA_HILOGE("write reply failed");
217 return ErrorCode::ERROR_EX_PARCELABLE;
218 }
219 return ret;
220 }
221
ListInputMethodSubtypeOnRemote(MessageParcel & data,MessageParcel & reply)222 int32_t InputMethodSystemAbilityStub::ListInputMethodSubtypeOnRemote(MessageParcel &data, MessageParcel &reply)
223 {
224 std::string bundleName;
225 if (!ITypesUtil::Unmarshal(data, bundleName)) {
226 IMSA_HILOGE("InputMethodSystemAbilityStub::read bundleName failed");
227 return ErrorCode::ERROR_EX_PARCELABLE;
228 }
229 std::vector<SubProperty> subProps = {};
230 auto ret = ListInputMethodSubtype(bundleName, subProps);
231 if (ret != ErrorCode::NO_ERROR) {
232 IMSA_HILOGE("ListInputMethodSubtype failed");
233 return ret;
234 }
235 if (!ITypesUtil::Marshal(reply, ret, subProps)) {
236 IMSA_HILOGE("InputMethodSystemAbilityStub::write reply failed");
237 return ErrorCode::ERROR_EX_PARCELABLE;
238 }
239 return ret;
240 }
241
ListCurrentInputMethodSubtypeOnRemote(MessageParcel & data,MessageParcel & reply)242 int32_t InputMethodSystemAbilityStub::ListCurrentInputMethodSubtypeOnRemote(MessageParcel &data, MessageParcel &reply)
243 {
244 std::vector<SubProperty> subProps = {};
245 auto ret = ListCurrentInputMethodSubtype(subProps);
246 if (ret != ErrorCode::NO_ERROR) {
247 IMSA_HILOGE("ListCurrentInputMethodSubtype failed");
248 return ret;
249 }
250 if (!ITypesUtil::Marshal(reply, ret, subProps)) {
251 IMSA_HILOGE("InputMethodSystemAbilityStub::write reply failed");
252 return ErrorCode::ERROR_EX_PARCELABLE;
253 }
254 return ret;
255 }
256
SwitchInputMethodOnRemote(MessageParcel & data,MessageParcel & reply)257 int32_t InputMethodSystemAbilityStub::SwitchInputMethodOnRemote(MessageParcel &data, MessageParcel &reply)
258 {
259 if (!CheckPermission(PERMISSION_CONNECT_IME_ABILITY)) {
260 reply.WriteInt32(ErrorCode::ERROR_STATUS_PERMISSION_DENIED);
261 IMSA_HILOGE("%{public}s Permission denied", __func__);
262 return ErrorCode::ERROR_STATUS_PERMISSION_DENIED;
263 }
264 std::string name;
265 std::string subName;
266 if (!ITypesUtil::Unmarshal(data, name, subName)) {
267 reply.WriteInt32(ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT);
268 IMSA_HILOGE("%{public}s parcel failed", __func__);
269 return ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT;
270 }
271 int32_t ret = SwitchInputMethod(name, subName);
272 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
273 }
274
ShowCurrentInputOnRemoteDeprecated(MessageParcel & data,MessageParcel & reply)275 int32_t InputMethodSystemAbilityStub::ShowCurrentInputOnRemoteDeprecated(MessageParcel &data, MessageParcel &reply)
276 {
277 int32_t ret = ShowCurrentInputDeprecated();
278 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
279 }
280
HideCurrentInputOnRemoteDeprecated(MessageParcel & data,MessageParcel & reply)281 int32_t InputMethodSystemAbilityStub::HideCurrentInputOnRemoteDeprecated(MessageParcel &data, MessageParcel &reply)
282 {
283 int32_t ret = HideCurrentInputDeprecated();
284 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
285 }
286
DisplayInputOnRemoteDeprecated(MessageParcel & data,MessageParcel & reply)287 int32_t InputMethodSystemAbilityStub::DisplayInputOnRemoteDeprecated(MessageParcel &data, MessageParcel &reply)
288 {
289 int32_t ret = DisplayOptionalInputMethodDeprecated();
290 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
291 }
292
SetCoreAndAgentOnRemoteDeprecated(MessageParcel & data,MessageParcel & reply)293 int32_t InputMethodSystemAbilityStub::SetCoreAndAgentOnRemoteDeprecated(MessageParcel &data, MessageParcel &reply)
294 {
295 auto coreObject = data.ReadRemoteObject();
296 if (coreObject == nullptr) {
297 reply.WriteInt32(ErrorCode::ERROR_EX_NULL_POINTER);
298 IMSA_HILOGE("%{public}s coreObject is nullptr", __func__);
299 return ErrorCode::ERROR_EX_NULL_POINTER;
300 }
301 auto agentObject = data.ReadRemoteObject();
302 if (agentObject == nullptr) {
303 reply.WriteInt32(ErrorCode::ERROR_EX_NULL_POINTER);
304 IMSA_HILOGE("%{public}s agentObject is nullptr", __func__);
305 return ErrorCode::ERROR_EX_NULL_POINTER;
306 }
307 int32_t ret = SetCoreAndAgent(iface_cast<IInputMethodCore>(coreObject), iface_cast<IInputMethodAgent>(agentObject));
308 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
309 }
310
CheckPermission(const std::string & permission)311 bool InputMethodSystemAbilityStub::CheckPermission(const std::string &permission)
312 {
313 AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
314 TypeATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
315 if (tokenType == TOKEN_INVALID) {
316 IMSA_HILOGE("invalid token");
317 return false;
318 }
319 int result = AccessTokenKit::VerifyAccessToken(tokenId, permission);
320 IMSA_HILOGI("CheckPermission %{public}s", result == PERMISSION_GRANTED ? "success" : "failed");
321 return result == PERMISSION_GRANTED;
322 }
323 } // namespace MiscServices
324 } // namespace OHOS
325