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_manager.h"
17
18 #include "core_service_errors.h"
19 #include "radio_event.h"
20 #include "telephony_errors.h"
21
22 namespace OHOS {
23 namespace Telephony {
24 constexpr static const int32_t WAIT_TIME_SECOND = 1;
25 constexpr static const int32_t WAIT_QUERY_TIME_SECOND = 30;
26
IccDiallingNumbersManager(std::weak_ptr<SimFileManager> simFileManager,std::shared_ptr<SimStateManager> simState)27 IccDiallingNumbersManager::IccDiallingNumbersManager(
28 std::weak_ptr<SimFileManager> simFileManager, std::shared_ptr<SimStateManager> simState)
29 : TelEventHandler("IccDiallingNumbersManager"), simFileManager_(simFileManager), simStateManager_(simState)
30 {}
31
Init()32 void IccDiallingNumbersManager::Init()
33 {
34 TELEPHONY_LOGI("IccDiallingNumbersManager::Init() started ");
35 if (stateDiallingNumbers_ == HandleRunningState::STATE_RUNNING) {
36 TELEPHONY_LOGI("IccDiallingNumbersManager::Init eventLoopDiallingNumbers_ started.");
37 return;
38 }
39
40 auto simFileManager = simFileManager_.lock();
41 if (simFileManager == nullptr) {
42 TELEPHONY_LOGE("SimFileManager null pointer");
43 return;
44 }
45
46 diallingNumbersCache_ = std::make_shared<IccDiallingNumbersCache>(simFileManager);
47 if (diallingNumbersCache_ == nullptr) {
48 TELEPHONY_LOGE("simFile create nullptr.");
49 return;
50 }
51
52 stateDiallingNumbers_ = HandleRunningState::STATE_RUNNING;
53
54 diallingNumbersCache_->Init();
55 simFileManager->RegisterCoreNotify(shared_from_this(), RadioEvent::RADIO_SIM_RECORDS_LOADED);
56 TELEPHONY_LOGI("Init() end");
57 }
58
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)59 void IccDiallingNumbersManager::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
60 {
61 if (event == nullptr) {
62 TELEPHONY_LOGE("event is nullptr!");
63 return;
64 }
65 uint32_t id = event->GetInnerEventId();
66 TELEPHONY_LOGD("IccDiallingNumbersManager ProcessEvent Id is %{public}d", id);
67 switch (id) {
68 case MSG_SIM_DIALLING_NUMBERS_GET_DONE:
69 ProcessLoadDone(event);
70 break;
71 case MSG_SIM_DIALLING_NUMBERS_UPDATE_DONE:
72 ProcessUpdateDone(event);
73 break;
74 case MSG_SIM_DIALLING_NUMBERS_WRITE_DONE:
75 ProcessWriteDone(event);
76 break;
77 case MSG_SIM_DIALLING_NUMBERS_DELETE_DONE:
78 ProcessDeleteDone(event);
79 break;
80 case RadioEvent::RADIO_SIM_RECORDS_LOADED:
81 InitFdnCache();
82 break;
83 default:
84 break;
85 }
86 }
87
InitFdnCache()88 void IccDiallingNumbersManager::InitFdnCache()
89 {
90 TELEPHONY_LOGI("IccDiallingNumbersManager::InitFdnCache start");
91 if (diallingNumbersCache_ != nullptr) {
92 diallingNumbersCache_->ClearDiallingNumberCache();
93 }
94 TelFFRTUtils::Submit([&]() {
95 std::vector<std::shared_ptr<DiallingNumbersInfo>> diallingNumbers;
96 QueryIccDiallingNumbers(DiallingNumbersInfo::SIM_FDN, diallingNumbers);
97 });
98 }
99
ProcessLoadDone(const AppExecFwk::InnerEvent::Pointer & event)100 void IccDiallingNumbersManager::ProcessLoadDone(const AppExecFwk::InnerEvent::Pointer &event)
101 {
102 TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessLoadDone: start");
103 std::unique_ptr<ResponseResult> object = event->GetUniqueObject<ResponseResult>();
104 if (object != nullptr) {
105 if (object->exception == nullptr) {
106 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingNumberList =
107 std::static_pointer_cast<std::vector<std::shared_ptr<DiallingNumbersInfo>>>(object->result);
108 if (diallingNumberList != nullptr) {
109 FillResults(diallingNumberList);
110 } else {
111 TELEPHONY_LOGE("ProcessDiallingNumberLoadDone: get null vectors!!!");
112 }
113 } else {
114 TELEPHONY_LOGE("ProcessLoadDone: icc diallingnumbers get exception result");
115 }
116 } else {
117 TELEPHONY_LOGE("ProcessDiallingNumberLoadDone: get null pointer!!!");
118 }
119 TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessLoadDone: end");
120 hasQueryEventDone_ = true;
121 processWait_.notify_all();
122 }
123
ProcessUpdateDone(const AppExecFwk::InnerEvent::Pointer & event)124 void IccDiallingNumbersManager::ProcessUpdateDone(const AppExecFwk::InnerEvent::Pointer &event)
125 {
126 std::unique_ptr<ResponseResult> object = event->GetUniqueObject<ResponseResult>();
127 if (object != nullptr && object->exception != nullptr) {
128 std::shared_ptr<HRilRadioResponseInfo> responseInfo =
129 std::static_pointer_cast<HRilRadioResponseInfo>(object->exception);
130 TELEPHONY_LOGE("IccDiallingNumbersManager::ProcessUpdateDone error %{public}d", responseInfo->error);
131 hasEventDone_ = (responseInfo->error == HRilErrType::NONE);
132 } else {
133 hasEventDone_ = true;
134 }
135 TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessUpdateDone: end");
136 processWait_.notify_all();
137 }
138
ProcessWriteDone(const AppExecFwk::InnerEvent::Pointer & event)139 void IccDiallingNumbersManager::ProcessWriteDone(const AppExecFwk::InnerEvent::Pointer &event)
140 {
141 std::unique_ptr<ResponseResult> object = event->GetUniqueObject<ResponseResult>();
142 if (object != nullptr && object->exception != nullptr) {
143 std::shared_ptr<HRilRadioResponseInfo> responseInfo =
144 std::static_pointer_cast<HRilRadioResponseInfo>(object->exception);
145 TELEPHONY_LOGE("IccDiallingNumbersManager::ProcessWriteDone error %{public}d", responseInfo->error);
146 hasEventDone_ = (responseInfo->error == HRilErrType::NONE);
147 } else {
148 hasEventDone_ = true;
149 }
150 TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessWriteDone: end");
151 processWait_.notify_all();
152 }
153
ProcessDeleteDone(const AppExecFwk::InnerEvent::Pointer & event)154 void IccDiallingNumbersManager::ProcessDeleteDone(const AppExecFwk::InnerEvent::Pointer &event)
155 {
156 std::unique_ptr<ResponseResult> object = event->GetUniqueObject<ResponseResult>();
157 if (object != nullptr && object->exception != nullptr) {
158 std::shared_ptr<HRilRadioResponseInfo> responseInfo =
159 std::static_pointer_cast<HRilRadioResponseInfo>(object->exception);
160 TELEPHONY_LOGE("IccDiallingNumbersManager::ProcessDeleteDone error %{public}d", responseInfo->error);
161 hasEventDone_ = (responseInfo->error == HRilErrType::NONE);
162 } else {
163 hasEventDone_ = true;
164 }
165 TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessDeleteDone: end");
166 processWait_.notify_all();
167 }
168
UpdateIccDiallingNumbers(int type,const std::shared_ptr<DiallingNumbersInfo> & diallingNumber)169 int32_t IccDiallingNumbersManager::UpdateIccDiallingNumbers(
170 int type, const std::shared_ptr<DiallingNumbersInfo> &diallingNumber)
171 {
172 std::unique_lock<std::mutex> lock(mtx_);
173 if (diallingNumber == nullptr) {
174 return TELEPHONY_ERR_LOCAL_PTR_NULL;
175 }
176 if (!HasSimCard()) {
177 return TELEPHONY_ERR_NO_SIM_CARD;
178 }
179 if (!IsValidType(type) || !IsValidParam(type, diallingNumber)) {
180 return TELEPHONY_ERR_ARGUMENT_INVALID;
181 }
182 int index = diallingNumber->GetIndex();
183 TELEPHONY_LOGI("UpdateIccDiallingNumbers start: %{public}d %{public}d", type, index);
184 int fileId = GetFileIdForType(type);
185 AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_SIM_DIALLING_NUMBERS_UPDATE_DONE);
186 hasEventDone_ = false;
187 diallingNumbersCache_->UpdateDiallingNumberToIcc(fileId, diallingNumber, index, false, response);
188 while (!hasEventDone_) {
189 TELEPHONY_LOGI("UpdateIccDiallingNumbers::wait(), response = false");
190 if (processWait_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
191 break;
192 }
193 }
194 TELEPHONY_LOGI("IccDiallingNumbersManager::UpdateIccDiallingNumbers OK return %{public}d", hasEventDone_);
195 return hasEventDone_ ? TELEPHONY_SUCCESS : CORE_ERR_SIM_CARD_UPDATE_FAILED;
196 }
197
DelIccDiallingNumbers(int type,const std::shared_ptr<DiallingNumbersInfo> & diallingNumber)198 int32_t IccDiallingNumbersManager::DelIccDiallingNumbers(
199 int type, const std::shared_ptr<DiallingNumbersInfo> &diallingNumber)
200 {
201 std::unique_lock<std::mutex> lock(mtx_);
202 if (diallingNumber == nullptr) {
203 return TELEPHONY_ERR_LOCAL_PTR_NULL;
204 }
205 if (!HasSimCard()) {
206 return TELEPHONY_ERR_NO_SIM_CARD;
207 }
208 if (!IsValidType(type) || !IsValidParam(type, diallingNumber)) {
209 return TELEPHONY_ERR_ARGUMENT_INVALID;
210 }
211 int index = diallingNumber->GetIndex();
212 TELEPHONY_LOGI("DelIccDiallingNumbers start: %{public}d %{public}d", type, index);
213 int fileId = GetFileIdForType(type);
214 AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_SIM_DIALLING_NUMBERS_DELETE_DONE);
215 hasEventDone_ = false;
216 diallingNumbersCache_->UpdateDiallingNumberToIcc(fileId, diallingNumber, index, true, response);
217 while (!hasEventDone_) {
218 TELEPHONY_LOGI("DelIccDiallingNumbers::wait(), response = false");
219 if (processWait_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
220 break;
221 }
222 }
223 TELEPHONY_LOGI("IccDiallingNumbersManager::DelIccDiallingNumbers OK return %{public}d", hasEventDone_);
224 return hasEventDone_ ? TELEPHONY_SUCCESS : CORE_ERR_SIM_CARD_UPDATE_FAILED;
225 }
226
AddIccDiallingNumbers(int type,const std::shared_ptr<DiallingNumbersInfo> & diallingNumber)227 int32_t IccDiallingNumbersManager::AddIccDiallingNumbers(
228 int type, const std::shared_ptr<DiallingNumbersInfo> &diallingNumber)
229 {
230 std::unique_lock<std::mutex> lock(mtx_);
231 TELEPHONY_LOGI("AddIccDiallingNumbers start:%{public}d", type);
232 if (diallingNumber == nullptr) {
233 return TELEPHONY_ERR_LOCAL_PTR_NULL;
234 }
235 if (!HasSimCard()) {
236 return TELEPHONY_ERR_NO_SIM_CARD;
237 }
238 if (!IsValidType(type) || !IsValidParam(type, diallingNumber)) {
239 return TELEPHONY_ERR_ARGUMENT_INVALID;
240 }
241 AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_SIM_DIALLING_NUMBERS_WRITE_DONE);
242 int fileId = GetFileIdForType(type);
243 hasEventDone_ = false;
244 diallingNumbersCache_->UpdateDiallingNumberToIcc(fileId, diallingNumber, ADD_FLAG, false, response);
245 while (!hasEventDone_) {
246 TELEPHONY_LOGI("AddIccDiallingNumbers::wait(), response = false");
247 if (processWait_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
248 break;
249 }
250 }
251 TELEPHONY_LOGI("IccDiallingNumbersManager::AddIccDiallingNumbers OK return %{public}d", hasEventDone_);
252 return hasEventDone_ ? TELEPHONY_SUCCESS : CORE_ERR_SIM_CARD_UPDATE_FAILED;
253 }
254
QueryIccDiallingNumbers(int type,std::vector<std::shared_ptr<DiallingNumbersInfo>> & result)255 int32_t IccDiallingNumbersManager::QueryIccDiallingNumbers(
256 int type, std::vector<std::shared_ptr<DiallingNumbersInfo>> &result)
257 {
258 std::unique_lock<std::mutex> lock(mtx_);
259 if (diallingNumbersCache_ == nullptr) {
260 return TELEPHONY_ERR_LOCAL_PTR_NULL;
261 }
262 if (!HasSimCard()) {
263 return TELEPHONY_ERR_NO_SIM_CARD;
264 }
265 if (!IsValidType(type)) {
266 return TELEPHONY_ERR_ARGUMENT_INVALID;
267 }
268 TELEPHONY_LOGI("QueryIccDiallingNumbers start:%{public}d", type);
269 if (hasQueryEventDone_) {
270 ClearRecords();
271 int fileId = GetFileIdForType(type);
272 int extensionEf = diallingNumbersCache_->ExtendedElementFile(fileId);
273 AppExecFwk::InnerEvent::Pointer event = BuildCallerInfo(MSG_SIM_DIALLING_NUMBERS_GET_DONE);
274 hasQueryEventDone_ = false;
275 diallingNumbersCache_->ObtainAllDiallingNumberFiles(fileId, extensionEf, event);
276 }
277 processWait_.wait_for(
278 lock, std::chrono::seconds(WAIT_QUERY_TIME_SECOND), [this] { return hasQueryEventDone_ == true; });
279 TELEPHONY_LOGI("QueryIccDiallingNumbers: end");
280 if (!diallingNumbersList_.empty()) {
281 result = diallingNumbersList_;
282 }
283 return hasQueryEventDone_ ? TELEPHONY_SUCCESS : CORE_ERR_SIM_CARD_LOAD_FAILED;
284 }
285
BuildCallerInfo(int eventId)286 AppExecFwk::InnerEvent::Pointer IccDiallingNumbersManager::BuildCallerInfo(int eventId)
287 {
288 std::unique_ptr<ResultObtain> object = std::make_unique<ResultObtain>();
289 int eventParam = 0;
290 AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventId, object, eventParam);
291 if (event == nullptr) {
292 TELEPHONY_LOGE("event is nullptr!");
293 return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
294 }
295 event->SetOwner(shared_from_this());
296 return event;
297 }
298
ClearRecords()299 void IccDiallingNumbersManager::ClearRecords()
300 {
301 std::vector<std::shared_ptr<DiallingNumbersInfo>> nullVector;
302 diallingNumbersList_.swap(nullVector);
303 }
304
GetFileIdForType(int fileType)305 int IccDiallingNumbersManager::GetFileIdForType(int fileType)
306 {
307 int fileId = 0;
308 if (fileType == DiallingNumbersInfo::SIM_ADN) {
309 fileId = ELEMENTARY_FILE_ADN; // ELEMENTARY_FILE_PBR for usim
310 } else if (fileType == DiallingNumbersInfo::SIM_FDN) {
311 fileId = ELEMENTARY_FILE_FDN;
312 }
313 return fileId;
314 }
315
FillResults(const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> & listInfo)316 void IccDiallingNumbersManager::FillResults(
317 const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> &listInfo)
318 {
319 TELEPHONY_LOGI("IccDiallingNumbersManager::FillResults %{public}zu", listInfo->size());
320 for (auto it = listInfo->begin(); it != listInfo->end(); it++) {
321 std::shared_ptr<DiallingNumbersInfo> item = *it;
322 if (!item->IsEmpty()) {
323 diallingNumbersList_.push_back(item);
324 }
325 }
326 TELEPHONY_LOGI("IccDiallingNumbersManager::FillResults end");
327 }
328
IsValidType(int type)329 bool IccDiallingNumbersManager::IsValidType(int type)
330 {
331 switch (type) {
332 case DiallingNumbersInfo::SIM_ADN:
333 case DiallingNumbersInfo::SIM_FDN:
334 return true;
335 default:
336 return false;
337 }
338 }
339
CreateInstance(std::weak_ptr<SimFileManager> simFile,std::shared_ptr<SimStateManager> simState)340 std::shared_ptr<IccDiallingNumbersManager> IccDiallingNumbersManager::CreateInstance(
341 std::weak_ptr<SimFileManager> simFile, std::shared_ptr<SimStateManager> simState)
342 {
343 if (simFile.lock() == nullptr) {
344 TELEPHONY_LOGE("IccDiallingNumbersManager::Init SimFileManager null pointer");
345 return nullptr;
346 }
347 std::shared_ptr<IccDiallingNumbersManager> manager = std::make_shared<IccDiallingNumbersManager>(simFile, simState);
348 if (manager == nullptr) {
349 TELEPHONY_LOGE("IccDiallingNumbersManager::Init manager create nullptr.");
350 return nullptr;
351 }
352 return manager;
353 }
354
HasSimCard()355 bool IccDiallingNumbersManager::HasSimCard()
356 {
357 return (simStateManager_ != nullptr) ? simStateManager_->HasSimCard() : false;
358 }
359
IsValidParam(int type,const std::shared_ptr<DiallingNumbersInfo> & info)360 bool IccDiallingNumbersManager::IsValidParam(int type, const std::shared_ptr<DiallingNumbersInfo> &info)
361 {
362 if (type == DiallingNumbersInfo::SIM_FDN) {
363 return !(info->pin2_.empty());
364 } else {
365 return true;
366 }
367 }
368
~IccDiallingNumbersManager()369 IccDiallingNumbersManager::~IccDiallingNumbersManager() {}
370 } // namespace Telephony
371 } // namespace OHOS
372