• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "securec.h"
24 
25 namespace OHOS {
26 namespace Telephony {
27 constexpr int16_t DEFAULT_COUNTRY_CODE = 0;
28 constexpr int16_t DEFAULT_TIME = 0;
29 const int32_t ACTIVE_USER_ID = 100;
30 const int32_t FEATURES_VIDEO = 1 << 0;
CallRecordsManager()31 CallRecordsManager::CallRecordsManager() : callRecordsHandlerServerPtr_(nullptr) {}
32 
~CallRecordsManager()33 CallRecordsManager::~CallRecordsManager()
34 {
35     if (statusChangeListener_ != nullptr) {
36         auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
37         if (samgrProxy != nullptr) {
38             samgrProxy->UnSubscribeSystemAbility(OHOS::SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN, statusChangeListener_);
39             statusChangeListener_ = nullptr;
40         }
41     }
42 }
43 
Init()44 void CallRecordsManager::Init()
45 {
46     callRecordsHandlerServerPtr_ = DelayedSingleton<CallRecordsHandlerService>::GetInstance();
47     if (callRecordsHandlerServerPtr_ == nullptr) {
48         TELEPHONY_LOGE("call record manager init failure.");
49         return;
50     }
51     callRecordsHandlerServerPtr_->Start();
52     statusChangeListener_ = new (std::nothrow) AccountSystemAbilityListener();
53     if (statusChangeListener_ == nullptr) {
54         TELEPHONY_LOGE("failed to create statusChangeListener");
55         return;
56     }
57     auto managerPtr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
58     if (managerPtr == nullptr) {
59         TELEPHONY_LOGE("get system ability manager error");
60         return;
61     }
62     int32_t ret = managerPtr->SubscribeSystemAbility(OHOS::SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN, statusChangeListener_);
63     if (ret != TELEPHONY_SUCCESS) {
64         TELEPHONY_LOGE("failed to subscribe account manager service SA!");
65         return;
66     }
67 }
68 
CallStateUpdated(sptr<CallBase> & callObjectPtr,TelCallState priorState,TelCallState nextState)69 void CallRecordsManager::CallStateUpdated(
70     sptr<CallBase> &callObjectPtr, TelCallState priorState, TelCallState nextState)
71 {
72     if (callObjectPtr != nullptr && callObjectPtr->GetCallType() == CallType::TYPE_VOIP) {
73         TELEPHONY_LOGI("Voip call should not save cellular call records");
74         return;
75     }
76     CallAttributeInfo info;
77     if (nextState != TelCallState::CALL_STATUS_DISCONNECTED) {
78         return;
79     }
80     if (callObjectPtr == nullptr) {
81         TELEPHONY_LOGE("call object is nullptr");
82         return;
83     }
84     (void)memset_s(&info, sizeof(CallAttributeInfo), 0, sizeof(CallAttributeInfo));
85     callObjectPtr->GetCallAttributeBaseInfo(info);
86     AddOneCallRecord(info);
87 }
88 
AddOneCallRecord(sptr<CallBase> call,CallAnswerType answerType)89 void CallRecordsManager::AddOneCallRecord(sptr<CallBase> call, CallAnswerType answerType)
90 {
91     CallAttributeInfo info;
92     (void)memset_s(&info, sizeof(CallAttributeInfo), 0, sizeof(CallAttributeInfo));
93     call->GetCallAttributeBaseInfo(info);
94     AddOneCallRecord(info);
95 }
96 
AddOneCallRecord(CallAttributeInfo & info)97 void CallRecordsManager::AddOneCallRecord(CallAttributeInfo &info)
98 {
99     CallRecordInfo data;
100     (void)memset_s(&data, sizeof(CallRecordInfo), 0, sizeof(CallRecordInfo));
101     if (callRecordsHandlerServerPtr_ == nullptr) {
102         TELEPHONY_LOGE("callRecordsHandlerServerPtr_ is nullptr");
103         return;
104     }
105     if (strlen(info.accountNumber) > static_cast<size_t>(kMaxNumberLen)) {
106         TELEPHONY_LOGE("Number out of limit!");
107         return;
108     }
109     errno_t result = memcpy_s(data.phoneNumber, kMaxNumberLen, info.accountNumber, strlen(info.accountNumber));
110     if (result != EOK) {
111         TELEPHONY_LOGE("memcpy_s failed!");
112         return;
113     }
114     CopyCallInfoToRecord(info, data);
115     std::string tmpStr("");
116     (void)DelayedSingleton<CallNumberUtils>::GetInstance()->FormatPhoneNumber(
117         std::string(data.phoneNumber), "CN", tmpStr);
118 
119     if (tmpStr.length() > static_cast<size_t>(kMaxNumberLen)) {
120         TELEPHONY_LOGE("Number out of limit!");
121         return;
122     }
123     if (memcpy_s(data.formattedPhoneNumber, kMaxNumberLen, tmpStr.c_str(), tmpStr.length()) != 0) {
124         TELEPHONY_LOGE("memcpy_s failed!");
125         return;
126     }
127     callRecordsHandlerServerPtr_->StoreCallRecord(data);
128 }
129 
CopyCallInfoToRecord(CallAttributeInfo & info,CallRecordInfo & data)130 void CallRecordsManager::CopyCallInfoToRecord(CallAttributeInfo &info, CallRecordInfo &data)
131 {
132     if ((info.callBeginTime == DEFAULT_TIME) || (info.callEndTime == DEFAULT_TIME)) {
133         data.callDuration = DEFAULT_TIME;
134     } else {
135         data.callDuration = difftime(info.callEndTime, info.callBeginTime);
136     }
137     if ((info.ringBeginTime == DEFAULT_TIME) || (info.ringEndTime == DEFAULT_TIME)) {
138         data.ringDuration = DEFAULT_TIME;
139     } else {
140         data.ringDuration = difftime(info.ringEndTime, info.ringBeginTime);
141     }
142     data.callId = info.callId;
143     data.callBeginTime = info.callBeginTime;
144     data.callEndTime = info.callEndTime;
145     data.directionType = info.callDirection;
146     data.answerType = info.answerType;
147     data.countryCode = DEFAULT_COUNTRY_CODE;
148     data.slotId = info.accountId;
149     data.callType = info.callType;
150     // use original call type for video call record
151     int32_t callFeatures = GetCallFeatures(info.originalCallType);
152     data.features = callFeatures;
153 }
154 
RemoveMissedIncomingCallNotification()155 int32_t CallRecordsManager::RemoveMissedIncomingCallNotification()
156 {
157     if (callRecordsHandlerServerPtr_ == nullptr) {
158         TELEPHONY_LOGE("callRecordsHandlerServerPtr_ is nullptr");
159         return TELEPHONY_ERR_LOCAL_PTR_NULL;
160     }
161     int32_t ret = callRecordsHandlerServerPtr_->RemoveMissedIncomingCallNotification();
162     if (ret != TELEPHONY_SUCCESS) {
163         TELEPHONY_LOGE("RemoveMissedIncomingCallNotification failed!");
164         return ret;
165     }
166     return TELEPHONY_SUCCESS;
167 }
168 
GetCallFeatures(int32_t videoState)169 int32_t CallRecordsManager::GetCallFeatures(int32_t videoState)
170 {
171     int32_t features = 0;
172     if (IsVideoCall(videoState)) {
173         features |= FEATURES_VIDEO;
174     }
175     return features;
176 }
177 
IsVideoCall(int32_t videoState)178 bool CallRecordsManager::IsVideoCall(int32_t videoState)
179 {
180     if (static_cast<VideoStateType>(videoState) == VideoStateType::TYPE_SEND_ONLY ||
181         static_cast<VideoStateType>(videoState) == VideoStateType::TYPE_RECEIVE_ONLY ||
182         static_cast<VideoStateType>(videoState) == VideoStateType::TYPE_VIDEO) {
183         return true;
184     }
185     return false;
186 }
187 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)188 void AccountSystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
189 {
190     TELEPHONY_LOGI("SA:%{public}d is added!", systemAbilityId);
191     if (!CheckInputSysAbilityId(systemAbilityId)) {
192         TELEPHONY_LOGE("added SA is invalid!");
193         return;
194     }
195     if (systemAbilityId != OHOS::SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN) {
196         TELEPHONY_LOGE("added SA is not accoubt manager service, ignored.");
197         return;
198     }
199     std::vector<int32_t> activeList = { 0 };
200     DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->QueryActiveOsAccountIds(activeList);
201     TELEPHONY_LOGI("current active user id is :%{public}d", activeList[0]);
202     if (activeList[0] == ACTIVE_USER_ID) {
203         int32_t ret = DelayedSingleton<CallRecordsHandlerService>::GetInstance()->QueryUnReadMissedCallLog();
204         if (ret != TELEPHONY_SUCCESS) {
205             TELEPHONY_LOGE("QueryUnReadMissedCallLog failed!");
206         }
207     } else {
208         MatchingSkills matchingSkills;
209         matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
210         CommonEventSubscribeInfo subscriberInfo(matchingSkills);
211         subscriberInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
212         userSwitchSubscriber_ = std::make_shared<UserSwitchEventSubscriber>(subscriberInfo);
213         bool subRet = CommonEventManager::SubscribeCommonEvent(userSwitchSubscriber_);
214         if (!subRet) {
215             TELEPHONY_LOGE("Subscribe user switched event failed!");
216         }
217     }
218 }
219 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)220 void AccountSystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
221 {
222     TELEPHONY_LOGI("SA:%{public}d is removed!", systemAbilityId);
223     if (!CheckInputSysAbilityId(systemAbilityId)) {
224         TELEPHONY_LOGE("removed SA is invalid!");
225         return;
226     }
227     if (systemAbilityId != OHOS::SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN) {
228         TELEPHONY_LOGE("removed SA is not account manager service,, ignored.");
229         return;
230     }
231     if (userSwitchSubscriber_ != nullptr) {
232         bool subRet = CommonEventManager::UnSubscribeCommonEvent(userSwitchSubscriber_);
233         if (!subRet) {
234             TELEPHONY_LOGE("UnSubscribe user switched event failed!");
235         }
236         userSwitchSubscriber_ = nullptr;
237     }
238 }
239 
OnReceiveEvent(const CommonEventData & data)240 void UserSwitchEventSubscriber::OnReceiveEvent(const CommonEventData &data)
241 {
242     OHOS::EventFwk::Want want = data.GetWant();
243     std::string action = data.GetWant().GetAction();
244     TELEPHONY_LOGI("action = %{public}s", action.c_str());
245     if (action == CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
246         int32_t userId = data.GetCode();
247         if (userId == ACTIVE_USER_ID) {
248             int32_t ret = DelayedSingleton<CallRecordsHandlerService>::GetInstance()->QueryUnReadMissedCallLog();
249             if (ret != TELEPHONY_SUCCESS) {
250                 TELEPHONY_LOGE("Query unread missed call log failed!");
251             }
252         }
253     }
254 }
255 } // namespace Telephony
256 } // namespace OHOS