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_state_report_proxy.h"
17 
18 #include <string_ex.h>
19 
20 #include "iservice_registry.h"
21 #include "system_ability.h"
22 #include "system_ability_definition.h"
23 
24 #include "call_control_manager.h"
25 #include "call_manager_errors.h"
26 #include "call_manager_inner_type.h"
27 #include "call_object_manager.h"
28 #include "telephony_log_wrapper.h"
29 #include "telephony_state_registry_client.h"
30 
31 namespace OHOS {
32 namespace Telephony {
CallStateReportProxy()33 CallStateReportProxy::CallStateReportProxy() {}
34 
~CallStateReportProxy()35 CallStateReportProxy::~CallStateReportProxy() {}
36 
CallStateUpdated(sptr<CallBase> & callObjectPtr,TelCallState priorState,TelCallState nextState)37 void CallStateReportProxy::CallStateUpdated(
38     sptr<CallBase> &callObjectPtr, TelCallState priorState, TelCallState nextState)
39 {
40     if (callObjectPtr == nullptr) {
41         TELEPHONY_LOGE("callObjectPtr is nullptr!");
42         return;
43     }
44     if (callObjectPtr->GetCallType() == CallType::TYPE_VOIP) {
45         TELEPHONY_LOGI("voip call no need to report call state");
46         return;
47     }
48     UpdateCallState(callObjectPtr, nextState);
49     UpdateCallStateForSlotId(callObjectPtr, nextState);
50 }
51 
UpdateCallState(sptr<CallBase> & callObjectPtr,TelCallState nextState)52 void CallStateReportProxy::UpdateCallState(sptr<CallBase> &callObjectPtr, TelCallState nextState)
53 {
54     sptr<CallBase> foregroundCall;
55     if (nextState == TelCallState::CALL_STATUS_ANSWERED) {
56         foregroundCall = callObjectPtr;
57     } else {
58         foregroundCall = CallObjectManager::GetForegroundCall(false);
59     }
60     if (foregroundCall == nullptr && callObjectPtr != nullptr) {
61         foregroundCall = callObjectPtr;
62     }
63     CallAttributeInfo info;
64     TelCallState currentVoipCallState = GetVoipCallState();
65     if ((foregroundCall != nullptr) && (nextState == TelCallState::CALL_STATUS_ANSWERED ||
66         foregroundCall->GetTelCallState() == TelCallState::CALL_STATUS_INCOMING ||
67         foregroundCall->GetTelCallState() == TelCallState::CALL_STATUS_WAITING)) {
68         foregroundCall->GetCallAttributeInfo(info);
69         if (nextState == TelCallState::CALL_STATUS_ANSWERED) {
70             info.callState = TelCallState::CALL_STATUS_ANSWERED;
71         }
72     } else if (currentVoipCallState == TelCallState::CALL_STATUS_INCOMING ||
73         currentVoipCallState == TelCallState::CALL_STATUS_ANSWERED) {
74         info.callState = currentVoipCallState;
75     } else if (foregroundCall != nullptr) {
76         foregroundCall->GetCallAttributeInfo(info);
77     } else {
78         info.callState = currentVoipCallState;
79     }
80     if (info.callState == currentCallState_) {
81         TELEPHONY_LOGI("foreground call state is not changed, currentCallState_:%{public}d!", currentCallState_);
82         return;
83     }
84     if (info.callState == TelCallState::CALL_STATUS_DISCONNECTING) {
85         TELEPHONY_LOGI("disconnecting call no need to report call state");
86         return;
87     }
88     currentCallState_ = info.callState;
89     std::string str(info.accountNumber);
90     std::u16string accountNumber = Str8ToStr16(str);
91     ReportCallState(static_cast<int32_t>(info.callState), accountNumber);
92 }
93 
UpdateCallStateForVoIPOrRestart()94 void CallStateReportProxy::UpdateCallStateForVoIPOrRestart()
95 {
96     sptr<CallBase> callObjectPtr = nullptr;
97     UpdateCallState(callObjectPtr, TelCallState::CALL_STATUS_IDLE);
98 }
99 
GetVoipCallState()100 TelCallState CallStateReportProxy::GetVoipCallState()
101 {
102     int32_t state;
103     DelayedSingleton<CallControlManager>::GetInstance()->GetVoIPCallState(state);
104     TELEPHONY_LOGI("report voip call state = %{public}d.", state);
105     TelCallState nextState = TelCallState::CALL_STATUS_IDLE;
106     switch ((CallStateToApp)state) {
107         case CallStateToApp::CALL_STATE_IDLE:
108             nextState = TelCallState::CALL_STATUS_IDLE;
109             break;
110         case CallStateToApp::CALL_STATE_OFFHOOK:
111             nextState = TelCallState::CALL_STATUS_ACTIVE;
112             break;
113         case CallStateToApp::CALL_STATE_RINGING:
114             nextState = TelCallState::CALL_STATUS_INCOMING;
115             break;
116         case CallStateToApp::CALL_STATE_ANSWERED:
117             nextState = TelCallState::CALL_STATUS_ANSWERED;
118             break;
119         default:
120             break;
121     }
122     return nextState;
123 }
124 
UpdateCallStateForSlotId(sptr<CallBase> & callObjectPtr,TelCallState nextState)125 void CallStateReportProxy::UpdateCallStateForSlotId(sptr<CallBase> &callObjectPtr, TelCallState nextState)
126 {
127     CallAttributeInfo info;
128     callObjectPtr->GetCallAttributeInfo(info);
129     std::string str(info.accountNumber);
130     std::u16string accountNumber = Str8ToStr16(str);
131     if (nextState == TelCallState::CALL_STATUS_ANSWERED) {
132         info.callState = TelCallState::CALL_STATUS_ANSWERED;
133     }
134     if (info.callState == TelCallState::CALL_STATUS_DISCONNECTING) {
135         TELEPHONY_LOGI("disconnecting call no need to report call state");
136         return;
137     }
138     ReportCallStateForCallId(info.accountId, static_cast<int32_t>(info.callState), accountNumber);
139 }
140 
ReportCallState(int32_t callState,std::u16string phoneNumber)141 int32_t CallStateReportProxy::ReportCallState(int32_t callState, std::u16string phoneNumber)
142 {
143     int32_t ret = TELEPHONY_ERR_FAIL;
144     ret = DelayedRefSingleton<TelephonyStateRegistryClient>::GetInstance().UpdateCallState(
145         callState, phoneNumber);
146     if (ret != TELEPHONY_SUCCESS) {
147         TELEPHONY_LOGE("notifyCallStateUpdated failed, errcode:%{public}d", ret);
148         return ret;
149     }
150     TELEPHONY_LOGI("report call state:%{public}d", callState);
151     return ret;
152 }
153 
ReportCallStateForCallId(int32_t slotId,int32_t callState,std::u16string incomingNumber)154 int32_t CallStateReportProxy::ReportCallStateForCallId(
155     int32_t slotId, int32_t callState, std::u16string incomingNumber)
156 {
157     int32_t ret = TELEPHONY_ERR_FAIL;
158     ret = DelayedRefSingleton<TelephonyStateRegistryClient>::GetInstance().UpdateCallStateForSlotId(
159         slotId, callState, incomingNumber);
160     if (ret != TELEPHONY_SUCCESS) {
161         TELEPHONY_LOGE("NotifyCallStateUpdated failed, errcode:%{public}d", ret);
162         return ret;
163     }
164     TELEPHONY_LOGI("report call state:%{public}d, slotId:%{public}d", callState, slotId);
165     return ret;
166 }
167 } // namespace Telephony
168 } // namespace OHOS
169