• 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 
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