1 /*
2 * Copyright (c) 2023 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 "input_type_manager.h"
17
18 #include <dlfcn.h>
19 #include <fcntl.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <unistd.h>
23
24 #include <algorithm>
25 #include <cinttypes>
26 #include <cstdio>
27 #include <fstream>
28 #include <ios>
29 #include <string>
30
31 #include "climits"
32 #include "config_policy_utils.h"
33 #include "input_method_config_parser.h"
34 #include "global.h"
35 #include "ime_cfg_manager.h"
36
37 namespace OHOS {
38 namespace MiscServices {
39 namespace {
40 const std::string SUPPORTED_INPUT_TYPE_LIST = "supportedInputTypeList";
41 const std::string INPUT_TYPE = "inputType";
42 const std::string BUNDLE_NAME = "bundleName";
43 const std::string SUBTYPE_ID = "subtypeId";
44 using json = nlohmann::json;
45 } // namespace
46
from_json(const json & jsonObj,InputTypeCfg & cfg)47 void from_json(const json &jsonObj, InputTypeCfg &cfg)
48 {
49 if (!jsonObj.contains(INPUT_TYPE) || !jsonObj[INPUT_TYPE].is_number()) {
50 IMSA_HILOGE("INPUT_TYPE is invalid");
51 return;
52 }
53 cfg.type = static_cast<InputType>(jsonObj.at(INPUT_TYPE).get<int32_t>());
54 if (!jsonObj.contains(BUNDLE_NAME) || !jsonObj[BUNDLE_NAME].is_string()) {
55 IMSA_HILOGE("BUNDLE_NAME is invalid");
56 return;
57 }
58 cfg.ime.bundleName = jsonObj.at(BUNDLE_NAME).get<std::string>();
59 if (!jsonObj.contains(SUBTYPE_ID) || !jsonObj[SUBTYPE_ID].is_string()) {
60 IMSA_HILOGE("SUBTYPE_ID is invalid");
61 return;
62 }
63 cfg.ime.subName = jsonObj.at(SUBTYPE_ID).get<std::string>();
64 }
65
GetInstance()66 InputTypeManager &InputTypeManager::GetInstance()
67 {
68 static InputTypeManager instance;
69 return instance;
70 }
71
IsSupported(InputType type)72 bool InputTypeManager::IsSupported(InputType type)
73 {
74 if (!isTypeCfgReady_.load() && !Init()) {
75 IMSA_HILOGE("init cfg failed");
76 return false;
77 }
78 std::lock_guard<std::mutex> lock(typesLock_);
79 return inputTypes_.find(type) != inputTypes_.end();
80 }
81
IsInputType(const ImeIdentification & ime)82 bool InputTypeManager::IsInputType(const ImeIdentification &ime)
83 {
84 if (!isTypeCfgReady_.load() && !Init()) {
85 IMSA_HILOGE("init cfg failed");
86 return false;
87 }
88 std::lock_guard<std::mutex> lock(listLock_);
89 return inputTypeImeList_.find(ime) != inputTypeImeList_.end();
90 }
91
GetImeByInputType(InputType type,ImeIdentification & ime)92 int32_t InputTypeManager::GetImeByInputType(InputType type, ImeIdentification &ime)
93 {
94 if (!isTypeCfgReady_.load() && !Init()) {
95 IMSA_HILOGE("init cfg failed");
96 return ErrorCode::ERROR_PARSE_CONFIG_FILE;
97 }
98 std::lock_guard<std::mutex> lock(typesLock_);
99 auto iter = inputTypes_.find(type);
100 if (iter == inputTypes_.end()) {
101 IMSA_HILOGE("type: %{public}d not supported", type);
102 return ErrorCode::ERROR_BAD_PARAMETERS;
103 }
104 ime = iter->second;
105 IMSA_HILOGI("type: %{public}d find ime: %{public}s|%{public}s", type, ime.bundleName.c_str(), ime.subName.c_str());
106 return ErrorCode::NO_ERROR;
107 }
108
Set(bool isStarted,const ImeIdentification & currentIme)109 void InputTypeManager::Set(bool isStarted, const ImeIdentification ¤tIme)
110 {
111 std::lock_guard<std::mutex> lock(stateLock_);
112 isStarted_ = isStarted;
113 currentTypeIme_ = currentIme;
114 }
115
IsStarted()116 bool InputTypeManager::IsStarted()
117 {
118 std::lock_guard<std::mutex> lock(stateLock_);
119 return isStarted_;
120 }
121
IsCameraImeStarted()122 bool InputTypeManager::IsCameraImeStarted()
123 {
124 std::lock_guard<std::mutex> lock(stateLock_);
125 return isStarted_ && inputTypes_.find(InputType::CAMERA_INPUT) != inputTypes_.end()
126 && inputTypes_[InputType::CAMERA_INPUT] == currentTypeIme_;
127 }
128
GetCurrentIme()129 ImeIdentification InputTypeManager::GetCurrentIme()
130 {
131 std::lock_guard<std::mutex> lock(stateLock_);
132 return currentTypeIme_;
133 }
134
Init()135 bool InputTypeManager::Init()
136 {
137 IMSA_HILOGD("start");
138 if (isInitInProgress_.load()) {
139 return isInitSuccess_.GetValue();
140 }
141 isInitInProgress_.store(true);
142 isInitSuccess_.Clear(false);
143 std::vector<InputTypeCfg> configs;
144 bool isSuccess = ImeConfigParse::ParseFromCustomSystem(SUPPORTED_INPUT_TYPE_LIST, configs);
145 IMSA_HILOGD("ParseFromCustomSystem end isSuccess %{public}d", isSuccess);
146 if (isSuccess) {
147 std::lock_guard<std::mutex> lk(typesLock_);
148 for (const auto& config : configs) {
149 inputTypes_.insert({ config.type, config.ime });
150 }
151 for (const auto& cfg : inputTypes_) {
152 std::lock_guard<std::mutex> lock(listLock_);
153 inputTypeImeList_.insert(cfg.second);
154 }
155 } else {
156 std::lock_guard<std::mutex> lk(typesLock_);
157 inputTypes_.clear();
158 }
159 isTypeCfgReady_.store(isSuccess);
160 isInitSuccess_.SetValue(isSuccess);
161 isInitInProgress_.store(false);
162 return isSuccess;
163 }
164 } // namespace MiscServices
165 } // namespace OHOS