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