1 /*
2 * Copyright (C) 2021 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 "icc_dialling_numbers_cache.h"
17
18 namespace OHOS {
19 namespace Telephony {
IccDiallingNumbersCache(std::shared_ptr<SimFileManager> simFileManager)20 IccDiallingNumbersCache::IccDiallingNumbersCache(std::shared_ptr<SimFileManager> simFileManager)
21 : TelEventHandler("IccDiallingNumbersCache"), simFileManager_(simFileManager)
22 {
23 InitFileTypeMap();
24 }
25
~IccDiallingNumbersCache()26 IccDiallingNumbersCache::~IccDiallingNumbersCache() {}
27
Init()28 void IccDiallingNumbersCache::Init()
29 {
30 if ((usimDiallingNumberSrv_ != nullptr) && (diallingNumbersHandler_ != nullptr)) {
31 TELEPHONY_LOGI("IccDiallingNumbersCache init already done");
32 return;
33 }
34 if (simFileManager_ == nullptr) {
35 TELEPHONY_LOGE("IccDiallingNumbersCache int get null pointer");
36 return;
37 }
38 diallingNumbersHandler_ = simFileManager_->ObtainDiallingNumberHandler();
39 if (diallingNumbersHandler_ == nullptr) {
40 TELEPHONY_LOGE("IccDiallingNumbersCache failed to InitDiallingNumbersLoader");
41 return;
42 }
43
44 usimDiallingNumberSrv_ = std::make_shared<UsimDiallingNumbersService>();
45 if (usimDiallingNumberSrv_ == nullptr) {
46 TELEPHONY_LOGE("IccDiallingNumbersCache failed to create usimpdiallingnumbers.");
47 return;
48 }
49 std::shared_ptr<IccFileController> fileController = simFileManager_->GetIccFileController();
50 usimDiallingNumberSrv_->SetFileControllerAndDiallingNumberHandler(fileController, diallingNumbersHandler_);
51 }
52
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)53 void IccDiallingNumbersCache::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
54 {
55 if (event == nullptr) {
56 TELEPHONY_LOGE("event is nullptr!");
57 return;
58 }
59 uint32_t id = event->GetInnerEventId();
60 TELEPHONY_LOGD("IccDiallingNumbersCache ProcessEvent Id is %{public}d", id);
61 switch (id) {
62 case MSG_SIM_OBTAIN_ADN_DETAILS_DONE:
63 ProcessObtainAdnDetailsDone(event);
64 break;
65 case MSG_SIM_CHANGE_DIALLING_NUMBERS_DONE:
66 ProcessChangeDiallingNumbersDone(event);
67 break;
68 case MSG_SIM_OBTAIN_PBR_DETAILS_DONE:
69 ProcessObtainPbrDetailsDone(event);
70 break;
71 default:
72 break;
73 }
74 }
75
ClearDiallingNumberCache()76 void IccDiallingNumbersCache::ClearDiallingNumberCache()
77 {
78 diallingNumberFileList_.clear();
79 }
80
ProcessObtainPbrDetailsDone(const AppExecFwk::InnerEvent::Pointer & event)81 void IccDiallingNumbersCache::ProcessObtainPbrDetailsDone(const AppExecFwk::InnerEvent::Pointer &event)
82 {
83 std::unique_ptr<UsimResult> fd = event->GetUniqueObject<UsimResult>();
84 if (fd == nullptr) {
85 TELEPHONY_LOGE("fd is nullptr!");
86 return;
87 }
88 int fileId = fd->fileID;
89 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingNumberList =
90 std::static_pointer_cast<std::vector<std::shared_ptr<DiallingNumbersInfo>>>(fd->result);
91 auto iter = diallingNumberFileList_.find(fileId);
92 if (iter != diallingNumberFileList_.end()) {
93 diallingNumberFileList_.erase(fileId);
94 }
95 diallingNumberFileList_.insert(
96 std::pair<int, std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>>>(
97 fileId, diallingNumberList));
98 SendBackResult(fd->callerCache->caller, diallingNumberList, fd->exception);
99 TELEPHONY_LOGI("IccDiallingNumbersCache::ProcessUsimDiallingNumberLoadDone finished");
100 }
101
ProcessObtainAdnDetailsDone(const AppExecFwk::InnerEvent::Pointer & event)102 void IccDiallingNumbersCache::ProcessObtainAdnDetailsDone(const AppExecFwk::InnerEvent::Pointer &event)
103 {
104 std::unique_ptr<DiallingNumbersHandlerResult> fd = event->GetUniqueObject<DiallingNumbersHandlerResult>();
105 if (fd == nullptr) {
106 TELEPHONY_LOGE("fd is nullptr!");
107 return;
108 }
109 int fileId = fd->fileID;
110 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingNumberList =
111 std::static_pointer_cast<std::vector<std::shared_ptr<DiallingNumbersInfo>>>(fd->result);
112 if (diallingNumberList == nullptr) {
113 TELEPHONY_LOGE("diallingNumber loader ProcessObtainAdnDetailsDone error occured");
114 } else {
115 TELEPHONY_LOGI("ProcessObtainAdnDetailsDone %{public}zu", diallingNumberList->size());
116 }
117 auto iter = diallingNumberFileList_.find(fileId);
118 if (iter != diallingNumberFileList_.end()) {
119 diallingNumberFileList_.erase(fileId);
120 }
121 diallingNumberFileList_.insert(
122 std::pair<int, std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>>>(
123 fileId, diallingNumberList));
124 SendBackResult(fd->callerCache->caller, diallingNumberList, fd->exception);
125 TELEPHONY_LOGI("IccDiallingNumbersCache::ProcessObtainAdnDetailsDone finished");
126 }
127
ProcessChangeDiallingNumbersDone(const AppExecFwk::InnerEvent::Pointer & event)128 void IccDiallingNumbersCache::ProcessChangeDiallingNumbersDone(const AppExecFwk::InnerEvent::Pointer &event)
129 {
130 std::unique_ptr<DiallingNumbersHandlerResult> fd = event->GetUniqueObject<DiallingNumbersHandlerResult>();
131 if (fd == nullptr) {
132 TELEPHONY_LOGE("fd is nullptr!");
133 return;
134 }
135 int fileId = fd->fileID;
136 int index = fd->index;
137 std::shared_ptr<DiallingNumbersInfo> diallingNumber = std::static_pointer_cast<DiallingNumbersInfo>(fd->result);
138 auto iter = diallingNumberFileList_.find(fileId);
139 if (iter != diallingNumberFileList_.end()) {
140 if (fd->exception == nullptr) {
141 diallingNumberFileList_.at(fileId)->at(index - 1) = diallingNumber;
142 } else {
143 std::shared_ptr<HRilRadioResponseInfo> responseInfo =
144 std::static_pointer_cast<HRilRadioResponseInfo>(fd->exception);
145 if (responseInfo == nullptr) {
146 TELEPHONY_LOGE("responseInfo is nullptr");
147 return;
148 }
149 if (responseInfo->error == HRilErrType::NONE) {
150 diallingNumberFileList_.at(fileId)->at(index - 1) = diallingNumber;
151 }
152 }
153 } else {
154 TELEPHONY_LOGE("no diallingNumber list");
155 }
156 SendUpdateResult(fd->callerCache->caller, fd->exception);
157 TELEPHONY_LOGI("IccDiallingNumbersCache::ProcessChangeDiallingNumbersDone finished");
158 }
159
LoadReadyDiallingNumbers(int fileId)160 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> IccDiallingNumbersCache::LoadReadyDiallingNumbers
161 (int fileId)
162 {
163 auto itDiallingNumbers = diallingNumberFileList_.find(fileId);
164 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingNumberList = nullptr;
165 if (itDiallingNumbers != diallingNumberFileList_.end()) {
166 diallingNumberList = itDiallingNumbers->second;
167 }
168 return diallingNumberList;
169 }
170
ExtendedElementFile(int fileId)171 int IccDiallingNumbersCache::ExtendedElementFile(int fileId)
172 {
173 auto iter = extTypeMap_.find(fileId);
174 return (iter != extTypeMap_.end()) ? iter->second : -1;
175 }
176
UpdateDiallingNumberToIcc(int fileId,std::shared_ptr<DiallingNumbersInfo> diallingNumberInfor,int index,bool isDel,const AppExecFwk::InnerEvent::Pointer & caller)177 void IccDiallingNumbersCache::UpdateDiallingNumberToIcc(int fileId,
178 std::shared_ptr<DiallingNumbersInfo> diallingNumberInfor, int index,
179 bool isDel, const AppExecFwk::InnerEvent::Pointer &caller)
180 {
181 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> oldDiallingNumberList =
182 LoadReadyDiallingNumbers(fileId);
183
184 if (oldDiallingNumberList == nullptr) {
185 SendExceptionResult(caller, LOADER_ERROR);
186 TELEPHONY_LOGE("WriteDiallingNumberToSim not load at first");
187 return;
188 }
189 if (diallingNumberInfor == nullptr) {
190 TELEPHONY_LOGE("diallingNumberInfor is nullptr!");
191 return;
192 }
193 if (isDel && index == DiallingNumbersInfo::EMPTY_INDEX) {
194 SearchIndexByNameAndNumber(oldDiallingNumberList, diallingNumberInfor, index);
195 }
196 if (!CheckValueAndOperation(oldDiallingNumberList, diallingNumberInfor, index, fileId)) {
197 SendExceptionResult(caller, LOADER_ERROR);
198 return;
199 }
200 diallingNumberInfor->elementaryFileId_ = fileId;
201 diallingNumberInfor->index_ = index;
202 std::string pin2 = Str16ToStr8(diallingNumberInfor->pin2_);
203 diallingNumberInfor->pin2_ = u""; // reset
204
205 DiallingNumberUpdateInfor infor;
206 infor.diallingNumber = diallingNumberInfor;
207 infor.fileId = fileId;
208 infor.extFile = ExtendedElementFile(fileId);
209 infor.index = index;
210 infor.pin2 = (fileId == ELEMENTARY_FILE_ADN) ? "" : pin2;
211 infor.isDel = isDel;
212 AppExecFwk::InnerEvent::Pointer event =
213 BuildCallerInfo(MSG_SIM_CHANGE_DIALLING_NUMBERS_DONE, fileId, index, diallingNumberInfor, caller);
214 diallingNumbersHandler_->UpdateDiallingNumbers(infor, event);
215 }
216
CheckValueAndOperation(const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> & list,const std::shared_ptr<DiallingNumbersInfo> & info,int & index,int fileId)217 bool IccDiallingNumbersCache::CheckValueAndOperation(
218 const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> &list,
219 const std::shared_ptr<DiallingNumbersInfo> &info, int &index, int fileId)
220 {
221 if (index == ADD_FLAG) { // insert into nullpos
222 int count = 0;
223 for (auto it = list->begin(); it != list->end(); it++) {
224 std::shared_ptr<DiallingNumbersInfo> &item = *it;
225 count++;
226 if (item->IsEmpty()) { // find first null position for save
227 index = count;
228 return true;
229 }
230 }
231 } else {
232 auto iter = diallingNumberFileList_.find(fileId);
233 if (iter != diallingNumberFileList_.end()) {
234 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> &vc = iter->second;
235 int size = static_cast<int>(vc->size());
236 if ((index < 1) || (index > size)) { // check index range
237 TELEPHONY_LOGE("error index!!");
238 return false;
239 }
240 }
241 // check unnormal opearion del or update
242 for (auto it = list->begin(); it != list->end(); it++) {
243 std::shared_ptr<DiallingNumbersInfo> &item = *it;
244 if (item->GetIndex() == index && item->IsEmpty()) {
245 TELEPHONY_LOGE("update or del on null pos, invalid operation!!");
246 return false;
247 }
248 }
249 }
250 return true;
251 }
252
SearchIndexByNameAndNumber(const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> & list,const std::shared_ptr<DiallingNumbersInfo> & info,int & index)253 void IccDiallingNumbersCache::SearchIndexByNameAndNumber(
254 const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> &list,
255 const std::shared_ptr<DiallingNumbersInfo> &info, int &index)
256 {
257 for (auto it = list->begin(); it != list->end(); it++) {
258 std::shared_ptr<DiallingNumbersInfo> &item = *it;
259 if (item == nullptr) {
260 continue;
261 }
262 if (IsDiallingNumberEqual(info, item)) {
263 index = item->GetIndex();
264 TELEPHONY_LOGI("Search index is %{public}d", index);
265 }
266 }
267 }
268
ObtainAllDiallingNumberFiles(int fileId,int extFileId,const AppExecFwk::InnerEvent::Pointer & caller)269 void IccDiallingNumbersCache::ObtainAllDiallingNumberFiles(
270 int fileId, int extFileId, const AppExecFwk::InnerEvent::Pointer &caller)
271 {
272 TELEPHONY_LOGI("ObtainAllDiallingNumberFiles fileId: %{public}d %{public}d", fileId, extFileId);
273 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> result = LoadReadyDiallingNumbers(fileId);
274
275 if (result != nullptr && caller != nullptr) {
276 std::shared_ptr<void> object = nullptr;
277 TELEPHONY_LOGI("ObtainAllDiallingNumberFiles has already loaded");
278 SendBackResult(caller, result, object);
279 return;
280 }
281
282 if (fileId == ELEMENTARY_FILE_PBR) {
283 TELEPHONY_LOGI("ObtainAllDiallingNumberFiles start usim adn");
284 AppExecFwk::InnerEvent::Pointer pointer = CreateUsimPointer(MSG_SIM_OBTAIN_PBR_DETAILS_DONE, fileId, caller);
285 usimDiallingNumberSrv_->ObtainUsimElementaryFiles(pointer);
286 } else {
287 AppExecFwk::InnerEvent::Pointer event = BuildCallerInfo(
288 MSG_SIM_OBTAIN_ADN_DETAILS_DONE, fileId, 0, nullptr, caller);
289 diallingNumbersHandler_->GetAllDiallingNumbers(fileId, extFileId, event);
290 }
291 }
292
SendExceptionResult(const AppExecFwk::InnerEvent::Pointer & caller,int errCode)293 void IccDiallingNumbersCache::SendExceptionResult(const AppExecFwk::InnerEvent::Pointer &caller, int errCode)
294 {
295 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingNumberList = nullptr;
296 std::shared_ptr<HRilRadioResponseInfo> responseInfo = std::make_shared<HRilRadioResponseInfo>();
297 responseInfo->error = static_cast<Telephony::HRilErrType>(errCode);
298 std::shared_ptr<void> exception = static_cast<std::shared_ptr<void>>(responseInfo);
299 SendBackResult(caller, diallingNumberList, exception);
300 }
301
SendBackResult(const AppExecFwk::InnerEvent::Pointer & callPointer,const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> & ar,const std::shared_ptr<void> & object)302 void IccDiallingNumbersCache::SendBackResult(const AppExecFwk::InnerEvent::Pointer &callPointer,
303 const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> &ar,
304 const std::shared_ptr<void> &object)
305 {
306 if (callPointer == nullptr) {
307 TELEPHONY_LOGE("callPointer is null pointer");
308 return;
309 }
310 auto owner = callPointer->GetOwner();
311 uint32_t id = callPointer->GetInnerEventId();
312 std::unique_ptr<ResultObtain> fd = callPointer->GetUniqueObject<ResultObtain>();
313 std::unique_ptr<ResponseResult> data = std::make_unique<ResponseResult>(fd.get());
314 data->result = static_cast<std::shared_ptr<void>>(ar);
315 data->exception = object;
316 if (owner != nullptr) {
317 TelEventHandler::SendTelEvent(owner, id, data);
318 } else {
319 TELEPHONY_LOGE("IccDiallingNumbersCache::SendBackResult null owner");
320 }
321 TELEPHONY_LOGD("IccDiallingNumbersCache::SendBackResult send end");
322 }
323
SendUpdateResult(const AppExecFwk::InnerEvent::Pointer & response,const std::shared_ptr<void> & object)324 void IccDiallingNumbersCache::SendUpdateResult(
325 const AppExecFwk::InnerEvent::Pointer &response, const std::shared_ptr<void> &object)
326 {
327 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingNumbers = nullptr;
328 SendBackResult(response, diallingNumbers, object);
329 }
330
BuildCallerInfo(int eventid,int efId,int index,std::shared_ptr<void> pobj,const AppExecFwk::InnerEvent::Pointer & caller)331 AppExecFwk::InnerEvent::Pointer IccDiallingNumbersCache::BuildCallerInfo(
332 int eventid, int efId, int index, std::shared_ptr<void> pobj, const AppExecFwk::InnerEvent::Pointer &caller)
333 {
334 std::unique_ptr<DiallingNumbersHandleHolder> holder = std::make_unique<DiallingNumbersHandleHolder>();
335 holder->fileID = efId;
336 holder->index = index;
337 holder->diallingNumber = pobj;
338 holder->callerCache = std::make_shared<PointerWrapper>();
339 holder->callerCache->caller = std::move(const_cast<AppExecFwk::InnerEvent::Pointer &>(caller));
340 int eventParam = 0;
341 AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventid, holder, eventParam);
342 if (event == nullptr) {
343 TELEPHONY_LOGE("event is nullptr!");
344 return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
345 }
346 event->SetOwner(shared_from_this());
347 return event;
348 }
349
CreateUsimPointer(int eventid,int efId,const AppExecFwk::InnerEvent::Pointer & caller)350 AppExecFwk::InnerEvent::Pointer IccDiallingNumbersCache::CreateUsimPointer(
351 int eventid, int efId, const AppExecFwk::InnerEvent::Pointer &caller)
352 {
353 std::unique_ptr<UsimFetcher> holder = std::make_unique<UsimFetcher>();
354 holder->fileID = efId;
355 holder->callerCache = std::make_shared<PointerWrapper>();
356 holder->callerCache->caller = std::move(const_cast<AppExecFwk::InnerEvent::Pointer &>(caller));
357 int eventParam = 0;
358 AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventid, holder, eventParam);
359 if (event == nullptr) {
360 TELEPHONY_LOGE("event is nullptr!");
361 return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
362 }
363 event->SetOwner(shared_from_this());
364 return event;
365 }
366
IsDiallingNumberEqual(const std::shared_ptr<DiallingNumbersInfo> & src,const std::shared_ptr<DiallingNumbersInfo> & dest)367 bool IccDiallingNumbersCache::IsDiallingNumberEqual(
368 const std::shared_ptr<DiallingNumbersInfo> &src, const std::shared_ptr<DiallingNumbersInfo> &dest)
369 {
370 if (src == nullptr) {
371 TELEPHONY_LOGE("src is nullptr!");
372 return false;
373 }
374 return (StringEqual(src->name_, dest->name_) &&
375 StringEqual(src->number_, dest->number_) && ArrayEqual(src->emails_, dest->emails_));
376 }
377
StringEqual(const std::u16string & s1,const std::u16string & s2)378 bool IccDiallingNumbersCache::StringEqual(const std::u16string &s1, const std::u16string &s2)
379 {
380 return s1.compare(s2) == 0;
381 }
382
ArrayEqual(const std::vector<std::u16string> & mailsSrc,const std::vector<std::u16string> & mailsDest)383 bool IccDiallingNumbersCache::ArrayEqual(
384 const std::vector<std::u16string> &mailsSrc, const std::vector<std::u16string> &mailsDest)
385 {
386 return std::equal(mailsSrc.begin(), mailsSrc.end(), mailsDest.begin(), mailsDest.end());
387 }
388
InitFileTypeMap()389 void IccDiallingNumbersCache::InitFileTypeMap()
390 {
391 extTypeMap_[ELEMENTARY_FILE_MBDN] = ELEMENTARY_FILE_EXT6;
392 extTypeMap_[ELEMENTARY_FILE_ADN] = ELEMENTARY_FILE_EXT1;
393 extTypeMap_[ELEMENTARY_FILE_SDN] = ELEMENTARY_FILE_EXT3;
394 extTypeMap_[ELEMENTARY_FILE_FDN] = ELEMENTARY_FILE_EXT2;
395 extTypeMap_[ELEMENTARY_FILE_MSISDN] = ELEMENTARY_FILE_EXT1;
396 extTypeMap_[ELEMENTARY_FILE_PBR] = 0;
397 }
398 } // namespace Telephony
399 } // namespace OHOS
400