1 /* 2 * Copyright (C) 2021 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 #include "input_method_core_stub.h" 16 17 #include <string_ex.h> 18 19 #include <chrono> 20 #include <cstdint> 21 22 #include "i_input_data_channel.h" 23 #include "input_channel.h" 24 #include "input_control_channel_proxy.h" 25 #include "input_method_ability.h" 26 #include "message_handler.h" 27 #include "message_parcel.h" 28 29 namespace OHOS { 30 namespace MiscServices { 31 using namespace MessageID; 32 /** 33 * param userId the id of the user to whom the object is linking 34 * @param userId 35 */ InputMethodCoreStub(int userId)36 InputMethodCoreStub::InputMethodCoreStub(int userId) 37 { 38 userId_ = userId; 39 msgHandler_ = nullptr; 40 } 41 ~InputMethodCoreStub()42 InputMethodCoreStub::~InputMethodCoreStub() 43 { 44 } 45 OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)46 int32_t InputMethodCoreStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, 47 MessageOption& option) 48 { 49 auto descriptorToken = data.ReadInterfaceToken(); 50 if (descriptorToken != GetDescriptor()) { 51 IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest descriptorToken is invalid"); 52 return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION; 53 } 54 switch (code) { 55 case INIT_INPUT_CONTROL_CHANNEL: { 56 sptr<IRemoteObject> channelObject = data.ReadRemoteObject(); 57 if (!channelObject) { 58 IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest channelObject is nullptr"); 59 } 60 sptr<IInputControlChannel> inputControlChannel = new InputControlChannelProxy(channelObject); 61 if (!inputControlChannel) { 62 IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest inputControlChannel is nullptr"); 63 } 64 65 InitInputControlChannel(inputControlChannel, data.ReadString()); 66 reply.WriteNoException(); 67 break; 68 } 69 case SHOW_KEYBOARD: { 70 ShowKeyboardOnRemote(data, reply); 71 break; 72 } 73 case HIDE_KEYBOARD: { 74 int32_t flags = data.ReadInt32(); 75 hideKeyboard(flags); 76 reply.WriteNoException(); 77 break; 78 } 79 case STOP_INPUT_SERVICE: { 80 std::string imeId = Str16ToStr8(data.ReadString16()); 81 StopInputService(imeId); 82 reply.WriteNoException(); 83 break; 84 } 85 case SET_SUBTYPE: { 86 SetSubtypeOnRemote(data, reply); 87 break; 88 } 89 default: { 90 return IRemoteStub::OnRemoteRequest(code, data, reply, option); 91 } 92 } 93 return NO_ERROR; 94 } 95 96 InitInputControlChannel(sptr<IInputControlChannel> & inputControlChannel,const std::string & imeId)97 int32_t InputMethodCoreStub::InitInputControlChannel( 98 sptr<IInputControlChannel> &inputControlChannel, const std::string &imeId) 99 { 100 IMSA_HILOGD("InputMethodCoreStub::InitInputControlChannel"); 101 if (!msgHandler_) { 102 return ErrorCode::ERROR_NULL_POINTER; 103 } 104 105 MessageParcel *data = new MessageParcel(); 106 if (inputControlChannel) { 107 IMSA_HILOGI("InputMethodCoreStub::InitInputControlChannel. inputControlChannel is not nullptr"); 108 data->WriteRemoteObject(inputControlChannel->AsObject()); 109 } 110 data->WriteString(imeId); 111 Message *msg = new Message(MessageID::MSG_ID_INIT_INPUT_CONTROL_CHANNEL, data); 112 msgHandler_->SendMessage(msg); 113 return ErrorCode::NO_ERROR; 114 } 115 hideKeyboard(int32_t flags)116 bool InputMethodCoreStub::hideKeyboard(int32_t flags) 117 { 118 IMSA_HILOGD("InputMethodCoreStub::hideKeyboard"); 119 if (!msgHandler_) { 120 return ErrorCode::ERROR_NULL_POINTER; 121 } 122 MessageParcel *data = new MessageParcel(); 123 data->WriteInt32(userId_); 124 data->WriteInt32(flags); 125 126 Message *msg = new Message(MessageID::MSG_ID_HIDE_KEYBOARD, data); 127 msgHandler_->SendMessage(msg); 128 return true; 129 } 130 131 StopInputService(std::string imeId)132 void InputMethodCoreStub::StopInputService(std::string imeId) 133 { 134 IMSA_HILOGD("InputMethodCoreStub::StopInputService"); 135 if (!msgHandler_) { 136 return; 137 } 138 MessageParcel *data = new MessageParcel(); 139 data->WriteString16(Str8ToStr16(imeId)); 140 141 Message *msg = new Message(MessageID::MSG_ID_STOP_INPUT_SERVICE, data); 142 msgHandler_->SendMessage(msg); 143 } 144 145 SetMessageHandler(MessageHandler * msgHandler)146 void InputMethodCoreStub::SetMessageHandler(MessageHandler *msgHandler) 147 { 148 msgHandler_ = msgHandler; 149 } 150 ShowKeyboardOnRemote(MessageParcel & data,MessageParcel & reply)151 void InputMethodCoreStub::ShowKeyboardOnRemote(MessageParcel &data, MessageParcel &reply) 152 { 153 IMSA_HILOGD("InputMethodCoreStub::ShowKeyboardOnRemote"); 154 sptr<IRemoteObject> channel; 155 bool isShowKeyboard = false; 156 SubProperty subProperty; 157 int32_t ret = SendMessage( 158 MessageID::MSG_ID_SHOW_KEYBOARD, [&data, &channel, &isShowKeyboard, &subProperty](MessageParcel &parcel) { 159 return ITypesUtil::Unmarshal(data, channel, isShowKeyboard, subProperty) 160 && ITypesUtil::Marshal(parcel, channel, isShowKeyboard, subProperty); 161 }); 162 reply.WriteInt32(ret); 163 } 164 SetSubtypeOnRemote(MessageParcel & data,MessageParcel & reply)165 void InputMethodCoreStub::SetSubtypeOnRemote(MessageParcel &data, MessageParcel &reply) 166 { 167 IMSA_HILOGD("InputMethodCoreStub::SetSubtypeOnRemote"); 168 SubProperty property; 169 int32_t ret = SendMessage(MessageID::MSG_ID_SET_SUBTYPE, [&data, &property](MessageParcel &parcel) { 170 return ITypesUtil::Unmarshal(data, property) && ITypesUtil::Marshal(parcel, property); 171 }); 172 reply.WriteInt32(ret); 173 } 174 showKeyboard(const sptr<IInputDataChannel> & inputDataChannel,bool isShowKeyboard,const SubProperty & subProperty)175 int32_t InputMethodCoreStub::showKeyboard( 176 const sptr<IInputDataChannel> &inputDataChannel, bool isShowKeyboard, const SubProperty &subProperty) 177 { 178 return ErrorCode::NO_ERROR; 179 } 180 SetSubtype(const SubProperty & property)181 int32_t InputMethodCoreStub::SetSubtype(const SubProperty &property) 182 { 183 return ErrorCode::NO_ERROR; 184 } 185 SendMessage(int code,ParcelHandler input)186 int32_t InputMethodCoreStub::SendMessage(int code, ParcelHandler input) 187 { 188 IMSA_HILOGD("InputMethodCoreStub::SendMessage"); 189 if (msgHandler_ == nullptr) { 190 IMSA_HILOGE("InputMethodCoreStub::msgHandler_ is nullptr"); 191 return ErrorCode::ERROR_EX_NULL_POINTER; 192 } 193 auto *parcel = new (std::nothrow) MessageParcel(); 194 if (parcel == nullptr) { 195 IMSA_HILOGE("parcel is nullptr"); 196 return ErrorCode::ERROR_EX_NULL_POINTER; 197 } 198 if (input != nullptr && (!input(*parcel))) { 199 IMSA_HILOGE("write data failed"); 200 delete parcel; 201 return ErrorCode::ERROR_EX_PARCELABLE; 202 } 203 auto *msg = new (std::nothrow) Message(code, parcel); 204 if (msg == nullptr) { 205 IMSA_HILOGE("msg is nullptr"); 206 delete parcel; 207 return ErrorCode::ERROR_EX_NULL_POINTER; 208 } 209 msgHandler_->SendMessage(msg); 210 return ErrorCode::NO_ERROR; 211 } 212 } // namespace MiscServices 213 } // namespace OHOS 214