• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-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_voice_assistant_manager.h"
17 #include "distributed_call_manager.h"
18 #include "ffrt_inner.h"
19 
20 namespace {
21     ffrt::queue callVoiceAssistantQueue { "call_voice_assistant_manager",
22         ffrt::queue_attr().qos(ffrt_qos_user_interactive)};
23 }
24 
25 namespace OHOS {
26 namespace Telephony {
27 
28 std::shared_ptr<VoiceAssistantRingSubscriber> VoiceAssistantRingSubscriber::subscriber_ = nullptr;
29 std::shared_ptr<CallVoiceAssistantManager> CallVoiceAssistantManager::mInstance_ =
30     std::make_shared<CallVoiceAssistantManager>();
31 
GetInstance()32 std::shared_ptr<CallVoiceAssistantManager> CallVoiceAssistantManager::GetInstance()
33 {
34     if (mInstance_ != nullptr) {
35         return mInstance_;
36     }
37     return std::make_shared<CallVoiceAssistantManager>();
38 };
39 
IsStartVoiceBroadcast()40 bool CallVoiceAssistantManager::IsStartVoiceBroadcast()
41 {
42     if (!isQueryedBroadcastSwitch) {
43         TELEPHONY_LOGI("first query broad switch");
44         bool queryResult = IsSwitchOn(BROADCAST_SWITCH);
45         isBroadcastSwitchOn = queryResult;
46         isQueryedBroadcastSwitch = true;
47         return queryResult;
48     }
49     return isBroadcastSwitchOn;
50 }
51 
Initial()52 std::shared_ptr<DataShare::DataShareHelper> CallVoiceAssistantManager::Initial()
53 {
54     sptr<ISystemAbilityManager> saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
55     if (saManager == nullptr) {
56         TELEPHONY_LOGE("saManager is nullptr");
57         return nullptr;
58     }
59     sptr<IRemoteObject> remote = saManager->GetSystemAbility(OHOS::TELEPHONY_CALL_MANAGER_SYS_ABILITY_ID);
60     if (remote == nullptr) {
61         TELEPHONY_LOGE("remote is nullptr");
62         return nullptr;
63     }
64     return DataShare::DataShareHelper::Creator(remote, SETTINGS_DATASHARE_URI, SETTINGS_DATASHARE_EXT_URI);
65 };
66 
~CallVoiceAssistantManager()67 CallVoiceAssistantManager::~CallVoiceAssistantManager() {}
68 
Release()69 void CallVoiceAssistantManager::Release()
70 {
71     connectCallback_ = nullptr;
72     settingsCallback_ = nullptr;
73     mRemoteObject = nullptr;
74     isBroadcastSwitchOn = false;
75     isControlSwitchOn = false;
76     isQueryedBroadcastSwitch = false;
77     isConnectService = false;
78     broadcastCheck = DEFAULT_STRING;
79     isplay = SWITCH_TURN_OFF;
80 };
81 
IsSwitchOn(const std::string & switchState)82 bool CallVoiceAssistantManager::IsSwitchOn(const std::string& switchState)
83 {
84     bool isHiCarConnected = DelayedSingleton<DistributedCallManager>::GetInstance()->IsDistributedCarDeviceOnline();
85     if (isHiCarConnected) {
86         TELEPHONY_LOGI("hicar is connected, voice control by hicar");
87         return true;
88     }
89     int32_t userId = 0;
90     bool isUserUnlocked = false;
91     AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId);
92     AccountSA::OsAccountManager::IsOsAccountVerified(userId, isUserUnlocked);
93     if (!isUserUnlocked) {
94         TELEPHONY_LOGE("user is locked");
95         return false;
96     }
97     std::string value = SWITCH_TURN_OFF;
98     this->QueryValue(switchState, value);
99     TELEPHONY_LOGI("%{public}s is %{public}s", switchState.c_str(), value.c_str());
100     if (value == SWITCH_TURN_OFF) {
101         return false;
102     }
103     return true;
104 };
105 
RegisterListenSwitchState()106 bool CallVoiceAssistantManager::RegisterListenSwitchState()
107 {
108     if (settingsCallback_ == nullptr) {
109         settingsCallback_ = sptr<VoiceAssistantSwitchObserver>::MakeSptr();
110         if (settingsCallback_ == nullptr) {
111             TELEPHONY_LOGE("settingsCallback is nullptr");
112             return false;
113         }
114         auto datashareHelper_ = Initial();
115         if (datashareHelper_ == nullptr) {
116             TELEPHONY_LOGE("datashareHelper is nullptr");
117             return false;
118         }
119         OHOS::Uri uri_listen(SETTINGS_DATASHARE_URI_KEY + CONTROL_SWITCH);
120         datashareHelper_->RegisterObserver(uri_listen, settingsCallback_);
121         datashareHelper_->Release();
122     }
123     TELEPHONY_LOGI("listen success");
124     return true;
125 };
126 
UnRegisterListenSwitchState()127 bool CallVoiceAssistantManager::UnRegisterListenSwitchState()
128 {
129     if (settingsCallback_ == nullptr) {
130         TELEPHONY_LOGE("listen already close");
131         return false;
132     };
133     auto datashareHelper_ = Initial();
134     if (datashareHelper_ == nullptr) {
135         TELEPHONY_LOGE("datashareHelper is nullptr");
136         return false;
137     }
138     OHOS::Uri uri_listen(SETTINGS_DATASHARE_URI_KEY + CONTROL_SWITCH);
139     datashareHelper_->UnregisterObserver(uri_listen, settingsCallback_);
140     datashareHelper_->Release();
141     TELEPHONY_LOGI("listen close success");
142     return true;
143 };
144 
ConnectAbility(int32_t callId)145 bool CallVoiceAssistantManager::ConnectAbility(int32_t callId)
146 {
147     if (connectCallback_ == nullptr) {
148         connectCallback_ = sptr<VoiceAssistantConnectCallback>::MakeSptr(callId);
149         if (connectCallback_ == nullptr) {
150             TELEPHONY_LOGE("connectCallback is nullptr");
151             return false;
152         }
153     }
154     bool isHiCarConnected = DelayedSingleton<DistributedCallManager>::GetInstance()->IsDistributedCarDeviceOnline();
155     AAFwk::Want want;
156     AppExecFwk::ElementName element(
157         DEFAULT_STRING, isHiCarConnected ? HICAR_BUNDLE_NAME : BUNDLE_NAME, ABILITY_NAME);
158     want.SetElement(element);
159     int32_t userId = FAIL_CODE;
160     auto ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, connectCallback_, userId);
161     if (ret != TELEPHONY_SUCCESS && isBroadcastSwitchOn) {
162         VoiceAssistantRingSubscriber::Initial();
163         isplay = SWITCH_TURN_ON;
164         isConnectService = false;
165         PublishCommonEvent(false, std::string("connect_voice_assistant_ability_failed"));
166     }
167     return ret == TELEPHONY_SUCCESS;
168 };
169 
DisconnectAbility()170 bool CallVoiceAssistantManager::DisconnectAbility()
171 {
172     if (connectCallback_ == nullptr) {
173         TELEPHONY_LOGI("disconnectAbility already close");
174         return false;
175     }
176     auto ret = AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(connectCallback_);
177     TELEPHONY_LOGI("disconnectAbility %{public}d", ret);
178     return true;
179 };
180 
PublishCommonEvent(bool isConnect,std::string publisher)181 void CallVoiceAssistantManager::PublishCommonEvent(bool isConnect, std::string publisher)
182 {
183     if (connectCallback_ == nullptr) {
184         TELEPHONY_LOGI("service is not start");
185         return;
186     }
187     if (isConnect) {
188         isConnect = isConnectService;
189     }
190     std::string startService = isConnect ? SWITCH_TURN_ON : SWITCH_TURN_OFF;
191     EventFwk::Want want;
192     want.SetAction(CONTROL_SWITCH_STATE_CHANGE_EVENT);
193     want.SetParam(IS_CONNECT_SERVICE, startService);
194     want.SetParam(CONTROL_SWITCH.c_str(), controlCheck);
195     want.SetParam(BROADCAST_SWITCH.c_str(), broadcastCheck);
196     want.SetParam(IS_PLAY_RING, isplay);
197     want.SetParam("publisher_name", publisher);
198     EventFwk::CommonEventData data;
199     data.SetWant(want);
200     EventFwk::CommonEventPublishInfo publishInfo;
201     std::vector<std::string> recePermissions;
202     recePermissions.emplace_back("ohos.permission.ANSWER_CALL");
203     publishInfo.SetSubscriberPermissions(recePermissions);
204     EventFwk::CommonEventManager::PublishCommonEvent(data, publishInfo, nullptr);
205     TELEPHONY_LOGI("publish commonEvent done, [%{public}s].", publisher.c_str());
206 }
207 
OnStartService(const std::string & isDial,const int32_t & callId)208 void CallVoiceAssistantManager::OnStartService(const std::string& isDial, const int32_t& callId)
209 {
210     if (mRemoteObject != nullptr) {
211         TELEPHONY_LOGI("mRemote Object is not nullptr");
212         this->SendRequest(accountIds[callId], true);
213         return;
214     }
215     OnStopService();
216     if (isDial == INCOMING) {
217         IsStartVoiceBroadcast();
218     }
219     isControlSwitchOn = IsSwitchOn(CONTROL_SWITCH);
220     if (!isControlSwitchOn && !isBroadcastSwitchOn) {
221         TELEPHONY_LOGE("the switch is all close");
222         return;
223     }
224     if (ConnectAbility(callId)) {
225         TELEPHONY_LOGI("start service success");
226         return;
227     }
228     TELEPHONY_LOGE("start service failed");
229 };
230 
OnStopService(bool isDestructor)231 void CallVoiceAssistantManager::OnStopService(bool isDestructor)
232 {
233     TELEPHONY_LOGI("OnStopService enter");
234     DisconnectAbility();
235     UnRegisterListenSwitchState();
236     if (!isDestructor) {
237         DelayedSingleton<AudioControlManager>::GetInstance()->StopRingtone();
238     }
239     VoiceAssistantRingSubscriber::Release();
240     PublishCommonEvent(false, std::string("on_stop_service"));
241     Release();
242 };
243 
QueryValue(const std::string & key,std::string & value)244 int CallVoiceAssistantManager::QueryValue(const std::string& key, std::string& value)
245 {
246     auto datashareHelper_ = Initial();
247     if (datashareHelper_ == nullptr) {
248         TELEPHONY_LOGE("datashareHelper is nullptr");
249         return FAIL_CODE;
250     }
251     std::vector<std::string> columns;
252     DataShare::DataSharePredicates predicates;
253     predicates.EqualTo("KEYWORD", key);
254     OHOS::Uri uri(SETTINGS_DATASHARE_URI_KEY + key);
255     auto result = datashareHelper_->Query(uri, predicates, columns);
256     datashareHelper_->Release();
257     if (result == nullptr) {
258         TELEPHONY_LOGE("result is nullptr");
259         return FAIL_CODE;
260     }
261     int rowCount = 0;
262     result->GetRowCount(rowCount);
263     if (rowCount == 0) {
264         TELEPHONY_LOGI("rowCount is 0");
265         result->Close();
266         return FAIL_CODE;
267     }
268     if (result->GoToFirstRow() != DataShare::E_OK) {
269         TELEPHONY_LOGE("gotofirst row error");
270         result->Close();
271         return FAIL_CODE;
272     }
273     int columnIndex = 0;
274     result->GetColumnIndex("VALUE", columnIndex);
275     result->GetString(columnIndex, value);
276     result->Close();
277     return TELEPHONY_SUCCESS;
278 }
279 
UpdateNumberLocation(const std::string & location,int32_t callId)280 void CallVoiceAssistantManager::UpdateNumberLocation(const std::string& location, int32_t callId)
281 {
282     callVoiceAssistantQueue.submit([=]() {
283         TELEPHONY_LOGI("update location callId, %{public}d", callId);
284         auto it_callId = accountIds.find(callId);
285         if (it_callId == accountIds.end()) {
286             TELEPHONY_LOGE("iterator is end");
287             return;
288         }
289         auto nowInfo = it_callId->second;
290         if (nowInfo == nullptr) {
291             TELEPHONY_LOGE("info is nullptr");
292             return;
293         }
294         if ((TelCallState)nowInfo->call_status == TelCallState::CALL_STATUS_DIALING) {
295             TELEPHONY_LOGE("dialing without number location");
296             return;
297         }
298         nowInfo->numberLocation = location;
299         SendRequest(nowInfo, true);
300     });
301 }
302 
GetContactInfo(int32_t callId)303 std::shared_ptr<IncomingContactInformation> CallVoiceAssistantManager::GetContactInfo(int32_t callId)
304 {
305     if (accountIds[callId] == nullptr) {
306         TELEPHONY_LOGI("initial accountIds callId, %{public}d", callId);
307         accountIds[callId] = std::make_shared<IncomingContactInformation>();
308     }
309     return accountIds[callId];
310 }
311 
UpdateRemoteObject(const sptr<IRemoteObject> & object,int32_t callId,const sptr<AAFwk::IAbilityConnection> callback)312 void CallVoiceAssistantManager::UpdateRemoteObject(const sptr<IRemoteObject> &object, int32_t callId,
313     const sptr<AAFwk::IAbilityConnection> callback)
314 {
315     callVoiceAssistantQueue.submit([=]() {
316         TELEPHONY_LOGI("update remote object callId, %{public}d", callId);
317         if (nowCallId != callId || accountIds.find(callId) == accountIds.end()) {
318             TELEPHONY_LOGE("nowCallId, %{public}d", nowCallId);
319             AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(callback);
320             return;
321         }
322         mRemoteObject = object;
323         this->SendRequest(accountIds[callId], true);
324     });
325 }
326 
UpdateContactInfo(const ContactInfo & info,int32_t callId)327 void CallVoiceAssistantManager::UpdateContactInfo(const ContactInfo& info, int32_t callId)
328 {
329     callVoiceAssistantQueue.submit([=]() {
330         TELEPHONY_LOGI("update contact info callId, %{public}d", callId);
331         auto it_callId = accountIds.find(callId);
332         if (it_callId == accountIds.end()) {
333             TELEPHONY_LOGE("iterator is end");
334             return;
335         }
336         auto nowInfo = it_callId->second;
337         if (nowInfo == nullptr) {
338             TELEPHONY_LOGE("info is nullptr");
339             return;
340         }
341         if ((TelCallState)nowInfo->call_status == TelCallState::CALL_STATUS_DIALING) {
342             TELEPHONY_LOGE("dialing without contact info");
343             return;
344         }
345         nowInfo->incomingName = info.name;
346         nowInfo->phoneNumber = info.number;
347         nowInfo->isQueryComplete = info.isQueryComplete;
348         nowInfo->isContact = (nowInfo->incomingName == "") ? SWITCH_TURN_OFF : SWITCH_TURN_ON;
349         SendRequest(nowInfo, true);
350     });
351 }
352 
MuteRinger()353 void CallVoiceAssistantManager::MuteRinger()
354 {
355     callVoiceAssistantQueue.submit([=]() {
356         TELEPHONY_LOGI("stop broadcast event and SetRingToneVolume");
357         DelayedSingleton<AudioControlManager>::GetInstance()->SetRingToneVolume(0.0f);
358         VoiceAssistantRingSubscriber::Release();
359         isplay = SWITCH_TURN_OFF;
360         if (nowCallId == FAIL_CODE) {
361             TELEPHONY_LOGE("nowCallId is invalid");
362             return;
363         }
364         auto info = accountIds[nowCallId];
365         if (info != nullptr) {
366             info->stopBroadcasting = 1;
367         }
368         this->SendRequest(info, false);
369         this->PublishCommonEvent(isConnectService, std::string("stop_broadcast_event"));
370     });
371 }
372 
SendRequest(const std::shared_ptr<IncomingContactInformation> info,bool isNeed)373 void CallVoiceAssistantManager::SendRequest(const std::shared_ptr<IncomingContactInformation> info, bool isNeed)
374 {
375     if (mRemoteObject == nullptr) {
376         TELEPHONY_LOGE("mRemoteObject is nullptr");
377         return;
378     }
379     if (info == nullptr) {
380         TELEPHONY_LOGE("info is nullptr");
381         return;
382     }
383     if (!info->isQueryComplete || info->dialOrCome == DEFAULT_STRING || info->numberLocation == "default") {
384         TELEPHONY_LOGE("exist null string: %{public}s.", (info->dialOrCome).c_str());
385         return;
386     }
387     MessageParcel data;
388     MessageParcel reply;
389     MessageOption option;
390     std::u16string sendStr = GetSendString(info);
391     if (sendStr == DEFAULT_U16STRING) {
392         TELEPHONY_LOGE("send string is invalid");
393         return;
394     }
395     data.WriteString16(sendStr);
396     int32_t retCode = mRemoteObject->SendRequest(CHECK_CODE, data, reply, option);
397     TELEPHONY_LOGI("send request ret code: %{public}d.", retCode);
398     if (!isNeed) {
399         return;
400     }
401     isConnectService = false;
402     isplay = SWITCH_TURN_OFF;
403     UpdateReplyData(Str16ToStr8(reply.ReadString16()));
404     if (controlCheck == SWITCH_TURN_ON && isControlSwitchOn) {
405         isConnectService = true;
406         RegisterListenSwitchState();
407     }
408     bool isShouldRing = (broadcastCheck == SWITCH_TURN_ON || retCode != TELEPHONY_SUCCESS);
409     if (isShouldRing && isBroadcastSwitchOn && info->stopBroadcasting == 0 && info->dialOrCome != DIALING) {
410         VoiceAssistantRingSubscriber::Initial();
411         isplay = SWITCH_TURN_ON;
412     }
413     PublishCommonEvent(isConnectService, std::string("remote_object_send_request"));
414 }
415 
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)416 void VoiceAssistantConnectCallback::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
417     const sptr<IRemoteObject> &remoteObject, int resultCode)
418 {
419     TELEPHONY_LOGI("connect callback result code, %{public}d", resultCode);
420     if (remoteObject == nullptr) {
421         TELEPHONY_LOGE("RemoteObject is nullptr");
422         return;
423     }
424     if (resultCode == TELEPHONY_SUCCESS) {
425         sptr<AAFwk::IAbilityConnection> callback = sptr<AAFwk::IAbilityConnection>(this);
426         CallVoiceAssistantManager::GetInstance()->UpdateRemoteObject(remoteObject, startId, callback);
427     }
428 };
429 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)430 void VoiceAssistantConnectCallback::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
431 {
432     TELEPHONY_LOGI("disconnect callback result code, %{public}d", resultCode);
433 };
434 
GetSendString(const std::shared_ptr<IncomingContactInformation> nowInfo)435 std::u16string CallVoiceAssistantManager::GetSendString(const std::shared_ptr<IncomingContactInformation> nowInfo)
436 {
437     if (nowInfo == nullptr) {
438         TELEPHONY_LOGE("nowInfo is nullptr");
439         return DEFAULT_U16STRING;
440     }
441     if (Str8ToStr16(nowInfo->incomingName) == DEFAULT_U16STRING) {
442         TELEPHONY_LOGE("incomingName is invalid.");
443         nowInfo->incomingName = DEFAULT_STRING;
444     }
445     if (Str8ToStr16(nowInfo->numberLocation) == DEFAULT_U16STRING) {
446         TELEPHONY_LOGE("numberLocation is invalid.");
447         nowInfo->numberLocation = DEFAULT_STRING;
448     }
449     if (Str8ToStr16(nowInfo->phoneNumber) == DEFAULT_U16STRING) {
450         TELEPHONY_LOGE("phoneNumber is invalid.");
451         nowInfo->phoneNumber = DEFAULT_STRING;
452     }
453     std::string str = DEFAULT_STRING;
454     auto fun = [&str](std::string key, std::string value, bool start = false, bool end = false) {
455         std::string first = (start) ? "{" : "";
456         std::string last = (end) ? "}" : ",";
457         str = str + first + "\"" + key + "\"" + ":" + "\"" + value + "\"" + last;
458     };
459     fun("dialOrCome", nowInfo->dialOrCome, true);
460     fun("callStatus", std::to_string(nowInfo->call_status));
461     fun("callId", std::to_string(nowInfo->callId));
462     fun("phoneNumber", nowInfo->phoneNumber);
463     fun("isContact", nowInfo->isContact);
464     fun("contactName", nowInfo->incomingName);
465     fun("sim", std::to_string(nowInfo->accountId));
466     fun("stopBroadcasting", std::to_string(nowInfo->stopBroadcasting));
467     fun("location", nowInfo->numberLocation, false, true);
468     return Str8ToStr16(str);
469 }
470 
OnChange()471 void VoiceAssistantSwitchObserver::OnChange()
472 {
473     auto voicePtr = CallVoiceAssistantManager::GetInstance();
474     if (voicePtr == nullptr) {
475         TELEPHONY_LOGE("voicePtr is nullptr");
476         return;
477     }
478     std::string switch_off = voicePtr->SWITCH_TURN_OFF;
479     auto lastControlVal = voicePtr->GetIsControlSwitchOn();
480     if (!lastControlVal) {
481         TELEPHONY_LOGI("the controlswitch already close");
482         return;
483     }
484     auto ret = voicePtr->IsSwitchOn(voicePtr->CONTROL_SWITCH);
485     if (lastControlVal && !ret) {
486         TELEPHONY_LOGI("controlswitch from true to false");
487         voicePtr->PublishCommonEvent(false, std::string("control_switch_state_on_change"));
488         voicePtr->SetIsControlSwitchOn(false);
489     }
490 }
491 
CallStateUpdated(sptr<CallBase> & callObjectPtr,TelCallState priorState,TelCallState nextState)492 void CallVoiceAssistantManager::CallStateUpdated(
493     sptr<CallBase> &callObjectPtr, TelCallState priorState, TelCallState nextState)
494 {
495     callVoiceAssistantQueue.submit([=]() {
496         if (callObjectPtr == nullptr) {
497             TELEPHONY_LOGE("callobject is nullptr");
498             return;
499         }
500         TelCallState callState = callObjectPtr->GetTelCallState();
501         if (callState != TelCallState::CALL_STATUS_ACTIVE && callState != TelCallState::CALL_STATUS_DIALING &&
502             callState != TelCallState::CALL_STATUS_INCOMING && callState != TelCallState::CALL_STATUS_DISCONNECTED) {
503             return;
504         }
505         int32_t callId = callObjectPtr->GetCallID();
506         int32_t accountId = callObjectPtr->GetAccountId();
507         auto info = GetContactInfo(callId);
508         if (info != nullptr) {
509             info->call_status = (int32_t)callState;
510             info->accountId = accountId;
511             info->callId = callId;
512             info->call = callObjectPtr;
513         }
514         switch (callState) {
515             case TelCallState::CALL_STATUS_ACTIVE:
516                 CallStatusActive(callId, accountId);
517                 break;
518             case TelCallState::CALL_STATUS_DIALING:
519                 CallStatusDialing(callId, accountId);
520                 break;
521             case TelCallState::CALL_STATUS_INCOMING:
522                 if (!CallObjectManager::IsNeedSilentInDoNotDisturbMode()) {
523                     CallStatusIncoming(callId, accountId);
524                 } else {
525                     TELEPHONY_LOGI("need silent, no need voice assistant");
526                 }
527                 break;
528             case TelCallState::CALL_STATUS_DISCONNECTED:
529                 CallStatusDisconnected(callId, accountId);
530                 break;
531             default:
532                 break;
533         }
534     });
535 }
536 
UpdateVoipCallState(int32_t state)537 void CallVoiceAssistantManager::UpdateVoipCallState(int32_t state)
538 {
539     TELEPHONY_LOGI("voip callstate is %{public}d", state);
540     nowVoipCallState = state;
541 }
542 
CallStatusIncoming(const int32_t & callId,const int32_t & accountId)543 void CallVoiceAssistantManager::CallStatusIncoming(const int32_t& callId, const int32_t& accountId)
544 {
545     if (nowCallId != callId && nowAccountId != accountId) {
546         TELEPHONY_LOGI("call_status_incoming, [%{public}d][%{public}d]", accountId, callId);
547         if ((CallStateToApp)nowVoipCallState == CallStateToApp::CALL_STATE_OFFHOOK) {
548             TELEPHONY_LOGE("the meetime callstate is off_hook");
549             OnStopService();
550             return;
551         }
552         auto info = accountIds[callId];
553         if (info == nullptr) {
554             TELEPHONY_LOGE("info is nullptr");
555             return;
556         }
557         info->dialOrCome = INCOMING;
558         if (CheckTelCallState(TelCallState::CALL_STATUS_ACTIVE) != FAIL_CODE) {
559             return;
560         }
561         if (CheckTelCallState(TelCallState::CALL_STATUS_DIALING) != FAIL_CODE) {
562             info->dialOrCome = DIALING;
563         }
564         if (info->call != nullptr) {
565             ContactInfo contactInfo = info->call->GetCallerInfo();
566             info->numberLocation = info->call->GetNumberLocation();
567             info->incomingName = contactInfo.name;
568             info->phoneNumber = contactInfo.number;
569             info->isContact = (info->incomingName == "") ? SWITCH_TURN_OFF : SWITCH_TURN_ON;
570             info->isQueryComplete = contactInfo.isQueryComplete;
571         }
572         nowCallId = callId;
573         nowAccountId = accountId;
574         OnStartService(info->dialOrCome, callId);
575     }
576 }
577 
CallStatusDialing(const int32_t & callId,const int32_t & accountId)578 void CallVoiceAssistantManager::CallStatusDialing(const int32_t& callId, const int32_t& accountId)
579 {
580     auto info = accountIds[callId];
581     if (info == nullptr) {
582         TELEPHONY_LOGE("info is nullptr");
583         return;
584     }
585     if (nowCallId != callId && nowAccountId != accountId) {
586         TELEPHONY_LOGI("call_status_dialing, [%{public}d][%{public}d]", accountId, callId);
587         info->dialOrCome = DIALING;
588         info->numberLocation = DIALING;
589         info->phoneNumber = DIALING;
590         info->isQueryComplete = true;
591         nowCallId = callId;
592         nowAccountId = accountId;
593         OnStartService(info->dialOrCome, callId);
594     }
595 }
596 
CallStatusActive(const int32_t & callId,const int32_t & accountId)597 void CallVoiceAssistantManager::CallStatusActive(const int32_t& callId, const int32_t& accountId)
598 {
599     TELEPHONY_LOGI("muteRinger before playSoundTone, [%{public}d][%{public}d]", accountId, callId);
600     DelayedSingleton<AudioControlManager>::GetInstance()->SetRingToneVolume(0.0f);
601     VoiceAssistantRingSubscriber::Release();
602     PublishCommonEvent(false, std::string("call_status_active"));
603     mRemoteObject = nullptr;
604     isQueryedBroadcastSwitch = false;
605 }
606 
CallStatusDisconnected(const int32_t & callId,const int32_t & accountId)607 void CallVoiceAssistantManager::CallStatusDisconnected(const int32_t& callId, const int32_t& accountId)
608 {
609     TELEPHONY_LOGI("call_status_disconnected, [%{public}d][%{public}d]", accountId, callId);
610     auto lastInfo = accountIds[callId];
611     accountIds.erase(callId);
612     if (CheckTelCallState(TelCallState::CALL_STATUS_ACTIVE) != FAIL_CODE) {
613         return;
614     }
615     int32_t comeCallId = CheckTelCallState(TelCallState::CALL_STATUS_INCOMING);
616     TELEPHONY_LOGI("comeCallId, %{public}d.", comeCallId);
617     if (comeCallId != FAIL_CODE) {
618         auto nowInfo = accountIds[comeCallId];
619         if (nowInfo != nullptr && nowInfo->dialOrCome == INCOMING) {
620             nowCallId = nowInfo->callId;
621             nowAccountId = nowInfo->accountId;
622             SendRequest(nowInfo, true);
623         }
624         return;
625     }
626     TELEPHONY_LOGI("accountIds size is %{public}zu", accountIds.size());
627     SendRequest(lastInfo, false);
628     OnStopService();
629     nowCallId = FAIL_CODE;
630     nowAccountId = FAIL_CODE;
631 }
632 
CheckTelCallState(TelCallState state)633 int32_t CallVoiceAssistantManager::CheckTelCallState(TelCallState state)
634 {
635     TELEPHONY_LOGI("check state, %{public}d.", state);
636     int32_t invalid = FAIL_CODE;
637     for (auto& id : accountIds) {
638         if (id.second == nullptr) {
639             TELEPHONY_LOGE("invalid callId, %{public}d.", id.first);
640             invalid = id.first;
641             continue;
642         }
643         TELEPHONY_LOGI("callId %{public}d, state %{public}d.", id.first, id.second->call_status);
644         if ((TelCallState)id.second->call_status == state) {
645             return id.first;
646         }
647     }
648     accountIds.erase(invalid);
649     return FAIL_CODE;
650 }
651 
VoiceAssistantRingSubscriber(const EventFwk::CommonEventSubscribeInfo & subscriberInfo)652 VoiceAssistantRingSubscriber::VoiceAssistantRingSubscriber(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
653     : EventFwk::CommonEventSubscriber(subscriberInfo) {}
654 
Initial()655 bool VoiceAssistantRingSubscriber::Initial()
656 {
657     if (subscriber_ == nullptr) {
658         auto voicePtr = CallVoiceAssistantManager::GetInstance();
659         if (voicePtr == nullptr) {
660             TELEPHONY_LOGE("voicePtr is nullptr");
661             return false;
662         }
663         EventFwk::MatchingSkills matchingSkills;
664         matchingSkills.AddEvent(voicePtr->CONTROL_SWITCH_STATE_CHANGE_EVENT);
665         EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
666         subscribeInfo.SetPermission("ohos.permission.GET_TELEPHONY_STATE");
667         subscriber_ = std::make_shared<VoiceAssistantRingSubscriber>(subscribeInfo);
668         EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber_);
669     }
670     TELEPHONY_LOGI("prepare ring initial");
671     return true;
672 };
673 
Release()674 void VoiceAssistantRingSubscriber::Release()
675 {
676     if (subscriber_ != nullptr) {
677         TELEPHONY_LOGI("UnSubscribeCommonEvent");
678         EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriber_);
679         subscriber_ = nullptr;
680     }
681 }
682 
OnReceiveEvent(const EventFwk::CommonEventData & eventData)683 void VoiceAssistantRingSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
684 {
685     callVoiceAssistantQueue.submit([=]() {
686         auto voicePtr = CallVoiceAssistantManager::GetInstance();
687         if (voicePtr == nullptr) {
688             TELEPHONY_LOGE("voicePtr is nullptr");
689             return;
690         }
691         const AAFwk::Want &want = eventData.GetWant();
692         std::string action = want.GetAction();
693         if (action != voicePtr->CONTROL_SWITCH_STATE_CHANGE_EVENT) {
694             return;
695         }
696         std::string publisher = want.GetStringParam("publisher_name");
697         if (publisher != std::string("remote_object_send_request") &&
698             publisher != std::string("connect_voice_assistant_ability_failed")) {
699             TELEPHONY_LOGE("publisher name, [%{public}s]", publisher.c_str());
700             return;
701         }
702         std::string isplay = want.GetStringParam(voicePtr->IS_PLAY_RING);
703         bool isPlayRing = voicePtr->GetIsPlayRing();
704         if (isplay == voicePtr->SWITCH_TURN_ON && isPlayRing) {
705             TELEPHONY_LOGI("broadcast switch is open, start play system ring");
706             DelayedSingleton<AudioControlManager>::GetInstance()->StopRingtone();
707             sptr<CallBase> incomingCall =
708                 CallObjectManager::GetOneCarrierCallObject(CallRunningState::CALL_RUNNING_STATE_RINGING);
709             ContactInfo contactInfo = incomingCall->GetCallerInfo();
710             if (DelayedSingleton<AudioControlManager>::GetInstance()->NeedPlayVideoRing(contactInfo, incomingCall)) {
711                 AAFwk::WantParams params = incomingCall->GetExtraParams();
712                 params.SetParam("VideoRingPath", AAFwk::String::Box(std::string(contactInfo.ringtonePath)));
713                 incomingCall->SetExtraParams(params);
714                 CallAttributeInfo info;
715                 incomingCall->GetCallAttributeBaseInfo(info);
716                 DelayedSingleton<CallAbilityReportProxy>::GetInstance()->ReportCallStateInfo(info);
717             }
718             DelayedSingleton<AudioControlManager>::GetInstance()->PlayRingtone();
719         }
720     });
721 };
722 
GetIsPlayRing()723 bool CallVoiceAssistantManager::GetIsPlayRing()
724 {
725     return (isplay == SWITCH_TURN_ON) ? true : false;
726 }
727 
SetIsControlSwitchOn(bool state)728 void CallVoiceAssistantManager::SetIsControlSwitchOn(bool state)
729 {
730     isControlSwitchOn = state;
731 };
732 
GetIsControlSwitchOn()733 bool CallVoiceAssistantManager::GetIsControlSwitchOn()
734 {
735     return isControlSwitchOn;
736 };
737 
UpdateReplyData(const std::string & str)738 void CallVoiceAssistantManager::UpdateReplyData(const std::string& str)
739 {
740     TELEPHONY_LOGI("receiveData, %{public}s.", str.c_str());
741     std::size_t pos1 = 0;
742     std::size_t pos2 = 0;
743     std::map<std::string, std::string> replyData;
744     while (pos1 != std::string::npos && pos2 != std::string::npos) {
745         pos1 = str.find("\"", pos2 + 1);
746         if (pos1 == std::string::npos) {
747             break;
748         }
749         pos2 = str.find("\"", pos1 + 1);
750         if (pos2 == std::string::npos) {
751             break;
752         }
753         auto key = str.substr(pos1 + 1, pos2 -pos1 - 1);
754         pos1 = str.find("\"", pos2 + 1);
755         if (pos1 == std::string::npos) {
756             break;
757         }
758         pos2 = str.find("\"", pos1 + 1);
759         if (pos2 == std::string::npos) {
760             break;
761         }
762         auto value = str.substr(pos1 + 1, pos2 -pos1 - 1);
763         replyData.insert({key, value});
764     }
765     controlCheck = SWITCH_TURN_OFF;
766     broadcastCheck = DEFAULT_STRING;
767     auto it_control = replyData.find(CONTROL_CHECK_RESULT);
768     if (it_control != replyData.end()) {
769         controlCheck = it_control->second;
770     }
771     auto it_broadcast = replyData.find(BROADCAST_CHECK_RESULT);
772     if (it_broadcast != replyData.end()) {
773         broadcastCheck = it_broadcast->second;
774     }
775     TELEPHONY_LOGI("%{public}s, %{public}s.", broadcastCheck.c_str(), controlCheck.c_str());
776 }
777 }
778 }