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 default:
81 break;
82 }
83 }
84
ProcessLoadDone(const AppExecFwk::InnerEvent::Pointer & event)85 void IccDiallingNumbersManager::ProcessLoadDone(const AppExecFwk::InnerEvent::Pointer &event)
86 {
87 TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessLoadDone: start");
88 std::unique_ptr<ResponseResult> object = event->GetUniqueObject<ResponseResult>();
89 if (object != nullptr) {
90 if (object->exception == nullptr) {
91 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingNumberList =
92 std::static_pointer_cast<std::vector<std::shared_ptr<DiallingNumbersInfo>>>(object->result);
93 if (diallingNumberList != nullptr) {
94 FillResults(diallingNumberList);
95 } else {
96 TELEPHONY_LOGE("ProcessDiallingNumberLoadDone: get null vectors!!!");
97 }
98 } else {
99 TELEPHONY_LOGE("ProcessLoadDone: icc diallingnumbers get exception result");
100 }
101 } else {
102 TELEPHONY_LOGE("ProcessDiallingNumberLoadDone: get null pointer!!!");
103 }
104 TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessLoadDone: end");
105 hasQueryEventDone_ = true;
106 processWait_.notify_all();
107 }
108
ProcessUpdateDone(const AppExecFwk::InnerEvent::Pointer & event)109 void IccDiallingNumbersManager::ProcessUpdateDone(const AppExecFwk::InnerEvent::Pointer &event)
110 {
111 std::unique_ptr<ResponseResult> object = event->GetUniqueObject<ResponseResult>();
112 if (object != nullptr && object->exception != nullptr) {
113 std::shared_ptr<RadioResponseInfo> responseInfo =
114 std::static_pointer_cast<RadioResponseInfo>(object->exception);
115 TELEPHONY_LOGE("IccDiallingNumbersManager::ProcessUpdateDone error %{public}d", responseInfo->error);
116 hasEventDone_ = (responseInfo->error == ErrType::NONE);
117 } else {
118 hasEventDone_ = true;
119 }
120 TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessUpdateDone: end");
121 processWait_.notify_all();
122 }
123
ProcessWriteDone(const AppExecFwk::InnerEvent::Pointer & event)124 void IccDiallingNumbersManager::ProcessWriteDone(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<RadioResponseInfo> responseInfo =
129 std::static_pointer_cast<RadioResponseInfo>(object->exception);
130 TELEPHONY_LOGE("IccDiallingNumbersManager::ProcessWriteDone error %{public}d", responseInfo->error);
131 hasEventDone_ = (responseInfo->error == ErrType::NONE);
132 } else {
133 hasEventDone_ = true;
134 }
135 TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessWriteDone: end");
136 processWait_.notify_all();
137 }
138
ProcessDeleteDone(const AppExecFwk::InnerEvent::Pointer & event)139 void IccDiallingNumbersManager::ProcessDeleteDone(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<RadioResponseInfo> responseInfo =
144 std::static_pointer_cast<RadioResponseInfo>(object->exception);
145 TELEPHONY_LOGE("IccDiallingNumbersManager::ProcessDeleteDone error %{public}d", responseInfo->error);
146 hasEventDone_ = (responseInfo->error == ErrType::NONE);
147 } else {
148 hasEventDone_ = true;
149 }
150 TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessDeleteDone: end");
151 processWait_.notify_all();
152 }
153
UpdateIccDiallingNumbers(int type,const std::shared_ptr<DiallingNumbersInfo> & diallingNumber)154 int32_t IccDiallingNumbersManager::UpdateIccDiallingNumbers(
155 int type, const std::shared_ptr<DiallingNumbersInfo> &diallingNumber)
156 {
157 std::unique_lock<std::mutex> lock(mtx_);
158 if (diallingNumber == nullptr) {
159 return TELEPHONY_ERR_LOCAL_PTR_NULL;
160 }
161 if (!HasSimCard()) {
162 return TELEPHONY_ERR_NO_SIM_CARD;
163 }
164 if (!IsValidType(type) || !IsValidParam(type, diallingNumber)) {
165 return TELEPHONY_ERR_ARGUMENT_INVALID;
166 }
167 int index = diallingNumber->GetIndex();
168 TELEPHONY_LOGI("UpdateIccDiallingNumbers start: %{public}d %{public}d", type, index);
169 int fileId = GetFileIdForType(type);
170 AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_SIM_DIALLING_NUMBERS_UPDATE_DONE);
171 hasEventDone_ = false;
172 diallingNumbersCache_->UpdateDiallingNumberToIcc(fileId, diallingNumber, index, false, response);
173 while (!hasEventDone_) {
174 TELEPHONY_LOGI("UpdateIccDiallingNumbers::wait(), response = false");
175 if (processWait_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
176 break;
177 }
178 }
179 TELEPHONY_LOGI("IccDiallingNumbersManager::UpdateIccDiallingNumbers OK return %{public}d", hasEventDone_);
180 return hasEventDone_ ? TELEPHONY_SUCCESS : CORE_ERR_SIM_CARD_UPDATE_FAILED;
181 }
182
DelIccDiallingNumbers(int type,const std::shared_ptr<DiallingNumbersInfo> & diallingNumber)183 int32_t IccDiallingNumbersManager::DelIccDiallingNumbers(
184 int type, const std::shared_ptr<DiallingNumbersInfo> &diallingNumber)
185 {
186 std::unique_lock<std::mutex> lock(mtx_);
187 if (diallingNumber == nullptr) {
188 return TELEPHONY_ERR_LOCAL_PTR_NULL;
189 }
190 if (!HasSimCard()) {
191 return TELEPHONY_ERR_NO_SIM_CARD;
192 }
193 if (!IsValidType(type) || !IsValidParam(type, diallingNumber)) {
194 return TELEPHONY_ERR_ARGUMENT_INVALID;
195 }
196 int index = diallingNumber->GetIndex();
197 TELEPHONY_LOGI("DelIccDiallingNumbers start: %{public}d %{public}d", type, index);
198 int fileId = GetFileIdForType(type);
199 AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_SIM_DIALLING_NUMBERS_DELETE_DONE);
200 hasEventDone_ = false;
201 diallingNumbersCache_->UpdateDiallingNumberToIcc(fileId, diallingNumber, index, true, response);
202 while (!hasEventDone_) {
203 TELEPHONY_LOGI("DelIccDiallingNumbers::wait(), response = false");
204 if (processWait_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
205 break;
206 }
207 }
208 TELEPHONY_LOGI("IccDiallingNumbersManager::DelIccDiallingNumbers OK return %{public}d", hasEventDone_);
209 return hasEventDone_ ? TELEPHONY_SUCCESS : CORE_ERR_SIM_CARD_UPDATE_FAILED;
210 }
211
AddIccDiallingNumbers(int type,const std::shared_ptr<DiallingNumbersInfo> & diallingNumber)212 int32_t IccDiallingNumbersManager::AddIccDiallingNumbers(
213 int type, const std::shared_ptr<DiallingNumbersInfo> &diallingNumber)
214 {
215 std::unique_lock<std::mutex> lock(mtx_);
216 TELEPHONY_LOGI("AddIccDiallingNumbers start:%{public}d", type);
217 if (diallingNumber == nullptr) {
218 return TELEPHONY_ERR_LOCAL_PTR_NULL;
219 }
220 if (!HasSimCard()) {
221 return TELEPHONY_ERR_NO_SIM_CARD;
222 }
223 if (!IsValidType(type) || !IsValidParam(type, diallingNumber)) {
224 return TELEPHONY_ERR_ARGUMENT_INVALID;
225 }
226 AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_SIM_DIALLING_NUMBERS_WRITE_DONE);
227 int fileId = GetFileIdForType(type);
228 hasEventDone_ = false;
229 diallingNumbersCache_->UpdateDiallingNumberToIcc(fileId, diallingNumber, ADD_FLAG, false, response);
230 while (!hasEventDone_) {
231 TELEPHONY_LOGI("AddIccDiallingNumbers::wait(), response = false");
232 if (processWait_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
233 break;
234 }
235 }
236 TELEPHONY_LOGI("IccDiallingNumbersManager::AddIccDiallingNumbers OK return %{public}d", hasEventDone_);
237 return hasEventDone_ ? TELEPHONY_SUCCESS : CORE_ERR_SIM_CARD_UPDATE_FAILED;
238 }
239
QueryIccDiallingNumbers(int type,std::vector<std::shared_ptr<DiallingNumbersInfo>> & result)240 int32_t IccDiallingNumbersManager::QueryIccDiallingNumbers(
241 int type, std::vector<std::shared_ptr<DiallingNumbersInfo>> &result)
242 {
243 std::unique_lock<std::mutex> lock(mtx_);
244 if (diallingNumbersCache_ == nullptr) {
245 return TELEPHONY_ERR_LOCAL_PTR_NULL;
246 }
247 if (!HasSimCard()) {
248 return TELEPHONY_ERR_NO_SIM_CARD;
249 }
250 if (!IsValidType(type)) {
251 return TELEPHONY_ERR_ARGUMENT_INVALID;
252 }
253 TELEPHONY_LOGI("QueryIccDiallingNumbers start:%{public}d", type);
254 if (hasQueryEventDone_) {
255 ClearRecords();
256 int fileId = GetFileIdForType(type);
257 int extensionEf = diallingNumbersCache_->ExtendedElementFile(fileId);
258 AppExecFwk::InnerEvent::Pointer event = BuildCallerInfo(MSG_SIM_DIALLING_NUMBERS_GET_DONE);
259 hasQueryEventDone_ = false;
260 diallingNumbersCache_->ObtainAllDiallingNumberFiles(fileId, extensionEf, event);
261 }
262 processWait_.wait_for(
263 lock, std::chrono::seconds(WAIT_QUERY_TIME_SECOND), [this] { return hasQueryEventDone_ == true; });
264 TELEPHONY_LOGI("QueryIccDiallingNumbers: end");
265 if (!diallingNumbersList_.empty()) {
266 result = diallingNumbersList_;
267 }
268 return hasQueryEventDone_ ? TELEPHONY_SUCCESS : CORE_ERR_SIM_CARD_LOAD_FAILED;
269 }
270
BuildCallerInfo(int eventId)271 AppExecFwk::InnerEvent::Pointer IccDiallingNumbersManager::BuildCallerInfo(int eventId)
272 {
273 std::unique_ptr<ResultObtain> object = std::make_unique<ResultObtain>();
274 int eventParam = 0;
275 AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventId, object, eventParam);
276 if (event == nullptr) {
277 TELEPHONY_LOGE("event is nullptr!");
278 return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
279 }
280 event->SetOwner(shared_from_this());
281 return event;
282 }
283
ClearRecords()284 void IccDiallingNumbersManager::ClearRecords()
285 {
286 std::vector<std::shared_ptr<DiallingNumbersInfo>> nullVector;
287 diallingNumbersList_.swap(nullVector);
288 }
289
GetFileIdForType(int fileType)290 int IccDiallingNumbersManager::GetFileIdForType(int fileType)
291 {
292 int fileId = 0;
293 if (fileType == DiallingNumbersInfo::SIM_ADN) {
294 fileId = ELEMENTARY_FILE_ADN; // ELEMENTARY_FILE_PBR for usim
295 } else if (fileType == DiallingNumbersInfo::SIM_FDN) {
296 fileId = ELEMENTARY_FILE_FDN;
297 }
298 return fileId;
299 }
300
FillResults(const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> & listInfo)301 void IccDiallingNumbersManager::FillResults(
302 const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> &listInfo)
303 {
304 TELEPHONY_LOGI("IccDiallingNumbersManager::FillResults %{public}zu", listInfo->size());
305 for (auto it = listInfo->begin(); it != listInfo->end(); it++) {
306 std::shared_ptr<DiallingNumbersInfo> item = *it;
307 if (!item->IsEmpty()) {
308 diallingNumbersList_.push_back(item);
309 }
310 }
311 TELEPHONY_LOGI("IccDiallingNumbersManager::FillResults end");
312 }
313
IsValidType(int type)314 bool IccDiallingNumbersManager::IsValidType(int type)
315 {
316 switch (type) {
317 case DiallingNumbersInfo::SIM_ADN:
318 case DiallingNumbersInfo::SIM_FDN:
319 return true;
320 default:
321 return false;
322 }
323 }
324
CreateInstance(std::weak_ptr<SimFileManager> simFile,std::shared_ptr<SimStateManager> simState)325 std::shared_ptr<IccDiallingNumbersManager> IccDiallingNumbersManager::CreateInstance(
326 std::weak_ptr<SimFileManager> simFile, std::shared_ptr<SimStateManager> simState)
327 {
328 if (simFile.lock() == nullptr) {
329 TELEPHONY_LOGE("IccDiallingNumbersManager::Init SimFileManager null pointer");
330 return nullptr;
331 }
332 std::shared_ptr<IccDiallingNumbersManager> manager = std::make_shared<IccDiallingNumbersManager>(simFile, simState);
333 if (manager == nullptr) {
334 TELEPHONY_LOGE("IccDiallingNumbersManager::Init manager create nullptr.");
335 return nullptr;
336 }
337 return manager;
338 }
339
HasSimCard()340 bool IccDiallingNumbersManager::HasSimCard()
341 {
342 return (simStateManager_ != nullptr) ? simStateManager_->HasSimCard() : false;
343 }
344
IsValidParam(int type,const std::shared_ptr<DiallingNumbersInfo> & info)345 bool IccDiallingNumbersManager::IsValidParam(int type, const std::shared_ptr<DiallingNumbersInfo> &info)
346 {
347 if (type == DiallingNumbersInfo::SIM_FDN) {
348 return !(info->pin2_.empty());
349 } else {
350 return true;
351 }
352 }
353
~IccDiallingNumbersManager()354 IccDiallingNumbersManager::~IccDiallingNumbersManager() {}
355 } // namespace Telephony
356 } // namespace OHOS
357