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 <algorithm> 19#include <fcntl.h> 20#include <ios> 21#include <string> 22 23#include "file_operator.h" 24#include "global.h" 25namespace OHOS { 26namespace MiscServices { 27namespace { 28constexpr const char *IME_CFG_FILE_PATH = "/data/service/el1/public/imf/ime_cfg.json"; 29} // namespace 30ImeCfgManager &ImeCfgManager::GetInstance() 31{ 32 static ImeCfgManager instance; 33 return instance; 34} 35 36void ImeCfgManager::Init() 37{ 38 ReadImeCfg(); 39} 40 41void ImeCfgManager::ReadImeCfg() 42{ 43 if (!FileOperator::IsExist(IME_CFG_FILE_PATH)) { 44 IMSA_HILOGD("ime cfg file not found."); 45 return; 46 } 47 std::string cfg; 48 bool ret = FileOperator::Read(IME_CFG_FILE_PATH, cfg); 49 if (!ret) { 50 IMSA_HILOGE("failed to ReadJsonFile!"); 51 return; 52 } 53 ParseImeCfg(cfg); 54} 55 56void ImeCfgManager::WriteImeCfg() 57{ 58 auto content = PackageImeCfg(); 59 if (content.empty()) { 60 IMSA_HILOGE("failed to Package imeCfg!"); 61 return; 62 } 63 if (!FileOperator::Write(IME_CFG_FILE_PATH, content, O_CREAT | O_WRONLY | O_SYNC | O_TRUNC)) { 64 IMSA_HILOGE("failed to WriteJsonFile!"); 65 } 66} 67 68bool ImeCfgManager::ParseImeCfg(const std::string &content) 69{ 70 IMSA_HILOGD("content: %{public}s", content.c_str()); 71 ImePersistCfg cfg; 72 auto ret = cfg.Unmarshall(content); 73 if (!ret) { 74 IMSA_HILOGE("Unmarshall failed!"); 75 return false; 76 } 77 std::lock_guard<std::recursive_mutex> lock(imeCfgLock_); 78 imeConfigs_ = cfg.imePersistInfo; 79 return true; 80} 81 82std::string ImeCfgManager::PackageImeCfg() 83{ 84 ImePersistCfg cfg; 85 { 86 std::lock_guard<std::recursive_mutex> lock(imeCfgLock_); 87 cfg.imePersistInfo = imeConfigs_; 88 } 89 std::string content; 90 auto ret = cfg.Marshall(content); 91 IMSA_HILOGD("ret: %{public}d, content: %{public}s, size: %{public}zu", ret, content.c_str(), 92 cfg.imePersistInfo.size()); 93 return content; 94} 95 96void ImeCfgManager::AddImeCfg(const ImePersistInfo &cfg) 97{ 98 std::lock_guard<std::recursive_mutex> lock(imeCfgLock_); 99 imeConfigs_.push_back(cfg); 100 WriteImeCfg(); 101} 102 103void ImeCfgManager::ModifyImeCfg(const ImePersistInfo &cfg) 104{ 105 std::lock_guard<std::recursive_mutex> lock(imeCfgLock_); 106 auto it = std::find_if(imeConfigs_.begin(), imeConfigs_.end(), 107 [&cfg](const ImePersistInfo &imeCfg) { return imeCfg.userId == cfg.userId && !cfg.currentIme.empty(); }); 108 if (it != imeConfigs_.end()) { 109 if (it->isDefaultImeSet) { 110 ImePersistInfo imePersistInfo; 111 imePersistInfo.userId = cfg.userId; 112 imePersistInfo.currentIme = cfg.currentIme; 113 imePersistInfo.currentSubName = cfg.currentSubName; 114 imePersistInfo.isDefaultImeSet = true; 115 *it = imePersistInfo; 116 } else { 117 *it = cfg; 118 } 119 } 120 121 WriteImeCfg(); 122} 123 124void ImeCfgManager::DeleteImeCfg(int32_t userId) 125{ 126 std::lock_guard<std::recursive_mutex> lock(imeCfgLock_); 127 for (auto iter = imeConfigs_.begin(); iter != imeConfigs_.end(); iter++) { 128 if (iter->userId == userId) { 129 imeConfigs_.erase(iter); 130 break; 131 } 132 } 133 WriteImeCfg(); 134} 135 136ImePersistInfo ImeCfgManager::GetImeCfg(int32_t userId) 137{ 138 std::lock_guard<std::recursive_mutex> lock(imeCfgLock_); 139 auto it = std::find_if(imeConfigs_.begin(), imeConfigs_.end(), 140 [userId](const ImePersistInfo &cfg) { return cfg.userId == userId; }); 141 if (it != imeConfigs_.end()) { 142 return *it; 143 } 144 return {}; 145} 146 147std::shared_ptr<ImeNativeCfg> ImeCfgManager::GetCurrentImeCfg(int32_t userId) 148{ 149 auto cfg = GetImeCfg(userId); 150 ImeNativeCfg info; 151 info.subName = cfg.currentSubName; 152 info.imeId = cfg.currentIme; 153 auto pos = info.imeId.find('/'); 154 if (pos != std::string::npos && pos + 1 < info.imeId.size()) { 155 info.bundleName = info.imeId.substr(0, pos); 156 info.extName = info.imeId.substr(pos + 1); 157 } 158 return std::make_shared<ImeNativeCfg>(info); 159} 160 161bool ImeCfgManager::IsDefaultImeSet(int32_t userId) 162{ 163 IMSA_HILOGI("ImeCfgManager::IsDefaultImeSet enter."); 164 auto cfg = GetImeCfg(userId); 165 IMSA_HILOGI("isDefaultImeSet: %{public}d", cfg.isDefaultImeSet); 166 return cfg.isDefaultImeSet; 167} 168} // namespace MiscServices 169} // namespace OHOS