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