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