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 <chrono> 19#include <cinttypes> 20#include <memory> 21 22#include "element_name.h" 23#include "input_client_proxy.h" 24#include "input_method_core_proxy.h" 25#include "ipc_skeleton.h" 26#include "itypes_util.h" 27#include "xcollie/xcollie.h" 28#include "xcollie/xcollie_define.h" 29namespace OHOS { 30namespace MiscServices { 31using namespace std::chrono; 32using namespace HiviewDFX; 33constexpr uint32_t FATAL_TIMEOUT = 30; // 30s 34constexpr int64_t WARNING_TIMEOUT = 5000; // 5s 35int32_t InputMethodSystemAbilityStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, 36 MessageOption &option) 37{ 38 if (code != static_cast<uint32_t>(InputMethodInterfaceCode::RELEASE_INPUT)) { 39 IMSA_HILOGI("IMSA, code = %{public}u, callingPid/Uid/timestamp: %{public}d/%{public}d/%{public}lld", code, 40 IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid(), 41 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()) 42 .count()); 43 } 44 std::u16string remoteDescriptor = data.ReadInterfaceToken(); 45 if (remoteDescriptor != IInputMethodSystemAbility::GetDescriptor()) { 46 IMSA_HILOGE("%{public}s descriptor failed!", __func__); 47 return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION; 48 } 49 if (code >= static_cast<uint32_t>(InputMethodInterfaceCode::IMS_CMD_BEGIN) && 50 code < static_cast<uint32_t>(InputMethodInterfaceCode::IMS_CMD_END)) { 51 // service reboot when timeout 30s 52 auto id = XCollie::GetInstance().SetTimer("IMSA_API[" + std::to_string(code) + "]", FATAL_TIMEOUT, nullptr, 53 nullptr, XCOLLIE_FLAG_DEFAULT); 54 int64_t startPoint = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); 55 auto ret = (this->*HANDLERS[code])(data, reply); 56 int64_t costTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count() - startPoint; 57 // log warning when timeout 5s 58 if (costTime > WARNING_TIMEOUT) { 59 IMSA_HILOGW("code: %{public}d, pid: %{public}d, uid: %{public}d, cost: %{public}" PRId64 "", code, 60 IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid(), costTime); 61 } 62 XCollie::GetInstance().CancelTimer(id); 63 return ret; 64 } else { 65 IMSA_HILOGE("code error, code = %{public}u, callingPid: %{public}d, callingUid: %{public}d.", code, 66 IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid()); 67 return IPCObjectStub::OnRemoteRequest(code, data, reply, option); 68 } 69} 70 71int32_t InputMethodSystemAbilityStub::StartInputOnRemote(MessageParcel &data, MessageParcel &reply) 72{ 73 InputClientInfo clientInfo; 74 sptr<IRemoteObject> client = nullptr; 75 if (!ITypesUtil::Unmarshal(data, clientInfo, client, clientInfo.channel)) { 76 IMSA_HILOGE("read clientInfo failed!"); 77 return ErrorCode::ERROR_EX_PARCELABLE; 78 } 79 clientInfo.client = iface_cast<IInputClient>(client); 80 sptr<IRemoteObject> agent = nullptr; 81 int32_t ret = StartInput(clientInfo, agent); 82 return reply.WriteInt32(ret) && reply.WriteRemoteObject(agent) ? ErrorCode::NO_ERROR 83 : ErrorCode::ERROR_EX_PARCELABLE; 84} 85 86int32_t InputMethodSystemAbilityStub::ShowCurrentInputOnRemote(MessageParcel &data, MessageParcel &reply) 87{ 88 int32_t ret = ShowCurrentInput(); 89 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 90} 91 92int32_t InputMethodSystemAbilityStub::HideCurrentInputOnRemote(MessageParcel &data, MessageParcel &reply) 93{ 94 int32_t ret = HideCurrentInput(); 95 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 96} 97 98int32_t InputMethodSystemAbilityStub::StopInputSessionOnRemote(MessageParcel &data, MessageParcel &reply) 99{ 100 int32_t ret = StopInputSession(); 101 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 102} 103 104int32_t InputMethodSystemAbilityStub::ShowInputOnRemote(MessageParcel &data, MessageParcel &reply) 105{ 106 auto clientObject = data.ReadRemoteObject(); 107 if (clientObject == nullptr) { 108 IMSA_HILOGE("clientObject is nullptr!"); 109 return ErrorCode::ERROR_EX_PARCELABLE; 110 } 111 int32_t ret = ShowInput(iface_cast<IInputClient>(clientObject)); 112 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 113} 114 115int32_t InputMethodSystemAbilityStub::HideInputOnRemote(MessageParcel &data, MessageParcel &reply) 116{ 117 auto clientObject = data.ReadRemoteObject(); 118 if (clientObject == nullptr) { 119 IMSA_HILOGE("clientObject is nullptr!"); 120 return ErrorCode::ERROR_EX_PARCELABLE; 121 } 122 int32_t ret = HideInput(iface_cast<IInputClient>(clientObject)); 123 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 124} 125 126int32_t InputMethodSystemAbilityStub::ReleaseInputOnRemote(MessageParcel &data, MessageParcel &reply) 127{ 128 auto clientObject = data.ReadRemoteObject(); 129 if (clientObject == nullptr) { 130 IMSA_HILOGE("clientObject is nullptr!"); 131 return ErrorCode::ERROR_EX_PARCELABLE; 132 } 133 int32_t ret = ReleaseInput(iface_cast<IInputClient>(clientObject)); 134 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 135} 136 137int32_t InputMethodSystemAbilityStub::RequestShowInputOnRemote(MessageParcel &data, MessageParcel &reply) 138{ 139 return reply.WriteInt32(RequestShowInput()) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 140} 141 142int32_t InputMethodSystemAbilityStub::RequestHideInputOnRemote(MessageParcel &data, MessageParcel &reply) 143{ 144 return reply.WriteInt32(RequestHideInput()) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 145} 146 147int32_t InputMethodSystemAbilityStub::DisplayOptionalInputMethodOnRemote(MessageParcel &data, MessageParcel &reply) 148{ 149 int32_t ret = DisplayOptionalInputMethod(); 150 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 151} 152 153int32_t InputMethodSystemAbilityStub::SetCoreAndAgentOnRemote(MessageParcel &data, MessageParcel &reply) 154{ 155 auto coreObject = data.ReadRemoteObject(); 156 if (coreObject == nullptr) { 157 IMSA_HILOGE("coreObject is nullptr!"); 158 return ErrorCode::ERROR_EX_PARCELABLE; 159 } 160 auto agentObject = data.ReadRemoteObject(); 161 if (agentObject == nullptr) { 162 IMSA_HILOGE("agentObject is nullptr!"); 163 return ErrorCode::ERROR_EX_PARCELABLE; 164 } 165 int32_t ret = SetCoreAndAgent(iface_cast<IInputMethodCore>(coreObject), agentObject); 166 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 167} 168 169int32_t InputMethodSystemAbilityStub::GetDefaultInputMethodOnRemote(MessageParcel &data, MessageParcel &reply) 170{ 171 std::shared_ptr<Property> prop = std::make_shared<Property>(); 172 bool isBrief = false; 173 auto ret = data.ReadBool(isBrief); 174 if (!ret) { 175 IMSA_HILOGE("read isBrief failed!"); 176 } 177 ret = GetDefaultInputMethod(prop, isBrief); 178 if (prop == nullptr) { 179 return ErrorCode::ERROR_EX_PARCELABLE; 180 } 181 return ITypesUtil::Marshal(reply, ret, *prop) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 182} 183 184int32_t InputMethodSystemAbilityStub::IsDefaultImeSetOnRemote(MessageParcel &data, MessageParcel &reply) 185{ 186 return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, IsDefaultImeSet()) ? ErrorCode::NO_ERROR 187 : ErrorCode::ERROR_EX_PARCELABLE; 188} 189 190int32_t InputMethodSystemAbilityStub::EnableImeOnRemote(MessageParcel &data, MessageParcel &reply) 191{ 192 std::string bundleName; 193 if (!ITypesUtil::Unmarshal(data, bundleName)) { 194 IMSA_HILOGE("unmarshal failed!"); 195 return ErrorCode::ERROR_EX_PARCELABLE; 196 } 197 return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, EnableIme(bundleName)) ? ErrorCode::NO_ERROR 198 : ErrorCode::ERROR_EX_PARCELABLE; 199} 200 201int32_t InputMethodSystemAbilityStub::GetInputMethodConfigOnRemote(MessageParcel &data, MessageParcel &reply) 202{ 203 OHOS::AppExecFwk::ElementName inputMethodConfig; 204 auto ret = GetInputMethodConfig(inputMethodConfig); 205 IMSA_HILOGD("GetInputMethodConfigOnRemote inputMethodConfig is %{public}s, %{public}s", 206 inputMethodConfig.GetBundleName().c_str(), inputMethodConfig.GetAbilityName().c_str()); 207 return ITypesUtil::Marshal(reply, ret, inputMethodConfig) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 208} 209 210int32_t InputMethodSystemAbilityStub::GetSecurityModeOnRemote(MessageParcel &data, MessageParcel &reply) 211{ 212 IMSA_HILOGD("GetSecurityModeOnRemote start."); 213 int32_t security; 214 auto ret = GetSecurityMode(security); 215 IMSA_HILOGD("GetSecurityModeOnRemote, security: %{public}d", security); 216 return ITypesUtil::Marshal(reply, ret, security) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 217} 218 219int32_t InputMethodSystemAbilityStub::GetCurrentInputMethodOnRemote(MessageParcel &data, MessageParcel &reply) 220{ 221 auto property = GetCurrentInputMethod(); 222 if (property == nullptr) { 223 IMSA_HILOGE("property is nullptr!"); 224 return reply.WriteInt32(ErrorCode::ERROR_EX_NULL_POINTER) ? ErrorCode::NO_ERROR 225 : ErrorCode::ERROR_EX_PARCELABLE; 226 } 227 if (!ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, *property)) { 228 IMSA_HILOGE("marshal failed!"); 229 return ErrorCode::ERROR_EX_PARCELABLE; 230 } 231 return ErrorCode::NO_ERROR; 232} 233 234int32_t InputMethodSystemAbilityStub::GetCurrentInputMethodSubtypeOnRemote(MessageParcel &data, MessageParcel &reply) 235{ 236 auto property = GetCurrentInputMethodSubtype(); 237 if (property == nullptr) { 238 IMSA_HILOGE("property is nullptr!"); 239 return reply.WriteInt32(ErrorCode::ERROR_EX_NULL_POINTER) ? ErrorCode::NO_ERROR 240 : ErrorCode::ERROR_EX_PARCELABLE; 241 } 242 if (!ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, *property)) { 243 IMSA_HILOGE("marshal failed!"); 244 return ErrorCode::ERROR_EX_PARCELABLE; 245 } 246 return ErrorCode::NO_ERROR; 247} 248 249int32_t InputMethodSystemAbilityStub::ListInputMethodOnRemote(MessageParcel &data, MessageParcel &reply) 250{ 251 uint32_t status; 252 if (!ITypesUtil::Unmarshal(data, status)) { 253 IMSA_HILOGE("read status failed!"); 254 return ErrorCode::ERROR_EX_PARCELABLE; 255 } 256 std::vector<Property> properties = {}; 257 auto ret = ListInputMethod(InputMethodStatus(status), properties); 258 if (!ITypesUtil::Marshal(reply, ret, properties)) { 259 IMSA_HILOGE("marshal failed!"); 260 return ErrorCode::ERROR_EX_PARCELABLE; 261 } 262 return ErrorCode::NO_ERROR; 263} 264 265int32_t InputMethodSystemAbilityStub::ListInputMethodSubtypeOnRemote(MessageParcel &data, MessageParcel &reply) 266{ 267 std::string bundleName; 268 if (!ITypesUtil::Unmarshal(data, bundleName)) { 269 IMSA_HILOGE("read bundleName failed!"); 270 return ErrorCode::ERROR_EX_PARCELABLE; 271 } 272 std::vector<SubProperty> subProps = {}; 273 auto ret = ListInputMethodSubtype(bundleName, subProps); 274 if (!ITypesUtil::Marshal(reply, ret, subProps)) { 275 IMSA_HILOGE("marshal failed!"); 276 return ErrorCode::ERROR_EX_PARCELABLE; 277 } 278 return ErrorCode::NO_ERROR; 279} 280 281int32_t InputMethodSystemAbilityStub::ListCurrentInputMethodSubtypeOnRemote(MessageParcel &data, MessageParcel &reply) 282{ 283 std::vector<SubProperty> subProps = {}; 284 auto ret = ListCurrentInputMethodSubtype(subProps); 285 if (!ITypesUtil::Marshal(reply, ret, subProps)) { 286 IMSA_HILOGE("marshal failed!"); 287 return ErrorCode::ERROR_EX_PARCELABLE; 288 } 289 return ErrorCode::NO_ERROR; 290} 291 292int32_t InputMethodSystemAbilityStub::SwitchInputMethodOnRemote(MessageParcel &data, MessageParcel &reply) 293{ 294 std::string name; 295 std::string subName; 296 SwitchTrigger trigger; 297 if (!ITypesUtil::Unmarshal(data, name, subName, trigger)) { 298 IMSA_HILOGE("unmarshal failed!"); 299 return ErrorCode::ERROR_EX_PARCELABLE; 300 } 301 return reply.WriteInt32(SwitchInputMethod(name, subName, trigger)) ? ErrorCode::NO_ERROR 302 : ErrorCode::ERROR_EX_PARCELABLE; 303} 304 305int32_t InputMethodSystemAbilityStub::PanelStatusChangeOnRemote(MessageParcel &data, MessageParcel &reply) 306{ 307 uint32_t status = 0; 308 ImeWindowInfo info; 309 if (!ITypesUtil::Unmarshal(data, status, info)) { 310 IMSA_HILOGE("unmarshal failed!"); 311 return ErrorCode::ERROR_EX_PARCELABLE; 312 } 313 int32_t ret = PanelStatusChange(static_cast<InputWindowStatus>(status), info); 314 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 315} 316 317int32_t InputMethodSystemAbilityStub::UpdateListenEventFlagOnRemote(MessageParcel &data, MessageParcel &reply) 318{ 319 InputClientInfo clientInfo; 320 sptr<IRemoteObject> client = nullptr; 321 uint32_t eventFlag = 0; 322 if (!ITypesUtil::Unmarshal(data, clientInfo, client, clientInfo.channel, eventFlag)) { 323 IMSA_HILOGE("unmarshal failed!"); 324 return ErrorCode::ERROR_EX_PARCELABLE; 325 } 326 clientInfo.client = iface_cast<IInputClient>(client); 327 int32_t ret = UpdateListenEventFlag(clientInfo, eventFlag); 328 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 329} 330 331int32_t InputMethodSystemAbilityStub::ShowCurrentInputOnRemoteDeprecated(MessageParcel &data, MessageParcel &reply) 332{ 333 int32_t ret = ShowCurrentInputDeprecated(); 334 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 335} 336 337int32_t InputMethodSystemAbilityStub::HideCurrentInputOnRemoteDeprecated(MessageParcel &data, MessageParcel &reply) 338{ 339 int32_t ret = HideCurrentInputDeprecated(); 340 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 341} 342 343int32_t InputMethodSystemAbilityStub::IsCurrentImeOnRemote(MessageParcel &data, MessageParcel &reply) 344{ 345 return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, IsCurrentIme()) ? ErrorCode::NO_ERROR 346 : ErrorCode::ERROR_EX_PARCELABLE; 347} 348 349int32_t InputMethodSystemAbilityStub::UnRegisteredProxyImeOnRemote(MessageParcel &data, MessageParcel &reply) 350{ 351 int32_t type = -1; 352 sptr<IRemoteObject> coreObject = nullptr; 353 if (!ITypesUtil::Unmarshal(data, type, coreObject) || coreObject == nullptr) { 354 IMSA_HILOGE("coreObject is nullptr!"); 355 return ErrorCode::ERROR_EX_PARCELABLE; 356 } 357 int32_t ret = UnRegisteredProxyIme(static_cast<UnRegisteredType>(type), iface_cast<IInputMethodCore>(coreObject)); 358 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 359} 360 361int32_t InputMethodSystemAbilityStub::IsInputTypeSupportedOnRemote(MessageParcel &data, MessageParcel &reply) 362{ 363 InputType type; 364 if (!ITypesUtil::Unmarshal(data, type)) { 365 IMSA_HILOGE("unmarshal failed!"); 366 return ErrorCode::ERROR_EX_PARCELABLE; 367 } 368 return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, IsInputTypeSupported(type)) ? ErrorCode::NO_ERROR 369 : ErrorCode::ERROR_EX_PARCELABLE; 370} 371 372int32_t InputMethodSystemAbilityStub::StartInputTypeOnRemote(MessageParcel &data, MessageParcel &reply) 373{ 374 InputType type; 375 if (!ITypesUtil::Unmarshal(data, type)) { 376 IMSA_HILOGE("unmarshal failed!"); 377 return ErrorCode::ERROR_EX_PARCELABLE; 378 } 379 return ITypesUtil::Marshal(reply, StartInputType(type)) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 380} 381 382int32_t InputMethodSystemAbilityStub::ExitCurrentInputTypeOnRemote(MessageParcel &data, MessageParcel &reply) 383{ 384 return ITypesUtil::Marshal(reply, ExitCurrentInputType()) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 385} 386 387int32_t InputMethodSystemAbilityStub::IsPanelShownOnRemote(MessageParcel &data, MessageParcel &reply) 388{ 389 PanelInfo info; 390 if (!ITypesUtil::Unmarshal(data, info)) { 391 IMSA_HILOGE("unmarshal failed!"); 392 return ErrorCode::ERROR_EX_PARCELABLE; 393 } 394 bool isShown = false; 395 int32_t ret = IsPanelShown(info, isShown); 396 return ITypesUtil::Marshal(reply, ret, isShown) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 397} 398 399int32_t InputMethodSystemAbilityStub::IsDefaultImeOnRemote(MessageParcel &data, MessageParcel &reply) 400{ 401 return ITypesUtil::Marshal(reply, IsDefaultIme()) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 402} 403 404int32_t InputMethodSystemAbilityStub::ConnectSystemCmdOnRemote(MessageParcel &data, MessageParcel &reply) 405{ 406 auto systemCmdStub = data.ReadRemoteObject(); 407 if (systemCmdStub == nullptr) { 408 IMSA_HILOGE("systemCmdStub is nullptr!"); 409 return ErrorCode::ERROR_EX_PARCELABLE; 410 } 411 sptr<IRemoteObject> agent = nullptr; 412 int32_t ret = ConnectSystemCmd(systemCmdStub, agent); 413 return reply.WriteInt32(ret) && reply.WriteRemoteObject(agent) ? ErrorCode::NO_ERROR 414 : ErrorCode::ERROR_EX_PARCELABLE; 415} 416 417int32_t InputMethodSystemAbilityStub::IsCurrentImeByPidOnRemote(MessageParcel &data, MessageParcel &reply) 418{ 419 int32_t pid = -1; 420 if (!ITypesUtil::Unmarshal(data, pid)) { 421 IMSA_HILOGE("unmarshal failed!"); 422 return ErrorCode::ERROR_EX_PARCELABLE; 423 } 424 return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, IsCurrentImeByPid(pid)) ? ErrorCode::NO_ERROR 425 : ErrorCode::ERROR_EX_PARCELABLE; 426} 427 428int32_t InputMethodSystemAbilityStub::InitConnectOnRemote(MessageParcel &data, MessageParcel &reply) 429{ 430 return reply.WriteInt32(InitConnect()) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; 431} 432} // namespace MiscServices 433} // namespace OHOS