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 "call_records_manager.h"
17
18 #include "call_manager_inner_type.h"
19 #include "call_number_utils.h"
20 #include "common_event_manager.h"
21 #include "common_event_support.h"
22 #include "os_account_manager_wrapper.h"
23 #include "parameter.h"
24 #include "securec.h"
25 #include <regex>
26
27 namespace OHOS {
28 namespace Telephony {
29 constexpr const char *PROP_NETWORK_COUNTRY_ISO = "telephony.operator.iso-country";
30 constexpr const char *DEFAULT_NETWORK_COUNTRY = "CN";
31 constexpr int16_t DEFAULT_COUNTRY_CODE = 0;
32 constexpr int16_t DEFAULT_TIME = 0;
33 const int32_t ACTIVE_USER_ID = 100;
34 const uint32_t FEATURES_VIDEO = 1 << 0;
35 const int32_t PROP_SYSPARA_SIZE = 128;
36 const char *FORMAT_PATTERN = ",|;";
CallRecordsManager()37 CallRecordsManager::CallRecordsManager() : callRecordsHandlerServerPtr_(nullptr) {}
38
~CallRecordsManager()39 CallRecordsManager::~CallRecordsManager()
40 {
41 if (statusChangeListener_ != nullptr) {
42 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
43 if (samgrProxy != nullptr) {
44 samgrProxy->UnSubscribeSystemAbility(OHOS::SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN, statusChangeListener_);
45 statusChangeListener_ = nullptr;
46 }
47 }
48 if (dataShareReadySubscriber_ != nullptr) {
49 bool subRet = CommonEventManager::UnSubscribeCommonEvent(dataShareReadySubscriber_);
50 if (!subRet) {
51 TELEPHONY_LOGE("UnSubscribe data share ready event failed!");
52 }
53 dataShareReadySubscriber_ = nullptr;
54 }
55 }
56
Init()57 void CallRecordsManager::Init()
58 {
59 callRecordsHandlerServerPtr_ = DelayedSingleton<CallRecordsHandlerService>::GetInstance();
60 if (callRecordsHandlerServerPtr_ == nullptr) {
61 TELEPHONY_LOGE("call record manager init failure.");
62 return;
63 }
64 callRecordsHandlerServerPtr_->Start();
65 statusChangeListener_ = new (std::nothrow) AccountSystemAbilityListener();
66 if (statusChangeListener_ == nullptr) {
67 TELEPHONY_LOGE("failed to create statusChangeListener");
68 return;
69 }
70 RegisterDataShareReadySubscriber();
71 auto managerPtr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
72 if (managerPtr == nullptr) {
73 TELEPHONY_LOGE("get system ability manager error");
74 return;
75 }
76 int32_t ret = managerPtr->SubscribeSystemAbility(OHOS::SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN, statusChangeListener_);
77 if (ret != TELEPHONY_SUCCESS) {
78 TELEPHONY_LOGE("failed to subscribe account manager service SA!");
79 return;
80 }
81 }
82
RegisterDataShareReadySubscriber()83 void CallRecordsManager::RegisterDataShareReadySubscriber()
84 {
85 MatchingSkills matchingSkills;
86 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_DATA_SHARE_READY);
87 CommonEventSubscribeInfo subscriberInfo(matchingSkills);
88 subscriberInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
89 dataShareReadySubscriber_ = std::make_shared<DataShareReadyEventSubscriber>(subscriberInfo);
90 bool subRet = CommonEventManager::SubscribeCommonEvent(dataShareReadySubscriber_);
91 if (!subRet) {
92 TELEPHONY_LOGE("Subscribe data share ready event failed!");
93 }
94 }
95
CallStateUpdated(sptr<CallBase> & callObjectPtr,TelCallState priorState,TelCallState nextState)96 void CallRecordsManager::CallStateUpdated(
97 sptr<CallBase> &callObjectPtr, TelCallState priorState, TelCallState nextState)
98 {
99 if (callObjectPtr != nullptr && callObjectPtr->GetCallType() == CallType::TYPE_VOIP) {
100 TELEPHONY_LOGI("Voip call should not save cellular call records");
101 return;
102 }
103 CallAttributeInfo info;
104 if (nextState != TelCallState::CALL_STATUS_DISCONNECTED) {
105 return;
106 }
107 if (callObjectPtr == nullptr) {
108 TELEPHONY_LOGE("call object is nullptr");
109 return;
110 }
111 (void)memset_s(&info, sizeof(CallAttributeInfo), 0, sizeof(CallAttributeInfo));
112 callObjectPtr->GetCallAttributeBaseInfo(info);
113 AddOneCallRecord(info);
114 }
115
AddOneCallRecord(sptr<CallBase> call,CallAnswerType answerType)116 void CallRecordsManager::AddOneCallRecord(sptr<CallBase> call, CallAnswerType answerType)
117 {
118 CallAttributeInfo info;
119 (void)memset_s(&info, sizeof(CallAttributeInfo), 0, sizeof(CallAttributeInfo));
120 call->GetCallAttributeBaseInfo(info);
121 AddOneCallRecord(info);
122 }
123
AddOneCallRecord(CallAttributeInfo & info)124 void CallRecordsManager::AddOneCallRecord(CallAttributeInfo &info)
125 {
126 CallRecordInfo data;
127 (void)memset_s(&data, sizeof(CallRecordInfo), 0, sizeof(CallRecordInfo));
128 if (callRecordsHandlerServerPtr_ == nullptr) {
129 TELEPHONY_LOGE("callRecordsHandlerServerPtr_ is nullptr");
130 return;
131 }
132 if (strlen(info.accountNumber) > static_cast<size_t>(kMaxNumberLen)) {
133 TELEPHONY_LOGE("Number out of limit!");
134 return;
135 }
136 errno_t result = memcpy_s(data.phoneNumber, kMaxNumberLen, info.accountNumber, strlen(info.accountNumber));
137 if (result != EOK) {
138 TELEPHONY_LOGE("memcpy_s failed!");
139 return;
140 }
141 if (strlen(info.numberLocation) > static_cast<size_t>(kMaxNumberLen)) {
142 TELEPHONY_LOGE("Location out of limit!");
143 return;
144 }
145 result = memcpy_s(data.numberLocation, kMaxNumberLen, info.numberLocation, strlen(info.numberLocation));
146 if (result != EOK) {
147 TELEPHONY_LOGE("memcpy_s failed!");
148 return;
149 }
150 CopyCallInfoToRecord(info, data);
151 std::string countryIso = GetCountryIso();
152 int32_t formatRet = CopyFormatNumberToRecord(countryIso, data);
153 if (formatRet != TELEPHONY_SUCCESS) {
154 TELEPHONY_LOGE("CopyFormatNumberToRecord failed!");
155 return;
156 }
157 int32_t formatToE164Ret = CopyFormatNumberToE164ToRecord(countryIso, data);
158 if (formatToE164Ret != TELEPHONY_SUCCESS) {
159 TELEPHONY_LOGE("CopyFormatNumberToE164ToRecord failed!");
160 return;
161 }
162 callRecordsHandlerServerPtr_->StoreCallRecord(data);
163 }
164
GetCountryIso()165 std::string CallRecordsManager::GetCountryIso()
166 {
167 char valueStr[PROP_SYSPARA_SIZE] = {0};
168 GetParameter(PROP_NETWORK_COUNTRY_ISO, "", valueStr, PROP_SYSPARA_SIZE);
169 std::string countryIso = valueStr;
170 if (countryIso == "") {
171 TELEPHONY_LOGI("GetParameter is null, default network countryIso cn");
172 countryIso = DEFAULT_NETWORK_COUNTRY;
173 } else {
174 TELEPHONY_LOGI("GetParameter network countryIso is %{public}s", countryIso.c_str());
175 }
176 return countryIso;
177 }
178
CopyFormatNumberToRecord(std::string & countryIso,CallRecordInfo & data)179 int32_t CallRecordsManager::CopyFormatNumberToRecord(std::string &countryIso, CallRecordInfo &data)
180 {
181 std::string tmpStr("");
182 if (std::regex_search(std::string(data.phoneNumber), std::regex(FORMAT_PATTERN))) {
183 (void)DelayedSingleton<CallNumberUtils>::GetInstance()->FormatPhoneNumberAsYouType(
184 std::string(data.phoneNumber), countryIso, tmpStr);
185 } else {
186 (void)DelayedSingleton<CallNumberUtils>::GetInstance()->FormatPhoneNumber(
187 std::string(data.phoneNumber), countryIso, tmpStr);
188 }
189
190 if (tmpStr.length() > static_cast<size_t>(kMaxNumberLen)) {
191 TELEPHONY_LOGE("Number out of limit!");
192 return TELEPHONY_ERR_ARGUMENT_INVALID;
193 }
194 errno_t result = memcpy_s(data.formattedNumber, kMaxNumberLen, tmpStr.c_str(), tmpStr.length());
195 if (result != EOK) {
196 TELEPHONY_LOGE("memcpy_s failed!");
197 return result;
198 }
199 return TELEPHONY_SUCCESS;
200 }
201
CopyFormatNumberToE164ToRecord(std::string & countryIso,CallRecordInfo & data)202 int32_t CallRecordsManager::CopyFormatNumberToE164ToRecord(std::string &countryIso, CallRecordInfo &data)
203 {
204 std::string tmpStr("");
205 (void)DelayedSingleton<CallNumberUtils>::GetInstance()->FormatPhoneNumberToE164(
206 std::string(data.phoneNumber), countryIso, tmpStr);
207 if (tmpStr.length() > static_cast<size_t>(kMaxNumberLen)) {
208 TELEPHONY_LOGE("Number out of limit!");
209 return TELEPHONY_ERR_ARGUMENT_INVALID;
210 }
211 errno_t result = memcpy_s(data.formattedNumberToE164, kMaxNumberLen, tmpStr.c_str(), tmpStr.length());
212 if (result != EOK) {
213 TELEPHONY_LOGE("memcpy_s failed!");
214 return result;
215 }
216 return TELEPHONY_SUCCESS;
217 }
218
CopyCallInfoToRecord(CallAttributeInfo & info,CallRecordInfo & data)219 void CallRecordsManager::CopyCallInfoToRecord(CallAttributeInfo &info, CallRecordInfo &data)
220 {
221 if ((info.callBeginTime == DEFAULT_TIME) || (info.callEndTime == DEFAULT_TIME)) {
222 data.callDuration = DEFAULT_TIME;
223 } else {
224 data.callDuration = difftime(info.callEndTime, info.callBeginTime);
225 }
226 if ((info.ringBeginTime == DEFAULT_TIME) || (info.ringEndTime == DEFAULT_TIME)) {
227 data.ringDuration = DEFAULT_TIME;
228 } else {
229 data.ringDuration = difftime(info.ringEndTime, info.ringBeginTime);
230 }
231 data.callId = info.callId;
232 data.callBeginTime = info.callBeginTime;
233 data.callCreateTime = info.callCreateTime;
234 data.callEndTime = info.callEndTime;
235 data.directionType = info.callDirection;
236 data.answerType = info.answerType;
237 data.countryCode = DEFAULT_COUNTRY_CODE;
238 data.slotId = info.accountId;
239 data.callType = info.callType;
240 // use original call type for video call record
241 int32_t callFeatures = GetCallFeatures(info.originalCallType);
242 data.features = callFeatures;
243 data.numberMarkInfo = info.numberMarkInfo;
244 data.blockReason = info.blockReason;
245 data.celiaCallType = info.celiaCallType;
246 }
247
RemoveMissedIncomingCallNotification()248 int32_t CallRecordsManager::RemoveMissedIncomingCallNotification()
249 {
250 if (callRecordsHandlerServerPtr_ == nullptr) {
251 TELEPHONY_LOGE("callRecordsHandlerServerPtr_ is nullptr");
252 return TELEPHONY_ERR_LOCAL_PTR_NULL;
253 }
254 int32_t ret = callRecordsHandlerServerPtr_->RemoveMissedIncomingCallNotification();
255 if (ret != TELEPHONY_SUCCESS) {
256 TELEPHONY_LOGE("RemoveMissedIncomingCallNotification failed!");
257 return ret;
258 }
259 return TELEPHONY_SUCCESS;
260 }
261
GetCallFeatures(int32_t videoState)262 int32_t CallRecordsManager::GetCallFeatures(int32_t videoState)
263 {
264 uint32_t features = 0;
265 if (IsVideoCall(videoState)) {
266 features |= FEATURES_VIDEO;
267 }
268 return static_cast<int32_t>(features);
269 }
270
IsVideoCall(int32_t videoState)271 bool CallRecordsManager::IsVideoCall(int32_t videoState)
272 {
273 if (static_cast<VideoStateType>(videoState) == VideoStateType::TYPE_SEND_ONLY ||
274 static_cast<VideoStateType>(videoState) == VideoStateType::TYPE_RECEIVE_ONLY ||
275 static_cast<VideoStateType>(videoState) == VideoStateType::TYPE_VIDEO) {
276 return true;
277 }
278 return false;
279 }
280
SetDataShareReady(bool isDataShareReady)281 void CallRecordsManager::SetDataShareReady(bool isDataShareReady)
282 {
283 isDataShareReady_ = isDataShareReady;
284 }
285
SetSystemAbilityAdd(bool isSystemAbilityAdd)286 void CallRecordsManager::SetSystemAbilityAdd(bool isSystemAbilityAdd)
287 {
288 isSystemAbilityAdd_ = isSystemAbilityAdd;
289 }
290
QueryUnReadMissedCallLog(int32_t userId)291 void CallRecordsManager::QueryUnReadMissedCallLog(int32_t userId)
292 {
293 if (!isDataShareReady_ || !isSystemAbilityAdd_ || isUnReadMissedCallLogQuery_) {
294 return;
295 }
296 TELEPHONY_LOGI("the user id is :%{public}d", userId);
297 if (userId == ACTIVE_USER_ID) {
298 int32_t ret = DelayedSingleton<CallRecordsHandlerService>::GetInstance()->QueryUnReadMissedCallLog();
299 if (ret != TELEPHONY_SUCCESS) {
300 TELEPHONY_LOGE("Query unread missed call log failed!");
301 isUnReadMissedCallLogQuery_ = false;
302 } else {
303 isUnReadMissedCallLogQuery_ = true;
304 }
305 }
306 }
307
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)308 void AccountSystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
309 {
310 TELEPHONY_LOGI("SA:%{public}d is added!", systemAbilityId);
311 if (!CheckInputSysAbilityId(systemAbilityId)) {
312 TELEPHONY_LOGE("added SA is invalid!");
313 return;
314 }
315 if (systemAbilityId != OHOS::SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN) {
316 TELEPHONY_LOGE("added SA is not accoubt manager service, ignored.");
317 return;
318 }
319 DelayedSingleton<CallRecordsManager>::GetInstance()->SetSystemAbilityAdd(true);
320 std::vector<int32_t> activeList = { 0 };
321 DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->QueryActiveOsAccountIds(activeList);
322 TELEPHONY_LOGI("current active user id is :%{public}d", activeList[0]);
323 if (activeList[0] == ACTIVE_USER_ID) {
324 DelayedSingleton<CallRecordsManager>::GetInstance()->QueryUnReadMissedCallLog(activeList[0]);
325 } else {
326 MatchingSkills matchingSkills;
327 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
328 CommonEventSubscribeInfo subscriberInfo(matchingSkills);
329 subscriberInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
330 userSwitchSubscriber_ = std::make_shared<UserSwitchEventSubscriber>(subscriberInfo);
331 bool subRet = CommonEventManager::SubscribeCommonEvent(userSwitchSubscriber_);
332 if (!subRet) {
333 TELEPHONY_LOGE("Subscribe user switched event failed!");
334 }
335 }
336 }
337
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)338 void AccountSystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
339 {
340 TELEPHONY_LOGI("SA:%{public}d is removed!", systemAbilityId);
341 if (!CheckInputSysAbilityId(systemAbilityId)) {
342 TELEPHONY_LOGE("removed SA is invalid!");
343 return;
344 }
345 if (systemAbilityId != OHOS::SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN) {
346 TELEPHONY_LOGE("removed SA is not account manager service,, ignored.");
347 return;
348 }
349 if (userSwitchSubscriber_ != nullptr) {
350 bool subRet = CommonEventManager::UnSubscribeCommonEvent(userSwitchSubscriber_);
351 if (!subRet) {
352 TELEPHONY_LOGE("UnSubscribe user switched event failed!");
353 }
354 userSwitchSubscriber_ = nullptr;
355 }
356 }
357
OnReceiveEvent(const CommonEventData & data)358 void UserSwitchEventSubscriber::OnReceiveEvent(const CommonEventData &data)
359 {
360 OHOS::EventFwk::Want want = data.GetWant();
361 std::string action = data.GetWant().GetAction();
362 TELEPHONY_LOGI("action = %{public}s", action.c_str());
363 if (action == CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
364 int32_t userId = data.GetCode();
365 DelayedSingleton<CallRecordsManager>::GetInstance()->QueryUnReadMissedCallLog(userId);
366 }
367 }
368
OnReceiveEvent(const CommonEventData & data)369 void DataShareReadyEventSubscriber::OnReceiveEvent(const CommonEventData &data)
370 {
371 OHOS::EventFwk::Want want = data.GetWant();
372 std::string action = data.GetWant().GetAction();
373 TELEPHONY_LOGI("action = %{public}s", action.c_str());
374 if (action == CommonEventSupport::COMMON_EVENT_DATA_SHARE_READY) {
375 DelayedSingleton<CallRecordsManager>::GetInstance()->SetDataShareReady(true);
376 std::vector<int32_t> activeList = { 0 };
377 DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->QueryActiveOsAccountIds(activeList);
378 DelayedSingleton<CallRecordsManager>::GetInstance()->QueryUnReadMissedCallLog(activeList[0]);
379 }
380 }
381 } // namespace Telephony
382 } // namespace OHOS