• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ime_cfg_manager.h"
17 
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21 
22 #include <algorithm>
23 #include <cstdio>
24 #include <fstream>
25 #include <string>
26 
27 #include "file_ex.h"
28 #include "global.h"
29 #include "parameter.h"
30 namespace OHOS {
31 namespace MiscServices {
32 namespace {
33 constexpr const char *IME_CFG_DIR = "/data/service/el1/public/imf/ime_cfg";
34 constexpr const char *IME_CFG_FILE_PATH = "/data/service/el1/public/imf/ime_cfg/ime_cfg.json";
35 static constexpr const char *DEFAULT_IME_KEY = "persist.sys.default_ime";
36 static constexpr int32_t CONFIG_LEN = 128;
37 static constexpr int32_t SUCCESS = 0;
38 using json = nlohmann::json;
39 } // namespace
GetInstance()40 ImeCfgManager &ImeCfgManager::GetInstance()
41 {
42     static ImeCfgManager instance;
43     return instance;
44 }
45 
Init()46 void ImeCfgManager::Init()
47 {
48     std::string path(IME_CFG_DIR);
49     if (CreateCachePath(path, S_IRWXU) != SUCCESS) {
50         IMSA_HILOGE("CreateCachePath failed");
51         return;
52     }
53     ReadImeCfgFile();
54 }
55 
ReadImeCfgFile()56 void ImeCfgManager::ReadImeCfgFile()
57 {
58     json jsonConfigs;
59     bool ret = ReadCacheFile(IME_CFG_FILE_PATH, jsonConfigs);
60     if (!ret) {
61         IMSA_HILOGE("ReadJsonFile failed");
62         return;
63     }
64     std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
65     FromJson(jsonConfigs, imeConfigs_);
66 }
67 
WriteImeCfgFile()68 void ImeCfgManager::WriteImeCfgFile()
69 {
70     std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
71     json jsonConfigs;
72     ToJson(jsonConfigs, imeConfigs_);
73     if (!WriteCacheFile(IME_CFG_FILE_PATH, jsonConfigs)) {
74         IMSA_HILOGE("WriteJsonFile failed");
75     }
76 }
77 
AddImeCfg(const ImeCfg & cfg)78 void ImeCfgManager::AddImeCfg(const ImeCfg &cfg)
79 {
80     std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
81     imeConfigs_.push_back(cfg);
82     WriteImeCfgFile();
83 }
84 
ModifyImeCfg(const ImeCfg & cfg)85 void ImeCfgManager::ModifyImeCfg(const ImeCfg &cfg)
86 {
87     std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
88     for (auto &imeConfig : imeConfigs_) {
89         if (imeConfig.userId == cfg.userId && !cfg.currentIme.empty()) {
90             imeConfig.currentIme = cfg.currentIme;
91         }
92     }
93     WriteImeCfgFile();
94 }
95 
DeleteImeCfg(int32_t userId)96 void ImeCfgManager::DeleteImeCfg(int32_t userId)
97 {
98     std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
99     for (auto iter = imeConfigs_.begin(); iter != imeConfigs_.end(); iter++) {
100         if (iter->userId == userId) {
101             imeConfigs_.erase(iter);
102             break;
103         }
104     }
105     WriteImeCfgFile();
106 }
107 
GetImeCfg(int32_t userId)108 ImeCfg ImeCfgManager::GetImeCfg(int32_t userId)
109 {
110     std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
111     auto it = std::find_if(
112         imeConfigs_.begin(), imeConfigs_.end(), [userId](const ImeCfg &cfg) { return cfg.userId == userId; });
113     if (it != imeConfigs_.end()) {
114         return *it;
115     }
116     return {};
117 }
118 
GetDefaultIme()119 std::string ImeCfgManager::GetDefaultIme()
120 {
121     char value[CONFIG_LEN] = { 0 };
122     auto code = GetParameter(DEFAULT_IME_KEY, "", value, CONFIG_LEN);
123     return code > 0 ? value : "";
124 }
125 
FromJson(const json & jsonConfigs,std::vector<ImeCfg> & configs)126 void ImeCfgManager::FromJson(const json &jsonConfigs, std::vector<ImeCfg> &configs)
127 {
128     if (!jsonConfigs.contains("imeCfg_list")) {
129         IMSA_HILOGE("imeCfg_list not find");
130         return;
131     }
132     for (auto &jsonCfg : jsonConfigs["imeCfg_list"]) {
133         ImeCfg cfg;
134         FromJson(jsonCfg, cfg);
135         configs.push_back(cfg);
136     }
137 }
138 
ToJson(json & jsonConfigs,const std::vector<ImeCfg> & configs)139 void ImeCfgManager::ToJson(json &jsonConfigs, const std::vector<ImeCfg> &configs)
140 {
141     for (auto &cfg : configs) {
142         json jsonCfg;
143         ToJson(jsonCfg, cfg);
144         jsonConfigs["imeCfg_list"].push_back(jsonCfg);
145     }
146 }
147 
CreateCachePath(std::string & path,mode_t pathMode)148 int32_t ImeCfgManager::CreateCachePath(std::string &path, mode_t pathMode)
149 {
150     if (IsCachePathExit(path)) {
151         IMSA_HILOGI("dir: %{public}s exist", path.c_str());
152         return SUCCESS;
153     }
154     return mkdir(path.c_str(), pathMode);
155 }
156 
IsCachePathExit(std::string & path)157 bool ImeCfgManager::IsCachePathExit(std::string &path)
158 {
159     return access(path.c_str(), F_OK) == SUCCESS;
160 }
161 
ReadCacheFile(const std::string & path,json & jsonCfg)162 bool ImeCfgManager::ReadCacheFile(const std::string &path, json &jsonCfg)
163 {
164     std::ifstream jsonFs(path);
165     if (!jsonFs.is_open()) {
166         IMSA_HILOGE("file read open failed");
167         return false;
168     }
169     jsonCfg = json::parse(jsonFs, nullptr, false);
170     if (jsonCfg.is_null() || jsonCfg.is_discarded()) {
171         IMSA_HILOGE("json parse failed");
172         return false;
173     }
174     IMSA_HILOGI("json: %{public}s", jsonCfg.dump().c_str());
175     return true;
176 }
WriteCacheFile(const std::string & path,const json & jsonCfg)177 bool ImeCfgManager::WriteCacheFile(const std::string &path, const json &jsonCfg)
178 {
179     std::ofstream jsonFs(path);
180     if (!jsonFs.is_open()) {
181         IMSA_HILOGE("file write open failed");
182         return false;
183     }
184     constexpr int32_t width = 2;
185     jsonFs << std::setw(width) << jsonCfg << std::endl;
186     return true;
187 }
188 } // namespace MiscServices
189 } // namespace OHOS