• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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