1 /*
2  * Copyright (C) 2021-2023 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 "report_call_info_handler.h"
17 
18 #include "call_manager_errors.h"
19 #include "call_manager_hisysevent.h"
20 #include "ffrt.h"
21 #include "ims_call.h"
22 #include "telephony_log_wrapper.h"
23 #include "thread"
24 
25 namespace OHOS {
26 namespace Telephony {
27 namespace {
28 ffrt::queue reportCallInfoQueue { "report_call_info_queue" };
29 }
ReportCallInfoHandler()30 ReportCallInfoHandler::ReportCallInfoHandler() {}
31 
~ReportCallInfoHandler()32 ReportCallInfoHandler::~ReportCallInfoHandler() {}
33 
Init()34 void ReportCallInfoHandler::Init()
35 {
36     callStatusManagerPtr_ = std::make_shared<CallStatusManager>();
37     callStatusManagerPtr_->Init();
38     return;
39 }
40 
UpdateCallReportInfo(const CallDetailInfo & info)41 int32_t ReportCallInfoHandler::UpdateCallReportInfo(const CallDetailInfo &info)
42 {
43     if (callStatusManagerPtr_ == nullptr) {
44         TELEPHONY_LOGE("callStatusManagerPtr_ is null");
45         return TELEPHONY_ERR_LOCAL_PTR_NULL;
46     }
47     CallDetailInfo callDetailInfo = info;
48     std::weak_ptr<CallStatusManager> callStatusManagerPtr = callStatusManagerPtr_;
49     TELEPHONY_LOGI("UpdateCallReportInfo submit task enter");
50     reportCallInfoQueue.submit([callStatusManagerPtr, callDetailInfo]() {
51         std::shared_ptr<CallStatusManager> managerPtr = callStatusManagerPtr.lock();
52         if (managerPtr == nullptr) {
53             TELEPHONY_LOGE("managerPtr is null");
54             return;
55         }
56         auto ret = managerPtr->HandleCallReportInfo(callDetailInfo);
57         if (ret != TELEPHONY_SUCCESS) {
58             TELEPHONY_LOGE("HandleCallReportInfo failed! ret:%{public}d", ret);
59         }
60     });
61     return TELEPHONY_SUCCESS;
62 }
63 
BuildCallDetailsInfo(CallDetailsInfo & info,CallDetailsInfo & callDetailsInfo)64 void ReportCallInfoHandler::BuildCallDetailsInfo(CallDetailsInfo &info, CallDetailsInfo &callDetailsInfo)
65 {
66     CallDetailInfo callDetailInfo;
67     std::vector<CallDetailInfo>::iterator iter = info.callVec.begin();
68     for (; iter != info.callVec.end(); ++iter) {
69         callDetailInfo.callType = (*iter).callType;
70         callDetailInfo.accountId = (*iter).accountId;
71         callDetailInfo.state = (*iter).state;
72         callDetailInfo.callMode = (*iter).callMode;
73         callDetailInfo.index = (*iter).index;
74         callDetailInfo.voiceDomain = (*iter).voiceDomain;
75         callDetailInfo.mpty = (*iter).mpty;
76         callDetailInfo.crsType = (*iter).crsType;
77         callDetailInfo.originalCallType = (*iter).originalCallType;
78         (void)memcpy_s(callDetailInfo.phoneNum, kMaxNumberLen, (*iter).phoneNum, kMaxNumberLen);
79         (void)memcpy_s(callDetailInfo.bundleName, kMaxBundleNameLen, (*iter).bundleName, kMaxBundleNameLen);
80         callDetailsInfo.callVec.push_back(callDetailInfo);
81     }
82 }
83 
UpdateCallsReportInfo(CallDetailsInfo & info)84 int32_t ReportCallInfoHandler::UpdateCallsReportInfo(CallDetailsInfo &info)
85 {
86     if (callStatusManagerPtr_ == nullptr) {
87         TELEPHONY_LOGE("callStatusManagerPtr_ is null");
88         return TELEPHONY_ERR_LOCAL_PTR_NULL;
89     }
90     CallDetailsInfo callDetailsInfo;
91     callDetailsInfo.slotId = info.slotId;
92     (void)memcpy_s(callDetailsInfo.bundleName, kMaxBundleNameLen, info.bundleName, kMaxBundleNameLen);
93     BuildCallDetailsInfo(info, callDetailsInfo);
94     std::weak_ptr<CallStatusManager> callStatusManagerPtr = callStatusManagerPtr_;
95     TELEPHONY_LOGI("UpdateCallsReportInfo submit task enter");
96     reportCallInfoQueue.submit([callStatusManagerPtr, callDetailsInfo]() {
97         std::shared_ptr<CallStatusManager> managerPtr = callStatusManagerPtr.lock();
98         if (managerPtr == nullptr) {
99             TELEPHONY_LOGE("managerPtr is null");
100             return;
101         }
102         int32_t ret = managerPtr->HandleCallsReportInfo(callDetailsInfo);
103         if (ret != TELEPHONY_SUCCESS) {
104             TELEPHONY_LOGE("HandleCallsReportInfo failed! ret:%{public}d", ret);
105         }
106     });
107 
108     CallDetailInfo detailInfo;
109     detailInfo.state = TelCallState::CALL_STATUS_UNKNOWN;
110     std::vector<CallDetailInfo>::iterator it = info.callVec.begin();
111     for (; it != info.callVec.end(); ++it) {
112         detailInfo.callType = (*it).callType;
113         detailInfo.accountId = (*it).accountId;
114         detailInfo.state = (*it).state;
115         detailInfo.callMode = (*it).callMode;
116     }
117     if (detailInfo.state == TelCallState::CALL_STATUS_INCOMING) {
118         CallManagerHisysevent::WriteIncomingCallFaultEvent(info.slotId, static_cast<int32_t>(detailInfo.callType),
119             static_cast<int32_t>(detailInfo.callMode), CALL_ERR_SYSTEM_EVENT_HANDLE_FAILURE,
120             "ID HANDLER_UPDATE_CALL_INFO_LIST");
121     }
122     return TELEPHONY_SUCCESS;
123 }
124 
UpdateDisconnectedCause(const DisconnectedDetails & details)125 int32_t ReportCallInfoHandler::UpdateDisconnectedCause(const DisconnectedDetails &details)
126 {
127     if (callStatusManagerPtr_ == nullptr) {
128         TELEPHONY_LOGE("callStatusManagerPtr_ is null");
129         return TELEPHONY_ERR_LOCAL_PTR_NULL;
130     }
131     DisconnectedDetails disconnectedDetails = details;
132     std::weak_ptr<CallStatusManager> callStatusManagerPtr = callStatusManagerPtr_;
133     TELEPHONY_LOGI("UpdateDisconnectedCause submit task enter");
134     reportCallInfoQueue.submit([callStatusManagerPtr, disconnectedDetails]() {
135         std::shared_ptr<CallStatusManager> managerPtr = callStatusManagerPtr.lock();
136         if (managerPtr == nullptr) {
137             TELEPHONY_LOGE("managerPtr is null");
138             return;
139         }
140         int32_t ret = managerPtr->HandleDisconnectedCause(disconnectedDetails);
141         if (ret != TELEPHONY_SUCCESS) {
142             TELEPHONY_LOGE("HandleDisconnectedCause failed! ret:%{public}d", ret);
143         }
144     });
145     return TELEPHONY_SUCCESS;
146 }
147 
UpdateEventResultInfo(const CellularCallEventInfo & info)148 int32_t ReportCallInfoHandler::UpdateEventResultInfo(const CellularCallEventInfo &info)
149 {
150     if (callStatusManagerPtr_ == nullptr) {
151         TELEPHONY_LOGE("callStatusManagerPtr_ is null");
152         return TELEPHONY_ERR_LOCAL_PTR_NULL;
153     }
154     std::weak_ptr<CallStatusManager> callStatusManagerPtr = callStatusManagerPtr_;
155     TELEPHONY_LOGI("UpdateEventResultInfo submit task enter");
156     reportCallInfoQueue.submit([callStatusManagerPtr, info]() {
157         std::shared_ptr<CallStatusManager> managerPtr = callStatusManagerPtr.lock();
158         if (managerPtr == nullptr) {
159             TELEPHONY_LOGE("managerPtr is null");
160             return;
161         }
162         int32_t ret = managerPtr->HandleEventResultReportInfo(info);
163         if (ret != TELEPHONY_SUCCESS) {
164             TELEPHONY_LOGE("HandleEventResultReportInfo failed! ret:%{public}d", ret);
165         }
166     });
167     return TELEPHONY_SUCCESS;
168 }
169 
UpdateOttEventInfo(const OttCallEventInfo & info)170 int32_t ReportCallInfoHandler::UpdateOttEventInfo(const OttCallEventInfo &info)
171 {
172     if (callStatusManagerPtr_ == nullptr) {
173         TELEPHONY_LOGE("callStatusManagerPtr_ is null");
174         return TELEPHONY_ERR_LOCAL_PTR_NULL;
175     }
176     OttCallEventInfo ottCallEventInfo = info;
177     std::weak_ptr<CallStatusManager> callStatusManagerPtr = callStatusManagerPtr_;
178     TELEPHONY_LOGI("UpdateOttEventInfo submit task enter");
179     reportCallInfoQueue.submit([callStatusManagerPtr, ottCallEventInfo]() {
180         std::shared_ptr<CallStatusManager> managerPtr = callStatusManagerPtr.lock();
181         if (managerPtr == nullptr) {
182             TELEPHONY_LOGE("managerPtr is null");
183             return;
184         }
185         int32_t ret = managerPtr->HandleOttEventReportInfo(ottCallEventInfo);
186         if (ret != TELEPHONY_SUCCESS) {
187             TELEPHONY_LOGE("HandleOttEventReportInfo failed! ret:%{public}d", ret);
188         }
189     });
190     return TELEPHONY_SUCCESS;
191 }
192 
ReceiveImsCallModeRequest(const CallModeReportInfo & response)193 int32_t ReportCallInfoHandler::ReceiveImsCallModeRequest(const CallModeReportInfo &response)
194 {
195     TELEPHONY_LOGI("ReceiveImsCallModeRequest submit task enter");
196     reportCallInfoQueue.submit([response]() {
197         CallModeReportInfo reportInfo = response;
198         sptr<CallBase> call = CallObjectManager::GetOneCallObjectByIndex(response.callIndex);
199         if (call == nullptr) {
200             TELEPHONY_LOGE("call not exists");
201             return;
202         }
203         if (call->GetCallType() == CallType::TYPE_IMS) {
204             sptr<IMSCall> imsCall = reinterpret_cast<IMSCall *>(call.GetRefPtr());
205             imsCall->RecieveUpdateCallMediaModeRequest(reportInfo);
206         }
207     });
208     return TELEPHONY_SUCCESS;
209 }
210 
ReceiveImsCallModeResponse(const CallModeReportInfo & response)211 int32_t ReportCallInfoHandler::ReceiveImsCallModeResponse(const CallModeReportInfo &response)
212 {
213     TELEPHONY_LOGI("ReceiveImsCallModeResponse submit task enter");
214     reportCallInfoQueue.submit([response]() {
215         CallModeReportInfo reportInfo = response;
216         sptr<CallBase> call = nullptr;
217         if (response.slotId != -1) {
218             call = CallObjectManager::GetOneCallObjectByIndexAndSlotId(response.callIndex, response.slotId);
219         }
220         if (call == nullptr) {
221             call = CallObjectManager::GetOneCallObjectByIndex(response.callIndex);
222         }
223         if (call == nullptr) {
224             TELEPHONY_LOGE("call not exists");
225             return;
226         }
227         if (call->GetCallType() == CallType::TYPE_IMS) {
228             sptr<IMSCall> imsCall = reinterpret_cast<IMSCall *>(call.GetRefPtr());
229             imsCall->ReceiveUpdateCallMediaModeResponse(reportInfo);
230         }
231     });
232     return TELEPHONY_SUCCESS;
233 }
234 
UpdateVoipEventInfo(const VoipCallEventInfo & info)235 int32_t ReportCallInfoHandler::UpdateVoipEventInfo(const VoipCallEventInfo &info)
236 {
237     if (callStatusManagerPtr_ == nullptr) {
238         TELEPHONY_LOGE("callStatusManagerPtr_ is null");
239         return TELEPHONY_ERR_LOCAL_PTR_NULL;
240     }
241     VoipCallEventInfo voipCallEventInfo = info;
242     std::weak_ptr<CallStatusManager> callStatusManagerPtr = callStatusManagerPtr_;
243     TELEPHONY_LOGI("UpdateVoipEventInfo submit task enter");
244     reportCallInfoQueue.submit([callStatusManagerPtr, voipCallEventInfo]() {
245         std::shared_ptr<CallStatusManager> managerPtr = callStatusManagerPtr.lock();
246         if (managerPtr == nullptr) {
247             TELEPHONY_LOGE("managerPtr is null");
248             return;
249         }
250         int32_t ret = managerPtr->HandleVoipEventReportInfo(voipCallEventInfo);
251         if (ret != TELEPHONY_SUCCESS) {
252             TELEPHONY_LOGE("UpdateVoipEventInfo failed! ret:%{public}d", ret);
253         }
254     });
255     return TELEPHONY_SUCCESS;
256 }
257 } // namespace Telephony
258 } // namespace OHOS
259