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<RadioResponseInfo> responseInfo =
144 std::static_pointer_cast<RadioResponseInfo>(fd->exception);
145 if (responseInfo == nullptr) {
146 TELEPHONY_LOGE("responseInfo is nullptr");
147 return;
148 }
149 if (responseInfo->error == ErrType::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 if (diallingNumbersHandler_ != nullptr) {
215 diallingNumbersHandler_->UpdateDiallingNumbers(infor, event);
216 }
217 }
218
CheckValueAndOperation(const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> & list,const std::shared_ptr<DiallingNumbersInfo> & info,int & index,int fileId)219 bool IccDiallingNumbersCache::CheckValueAndOperation(
220 const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> &list,
221 const std::shared_ptr<DiallingNumbersInfo> &info, int &index, int fileId)
222 {
223 if (index == ADD_FLAG) { // insert into nullpos
224 int count = 0;
225 for (auto it = list->begin(); it != list->end(); it++) {
226 std::shared_ptr<DiallingNumbersInfo> &item = *it;
227 count++;
228 if (item->IsEmpty()) { // find first null position for save
229 index = count;
230 return true;
231 }
232 }
233 } else {
234 auto iter = diallingNumberFileList_.find(fileId);
235 if (iter != diallingNumberFileList_.end()) {
236 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> &vc = iter->second;
237 int size = static_cast<int>(vc->size());
238 if ((index < 1) || (index > size)) { // check index range
239 TELEPHONY_LOGE("error index!!");
240 return false;
241 }
242 }
243 // check unnormal opearion del or update
244 for (auto it = list->begin(); it != list->end(); it++) {
245 std::shared_ptr<DiallingNumbersInfo> &item = *it;
246 if (item->GetIndex() == index && item->IsEmpty()) {
247 TELEPHONY_LOGE("update or del on null pos, invalid operation!!");
248 return false;
249 }
250 }
251 }
252 return true;
253 }
254
SearchIndexByNameAndNumber(const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> & list,const std::shared_ptr<DiallingNumbersInfo> & info,int & index)255 void IccDiallingNumbersCache::SearchIndexByNameAndNumber(
256 const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> &list,
257 const std::shared_ptr<DiallingNumbersInfo> &info, int &index)
258 {
259 for (auto it = list->begin(); it != list->end(); it++) {
260 std::shared_ptr<DiallingNumbersInfo> &item = *it;
261 if (item == nullptr) {
262 continue;
263 }
264 if (IsDiallingNumberEqual(info, item)) {
265 index = item->GetIndex();
266 TELEPHONY_LOGI("Search index is %{public}d", index);
267 }
268 }
269 }
270
ObtainAllDiallingNumberFiles(int fileId,int extFileId,const AppExecFwk::InnerEvent::Pointer & caller)271 void IccDiallingNumbersCache::ObtainAllDiallingNumberFiles(
272 int fileId, int extFileId, const AppExecFwk::InnerEvent::Pointer &caller)
273 {
274 TELEPHONY_LOGI("ObtainAllDiallingNumberFiles fileId: %{public}d %{public}d", fileId, extFileId);
275 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> result = LoadReadyDiallingNumbers(fileId);
276
277 if (result != nullptr && caller != nullptr) {
278 std::shared_ptr<void> object = nullptr;
279 TELEPHONY_LOGI("ObtainAllDiallingNumberFiles has already loaded");
280 SendBackResult(caller, result, object);
281 return;
282 }
283
284 if (fileId == ELEMENTARY_FILE_PBR) {
285 TELEPHONY_LOGI("ObtainAllDiallingNumberFiles start usim adn");
286 AppExecFwk::InnerEvent::Pointer pointer = CreateUsimPointer(MSG_SIM_OBTAIN_PBR_DETAILS_DONE, fileId, caller);
287 if (usimDiallingNumberSrv_ != nullptr) {
288 usimDiallingNumberSrv_->ObtainUsimElementaryFiles(pointer);
289 }
290 } else {
291 AppExecFwk::InnerEvent::Pointer event = BuildCallerInfo(
292 MSG_SIM_OBTAIN_ADN_DETAILS_DONE, fileId, 0, nullptr, caller);
293 if (diallingNumbersHandler_ != nullptr) {
294 diallingNumbersHandler_->GetAllDiallingNumbers(fileId, extFileId, event);
295 }
296 }
297 }
298
SendExceptionResult(const AppExecFwk::InnerEvent::Pointer & caller,int errCode)299 void IccDiallingNumbersCache::SendExceptionResult(const AppExecFwk::InnerEvent::Pointer &caller, int errCode)
300 {
301 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingNumberList = nullptr;
302 std::shared_ptr<RadioResponseInfo> responseInfo = std::make_shared<RadioResponseInfo>();
303 responseInfo->error = static_cast<Telephony::ErrType>(errCode);
304 std::shared_ptr<void> exception = static_cast<std::shared_ptr<void>>(responseInfo);
305 SendBackResult(caller, diallingNumberList, exception);
306 }
307
SendBackResult(const AppExecFwk::InnerEvent::Pointer & callPointer,const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> & ar,const std::shared_ptr<void> & object)308 void IccDiallingNumbersCache::SendBackResult(const AppExecFwk::InnerEvent::Pointer &callPointer,
309 const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> &ar,
310 const std::shared_ptr<void> &object)
311 {
312 if (callPointer == nullptr) {
313 TELEPHONY_LOGE("callPointer is null pointer");
314 return;
315 }
316 auto owner = callPointer->GetOwner();
317 uint32_t id = callPointer->GetInnerEventId();
318 std::unique_ptr<ResultObtain> fd = callPointer->GetUniqueObject<ResultObtain>();
319 if (fd == nullptr) {
320 TELEPHONY_LOGE("fd is nullptr!");
321 return;
322 }
323 std::unique_ptr<ResponseResult> data = std::make_unique<ResponseResult>(fd.get());
324 if (data == nullptr) {
325 TELEPHONY_LOGE("data is nullptr!");
326 return;
327 }
328 data->result = static_cast<std::shared_ptr<void>>(ar);
329 data->exception = object;
330 if (owner != nullptr) {
331 TelEventHandler::SendTelEvent(owner, id, data);
332 } else {
333 TELEPHONY_LOGE("IccDiallingNumbersCache::SendBackResult null owner");
334 }
335 TELEPHONY_LOGD("IccDiallingNumbersCache::SendBackResult send end");
336 }
337
SendUpdateResult(const AppExecFwk::InnerEvent::Pointer & response,const std::shared_ptr<void> & object)338 void IccDiallingNumbersCache::SendUpdateResult(
339 const AppExecFwk::InnerEvent::Pointer &response, const std::shared_ptr<void> &object)
340 {
341 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingNumbers = nullptr;
342 SendBackResult(response, diallingNumbers, object);
343 }
344
BuildCallerInfo(int eventid,int efId,int index,std::shared_ptr<void> pobj,const AppExecFwk::InnerEvent::Pointer & caller)345 AppExecFwk::InnerEvent::Pointer IccDiallingNumbersCache::BuildCallerInfo(
346 int eventid, int efId, int index, std::shared_ptr<void> pobj, const AppExecFwk::InnerEvent::Pointer &caller)
347 {
348 std::unique_ptr<DiallingNumbersHandleHolder> holder = std::make_unique<DiallingNumbersHandleHolder>();
349 holder->fileID = efId;
350 holder->index = index;
351 holder->diallingNumber = pobj;
352 holder->callerCache = std::make_shared<PointerWrapper>();
353 holder->callerCache->caller = std::move(const_cast<AppExecFwk::InnerEvent::Pointer &>(caller));
354 int eventParam = 0;
355 AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventid, holder, eventParam);
356 if (event == nullptr) {
357 TELEPHONY_LOGE("event is nullptr!");
358 return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
359 }
360 event->SetOwner(shared_from_this());
361 return event;
362 }
363
CreateUsimPointer(int eventid,int efId,const AppExecFwk::InnerEvent::Pointer & caller)364 AppExecFwk::InnerEvent::Pointer IccDiallingNumbersCache::CreateUsimPointer(
365 int eventid, int efId, const AppExecFwk::InnerEvent::Pointer &caller)
366 {
367 std::unique_ptr<UsimFetcher> holder = std::make_unique<UsimFetcher>();
368 holder->fileID = efId;
369 holder->callerCache = std::make_shared<PointerWrapper>();
370 holder->callerCache->caller = std::move(const_cast<AppExecFwk::InnerEvent::Pointer &>(caller));
371 int eventParam = 0;
372 AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventid, holder, eventParam);
373 if (event == nullptr) {
374 TELEPHONY_LOGE("event is nullptr!");
375 return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
376 }
377 event->SetOwner(shared_from_this());
378 return event;
379 }
380
IsDiallingNumberEqual(const std::shared_ptr<DiallingNumbersInfo> & src,const std::shared_ptr<DiallingNumbersInfo> & dest)381 bool IccDiallingNumbersCache::IsDiallingNumberEqual(
382 const std::shared_ptr<DiallingNumbersInfo> &src, const std::shared_ptr<DiallingNumbersInfo> &dest)
383 {
384 if (src == nullptr) {
385 TELEPHONY_LOGE("src is nullptr!");
386 return false;
387 }
388 return (StringEqual(src->name_, dest->name_) &&
389 StringEqual(src->number_, dest->number_) && ArrayEqual(src->emails_, dest->emails_));
390 }
391
StringEqual(const std::u16string & s1,const std::u16string & s2)392 bool IccDiallingNumbersCache::StringEqual(const std::u16string &s1, const std::u16string &s2)
393 {
394 return s1.compare(s2) == 0;
395 }
396
ArrayEqual(const std::vector<std::u16string> & mailsSrc,const std::vector<std::u16string> & mailsDest)397 bool IccDiallingNumbersCache::ArrayEqual(
398 const std::vector<std::u16string> &mailsSrc, const std::vector<std::u16string> &mailsDest)
399 {
400 return std::equal(mailsSrc.begin(), mailsSrc.end(), mailsDest.begin(), mailsDest.end());
401 }
402
InitFileTypeMap()403 void IccDiallingNumbersCache::InitFileTypeMap()
404 {
405 extTypeMap_[ELEMENTARY_FILE_MBDN] = ELEMENTARY_FILE_EXT6;
406 extTypeMap_[ELEMENTARY_FILE_ADN] = ELEMENTARY_FILE_EXT1;
407 extTypeMap_[ELEMENTARY_FILE_SDN] = ELEMENTARY_FILE_EXT3;
408 extTypeMap_[ELEMENTARY_FILE_FDN] = ELEMENTARY_FILE_EXT2;
409 extTypeMap_[ELEMENTARY_FILE_MSISDN] = ELEMENTARY_FILE_EXT1;
410 extTypeMap_[ELEMENTARY_FILE_PBR] = 0;
411 }
412 } // namespace Telephony
413 } // namespace OHOS
414