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