From 1f31c0194899f2f4c8a33e5d88fc142420c7ab09 Mon Sep 17 00:00:00 2001 From: hemenghao Date: Sat, 19 Oct 2024 10:01:15 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BE=93=E5=85=A5=E6=B3=95=E5=8F=8C=E7=94=9F?= =?UTF-8?q?=E5=8D=95=E5=A2=9E=E5=8A=A0=E6=9F=A5=E8=AF=A2=E5=92=8C=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hemenghao --- etc/init/inputmethodservice.cfg | 3 +- .../input_method_system_ability_proxy.h | 2 + .../include/input_method_utils.h | 2 +- .../src/input_method_controller.cpp | 22 ++++++ .../src/input_method_system_ability_proxy.cpp | 19 +++++ .../include/input_method_controller.h | 20 +++++ .../common/include/settings_data_utils.h | 7 +- .../common/src/settings_data_utils.cpp | 77 ++++++++++++++++++- .../include/i_input_method_system_ability.h | 2 + services/include/ime_cfg_manager.h | 13 +++- services/include/ime_info_inquirer.h | 1 + .../include/input_method_system_ability.h | 4 + .../input_method_system_ability_stub.h | 8 ++ .../inputmethod_service_ipc_interface_code.h | 2 + services/src/ime_cfg_manager.cpp | 19 ++++- services/src/ime_info_inquirer.cpp | 11 ++- services/src/input_method_system_ability.cpp | 37 ++++++++- .../src/input_method_system_ability_stub.cpp | 17 ++++ test/unittest/cpp_test/BUILD.gn | 4 + .../unittest/cpp_test/common/src/tdd_util.cpp | 2 +- .../cpp_test/mock/datashare_helper.cpp | 10 +++ .../unittest/cpp_test/mock/datashare_helper.h | 4 + .../cpp_test/src/identity_checker_test.cpp | 2 +- .../src/input_method_private_member_test.cpp | 24 +++--- .../cpp_test/src/json_operate_test.cpp | 18 +++-- 25 files changed, 296 insertions(+), 34 deletions(-) diff --git a/etc/init/inputmethodservice.cfg b/etc/init/inputmethodservice.cfg index 34648b25..da17b868 100644 --- a/etc/init/inputmethodservice.cfg +++ b/etc/init/inputmethodservice.cfg @@ -20,7 +20,8 @@ "ohos.permission.MANAGE_LOCAL_ACCOUNTS", "ohos.permission.INPUT_PANEL_STATUS_PUBLISHER", "ohos.permission.RECEIVER_STARTUP_COMPLETED", - "ohos.permission.GET_RUNNING_INFO" + "ohos.permission.GET_RUNNING_INFO", + "ohos.permission.MANAGE_SETTINGS" ], "permission_acls" : ["ohos.permission.INPUT_MONITORING"], "caps" : [], 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 bf9c7dd5..2fbe1652 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 @@ -79,6 +79,8 @@ public: // Deprecated because of no permission check, kept for compatibility int32_t HideCurrentInputDeprecated() override; int32_t ShowCurrentInputDeprecated() override; + bool IsDefaultImeSet() override; + bool EnableIme(const std::string &bundleName) override; private: static inline BrokerDelegator delegator_; diff --git a/frameworks/native/inputmethod_controller/include/input_method_utils.h b/frameworks/native/inputmethod_controller/include/input_method_utils.h index 5ebd2d0b..c5b0baab 100644 --- a/frameworks/native/inputmethod_controller/include/input_method_utils.h +++ b/frameworks/native/inputmethod_controller/include/input_method_utils.h @@ -279,7 +279,7 @@ struct TextConfig { enum class InputType : int32_t { NONE = -1, CAMERA_INPUT = 0, SECURITY_INPUT, VOICE_INPUT, END }; -enum class SwitchTrigger : uint32_t { CURRENT_IME = 0, SYSTEM_APP, IMSA }; +enum class SwitchTrigger : uint32_t { CURRENT_IME = 0, SYSTEM_APP, IMSA, NATIVE_SA}; } // namespace MiscServices } // namespace OHOS #endif // FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_INPUT_METHOD_UTILS_H diff --git a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp index 1ec4ddb5..86df7622 100644 --- a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp +++ b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp @@ -482,6 +482,28 @@ std::shared_ptr InputMethodController::GetCurrentInputMethodSubtype return property; } +bool InputMethodController::IsDefaultImeSet() +{ + IMSA_HILOGI("enter."); + auto proxy = GetSystemAbilityProxy(); + if (proxy == nullptr) { + IMSA_HILOGE("proxy is nullptr!"); + return false; + } + return proxy->IsDefaultImeSet(); +} + +bool InputMethodController::EnableIme(const std::string &bundleName) +{ + IMSA_HILOGI("enter."); + auto proxy = GetSystemAbilityProxy(); + if (proxy == nullptr) { + IMSA_HILOGE("proxy is nullptr!"); + return false; + } + return proxy->EnableIme(bundleName); +} + int32_t InputMethodController::StartInput(InputClientInfo &inputClientInfo, sptr &agent) { IMSA_HILOGD("InputMethodController::StartInput start."); 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 9790cc6e..7e290e5d 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 @@ -166,6 +166,25 @@ std::shared_ptr InputMethodSystemAbilityProxy::GetCurrentInputMetho return ret != ErrorCode::NO_ERROR ? nullptr : property; } +bool InputMethodSystemAbilityProxy::IsDefaultImeSet() +{ + bool isDefaultImeSet = false; + IMSA_HILOGI("InputMethodSystemAbilityProxy::IsDefaultImeSet enter."); + SendRequest(static_cast(InputMethodInterfaceCode::IS_DEFAULT_IME_SET), nullptr, + [&isDefaultImeSet](MessageParcel &reply) { return ITypesUtil::Unmarshal(reply, isDefaultImeSet); }); + return isDefaultImeSet; +} + +bool InputMethodSystemAbilityProxy::EnableIme(const std::string &bundleName) +{ + bool enableIme = false; + IMSA_HILOGI("InputMethodSystemAbilityProxy::EnableIme enter."); + SendRequest(static_cast(InputMethodInterfaceCode::ENABLE_IME), + [&bundleName](MessageParcel &data) { return ITypesUtil::Marshal(data, bundleName); }, + [&enableIme](MessageParcel &reply) { return ITypesUtil::Unmarshal(reply, enableIme); }); + return enableIme; +} + int32_t InputMethodSystemAbilityProxy::ListInputMethod(InputMethodStatus status, std::vector &props) { return SendRequest( 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 def9a00d..d36d6040 100644 --- a/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h +++ b/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h @@ -801,6 +801,26 @@ public: */ IMF_API void Reset(); + /** + * @brief Query whether the default input method is setting. + * + * This function is used to query whether the default input method is setting. + * Do not call this interface unless you know what you are doing + * + * @since 13 + */ + IMF_API bool IsDefaultImeSet(); + + /** + * @brief Enable the ime called bundleName. + * + * This function is used to enable the ime called bundleName. + * Do not call this interface unless you know what you are doing + * + * @since 13 + */ + IMF_API bool EnableIme(const std::string &bundleName); + private: InputMethodController(); ~InputMethodController(); diff --git a/services/adapter/settings_data_provider/common/include/settings_data_utils.h b/services/adapter/settings_data_provider/common/include/settings_data_utils.h index 530967e4..96914a9f 100644 --- a/services/adapter/settings_data_provider/common/include/settings_data_utils.h +++ b/services/adapter/settings_data_provider/common/include/settings_data_utils.h @@ -46,15 +46,18 @@ public: std::shared_ptr CreateDataShareHelper(); int32_t CreateAndRegisterObserver(const std::string &key, SettingsDataObserver::CallbackFunc func); int32_t GetStringValue(const std::string &key, std::string &value); + bool ReleaseDataShareHelper(std::shared_ptr &helper); + Uri GenerateTargetUri(const std::string &key); + bool EnableIme(int32_t userId, const std::string &bundleName); private: SettingsDataUtils() = default; ~SettingsDataUtils(); - bool ReleaseDataShareHelper(std::shared_ptr &helper); int32_t RegisterObserver(const sptr &observer); int32_t UnregisterObserver(const sptr &observer); - Uri GenerateTargetUri(const std::string &key); sptr GetToken(); + std::vector split(const std::string &text, char separator); + std::string SetSettingValues(const std::string &settingValue, const std::string &bundleName); private: static std::mutex instanceMutex_; diff --git a/services/adapter/settings_data_provider/common/src/settings_data_utils.cpp b/services/adapter/settings_data_provider/common/src/settings_data_utils.cpp index a66d53ce..f956a0ad 100644 --- a/services/adapter/settings_data_provider/common/src/settings_data_utils.cpp +++ b/services/adapter/settings_data_provider/common/src/settings_data_utils.cpp @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#include #include "settings_data_utils.h" #include "ime_info_inquirer.h" @@ -193,5 +193,80 @@ sptr SettingsDataUtils::GetToken() remoteObj_ = remoteObj; return remoteObj_; } + +bool SettingsDataUtils::EnableIme(int32_t userId, const std::string &bundleName) +{ + const int32_t mainUserId = 100; + if (userId != mainUserId) { + IMSA_HILOGE("user is not main."); + return false; + } + const char *SETTING_COLUMN_KEYWORD = "KEYWORD"; + const char *SETTING_COLUMN_VALUE = "VALUE"; + const char *settingKey = "settings.inputmethod.enable_ime"; + std::string settingValue = ""; + GetStringValue(settingKey, settingValue); + IMSA_HILOGI("settingValue: %{public}s", settingValue.c_str()); + std::string value = ""; + if (settingValue == "") { + value = "{\"enableImeList\" : {\"100\" : [\"" + bundleName + "\"]}}"; + } else { + value = SetSettingValues(settingValue, bundleName); + } + IMSA_HILOGI("value: %{public}s", value.c_str()); + auto helper = CreateDataShareHelper(); + if (helper == nullptr) { + IMSA_HILOGE("helper is nullptr."); + return false; + } + DataShare::DataShareValueObject keyObj(settingKey); + DataShare::DataShareValueObject valueObj(value); + DataShare::DataShareValuesBucket bucket; + bucket.Put(SETTING_COLUMN_KEYWORD, keyObj); + bucket.Put(SETTING_COLUMN_VALUE, valueObj); + DataShare::DataSharePredicates predicates; + predicates.EqualTo(SETTING_COLUMN_KEYWORD, settingKey); + Uri uri(GenerateTargetUri(settingKey)); + if (helper->Update(uri, predicates, bucket) <= 0) { + int index = helper->Insert(uri, bucket); + IMSA_HILOGI("no data exists, insert ret index: %{public}d", index); + } else { + IMSA_HILOGI("data exits"); + } + bool ret = ReleaseDataShareHelper(helper); + IMSA_HILOGI("ReleaseDataShareHelper isSuccess: %{public}d", ret); + return ret; +} + +std::vector SettingsDataUtils::split(const std::string &text, char delim) +{ + std::vector tokens; + std::stringstream ss(text); + std::string item; + while (std::getline(ss, item, delim)) { + if (!item.empty()) { + tokens.push_back(item); + } + } + return tokens; +} + +std::string SettingsDataUtils::SetSettingValues(const std::string &settingValue, const std::string &bundleName) +{ + std::string value = ""; + std::vector settingValues = split(settingValue, ']'); + for (uint32_t i = 0; i < settingValues.size(); ++i) { + if (i == 0) { + if (settingValues[0].back() == '[') { + value += settingValues[i] + "\"" + bundleName + "\"" + "]"; + } else { + value += settingValues[i] + ",\"" + bundleName + "\"" + "]"; + } + } else { + value += settingValues[i]; + } + } + return value; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/services/include/i_input_method_system_ability.h b/services/include/i_input_method_system_ability.h index c79f5085..f9be4622 100644 --- a/services/include/i_input_method_system_ability.h +++ b/services/include/i_input_method_system_ability.h @@ -74,6 +74,8 @@ public: virtual int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown) = 0; virtual int32_t GetSecurityMode(int32_t &security) = 0; virtual int32_t IsDefaultIme() = 0; + virtual bool IsDefaultImeSet() = 0; + virtual bool EnableIme(const std::string &bundleName) = 0; virtual int32_t ConnectSystemCmd(const sptr &channel, sptr &agent) = 0; // Deprecated because of no permission check, and keep for compatibility diff --git a/services/include/ime_cfg_manager.h b/services/include/ime_cfg_manager.h index 32176f2d..b92ddaff 100644 --- a/services/include/ime_cfg_manager.h +++ b/services/include/ime_cfg_manager.h @@ -26,25 +26,29 @@ namespace OHOS { namespace MiscServices { struct ImePersistInfo : public Serializable { ImePersistInfo() = default; - ImePersistInfo(int32_t userId, std::string currentIme, std::string currentSubName) - : userId(userId), currentIme(std::move(currentIme)), currentSubName(std::move(currentSubName)){}; + ImePersistInfo(int32_t userId, std::string currentIme, std::string currentSubName, bool isDefaultImeSet) + : userId(userId), currentIme(std::move(currentIme)), currentSubName(std::move(currentSubName)), + isDefaultImeSet(isDefaultImeSet){}; static constexpr int32_t INVALID_USERID = -1; int32_t userId{ INVALID_USERID }; std::string currentIme; std::string currentSubName; + bool isDefaultImeSet{ false }; bool Marshal(cJSON *node) const override { auto ret = SetValue(node, GET_NAME(userId), userId); ret = SetValue(node, GET_NAME(currentIme), currentIme) && ret; - SetValue(node, GET_NAME(currentSubName), currentSubName); + ret = SetValue(node, GET_NAME(currentSubName), currentSubName) && ret; + ret = SetValue(node, GET_NAME(isDefaultImeSet), isDefaultImeSet) && ret; return ret; } bool Unmarshal(cJSON *node) override { auto ret = GetValue(node, GET_NAME(userId), userId); ret = GetValue(node, GET_NAME(currentIme), currentIme) && ret; - GetValue(node, GET_NAME(currentSubName), currentSubName); + ret = GetValue(node, GET_NAME(currentSubName), currentSubName) && ret; + ret = GetValue(node, GET_NAME(isDefaultImeSet), isDefaultImeSet) && ret; return ret; } }; @@ -76,6 +80,7 @@ public: void ModifyImeCfg(const ImePersistInfo &cfg); void DeleteImeCfg(int32_t userId); std::shared_ptr GetCurrentImeCfg(int32_t userId); + bool IsDefaultImeSet(int32_t userId); private: ImeCfgManager() = default; diff --git a/services/include/ime_info_inquirer.h b/services/include/ime_info_inquirer.h index d10ebc28..a65beb25 100644 --- a/services/include/ime_info_inquirer.h +++ b/services/include/ime_info_inquirer.h @@ -103,6 +103,7 @@ public: bool IsInputMethod(int32_t userId, const std::string &bundleName); bool IsRunningIme(int32_t userId, const std::string &bundleName); std::vector GetRunningIme(int32_t userId); + bool IsDefaultImeSet(int32_t userId); private: ImeInfoInquirer() = default; diff --git a/services/include/input_method_system_ability.h b/services/include/input_method_system_ability.h index 2fcdc15c..99c66699 100644 --- a/services/include/input_method_system_ability.h +++ b/services/include/input_method_system_ability.h @@ -88,6 +88,8 @@ public: int Dump(int fd, const std::vector &args) override; void DumpAllMethod(int fd); int32_t IsDefaultIme() override; + bool IsDefaultImeSet() override; + bool EnableIme(const std::string &bundleName) override; protected: void OnStart() override; @@ -108,6 +110,8 @@ private: int32_t OnUserStop(const Message *msg); int32_t OnHideKeyboardSelf(const Message *msg); bool IsNeedSwitch(int32_t userId, const std::string &bundleName, const std::string &subName); + int32_t CheckEnableAndSwitchPermission(); + std::string SetSettingValues(const std::string &settingValue, const std::string &bundleName); int32_t CheckSwitchPermission(int32_t userId, const SwitchInfo &switchInfo, SwitchTrigger trigger); bool IsStartInputTypePermitted(int32_t userId); int32_t OnSwitchInputMethod(int32_t userId, const SwitchInfo &switchInfo, SwitchTrigger trigger); diff --git a/services/include/input_method_system_ability_stub.h b/services/include/input_method_system_ability_stub.h index 2ed222cd..90de6a0d 100644 --- a/services/include/input_method_system_ability_stub.h +++ b/services/include/input_method_system_ability_stub.h @@ -91,6 +91,10 @@ private: int32_t GetDefaultInputMethodOnRemote(MessageParcel &data, MessageParcel &reply); + int32_t IsDefaultImeSetOnRemote(MessageParcel &data, MessageParcel &reply); + + int32_t EnableImeOnRemote(MessageParcel &data, MessageParcel &reply); + int32_t GetInputMethodConfigOnRemote(MessageParcel &data, MessageParcel &reply); int32_t IsPanelShownOnRemote(MessageParcel &data, MessageParcel &reply); @@ -176,6 +180,10 @@ private: &InputMethodSystemAbilityStub::IsCurrentImeByPidOnRemote, [static_cast(InputMethodInterfaceCode::INIT_CONNECT)] = &InputMethodSystemAbilityStub::InitConnectOnRemote, + [static_cast(InputMethodInterfaceCode::IS_DEFAULT_IME_SET)] = + &InputMethodSystemAbilityStub::IsDefaultImeSetOnRemote, + [static_cast(InputMethodInterfaceCode::ENABLE_IME)] = + &InputMethodSystemAbilityStub::EnableImeOnRemote, }; }; } // namespace OHOS::MiscServices diff --git a/services/include/inputmethod_service_ipc_interface_code.h b/services/include/inputmethod_service_ipc_interface_code.h index 959b6ed7..d9c70d61 100644 --- a/services/include/inputmethod_service_ipc_interface_code.h +++ b/services/include/inputmethod_service_ipc_interface_code.h @@ -55,6 +55,8 @@ enum class InputMethodInterfaceCode { CONNECT_SYSTEM_CMD, IS_CURRENT_IME_BY_PID, INIT_CONNECT, + IS_DEFAULT_IME_SET, + ENABLE_IME, IMS_CMD_END, }; } // namespace MiscServices diff --git a/services/src/ime_cfg_manager.cpp b/services/src/ime_cfg_manager.cpp index d2c897e7..74e754ad 100644 --- a/services/src/ime_cfg_manager.cpp +++ b/services/src/ime_cfg_manager.cpp @@ -106,7 +106,16 @@ void ImeCfgManager::ModifyImeCfg(const ImePersistInfo &cfg) auto it = std::find_if(imeConfigs_.begin(), imeConfigs_.end(), [&cfg](const ImePersistInfo &imeCfg) { return imeCfg.userId == cfg.userId && !cfg.currentIme.empty(); }); if (it != imeConfigs_.end()) { - *it = cfg; + if (it->isDefaultImeSet) { + ImePersistInfo imePersistInfo; + imePersistInfo.userId = cfg.userId; + imePersistInfo.currentIme = cfg.currentIme; + imePersistInfo.currentSubName = cfg.currentSubName; + imePersistInfo.isDefaultImeSet = true; + *it = imePersistInfo; + } else { + *it = cfg; + } } WriteImeCfg(); @@ -148,5 +157,13 @@ std::shared_ptr ImeCfgManager::GetCurrentImeCfg(int32_t userId) } return std::make_shared(info); } + +bool ImeCfgManager::IsDefaultImeSet(int32_t userId) +{ + IMSA_HILOGI("ImeCfgManager::IsDefaultImeSet enter."); + auto cfg = GetImeCfg(userId); + IMSA_HILOGI("isDefaultImeSet: %{public}d", cfg.isDefaultImeSet); + return cfg.isDefaultImeSet; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/services/src/ime_info_inquirer.cpp b/services/src/ime_info_inquirer.cpp index f89be635..9d9cd20e 100644 --- a/services/src/ime_info_inquirer.cpp +++ b/services/src/ime_info_inquirer.cpp @@ -699,7 +699,7 @@ std::shared_ptr ImeInfoInquirer::GetCurrentSubtype(int32_t userId) return std::make_shared(*iter); } IMSA_HILOGW("subtype %{public}s not found.", currentIme->subName.c_str()); - ImeCfgManager::GetInstance().ModifyImeCfg({ userId, currentIme->imeId, it->subProps[0].id }); + ImeCfgManager::GetInstance().ModifyImeCfg({ userId, currentIme->imeId, it->subProps[0].id, false }); return std::make_shared(it->subProps[0]); } @@ -754,8 +754,8 @@ std::shared_ptr ImeInfoInquirer::GetImeToStart(int32_t userId) newIme.subName = info->subProp.id; } currentImeCfg->imeId.empty() - ? ImeCfgManager::GetInstance().AddImeCfg({ userId, newIme.imeId, newIme.subName }) - : ImeCfgManager::GetInstance().ModifyImeCfg({ userId, newIme.imeId, newIme.subName }); + ? ImeCfgManager::GetInstance().AddImeCfg({ userId, newIme.imeId, newIme.subName, false }) + : ImeCfgManager::GetInstance().ModifyImeCfg({ userId, newIme.imeId, newIme.subName, false}); return std::make_shared(newIme); } return currentImeCfg; @@ -1104,6 +1104,11 @@ std::vector ImeInfoInquirer::GetRunningIme(int32_t userId) return bundleNames; } +bool ImeInfoInquirer::IsDefaultImeSet(int32_t userId) +{ + return ImeCfgManager::GetInstance().IsDefaultImeSet(userId); +} + bool ImeInfoInquirer::IsRunningIme(int32_t userId, const std::string &bundleName) { auto bundleNames = GetRunningIme(userId); diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index 1d73e2dc..66e9227c 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -673,6 +673,16 @@ int32_t InputMethodSystemAbility::SwitchInputMethod(const std::string &bundleNam : OnSwitchInputMethod(userId, switchInfo, trigger); } +bool InputMethodSystemAbility::EnableIme(const std::string &bundleName) +{ + if (CheckEnableAndSwitchPermission() != ErrorCode::NO_ERROR) { + IMSA_HILOGE("Check enable ime value failed!"); + return false; + } + int32_t userId = GetCallingUserId(); + return SettingsDataUtils::GetInstance()->EnableIme(userId, bundleName); +} + int32_t InputMethodSystemAbility::OnSwitchInputMethod(int32_t userId, const SwitchInfo &switchInfo, SwitchTrigger trigger) { @@ -703,7 +713,7 @@ int32_t InputMethodSystemAbility::OnSwitchInputMethod(int32_t userId, const Swit { InputMethodSyncTrace tracer("InputMethodSystemAbility_OnSwitchInputMethod"); std::string targetImeName = info->prop.name + "/" + info->prop.id; - ImeCfgManager::GetInstance().ModifyImeCfg({ userId, targetImeName, info->subProp.id }); + ImeCfgManager::GetInstance().ModifyImeCfg({ userId, targetImeName, info->subProp.id, true }); auto targetIme = std::make_shared(ImeNativeCfg { targetImeName, info->prop.name, switchInfo.subName.empty() ? "" : info->subProp.id, info->prop.id }); if (!session->StartIme(targetIme)) { @@ -806,7 +816,7 @@ int32_t InputMethodSystemAbility::SwitchExtension(int32_t userId, const std::sha return ErrorCode::ERROR_NULL_POINTER; } std::string targetImeName = info->prop.name + "/" + info->prop.id; - ImeCfgManager::GetInstance().ModifyImeCfg({ userId, targetImeName, info->subProp.id }); + ImeCfgManager::GetInstance().ModifyImeCfg({ userId, targetImeName, info->subProp.id, false }); ImeNativeCfg targetIme = { targetImeName, info->prop.name, info->subProp.id, info->prop.id }; if (!session->StartIme(std::make_shared(targetIme))) { IMSA_HILOGE("start input method failed!"); @@ -832,7 +842,7 @@ int32_t InputMethodSystemAbility::SwitchSubType(int32_t userId, const std::share return ret; } auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId)->imeId; - ImeCfgManager::GetInstance().ModifyImeCfg({ userId, currentIme, info->subProp.id }); + ImeCfgManager::GetInstance().ModifyImeCfg({ userId, currentIme, info->subProp.id, false }); session->NotifyImeChangeToClients(info->prop, info->subProp); return ErrorCode::NO_ERROR; } @@ -906,6 +916,11 @@ std::shared_ptr InputMethodSystemAbility::GetCurrentInputMethod() return ImeInfoInquirer::GetInstance().GetCurrentInputMethod(GetCallingUserId()); } +bool InputMethodSystemAbility::IsDefaultImeSet() +{ + return ImeInfoInquirer::GetInstance().IsDefaultImeSet(GetCallingUserId()); +} + std::shared_ptr InputMethodSystemAbility::GetCurrentInputMethodSubtype() { return ImeInfoInquirer::GetInstance().GetCurrentSubtype(GetCallingUserId()); @@ -1508,6 +1523,19 @@ int32_t InputMethodSystemAbility::UnRegisteredProxyIme(UnRegisteredType type, co return session->OnUnRegisteredProxyIme(type, core); } +int32_t InputMethodSystemAbility::CheckEnableAndSwitchPermission() +{ + if (!identityChecker_->IsNativeSa(IPCSkeleton::GetCallingFullTokenID())) { + IMSA_HILOGE("not native sa!"); + return ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION; + } + if (!identityChecker_->HasPermission(IPCSkeleton::GetCallingTokenID(), PERMISSION_CONNECT_IME_ABILITY)) { + IMSA_HILOGE("have not PERMISSION_CONNECT_IME_ABILITY!"); + return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; + } + return ErrorCode::NO_ERROR; +} + int32_t InputMethodSystemAbility::CheckSwitchPermission(int32_t userId, const SwitchInfo &switchInfo, SwitchTrigger trigger) { @@ -1515,6 +1543,9 @@ int32_t InputMethodSystemAbility::CheckSwitchPermission(int32_t userId, const Sw if (trigger == SwitchTrigger::IMSA) { return ErrorCode::NO_ERROR; } + if (trigger == SwitchTrigger::NATIVE_SA) { + return CheckEnableAndSwitchPermission(); + } if (trigger == SwitchTrigger::SYSTEM_APP) { if (!identityChecker_->IsSystemApp(IPCSkeleton::GetCallingFullTokenID())) { IMSA_HILOGE("not system app!"); diff --git a/services/src/input_method_system_ability_stub.cpp b/services/src/input_method_system_ability_stub.cpp index b3d607f4..4769d874 100644 --- a/services/src/input_method_system_ability_stub.cpp +++ b/services/src/input_method_system_ability_stub.cpp @@ -181,6 +181,23 @@ int32_t InputMethodSystemAbilityStub::GetDefaultInputMethodOnRemote(MessageParce return ITypesUtil::Marshal(reply, ret, *prop) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; } +int32_t InputMethodSystemAbilityStub::IsDefaultImeSetOnRemote(MessageParcel &data, MessageParcel &reply) +{ + return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, IsDefaultImeSet()) ? ErrorCode::NO_ERROR + : ErrorCode::ERROR_EX_PARCELABLE; +} + +int32_t InputMethodSystemAbilityStub::EnableImeOnRemote(MessageParcel &data, MessageParcel &reply) +{ + std::string bundleName; + if (!ITypesUtil::Unmarshal(data, bundleName)) { + IMSA_HILOGE("unmarshal failed!"); + return ErrorCode::ERROR_EX_PARCELABLE; + } + return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, EnableIme(bundleName)) ? ErrorCode::NO_ERROR + : ErrorCode::ERROR_EX_PARCELABLE; +} + int32_t InputMethodSystemAbilityStub::GetInputMethodConfigOnRemote(MessageParcel &data, MessageParcel &reply) { OHOS::AppExecFwk::ElementName inputMethodConfig; diff --git a/test/unittest/cpp_test/BUILD.gn b/test/unittest/cpp_test/BUILD.gn index a46b69bd..f1526624 100644 --- a/test/unittest/cpp_test/BUILD.gn +++ b/test/unittest/cpp_test/BUILD.gn @@ -726,6 +726,8 @@ ohos_unittest("EnableImeDataParseTest") { "ability_runtime:dataobs_manager", "bundle_framework:appexecfwk_core", "c_utils:utils", + "data_share:datashare_common", + "data_share:datashare_consumer", "hilog:libhilog", "samgr:samgr_proxy", ] @@ -773,6 +775,8 @@ ohos_unittest("SecurityModeParseTest") { "access_token:libaccesstoken_sdk", "bundle_framework:appexecfwk_core", "c_utils:utils", + "data_share:datashare_common", + "data_share:datashare_consumer", "hilog:libhilog", "input:libmmi-client", "ipc:ipc_core", diff --git a/test/unittest/cpp_test/common/src/tdd_util.cpp b/test/unittest/cpp_test/common/src/tdd_util.cpp index 1ea8f412..12de8ace 100644 --- a/test/unittest/cpp_test/common/src/tdd_util.cpp +++ b/test/unittest/cpp_test/common/src/tdd_util.cpp @@ -388,7 +388,7 @@ void TddUtil::InitCurrentImePermissionInfo() } currentBundleNameMock_ = property->name; session->InitImeData({ property->name, property->id }); - ImeCfgManager::GetInstance().imeConfigs_ = { { userId, property->name + "/" + property->id, "" } }; + ImeCfgManager::GetInstance().imeConfigs_ = { { userId, property->name + "/" + property->id, "", false } }; } void TddUtil::WindowManager::CreateWindow() diff --git a/test/unittest/cpp_test/mock/datashare_helper.cpp b/test/unittest/cpp_test/mock/datashare_helper.cpp index d53b2367..57dcc123 100644 --- a/test/unittest/cpp_test/mock/datashare_helper.cpp +++ b/test/unittest/cpp_test/mock/datashare_helper.cpp @@ -85,5 +85,15 @@ bool DataShareHelper::Release() { return true; } + +int DataShareHelper::Update(Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) +{ + return 0; +} + +int DataShareHelper::Insert(Uri &uri, const DataShareValuesBucket &value) +{ + return 0; +} } // namespace DataShare } // namespace OHOS diff --git a/test/unittest/cpp_test/mock/datashare_helper.h b/test/unittest/cpp_test/mock/datashare_helper.h index b4634efe..b2c6be70 100644 --- a/test/unittest/cpp_test/mock/datashare_helper.h +++ b/test/unittest/cpp_test/mock/datashare_helper.h @@ -20,6 +20,8 @@ #include #include "data_ability_observer_interface.h" +#include "datashare_value_object.h" +#include "datashare_values_bucket.h" #include "uri.h" namespace OHOS { @@ -55,6 +57,8 @@ public: static void RegisterObserver(const Uri &uri, const sptr &dataObserver); static void UnregisterObserver(const Uri &uri, const sptr &dataObserver); static bool Release(); + static int Update(Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value); + static int Insert(Uri &uri, const DataShareValuesBucket &value); private: static std::shared_ptr instance_; diff --git a/test/unittest/cpp_test/src/identity_checker_test.cpp b/test/unittest/cpp_test/src/identity_checker_test.cpp index 7030b8aa..c901f888 100644 --- a/test/unittest/cpp_test/src/identity_checker_test.cpp +++ b/test/unittest/cpp_test/src/identity_checker_test.cpp @@ -100,7 +100,7 @@ void IdentityCheckerTest::SetUpTestCase(void) return; } service_->OnStart(); - ImeCfgManager::GetInstance().imeConfigs_ = { { MAIN_USER_ID, CURRENT_IME, CURRENT_SUBNAME } }; + ImeCfgManager::GetInstance().imeConfigs_ = { { MAIN_USER_ID, CURRENT_IME, CURRENT_SUBNAME, false} }; identityCheckerImpl_ = std::make_shared(); } 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 83d98bc1..48c9559e 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 @@ -383,7 +383,8 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_SwitchByCombinationKey_003, TestSize.L info.prop = { .name = "testBundleName" }; info.subProps = { { .id = "testSubName" } }; FullImeInfoManager::GetInstance().fullImeInfos_.insert({ MAIN_USER_ID, { info } }); - ImeCfgManager::GetInstance().imeConfigs_.push_back({ MAIN_USER_ID, "testBundleName/testExtName", "testSubName" }); + ImeCfgManager::GetInstance().imeConfigs_.push_back({ MAIN_USER_ID, "testBundleName/testExtName", "testSubName", + false }); auto ret = service_->SwitchByCombinationKey(KeyboardEvent::SHIFT_RIGHT_MASK); EXPECT_EQ(ret, ErrorCode::NO_ERROR); ret = service_->SwitchByCombinationKey(KeyboardEvent::CAPS_MASK); @@ -404,7 +405,8 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_SwitchByCombinationKey_004, TestSize.L info.prop = { .name = "testBundleName", .id = "testExtName" }; info.subProps = { { .name = "testBundleName", .id = "testSubName", .language = "French" } }; FullImeInfoManager::GetInstance().fullImeInfos_.insert({ MAIN_USER_ID, { info } }); - ImeCfgManager::GetInstance().imeConfigs_.push_back({ MAIN_USER_ID, "testBundleName/testExtName", "testSubName" }); + ImeCfgManager::GetInstance().imeConfigs_.push_back({ MAIN_USER_ID, "testBundleName/testExtName", "testSubName", + false }); auto ret = service_->SwitchByCombinationKey(KeyboardEvent::SHIFT_RIGHT_MASK); EXPECT_EQ(ret, ErrorCode::NO_ERROR); } @@ -423,7 +425,8 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_SwitchByCombinationKey_005, TestSize.L info.prop = { .name = "testBundleName", .id = "testExtName" }; info.subProps = { { .name = "testBundleName", .id = "testSubName", .mode = "upper", .language = "english" } }; FullImeInfoManager::GetInstance().fullImeInfos_.insert({ MAIN_USER_ID, { info } }); - ImeCfgManager::GetInstance().imeConfigs_.push_back({ MAIN_USER_ID, "testBundleName/testExtName", "testSubName" }); + ImeCfgManager::GetInstance().imeConfigs_.push_back({ MAIN_USER_ID, "testBundleName/testExtName", "testSubName", + false }); auto ret = service_->SwitchByCombinationKey(KeyboardEvent::SHIFT_RIGHT_MASK); EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS); ret = service_->SwitchByCombinationKey(KeyboardEvent::CAPS_MASK); @@ -446,7 +449,8 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_SwitchByCombinationKey_006, TestSize.L { .name = "testBundleName", .id = "testSubName1", .mode = "lower", .language = "chinese" } }; FullImeInfoManager::GetInstance().fullImeInfos_.insert({ MAIN_USER_ID, { info } }); - ImeCfgManager::GetInstance().imeConfigs_.push_back({ MAIN_USER_ID, "testBundleName/testExtName", "testSubName" }); + ImeCfgManager::GetInstance().imeConfigs_.push_back({ MAIN_USER_ID, "testBundleName/testExtName", "testSubName", + false}); // english->chinese auto ret = service_->SwitchByCombinationKey(KeyboardEvent::SHIFT_RIGHT_MASK); EXPECT_EQ(ret, ErrorCode::ERROR_IME_START_FAILED); @@ -489,7 +493,7 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_SwitchByCombinationKey_008, TestSize.L service_->userId_ = userId; auto prop = InputMethodController::GetInstance()->GetCurrentInputMethod(); auto subProp = InputMethodController::GetInstance()->GetCurrentInputMethodSubtype(); - ImeCfgManager::GetInstance().imeConfigs_.push_back({ userId, prop->name + "/" + prop->id, subProp->id }); + ImeCfgManager::GetInstance().imeConfigs_.push_back({ userId, prop->name + "/" + prop->id, subProp->id, false }); std::vector props; InputMethodController::GetInstance()->ListInputMethod(props); if (props.size() == 1) { @@ -530,7 +534,7 @@ HWTEST_F(InputMethodPrivateMemberTest, III_TestGetCurrentSubtype_001, TestSize.L // subName is not find auto currentProp = InputMethodController::GetInstance()->GetCurrentInputMethod(); ImeCfgManager::GetInstance().imeConfigs_.push_back( - { currentUserId, currentProp->name + "/" + currentProp->id, "tt" }); + { currentUserId, currentProp->name + "/" + currentProp->id, "tt", false }); subProp = ImeInfoInquirer::GetInstance().GetCurrentSubtype(currentUserId); ASSERT_TRUE(subProp != nullptr); EXPECT_TRUE(subProp->name == currentProp->name); @@ -539,7 +543,7 @@ HWTEST_F(InputMethodPrivateMemberTest, III_TestGetCurrentSubtype_001, TestSize.L auto currentSubProp = InputMethodController::GetInstance()->GetCurrentInputMethodSubtype(); ImeCfgManager::GetInstance().imeConfigs_.clear(); ImeCfgManager::GetInstance().imeConfigs_.push_back( - { currentUserId, currentProp->name + "/" + currentProp->id, currentSubProp->id }); + { currentUserId, currentProp->name + "/" + currentProp->id, currentSubProp->id, false}); subProp = ImeInfoInquirer::GetInstance().GetCurrentSubtype(currentUserId); ASSERT_TRUE(subProp != nullptr); EXPECT_TRUE(subProp->id == currentSubProp->id); @@ -563,7 +567,7 @@ HWTEST_F(InputMethodPrivateMemberTest, III_TestGetCurrentIme_001, TestSize.Level // get correct prop auto currentProp = InputMethodController::GetInstance()->GetCurrentInputMethod(); ImeCfgManager::GetInstance().imeConfigs_.push_back( - { currentUserId, currentProp->name + "/" + currentProp->id, "test" }); + { currentUserId, currentProp->name + "/" + currentProp->id, currentProp->id, false}); prop = ImeInfoInquirer::GetInstance().GetCurrentInputMethod(currentUserId); ASSERT_TRUE(prop != nullptr); EXPECT_TRUE(prop->id == currentProp->id); @@ -644,7 +648,7 @@ HWTEST_F(InputMethodPrivateMemberTest, III_TestIsNewExtInfos_001, TestSize.Level HWTEST_F(InputMethodPrivateMemberTest, ICM_TestDeleteImeCfg_001, TestSize.Level0) { IMSA_HILOGI("InputMethodPrivateMemberTest ICM_TestDeleteImeCfg_001 TEST START"); - ImeCfgManager::GetInstance().imeConfigs_.push_back({ 100, "testBundleName", "testSubName" }); + ImeCfgManager::GetInstance().imeConfigs_.push_back({ 100, "testBundleName", "testSubName", false}); ImeCfgManager::GetInstance().DeleteImeCfg(100); EXPECT_TRUE(ImeCfgManager::GetInstance().imeConfigs_.empty()); } @@ -829,7 +833,7 @@ HWTEST_F(InputMethodPrivateMemberTest, TestHandlePackageEvent, TestSize.Level0) //remove bundle not current ime auto parcel3 = new (std::nothrow) MessageParcel(); service_->userId_ = userId; - ImeCfgManager::GetInstance().imeConfigs_.push_back({ 60, "testBundleName/testExtName", "testSubName" }); + ImeCfgManager::GetInstance().imeConfigs_.push_back({ 60, "testBundleName/testExtName", "testSubName", false }); parcel3->WriteInt32(userId); parcel3->WriteString(bundleName); auto msg3 = std::make_shared(MessageID::MSG_ID_PACKAGE_REMOVED, parcel3); diff --git a/test/unittest/cpp_test/src/json_operate_test.cpp b/test/unittest/cpp_test/src/json_operate_test.cpp index 754ebbdd..f6a842a3 100644 --- a/test/unittest/cpp_test/src/json_operate_test.cpp +++ b/test/unittest/cpp_test/src/json_operate_test.cpp @@ -32,9 +32,10 @@ namespace MiscServices { class JsonOperateTest : public testing::Test { public: static constexpr const char *IME_PERSIST_CFG = "{\"imeCfgList\":[{\"userId\":100,\"currentIme\":\"bundleName/" - "extName\",\"currentSubName\":\"subName\"},{\"userId\":" - "104,\"currentIme\":\"bundleName1/" - "extName1\",\"currentSubName\":\"subName1\"}]}"; + "extName\",\"currentSubName\":\"subName\",\"isDefaultImeSet\":" + "false},{\"userId\":104,\"currentIme\":\"bundleName1/" + "extName1\",\"currentSubName\":\"subName1\"," + "\"isDefaultImeSet\":false}]}"; static constexpr const char *IME_PERSIST_CFG_NULL = "{\"imeCfgList\":[]}"; static constexpr const char *IME_PERSIST_CFG_VALUE_TYPE_ERROR = "{\"imeCfgList\":[{\"userId\":100,\"currentIme\":" "\"bundleName/" @@ -239,11 +240,16 @@ HWTEST_F(JsonOperateTest, testParseImePersistCfg001, TestSize.Level0) HWTEST_F(JsonOperateTest, testPackageImePersistCfg001, TestSize.Level0) { IMSA_HILOGI("JsonOperateTest testPackageImePersistCfg001 START"); + const std::string imePersistCfg = "{\"imeCfgList\":[{\"userId\":100,\"currentIme\":\"bundleName/" + "extName\",\"currentSubName\":\"subName\",\"isDefaultImeSet\":0}," + "{\"userId\":104,\"currentIme\":\"bundleName1/" + "extName1\",\"currentSubName\":\"subName1\"," + "\"isDefaultImeSet\":0}]}"; ImeCfgManager::GetInstance().imeConfigs_.clear(); - ImeCfgManager::GetInstance().imeConfigs_.emplace_back(100, "bundleName/extName", "subName"); - ImeCfgManager::GetInstance().imeConfigs_.emplace_back(104, "bundleName1/extName1", "subName1"); + ImeCfgManager::GetInstance().imeConfigs_.emplace_back(100, "bundleName/extName", "subName", false); + ImeCfgManager::GetInstance().imeConfigs_.emplace_back(104, "bundleName1/extName1", "subName1", false); auto str = ImeCfgManager::GetInstance().PackageImeCfg(); - EXPECT_EQ(str, JsonOperateTest::IME_PERSIST_CFG); + EXPECT_EQ(str, imePersistCfg); } /**