122736c2fSopenharmony_ci/*
222736c2fSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
322736c2fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
422736c2fSopenharmony_ci * you may not use this file except in compliance with the License.
522736c2fSopenharmony_ci * You may obtain a copy of the License at
622736c2fSopenharmony_ci *
722736c2fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
822736c2fSopenharmony_ci *
922736c2fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1022736c2fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1122736c2fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1222736c2fSopenharmony_ci * See the License for the specific language governing permissions and
1322736c2fSopenharmony_ci * limitations under the License.
1422736c2fSopenharmony_ci */
1522736c2fSopenharmony_ci
1622736c2fSopenharmony_ci#include "ime_cfg_manager.h"
1722736c2fSopenharmony_ci
1822736c2fSopenharmony_ci#include <algorithm>
1922736c2fSopenharmony_ci#include <fcntl.h>
2022736c2fSopenharmony_ci#include <ios>
2122736c2fSopenharmony_ci#include <string>
2222736c2fSopenharmony_ci
2322736c2fSopenharmony_ci#include "file_operator.h"
2422736c2fSopenharmony_ci#include "global.h"
2522736c2fSopenharmony_cinamespace OHOS {
2622736c2fSopenharmony_cinamespace MiscServices {
2722736c2fSopenharmony_cinamespace {
2822736c2fSopenharmony_ciconstexpr const char *IME_CFG_FILE_PATH = "/data/service/el1/public/imf/ime_cfg.json";
2922736c2fSopenharmony_ci} // namespace
3022736c2fSopenharmony_ciImeCfgManager &ImeCfgManager::GetInstance()
3122736c2fSopenharmony_ci{
3222736c2fSopenharmony_ci    static ImeCfgManager instance;
3322736c2fSopenharmony_ci    return instance;
3422736c2fSopenharmony_ci}
3522736c2fSopenharmony_ci
3622736c2fSopenharmony_civoid ImeCfgManager::Init()
3722736c2fSopenharmony_ci{
3822736c2fSopenharmony_ci    ReadImeCfg();
3922736c2fSopenharmony_ci}
4022736c2fSopenharmony_ci
4122736c2fSopenharmony_civoid ImeCfgManager::ReadImeCfg()
4222736c2fSopenharmony_ci{
4322736c2fSopenharmony_ci    if (!FileOperator::IsExist(IME_CFG_FILE_PATH)) {
4422736c2fSopenharmony_ci        IMSA_HILOGD("ime cfg file not found.");
4522736c2fSopenharmony_ci        return;
4622736c2fSopenharmony_ci    }
4722736c2fSopenharmony_ci    std::string cfg;
4822736c2fSopenharmony_ci    bool ret = FileOperator::Read(IME_CFG_FILE_PATH, cfg);
4922736c2fSopenharmony_ci    if (!ret) {
5022736c2fSopenharmony_ci        IMSA_HILOGE("failed to ReadJsonFile!");
5122736c2fSopenharmony_ci        return;
5222736c2fSopenharmony_ci    }
5322736c2fSopenharmony_ci    ParseImeCfg(cfg);
5422736c2fSopenharmony_ci}
5522736c2fSopenharmony_ci
5622736c2fSopenharmony_civoid ImeCfgManager::WriteImeCfg()
5722736c2fSopenharmony_ci{
5822736c2fSopenharmony_ci    auto content = PackageImeCfg();
5922736c2fSopenharmony_ci    if (content.empty()) {
6022736c2fSopenharmony_ci        IMSA_HILOGE("failed to Package imeCfg!");
6122736c2fSopenharmony_ci        return;
6222736c2fSopenharmony_ci    }
6322736c2fSopenharmony_ci    if (!FileOperator::Write(IME_CFG_FILE_PATH, content, O_CREAT | O_WRONLY | O_SYNC | O_TRUNC)) {
6422736c2fSopenharmony_ci        IMSA_HILOGE("failed to WriteJsonFile!");
6522736c2fSopenharmony_ci    }
6622736c2fSopenharmony_ci}
6722736c2fSopenharmony_ci
6822736c2fSopenharmony_cibool ImeCfgManager::ParseImeCfg(const std::string &content)
6922736c2fSopenharmony_ci{
7022736c2fSopenharmony_ci    IMSA_HILOGD("content: %{public}s", content.c_str());
7122736c2fSopenharmony_ci    ImePersistCfg cfg;
7222736c2fSopenharmony_ci    auto ret = cfg.Unmarshall(content);
7322736c2fSopenharmony_ci    if (!ret) {
7422736c2fSopenharmony_ci        IMSA_HILOGE("Unmarshall failed!");
7522736c2fSopenharmony_ci        return false;
7622736c2fSopenharmony_ci    }
7722736c2fSopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
7822736c2fSopenharmony_ci    imeConfigs_ = cfg.imePersistInfo;
7922736c2fSopenharmony_ci    return true;
8022736c2fSopenharmony_ci}
8122736c2fSopenharmony_ci
8222736c2fSopenharmony_cistd::string ImeCfgManager::PackageImeCfg()
8322736c2fSopenharmony_ci{
8422736c2fSopenharmony_ci    ImePersistCfg cfg;
8522736c2fSopenharmony_ci    {
8622736c2fSopenharmony_ci        std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
8722736c2fSopenharmony_ci        cfg.imePersistInfo = imeConfigs_;
8822736c2fSopenharmony_ci    }
8922736c2fSopenharmony_ci    std::string content;
9022736c2fSopenharmony_ci    auto ret = cfg.Marshall(content);
9122736c2fSopenharmony_ci    IMSA_HILOGD("ret: %{public}d, content: %{public}s, size: %{public}zu", ret, content.c_str(),
9222736c2fSopenharmony_ci        cfg.imePersistInfo.size());
9322736c2fSopenharmony_ci    return content;
9422736c2fSopenharmony_ci}
9522736c2fSopenharmony_ci
9622736c2fSopenharmony_civoid ImeCfgManager::AddImeCfg(const ImePersistInfo &cfg)
9722736c2fSopenharmony_ci{
9822736c2fSopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
9922736c2fSopenharmony_ci    imeConfigs_.push_back(cfg);
10022736c2fSopenharmony_ci    WriteImeCfg();
10122736c2fSopenharmony_ci}
10222736c2fSopenharmony_ci
10322736c2fSopenharmony_civoid ImeCfgManager::ModifyImeCfg(const ImePersistInfo &cfg)
10422736c2fSopenharmony_ci{
10522736c2fSopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
10622736c2fSopenharmony_ci    auto it = std::find_if(imeConfigs_.begin(), imeConfigs_.end(),
10722736c2fSopenharmony_ci        [&cfg](const ImePersistInfo &imeCfg) { return imeCfg.userId == cfg.userId && !cfg.currentIme.empty(); });
10822736c2fSopenharmony_ci    if (it != imeConfigs_.end()) {
10922736c2fSopenharmony_ci        if (it->isDefaultImeSet) {
11022736c2fSopenharmony_ci            ImePersistInfo imePersistInfo;
11122736c2fSopenharmony_ci            imePersistInfo.userId = cfg.userId;
11222736c2fSopenharmony_ci            imePersistInfo.currentIme = cfg.currentIme;
11322736c2fSopenharmony_ci            imePersistInfo.currentSubName = cfg.currentSubName;
11422736c2fSopenharmony_ci            imePersistInfo.isDefaultImeSet = true;
11522736c2fSopenharmony_ci            *it = imePersistInfo;
11622736c2fSopenharmony_ci        } else {
11722736c2fSopenharmony_ci            *it = cfg;
11822736c2fSopenharmony_ci        }
11922736c2fSopenharmony_ci    }
12022736c2fSopenharmony_ci
12122736c2fSopenharmony_ci    WriteImeCfg();
12222736c2fSopenharmony_ci}
12322736c2fSopenharmony_ci
12422736c2fSopenharmony_civoid ImeCfgManager::DeleteImeCfg(int32_t userId)
12522736c2fSopenharmony_ci{
12622736c2fSopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
12722736c2fSopenharmony_ci    for (auto iter = imeConfigs_.begin(); iter != imeConfigs_.end(); iter++) {
12822736c2fSopenharmony_ci        if (iter->userId == userId) {
12922736c2fSopenharmony_ci            imeConfigs_.erase(iter);
13022736c2fSopenharmony_ci            break;
13122736c2fSopenharmony_ci        }
13222736c2fSopenharmony_ci    }
13322736c2fSopenharmony_ci    WriteImeCfg();
13422736c2fSopenharmony_ci}
13522736c2fSopenharmony_ci
13622736c2fSopenharmony_ciImePersistInfo ImeCfgManager::GetImeCfg(int32_t userId)
13722736c2fSopenharmony_ci{
13822736c2fSopenharmony_ci    std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
13922736c2fSopenharmony_ci    auto it = std::find_if(imeConfigs_.begin(), imeConfigs_.end(),
14022736c2fSopenharmony_ci        [userId](const ImePersistInfo &cfg) { return cfg.userId == userId; });
14122736c2fSopenharmony_ci    if (it != imeConfigs_.end()) {
14222736c2fSopenharmony_ci        return *it;
14322736c2fSopenharmony_ci    }
14422736c2fSopenharmony_ci    return {};
14522736c2fSopenharmony_ci}
14622736c2fSopenharmony_ci
14722736c2fSopenharmony_cistd::shared_ptr<ImeNativeCfg> ImeCfgManager::GetCurrentImeCfg(int32_t userId)
14822736c2fSopenharmony_ci{
14922736c2fSopenharmony_ci    auto cfg = GetImeCfg(userId);
15022736c2fSopenharmony_ci    ImeNativeCfg info;
15122736c2fSopenharmony_ci    info.subName = cfg.currentSubName;
15222736c2fSopenharmony_ci    info.imeId = cfg.currentIme;
15322736c2fSopenharmony_ci    auto pos = info.imeId.find('/');
15422736c2fSopenharmony_ci    if (pos != std::string::npos && pos + 1 < info.imeId.size()) {
15522736c2fSopenharmony_ci        info.bundleName = info.imeId.substr(0, pos);
15622736c2fSopenharmony_ci        info.extName = info.imeId.substr(pos + 1);
15722736c2fSopenharmony_ci    }
15822736c2fSopenharmony_ci    return std::make_shared<ImeNativeCfg>(info);
15922736c2fSopenharmony_ci}
16022736c2fSopenharmony_ci
16122736c2fSopenharmony_cibool ImeCfgManager::IsDefaultImeSet(int32_t userId)
16222736c2fSopenharmony_ci{
16322736c2fSopenharmony_ci    IMSA_HILOGI("ImeCfgManager::IsDefaultImeSet enter.");
16422736c2fSopenharmony_ci    auto cfg = GetImeCfg(userId);
16522736c2fSopenharmony_ci    IMSA_HILOGI("isDefaultImeSet: %{public}d", cfg.isDefaultImeSet);
16622736c2fSopenharmony_ci    return cfg.isDefaultImeSet;
16722736c2fSopenharmony_ci}
16822736c2fSopenharmony_ci} // namespace MiscServices
16922736c2fSopenharmony_ci} // namespace OHOS