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 <algorithm>
19
20 #include "common_timer_errors.h"
21 #include "ime_info_inquirer.h"
22 namespace OHOS {
23 namespace MiscServices {
24 constexpr uint32_t TIMER_TASK_INTERNAL = 3600000; // updated hourly
~FullImeInfoManager()25 FullImeInfoManager::~FullImeInfoManager()
26 {
27 timer_.Unregister(timerId_);
28 timer_.Shutdown();
29 fullImeInfos_.clear();
30 }
31
FullImeInfoManager()32 FullImeInfoManager::FullImeInfoManager()
33 {
34 uint32_t ret = timer_.Setup();
35 if (ret != Utils::TIMER_ERR_OK) {
36 IMSA_HILOGE("failed to create timer");
37 return;
38 }
39 timerId_ = timer_.Register([this]() { Init(); }, TIMER_TASK_INTERNAL, false);
40 }
41
GetInstance()42 FullImeInfoManager &FullImeInfoManager::GetInstance()
43 {
44 static FullImeInfoManager instance;
45 return instance;
46 }
47
Init()48 int32_t FullImeInfoManager::Init()
49 {
50 std::vector<std::pair<int32_t, std::vector<FullImeInfo>>> fullImeInfos;
51 auto ret = ImeInfoInquirer::GetInstance().QueryFullImeInfo(fullImeInfos);
52 if (ret != ErrorCode::NO_ERROR) {
53 IMSA_HILOGW("failed to QueryFullImeInfo, ret:%{public}d", ret);
54 return ret;
55 }
56 std::lock_guard<std::mutex> lock(lock_);
57 fullImeInfos_.clear();
58 for (const auto &infos : fullImeInfos) {
59 fullImeInfos_.insert_or_assign(infos.first, infos.second);
60 }
61 return ErrorCode::NO_ERROR;
62 }
63
Add(int32_t userId)64 int32_t FullImeInfoManager::Add(int32_t userId)
65 {
66 {
67 std::lock_guard<std::mutex> lock(lock_);
68 auto it = fullImeInfos_.find(userId);
69 if (it != fullImeInfos_.end()) {
70 return ErrorCode::NO_ERROR;
71 }
72 }
73 std::vector<FullImeInfo> infos;
74 auto ret = ImeInfoInquirer::GetInstance().QueryFullImeInfo(userId, infos);
75 if (ret != ErrorCode::NO_ERROR) {
76 IMSA_HILOGE("failed to QueryFullImeInfo, userId:%{public}d, ret:%{public}d", userId, ret);
77 return ret;
78 }
79 std::lock_guard<std::mutex> lock(lock_);
80 fullImeInfos_.insert_or_assign(userId, infos);
81 return ErrorCode::NO_ERROR;
82 }
83
Update()84 int32_t FullImeInfoManager::Update()
85 {
86 auto ret = Init();
87 if (ret != ErrorCode::NO_ERROR) {
88 std::lock_guard<std::mutex> lock(lock_);
89 fullImeInfos_.clear();
90 }
91 return ErrorCode::NO_ERROR;
92 }
93
Delete(int32_t userId)94 int32_t FullImeInfoManager::Delete(int32_t userId)
95 {
96 std::lock_guard<std::mutex> lock(lock_);
97 fullImeInfos_.erase(userId);
98 return ErrorCode::NO_ERROR;
99 }
100
Add(int32_t userId,const std::string & bundleName)101 int32_t FullImeInfoManager::Add(int32_t userId, const std::string &bundleName)
102 {
103 FullImeInfo info;
104 auto ret = ImeInfoInquirer::GetInstance().GetFullImeInfo(userId, bundleName, info);
105 if (ret != ErrorCode::NO_ERROR) {
106 IMSA_HILOGE("failed to GetFullImeInfo, userId:%{public}d, bundleName:%{public}s, ret:%{public}d", userId,
107 bundleName.c_str(), ret);
108 return ret;
109 }
110 std::lock_guard<std::mutex> lock(lock_);
111 auto it = fullImeInfos_.find(userId);
112 if (it == fullImeInfos_.end()) {
113 fullImeInfos_.insert({ userId, { info } });
114 return ErrorCode::NO_ERROR;
115 }
116 auto iter = std::find_if(it->second.begin(), it->second.end(),
117 [&bundleName](const FullImeInfo &info) { return bundleName == info.prop.name; });
118 if (iter != it->second.end()) {
119 return ErrorCode::NO_ERROR;
120 }
121 it->second.push_back(info);
122 return ErrorCode::NO_ERROR;
123 }
124
Delete(int32_t userId,const std::string & bundleName)125 int32_t FullImeInfoManager::Delete(int32_t userId, const std::string &bundleName)
126 {
127 std::lock_guard<std::mutex> lock(lock_);
128 auto it = fullImeInfos_.find(userId);
129 if (it == fullImeInfos_.end()) {
130 return ErrorCode::NO_ERROR;
131 }
132 auto iter = std::find_if(it->second.begin(), it->second.end(),
133 [&bundleName](const FullImeInfo &info) { return bundleName == info.prop.name; });
134 if (iter == it->second.end()) {
135 return ErrorCode::NO_ERROR;
136 }
137 it->second.erase(iter);
138 if (it->second.empty()) {
139 fullImeInfos_.erase(it->first);
140 }
141 return ErrorCode::NO_ERROR;
142 }
143
Update(int32_t userId,const std::string & bundleName)144 int32_t FullImeInfoManager::Update(int32_t userId, const std::string &bundleName)
145 {
146 FullImeInfo info;
147 auto ret = ImeInfoInquirer::GetInstance().GetFullImeInfo(userId, bundleName, info);
148 if (ret != ErrorCode::NO_ERROR) {
149 IMSA_HILOGE("failed to GetFullImeInfo failed, userId:%{public}d, bundleName:%{public}s, ret:%{public}d",
150 userId, bundleName.c_str(), ret);
151 return ErrorCode::ERROR_PACKAGE_MANAGER;
152 }
153 std::lock_guard<std::mutex> lock(lock_);
154 auto it = fullImeInfos_.find(userId);
155 if (it == fullImeInfos_.end()) {
156 fullImeInfos_.insert({ userId, { info } });
157 return ErrorCode::NO_ERROR;
158 }
159 auto iter = std::find_if(it->second.begin(), it->second.end(),
160 [&bundleName](const FullImeInfo &info) { return bundleName == info.prop.name; });
161 if (iter != it->second.end()) {
162 it->second.erase(iter);
163 }
164 it->second.push_back(info);
165 return ErrorCode::NO_ERROR;
166 }
167
Get(int32_t userId)168 std::vector<FullImeInfo> FullImeInfoManager::Get(int32_t userId)
169 {
170 std::lock_guard<std::mutex> lock(lock_);
171 auto it = fullImeInfos_.find(userId);
172 if (it == fullImeInfos_.end()) {
173 return {};
174 }
175 return it->second;
176 }
177
Get(const std::string & bundleName,int32_t userId,FullImeInfo & fullImeInfo)178 bool FullImeInfoManager::Get(const std::string &bundleName, int32_t userId, FullImeInfo &fullImeInfo)
179 {
180 std::lock_guard<std::mutex> lock(lock_);
181 auto it = fullImeInfos_.find(userId);
182 if (it == fullImeInfos_.end()) {
183 IMSA_HILOGD("user %{public}d info", userId);
184 return false;
185 }
186 auto iter = std::find_if(it->second.begin(), it->second.end(),
187 [&bundleName](const FullImeInfo &info) { return bundleName == info.prop.name; });
188 if (iter == it->second.end()) {
189 IMSA_HILOGD("ime: %{public}s not in cache", bundleName.c_str());
190 return false;
191 }
192 fullImeInfo = *iter;
193 return true;
194 }
195
Has(int32_t userId,const std::string & bundleName)196 bool FullImeInfoManager::Has(int32_t userId, const std::string &bundleName)
197 {
198 std::lock_guard<std::mutex> lock(lock_);
199 auto it = fullImeInfos_.find(userId);
200 if (it == fullImeInfos_.end()) {
201 return false;
202 }
203 auto iter = std::find_if(it->second.begin(), it->second.end(),
204 [&bundleName](const FullImeInfo &info) { return bundleName == info.prop.name; });
205 return iter != it->second.end();
206 }
207
Get(int32_t userId,uint32_t tokenId)208 std::string FullImeInfoManager::Get(int32_t userId, uint32_t tokenId)
209 {
210 std::lock_guard<std::mutex> lock(lock_);
211 auto it = fullImeInfos_.find(userId);
212 if (it == fullImeInfos_.end()) {
213 return "";
214 }
215 auto iter = std::find_if(
216 it->second.begin(), it->second.end(), [&tokenId](const FullImeInfo &info) { return tokenId == info.tokenId; });
217 if (iter == it->second.end()) {
218 return "";
219 }
220 return (*iter).prop.name;
221 }
222 } // namespace MiscServices
223 } // namespace OHOS