Signed-off-by: ma-shaoyin <mashaoyin1@huawei.com>

Changes to be committed:
This commit is contained in:
ma-shaoyin 2023-10-12 21:11:41 +08:00
parent 8cdfa37ea1
commit 4789134360
10 changed files with 90 additions and 173 deletions

View File

@ -30,9 +30,9 @@
namespace OHOS {
namespace MiscServices {
int32_t MAX_TYPE_NUM = 128;
constexpr size_t ARGC_ZERO = 0;
constexpr size_t ARGC_ONE = 1;
constexpr size_t ARGC_TWO = 2;
constexpr size_t ARGC_MAX = 6;
thread_local napi_ref JsGetInputMethodSetting::IMSRef_ = nullptr;
const std::string JsGetInputMethodSetting::IMS_CLASS_NAME = "InputMethodSetting";
const std::map<InputWindowStatus, std::string> PANEL_STATUS{ { InputWindowStatus::SHOW, "imeShow" },
@ -57,6 +57,7 @@ napi_value JsGetInputMethodSetting::Init(napi_env env, napi_value exports)
DECLARE_NAPI_FUNCTION("listInputMethodSubtype", ListInputMethodSubtype),
DECLARE_NAPI_FUNCTION("listCurrentInputMethodSubtype", ListCurrentInputMethodSubtype),
DECLARE_NAPI_FUNCTION("getInputMethods", GetInputMethods),
DECLARE_NAPI_FUNCTION("getInputMethodsSync", getInputMethodsSync),
DECLARE_NAPI_FUNCTION("displayOptionalInputMethod", DisplayOptionalInputMethod),
DECLARE_NAPI_FUNCTION("showOptionalInputMethods", ShowOptionalInputMethods),
DECLARE_NAPI_FUNCTION("on", Subscribe),

View File

@ -25,6 +25,7 @@
#include "enable_ime_data_observer.h"
#include "global.h"
#include "input_method_property.h"
#include "uri.h"
namespace OHOS {
namespace MiscServices {
@ -48,7 +49,6 @@ public:
bool CheckNeedSwitch(const std::string &key, SwitchInfo &switchInfo, const int32_t userId);
// for switch target ime
bool CheckNeedSwitch(const SwitchInfo &info, const int32_t userId);
int32_t GetNextSwitchInfo(SwitchInfo &switchInfo, const int32_t userId);
void OnUserChanged(const int32_t userId);
static constexpr const char *ENABLE_IME = "settings.inputmethod.enable_ime";
@ -62,26 +62,26 @@ private:
std::shared_ptr<DataShare::DataShareHelper> CreateDataShareHelper();
bool ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> &helper);
int32_t RegisterObserver(const sptr<EnableImeDataObserver> &observer);
int32_t UnregisterObserver(const sptr<EnableImeDataObserver> &observer);
int32_t GetStringValue(const std::string &key, std::string &value);
Uri GenerateTargetUri(const std::string &key);
bool ParseJsonData(const std::string &key, const std::string &valueStr, std::vector<std::string> &enableVec,
const int32_t userId);
const std::string GetJsonListName(const std::string &key);
bool CheckTargetEnableName(
const std::string &key, const std::string &targetName, std::string &nextIme, const int32_t userId);
std::shared_ptr<Property> GetDefaultIme();
int32_t UnregisterObserver(const sptr<EnableImeDataObserver> &observer);
Uri GenerateTargetUri(const std::string &key);
private:
static std::mutex instanceMutex_;
static sptr<EnableImeDataParser> instance_;
std::mutex tokenMutex_;
sptr<IRemoteObject> remoteObj_ = nullptr;
std::mutex listMutex_;
std::unordered_map<std::string, std::vector<std::string>> enableList_;
std::shared_ptr<Property> defaultImeInfo_{ nullptr };
std::vector<sptr<EnableImeDataObserver>> observerList_;
int32_t currrentUserId_ = 0;
};
} // namespace MiscServices

View File

@ -18,22 +18,18 @@
#include "ime_info_inquirer.h"
#include "iservice_registry.h"
#include "nlohmann/json.hpp"
#include "datashare_errno.h"
#include "system_ability_definition.h"
#include "uri.h"
namespace OHOS {
namespace MiscServices {
using json = nlohmann::json;
std::mutex EnableImeDataParser::instanceMutex_;
sptr<EnableImeDataParser> EnableImeDataParser::instance_ = nullptr;
namespace {
constexpr const char *SETTING_COLUMN_KEYWORD = "KEYWORD";
constexpr const char *SETTING_COLUMN_VALUE = "VALUE";
constexpr const char *SETTING_URI_PROXY = "datashare:///com.ohos.settingsdata/entry/settingsdata/"
"SETTINGSDATA?Proxy=true";
constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
} // namespace
EnableImeDataParser::~EnableImeDataParser()
{
remoteObj_ = nullptr;
@ -163,35 +159,6 @@ bool EnableImeDataParser::ReleaseDataShareHelper(std::shared_ptr<DataShare::Data
return true;
}
int32_t EnableImeDataParser::GetNextSwitchInfo(SwitchInfo &switchInfo, const int32_t userId)
{
IMSA_HILOGD("Run in.");
std::vector<std::string> enableVec;
int32_t ret = GetEnableData(ENABLE_IME, enableVec, userId);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("Get enable list abnormal.");
return ret;
}
enableVec.insert(enableVec.begin(), GetDefaultIme()->name);
auto currentIme = ImeInfoInquirer::GetInstance().GetCurrentInputMethod(userId);
switchInfo.bundleName = GetDefaultIme()->name;
switchInfo.subName = "";
auto iter = std::find_if(
enableVec.begin(), enableVec.end(), [&currentIme](const std::string &ime) { return currentIme->name == ime; });
if (iter == enableVec.end()) {
IMSA_HILOGW("Enable list is not contain current ime, get default ime.");
return ErrorCode::NO_ERROR;
}
auto nextIter = std::next(iter);
if (nextIter == enableVec.end()) {
IMSA_HILOGW("Current ime is last ime in enable list, get default ime.");
return ErrorCode::NO_ERROR;
}
switchInfo.bundleName = *nextIter;
return ErrorCode::NO_ERROR;
}
bool EnableImeDataParser::CheckNeedSwitch(const std::string &key, SwitchInfo &switchInfo, const int32_t userId)
{
IMSA_HILOGD("Run in, data changed.");
@ -200,6 +167,7 @@ bool EnableImeDataParser::CheckNeedSwitch(const std::string &key, SwitchInfo &sw
switchInfo.subName = "";
if (key == std::string(ENABLE_IME)) {
if (currentIme->name == GetDefaultIme()->name) {
GetEnableData(key, enableList_[key], userId);
IMSA_HILOGD("Current ime is default, do not need switch ime.");
return false;
}
@ -207,6 +175,7 @@ bool EnableImeDataParser::CheckNeedSwitch(const std::string &key, SwitchInfo &sw
} else if (key == std::string(ENABLE_KEYBOARD)) {
if (currentIme->name != GetDefaultIme()->name || currentIme->id == GetDefaultIme()->id) {
IMSA_HILOGD("Current ime is not default or id is default.");
GetEnableData(key, enableList_[key], userId);
return false;
}
switchInfo.subName = GetDefaultIme()->id;
@ -224,7 +193,7 @@ bool EnableImeDataParser::CheckNeedSwitch(const SwitchInfo &info, const int32_t
int32_t ret = 0;
if (info.bundleName == GetDefaultIme()->name) {
IMSA_HILOGD("Check ime keyboard.");
if (info.subName == GetDefaultIme()->id) {
if (info.subName == GetDefaultIme()->id || info.subName.empty()) {
return true;
}
targetName = info.subName;
@ -299,44 +268,63 @@ int32_t EnableImeDataParser::GetEnableData(
return ErrorCode::ERROR_ENABLE_IME;
}
IMSA_HILOGD("key: %{public}s.", key.c_str());
IMSA_HILOGD("userId: %{public}d, key: %{public}s.", userId, key.c_str());
std::string valueStr;
int32_t ret = GetStringValue(key, valueStr);
if (ret != ErrorCode::NO_ERROR) {
return ret;
if (ret != ErrorCode::NO_ERROR || valueStr.empty()) {
IMSA_HILOGW("Get value failed, or valueStr is empty");
return ErrorCode::ERROR_ENABLE_IME;
}
if (!ParseJsonData(key, valueStr, enableVec, userId)) {
IMSA_HILOGE("valueStr is empty");
return ErrorCode::ERROR_ENABLE_IME;
}
return ErrorCode::NO_ERROR;
}
bool EnableImeDataParser::ParseJsonData(
const std::string &key, const std::string &valueStr, std::vector<std::string> &enableVec, const int32_t userId)
{
IMSA_HILOGD("valueStr: %{public}s.", valueStr.c_str());
if (valueStr.empty()) {
IMSA_HILOGW("valueStr is empty");
return ErrorCode::NO_ERROR;
}
json jsonEnableData = json::parse(valueStr.c_str());
if (jsonEnableData.is_null() || jsonEnableData.is_discarded()) {
IMSA_HILOGE("json parse failed.");
return ErrorCode::ERROR_ENABLE_IME;
return false;
}
std::string listName = GetJsonListName(key);
if (listName.empty()) {
IMSA_HILOGE("Get list name failed.");
return false;
}
if (!jsonEnableData.contains("enableImeList") || !jsonEnableData["enableImeList"].is_object()) {
IMSA_HILOGE("enableImeList not find or abnormal");
return ErrorCode::ERROR_ENABLE_IME;
if (!jsonEnableData.contains(listName) || !jsonEnableData[listName].is_object()) {
IMSA_HILOGE("listName not find or abnormal");
return false;
}
std::string id = std::to_string(userId);
if (!jsonEnableData["enableImeList"].contains(id) || !jsonEnableData["enableImeList"][id].is_array()) {
if (!jsonEnableData[listName].contains(id) || !jsonEnableData[listName][id].is_array()) {
IMSA_HILOGE("user id not find or abnormal");
return ErrorCode::ERROR_ENABLE_IME;
return false;
}
std::vector<std::string> enableVecTemp;
for (const auto &bundleName : jsonEnableData["enableImeList"][id]) {
for (const auto &bundleName : jsonEnableData[listName][id]) {
IMSA_HILOGD("enable ime string: %{public}s", std::string(bundleName).c_str());
enableVecTemp.push_back(bundleName);
}
enableVec.assign(enableVecTemp.begin(), enableVecTemp.end());
return true;
}
return ErrorCode::NO_ERROR;
const std::string EnableImeDataParser::GetJsonListName(const std::string &key)
{
if (key == std::string(ENABLE_IME)) {
return "enableImeList";
} else if (key == std::string(ENABLE_KEYBOARD)) {
return "enableKeyboardList";
}
return "";
}
int32_t EnableImeDataParser::GetStringValue(const std::string &key, std::string &value)

View File

@ -97,8 +97,9 @@ enum {
ERROR_ADD_DEATH_RECIPIENT_FAILED = 23,
ERROR_STATUS_SYSTEM_PERMISSION = 24, // not system application
ERROR_IME = 25,
ERROR_KEYWORD_NOT_FOUND = 26,
ERROR_ENABLE_IME = 27,
ERROR_PARAMETER_CHECK_FAILED = 26,
ERROR_KEYWORD_NOT_FOUND = 27,
ERROR_ENABLE_IME = 28,
};
}; // namespace ErrorCode

View File

@ -24,6 +24,7 @@
#include <vector>
#include "bundle_mgr_proxy.h"
#include "enable_ime_data_parser.h"
#include "input_method_info.h"
#include "input_method_property.h"
#include "input_method_status.h"
@ -69,6 +70,7 @@ public:
int32_t ListInputMethodSubtype(
const int32_t userId, const std::string &bundleName, std::vector<SubProperty> &subProps);
int32_t ListCurrentInputMethodSubtype(const int32_t userId, std::vector<SubProperty> &subProps);
int32_t GetNextSwitchInfo(SwitchInfo &switchInfo, const int32_t userId, bool enableOn);
private:
ImeInfoInquirer() = default;

View File

@ -20,7 +20,6 @@
#include "application_info.h"
#include "bundle_mgr_client_impl.h"
#include "enable_ime_data_parser.h"
#include "global.h"
#include "if_system_ability_manager.h"
#include "ime_cfg_manager.h"
@ -351,6 +350,30 @@ 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)
{
std::vector<Property> props = {};
switchInfo.bundleName = ImeInfoInquirer::GetInstance().GetDefaultImeInfo(userId)->prop.name;
switchInfo.subName = "";
auto ret = ListEnabledInputMethod(userId, props, enableOn);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("userId: %{public}d ListEnabledInputMethod failed", userId);
return ret;
}
auto currentImeBundle = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId)->bundleName;
auto iter = std::find_if(props.begin(), props.end(),
[&currentImeBundle](const Property &property) { return property.name == currentImeBundle; });
if (iter == props.end()) {
IMSA_HILOGE("Can not found current ime");
} else {
auto nextIter = std::next(iter);
if (nextIter != props.end()) {
switchInfo.bundleName = nextIter->name;
}
}
return ErrorCode::NO_ERROR;
}
int32_t ImeInfoInquirer::ListInputMethodSubtype(
const int32_t userId, const std::string &bundleName, std::vector<SubProperty> &subProps)
{

View File

@ -379,9 +379,7 @@ int32_t InputMethodSystemAbility::DisplayOptionalInputMethod()
int32_t InputMethodSystemAbility::SwitchInputMethod(const std::string &bundleName, const std::string &subName)
{
SwitchInfo switchInfo;
switchInfo.bundleName = bundleName;
switchInfo.subName = subName;
SwitchInfo switchInfo = { std::chrono::system_clock::now(), bundleName, subName };
if (enableImeOn_ && !EnableImeDataParser::GetInstance()->CheckNeedSwitch(switchInfo, userId_)) {
IMSA_HILOGW("Enable mode off or switch is not enable, stoped!");
return ErrorCode::ERROR_ENABLE_IME;
@ -587,6 +585,9 @@ int32_t InputMethodSystemAbility::OnUserStarted(const Message *msg)
return ErrorCode::NO_ERROR;
}
IMSA_HILOGI("%{public}d switch to %{public}d.", oldUserId, userId_);
if (enableImeOn_) {
EnableImeDataParser::GetInstance()->OnUserChanged(userId_);
}
auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(oldUserId)->imeId;
StopInputService(currentIme);
// user switch, reset currentImeInfo_ = nullptr
@ -741,36 +742,14 @@ int32_t InputMethodSystemAbility::SwitchLanguage()
int32_t InputMethodSystemAbility::SwitchType()
{
SwitchInfo switchInfo;
if (enableImeOn_) {
int32_t ret = EnableImeDataParser::GetInstance()->GetNextSwitchInfo(switchInfo, userId_);
if (ret != ErrorCode::NO_ERROR) {
return ret;
}
switchInfo.timestamp = std::chrono::system_clock::now();
} else {
std::vector<Property> props = {};
auto ret = ImeInfoInquirer::GetInstance().ListInputMethod(userId_, ALL, props, false);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("ListProperty failed");
return ret;
}
auto currentImeBundle = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName;
auto iter = std::find_if(props.begin(), props.end(),
[&currentImeBundle](const Property &property) { return property.name == currentImeBundle; });
switchInfo.bundleName = ImeInfoInquirer::GetInstance().GetDefaultImeInfo(userId_)->prop.name;
if (iter == props.end()) {
IMSA_HILOGE("Can not found current ime");
} else {
auto nextIter = std::next(iter);
if (nextIter != props.end()) {
switchInfo.bundleName = nextIter->name;
}
}
switchInfo.subName = "";
switchInfo.timestamp = std::chrono::system_clock::now();
SwitchInfo switchInfo = { std::chrono::system_clock::now(), "", "" };
int32_t ret = ImeInfoInquirer::GetInstance().GetNextSwitchInfo(switchInfo, userId_, enableImeOn_);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("Get next SwitchInfo failed, stop switching ime.");
return ret;
}
IMSA_HILOGD("switch to: %{public}s", switchInfo.bundleName.c_str());
switchInfo.timestamp = std::chrono::system_clock::now();
switchQueue_.Push(switchInfo);
return OnSwitchInputMethod(switchInfo, false);
}

View File

@ -24,6 +24,7 @@
namespace OHOS {
namespace DataShare {
constexpr int32_t E_OK = 0;
class DataSharePredicates {
public:
DataSharePredicates *EqualTo(const std::string &field, const std::string &value);

View File

@ -29,7 +29,6 @@
namespace OHOS {
namespace MiscServices {
using BRemoteObject = IPCObjectStub;
#define LOG_INFO(fmt, args...) \
@ -66,10 +65,6 @@ constexpr int32_t ERROR_ENABLE_IME = 27;
}; // namespace ErrorCode
namespace DataShare {
constexpr int32_t E_OK = 0;
}; // namespace DataShare
constexpr HiviewDFX::HiLogLabel g_SMALL_SERVICES_LABEL = { LOG_CORE, 0xD001C00, "ImsaKit" };
#define IMSA_HILOGD(fmt, ...) \

View File

@ -121,7 +121,7 @@ HWTEST_F(EnableImeDataParseTest, testGetEnableData_002, TestSize.Level0)
HWTEST_F(EnableImeDataParseTest, testGetEnableData_003, TestSize.Level0)
{
IMSA_HILOGI("EnableImeDataParseTest testGetEnableData_003 START");
EnableImeDataParseTest::resultSet_->strValue_ = "";
EnableImeDataParseTest::resultSet_->strValue_ = "{\"enableImeList\" : {\"100\" : []}}";
std::vector<std::string> enableVec;
int32_t ret =
EnableImeDataParser::GetInstance()->GetEnableData(IME_KEY, enableVec, EnableImeDataParseTest::USER_ID);
@ -350,7 +350,7 @@ HWTEST_F(EnableImeDataParseTest, testCheckNeedSwitch_012, TestSize.Level0)
IMSA_HILOGI("EnableImeDataParseTest testCheckNeedSwitch_005 START");
ImeInfoInquirer::GetInstance().GetCurrentInputMethod(USER_ID)->name = "xiaoyiIme";
ImeInfoInquirer::GetInstance().GetCurrentInputMethod(USER_ID)->id = "xiaoyiImeId";
EnableImeDataParseTest::resultSet_->strValue_ = "";
EnableImeDataParseTest::resultSet_->strValue_ = "{\"enableImeList\" : {\"100\" : []}}";
SwitchInfo switchInfo;
EnableImeDataParser::GetInstance()->enableList_[IME_KEY].push_back("xiaoyiIme");
EnableImeDataParser::GetInstance()->enableList_[IME_KEY].push_back("baiduIme");
@ -393,79 +393,6 @@ HWTEST_F(EnableImeDataParseTest, testCheckNeedSwitch_013, TestSize.Level0)
}
}
/**
* @tc.name: testGetNextSwitchInfo_001
* @tc.desc: Get next enable ime info when enable list is empty.
* @tc.type: FUNC
* @tc.require:
* @tc.author: mashaoyin
*/
HWTEST_F(EnableImeDataParseTest, testGetNextSwitchInfo_001, TestSize.Level0)
{
IMSA_HILOGI("EnableImeDataParseTest testGetNextSwitchInfo_001 START");
SwitchInfo switchInfo;
EnableImeDataParseTest::resultSet_->strValue_ = "";
int32_t ret = EnableImeDataParser::GetInstance()->GetNextSwitchInfo(switchInfo, USER_ID);
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
EXPECT_EQ(switchInfo.bundleName, EnableImeDataParser::GetInstance()->defaultImeInfo_->name);
}
/**
* @tc.name: testGetNextSwitchInfo_002
* @tc.desc: Get next enable ime info when the current ime is default.
* @tc.type: FUNC
* @tc.require:
* @tc.author: mashaoyin
*/
HWTEST_F(EnableImeDataParseTest, testGetNextSwitchInfo_002, TestSize.Level0)
{
IMSA_HILOGI("EnableImeDataParseTest testGetNextSwitchInfo_002 START");
SwitchInfo switchInfo;
EnableImeDataParseTest::resultSet_->strValue_ = "{\"enableImeList\" : {\"100\" : [ \"xiaoyiIme\", \"baiduIme\", "
"\"sougouIme\"],\"101\" : [\"sougouIme\"]}}";
int32_t ret = EnableImeDataParser::GetInstance()->GetNextSwitchInfo(switchInfo, USER_ID);
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
EXPECT_EQ(switchInfo.bundleName, "xiaoyiIme");
}
/**
* @tc.name: testGetNextSwitchInfo_003
* @tc.desc: Get next enable ime info when the current ime is the first.
* @tc.type: FUNC
* @tc.require:
* @tc.author: mashaoyin
*/
HWTEST_F(EnableImeDataParseTest, testGetNextSwitchInfo_003, TestSize.Level0)
{
IMSA_HILOGI("EnableImeDataParseTest testGetNextSwitchInfo_003 START");
SwitchInfo switchInfo;
ImeInfoInquirer::GetInstance().GetCurrentInputMethod(USER_ID)->name = "xiaoyiIme";
EnableImeDataParseTest::resultSet_->strValue_ = "{\"enableImeList\" : {\"100\" : [ \"xiaoyiIme\", \"baiduIme\", "
"\"sougouIme\"],\"101\" : [\"sougouIme\"]}}";
int32_t ret = EnableImeDataParser::GetInstance()->GetNextSwitchInfo(switchInfo, USER_ID);
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
EXPECT_EQ(switchInfo.bundleName, "baiduIme");
}
/**
* @tc.name: testGetNextSwitchInfo_004
* @tc.desc: Get next enable ime info when the current ime is the last.
* @tc.type: FUNC
* @tc.require:
* @tc.author: mashaoyin
*/
HWTEST_F(EnableImeDataParseTest, testGetNextSwitchInfo_004, TestSize.Level0)
{
IMSA_HILOGI("EnableImeDataParseTest testGetNextSwitchInfo_004 START");
SwitchInfo switchInfo;
ImeInfoInquirer::GetInstance().GetCurrentInputMethod(USER_ID)->name = "sougouIme";
EnableImeDataParseTest::resultSet_->strValue_ = "{\"enableImeList\" : {\"100\" : [ \"xiaoyiIme\", \"baiduIme\", "
"\"sougouIme\"],\"101\" : [\"sougouIme\"]}}";
int32_t ret = EnableImeDataParser::GetInstance()->GetNextSwitchInfo(switchInfo, USER_ID);
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
EXPECT_EQ(switchInfo.bundleName, EnableImeDataParser::GetInstance()->defaultImeInfo_->name);
}
/**
* @tc.name: testOnUserChanged_001
* @tc.desc: Test local enable list cache change when user changed.