nlohmann to cjson

Signed-off-by: cy7717 <chenyu301@huawei.com>
This commit is contained in:
cy7717 2024-02-07 19:12:57 +08:00
parent 971be8d98b
commit 3afc34d9bf
25 changed files with 678 additions and 537 deletions

View File

@ -51,7 +51,7 @@
"data_share"
],
"third_party": [
"jsoncpp"
"cJSON"
]
},
"build": {

View File

@ -28,7 +28,6 @@ config("inputmethod_services_native_config") {
"${inputmethod_path}/services/adapter/system_language_observer/include",
"${inputmethod_path}/services/adapter/wms_connection_monitor/include",
"${inputmethod_path}/services/identity_checker/include",
"${inputmethod_path}/services/dfx/include",
]
cflags_cc = [ "-fexceptions" ]
@ -58,7 +57,6 @@ ohos_shared_library("inputmethod_service") {
"src/ime_info_inquirer.cpp",
"src/input_control_channel_proxy.cpp",
"src/input_control_channel_stub.cpp",
"src/input_method_config_parser.cpp",
"src/input_method_system_ability.cpp",
"src/input_method_system_ability_stub.cpp",
"src/input_type_manager.cpp",
@ -76,6 +74,9 @@ ohos_shared_library("inputmethod_service") {
"${inputmethod_path}/services/adapter/keyboard:keboard_event_static",
"${inputmethod_path}/services/adapter/settings_data_provider:settings_data_static",
"${inputmethod_path}/services/dfx:inputmethod_dfx_static",
"${inputmethod_path}/services/file:imf_file_static",
"${inputmethod_path}/services/json:imf_json_static",
"//third_party/cJSON:cjson"
]
external_deps = [

View File

@ -19,6 +19,7 @@ config("settings_data_config") {
"include",
"${inputmethod_path}/services/include",
"${inputmethod_path}/services/adapter/settings_data_provider/common/include",
"${inputmethod_path}/services/json/include",
"${inputmethod_path}/frameworks/native/inputmethod_controller/include",
"${inputmethod_path}/frameworks/native/inputmethod_ability/include",
]
@ -41,7 +42,10 @@ ohos_static_library("settings_data_static") {
public_configs = [ ":settings_data_config" ]
cflags_cc = [ "-fvisibility=hidden" ]
deps = [
"${inputmethod_path}/services/json:imf_json_static",
"//third_party/cJSON:cjson"
]
external_deps = [
"ability_base:zuri",
"ability_runtime:dataobs_manager",

View File

@ -22,7 +22,6 @@
namespace OHOS {
namespace MiscServices {
using json = nlohmann::json;
std::mutex SettingsDataUtils::instanceMutex_;
sptr<SettingsDataUtils> SettingsDataUtils::instance_ = nullptr;
constexpr const char *SETTING_COLUMN_KEYWORD = "KEYWORD";

View File

@ -58,7 +58,7 @@ private:
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);
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();

View File

@ -18,12 +18,12 @@
#include "ime_info_inquirer.h"
#include "iservice_registry.h"
#include "nlohmann/json.hpp"
#include "serializable.h"
#include "settings_data_utils.h"
#include "system_ability_definition.h"
namespace OHOS {
namespace MiscServices {
using json = nlohmann::json;
std::mutex EnableImeDataParser::instanceMutex_;
sptr<EnableImeDataParser> EnableImeDataParser::instance_ = nullptr;
EnableImeDataParser::~EnableImeDataParser()
@ -201,37 +201,20 @@ 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());
json jsonEnableData = json::parse(valueStr.c_str());
if (jsonEnableData.is_null() || jsonEnableData.is_discarded()) {
IMSA_HILOGE("json parse failed.");
return false;
}
std::string listName = GetJsonListName(key);
if (listName.empty()) {
auto name = GetJsonListName(key);
if (name.empty()) {
IMSA_HILOGE("Get list name failed.");
return false;
}
if (!jsonEnableData.contains(listName) || !jsonEnableData[listName].is_object()) {
IMSA_HILOGE("listName not find or abnormal");
auto root = Serializable::ToJson(valueStr);
if (root == nullptr) {
return false;
}
std::string id = std::to_string(userId);
if (!jsonEnableData[listName].contains(id) || !jsonEnableData[listName][id].is_array()) {
IMSA_HILOGE("user id not find or abnormal");
return false;
}
std::vector<std::string> enableVecTemp;
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;
std::vector<std::string> names{ name, GET_NAME(userId) };
return Serializable::GetValue(root, names, enableVec);
}
const std::string EnableImeDataParser::GetJsonListName(const std::string &key)
std::string EnableImeDataParser::GetJsonListName(const std::string &key)
{
if (key == std::string(ENABLE_IME)) {
return "enableImeList";

View File

@ -19,12 +19,11 @@
#include "input_method_utils.h"
#include "iservice_registry.h"
#include "nlohmann/json.hpp"
#include "serializable.h"
#include "settings_data_utils.h"
#include "system_ability_definition.h"
namespace OHOS {
namespace MiscServices {
using json = nlohmann::json;
std::mutex SecurityModeParser::instanceMutex_;
sptr<SecurityModeParser> SecurityModeParser::instance_ = nullptr;
@ -78,30 +77,21 @@ bool SecurityModeParser::IsSecurityChange(const std::string bundleName, const in
return oldExit!= onewExit;
}
bool SecurityModeParser::ParseJsonData(const std::string& valueStr, const int32_t userId)
bool SecurityModeParser::ParseJsonData(const std::string &valueStr, const int32_t userId)
{
IMSA_HILOGD("valueStr: %{public}s.", valueStr.c_str());
json jsonData = json::parse(valueStr.c_str());
if (jsonData.is_null() || jsonData.is_discarded()) {
IMSA_HILOGE("json parse failed.");
auto root = Serializable::ToJson(valueStr);
if (root == nullptr) {
return false;
}
if (!jsonData.contains(SECURITY_KEY) || !jsonData[SECURITY_KEY].is_object()) {
IMSA_HILOGE("listName not find or abnormal");
return false;
}
std::string id = std::to_string(userId);
if (!jsonData[SECURITY_KEY].contains(id) || !jsonData[SECURITY_KEY][id].is_array()) {
IMSA_HILOGE("user id not find or abnormal");
return false;
}
std::vector<std::string> vecTemp;
for (const auto& bundleName : jsonData[SECURITY_KEY][id]) {
IMSA_HILOGD(" full mode app is : %{public}s.", std::string(bundleName).c_str());
vecTemp.push_back(bundleName);
std::vector<std::string> lists;
std::vector<std::string> names{ SECURITY_KEY, GET_NAME(userId) };
auto ret = Serializable::GetValue(root, names, lists);
if (!ret) {
return ret;
}
std::lock_guard<std::mutex> autoLock(listMutex_);
fullModeList_.assign(vecTemp.begin(), vecTemp.end());
fullModeList_.assign(lists.begin(), lists.end());
return true;
}

45
services/file/BUILD.gn Normal file
View File

@ -0,0 +1,45 @@
# Copyright (c) 2024 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.
import("//base/inputmethod/imf/inputmethod.gni")
import("//build/ohos.gni")
config("imf_file_config") {
include_dirs = [
"include",
"${inputmethod_path}/services/include",
]
}
ohos_static_library("imf_file_static") {
branch_protector_ret = "pac_ret"
sanitize = {
cfi = true
cfi_cross_dso = true
debug = false
}
sources = [
"src/file_operator.cpp",
]
public_configs = [ ":imf_file_config" ]
cflags_cc = [ "-fvisibility=hidden" ]
external_deps = [
"config_policy:configpolicy_util",
"c_utils:utils",
"hilog:libhilog",
]
subsystem_name = "inputmethod"
part_name = "imf"
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2024 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 IMF_SERVICES_INCLUDE_FILE_OPERATOR_H
#define IMF_SERVICES_INCLUDE_FILE_OPERATOR_H
#include <fcntl.h>
#include <sys/types.h>
#include <string>
#include "config_policy_utils.h"
namespace OHOS {
namespace MiscServices {
class FileOperator {
public:
static constexpr const char *IME_INPUT_TYPE_CFG_FILE_PATH = "etc/inputmethod/inputmethod_framework_config.json";
static constexpr uint32_t MAX_FILE_LENGTH = 1000000; //todo 這個長度是否夠
static int32_t Create(mode_t mode, const std::string &path);
static bool Read(mode_t mode, const std::string &path, std::string &content);
static bool Write(
int32_t flags, const std::string &path, const std::string &content, mode_t mode = S_IRUSR | S_IWUSR);
static bool IsExist(const std::string &path);
static std::string GetContentFromSysCfgFiles(const std::string &key);
private:
static CfgFiles *GetSysCfgFiles(const std::string &path);
static bool GetContentFromSysCfgFile(const std::string &path, const std::string &key, std::string &content);
};
} // namespace MiscServices
} // namespace OHOS
#endif // IMF_SERVICES_INCLUDE_FILE_OPERATOR_H

View File

@ -0,0 +1,129 @@
/*
* Copyright (c) 2024 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 "file_operator.h"
#include <sys/stat.h>
#include <unistd.h>
#include "global.h"
namespace OHOS {
namespace MiscServices {
int32_t FileOperator::Create(mode_t mode, const std::string &path)
{
return mkdir(path.c_str(), mode);
}
bool FileOperator::IsExist(const std::string &path)
{
return access(path.c_str(), F_OK) == 0;
}
bool FileOperator::Read(mode_t mode, const std::string &path, std::string &content)
{
auto fd = open(path.c_str(), mode);
if (fd <= 0) {
IMSA_HILOGE("file open failed, fd: %{public}d", fd);
return false;
}
char contentTemp[MAX_FILE_LENGTH] = { 0 };
auto ret = read(fd, contentTemp, MAX_FILE_LENGTH);
if (ret <= 0) {
IMSA_HILOGE("file read failed, ret: %{public}zd", ret);
close(fd);
return false;
}
close(fd);
if (contentTemp[0] == '\0') {
IMSA_HILOGE("content is empty");
return false;
}
content = contentTemp;
IMSA_HILOGD("content: %{public}s", content.c_str());
return true;
}
bool FileOperator::Write(int32_t flags, const std::string &path, const std::string &content, mode_t mode)
{
IMSA_HILOGD("content: %{public}s", content.c_str());
auto fd = open(path.c_str(), flags, mode);
if (fd <= 0) {
IMSA_HILOGE("file open failed, fd: %{public}d", fd);
return false;
}
auto ret = write(fd, content.c_str(), content.size());
if (ret <= 0) {
IMSA_HILOGE("file write failed, ret: %{public}zd", ret);
close(fd);
return false;
}
close(fd);
return true;
}
std::string FileOperator::GetContentFromSysCfgFiles(const std::string &key)
{
std::string content;
CfgFiles *cfgFiles = GetSysCfgFiles(IME_INPUT_TYPE_CFG_FILE_PATH);
if (cfgFiles == nullptr) {
IMSA_HILOGE("cfgFiles is nullptr");
return content;
}
// 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;
}
char realPath[PATH_MAX + 1] = { 0x00 };
if (strlen(path) == 0 || strlen(path) > PATH_MAX || realpath(path, realPath) == nullptr) {
IMSA_HILOGE("failed to get realpath");
continue;
}
std::string cfgPath(realPath);
std::string contentTemp;
if (!GetContentFromSysCfgFile(cfgPath, key, contentTemp)) {
continue;
}
content = std::move(contentTemp);
}
FreeCfgFiles(cfgFiles);
IMSA_HILOGI("content: %{public}s", content.c_str());
return content;
}
CfgFiles *FileOperator::GetSysCfgFiles(const std::string &path)
{
return GetCfgFiles(IME_INPUT_TYPE_CFG_FILE_PATH);
}
bool FileOperator::GetContentFromSysCfgFile(const std::string &path, const std::string &key, std::string &content)
{
std::string contentTemp;
bool ret = Read(O_RDONLY, path, contentTemp);
if (!ret) {
IMSA_HILOGE("failed");
return false;
}
if (contentTemp.find(key) == std::string::npos) {
IMSA_HILOGE("not contain %{public}s", key.c_str());
return false;
}
content = std::move(contentTemp);
return true;
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -20,17 +20,13 @@
#include <sys/time.h>
#include <time.h>
#include <functional>
#include "hilog/log.h"
#include "ipc_object_stub.h"
#include "iremote_broker.h"
#include "peer_holder.h"
#include "refbase.h"
namespace OHOS {
namespace MiscServices {
using BRemoteObject = IPCObjectStub;
#define LOG_INFO(fmt, args...) \
LogTimeStamp(); \
printf("I %s:%d %s - " fmt, basename(__FILE__), __LINE__, __FUNCTION__, ##args)

View File

@ -23,7 +23,7 @@
#include <string>
#include <vector>
#include "nlohmann/json.hpp"
#include "serializable.h"
namespace OHOS {
namespace MiscServices {
struct ImePersistCfg {
@ -31,6 +31,20 @@ struct ImePersistCfg {
int32_t userId{ INVALID_USERID };
std::string currentIme;
std::string currentSubName;
bool SetValue(cJSON *node) const
{
Serializable::SetValue(node, GET_NAME(userId), userId);
Serializable::SetValue(node, GET_NAME(currentIme), currentIme);
Serializable::SetValue(node, GET_NAME(currentSubName), currentSubName);
return true;
}
bool GetValue(cJSON *node)
{
Serializable::GetValue(node, GET_NAME(userId), userId);
Serializable::GetValue(node, GET_NAME(userId), currentIme);
Serializable::GetValue(node, GET_NAME(userId), currentSubName);
return true;
}
};
struct ImeNativeCfg {
@ -55,29 +69,8 @@ private:
void ReadImeCfg();
void WriteImeCfg();
ImePersistCfg GetImeCfg(int32_t userId);
static int32_t Create(std::string &path, mode_t pathMode);
static bool IsExist(std::string &path);
static bool Read(const std::string &path, nlohmann::json &jsonCfg);
static bool Write(const std::string &path, const nlohmann::json &jsonCfg);
inline static void FromJson(const nlohmann::json &jsonCfg, ImePersistCfg &cfg)
{
if (jsonCfg.find("userId") != jsonCfg.end() && jsonCfg["userId"].is_number()) {
jsonCfg.at("userId").get_to(cfg.userId);
}
if (jsonCfg.find("currentIme") != jsonCfg.end() && jsonCfg["currentIme"].is_string()) {
jsonCfg.at("currentIme").get_to(cfg.currentIme);
}
if (jsonCfg.find("currentSubName") != jsonCfg.end() && jsonCfg["currentSubName"].is_string()) {
jsonCfg.at("currentSubName").get_to(cfg.currentSubName);
}
}
inline static void ToJson(nlohmann::json &jsonCfg, const ImePersistCfg &cfg)
{
jsonCfg = nlohmann::json{ { "userId", cfg.userId }, { "currentIme", cfg.currentIme },
{ "currentSubName", cfg.currentSubName } };
}
static void FromJson(const nlohmann::json &jsonConfigs, std::vector<ImePersistCfg> &configs);
static void ToJson(nlohmann::json &jsonConfigs, const std::vector<ImePersistCfg> &configs);
bool ParseImeCfg(const std::string &content);
bool PackageImeCfg(std::string &content);
std::recursive_mutex imeCfgLock_;
std::vector<ImePersistCfg> imeConfigs_;
};

View File

@ -30,7 +30,6 @@
#include "input_method_info.h"
#include "input_method_property.h"
#include "input_method_status.h"
#include "nlohmann/json.hpp"
#include "refbase.h"
namespace OHOS {
namespace MiscServices {
@ -50,11 +49,37 @@ enum class Condition {
CHINESE,
};
struct SubtypeCfg {
std::string label; // the label of subtype
std::string id; // the name of subtype
std::string icon; // the icon of subtype
std::string mode; // the mode of subtype, containing "upper" and "lower"
std::string locale; // the tongues of subtype, such as "zh_CN", "en_US", etc.
bool GetValue(cJSON *node)
{
Serializable::GetValue(node, GET_NAME(label), label);
Serializable::GetValue(node, GET_NAME(id), id);
Serializable::GetValue(node, GET_NAME(icon), icon);
Serializable::GetValue(node, GET_NAME(mode), mode);
Serializable::GetValue(node, GET_NAME(locale), locale);
return true;
}
};
struct ImeConfig {
std::string systemInputMethodConfigAbility;
std::string defaultInputMethod;
bool enableInputMethodFeature = false;
bool enableFullExperienceFeature = false;
bool GetValue(cJSON *node)
{
Serializable::GetValue(node, GET_NAME(systemInputMethodConfigAbility), systemInputMethodConfigAbility);
Serializable::GetValue(node, GET_NAME(defaultInputMethod), defaultInputMethod);
Serializable::GetValue(node, GET_NAME(enableInputMethodFeature), enableInputMethodFeature);
Serializable::GetValue(node, GET_NAME(enableFullExperienceFeature), enableFullExperienceFeature);
return true;
}
};
class ImeInfoInquirer {
@ -73,7 +98,7 @@ public:
void SetCurrentImeInfo(std::shared_ptr<ImeInfo> info);
void RefreshCurrentImeInfo(int32_t userId);
std::shared_ptr<SubProperty> FindTargetSubtypeByCondition(
const std::vector<SubProperty> &subProps, const Condition &condition);
const std::vector<SubProperty> &subProps, const Condition &condition);
int32_t GetDefaultInputMethod(const int32_t userId, std::shared_ptr<Property> &prop);
int32_t GetInputMethodConfig(const int32_t userId, AppExecFwk::ElementName &inputMethodConfig);
int32_t ListInputMethod(int32_t userId, InputMethodStatus status, std::vector<Property> &props, bool enableOn);
@ -109,11 +134,11 @@ private:
const std::vector<OHOS::AppExecFwk::ExtensionAbilityInfo> &extInfos, std::vector<SubProperty> &subProps);
int32_t ListInputMethodSubtype(const int32_t userId, const OHOS::AppExecFwk::ExtensionAbilityInfo &extInfo,
std::vector<SubProperty> &subProps);
bool ParseSubProp(const std::vector<std::string> &profiles, std::vector<SubProperty> &subProps);
bool ParseSubProp(const nlohmann::json &jsonSubProps, std::vector<SubProperty> &subProps);
void ParseSubProp(const nlohmann::json &jsonSubProp, SubProperty &subProp);
void ParseLanguage(const std::string &locale, std::string &language);
bool ParseSubTypeCfg(const std::vector<std::string> &profiles, std::vector<SubtypeCfg> &subtypes);
void CovertToLanguage(const std::string &locale, std::string &language);
bool QueryImeExtInfos(const int32_t userId, std::vector<OHOS::AppExecFwk::ExtensionAbilityInfo> &infos);
bool GetImeConfigFromFile(ImeConfig &imeCfg);
bool ParseImeConfig(const std::string &content, ImeConfig &imeCfg);
ImeConfig imeConfig_;
std::mutex currentImeInfoLock_;

View File

@ -1,139 +0,0 @@
/*
* 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 SERVICES_INCLUDE_IME_CONFIG_PARSE_H
#define SERVICES_INCLUDE_IME_CONFIG_PARSE_H
#include <sys/types.h>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include "global.h"
#include "config_policy_utils.h"
#include "nlohmann/json.hpp"
namespace OHOS {
namespace MiscServices {
class ImeConfigParse {
public:
static std::string ReadFile(const std::string &path);
static CfgFiles* ParseFromCustom();
static bool ParseJson(const std::string &cfgPath, const std::string &parseKey, nlohmann::json &jsonCfg);
template<typename T>
static bool ParseFromCustomSystem(const std::string &parseKey, T &data);
template<typename T>
static bool ParseFromCustomSystem(const std::string &parseKey, std::vector<T> &data);
template<typename T>
static bool GetCfgsFromFile(const std::string &cfgPath, const std::string &parseKey, T &data);
template<typename T>
static bool GetCfgsFromFile(const std::string &cfgPath, const std::string &parseKey, std::vector<T> &data);
};
template<typename T>
bool ImeConfigParse::ParseFromCustomSystem(const std::string &parseKey, T &data)
{
CfgFiles* cfgFiles = ParseFromCustom();
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, parseKey, data)) {
isSuccess = true;
break;
}
}
FreeCfgFiles(cfgFiles);
IMSA_HILOGI("parse result: %{public}d", isSuccess);
return isSuccess;
}
template<typename T>
bool ImeConfigParse::ParseFromCustomSystem(const std::string &parseKey, std::vector<T> &data)
{
CfgFiles* cfgFiles = ParseFromCustom();
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, parseKey, data)) {
break;
}
isSuccess = true;
}
FreeCfgFiles(cfgFiles);
IMSA_HILOGI("parse result: %{public}d", isSuccess);
return isSuccess;
}
template<typename T>
bool ImeConfigParse::GetCfgsFromFile(const std::string &cfgPath, const std::string &parseKey, T &data)
{
nlohmann::json jsonCfg;
if (ParseJson(cfgPath, parseKey, jsonCfg)) {
data = jsonCfg.at(parseKey).get<T>();
return true;
}
return false;
}
template<typename T>
bool ImeConfigParse::GetCfgsFromFile(const std::string &cfgPath, const std::string &parseKey, std::vector<T> &data)
{
nlohmann::json jsonCfg;
if (ParseJson(cfgPath, parseKey, jsonCfg)) {
if (!jsonCfg.at(parseKey).is_array()) {
IMSA_HILOGE("%{public}s is not array", parseKey.c_str());
return false;
}
data = jsonCfg.at(parseKey).get<std::vector<T>>();
return true;
}
return false;
}
} // namespace MiscServices
} // namespace OHOS
#endif // SERVICES_INCLUDE_IME_CONFIG_PARSE_H

View File

@ -20,10 +20,11 @@
#include <mutex>
#include <set>
#include <string>
#include <vector>
#include "block_data.h"
#include "input_method_utils.h"
#include "nlohmann/json.hpp"
#include "serializable.h"
namespace OHOS {
namespace MiscServices {
@ -43,6 +44,15 @@ struct ImeIdentification {
struct InputTypeCfg {
InputType type{};
ImeIdentification ime;
bool GetValue(cJSON *node)
{
int32_t typeTemp = -1;
Serializable::GetValue(node, GET_NAME(inputType), typeTemp);
type = static_cast<InputType>(typeTemp);
Serializable::GetValue(node, GET_NAME(bundleName), ime.bundleName);
Serializable::GetValue(node, GET_NAME(subtypeId), ime.subName);
return true;
}
};
class InputTypeManager {
@ -58,9 +68,8 @@ public:
private:
bool Init();
bool ParseFromCustomSystem();
bool GetCfgsFromFile(const std::string &cfgPath);
std::string ReadFile(const std::string &path);
bool GetInputTypeFromFile(std::vector<InputTypeCfg> &configs);
bool ParseInputType(const std::string &content, std::vector<InputTypeCfg> &configs);
std::mutex stateLock_;
bool isStarted_{ false };
ImeIdentification currentTypeIme_;

45
services/json/BUILD.gn Normal file
View File

@ -0,0 +1,45 @@
# Copyright (c) 2024 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.
import("//base/inputmethod/imf/inputmethod.gni")
import("//build/ohos.gni")
config("imf_json_config") {
include_dirs = [
"include",
"${inputmethod_path}/services/include",
]
}
ohos_static_library("imf_json_static") {
branch_protector_ret = "pac_ret"
sanitize = {
cfi = true
cfi_cross_dso = true
debug = false
}
sources = [
"src/serializable.cpp",
]
public_configs = [ ":imf_json_config" ]
cflags_cc = [ "-fvisibility=hidden" ]
deps = ["//third_party/cJSON:cjson"]
external_deps = [
"hilog:libhilog",
]
subsystem_name = "inputmethod"
part_name = "imf"
}

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2024 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 DISTRIBUTED_RDB_SERIALIZABLE_H
#define DISTRIBUTED_RDB_SERIALIZABLE_H
#include <string>
#include <vector>
#include "cJSON.h"
namespace OHOS {
namespace MiscServices {
#ifndef GET_NAME
#define GET_NAME(value) #value
#endif
struct Serializable {
public:
static cJSON *ToJson(const std::string &jsonStr);
static std::string ToStr(cJSON *node);
static bool GetValue(cJSON *node, const std::string &name, std::string &value);
static bool GetValue(cJSON *node, const std::string &name, int32_t &value);
static bool GetValue(cJSON *node, const std::string &name, bool &value);
static bool GetValue(
cJSON *node, const std::vector<std::string> &names, std::vector<std::string> &values, uint32_t maxNum = 0);
template<typename T>
static bool GetValue(cJSON *node, const std::string &name, std::vector<T> &values, uint32_t maxNum = 0)
{
auto array = GetSubNode(node, name);
if (cJSON_IsArray(array)) {
return false;
}
auto size = cJSON_GetArraySize(array);
if (size <= 0) {
return false;
}
size = maxNum != 0 && size > maxNum ? maxNum : size;
values.resize(size);
for (int32_t i = 0; i < size; ++i) {
auto item = cJSON_GetArrayItem(array, i);
values[i].GetValue(item);
}
return true;
}
template<typename T> static bool GetValue(cJSON *node, const std::string &name, T &value)
{
auto object = GetSubNode(node, name);
if (cJSON_IsObject(object)) {
return false;
}
return value.GetValue(object);
}
static bool SetValue(cJSON *node, const std::string &name, const std::string &value);
static bool SetValue(cJSON *node, const std::string &name, const int32_t &value);
static bool SetValue(cJSON *node, const std::string &name, const bool &value);
template<typename T> static bool SetValue(cJSON *node, const std::string &name, const std::vector<T> &values)
{
auto array = cJSON_AddArrayToObject(node, name.c_str());
for (auto &value : values) {
cJSON *item = cJSON_CreateObject(); // todo 释放内存
cJSON_AddItemToArray(array, item);
value.SetValue(item);
}
return true;
}
private:
static cJSON *GetSubNode(cJSON *node, const std::string &name);
};
} // namespace MiscServices
} // namespace OHOS
#endif // DISTRIBUTED_RDB_SERIALIZABLE_H

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 2024 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 "serializable.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
cJSON *Serializable::ToJson(const std::string &jsonStr)
{
auto root = cJSON_Parse(jsonStr.c_str());
if (root == nullptr) {
IMSA_HILOGE("%{public}s: parse failed", jsonStr.c_str());
}
return root;
}
std::string Serializable::ToStr(cJSON *node)
{
return cJSON_PrintUnformatted(node);
}
bool Serializable::GetValue(cJSON *node, const std::string &name, std::string &value)
{
auto subNode = GetSubNode(node, name);
if (subNode == nullptr) {
return false;
}
if (!cJSON_IsString(subNode)) {
return false;
}
value = subNode->valuestring;
return true;
}
bool Serializable::GetValue(cJSON *node, const std::string &name, int32_t &value)
{
auto subNode = GetSubNode(node, name);
if (subNode == nullptr) {
return false;
}
if (!cJSON_IsNumber(subNode)) {
return false;
}
value = subNode->valueint;
return true;
}
bool Serializable::GetValue(cJSON *node, const std::string &name, bool &value)
{
auto subNode = GetSubNode(node, name);
if (subNode == nullptr) {
return false;
}
if (!cJSON_IsBool(subNode)) {
return false;
}
value = false;
if (subNode->type == cJSON_True) {
value = true;
}
return true;
}
bool Serializable::GetValue(
cJSON *node, const std::vector<std::string> &names, std::vector<std::string> &values, uint32_t maxNum)
{
auto subNode = node;
for (const auto &name : names) {
auto subNodeTemp = GetSubNode(subNode, name);
subNode = subNodeTemp;
}
if (cJSON_IsArray(subNode)) {
return false;
}
auto size = cJSON_GetArraySize(subNode);
if (size <= 0) {
return false;
}
size = maxNum != 0 && size > maxNum ? maxNum : size;
values.resize(size);
for (int32_t i = 0; i < size; ++i) {
auto item = cJSON_GetArrayItem(subNode, i);
values[i] = item->valuestring;
}
return true;
}
bool Serializable::SetValue(cJSON *node, const std::string &name, const std::string &value)
{
cJSON_AddStringToObject(node, name.c_str(), value.c_str());
return true;
}
bool Serializable::SetValue(cJSON *node, const std::string &name, const int32_t &value)
{
cJSON_AddNumberToObject(node, name.c_str(), value);
return true;
}
bool Serializable::SetValue(cJSON *node, const std::string &name, const bool &value)
{
cJSON_AddBoolToObject(node, name.c_str(), value);
return true;
}
cJSON *Serializable::GetSubNode(cJSON *node, const std::string &name)
{
if (!cJSON_IsObject(node)) {
IMSA_HILOGE("The json is not object");
return nullptr;
}
if (!cJSON_HasObjectItem(node, name.c_str())) {
IMSA_HILOGE("subNode: %{public}s not contain", name.c_str());
return nullptr;
}
auto *subNode = cJSON_GetObjectItem(node, name.c_str());
if (subNode == nullptr) {
IMSA_HILOGE("subNode: %{public}s is error", name.c_str());
}
return subNode;
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -16,16 +16,12 @@
#include "ime_cfg_manager.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <algorithm>
#include <cstdio>
#include <ios>
#include <string>
#include "file_ex.h"
#include "file_operator.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
@ -33,8 +29,6 @@ namespace {
constexpr const char *IME_CFG_DIR = "/data/service/el1/public/imf/ime_cfg";
constexpr const char *IME_CFG_FILE_PATH = "/data/service/el1/public/imf/ime_cfg/ime_cfg.json";
static constexpr int32_t SUCCESS = 0;
static constexpr uint32_t MAX_FILE_LENGTH = 10000;
using json = nlohmann::json;
} // namespace
ImeCfgManager &ImeCfgManager::GetInstance()
{
@ -50,39 +44,63 @@ void ImeCfgManager::Init()
void ImeCfgManager::ReadImeCfg()
{
std::string path(IME_CFG_FILE_PATH);
if (!IsExist(path)) {
if (!FileOperator::IsExist(path)) {
IMSA_HILOGD("ime cfg file not find");
return;
}
json jsonConfigs;
bool ret = Read(path, jsonConfigs);
std::string cfg;
bool ret = FileOperator::Read(O_RDONLY, path, cfg);
if (!ret) {
IMSA_HILOGE("ReadJsonFile failed");
return;
}
std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
FromJson(jsonConfigs, imeConfigs_);
ParseImeCfg(cfg);
}
void ImeCfgManager::WriteImeCfg()
{
std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
json jsonConfigs;
ToJson(jsonConfigs, imeConfigs_);
std::string content;
auto ret = PackageImeCfg(content);
if (!ret) {
return;
}
std::string path(IME_CFG_DIR);
if (!IsExist(path)) {
auto ret = Create(path, S_IRWXU);
if (!FileOperator::IsExist(path)) {
auto ret = FileOperator::Create(S_IRWXU, path);
if (ret != SUCCESS) {
IMSA_HILOGE("ime cfg dir create failed");
return;
}
}
if (!Write(IME_CFG_FILE_PATH, jsonConfigs)) {
if (!FileOperator::Write(O_CREAT | O_WRONLY | O_SYNC | O_TRUNC, IME_CFG_FILE_PATH, content)) {
IMSA_HILOGE("WriteJsonFile failed");
}
}
bool ImeCfgManager::ParseImeCfg(const std::string &content)
{
auto root = Serializable::ToJson(content);
if (root == nullptr) {
return false;
}
std::vector<ImePersistCfg> configs;
auto ret = Serializable::GetValue(root, GET_NAME(imeCfg_list), configs);
if (!ret) {
return false;
}
std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
imeConfigs_ = std::move(configs);
return true;
}
bool ImeCfgManager::PackageImeCfg(std::string &content)
{
cJSON *root = cJSON_CreateObject();
Serializable::SetValue(root, GET_NAME(imeCfg_list), imeConfigs_);
content = Serializable::ToStr(root);
return true;
}
void ImeCfgManager::AddImeCfg(const ImePersistCfg &cfg)
{
std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
@ -138,89 +156,5 @@ std::shared_ptr<ImeNativeCfg> ImeCfgManager::GetCurrentImeCfg(int32_t userId)
}
return std::make_shared<ImeNativeCfg>(info);
}
void ImeCfgManager::FromJson(const json &jsonConfigs, std::vector<ImePersistCfg> &configs)
{
if (!jsonConfigs.contains("imeCfg_list") || !jsonConfigs["imeCfg_list"].is_array()) {
IMSA_HILOGE("imeCfg_list not find or abnormal");
return;
}
for (auto &jsonCfg : jsonConfigs["imeCfg_list"]) {
ImePersistCfg cfg;
FromJson(jsonCfg, cfg);
configs.push_back(cfg);
}
}
void ImeCfgManager::ToJson(json &jsonConfigs, const std::vector<ImePersistCfg> &configs)
{
for (auto &cfg : configs) {
json jsonCfg;
ToJson(jsonCfg, cfg);
jsonConfigs["imeCfg_list"].push_back(jsonCfg);
}
}
int32_t ImeCfgManager::Create(std::string &path, mode_t pathMode)
{
return mkdir(path.c_str(), pathMode);
}
bool ImeCfgManager::IsExist(std::string &path)
{
return access(path.c_str(), F_OK) == SUCCESS;
}
bool ImeCfgManager::Read(const std::string &path, json &jsonCfg)
{
auto fd = open(path.c_str(), O_RDONLY);
if (fd <= 0) {
IMSA_HILOGE("file open failed, fd: %{public}d", fd);
return false;
}
char cfg[MAX_FILE_LENGTH] = { 0 };
auto ret = read(fd, cfg, MAX_FILE_LENGTH);
if (ret <= 0) {
IMSA_HILOGE("file read failed, ret: %{public}zd", ret);
close(fd);
return false;
}
close(fd);
if (cfg[0] == '\0') {
IMSA_HILOGE("imeCfg is empty");
return false;
}
jsonCfg = json::parse(cfg, nullptr, false);
if (jsonCfg.is_null() || jsonCfg.is_discarded()) {
IMSA_HILOGE("json parse failed.");
return false;
}
IMSA_HILOGD("imeCfg json: %{public}s", jsonCfg.dump().c_str());
return true;
}
bool ImeCfgManager::Write(const std::string &path, const json &jsonCfg)
{
std::string cfg = jsonCfg.dump();
if (cfg.empty()) {
IMSA_HILOGE("imeCfg is empty");
return false;
}
IMSA_HILOGD("imeCfg json: %{public}s", cfg.c_str());
auto fd = open(path.c_str(), O_CREAT | O_WRONLY | O_SYNC | O_TRUNC, S_IRUSR | S_IWUSR);
if (fd <= 0) {
IMSA_HILOGE("file open failed, fd: %{public}d", fd);
return false;
}
auto ret = write(fd, cfg.c_str(), cfg.size());
if (ret <= 0) {
IMSA_HILOGE("file write failed, ret: %{public}zd", ret);
close(fd);
return false;
}
close(fd);
return true;
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -20,11 +20,10 @@
#include "application_info.h"
#include "bundle_mgr_client_impl.h"
#include "config_policy_utils.h"
#include "file_operator.h"
#include "global.h"
#include "if_system_ability_manager.h"
#include "ime_cfg_manager.h"
#include "input_method_config_parser.h"
#include "input_method_info.h"
#include "input_type_manager.h"
#include "iservice_registry.h"
@ -36,39 +35,13 @@
namespace OHOS {
namespace MiscServices {
namespace {
using json = nlohmann::json;
using namespace OHOS::AppExecFwk;
constexpr const char *SUBTYPE_PROFILE_METADATA_NAME = "ohos.extension.input_method";
const std::string SYSTEM_CONFIG = "systemConfig";
const std::string SYSTEM_INPUT_METHOD_CONFIG_ABILITY = "systemInputMethodConfigAbility";
const std::string DEFAULT_INPUT_METHOD = "defaultInputMethod";
const std::string ENABLE_INPUT_METHOD_FEATURE = "enableInputMethodFeature";
const std::string ENABLE_FULL_EXPERIENCE_FEATURE = "enableFullExperienceFeature";
constexpr uint32_t SUBTYPE_PROFILE_NUM = 1;
constexpr uint32_t MAX_SUBTYPE_NUM = 256;
constexpr const char *DEFAULT_IME_KEY = "persist.sys.default_ime";
constexpr int32_t CONFIG_LEN = 128;
} // namespace
void from_json(const nlohmann::json &jsonConfigs, ImeConfig &config)
{
if (jsonConfigs.find(SYSTEM_INPUT_METHOD_CONFIG_ABILITY) != jsonConfigs.end()
&& jsonConfigs[SYSTEM_INPUT_METHOD_CONFIG_ABILITY].is_string()) {
jsonConfigs.at(SYSTEM_INPUT_METHOD_CONFIG_ABILITY).get_to(config.systemInputMethodConfigAbility);
}
if (jsonConfigs.find(DEFAULT_INPUT_METHOD) != jsonConfigs.end() && jsonConfigs[DEFAULT_INPUT_METHOD].is_string()) {
jsonConfigs.at(DEFAULT_INPUT_METHOD).get_to(config.defaultInputMethod);
}
if (jsonConfigs.find(ENABLE_INPUT_METHOD_FEATURE) != jsonConfigs.end()
&& jsonConfigs[ENABLE_INPUT_METHOD_FEATURE].is_boolean()) {
jsonConfigs.at(ENABLE_INPUT_METHOD_FEATURE).get_to(config.enableInputMethodFeature);
}
if (jsonConfigs.find(ENABLE_FULL_EXPERIENCE_FEATURE) != jsonConfigs.end()
&& jsonConfigs[ENABLE_FULL_EXPERIENCE_FEATURE].is_boolean()) {
jsonConfigs.at(ENABLE_FULL_EXPERIENCE_FEATURE).get_to(config.enableFullExperienceFeature);
}
}
ImeInfoInquirer &ImeInfoInquirer::GetInstance()
{
static ImeInfoInquirer instance;
@ -77,7 +50,26 @@ ImeInfoInquirer &ImeInfoInquirer::GetInstance()
void ImeInfoInquirer::InitConfig()
{
ImeConfigParse::ParseFromCustomSystem(SYSTEM_CONFIG, imeConfig_);
auto ret = GetImeConfigFromFile(imeConfig_);
IMSA_HILOGD("ret: %{public}d", ret);
}
bool ImeInfoInquirer::GetImeConfigFromFile(ImeConfig &imeCfg)
{
auto content = FileOperator::GetContentFromSysCfgFiles(GET_NAME(systemConfig));
if (content.empty()) {
return false;
}
return ParseImeConfig(content, imeCfg);
}
bool ImeInfoInquirer::ParseImeConfig(const std::string &content, ImeConfig &imeCfg)
{
auto root = Serializable::ToJson(content);
if (root == nullptr) {
return false;
}
return Serializable::GetValue(root, GET_NAME(systemConfig), imeCfg);
}
bool ImeInfoInquirer::IsEnableInputMethod()
@ -426,7 +418,7 @@ int32_t ImeInfoInquirer::GetNextSwitchInfo(SwitchInfo &switchInfo, int32_t userI
return ErrorCode::ERROR_PACKAGE_MANAGER;
}
auto nextIter = std::next(iter);
switchInfo.bundleName = nextIter == props.end() ? props[0].name: nextIter->name;
switchInfo.bundleName = nextIter == props.end() ? props[0].name : nextIter->name;
IMSA_HILOGD("Next ime: %{public}s", switchInfo.bundleName.c_str());
return ErrorCode::NO_ERROR;
}
@ -501,19 +493,25 @@ int32_t ImeInfoInquirer::ListInputMethodSubtype(
IMSA_HILOGE("GetProfileFromExtension failed");
return ErrorCode::ERROR_PACKAGE_MANAGER;
}
if (!ParseSubProp(profiles, subProps)) {
IMSA_HILOGE("ParseSubProp failed");
std::vector<SubtypeCfg> subtypes;
if (!ParseSubTypeCfg(profiles, subtypes)) {
IMSA_HILOGE("ParseSubTypeCfg failed");
return ErrorCode::ERROR_BAD_PARAMETERS;
}
IMSA_HILOGD("subProps size: %{public}zu", subProps.size());
for (auto it = subProps.begin(); it != subProps.end();) {
auto subProp = *it;
IMSA_HILOGD("subtypes size: %{public}zu", subtypes.size());
for (auto it = subtypes.begin(); it != subtypes.end();) {
auto subtype = *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);
if (InputTypeManager::GetInstance().IsInputType({ extInfo.bundleName, subtype.id })) {
it = subtypes.erase(it);
continue;
}
subProp.name = extInfo.bundleName;
SubProperty subProp{ .name = extInfo.bundleName,
.label = subtype.label,
.id = subtype.id,
.icon = subtype.icon,
.mode = subtype.mode,
.locale = subtype.locale };
auto pos = subProp.label.find(':');
if (pos != std::string::npos && pos + 1 < subProp.label.size()) {
subProp.labelId = atoi(subProp.label.substr(pos + 1).c_str());
@ -523,14 +521,15 @@ int32_t ImeInfoInquirer::ListInputMethodSubtype(
if (pos != std::string::npos && pos + 1 < subProp.icon.size()) {
subProp.iconId = atoi(subProp.icon.substr(pos + 1).c_str());
}
ParseLanguage(subProp.locale, subProp.language);
*it = subProp;
CovertToLanguage(subProp.locale, subProp.language);
*it = subtype;
++it;
subProps.emplace_back(subProp);
}
return ErrorCode::NO_ERROR;
}
void ImeInfoInquirer::ParseLanguage(const std::string &locale, std::string &language)
void ImeInfoInquirer::CovertToLanguage(const std::string &locale, std::string &language)
{
language = locale;
auto pos = locale.find('-');
@ -817,59 +816,17 @@ std::shared_ptr<SubProperty> ImeInfoInquirer::FindTargetSubtypeByCondition(
return std::make_shared<SubProperty>(*it);
}
bool ImeInfoInquirer::ParseSubProp(const std::vector<std::string> &profiles, std::vector<SubProperty> &subProps)
bool ImeInfoInquirer::ParseSubTypeCfg(const std::vector<std::string> &profiles, std::vector<SubtypeCfg> &subtypes)
{
if (profiles.empty() || profiles.size() != SUBTYPE_PROFILE_NUM) {
IMSA_HILOGE("profiles size: %{public}zu", profiles.size());
return false;
}
json jsonSubProps;
SubProperty subProp;
IMSA_HILOGD("profiles[0]: %{public}s", profiles[0].c_str());
jsonSubProps = json::parse(profiles[0], nullptr, false);
if (jsonSubProps.is_null() || jsonSubProps.is_discarded()) {
IMSA_HILOGE("json parse failed");
auto root = Serializable::ToJson(profiles[0]);
if (root == nullptr) {
return false;
}
return ParseSubProp(jsonSubProps, subProps);
}
bool ImeInfoInquirer::ParseSubProp(const json &jsonSubProps, std::vector<SubProperty> &subProps)
{
if (!jsonSubProps.contains("subtypes") || !jsonSubProps["subtypes"].is_array() ||
jsonSubProps["subtypes"].empty()) {
IMSA_HILOGE("the context of json file is abnormal");
return false;
}
IMSA_HILOGD("subType num: %{public}zu", jsonSubProps["subtypes"].size());
for (auto &jsonCfg : jsonSubProps["subtypes"]) {
if (subProps.size() >= MAX_SUBTYPE_NUM) {
break;
}
SubProperty subProp;
ParseSubProp(jsonCfg, subProp);
subProps.push_back(subProp);
}
return true;
}
void ImeInfoInquirer::ParseSubProp(const json &jsonSubProp, SubProperty &subProp)
{
if (jsonSubProp.find("label") != jsonSubProp.end() && jsonSubProp["label"].is_string()) {
jsonSubProp.at("label").get_to(subProp.label);
}
if (jsonSubProp.find("id") != jsonSubProp.end() && jsonSubProp["id"].is_string()) {
jsonSubProp.at("id").get_to(subProp.id);
}
if (jsonSubProp.find("icon") != jsonSubProp.end() && jsonSubProp["icon"].is_string()) {
jsonSubProp.at("icon").get_to(subProp.icon);
}
if (jsonSubProp.find("mode") != jsonSubProp.end() && jsonSubProp["mode"].is_string()) {
jsonSubProp.at("mode").get_to(subProp.mode);
}
if (jsonSubProp.find("locale") != jsonSubProp.end() && jsonSubProp["locale"].is_string()) {
jsonSubProp.at("locale").get_to(subProp.locale);
}
return Serializable::GetValue(root, GET_NAME(subtypes), subtypes, MAX_SUBTYPE_NUM);
}
std::shared_ptr<Property> ImeInfoInquirer::GetDefaultImeCfgProp()

View File

@ -1,82 +0,0 @@
/*
* 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_method_config_parser.h"
#include <algorithm>
#include <cstdio>
#include <fcntl.h>
#include <ios>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fstream>
#include "file_ex.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
namespace {
constexpr const char *IME_INPUT_TYPE_CFG_FILE_PATH = "etc/inputmethod/inputmethod_framework_config.json";
using json = nlohmann::json;
} // namespace
CfgFiles* ImeConfigParse::ParseFromCustom()
{
return GetCfgFiles(IME_INPUT_TYPE_CFG_FILE_PATH);
}
bool ImeConfigParse::ParseJson(const std::string &cfgPath, const std::string &parseKey, nlohmann::json &jsonCfg)
{
IMSA_HILOGD("in");
std::string jsonStr = ImeConfigParse::ReadFile(cfgPath);
if (jsonStr.empty()) {
IMSA_HILOGE("json config size is invalid");
return false;
}
jsonCfg = json::parse(jsonStr, nullptr, false);
if (jsonCfg.is_discarded()) {
IMSA_HILOGE("jsonStr parse failed");
return false;
}
if (!jsonCfg.contains(parseKey)) {
IMSA_HILOGE("%{public}s not find or abnormal", parseKey.c_str());
return false;
}
IMSA_HILOGD("get json: %{public}s", jsonCfg.dump().c_str());
return true;
}
std::string ImeConfigParse::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

View File

@ -30,39 +30,12 @@
#include "climits"
#include "config_policy_utils.h"
#include "input_method_config_parser.h"
#include "file_operator.h"
#include "global.h"
#include "ime_cfg_manager.h"
namespace OHOS {
namespace MiscServices {
namespace {
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<InputType>(jsonObj.at(INPUT_TYPE).get<int32_t>());
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<std::string>();
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<std::string>();
}
InputTypeManager &InputTypeManager::GetInstance()
{
static InputTypeManager instance;
@ -132,6 +105,24 @@ ImeIdentification InputTypeManager::GetCurrentIme()
return currentTypeIme_;
}
bool InputTypeManager::GetInputTypeFromFile(std::vector<InputTypeCfg> &configs)
{
auto content = FileOperator::GetContentFromSysCfgFiles(GET_NAME(supportedInputTypeList));
if (content.empty()) {
return false;
}
return ParseInputType(content, configs);
}
bool InputTypeManager::ParseInputType(const std::string &content, std::vector<InputTypeCfg> &configs)
{
auto root = Serializable::ToJson(content);
if (root == nullptr) {
return false;
}
return Serializable::GetValue(root, GET_NAME(supportedInputTypeList), configs);
}
bool InputTypeManager::Init()
{
IMSA_HILOGD("start");
@ -141,14 +132,14 @@ bool InputTypeManager::Init()
isInitInProgress_.store(true);
isInitSuccess_.Clear(false);
std::vector<InputTypeCfg> configs;
bool isSuccess = ImeConfigParse::ParseFromCustomSystem(SUPPORTED_INPUT_TYPE_LIST, configs);
IMSA_HILOGD("ParseFromCustomSystem end isSuccess %{public}d", isSuccess);
bool isSuccess = GetInputTypeFromFile(configs);
IMSA_HILOGD("GetInputTypeFromFile end isSuccess %{public}d", isSuccess);
if (isSuccess) {
std::lock_guard<std::mutex> lk(typesLock_);
for (const auto& config : configs) {
for (const auto &config : configs) {
inputTypes_.insert({ config.type, config.ime });
}
for (const auto& cfg : inputTypes_) {
for (const auto &cfg : inputTypes_) {
std::lock_guard<std::mutex> lock(listLock_);
inputTypeImeList_.insert(cfg.second);
}

View File

@ -47,7 +47,6 @@ ohos_fuzztest("PerUserSessionFuzzTest") {
"${inputmethod_path}/interfaces/inner_api/inputmethod_ability:inputmethod_ability",
"${inputmethod_path}/interfaces/inner_api/inputmethod_controller:inputmethod_client_static",
"${inputmethod_path}/services:inputmethod_service",
"//third_party/jsoncpp:jsoncpp",
]
external_deps = [

View File

@ -44,7 +44,6 @@ ohos_fuzztest("SystemAbilityStubFuzzTest") {
"${inputmethod_path}/services:inputmethod_service",
"${inputmethod_path}/services/adapter/settings_data_provider:settings_data_static",
"${inputmethod_path}/test/common:inputmethod_test_common",
"//third_party/jsoncpp:jsoncpp",
]
external_deps = [

View File

@ -44,7 +44,6 @@ ohos_static_library("imf_sa_stub_fuzztest_common_static") {
"${inputmethod_path}/services:inputmethod_service",
"${inputmethod_path}/services/adapter/settings_data_provider:settings_data_static",
"${inputmethod_path}/test/common:inputmethod_test_common",
"//third_party/jsoncpp:jsoncpp",
]
public_configs = [ ":imf_sa_stub_fuzztest_common_config" ]