1 /*
2 * Copyright (c) 2024 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 "full_ime_info_manager.h"
17
18 #include "common_timer_errors.h"
19 #include "ime_enabled_info_manager.h"
20 #include "ime_info_inquirer.h"
21 #include "inputmethod_message_handler.h"
22 #include "message.h"
23 namespace OHOS {
24 namespace MiscServices {
25 constexpr uint32_t TIMER_TASK_INTERNAL = 1 * 60 * 60 * 1000; // updated hourly
~FullImeInfoManager()26 FullImeInfoManager::~FullImeInfoManager()
27 {
28 timer_.Unregister(timerId_);
29 timer_.Shutdown();
30 fullImeInfos_.clear();
31 }
32
FullImeInfoManager()33 FullImeInfoManager::FullImeInfoManager()
34 {
35 uint32_t ret = timer_.Setup();
36 if (ret != Utils::TIMER_ERR_OK) {
37 IMSA_HILOGE("failed to create timer!");
38 return;
39 }
40 timerId_ = timer_.Register(
41 []() {
42 Message *msg = new (std::nothrow) Message(MessageID::MSG_ID_REGULAR_UPDATE_IME_INFO, nullptr);
43 if (msg == nullptr) {
44 IMSA_HILOGE("failed to create message!");
45 return;
46 }
47 auto instance = MessageHandler::Instance();
48 if (instance == nullptr) {
49 delete msg;
50 return;
51 }
52 instance->SendMessage(msg);
53 },
54 TIMER_TASK_INTERNAL, false);
55 }
56
GetInstance()57 FullImeInfoManager &FullImeInfoManager::GetInstance()
58 {
59 static FullImeInfoManager instance;
60 return instance;
61 }
62 // LCOV_EXCL_START
RegularInit()63 int32_t FullImeInfoManager::RegularInit()
64 {
65 std::vector<std::pair<int32_t, std::vector<FullImeInfo>>> fullImeInfos;
66 auto ret = ImeInfoInquirer::GetInstance().QueryFullImeInfo(fullImeInfos);
67 if (ret != ErrorCode::NO_ERROR) {
68 IMSA_HILOGW("failed to QueryFullImeInfo, ret:%{public}d", ret);
69 return ret;
70 }
71 std::lock_guard<std::mutex> lock(lock_);
72 fullImeInfos_.clear();
73 for (const auto &infos : fullImeInfos) {
74 fullImeInfos_.insert_or_assign(infos.first, infos.second);
75 }
76 return ErrorCode::NO_ERROR;
77 }
78 // LCOV_EXCL_STOP
Switch(int32_t userId)79 int32_t FullImeInfoManager::Switch(int32_t userId)
80 {
81 std::vector<FullImeInfo> infos;
82 auto ret = AddUser(userId, infos);
83 ImeEnabledInfoManager::GetInstance().Switch(userId, infos);
84 return ret;
85 }
86
Update()87 int32_t FullImeInfoManager::Update()
88 {
89 {
90 std::lock_guard<std::mutex> lock(lock_);
91 fullImeInfos_.clear();
92 }
93 IMSA_HILOGI("run in.");
94 std::vector<std::pair<int32_t, std::vector<FullImeInfo>>> fullImeInfos;
95 auto ret = ImeInfoInquirer::GetInstance().QueryFullImeInfo(fullImeInfos);
96 if (ret != ErrorCode::NO_ERROR) {
97 IMSA_HILOGW("failed to QueryFullImeInfo, ret:%{public}d", ret);
98 return ret;
99 }
100 {
101 std::lock_guard<std::mutex> lock(lock_);
102 for (const auto &infos : fullImeInfos) {
103 fullImeInfos_.insert_or_assign(infos.first, infos.second);
104 }
105 }
106 return ErrorCode::NO_ERROR;
107 }
108
Delete(int32_t userId)109 int32_t FullImeInfoManager::Delete(int32_t userId)
110 {
111 {
112 std::lock_guard<std::mutex> lock(lock_);
113 fullImeInfos_.erase(userId);
114 }
115 ImeEnabledInfoManager::GetInstance().Delete(userId);
116 return ErrorCode::NO_ERROR;
117 }
118
Add(int32_t userId,const std::string & bundleName)119 int32_t FullImeInfoManager::Add(int32_t userId, const std::string &bundleName)
120 {
121 FullImeInfo info;
122 auto ret = AddPackage(userId, bundleName, info);
123 if (ret != ErrorCode::NO_ERROR) {
124 return ret;
125 }
126 ImeEnabledInfoManager::GetInstance().Add(userId, info);
127 return ErrorCode::NO_ERROR;
128 }
129
Delete(int32_t userId,const std::string & bundleName)130 int32_t FullImeInfoManager::Delete(int32_t userId, const std::string &bundleName)
131 {
132 auto ret = DeletePackage(userId, bundleName);
133 ImeEnabledInfoManager::GetInstance().Delete(userId, bundleName);
134 return ret;
135 }
136
Update(int32_t userId,const std::string & bundleName)137 int32_t FullImeInfoManager::Update(int32_t userId, const std::string &bundleName)
138 {
139 FullImeInfo info;
140 auto ret = ImeInfoInquirer::GetInstance().GetFullImeInfo(userId, bundleName, info);
141 if (ret != ErrorCode::NO_ERROR) {
142 IMSA_HILOGE("failed to GetFullImeInfo failed, userId:%{public}d, bundleName:%{public}s, ret:%{public}d",
143 userId, bundleName.c_str(), ret);
144 return ErrorCode::ERROR_PACKAGE_MANAGER;
145 }
146 std::lock_guard<std::mutex> lock(lock_);
147 auto it = fullImeInfos_.find(userId);
148 if (it == fullImeInfos_.end()) {
149 fullImeInfos_.insert({ userId, { info } });
150 return ErrorCode::NO_ERROR;
151 }
152 auto iter = std::find_if(it->second.begin(), it->second.end(),
153 [&bundleName](const FullImeInfo &info) { return bundleName == info.prop.name; });
154 if (iter != it->second.end()) {
155 it->second.erase(iter);
156 }
157 it->second.push_back(info);
158 return ErrorCode::NO_ERROR;
159 }
160
Get(int32_t userId,std::vector<Property> & props)161 int32_t FullImeInfoManager::Get(int32_t userId, std::vector<Property> &props)
162 {
163 {
164 std::lock_guard<std::mutex> lock(lock_);
165 auto it = fullImeInfos_.find(userId);
166 if (it == fullImeInfos_.end()) {
167 return {};
168 }
169 for (auto &fullImeInfo : it->second) {
170 props.push_back(fullImeInfo.prop);
171 }
172 }
173 auto ret = ImeEnabledInfoManager::GetInstance().GetEnabledStates(userId, props);
174 if (ret != ErrorCode::NO_ERROR) {
175 IMSA_HILOGE("get enabled status failed:%{public}d!", ret);
176 return ErrorCode::ERROR_ENABLE_IME;
177 }
178 return ErrorCode::NO_ERROR;
179 }
180
Get(int32_t userId,const std::string & bundleName,FullImeInfo & fullImeInfo)181 bool FullImeInfoManager::Get(int32_t userId, const std::string &bundleName, FullImeInfo &fullImeInfo)
182 {
183 {
184 std::lock_guard<std::mutex> lock(lock_);
185 auto it = fullImeInfos_.find(userId);
186 if (it == fullImeInfos_.end()) {
187 IMSA_HILOGD("user %{public}d info", userId);
188 return false;
189 }
190 auto iter = std::find_if(it->second.begin(), it->second.end(),
191 [&bundleName](const FullImeInfo &info) { return bundleName == info.prop.name; });
192 if (iter == it->second.end()) {
193 IMSA_HILOGD("ime: %{public}s not in cache", bundleName.c_str());
194 return false;
195 }
196 fullImeInfo = *iter;
197 }
198 auto ret =
199 ImeEnabledInfoManager::GetInstance().GetEnabledState(userId, fullImeInfo.prop.name, fullImeInfo.prop.status);
200 if (ret != ErrorCode::NO_ERROR) {
201 IMSA_HILOGE("[%{public}d, %{public}s] get enabled status failed:%{public}d!", userId, bundleName.c_str(), ret);
202 }
203 return true;
204 }
205
Has(int32_t userId,const std::string & bundleName)206 bool FullImeInfoManager::Has(int32_t userId, const std::string &bundleName)
207 {
208 std::lock_guard<std::mutex> lock(lock_);
209 auto it = fullImeInfos_.find(userId);
210 if (it == fullImeInfos_.end()) {
211 return false;
212 }
213 auto iter = std::find_if(it->second.begin(), it->second.end(),
214 [&bundleName](const FullImeInfo &info) { return bundleName == info.prop.name; });
215 return iter != it->second.end();
216 }
217
Get(int32_t userId,uint32_t tokenId)218 std::string FullImeInfoManager::Get(int32_t userId, uint32_t tokenId)
219 {
220 std::lock_guard<std::mutex> lock(lock_);
221 auto it = fullImeInfos_.find(userId);
222 if (it == fullImeInfos_.end()) {
223 return "";
224 }
225 auto iter = std::find_if(
226 it->second.begin(), it->second.end(), [&tokenId](const FullImeInfo &info) { return tokenId == info.tokenId; });
227 if (iter == it->second.end()) {
228 return "";
229 }
230 return (*iter).prop.name;
231 }
232
Init()233 int32_t FullImeInfoManager::Init()
234 {
235 std::map<int32_t, std::vector<FullImeInfo>> fullImeInfos;
236 auto ret = Init(fullImeInfos);
237 if (ret != ErrorCode::NO_ERROR) {
238 return ret;
239 }
240 ImeEnabledInfoManager::GetInstance().Init(fullImeInfos);
241 return ErrorCode::NO_ERROR;
242 }
243
Init(std::map<int32_t,std::vector<FullImeInfo>> & fullImeInfos)244 int32_t FullImeInfoManager::Init(std::map<int32_t, std::vector<FullImeInfo>> &fullImeInfos)
245 {
246 {
247 std::lock_guard<std::mutex> lock(lock_);
248 if (!fullImeInfos_.empty()) {
249 fullImeInfos = fullImeInfos_;
250 return ErrorCode::NO_ERROR;
251 }
252 }
253 std::vector<std::pair<int32_t, std::vector<FullImeInfo>>> imeInfos;
254 auto ret = ImeInfoInquirer::GetInstance().QueryFullImeInfo(imeInfos);
255 if (ret != ErrorCode::NO_ERROR) {
256 IMSA_HILOGW("failed to QueryFullImeInfo, ret:%{public}d", ret);
257 return ret;
258 }
259 std::lock_guard<std::mutex> lock(lock_);
260 fullImeInfos_.clear();
261 for (const auto &infos : imeInfos) {
262 fullImeInfos_.insert_or_assign(infos.first, infos.second);
263 }
264 fullImeInfos = fullImeInfos_;
265 return ErrorCode::NO_ERROR;
266 }
267
AddUser(int32_t userId,std::vector<FullImeInfo> & infos)268 int32_t FullImeInfoManager::AddUser(int32_t userId, std::vector<FullImeInfo> &infos)
269 {
270 {
271 std::lock_guard<std::mutex> lock(lock_);
272 auto it = fullImeInfos_.find(userId);
273 if (it != fullImeInfos_.end()) {
274 infos = it->second;
275 return ErrorCode::NO_ERROR;
276 }
277 }
278 auto ret = ImeInfoInquirer::GetInstance().QueryFullImeInfo(userId, infos);
279 if (ret != ErrorCode::NO_ERROR) {
280 IMSA_HILOGE("failed to QueryFullImeInfo, userId:%{public}d, ret:%{public}d", userId, ret);
281 return ret;
282 }
283 std::lock_guard<std::mutex> lock(lock_);
284 fullImeInfos_.insert_or_assign(userId, infos);
285 return ErrorCode::NO_ERROR;
286 }
287
AddPackage(int32_t userId,const std::string & bundleName,FullImeInfo & info)288 int32_t FullImeInfoManager::AddPackage(int32_t userId, const std::string &bundleName, FullImeInfo &info)
289 {
290 auto ret = ImeInfoInquirer::GetInstance().GetFullImeInfo(userId, bundleName, info);
291 if (ret != ErrorCode::NO_ERROR) {
292 IMSA_HILOGE("failed to GetFullImeInfo failed, userId:%{public}d, bundleName:%{public}s, ret:%{public}d",
293 userId, bundleName.c_str(), ret);
294 return ErrorCode::ERROR_PACKAGE_MANAGER;
295 }
296 std::lock_guard<std::mutex> lock(lock_);
297 auto it = fullImeInfos_.find(userId);
298 if (it == fullImeInfos_.end()) {
299 fullImeInfos_.insert({ userId, { info } });
300 return ErrorCode::NO_ERROR;
301 }
302 auto iter = std::find_if(it->second.begin(), it->second.end(),
303 [&bundleName](const FullImeInfo &info) { return bundleName == info.prop.name; });
304 if (iter != it->second.end()) {
305 it->second.erase(iter);
306 }
307 it->second.push_back(info);
308 return ErrorCode::NO_ERROR;
309 }
310
DeletePackage(int32_t userId,const std::string & bundleName)311 int32_t FullImeInfoManager::DeletePackage(int32_t userId, const std::string &bundleName)
312 {
313 std::lock_guard<std::mutex> lock(lock_);
314 auto it = fullImeInfos_.find(userId);
315 if (it == fullImeInfos_.end()) {
316 return ErrorCode::NO_ERROR;
317 }
318 auto iter = std::find_if(it->second.begin(), it->second.end(),
319 [&bundleName](const FullImeInfo &info) { return bundleName == info.prop.name; });
320 if (iter == it->second.end()) {
321 return ErrorCode::NO_ERROR;
322 }
323 it->second.erase(iter);
324 if (it->second.empty()) {
325 fullImeInfos_.erase(it->first);
326 }
327 return ErrorCode::NO_ERROR;
328 }
329 } // namespace MiscServices
330 } // namespace OHOS