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