1 /*
2 * Copyright (C) 2024 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_object_manager.h"
17 #include "call_wired_headset.h"
18
19 #include "input_manager.h"
20 #include "audio_device_manager.h"
21 #include "audio_control_manager.h"
22 #include "call_manager_base.h"
23 #include "system_ability_definition.h"
24 #include "call_control_manager.h"
25 #include "audio_proxy.h"
26 #include "call_manager_base.h"
27 #include "ims_conference.h"
28
29 namespace OHOS {
30 namespace Telephony {
31
32 using WiredHeadSetCallback = std::function<void(const std::shared_ptr<OHOS::MMI::KeyEvent>)>;
33
34 constexpr int32_t INVALID_VALUE = -1;
35 constexpr int32_t FINAL_KEY_DOWN_DURATION_TWO = 2000;
CallWiredHeadSet()36 CallWiredHeadSet::CallWiredHeadSet()
37 {
38 isProcessed_ = false;
39 downFirstTime_ = 0;
40 subscribeIdForPressedUp_ = INVALID_VALUE;
41 subscribeIdForPressedDown_ = INVALID_VALUE;
42 }
43
~CallWiredHeadSet()44 CallWiredHeadSet::~CallWiredHeadSet()
45 {
46 DeInit();
47 }
48
Init()49 bool CallWiredHeadSet::Init()
50 {
51 bool pressedUp = RegistKeyMutePressedUp();
52 bool pressedDown = RegistKeyMutePressedDown();
53 if (pressedUp && pressedDown) {
54 TELEPHONY_LOGI("CallWiredHeadSet Registed KeyMute Pressed callback succeed");
55 return true;
56 } else {
57 TELEPHONY_LOGE("CallWiredHeadSet Registed KeyMute Pressed callback failed,"
58 "pressedUp is %{public}s, pressedDown is %{public}s",
59 pressedUp ? "true" : "false", pressedDown ? "true" : "false");
60 return false;
61 }
62 }
63
DeInit()64 void CallWiredHeadSet::DeInit()
65 {
66 UnregistKeyMutePressedUp();
67 UnregistKeyMutePressedDown();
68 TELEPHONY_LOGI("CallWiredHeadSet UnRegisted KeyMute Pressed callback succeed");
69 }
70
InitOption(const std::set<int32_t> & preKeys,int32_t finalKey,bool isFinalKeyDown,int32_t duration)71 std::shared_ptr<MMI::KeyOption> CallWiredHeadSet::InitOption(
72 const std::set<int32_t> &preKeys, int32_t finalKey, bool isFinalKeyDown, int32_t duration)
73 {
74 std::shared_ptr<MMI::KeyOption> keyOption = std::make_shared<MMI::KeyOption>();
75 keyOption->SetFinalKeyDown(isFinalKeyDown);
76 keyOption->SetFinalKey(finalKey);
77 keyOption->SetPreKeys(preKeys);
78 keyOption->SetFinalKeyDownDuration(duration);
79 return keyOption;
80 }
81
RegistKeyMutePressedUp()82 bool CallWiredHeadSet::RegistKeyMutePressedUp()
83 {
84 WiredHeadSetCallback pressedFunc = [this](const std::shared_ptr<OHOS::MMI::KeyEvent> event) {
85 this->DealKeyMutePressedUp(event);
86 };
87
88 std::set<int32_t> preKeys;
89 std::shared_ptr<MMI::KeyOption> keyOption = InitOption(preKeys, MMI::KeyEvent::KEYCODE_HEADSETHOOK, false, 0);
90 keyOption->SetPriority(MMI::SubscribePriority::PRIORITY_100);
91 subscribeIdForPressedUp_ = MMI::InputManager::GetInstance()->SubscribeKeyEvent(keyOption, pressedFunc);
92 TELEPHONY_LOGI("subscribeIdForPressedUp_: %{public}d", subscribeIdForPressedUp_);
93 return subscribeIdForPressedUp_ < 0 ? false : true;
94 }
95
RegistKeyMutePressedDown()96 bool CallWiredHeadSet::RegistKeyMutePressedDown()
97 {
98 WiredHeadSetCallback pressedFunc = [this](const std::shared_ptr<OHOS::MMI::KeyEvent> event) {
99 this->DealKeyMutePressedDown(event);
100 };
101
102 std::set<int32_t> preKeys;
103 std::shared_ptr<MMI::KeyOption> keyOption = InitOption(preKeys, MMI::KeyEvent::KEYCODE_HEADSETHOOK, true, 0);
104 keyOption->SetPriority(MMI::SubscribePriority::PRIORITY_100);
105 subscribeIdForPressedDown_ = MMI::InputManager::GetInstance()->SubscribeKeyEvent(keyOption, pressedFunc);
106 TELEPHONY_LOGI("subscribeIdForPressedDown_: %{public}d", subscribeIdForPressedDown_);
107 return subscribeIdForPressedDown_ < 0 ? false : true;
108 }
109
UnregistKeyMutePressedUp()110 void CallWiredHeadSet::UnregistKeyMutePressedUp()
111 {
112 if (subscribeIdForPressedUp_ > 0) {
113 MMI::InputManager::GetInstance()->UnsubscribeKeyEvent(subscribeIdForPressedUp_);
114 }
115 }
116
UnregistKeyMutePressedDown()117 void CallWiredHeadSet::UnregistKeyMutePressedDown()
118 {
119 if (subscribeIdForPressedDown_ > 0) {
120 MMI::InputManager::GetInstance()->UnsubscribeKeyEvent(subscribeIdForPressedDown_);
121 }
122 }
123
124 // wired headset mute key pressed callback method
DealKeyMutePressedUp(std::shared_ptr<MMI::KeyEvent> event)125 void CallWiredHeadSet::DealKeyMutePressedUp(std::shared_ptr<MMI::KeyEvent> event)
126 {
127 TELEPHONY_LOGI("received KeyMute Pressed Up event");
128 if (DelayedSingleton<AudioDeviceManager>::GetInstance()->IsWiredHeadsetConnected() == true) {
129 time_t currentTime = GetCurrentTimeMS();
130 if ((currentTime - downFirstTime_) < FINAL_KEY_DOWN_DURATION_TWO) {
131 DealKeyMuteShortPressed();
132 } else if (!isProcessed_) {
133 DealKeyMuteLongPressed();
134 }
135 }
136 downFirstTime_ = 0;
137 isProcessed_ = false;
138 }
139
DealKeyMutePressedDown(std::shared_ptr<MMI::KeyEvent> event)140 void CallWiredHeadSet::DealKeyMutePressedDown(std::shared_ptr<MMI::KeyEvent> event)
141 {
142 TELEPHONY_LOGI("received KeyMute Pressed Down event");
143 if (isProcessed_) {
144 return;
145 }
146 if (DelayedSingleton<AudioDeviceManager>::GetInstance()->IsWiredHeadsetConnected() == true) {
147 time_t currentTime = GetCurrentTimeMS();
148 if (downFirstTime_ == 0) {
149 downFirstTime_ = GetCurrentTimeMS();
150 return;
151 }
152 if (!isProcessed_ && (currentTime - downFirstTime_ >= FINAL_KEY_DOWN_DURATION_TWO)) {
153 DealKeyMuteLongPressed();
154 isProcessed_ = true;
155 }
156 }
157 }
158
159 // wired headset mute key short pressed callback method
DealKeyMuteShortPressed()160 void CallWiredHeadSet::DealKeyMuteShortPressed()
161 {
162 sptr<CallBase> ringingCall = CallObjectManager::GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_RINGING);
163 if (ringingCall == nullptr) {
164 sptr<CallBase> holdCall = CallObjectManager::GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_HOLD);
165 sptr<CallBase> activeCall = CallObjectManager::GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_ACTIVE);
166 if (activeCall != nullptr && holdCall != nullptr) {
167 TELEPHONY_LOGI("DealKeyMuteShortPressed UnHoldCall callid(%{public}d)", holdCall->GetCallID());
168 DelayedSingleton<CallControlManager>::GetInstance()->UnHoldCall(holdCall->GetCallID());
169 return;
170 }
171 sptr<CallBase> call = CallObjectManager::GetAudioLiveCall();
172 if (call != nullptr) {
173 bool isMuted = DelayedSingleton<AudioProxy>::GetInstance()->IsMicrophoneMute();
174 TELEPHONY_LOGI("DealKeyMuteShortPressed SetMuted isMuted((%{public}d))", (!isMuted));
175 DelayedSingleton<CallControlManager>::GetInstance()->SetMuted(!isMuted);
176 }
177 } else {
178 TELEPHONY_LOGI("DealKeyMuteShortPressed AnswerCall callid(%{public}d)", ringingCall->GetCallID());
179 VideoStateType videoState = ringingCall->GetVideoStateType();
180 if (videoState != VideoStateType::TYPE_VOICE && videoState != VideoStateType::TYPE_VIDEO) {
181 TELEPHONY_LOGI("DealKeyMuteShortPressed get original call type");
182 videoState = static_cast<VideoStateType>(ringingCall->GetOriginalCallType());
183 }
184 DelayedSingleton<CallControlManager>::GetInstance()->AnswerCall(
185 ringingCall->GetCallID(), static_cast<int32_t>(videoState));
186 }
187 }
188
189 // wired headset mute key long pressed callback method
DealKeyMuteLongPressed()190 void CallWiredHeadSet::DealKeyMuteLongPressed()
191 {
192 sptr<CallBase> ringingCall = CallObjectManager::GetOneCallObject(CallRunningState::CALL_RUNNING_STATE_RINGING);
193 if (ringingCall != nullptr) {
194 TELEPHONY_LOGI("DealKeyMuteLongPressed RejectCall callid(%{public}d)", ringingCall->GetCallID());
195 ringingCall->RejectCall();
196 } else {
197 sptr<CallBase> foregroundCall = CallObjectManager::GetForegroundCall();
198 if (foregroundCall != nullptr) {
199 TelConferenceState confState = foregroundCall->GetTelConferenceState();
200 if (confState != TelConferenceState::TEL_CONFERENCE_IDLE) {
201 int32_t conferenceId = DelayedSingleton<ImsConference>::GetInstance()->GetMainCall();
202 TELEPHONY_LOGI("DealKeyMuteLongPressed HangUpCall conferenceId(%{public}d)", conferenceId);
203 DelayedSingleton<CallControlManager>::GetInstance()->HangUpCall(conferenceId);
204 } else {
205 TELEPHONY_LOGI("DealKeyMuteLongPressed HangUpCall callid(%{public}d)", foregroundCall->GetCallID());
206 foregroundCall->HangUpCall();
207 }
208 }
209 }
210 }
211
GetCurrentTimeMS()212 time_t CallWiredHeadSet::GetCurrentTimeMS()
213 {
214 std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tpMicro
215 = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
216 return tpMicro.time_since_epoch().count();
217 }
218 } // namespace Telephony
219 } // namespace OHOS