diff --git a/bundle.json b/bundle.json index e7bb1b9db97c0fd2465eeb148aedc811a2c8481c..b1a5f859c55c1da0191433eebcb184cd71aaad7a 100644 --- a/bundle.json +++ b/bundle.json @@ -47,6 +47,7 @@ "hitrace", "graphic_2d", "ffrt", + "config_policy", "data_share" ], "third_party": [ diff --git a/frameworks/js/napi/inputmethodability/js_input_method_engine_setting.cpp b/frameworks/js/napi/inputmethodability/js_input_method_engine_setting.cpp index b0605d2d887bc5f594195e725811f050b94f9d35..ca1cd39c05e920b1a08316148bcd904f5c106923 100644 --- a/frameworks/js/napi/inputmethodability/js_input_method_engine_setting.cpp +++ b/frameworks/js/napi/inputmethodability/js_input_method_engine_setting.cpp @@ -579,11 +579,11 @@ void JsInputMethodEngineSetting::OnKeyboardStatus(bool isShow) uv_qos_user_initiated); } -void JsInputMethodEngineSetting::OnInputStop(const std::string &imeId) +void JsInputMethodEngineSetting::OnInputStop() { IMSA_HILOGD("run in"); std::string type = "inputStop"; - uv_work_t *work = GetUVwork(type, [&imeId](UvEntry &entry) { entry.imeid = imeId; }); + uv_work_t *work = GetUVwork(type); if (work == nullptr) { IMSA_HILOGD("failed to get uv entry"); return; @@ -595,20 +595,7 @@ void JsInputMethodEngineSetting::OnInputStop(const std::string &imeId) delete data; delete work; }); - if (entry == nullptr) { - IMSA_HILOGE("OnInputStop:: entryptr is null"); - return; - } - auto getInputStopProperty = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { - if (argc == 0) { - return false; - } - // 0 means the first param of callback. - napi_create_string_utf8(env, entry->imeid.c_str(), NAPI_AUTO_LENGTH, &args[0]); - return true; - }; - // 1 means callback has one param. - JsCallbackHandler::Traverse(entry->vecCopy, { 1, getInputStopProperty }); + JsCallbackHandler::Traverse(entry->vecCopy); }, uv_qos_user_initiated); } diff --git a/frameworks/js/napi/inputmethodability/js_input_method_engine_setting.h b/frameworks/js/napi/inputmethodability/js_input_method_engine_setting.h index 4952e8d9d94926e2c09b000b7a3dbd67e661921c..c7d7303cde4b89f6743a477cb4dc439c1b1df1f0 100644 --- a/frameworks/js/napi/inputmethodability/js_input_method_engine_setting.h +++ b/frameworks/js/napi/inputmethodability/js_input_method_engine_setting.h @@ -47,7 +47,7 @@ public: static napi_value DestroyPanel(napi_env env, napi_callback_info info); void OnInputStart() override; void OnKeyboardStatus(bool isShow) override; - void OnInputStop(const std::string &imeId) override; + void OnInputStop() override; void OnSetCallingWindow(uint32_t windowId) override; void OnSetSubtype(const SubProperty &property) override; @@ -94,7 +94,6 @@ private: struct UvEntry { std::vector> vecCopy; std::string type; - std::string imeid; uint32_t windowid = 0; SubProperty subProperty; UvEntry(const std::vector> &cbVec, const std::string &type) diff --git a/frameworks/js/napi/inputmethodability/js_keyboard_controller_engine.cpp b/frameworks/js/napi/inputmethodability/js_keyboard_controller_engine.cpp index a6c7b986b8485d1fde67202c3c660dd079c9e829..0b2e35954bd285204a02cf9b2b90eeed143ccbcf 100644 --- a/frameworks/js/napi/inputmethodability/js_keyboard_controller_engine.cpp +++ b/frameworks/js/napi/inputmethodability/js_keyboard_controller_engine.cpp @@ -28,6 +28,7 @@ napi_value JsKeyboardControllerEngine::Init(napi_env env, napi_value info) napi_property_descriptor properties[] = { DECLARE_NAPI_FUNCTION("hideKeyboard", HideKeyboard), DECLARE_NAPI_FUNCTION("hide", Hide), + DECLARE_NAPI_FUNCTION("exitCurrentInputType", ExitCurrentInputType), }; napi_value cons = nullptr; NAPI_CALL(env, napi_define_class(env, KCE_CLASS_NAME.c_str(), KCE_CLASS_NAME.size(), JsConstructor, nullptr, @@ -117,5 +118,20 @@ napi_value JsKeyboardControllerEngine::HideKeyboard(napi_env env, napi_callback_ AsyncCall asyncCall(env, info, ctxt, 1); return asyncCall.Call(env, exec, "hideKeyboard"); } + +napi_value JsKeyboardControllerEngine::ExitCurrentInputType(napi_env env, napi_callback_info info) +{ + auto ctxt = std::make_shared(); + auto input = [ctxt]( + napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { return napi_ok; }; + auto output = [ctxt](napi_env env, napi_value *result) -> napi_status { return napi_ok; }; + auto exec = [ctxt](AsyncCall::Context *ctx) { + int32_t errorCode = InputMethodAbility::GetInstance()->ExitCurrentInputType(); + errorCode == ErrorCode::NO_ERROR ? ctxt->SetState(napi_ok) : ctxt->SetErrorCode(errorCode); + }; + ctxt->SetAction(std::move(input), std::move(output)); + AsyncCall asyncCall(env, info, ctxt, 1); + return asyncCall.Call(env, exec, "exitCurrentInputType"); +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/napi/inputmethodability/js_keyboard_controller_engine.h b/frameworks/js/napi/inputmethodability/js_keyboard_controller_engine.h index bc351aa5fcd51e38f0f84cc2c972de292e32e4ae..37c27bdb56f61690683ff099fb7216c73c6c381c 100644 --- a/frameworks/js/napi/inputmethodability/js_keyboard_controller_engine.h +++ b/frameworks/js/napi/inputmethodability/js_keyboard_controller_engine.h @@ -60,6 +60,25 @@ struct HideContext : public AsyncCall::Context { } }; +struct ExitContext : public AsyncCall::Context { + napi_status status = napi_generic_failure; + ExitContext() : Context(nullptr, nullptr){}; + + napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override + { + CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); + return Context::operator()(env, argc, argv, self); + } + napi_status operator()(napi_env env, napi_value *result) override + { + if (status != napi_ok) { + output_ = nullptr; + return status; + } + return Context::operator()(env, result); + } +}; + class JsKeyboardControllerEngine { public: JsKeyboardControllerEngine() = default; @@ -68,6 +87,7 @@ public: static napi_value GetKeyboardControllerInstance(napi_env env); static napi_value HideKeyboard(napi_env env, napi_callback_info info); static napi_value Hide(napi_env env, napi_callback_info info); + static napi_value ExitCurrentInputType(napi_env env, napi_callback_info info); private: static napi_value JsConstructor(napi_env env, napi_callback_info info); diff --git a/frameworks/js/napi/inputmethodclient/js_utils.cpp b/frameworks/js/napi/inputmethodclient/js_utils.cpp index 04cd96d41e0dfeaef8dc84f8a911a7fb746e5cee..4d43edccef09a2e5825886f6225c136c226c9dcb 100644 --- a/frameworks/js/napi/inputmethodclient/js_utils.cpp +++ b/frameworks/js/napi/inputmethodclient/js_utils.cpp @@ -51,6 +51,7 @@ const std::map JsUtils::ERROR_CODE_MAP = { { ErrorCode::ERROR_NOT_IME, EXCEPTION_IME }, { ErrorCode::ERROR_IME, EXCEPTION_IMENGINE }, { ErrorCode::ERROR_PARAMETER_CHECK_FAILED, EXCEPTION_PARAMCHECK }, + { ErrorCode::ERROR_NOT_DEFAULT_IME, EXCEPTION_DEFAULTIME }, }; const std::map JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = { @@ -67,6 +68,7 @@ const std::map JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = { { EXCEPTION_SETTINGS, "input method settings extension error." }, { EXCEPTION_IMMS, "input method manager service error." }, { EXCEPTION_DETACHED, "input method not attached." }, + { EXCEPTION_DEFAULTIME, "not default input method configured by system." }, }; const std::map JsUtils::PARAMETER_TYPE = { diff --git a/frameworks/js/napi/inputmethodclient/js_utils.h b/frameworks/js/napi/inputmethodclient/js_utils.h index e3eeeb9063457e9a175008a0029786ac5e4a78f3..0b715ce1f31465eed38f7f5dfff12a98b1658ab2 100644 --- a/frameworks/js/napi/inputmethodclient/js_utils.h +++ b/frameworks/js/napi/inputmethodclient/js_utils.h @@ -45,6 +45,7 @@ enum IMFErrorCode : int32_t { EXCEPTION_SETTINGS, EXCEPTION_IMMS, EXCEPTION_DETACHED, + EXCEPTION_DEFAULTIME, }; enum TypeCode : int32_t { diff --git a/frameworks/native/inputmethod_ability/include/i_input_method_core.h b/frameworks/native/inputmethod_ability/include/i_input_method_core.h index 3254e0c475510c98720f569885c9430c1f2af9d4..d421f1dfadb42333b5a83aacad32bd2d7986eb4c 100644 --- a/frameworks/native/inputmethod_ability/include/i_input_method_core.h +++ b/frameworks/native/inputmethod_ability/include/i_input_method_core.h @@ -51,9 +51,8 @@ public: virtual int32_t StopInput(const sptr &channel) = 0; virtual int32_t ShowKeyboard() = 0; virtual int32_t HideKeyboard() = 0; - virtual int32_t InitInputControlChannel( - sptr &inputControlChannel, const std::string &imeId) = 0; - virtual void StopInputService(std::string imeId) = 0; + virtual int32_t InitInputControlChannel(const sptr &inputControlChannel) = 0; + virtual void StopInputService() = 0; virtual int32_t SetSubtype(const SubProperty &property) = 0; virtual bool IsEnable() = 0; }; diff --git a/frameworks/native/inputmethod_ability/include/input_method_ability.h b/frameworks/native/inputmethod_ability/include/input_method_ability.h index 1443251b4380481c205c22abe1cbb504192559e9..0eda4976589b87e58f6c01332e02e05764775119 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_ability.h +++ b/frameworks/native/inputmethod_ability/include/input_method_ability.h @@ -78,6 +78,7 @@ public: int32_t HidePanel(const std::shared_ptr &inputMethodPanel); bool IsCurrentIme(); bool IsEnable(); + int32_t ExitCurrentInputType(); private: std::thread workThreadHandler; @@ -100,7 +101,6 @@ private: std::mutex abilityLock_; sptr abilityManager_{ nullptr }; sptr deathRecipient_{ nullptr }; - std::string currentIme_; sptr GetImsaProxy(); void OnRemoteSaDied(const wptr &object); diff --git a/frameworks/native/inputmethod_ability/include/input_method_core_proxy.h b/frameworks/native/inputmethod_ability/include/input_method_core_proxy.h index 07d9b7efaf2d12c5005c506411330591c39089f5..80589a51be33d2aad9018ad217da1ba951a002c1 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_core_proxy.h +++ b/frameworks/native/inputmethod_ability/include/input_method_core_proxy.h @@ -39,8 +39,8 @@ public: int32_t StopInput(const sptr &channel) override; int32_t ShowKeyboard() override; int32_t HideKeyboard() override; - int32_t InitInputControlChannel(sptr &inputControlChannel, const std::string &imeId) override; - void StopInputService(std::string imeId) override; + int32_t InitInputControlChannel(const sptr &inputControlChannel) override; + void StopInputService() override; int32_t SetSubtype(const SubProperty &property) override; bool IsEnable() override; diff --git a/frameworks/native/inputmethod_ability/include/input_method_core_stub.h b/frameworks/native/inputmethod_ability/include/input_method_core_stub.h index 42b10bdf07070a1fe99a13720140ef3f1d6d99d9..a5c3429181e281d667885e19c17f844684296f9d 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_core_stub.h +++ b/frameworks/native/inputmethod_ability/include/input_method_core_stub.h @@ -43,8 +43,8 @@ public: int32_t StopInput(const sptr &channel) override; int32_t ShowKeyboard() override; int32_t HideKeyboard() override; - int32_t InitInputControlChannel(sptr &inputControlChannel, const std::string &imeId) override; - void StopInputService(std::string imeId) override; + int32_t InitInputControlChannel(const sptr &inputControlChannel) override; + void StopInputService() override; int32_t SetSubtype(const SubProperty &property) override; bool IsEnable() override; void SetMessageHandler(MessageHandler *msgHandler); diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp index 48b5e98797ab8854902de6cc9e11e80c02509a8f..bc3fa96c82cd959aca57cf6f23cbc445c7b35bfe 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp @@ -201,10 +201,8 @@ void InputMethodAbility::WorkThread() break; } case MSG_ID_STOP_INPUT_SERVICE: { - MessageParcel *data = msg->msgContent_; - std::string imeId = Str16ToStr8(data->ReadString16()); if (imeListener_ != nullptr) { - imeListener_->OnInputStop(imeId); + imeListener_->OnInputStop(); } isBound_.store(false); break; @@ -232,7 +230,6 @@ void InputMethodAbility::OnInitInputControlChannel(Message *msg) IMSA_HILOGI("InputMethodAbility::OnInitInputControlChannel channelObject is nullptr"); return; } - currentIme_ = data->ReadString(); SetInputControlChannel(channelObject); } @@ -715,7 +712,7 @@ void InputMethodAbility::OnRemoteSaDied(const wptr &object) abilityManager_ = nullptr; } if (imeListener_ != nullptr) { - imeListener_->OnInputStop(currentIme_); + imeListener_->OnInputStop(); } } @@ -804,5 +801,16 @@ bool InputMethodAbility::IsEnable() } return imeListener_->IsEnable(); } + +int32_t InputMethodAbility::ExitCurrentInputType() +{ + IMSA_HILOGD("InputMethodAbility, in"); + auto proxy = GetImsaProxy(); + if (proxy == nullptr) { + IMSA_HILOGE("failed to get imsa proxy"); + return false; + } + return proxy->ExitCurrentInputType(); +} } // namespace MiscServices } // namespace OHOS diff --git a/frameworks/native/inputmethod_ability/src/input_method_core_proxy.cpp b/frameworks/native/inputmethod_ability/src/input_method_core_proxy.cpp index 129e17f6733721fb826b7e555bdff689e88aa2b8..f3ac2ea0d1c8a4f7c6046b9abd05df88329bbad1 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_core_proxy.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_core_proxy.cpp @@ -31,11 +31,10 @@ InputMethodCoreProxy::InputMethodCoreProxy(const OHOS::sptr InputMethodCoreProxy::~InputMethodCoreProxy() = default; -int32_t InputMethodCoreProxy::InitInputControlChannel( - sptr &inputControlChannel, const std::string &imeId) +int32_t InputMethodCoreProxy::InitInputControlChannel(const sptr &inputControlChannel) { - return SendRequest(INIT_INPUT_CONTROL_CHANNEL, [&inputControlChannel, &imeId](MessageParcel &data) { - return ITypesUtil::Marshal(data, inputControlChannel->AsObject(), imeId); + return SendRequest(INIT_INPUT_CONTROL_CHANNEL, [&inputControlChannel](MessageParcel &data) { + return ITypesUtil::Marshal(data, inputControlChannel->AsObject()); }); } @@ -47,11 +46,9 @@ int32_t InputMethodCoreProxy::StartInput(const sptr &inputDat }); } -void InputMethodCoreProxy::StopInputService(std::string imeId) +void InputMethodCoreProxy::StopInputService() { - SendRequest(STOP_INPUT_SERVICE, [&imeId](MessageParcel &data) { - return ITypesUtil::Marshal(data, Str8ToStr16(imeId)); - }); + SendRequest(STOP_INPUT_SERVICE); } int32_t InputMethodCoreProxy::ShowKeyboard() diff --git a/frameworks/native/inputmethod_ability/src/input_method_core_stub.cpp b/frameworks/native/inputmethod_ability/src/input_method_core_stub.cpp index ce604f17c33e7df8d5f3e621bda83b4e5a487c64..f053e428805aa275bb2f2fc9d23b160ec5f6be82 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_core_stub.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_core_stub.cpp @@ -60,7 +60,7 @@ int32_t InputMethodCoreStub::OnRemoteRequest( break; } case STOP_INPUT_SERVICE: { - StopInputService(Str16ToStr8(data.ReadString16())); + StopInputService(); reply.WriteInt32(ErrorCode::NO_ERROR); break; } @@ -84,20 +84,17 @@ int32_t InputMethodCoreStub::OnRemoteRequest( return NO_ERROR; } -int32_t InputMethodCoreStub::InitInputControlChannel( - sptr &inputControlChannel, const std::string &imeId) +int32_t InputMethodCoreStub::InitInputControlChannel(const sptr &inputControlChannel) { IMSA_HILOGD("InputMethodCoreStub::InitInputControlChannel"); if (msgHandler_ == nullptr) { return ErrorCode::ERROR_NULL_POINTER; } - MessageParcel *data = new MessageParcel(); if (inputControlChannel != nullptr) { IMSA_HILOGD("InputMethodCoreStub, inputControlChannel is not nullptr"); data->WriteRemoteObject(inputControlChannel->AsObject()); } - data->WriteString(imeId); Message *msg = new Message(MessageID::MSG_ID_INIT_INPUT_CONTROL_CHANNEL, data); msgHandler_->SendMessage(msg); return ErrorCode::NO_ERROR; @@ -115,15 +112,13 @@ int32_t InputMethodCoreStub::HideKeyboard() return InputMethodAbility::GetInstance()->HideKeyboard(); } -void InputMethodCoreStub::StopInputService(std::string imeId) +void InputMethodCoreStub::StopInputService() { IMSA_HILOGD("InputMethodCoreStub::StopInputService"); - if (!msgHandler_) { + if (msgHandler_ == nullptr) { return; } MessageParcel *data = new MessageParcel(); - data->WriteString16(Str8ToStr16(imeId)); - Message *msg = new Message(MessageID::MSG_ID_STOP_INPUT_SERVICE, data); msgHandler_->SendMessage(msg); } @@ -147,7 +142,7 @@ void InputMethodCoreStub::InitInputControlChannelOnRemote(MessageParcel &data, M reply.WriteInt32(ErrorCode::ERROR_NULL_POINTER); return; } - auto ret = InitInputControlChannel(inputControlChannel, data.ReadString()); + auto ret = InitInputControlChannel(inputControlChannel); reply.WriteInt32(ret); } diff --git a/frameworks/native/inputmethod_controller/include/input_method_system_ability_proxy.h b/frameworks/native/inputmethod_controller/include/input_method_system_ability_proxy.h index 108406dde88f7997d9bb0113b169d0d76e44e1fa..ea5e671b7395335de30aba9d93981af5d942067d 100644 --- a/frameworks/native/inputmethod_controller/include/input_method_system_ability_proxy.h +++ b/frameworks/native/inputmethod_controller/include/input_method_system_ability_proxy.h @@ -63,6 +63,9 @@ public: int32_t PanelStatusChange(const InputWindowStatus &status, const InputWindowInfo &windowInfo) override; int32_t UpdateListenEventFlag(InputClientInfo &clientInfo, EventType eventType) override; bool IsCurrentIme() override; + bool IsInputTypeSupported(InputType type) override; + int32_t StartInputType(InputType type) override; + int32_t ExitCurrentInputType() override; // Deprecated because of no permission check, kept for compatibility int32_t HideCurrentInputDeprecated() override; diff --git a/frameworks/native/inputmethod_controller/include/input_method_utils.h b/frameworks/native/inputmethod_controller/include/input_method_utils.h index 3f158817e750835ca5f9d9f8c7844b78a8ea97f0..d1fb3e58059fe8dcadc8966ae3f7a6ae80e5ba5e 100644 --- a/frameworks/native/inputmethod_controller/include/input_method_utils.h +++ b/frameworks/native/inputmethod_controller/include/input_method_utils.h @@ -139,6 +139,11 @@ struct TextConfig { SelectionRange range = {}; uint32_t windowId = INVALID_WINDOW_ID; }; + +enum class InputType { + NONE = -1, + CAMERA_INPUT = 0, +}; } // namespace MiscServices } // namespace OHOS #endif // FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_INPUT_METHOD_UTILS_H diff --git a/frameworks/native/inputmethod_controller/include/itypes_util.h b/frameworks/native/inputmethod_controller/include/itypes_util.h index 70e3154d251778b9b1b9d5a96d60309dcdc7e05a..e47bb922ed4a85755e5e655b17e03c6e9a786dd7 100644 --- a/frameworks/native/inputmethod_controller/include/itypes_util.h +++ b/frameworks/native/inputmethod_controller/include/itypes_util.h @@ -81,6 +81,9 @@ public: static bool Marshalling(EventType input, MessageParcel &data); static bool Unmarshalling(EventType &output, MessageParcel &data); + static bool Marshalling(InputType input, MessageParcel &data); + static bool Unmarshalling(InputType &output, MessageParcel &data); + template static bool Marshalling(const std::vector &val, MessageParcel &parcel); template diff --git a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp index 7ff8c53f1ec05009b67c62d0bc2d85f2de617205..033cb3364c7e1998fd0ed2a367c5ab1b339009e6 100644 --- a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp +++ b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp @@ -1015,5 +1015,27 @@ int32_t InputMethodController::SendFunctionKey(int32_t functionKey) listener->SendFunctionKey(funcKey); return ErrorCode::NO_ERROR; } + +bool InputMethodController::IsInputTypeSupported(InputType type) +{ + IMSA_HILOGI("InputMethodController, type: %{public}d", static_cast(type)); + auto proxy = GetSystemAbilityProxy(); + if (proxy == nullptr) { + IMSA_HILOGE("proxy is nullptr"); + return ErrorCode::ERROR_NULL_POINTER; + } + return proxy->IsInputTypeSupported(type); +} + +int32_t InputMethodController::StartInputType(InputType type) +{ + IMSA_HILOGI("InputMethodController, type: %{public}d", static_cast(type)); + auto proxy = GetSystemAbilityProxy(); + if (proxy == nullptr) { + IMSA_HILOGE("proxy is nullptr"); + return ErrorCode::ERROR_NULL_POINTER; + } + return proxy->StartInputType(type); +} } // namespace MiscServices } // namespace OHOS diff --git a/frameworks/native/inputmethod_controller/src/input_method_system_ability_proxy.cpp b/frameworks/native/inputmethod_controller/src/input_method_system_ability_proxy.cpp index 7b72199829f7912192149270bbc1dd4be1afcaef..84585f103e16fc2d6d8161397123a139a386cef8 100644 --- a/frameworks/native/inputmethod_controller/src/input_method_system_ability_proxy.cpp +++ b/frameworks/native/inputmethod_controller/src/input_method_system_ability_proxy.cpp @@ -204,6 +204,27 @@ bool InputMethodSystemAbilityProxy::IsCurrentIme() return isCurrentIme; } +bool InputMethodSystemAbilityProxy::IsInputTypeSupported(InputType type) +{ + bool isSupported = false; + SendRequest( + static_cast(InputMethodInterfaceCode::IS_INPUT_TYPE_SUPPORTED), + [type](MessageParcel &data) { return ITypesUtil::Marshal(data, type); }, + [&isSupported](MessageParcel &reply) { return ITypesUtil::Unmarshal(reply, isSupported); }); + return isSupported; +} + +int32_t InputMethodSystemAbilityProxy::StartInputType(InputType type) +{ + return SendRequest(static_cast(InputMethodInterfaceCode::START_INPUT_TYPE), + [&type](MessageParcel &data) { return ITypesUtil::Marshal(data, type); }); +} + +int32_t InputMethodSystemAbilityProxy::ExitCurrentInputType() +{ + return SendRequest(static_cast(InputMethodInterfaceCode::EXIT_CURRENT_INPUT_TYPE)); +} + int32_t InputMethodSystemAbilityProxy::SendRequest(int code, ParcelHandler input, ParcelHandler output) { IMSA_HILOGI("InputMethodSystemAbilityProxy run in, code = %{public}d", code); diff --git a/frameworks/native/inputmethod_controller/src/itypes_util.cpp b/frameworks/native/inputmethod_controller/src/itypes_util.cpp index 6e35f32928c0c6a9bed8be0c46da417a9e25a08b..b11141834b48163adfe4cc2358f188fff3bca8b8 100644 --- a/frameworks/native/inputmethod_controller/src/itypes_util.cpp +++ b/frameworks/native/inputmethod_controller/src/itypes_util.cpp @@ -279,5 +279,20 @@ bool ITypesUtil::Unmarshalling(EventType &output, MessageParcel &data) output = static_cast(ret); return true; } + +bool ITypesUtil::Marshalling(InputType input, MessageParcel &data) +{ + return data.WriteInt32(static_cast(input)); +} + +bool ITypesUtil::Unmarshalling(InputType &output, MessageParcel &data) +{ + int32_t ret = 0; + if (!data.ReadInt32(ret)) { + return false; + } + output = static_cast(ret); + return true; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/interfaces/inner_api/inputmethod_ability/include/input_method_engine_listener.h b/interfaces/inner_api/inputmethod_ability/include/input_method_engine_listener.h index c7f5c6738bf16fc1b7ef0014208f5b30da1d1574..02cb768cdf6200d2ddc2e9b3be8824b7c5559d5f 100644 --- a/interfaces/inner_api/inputmethod_ability/include/input_method_engine_listener.h +++ b/interfaces/inner_api/inputmethod_ability/include/input_method_engine_listener.h @@ -25,7 +25,7 @@ public: virtual ~InputMethodEngineListener() = default; virtual void OnKeyboardStatus(bool isShow) = 0; virtual void OnInputStart() = 0; - virtual void OnInputStop(const std::string &imeId) = 0; + virtual void OnInputStop() = 0; virtual void OnSetCallingWindow(uint32_t windowId) = 0; virtual void OnSetSubtype(const SubProperty &property) = 0; virtual void OnInputFinish() diff --git a/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h b/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h index b5e77a86a47211f977c5a12326af4a9ff0548d5c..28df11826298657f68ca52196f064c1d61d52ec5 100644 --- a/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h +++ b/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h @@ -598,6 +598,28 @@ public: IMF_API int32_t OnPanelStatusChange( const InputWindowStatus &status, const std::vector &windowInfo); + /** + * @brief Query whether an input type is supported. + * + * This function is used to query whether an input type is supported. + * + * @param type Indicates the input type being queried. + * @return Returns true for supported, false for not supported. + * @since 10 + */ + bool IsInputTypeSupported(InputType type); + + /** + * @brief Start the input method which provides the specific input type. + * + * This function is used to start the input method which provides the specific input type. + * + * @param type Indicates the input type being specified. + * @return Returns 0 for success, others for failure. + * @since 10 + */ + int32_t StartInputType(InputType type); + private: InputMethodController(); ~InputMethodController(); diff --git a/services/BUILD.gn b/services/BUILD.gn index 6bf71e82e24b0272cc0439d9e9e75d122e77c5be..944263cb8409e6e1e9b4b6c18c89952773471899 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -51,6 +51,7 @@ ohos_shared_library("inputmethod_service") { "src/input_method_info.cpp", "src/input_method_system_ability.cpp", "src/input_method_system_ability_stub.cpp", + "src/input_type_manager.cpp", "src/message.cpp", "src/message_handler.cpp", "src/peruser_session.cpp", @@ -77,6 +78,7 @@ ohos_shared_library("inputmethod_service") { "c_utils:utils", "common_event_service:cesfwk_core", "common_event_service:cesfwk_innerkits", + "config_policy:configpolicy_util", "data_share:datashare_common", "data_share:datashare_consumer", "eventhandler:libeventhandler", diff --git a/services/identity_checker/include/identity_checker.h b/services/identity_checker/include/identity_checker.h index 26d03e7e7be24305cd929fd8091906b65c21fd28..b82cd006a693ac088b36687eaa28cbfff330cb9a 100644 --- a/services/identity_checker/include/identity_checker.h +++ b/services/identity_checker/include/identity_checker.h @@ -27,7 +27,7 @@ public: virtual ~IdentityChecker() = default; virtual bool IsFocused(int64_t callingPid, uint32_t callingTokenId, int64_t focusedPid = INVALID_PID) = 0; virtual bool IsSystemApp(uint64_t fullTokenId) = 0; - virtual bool IsCurrentIme(uint32_t tokenId, const std::string ¤tBundleName) = 0; + virtual bool IsBundleNameValid(uint32_t tokenId, const std::string &validBundleName) = 0; virtual bool HasPermission(uint32_t tokenId, const std::string &permission) = 0; virtual bool IsBroker(Security::AccessToken::AccessTokenID tokenId) = 0; virtual bool IsNativeSa(Security::AccessToken::AccessTokenID tokenId) = 0; diff --git a/services/identity_checker/include/identity_checker_impl.h b/services/identity_checker/include/identity_checker_impl.h index e88f9c414f53660d8535744440ffa0f341e3a213..a4f6f42157206ad498d5f6d25a04b0139f5f68a5 100644 --- a/services/identity_checker/include/identity_checker_impl.h +++ b/services/identity_checker/include/identity_checker_impl.h @@ -24,7 +24,7 @@ class IdentityCheckerImpl : public IdentityChecker { public: bool IsFocused(int64_t callingPid, uint32_t callingTokenId, int64_t focusedPid = INVALID_PID) override; bool IsSystemApp(uint64_t fullTokenId) override; - bool IsCurrentIme(uint32_t tokenId, const std::string ¤tBundleName) override; + bool IsBundleNameValid(uint32_t tokenId, const std::string &validBundleName) override; bool HasPermission(uint32_t tokenId, const std::string &permission) override; bool IsBroker(Security::AccessToken::AccessTokenID tokenId) override; bool IsNativeSa(Security::AccessToken::AccessTokenID tokenId) override; diff --git a/services/identity_checker/src/identity_checker_impl.cpp b/services/identity_checker/src/identity_checker_impl.cpp index d1371ad8b6d566ffa28525aa58963f581d6b172d..3da0b679f8a2fc99cf70b9a589f00237a12b74e1 100644 --- a/services/identity_checker/src/identity_checker_impl.cpp +++ b/services/identity_checker/src/identity_checker_impl.cpp @@ -50,18 +50,18 @@ bool IdentityCheckerImpl::IsSystemApp(uint64_t fullTokenId) return TokenIdKit::IsSystemAppByFullTokenID(fullTokenId); } -bool IdentityCheckerImpl::IsCurrentIme(uint32_t tokenId, const std::string ¤tBundleName) +bool IdentityCheckerImpl::IsBundleNameValid(uint32_t tokenId, const std::string &validBundleName) { std::string bundleName = GetBundleNameByToken(tokenId); if (bundleName.empty()) { return false; } - if (bundleName != currentBundleName) { - IMSA_HILOGE( - "not current ime, caller: %{public}s, current: %{public}s", bundleName.c_str(), currentBundleName.c_str()); + if (bundleName != validBundleName) { + IMSA_HILOGE("bundleName invalid, caller: %{public}s, current: %{public}s", bundleName.c_str(), + validBundleName.c_str()); return false; } - IMSA_HILOGD("checked ime successfully"); + IMSA_HILOGD("checked successfully"); return true; } diff --git a/services/include/global.h b/services/include/global.h index 94c2686fb56070cf96a2c3e72f21a5624e7fd12c..d66db3fca8c0b2870aac819258c63d1050923896 100644 --- a/services/include/global.h +++ b/services/include/global.h @@ -101,6 +101,8 @@ enum { ERROR_IME_START_INPUT_FAILED = 27, ERROR_KEYWORD_NOT_FOUND = 28, ERROR_ENABLE_IME = 29, + ERROR_PARSE_CONFIG_FILE = 30, + ERROR_NOT_DEFAULT_IME = 31, }; }; // namespace ErrorCode diff --git a/services/include/i_input_method_system_ability.h b/services/include/i_input_method_system_ability.h index e841f1007cd79c688d4227a83dfc94cf82fb9d9e..91f99514de00507246cf2285fc0997ea7320db29 100644 --- a/services/include/i_input_method_system_ability.h +++ b/services/include/i_input_method_system_ability.h @@ -61,6 +61,9 @@ public: virtual int32_t PanelStatusChange(const InputWindowStatus &status, const InputWindowInfo &windowInfo) = 0; virtual int32_t UpdateListenEventFlag(InputClientInfo &clientInfo, EventType eventType) = 0; virtual bool IsCurrentIme() = 0; + virtual bool IsInputTypeSupported(InputType type) = 0; + virtual int32_t StartInputType(InputType type) = 0; + virtual int32_t ExitCurrentInputType() = 0; // Deprecated because of no permission check, and keep for compatibility virtual int32_t HideCurrentInputDeprecated() = 0; diff --git a/services/include/ime_info_inquirer.h b/services/include/ime_info_inquirer.h index b5632f5c82b9c13effb33ccbbca4461b9ba69e22..0c382d2f134304ffd2de5bfdfe104746e0d9a7ff 100644 --- a/services/include/ime_info_inquirer.h +++ b/services/include/ime_info_inquirer.h @@ -52,30 +52,28 @@ class ImeInfoInquirer { public: using CompareHandler = std::function; static ImeInfoInquirer &GetInstance(); - std::shared_ptr GetImeSubProp(const std::vector &subProps, const Condition &condition); - std::string GetInputMethodParam(const int32_t userId); - std::shared_ptr GetCurrentInputMethod(const int32_t userId); - std::shared_ptr GetCurrentInputMethodSubtype(const int32_t userId); - std::string GetStartedIme(const int32_t userId); - std::shared_ptr GetDefaultImeInfo(const int32_t userId); - std::shared_ptr GetImeInfo( - const int32_t userId, const std::string &bundleName, const std::string &subName); - void SetCurrentImeInfo(std::shared_ptr info); - void SetCurrentImeInfo(const int32_t userId); + std::string GetDumpInfo(int32_t userId); + std::string GetImeToBeStarted(int32_t userId); + std::shared_ptr GetImeByBundleName(int32_t userId, const std::string &bundleName); + std::shared_ptr GetCurrentInputMethod(int32_t userId); + std::shared_ptr GetCurrentSubtype(int32_t userId); + std::shared_ptr GetImeInfo(int32_t userId, const std::string &bundleName, const std::string &subName); + std::shared_ptr GetDefaultImeInfo(int32_t userId); std::shared_ptr GetCurrentImeInfo(); - void UpdateCurrentImeInfo(const int32_t userId); - void ResetCurrentImeInfo(); - int32_t ListInputMethod( - const int32_t userId, const InputMethodStatus status, std::vector &props, bool enableOn); - int32_t ListInputMethodSubtype( - const int32_t userId, const std::string &bundleName, std::vector &subProps); - int32_t ListCurrentInputMethodSubtype(const int32_t userId, std::vector &subProps); - int32_t GetNextSwitchInfo(SwitchInfo &switchInfo, const int32_t userId, bool enableOn); + void SetCurrentImeInfo(std::shared_ptr info); + void RefreshCurrentImeInfo(int32_t userId); + std::shared_ptr FindTargetSubtypeByCondition( + const std::vector &subProps, const Condition &condition); + int32_t ListInputMethod(int32_t userId, InputMethodStatus status, std::vector &props, bool enableOn); + int32_t ListInputMethodSubtype(int32_t userId, const std::string &bundleName, std::vector &subProps); + int32_t ListCurrentInputMethodSubtype(int32_t userId, std::vector &subProps); + int32_t GetNextSwitchInfo(SwitchInfo &switchInfo, int32_t userId, bool enableOn); private: ImeInfoInquirer() = default; ~ImeInfoInquirer() = default; OHOS::sptr GetBundleMgr(); + void InitCache(int32_t userId); SubProperty GetExtends(const std::vector &metaData); std::string GetDefaultIme(); std::string GetStringById( diff --git a/services/include/input_method_system_ability.h b/services/include/input_method_system_ability.h index c985af7f779e9edbdef11d08e2303a7abf50c868..9569df91ea93e6f2c7ed7f18d71286778a503386 100644 --- a/services/include/input_method_system_ability.h +++ b/services/include/input_method_system_ability.h @@ -71,6 +71,9 @@ public: int32_t PanelStatusChange(const InputWindowStatus &status, const InputWindowInfo &windowInfo) override; int32_t UpdateListenEventFlag(InputClientInfo &clientInfo, EventType eventType) override; bool IsCurrentIme() override; + bool IsInputTypeSupported(InputType type) override; + int32_t StartInputType(InputType type) override; + int32_t ExitCurrentInputType() override; // Deprecated because of no permission check, kept for compatibility int32_t HideCurrentInputDeprecated() override; @@ -92,17 +95,20 @@ private: std::shared_ptr identityChecker_ = nullptr; void WorkThread(); bool StartInputService(const std::string &imeId); - void StopInputService(const std::string &imeId); int32_t OnUserStarted(const Message *msg); int32_t OnUserRemoved(const Message *msg); int32_t OnPackageRemoved(const Message *msg); int32_t OnDisplayOptionalInputMethod(); void StartUserIdListener(); bool IsNeedSwitch(const std::string &bundleName, const std::string &subName); + bool IsSwitchPermitted(const SwitchInfo &switchInfo); + bool IsStartInputTypePermitted(); int32_t OnSwitchInputMethod(const SwitchInfo &switchInfo, bool isCheckPermission); + int32_t OnStartInputType(const SwitchInfo &switchInfo); int32_t Switch(const std::string &bundleName, const std::shared_ptr &info); int32_t SwitchExtension(const std::shared_ptr &info); int32_t SwitchSubType(const std::shared_ptr &info); + int32_t SwitchInputType(const SwitchInfo &switchInfo); ServiceRunningState state_; void InitServiceHandler(); static std::shared_ptr serviceHandler_; diff --git a/services/include/input_method_system_ability_stub.h b/services/include/input_method_system_ability_stub.h index c6b9cc691d185f398c5dfabad731a0d1bbb4607d..00561aaf458ce4ed59d30a11167c11b90d27f604 100644 --- a/services/include/input_method_system_ability_stub.h +++ b/services/include/input_method_system_ability_stub.h @@ -71,6 +71,12 @@ private: int32_t IsCurrentImeOnRemote(MessageParcel &data, MessageParcel &reply); + int32_t IsInputTypeSupportedOnRemote(MessageParcel &data, MessageParcel &reply); + + int32_t StartInputTypeOnRemote(MessageParcel &data, MessageParcel &reply); + + int32_t ExitCurrentInputTypeOnRemote(MessageParcel &data, MessageParcel &reply); + // Deprecated because of no permission check, kept for compatibility int32_t DisplayInputOnRemoteDeprecated(MessageParcel &data, MessageParcel &reply); @@ -126,6 +132,12 @@ private: &InputMethodSystemAbilityStub::IsCurrentImeOnRemote, [static_cast(InputMethodInterfaceCode::UNREGISTERED_PROXY_IME)] = &InputMethodSystemAbilityStub::UnRegisteredProxyImeOnRemote, + [static_cast(InputMethodInterfaceCode::IS_INPUT_TYPE_SUPPORTED)] = + &InputMethodSystemAbilityStub::IsInputTypeSupportedOnRemote, + [static_cast(InputMethodInterfaceCode::START_INPUT_TYPE)] = + &InputMethodSystemAbilityStub::StartInputTypeOnRemote, + [static_cast(InputMethodInterfaceCode::EXIT_CURRENT_INPUT_TYPE)] = + &InputMethodSystemAbilityStub::ExitCurrentInputTypeOnRemote, }; }; } // namespace OHOS::MiscServices diff --git a/services/include/input_type_manager.h b/services/include/input_type_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..5cabf2c75e9d6f4037065163f9c1cb678880e66c --- /dev/null +++ b/services/include/input_type_manager.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INPUTMETHOD_IMF_INPUT_TYPE_MANAGER_H +#define INPUTMETHOD_IMF_INPUT_TYPE_MANAGER_H + +#include +#include +#include +#include + +#include "block_data.h" +#include "input_method_utils.h" +#include "nlohmann/json.hpp" + +namespace OHOS { +namespace MiscServices { +struct ImeIdentification { + std::string bundleName; + std::string subName; + bool operator==(const ImeIdentification &ime) const + { + return (bundleName == ime.bundleName && subName == ime.subName); + } + bool operator<(const ImeIdentification &ime) const + { + return bundleName == ime.bundleName ? (subName < ime.subName) : (bundleName < ime.bundleName); + } +}; + +struct InputTypeCfg { + InputType type{}; + ImeIdentification ime; +}; + +class InputTypeManager { +public: + static InputTypeManager &GetInstance(); + bool IsSupported(InputType type); + bool IsInputType(const ImeIdentification &ime); + bool IsStarted(); + void Set(bool isStarted, const ImeIdentification ¤tIme = {}); + ImeIdentification GetCurrentIme(); + int32_t GetImeByInputType(InputType type, ImeIdentification &ime); + +private: + bool Init(); + bool ParseFromCustomSystem(); + bool GetCfgsFromFile(const std::string &cfgPath); + std::string ReadFile(const std::string &path); + std::mutex stateLock_; + bool isStarted_{ false }; + ImeIdentification currentTypeIme_; + + std::mutex typesLock_; + std::map inputTypes_; + std::mutex listLock_; + std::set inputTypeImeList_; + + std::atomic_bool isTypeCfgReady_{ false }; + std::atomic_bool isInitInProgress_{ false }; + BlockData isInitSuccess_{ false }; +}; +} // namespace MiscServices +} // namespace OHOS + +#endif //INPUTMETHOD_IMF_INPUT_TYPE_MANAGER_H diff --git a/services/include/inputmethod_service_ipc_interface_code.h b/services/include/inputmethod_service_ipc_interface_code.h index 863ed7031bb3010e15d93669c6b0311239ea1611..4afcb98cbbeda5cf76ce3b4933c0f4e036e35b78 100644 --- a/services/include/inputmethod_service_ipc_interface_code.h +++ b/services/include/inputmethod_service_ipc_interface_code.h @@ -43,6 +43,9 @@ enum class InputMethodInterfaceCode { UPDATE_LISTEN_EVENT_FLAG, IS_CURRENT_IME, UNREGISTERED_PROXY_IME, + IS_INPUT_TYPE_SUPPORTED, + START_INPUT_TYPE, + EXIT_CURRENT_INPUT_TYPE, IMS_CMD_LAST }; } // namespace MiscServices diff --git a/services/include/peruser_session.h b/services/include/peruser_session.h index 9b467c95947373764d6f47aa784de7af23eb2d78..e365f80dba4bbce1fbb3225ff758300d37049e06 100644 --- a/services/include/peruser_session.h +++ b/services/include/peruser_session.h @@ -74,8 +74,9 @@ public: int32_t OnShowCurrentInput(); int32_t OnShowInput(sptr client); int32_t OnHideInput(sptr client); - void StopInputService(std::string imeId); - int32_t OnSwitchIme(const Property &property, const SubProperty &subProperty, bool isSubtypeSwitch); + void StopInputService(); + void NotifyImeChangeToClients(const Property &property, const SubProperty &subProperty); + int32_t SwitchSubtype(const SubProperty &subProperty); void UpdateCurrentUserId(int32_t userId); void OnFocused(int32_t pid, int32_t uid); void OnUnfocused(int32_t pid, int32_t uid); @@ -86,6 +87,8 @@ public: int32_t OnRegisterProxyIme(const sptr &core, const sptr &agent); int32_t OnUnRegisteredProxyIme(UnRegisteredType type, const sptr &core); bool IsProxyImeEnable(); + bool IsBoundToClient(); + int32_t ExitCurrentInputType(); private: struct ResetManager { diff --git a/services/src/ime_info_inquirer.cpp b/services/src/ime_info_inquirer.cpp index d6b39bb070797bf25b94a28cafec10421fd5379d..d1df6f6f2d0a278c2897655f335609068577cad4 100644 --- a/services/src/ime_info_inquirer.cpp +++ b/services/src/ime_info_inquirer.cpp @@ -24,6 +24,7 @@ #include "if_system_ability_manager.h" #include "ime_cfg_manager.h" #include "input_method_info.h" +#include "input_type_manager.h" #include "iservice_registry.h" #include "parameter.h" #include "string_ex.h" @@ -80,7 +81,7 @@ int32_t ImeInfoInquirer::GetExtInfosByBundleName( } std::shared_ptr ImeInfoInquirer::GetImeInfo( - const int32_t userId, const std::string &bundleName, const std::string &subName) + int32_t userId, const std::string &bundleName, const std::string &subName) { auto info = GetImeInfoFromCache(userId, bundleName, subName); return info == nullptr ? GetImeInfoFromBundleMgr(userId, bundleName, subName) : info; @@ -167,7 +168,7 @@ void ImeInfoInquirer::SetCurrentImeInfo(std::shared_ptr info) currentImeInfo_ = std::move(info); } -void ImeInfoInquirer::SetCurrentImeInfo(const int32_t userId) +void ImeInfoInquirer::InitCache(int32_t userId) { IMSA_HILOGD("userId: %{public}d", userId); auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); @@ -186,7 +187,7 @@ std::shared_ptr ImeInfoInquirer::GetCurrentImeInfo() return currentImeInfo_; } -void ImeInfoInquirer::UpdateCurrentImeInfo(const int32_t userId) +void ImeInfoInquirer::RefreshCurrentImeInfo(int32_t userId) { IMSA_HILOGD("run in"); std::lock_guard lock(currentImeInfoLock_); @@ -204,7 +205,7 @@ void ImeInfoInquirer::UpdateCurrentImeInfo(const int32_t userId) GetStringById(currentImeInfo_->prop.name, currentImeInfo_->moduleName, currentImeInfo_->prop.labelId, userId); } -std::string ImeInfoInquirer::GetInputMethodParam(const int32_t userId) +std::string ImeInfoInquirer::GetDumpInfo(int32_t userId) { auto properties = ListInputMethodInfo(userId); if (properties.empty()) { @@ -257,7 +258,7 @@ std::vector ImeInfoInquirer::ListInputMethodInfo(const int32_t } int32_t ImeInfoInquirer::ListInputMethod( - const int32_t userId, const InputMethodStatus status, std::vector &props, bool enableOn) + int32_t userId, InputMethodStatus status, std::vector &props, bool enableOn) { IMSA_HILOGD("userId: %{public}d, status: %{public}d", userId, status); if (status == InputMethodStatus::ALL) { @@ -349,7 +350,7 @@ int32_t ImeInfoInquirer::ListDisabledInputMethod(const int32_t userId, std::vect return ErrorCode::NO_ERROR; } -int32_t ImeInfoInquirer::GetNextSwitchInfo(SwitchInfo &switchInfo, const int32_t userId, bool enableOn) +int32_t ImeInfoInquirer::GetNextSwitchInfo(SwitchInfo &switchInfo, int32_t userId, bool enableOn) { std::vector props = {}; switchInfo.bundleName = ImeInfoInquirer::GetInstance().GetDefaultImeInfo(userId)->prop.name; @@ -373,7 +374,7 @@ int32_t ImeInfoInquirer::GetNextSwitchInfo(SwitchInfo &switchInfo, const int32_t } int32_t ImeInfoInquirer::ListInputMethodSubtype( - const int32_t userId, const std::string &bundleName, std::vector &subProps) + int32_t userId, const std::string &bundleName, std::vector &subProps) { IMSA_HILOGD("userId: %{public}d, bundleName: %{public}s", userId, bundleName.c_str()); std::vector extInfos; @@ -386,7 +387,7 @@ int32_t ImeInfoInquirer::ListInputMethodSubtype( : ListInputMethodSubtype(userId, extInfos, subProps); } -int32_t ImeInfoInquirer::ListCurrentInputMethodSubtype(const int32_t userId, std::vector &subProps) +int32_t ImeInfoInquirer::ListCurrentInputMethodSubtype(int32_t userId, std::vector &subProps) { auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); IMSA_HILOGD("currentIme: %{public}s", currentImeCfg->imeId.c_str()); @@ -447,7 +448,13 @@ int32_t ImeInfoInquirer::ListInputMethodSubtype( return ErrorCode::ERROR_BAD_PARAMETERS; } IMSA_HILOGD("subProps size: %{public}zu", subProps.size()); - for (auto &subProp : subProps) { + for (auto it = subProps.begin(); it != subProps.end();) { + auto subProp = *it; + // subtype which provides a particular input type should not appear in the subtype list + if (InputTypeManager::GetInstance().IsInputType({ subProp.name, subProp.id })) { + it = subProps.erase(it); + continue; + } subProp.name = extInfo.bundleName; auto pos = subProp.label.find(':'); if (pos != std::string::npos && pos + 1 < subProp.label.size()) { @@ -459,6 +466,8 @@ int32_t ImeInfoInquirer::ListInputMethodSubtype( subProp.iconId = atoi(subProp.icon.substr(pos + 1).c_str()); } ParseLanguage(subProp.locale, subProp.language); + *it = subProp; + ++it; } return ErrorCode::NO_ERROR; } @@ -513,7 +522,24 @@ SubProperty ImeInfoInquirer::GetExtends(const std::vector &metaData) return property; } -std::shared_ptr ImeInfoInquirer::GetCurrentInputMethod(const int32_t userId) +std::shared_ptr ImeInfoInquirer::GetImeByBundleName(int32_t userId, const std::string &bundleName) +{ + IMSA_HILOGD("run in, bundleName: %{public}s", bundleName.c_str()); + std::vector extInfos; + auto ret = ImeInfoInquirer::GetInstance().GetExtInfosByBundleName(userId, bundleName, extInfos); + if (ret != ErrorCode::NO_ERROR || extInfos.empty()) { + IMSA_HILOGE("userId: %{public}d getExtInfosByBundleName %{public}s failed", userId, bundleName.c_str()); + return nullptr; + } + Property prop = { .name = extInfos[0].bundleName, + .id = extInfos[0].name, + .label = extInfos[0].applicationInfo.label, + .labelId = extInfos[0].applicationInfo.labelId, + .iconId = extInfos[0].applicationInfo.iconId }; + return std::make_shared(prop); +} + +std::shared_ptr ImeInfoInquirer::GetCurrentInputMethod(int32_t userId) { auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); IMSA_HILOGD("currentIme: %{public}s", currentImeCfg->imeId.c_str()); @@ -533,7 +559,7 @@ std::shared_ptr ImeInfoInquirer::GetCurrentInputMethod(const int32_t u return std::make_shared(prop); } -std::shared_ptr ImeInfoInquirer::GetCurrentInputMethodSubtype(const int32_t userId) +std::shared_ptr ImeInfoInquirer::GetCurrentSubtype(int32_t userId) { auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); IMSA_HILOGD("currentIme: %{public}s", currentImeCfg->imeId.c_str()); @@ -571,7 +597,7 @@ bool ImeInfoInquirer::IsImeInstalled(const int32_t userId, const std::string &bu return true; } -std::string ImeInfoInquirer::GetStartedIme(const int32_t userId) +std::string ImeInfoInquirer::GetImeToBeStarted(int32_t userId) { auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); IMSA_HILOGD("userId: %{public}d, currentIme: %{public}s", userId, currentImeCfg->imeId.c_str()); @@ -591,11 +617,11 @@ std::string ImeInfoInquirer::GetStartedIme(const int32_t userId) return newUserIme; } // service start, user switch, set the currentImeInfo. - SetCurrentImeInfo(userId); + InitCache(userId); return currentImeCfg->imeId; } -std::shared_ptr ImeInfoInquirer::GetDefaultImeInfo(const int32_t userId) +std::shared_ptr ImeInfoInquirer::GetDefaultImeInfo(int32_t userId) { auto ime = GetDefaultIme(); auto pos = ime.find('/'); @@ -645,7 +671,7 @@ sptr ImeInfoInquirer::GetBundleMgr() return iface_cast(remoteObject); } -std::shared_ptr ImeInfoInquirer::GetImeSubProp( +std::shared_ptr ImeInfoInquirer::FindTargetSubtypeByCondition( const std::vector &subProps, const Condition &condition) { auto it = subProps.end(); diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index 3e62435fb905173bd042b5b3e9386788547a60ba..226b8b3e6d4f84d646cbb9f973cb7a27037bcf9f 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -26,6 +26,7 @@ #include "im_common_event_manager.h" #include "ime_cfg_manager.h" #include "ime_info_inquirer.h" +#include "input_type_manager.h" #include "ipc_skeleton.h" #include "iservice_registry.h" #include "itypes_util.h" @@ -118,7 +119,7 @@ void InputMethodSystemAbility::DumpAllMethod(int fd) } dprintf(fd, "\n - DumpAllMethod get Active Id succeed,count=%zu,", ids.size()); for (auto id : ids) { - const auto ¶ms = ImeInfoInquirer::GetInstance().GetInputMethodParam(id); + const auto ¶ms = ImeInfoInquirer::GetInstance().GetDumpInfo(id); if (params.empty()) { IMSA_HILOGI("userId: %{public}d The IME properties is empty.", id); dprintf(fd, "\n - The IME properties about the Active Id %d is empty.\n", id); @@ -202,12 +203,6 @@ bool InputMethodSystemAbility::StartInputService(const std::string &imeId) return userSession_->StartInputService(imeId, true); } -void InputMethodSystemAbility::StopInputService(const std::string &imeId) -{ - IMSA_HILOGE("InputMethodSystemAbility::StopInputService(%{public}s)", imeId.c_str()); - userSession_->StopInputService(imeId); -} - int32_t InputMethodSystemAbility::PrepareInput(InputClientInfo &clientInfo) { AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); @@ -354,7 +349,7 @@ int32_t InputMethodSystemAbility::ShowCurrentInput() int32_t InputMethodSystemAbility::PanelStatusChange(const InputWindowStatus &status, const InputWindowInfo &windowInfo) { auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); - if (!identityChecker_->IsCurrentIme(IPCSkeleton::GetCallingTokenID(), currentImeCfg->bundleName)) { + if (!identityChecker_->IsBundleNameValid(IPCSkeleton::GetCallingTokenID(), currentImeCfg->bundleName)) { IMSA_HILOGE("not current ime"); return ErrorCode::ERROR_NOT_CURRENT_IME; } @@ -378,8 +373,43 @@ int32_t InputMethodSystemAbility::UpdateListenEventFlag(InputClientInfo &clientI bool InputMethodSystemAbility::IsCurrentIme() { + if (InputTypeManager::GetInstance().IsStarted()) { + auto currentTypeIme = InputTypeManager::GetInstance().GetCurrentIme(); + return identityChecker_->IsBundleNameValid(IPCSkeleton::GetCallingTokenID(), currentTypeIme.bundleName); + } auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); - return identityChecker_->IsCurrentIme(IPCSkeleton::GetCallingTokenID(), currentImeCfg->bundleName); + return identityChecker_->IsBundleNameValid(IPCSkeleton::GetCallingTokenID(), currentImeCfg->bundleName); +} + +bool InputMethodSystemAbility::IsInputTypeSupported(InputType type) +{ + return InputTypeManager::GetInstance().IsSupported(type); +} + +int32_t InputMethodSystemAbility::StartInputType(InputType type) +{ + ImeIdentification ime; + int32_t ret = InputTypeManager::GetInstance().GetImeByInputType(type, ime); + if (ret != ErrorCode::NO_ERROR) { + return ret; + } + SwitchInfo switchInfo = { std::chrono::system_clock::now(), ime.bundleName, ime.subName }; + switchQueue_.Push(switchInfo); + IMSA_HILOGI("start input type: %{public}d", type); + return OnStartInputType(switchInfo); +} + +int32_t InputMethodSystemAbility::ExitCurrentInputType() +{ + auto defaultIme = ImeInfoInquirer::GetInstance().GetDefaultImeInfo(userId_); + if (defaultIme == nullptr) { + IMSA_HILOGE("failed to get default ime"); + return ErrorCode::ERROR_PERSIST_CONFIG; + } + if (!identityChecker_->IsBundleNameValid(IPCSkeleton::GetCallingTokenID(), defaultIme->prop.name)) { + return ErrorCode::ERROR_NOT_DEFAULT_IME; + } + return userSession_->ExitCurrentInputType(); } int32_t InputMethodSystemAbility::DisplayOptionalInputMethod() @@ -389,7 +419,7 @@ int32_t InputMethodSystemAbility::DisplayOptionalInputMethod() return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; } return OnDisplayOptionalInputMethod(); -}; +} int32_t InputMethodSystemAbility::SwitchInputMethod(const std::string &bundleName, const std::string &subName) { @@ -400,7 +430,8 @@ int32_t InputMethodSystemAbility::SwitchInputMethod(const std::string &bundleNam } switchInfo.timestamp = std::chrono::system_clock::now(); switchQueue_.Push(switchInfo); - return OnSwitchInputMethod(switchInfo, true); + return InputTypeManager::GetInstance().IsInputType({ bundleName, subName }) ? OnStartInputType(switchInfo) + : OnSwitchInputMethod(switchInfo, true); } int32_t InputMethodSystemAbility::OnSwitchInputMethod(const SwitchInfo &switchInfo, bool isCheckPermission) @@ -412,19 +443,12 @@ int32_t InputMethodSystemAbility::OnSwitchInputMethod(const SwitchInfo &switchIn switchQueue_.Wait(switchInfo); usleep(SWITCH_BLOCK_TIME); } - IMSA_HILOGD("start switch %{public}s", (switchInfo.bundleName + '/' + switchInfo.subName).c_str()); - // if currentIme is switching subtype, permission verification is not performed. - auto currentBundleName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName; - if (isCheckPermission - && !identityChecker_->HasPermission(IPCSkeleton::GetCallingTokenID(), PERMISSION_CONNECT_IME_ABILITY) - && !(identityChecker_->IsCurrentIme(IPCSkeleton::GetCallingTokenID(), currentBundleName) - && switchInfo.bundleName == currentBundleName && !switchInfo.subName.empty())) { + IMSA_HILOGI("start switch %{public}s|%{public}s", switchInfo.bundleName.c_str(), switchInfo.subName.c_str()); + if (isCheckPermission && !IsSwitchPermitted(switchInfo)) { switchQueue_.Pop(); - InputMethodSysEvent::GetInstance().InputmethodFaultReporter( - ErrorCode::ERROR_STATUS_PERMISSION_DENIED, switchInfo.bundleName, "switch inputmethod failed!"); return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; } - if (!IsNeedSwitch(switchInfo.bundleName, switchInfo.subName)) { + if (!InputTypeManager::GetInstance().IsStarted() && !IsNeedSwitch(switchInfo.bundleName, switchInfo.subName)) { switchQueue_.Pop(); return ErrorCode::NO_ERROR; } @@ -434,6 +458,9 @@ int32_t InputMethodSystemAbility::OnSwitchInputMethod(const SwitchInfo &switchIn return ErrorCode::ERROR_BAD_PARAMETERS; } auto ret = info->isNewIme ? Switch(switchInfo.bundleName, info) : SwitchExtension(info); + if (InputTypeManager::GetInstance().IsStarted()) { + InputTypeManager::GetInstance().Set(false); + } switchQueue_.Pop(); if (ret != ErrorCode::NO_ERROR) { InputMethodSysEvent::GetInstance().InputmethodFaultReporter( @@ -442,11 +469,38 @@ int32_t InputMethodSystemAbility::OnSwitchInputMethod(const SwitchInfo &switchIn return ret; } +int32_t InputMethodSystemAbility::OnStartInputType(const SwitchInfo &switchInfo) +{ + if (!switchQueue_.IsReady(switchInfo)) { + IMSA_HILOGD("start wait"); + switchQueue_.Wait(switchInfo); + usleep(SWITCH_BLOCK_TIME); + } + IMSA_HILOGD("start switch %{public}s|%{public}s", switchInfo.bundleName.c_str(), switchInfo.subName.c_str()); + if (!IsStartInputTypePermitted()) { + IMSA_HILOGE("not permitted to start input type"); + switchQueue_.Pop(); + return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; + } + if (!IsNeedSwitch(switchInfo.bundleName, switchInfo.subName)) { + IMSA_HILOGI("no need to switch"); + switchQueue_.Pop(); + return ErrorCode::NO_ERROR; + } + int32_t ret = SwitchInputType(switchInfo); + switchQueue_.Pop(); + return ret; +} + bool InputMethodSystemAbility::IsNeedSwitch(const std::string &bundleName, const std::string &subName) { + if (InputTypeManager::GetInstance().IsStarted()) { + ImeIdentification target = { bundleName, subName }; + return !(target == InputTypeManager::GetInstance().GetCurrentIme()); + } auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); - IMSA_HILOGI("currentIme: %{public}s, targetIme: %{public}s", - (currentImeCfg->bundleName + "/" + currentImeCfg->subName).c_str(), (bundleName + "/" + subName).c_str()); + IMSA_HILOGI("currentIme: %{public}s/%{public}s, targetIme: %{public}s/%{public}s", + currentImeCfg->bundleName.c_str(), currentImeCfg->subName.c_str(), bundleName.c_str(), subName.c_str()); if ((subName.empty() && bundleName == currentImeCfg->bundleName) || (!subName.empty() && subName == currentImeCfg->subName && currentImeCfg->bundleName == bundleName)) { IMSA_HILOGI("no need to switch"); @@ -464,8 +518,7 @@ int32_t InputMethodSystemAbility::Switch(const std::string &bundleName, const st // Switch the current InputMethodExtension to the new InputMethodExtension int32_t InputMethodSystemAbility::SwitchExtension(const std::shared_ptr &info) { - auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->imeId; - StopInputService(currentIme); + userSession_->StopInputService(); std::string targetIme = info->prop.name + "/" + info->prop.id; ImeCfgManager::GetInstance().ModifyImeCfg({ userId_, targetIme, info->subProp.id }); ImeInfoInquirer::GetInstance().SetCurrentImeInfo(info); @@ -473,20 +526,55 @@ int32_t InputMethodSystemAbility::SwitchExtension(const std::shared_ptr IMSA_HILOGE("start input method failed"); return ErrorCode::ERROR_IME_START_FAILED; } - userSession_->OnSwitchIme(info->prop, info->subProp, false); + userSession_->NotifyImeChangeToClients(info->prop, info->subProp); return ErrorCode::NO_ERROR; } // Inform current InputMethodExtension to switch subtype int32_t InputMethodSystemAbility::SwitchSubType(const std::shared_ptr &info) { - auto ret = userSession_->OnSwitchIme(info->prop, info->subProp, true); + auto ret = userSession_->SwitchSubtype(info->subProp); if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("failed to inform ime to switch subtype, ret: %{public}d", ret); return ret; } auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->imeId; ImeCfgManager::GetInstance().ModifyImeCfg({ userId_, currentIme, info->subProp.id }); ImeInfoInquirer::GetInstance().SetCurrentImeInfo(info); + userSession_->NotifyImeChangeToClients(info->prop, info->subProp); + return ErrorCode::NO_ERROR; +} + +int32_t InputMethodSystemAbility::SwitchInputType(const SwitchInfo &switchInfo) +{ + auto currentImeBundleName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName; + if (switchInfo.bundleName == currentImeBundleName) { + IMSA_HILOGD("only need to switch subtype: %{public}s", switchInfo.subName.c_str()); + auto ret = userSession_->SwitchSubtype({ .name = switchInfo.bundleName, .id = switchInfo.subName }); + if (ret == ErrorCode::NO_ERROR) { + InputTypeManager::GetInstance().Set(true, { switchInfo.bundleName, switchInfo.subName }); + } + return ret; + } + IMSA_HILOGD("need to switch ime: %{public}s|%{public}s", switchInfo.bundleName.c_str(), switchInfo.subName.c_str()); + auto targetImeProperty = ImeInfoInquirer::GetInstance().GetImeByBundleName(userId_, switchInfo.bundleName); + if (targetImeProperty == nullptr) { + return ErrorCode::ERROR_NULL_POINTER; + } + + userSession_->StopInputService(); + std::string targetIme = switchInfo.bundleName + '/' + targetImeProperty->id; + InputTypeManager::GetInstance().Set(true, { switchInfo.bundleName, switchInfo.subName }); + if (!StartInputService(targetIme)) { + IMSA_HILOGE("start input method failed"); + InputTypeManager::GetInstance().Set(false); + return ErrorCode::ERROR_IME_START_FAILED; + } + int32_t ret = userSession_->SwitchSubtype({ .name = switchInfo.bundleName, .id = switchInfo.subName }); + if (ret != ErrorCode::NO_ERROR) { + InputTypeManager::GetInstance().Set(false); + return ret; + } return ErrorCode::NO_ERROR; } @@ -525,7 +613,7 @@ std::shared_ptr InputMethodSystemAbility::GetCurrentInputMethod() std::shared_ptr InputMethodSystemAbility::GetCurrentInputMethodSubtype() { - return ImeInfoInquirer::GetInstance().GetCurrentInputMethodSubtype(userId_); + return ImeInfoInquirer::GetInstance().GetCurrentSubtype(userId_); } int32_t InputMethodSystemAbility::ListInputMethod(InputMethodStatus status, std::vector &props) @@ -603,10 +691,10 @@ int32_t InputMethodSystemAbility::OnUserStarted(const Message *msg) EnableImeDataParser::GetInstance()->OnUserChanged(userId_); } auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(oldUserId)->imeId; - StopInputService(currentIme); + userSession_->StopInputService(); // user switch, reset currentImeInfo_ = nullptr ImeInfoInquirer::GetInstance().SetCurrentImeInfo(nullptr); - auto newIme = ImeInfoInquirer::GetInstance().GetStartedIme(userId_); + auto newIme = ImeInfoInquirer::GetInstance().GetImeToBeStarted(userId_); InputMethodSysEvent::GetInstance().SetUserId(userId_); if (!StartInputService(newIme)) { IMSA_HILOGE("start input method failed"); @@ -721,7 +809,7 @@ int32_t InputMethodSystemAbility::SwitchMode() return ErrorCode::NO_ERROR; } auto condition = info->subProp.mode == "upper" ? Condition::LOWER : Condition::UPPER; - auto target = ImeInfoInquirer::GetInstance().GetImeSubProp(info->subProps, condition); + auto target = ImeInfoInquirer::GetInstance().FindTargetSubtypeByCondition(info->subProps, condition); if (target == nullptr) { IMSA_HILOGE("target is empty"); return ErrorCode::ERROR_BAD_PARAMETERS; @@ -748,7 +836,7 @@ int32_t InputMethodSystemAbility::SwitchLanguage() return ErrorCode::NO_ERROR; } auto condition = info->subProp.language == "chinese" ? Condition::ENGLISH : Condition::CHINESE; - auto target = ImeInfoInquirer::GetInstance().GetImeSubProp(info->subProps, condition); + auto target = ImeInfoInquirer::GetInstance().FindTargetSubtypeByCondition(info->subProps, condition); if (target == nullptr) { IMSA_HILOGE("target is empty"); return ErrorCode::ERROR_BAD_PARAMETERS; @@ -801,13 +889,13 @@ bool InputMethodSystemAbility::InitFocusChangeMonitor() [this](bool isOnFocused, int32_t pid, int32_t uid) { return isOnFocused ? userSession_->OnFocused(pid, uid) : userSession_->OnUnfocused(pid, uid); }, - [this]() { StartInputService(ImeInfoInquirer::GetInstance().GetStartedIme(userId_)); }); + [this]() { StartInputService(ImeInfoInquirer::GetInstance().GetImeToBeStarted(userId_)); }); } void InputMethodSystemAbility::InitSystemLanguageMonitor() { SystemLanguageObserver::GetInstance().Watch( - [this]() { ImeInfoInquirer::GetInstance().UpdateCurrentImeInfo(userId_); }); + [this]() { ImeInfoInquirer::GetInstance().RefreshCurrentImeInfo(userId_); }); } void InputMethodSystemAbility::RegisterEnableImeObserver() @@ -840,5 +928,37 @@ int32_t InputMethodSystemAbility::UnRegisteredProxyIme(UnRegisteredType type, co } return userSession_->OnUnRegisteredProxyIme(type, core); } + +bool InputMethodSystemAbility::IsSwitchPermitted(const SwitchInfo &switchInfo) +{ + auto currentBundleName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName; + // if currentIme is switching subtype, permission verification is not performed. + if (identityChecker_->HasPermission(IPCSkeleton::GetCallingTokenID(), PERMISSION_CONNECT_IME_ABILITY) + || (identityChecker_->IsBundleNameValid(IPCSkeleton::GetCallingTokenID(), currentBundleName) + && switchInfo.bundleName == currentBundleName && !switchInfo.subName.empty())) { + return true; + } + InputMethodSysEvent::GetInstance().InputmethodFaultReporter( + ErrorCode::ERROR_STATUS_PERMISSION_DENIED, switchInfo.bundleName, "switch inputmethod failed!"); + IMSA_HILOGE("not permitted"); + return false; +} + +bool InputMethodSystemAbility::IsStartInputTypePermitted() +{ + auto defaultIme = ImeInfoInquirer::GetInstance().GetDefaultImeInfo(userId_); + if (defaultIme == nullptr) { + IMSA_HILOGE("failed to get default ime"); + return false; + } + if (identityChecker_->IsBundleNameValid(IPCSkeleton::GetCallingTokenID(), defaultIme->prop.name)) { + return true; + } + if (!InputTypeManager::GetInstance().IsStarted()) { + return identityChecker_->IsFocused(IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid()) + && userSession_->IsBoundToClient(); + } + return false; +} } // namespace MiscServices } // namespace OHOS diff --git a/services/src/input_method_system_ability_stub.cpp b/services/src/input_method_system_ability_stub.cpp index bee0a6279ecfb42668f812c5deb92c320f58440d..4228288aae729ff69ae26b3e21e9460a4639be87 100644 --- a/services/src/input_method_system_ability_stub.cpp +++ b/services/src/input_method_system_ability_stub.cpp @@ -268,8 +268,8 @@ int32_t InputMethodSystemAbilityStub::DisplayInputOnRemoteDeprecated(MessageParc int32_t InputMethodSystemAbilityStub::IsCurrentImeOnRemote(MessageParcel &data, MessageParcel &reply) { - bool ret = IsCurrentIme(); - return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; + return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, IsCurrentIme()) ? ErrorCode::NO_ERROR + : ErrorCode::ERROR_EX_PARCELABLE; } int32_t InputMethodSystemAbilityStub::UnRegisteredProxyImeOnRemote(MessageParcel &data, MessageParcel &reply) @@ -283,5 +283,31 @@ int32_t InputMethodSystemAbilityStub::UnRegisteredProxyImeOnRemote(MessageParcel int32_t ret = UnRegisteredProxyIme(static_cast(type), iface_cast(coreObject)); return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; } + +int32_t InputMethodSystemAbilityStub::IsInputTypeSupportedOnRemote(MessageParcel &data, MessageParcel &reply) +{ + InputType type; + if (!ITypesUtil::Unmarshal(data, type)) { + IMSA_HILOGE("unmarshal failed"); + return ErrorCode::ERROR_EX_PARCELABLE; + } + return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, IsInputTypeSupported(type)) ? ErrorCode::NO_ERROR + : ErrorCode::ERROR_EX_PARCELABLE; +} + +int32_t InputMethodSystemAbilityStub::StartInputTypeOnRemote(MessageParcel &data, MessageParcel &reply) +{ + InputType type; + if (!ITypesUtil::Unmarshal(data, type)) { + IMSA_HILOGE("unmarshal failed"); + return ErrorCode::ERROR_EX_PARCELABLE; + } + return ITypesUtil::Marshal(reply, StartInputType(type)) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; +} + +int32_t InputMethodSystemAbilityStub::ExitCurrentInputTypeOnRemote(MessageParcel &data, MessageParcel &reply) +{ + return ITypesUtil::Marshal(reply, ExitCurrentInputType()) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; +} } // namespace MiscServices } // namespace OHOS diff --git a/services/src/input_type_manager.cpp b/services/src/input_type_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..79fdc3f2ea8c044b9f7c30a2d479b843e152732e --- /dev/null +++ b/services/src/input_type_manager.cpp @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "input_type_manager.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "climits" +#include "config_policy_utils.h" +#include "global.h" +#include "ime_cfg_manager.h" + +namespace OHOS { +namespace MiscServices { +namespace { +constexpr const char *IME_INPUT_TYPE_CFG_FILE_PATH = "etc/inputmethod/inputmethod_framework_config.json"; +const std::string SUPPORTED_INPUT_TYPE_LIST = "supportedInputTypeList"; +const std::string INPUT_TYPE = "inputType"; +const std::string BUNDLE_NAME = "bundleName"; +const std::string SUBTYPE_ID = "subtypeId"; +using json = nlohmann::json; +} // namespace + +void from_json(const json &jsonObj, InputTypeCfg &cfg) +{ + if (!jsonObj.contains(INPUT_TYPE) || !jsonObj[INPUT_TYPE].is_number()) { + IMSA_HILOGE("INPUT_TYPE is invalid"); + return; + } + cfg.type = static_cast(jsonObj.at(INPUT_TYPE).get()); + if (!jsonObj.contains(BUNDLE_NAME) || !jsonObj[BUNDLE_NAME].is_string()) { + IMSA_HILOGE("BUNDLE_NAME is invalid"); + return; + } + cfg.ime.bundleName = jsonObj.at(BUNDLE_NAME).get(); + if (!jsonObj.contains(SUBTYPE_ID) || !jsonObj[SUBTYPE_ID].is_string()) { + IMSA_HILOGE("SUBTYPE_ID is invalid"); + return; + } + cfg.ime.subName = jsonObj.at(SUBTYPE_ID).get(); +} + +InputTypeManager &InputTypeManager::GetInstance() +{ + static InputTypeManager instance; + return instance; +} + +bool InputTypeManager::IsSupported(InputType type) +{ + if (!isTypeCfgReady_.load() && !Init()) { + IMSA_HILOGE("init cfg failed"); + return false; + } + std::lock_guard lock(typesLock_); + return inputTypes_.find(type) != inputTypes_.end(); +} + +bool InputTypeManager::IsInputType(const ImeIdentification &ime) +{ + if (!isTypeCfgReady_.load() && !Init()) { + IMSA_HILOGE("init cfg failed"); + return false; + } + std::lock_guard lock(listLock_); + return inputTypeImeList_.find(ime) != inputTypeImeList_.end(); +} + +int32_t InputTypeManager::GetImeByInputType(InputType type, ImeIdentification &ime) +{ + if (!isTypeCfgReady_.load() && !Init()) { + IMSA_HILOGE("init cfg failed"); + return ErrorCode::ERROR_PARSE_CONFIG_FILE; + } + std::lock_guard lock(typesLock_); + auto iter = inputTypes_.find(type); + if (iter == inputTypes_.end()) { + IMSA_HILOGE("type: %{public}d not supported", type); + return ErrorCode::ERROR_BAD_PARAMETERS; + } + ime = iter->second; + IMSA_HILOGI("type: %{public}d find ime: %{public}s|%{public}s", type, ime.bundleName.c_str(), ime.subName.c_str()); + return ErrorCode::NO_ERROR; +} + +void InputTypeManager::Set(bool isStarted, const ImeIdentification ¤tIme) +{ + std::lock_guard lock(stateLock_); + isStarted_ = isStarted; + currentTypeIme_ = currentIme; +} + +bool InputTypeManager::IsStarted() +{ + std::lock_guard lock(stateLock_); + return isStarted_; +} + +ImeIdentification InputTypeManager::GetCurrentIme() +{ + std::lock_guard lock(stateLock_); + return currentTypeIme_; +} + +bool InputTypeManager::Init() +{ + IMSA_HILOGD("start"); + if (isInitInProgress_.load()) { + return isInitSuccess_.GetValue(); + } + isInitInProgress_.store(true); + isInitSuccess_.Clear(false); + bool isSuccess = ParseFromCustomSystem(); + if (isSuccess) { + std::lock_guard lk(typesLock_); + for (const auto &cfg : inputTypes_) { + std::lock_guard lock(listLock_); + inputTypeImeList_.insert(cfg.second); + } + } else { + std::lock_guard lk(typesLock_); + inputTypes_.clear(); + } + isTypeCfgReady_.store(isSuccess); + isInitSuccess_.SetValue(isSuccess); + isInitInProgress_.store(false); + return isSuccess; +} + +bool InputTypeManager::ParseFromCustomSystem() +{ + CfgFiles *cfgFiles = GetCfgFiles(IME_INPUT_TYPE_CFG_FILE_PATH); + if (cfgFiles == nullptr) { + IMSA_HILOGE("cfgFiles is nullptr"); + return false; + } + bool isSuccess = true; + // parse config files, ordered by priority from high to low + for (int32_t i = MAX_CFG_POLICY_DIRS_CNT - 1; i >= 0; i--) { + auto path = cfgFiles->paths[i]; + if (path == nullptr || *path == '\0') { + continue; + } + isSuccess = false; + char realPath[PATH_MAX + 1] = { 0x00 }; + if (strlen(path) == 0 || strlen(path) > PATH_MAX || realpath(path, realPath) == nullptr) { + IMSA_HILOGE("failed to get realpath"); + break; + } + std::string cfgPath(realPath); + if (!GetCfgsFromFile(cfgPath)) { + break; + } + isSuccess = true; + } + FreeCfgFiles(cfgFiles); + IMSA_HILOGI("parse result: %{public}d", isSuccess); + return isSuccess; +} + +bool InputTypeManager::GetCfgsFromFile(const std::string &cfgPath) +{ + IMSA_HILOGD("in"); + std::string jsonStr = ReadFile(cfgPath); + if (jsonStr.empty()) { + IMSA_HILOGE("json config size is invalid"); + return false; + } + auto jsonCfg = json::parse(jsonStr, nullptr, false); + if (jsonCfg.is_discarded()) { + IMSA_HILOGE("jsonStr parse failed"); + return false; + } + if (!jsonCfg.contains(SUPPORTED_INPUT_TYPE_LIST) || !jsonCfg[SUPPORTED_INPUT_TYPE_LIST].is_array()) { + IMSA_HILOGE("%{public}s not find or abnormal", SUPPORTED_INPUT_TYPE_LIST.c_str()); + return false; + } + IMSA_HILOGD("get json: %{public}s", jsonCfg.dump().c_str()); + std::vector configs = jsonCfg.at(SUPPORTED_INPUT_TYPE_LIST).get>(); + std::lock_guard lock(typesLock_); + for (const auto &config : configs) { + inputTypes_.insert({ config.type, config.ime }); + } + return true; +} + +std::string InputTypeManager::ReadFile(const std::string &path) +{ + std::ifstream infile; + std::string sLine; + std::string sAll = ""; + infile.open(path); + if (!infile.is_open()) { + IMSA_HILOGE("path: %s Readfile fail", path.c_str()); + return sAll; + } + + while (getline(infile, sLine)) { + sAll.append(sLine); + } + infile.close(); + return sAll; +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/services/src/peruser_session.cpp b/services/src/peruser_session.cpp index 8b6884e628e1a0afb15b9afd6afbcdf909c1983e..94350e5ce3a5b1ef8ea4ed1aab3cc26e5f0c69eb 100644 --- a/services/src/peruser_session.cpp +++ b/services/src/peruser_session.cpp @@ -26,6 +26,7 @@ #include "input_data_channel_proxy.h" #include "input_method_agent_proxy.h" #include "input_method_core_proxy.h" +#include "input_type_manager.h" #include "ipc_skeleton.h" #include "iservice_registry.h" #include "message_parcel.h" @@ -159,6 +160,7 @@ int32_t PerUserSession::HideKeyboard(const sptr ¤tClient) } bool isShowKeyboard = false; UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, isShowKeyboard } }); + ExitCurrentInputType(); return ErrorCode::NO_ERROR; } @@ -199,6 +201,7 @@ void PerUserSession::OnClientDied(sptr remote) auto clientInfo = GetClientInfo(remote->AsObject()); StopImeInput(clientInfo->bindImeType, clientInfo->channel); SetCurrentClient(nullptr); + ExitCurrentInputType(); } RemoveClientInfo(remote->AsObject(), true); } @@ -220,6 +223,7 @@ void PerUserSession::OnImeDied(const sptr &remote, ImeType typ StopClientInput(client); } if (type == ImeType::IME) { + InputTypeManager::GetInstance().Set(false); RestartIme(); } } @@ -336,6 +340,7 @@ int32_t PerUserSession::RemoveClient(const sptr &client) if (IsCurrentClient(client)) { UnBindClientWithIme(GetClientInfo(client->AsObject())); SetCurrentClient(nullptr); + ExitCurrentInputType(); } RemoveClientInfo(client->AsObject()); return ErrorCode::NO_ERROR; @@ -385,7 +390,7 @@ int32_t PerUserSession::BindClientWithIme(const std::shared_ptr auto data = GetImeData(type); if (data == nullptr && type == ImeType::IME) { IMSA_HILOGI("current ime is empty, try to restart it"); - if (!StartInputService(ImeInfoInquirer::GetInstance().GetStartedIme(userId_), true)) { + if (!StartInputService(ImeInfoInquirer::GetInstance().GetImeToBeStarted(userId_), true)) { IMSA_HILOGE("failed to restart ime"); return ErrorCode::ERROR_IME_START_FAILED; } @@ -397,7 +402,7 @@ int32_t PerUserSession::BindClientWithIme(const std::shared_ptr } auto ret = data->core->StartInput(clientInfo->channel, clientInfo->isShowKeyboard); if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("stop client input failed, ret: %{public}d", ret); + IMSA_HILOGE("start client input failed, ret: %{public}d", ret); return ErrorCode::ERROR_IME_START_INPUT_FAILED; } ret = clientInfo->client->OnInputReady(data->agent); @@ -519,11 +524,10 @@ int32_t PerUserSession::InitInputControlChannel() IMSA_HILOGE("ime: %{public}d is not exist", ImeType::IME); return ErrorCode::ERROR_IME_NOT_STARTED; } - return data->core->InitInputControlChannel( - inputControlChannel, ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->imeId); + return data->core->InitInputControlChannel(inputControlChannel); } -void PerUserSession::StopInputService(std::string imeId) +void PerUserSession::StopInputService() { IMSA_HILOGI("PerUserSession::StopInputService"); auto data = GetImeData(ImeType::IME); @@ -537,7 +541,7 @@ void PerUserSession::StopInputService(std::string imeId) if (clientInfo != nullptr && clientInfo->bindImeType == ImeType::IME) { StopClientInput(client); } - data->core->StopInputService(imeId); + data->core->StopInputService(); } bool PerUserSession::IsRestartIme() @@ -562,7 +566,7 @@ void PerUserSession::RestartIme() return; } IMSA_HILOGI("user %{public}d ime died, restart!", userId_); - StartInputService(ImeInfoInquirer::GetInstance().GetStartedIme(userId_), true); + StartInputService(ImeInfoInquirer::GetInstance().GetImeToBeStarted(userId_), true); } void PerUserSession::SetCurrentClient(sptr client) @@ -578,21 +582,9 @@ sptr PerUserSession::GetCurrentClient() return currentClient_; } -int32_t PerUserSession::OnSwitchIme(const Property &property, const SubProperty &subProperty, bool isSubtypeSwitch) +void PerUserSession::NotifyImeChangeToClients(const Property &property, const SubProperty &subProperty) { - IMSA_HILOGD("PerUserSession::OnSwitchIme"); - if (isSubtypeSwitch) { - auto data = GetImeData(ImeType::IME); - if (data == nullptr) { - IMSA_HILOGE("ime: %{public}d is not exist", ImeType::IME); - return ErrorCode::ERROR_IME_NOT_STARTED; - } - int32_t ret = data->core->SetSubtype(subProperty); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::SetSubtype failed, ret %{public}d", ret); - return ret; - } - } + IMSA_HILOGD("PerUserSession::NotifyImeChangeToClients"); std::lock_guard lock(mtx); for (const auto &client : mapClients_) { auto clientInfo = client.second; @@ -607,7 +599,6 @@ int32_t PerUserSession::OnSwitchIme(const Property &property, const SubProperty continue; } } - return ErrorCode::NO_ERROR; } int32_t PerUserSession::AddImeData(ImeType type, sptr core, sptr agent) @@ -838,5 +829,50 @@ bool PerUserSession::IsBindImeInProxyImeBind(ImeType bindImeType) { return bindImeType == ImeType::PROXY_IME && !IsProxyImeEnable(); } + +int32_t PerUserSession::SwitchSubtype(const SubProperty &subProperty) +{ + auto data = GetImeData(ImeType::IME); + if (data == nullptr) { + IMSA_HILOGE("ime: %{public}d is not exist", ImeType::IME); + return ErrorCode::ERROR_IME_NOT_STARTED; + } + return data->core->SetSubtype(subProperty); +} + +bool PerUserSession::IsBoundToClient() +{ + if (GetCurrentClient() == nullptr) { + IMSA_HILOGE("not in bound state"); + return false; + } + return true; +} + +int32_t PerUserSession::ExitCurrentInputType() +{ + if (!InputTypeManager::GetInstance().IsStarted()) { + IMSA_HILOGD("already exit"); + return ErrorCode::NO_ERROR; + } + auto typeIme = InputTypeManager::GetInstance().GetCurrentIme(); + auto cfgIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); + if (cfgIme->bundleName == typeIme.bundleName) { + IMSA_HILOGI("only need to switch subtype: %{public}s", cfgIme->subName.c_str()); + int32_t ret = SwitchSubtype({ .name = cfgIme->bundleName, .id = cfgIme->subName }); + if (ret == ErrorCode::NO_ERROR) { + InputTypeManager::GetInstance().Set(false); + } + return ret; + } + IMSA_HILOGI("need switch ime to: %{public}s/%{public}s", cfgIme->bundleName.c_str(), cfgIme->subName.c_str()); + StopInputService(); + InputTypeManager::GetInstance().Set(false); + if (!StartInputService(cfgIme->imeId, true)) { + IMSA_HILOGE("failed to start ime"); + return ErrorCode::ERROR_IME_START_FAILED; + } + return ErrorCode::NO_ERROR; +} } // namespace MiscServices } // namespace OHOS diff --git a/test/common/include/input_method_engine_listener_impl.h b/test/common/include/input_method_engine_listener_impl.h index f7a541145b871dc73d285a5d7c1e9008b69f2d28..4ddf7377f1c6e404139cd4857140ee7afc620a6e 100644 --- a/test/common/include/input_method_engine_listener_impl.h +++ b/test/common/include/input_method_engine_listener_impl.h @@ -38,7 +38,7 @@ public: static bool WaitInputFinish(); void OnKeyboardStatus(bool isShow) override; void OnInputStart() override; - void OnInputStop(const std::string &imeId) override; + void OnInputStop() override; void OnSetCallingWindow(uint32_t windowId) override; void OnSetSubtype(const SubProperty &property) override; void OnInputFinish()override; diff --git a/test/common/src/input_method_engine_listener_impl.cpp b/test/common/src/input_method_engine_listener_impl.cpp index 3122e620f81d666e98fc7aa6e77e967b2d3bdd02..3ae3a9c1c04deaf4997ee9c95233c74fa5895fe1 100644 --- a/test/common/src/input_method_engine_listener_impl.cpp +++ b/test/common/src/input_method_engine_listener_impl.cpp @@ -37,9 +37,9 @@ void InputMethodEngineListenerImpl::OnInputStart() isInputStart_ = true; imeListenerCv_.notify_one(); } -void InputMethodEngineListenerImpl::OnInputStop(const std::string &imeId) +void InputMethodEngineListenerImpl::OnInputStop() { - IMSA_HILOGI("InputMethodEngineListenerImpl::OnInputStop %{public}s", imeId.c_str()); + IMSA_HILOGI("InputMethodEngineListenerImpl::OnInputStop"); } void InputMethodEngineListenerImpl::OnSetCallingWindow(uint32_t windowId) { diff --git a/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp b/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp index 290c73e8d1115ec23d497b1b154cce1a13bc9c23..9824c66d23472e50dab367bd5bd1923e0c648bbe 100644 --- a/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp +++ b/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp @@ -103,12 +103,11 @@ bool FuzzPerUserSession(const uint8_t *rawData, size_t size) userSessions->OnShowCurrentInput(); userSessions->OnStartInput(client, false); userSessions->OnStartInput(client, true); - userSessions->OnSwitchIme(property, subProperty, false); - userSessions->OnSwitchIme(property, subProperty, true); + userSessions->NotifyImeChangeToClients(property, subProperty); userSessions->OnHideCurrentInput(); userSessions->OnHideInput(client); userSessions->OnReleaseInput(client); - userSessions->StopInputService(str); + userSessions->StopInputService(); return true; } } // namespace OHOS diff --git a/test/unittest/cpp_test/mock/ime_info_inquirer.cpp b/test/unittest/cpp_test/mock/ime_info_inquirer.cpp index 8b49b588fc31537ef979457e0c33ea4ba6c84d11..a78cc17795d72fb13f925b856ea1cdf54d03393b 100644 --- a/test/unittest/cpp_test/mock/ime_info_inquirer.cpp +++ b/test/unittest/cpp_test/mock/ime_info_inquirer.cpp @@ -25,7 +25,7 @@ ImeInfoInquirer &ImeInfoInquirer::GetInstance() return instance; } -std::shared_ptr ImeInfoInquirer::GetDefaultImeInfo(const int32_t userId) +std::shared_ptr ImeInfoInquirer::GetDefaultImeInfo(int32_t userId) { if (defaultIme_ != nullptr) { return defaultIme_; @@ -34,7 +34,7 @@ std::shared_ptr ImeInfoInquirer::GetDefaultImeInfo(const int32_t userId return defaultIme_; } -std::shared_ptr ImeInfoInquirer::GetCurrentInputMethod(const int32_t userId) +std::shared_ptr ImeInfoInquirer::GetCurrentInputMethod(int32_t userId) { if (currentIme_ != nullptr) { return currentIme_; diff --git a/test/unittest/cpp_test/mock/ime_info_inquirer.h b/test/unittest/cpp_test/mock/ime_info_inquirer.h index 9be7a7f14c2f57a1eba64110774529ac5ee3f984..ef065275dfc105cff02d9a92ce1598fb1e305bdf 100644 --- a/test/unittest/cpp_test/mock/ime_info_inquirer.h +++ b/test/unittest/cpp_test/mock/ime_info_inquirer.h @@ -36,8 +36,8 @@ struct ImeInfo { class ImeInfoInquirer { public: static ImeInfoInquirer &GetInstance(); - std::shared_ptr GetDefaultImeInfo(const int32_t userId); - std::shared_ptr GetCurrentInputMethod(const int32_t userId); + std::shared_ptr GetDefaultImeInfo(int32_t userId); + std::shared_ptr GetCurrentInputMethod(int32_t userId); private: static std::shared_ptr defaultIme_; diff --git a/test/unittest/cpp_test/src/identity_checker_test.cpp b/test/unittest/cpp_test/src/identity_checker_test.cpp index 447a26deea0d4aaa9dd86417a336fcaaf7c1dcb8..323d057c0168087291150f162459f399693ffa9b 100644 --- a/test/unittest/cpp_test/src/identity_checker_test.cpp +++ b/test/unittest/cpp_test/src/identity_checker_test.cpp @@ -42,7 +42,7 @@ public: virtual ~IdentityCheckerMock() = default; MOCK_METHOD3(IsFocused, bool(int64_t callingPid, uint32_t callingTokenId, int64_t focusedPid)); MOCK_METHOD1(IsSystemApp, bool(uint64_t fullTokenID)); - MOCK_METHOD2(IsCurrentIme, bool(uint32_t tokenID, const std::string ¤tBundleName)); + MOCK_METHOD2(IsBundleNameValid, bool(uint32_t tokenID, const std::string &validBundleName)); MOCK_METHOD2(HasPermission, bool(uint32_t tokenID, const std::string &permission)); MOCK_METHOD1(IsBroker, bool(uint32_t tokenID)); MOCK_METHOD1(IsNativeSa, bool(uint32_t tokenID)); @@ -384,7 +384,9 @@ HWTEST_F(IdentityCheckerTest, testSetCoreAndAgent_001, TestSize.Level0) HWTEST_F(IdentityCheckerTest, testSetCoreAndAgent_002, TestSize.Level0) { IMSA_HILOGI("IdentityCheckerTest testSetCoreAndAgent_002 start"); - EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, IsCurrentIme(_, _)).Times(1).WillRepeatedly(Return(true)); + EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, IsBundleNameValid(_, _)) + .Times(1) + .WillRepeatedly(Return(true)); int32_t ret = IdentityCheckerTest::service_->SetCoreAndAgent(nullptr, nullptr); EXPECT_EQ(ret, ErrorCode::ERROR_NULL_POINTER); } @@ -399,7 +401,9 @@ HWTEST_F(IdentityCheckerTest, testSetCoreAndAgent_002, TestSize.Level0) HWTEST_F(IdentityCheckerTest, testSetCoreAndAgent_003, TestSize.Level0) { IMSA_HILOGI("IdentityCheckerTest testSetCoreAndAgent_003 start"); - EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, IsCurrentIme(_, _)).Times(1).WillRepeatedly(Return(false)); + EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, IsBundleNameValid(_, _)) + .Times(1) + .WillRepeatedly(Return(false)); EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, IsNativeSa(_)).Times(1).WillRepeatedly(Return(true)); int32_t ret = IdentityCheckerTest::service_->SetCoreAndAgent(nullptr, nullptr); EXPECT_EQ(ret, ErrorCode::ERROR_NULL_POINTER); @@ -460,7 +464,9 @@ HWTEST_F(IdentityCheckerTest, testIsCurrentIme_001, TestSize.Level0) HWTEST_F(IdentityCheckerTest, testIsCurrentIme_002, TestSize.Level0) { IMSA_HILOGI("IdentityCheckerTest testIsCurrentIme_002 start"); - EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, IsCurrentIme(_, _)).Times(1).WillRepeatedly(Return(true)); + EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, IsBundleNameValid(_, _)) + .Times(1) + .WillRepeatedly(Return(true)); bool ret = IdentityCheckerTest::service_->IsCurrentIme(); EXPECT_TRUE(ret); } @@ -622,7 +628,9 @@ HWTEST_F(IdentityCheckerTest, testPanelStatusChange_001, TestSize.Level0) HWTEST_F(IdentityCheckerTest, testPanelStatusChange_002, TestSize.Level0) { IMSA_HILOGI("IdentityCheckerTest testPanelStatusChange_002 start"); - EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, IsCurrentIme(_, _)).Times(1).WillRepeatedly(Return(true)); + EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, IsBundleNameValid(_, _)) + .Times(1) + .WillRepeatedly(Return(true)); InputWindowStatus status = InputWindowStatus::SHOW; InputWindowInfo windowInfo{}; int32_t ret = IdentityCheckerTest::service_->PanelStatusChange(status, windowInfo); @@ -720,7 +728,7 @@ HWTEST_F(IdentityCheckerTest, testSwitchInputMethod_002, TestSize.Level0) { IMSA_HILOGI("IdentityCheckerTest testSwitchInputMethod_001 start"); EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, HasPermission(_, _)).Times(1).WillRepeatedly(Return(false)); - EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, IsCurrentIme(_, _)).Times(1).WillRepeatedly(Return(true)); + EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, IsBundleNameValid(_, _)).Times(1).WillRepeatedly(Return(true)); int32_t ret = IdentityCheckerTest::service_->SwitchInputMethod(CURRENT_BUNDLENAME, CURRENT_SUBNAME); EXPECT_EQ(ret, ErrorCode::NO_ERROR); } @@ -736,7 +744,7 @@ HWTEST_F(IdentityCheckerTest, testSwitchInputMethod_003, TestSize.Level0) { IMSA_HILOGI("IdentityCheckerTest testSwitchInputMethod_003 start"); EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, HasPermission(_, _)).Times(1).WillRepeatedly(Return(true)); - EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, IsCurrentIme(_, _)).WillRepeatedly(Return(false)); + EXPECT_CALL(*IdentityCheckerTest::identityCheckerMock_, IsBundleNameValid(_, _)).WillRepeatedly(Return(false)); int32_t ret = IdentityCheckerTest::service_->SwitchInputMethod(CURRENT_BUNDLENAME, CURRENT_SUBNAME); EXPECT_EQ(ret, ErrorCode::NO_ERROR); } diff --git a/test/unittest/cpp_test/src/input_method_ability_test.cpp b/test/unittest/cpp_test/src/input_method_ability_test.cpp index d924058c0244c311320cc80866047ebd424e543a..815cea7c56f22441751ca03a9baf2f4370f033ab 100644 --- a/test/unittest/cpp_test/src/input_method_ability_test.cpp +++ b/test/unittest/cpp_test/src/input_method_ability_test.cpp @@ -47,7 +47,6 @@ using WindowMgr = TddUtil::WindowManager; constexpr uint32_t DEALY_TIME = 1; class InputMethodAbilityTest : public testing::Test { public: - static std::string imeIdStopped_; static std::mutex imeListenerCallbackLock_; static std::condition_variable imeListenerCv_; static bool showKeyboard_; @@ -73,9 +72,8 @@ public: IMSA_HILOGI("InputMethodEngineListenerImpl OnInputStart"); } - void OnInputStop(const std::string &imeId) + void OnInputStop() { - imeIdStopped_ = imeId; IMSA_HILOGI("InputMethodEngineListenerImpl OnInputStop"); } @@ -125,7 +123,6 @@ public: } }; -std::string InputMethodAbilityTest::imeIdStopped_; std::mutex InputMethodAbilityTest::imeListenerCallbackLock_; std::condition_variable InputMethodAbilityTest::imeListenerCv_; bool InputMethodAbilityTest::showKeyboard_ = true; diff --git a/test/unittest/cpp_test/src/input_method_private_member_test.cpp b/test/unittest/cpp_test/src/input_method_private_member_test.cpp index 24a8ea32882c8a4b94ce28b59dd21ab62383af52..d36d076d0e21882fc80d9fa8227c57493138132d 100644 --- a/test/unittest/cpp_test/src/input_method_private_member_test.cpp +++ b/test/unittest/cpp_test/src/input_method_private_member_test.cpp @@ -262,8 +262,8 @@ HWTEST_F(InputMethodPrivateMemberTest, PerUserSessionCoreOrAgentNullptr, TestSiz EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_FOUND); ret = userSession->InitInputControlChannel(); EXPECT_EQ(ret, ErrorCode::ERROR_IME_NOT_STARTED); - userSession->StopInputService("test"); - ret = userSession->OnSwitchIme({}, {}, true); + userSession->StopInputService(); + ret = userSession->SwitchSubtype({}); EXPECT_EQ(ret, ErrorCode::ERROR_IME_NOT_STARTED); } @@ -429,7 +429,7 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_SwitchByCombinationKey_004, TestSize.L /** * @tc.name: SA_SwitchByCombinationKey_005 - * @tc.desc: SwitchLanguage()/SwitchMode():GetImeSubProp failed + * @tc.desc: SwitchLanguage()/SwitchMode():FindTargetSubtypeByCondition failed * @tc.type: FUNC * @tc.require: * @tc.author: chenyu @@ -732,19 +732,19 @@ HWTEST_F(InputMethodPrivateMemberTest, III_TestParseSubProp_008, TestSize.Level0 * @tc.require: * @tc.author: chenyu */ -HWTEST_F(InputMethodPrivateMemberTest, III_TestGetCurrentInputMethodSubtype_001, TestSize.Level0) +HWTEST_F(InputMethodPrivateMemberTest, III_TestGetCurrentSubtype_001, TestSize.Level0) { IMSA_HILOGI("InputMethodPrivateMemberTest III_TestGetCurrentInputMethodSubtype_001 TEST START"); // currentIme is empty auto currentUserId = TddUtil::GetCurrentUserId(); - auto subProp = ImeInfoInquirer::GetInstance().GetCurrentInputMethodSubtype(currentUserId); + auto subProp = ImeInfoInquirer::GetInstance().GetCurrentSubtype(currentUserId); EXPECT_TRUE(subProp == nullptr); // subName is not find auto currentProp = InputMethodController::GetInstance()->GetCurrentInputMethod(); ImeCfgManager::GetInstance().imeConfigs_.push_back( { currentUserId, currentProp->name + "/" + currentProp->id, "tt" }); - subProp = ImeInfoInquirer::GetInstance().GetCurrentInputMethodSubtype(currentUserId); + subProp = ImeInfoInquirer::GetInstance().GetCurrentSubtype(currentUserId); EXPECT_TRUE(subProp != nullptr); EXPECT_TRUE(subProp->name == currentProp->name); @@ -752,7 +752,7 @@ HWTEST_F(InputMethodPrivateMemberTest, III_TestGetCurrentInputMethodSubtype_001, auto currentSubProp = InputMethodController::GetInstance()->GetCurrentInputMethodSubtype(); ImeCfgManager::GetInstance().imeConfigs_.push_back( { currentUserId, currentProp->name + "/" + currentProp->id, currentSubProp->id }); - subProp = ImeInfoInquirer::GetInstance().GetCurrentInputMethodSubtype(currentUserId); + subProp = ImeInfoInquirer::GetInstance().GetCurrentSubtype(currentUserId); ASSERT_TRUE(subProp != nullptr); EXPECT_TRUE(subProp->id == currentSubProp->id); } @@ -764,7 +764,7 @@ HWTEST_F(InputMethodPrivateMemberTest, III_TestGetCurrentInputMethodSubtype_001, * @tc.require: * @tc.author: chenyu */ -HWTEST_F(InputMethodPrivateMemberTest, III_TestGetCurrentInputMethod_001, TestSize.Level0) +HWTEST_F(InputMethodPrivateMemberTest, III_TestGetCurrentIme_001, TestSize.Level0) { IMSA_HILOGI("InputMethodPrivateMemberTest III_TestGetCurrentInputMethod_001 TEST START"); // currentIme is empty