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, reply;
357     MessageOption option;
358     std::u16string sendStr = GetSendString(info);
359     if (sendStr == DEFAULT_U16STRING) {
360         TELEPHONY_LOGE("send string is invalid");
361         return;
362     }
363     data.WriteString16(sendStr);
364     int32_t retCode = mRemoteObject->SendRequest(CHECK_CODE, data, reply, option);
365     TELEPHONY_LOGI("send request ret code: %{public}d.", retCode);
366     if (!isNeed) {
367         return;
368     }
369     isConnectService = false;
370     isplay = SWITCH_TURN_OFF;
371     UpdateReplyData(Str16ToStr8(reply.ReadString16()));
372     if (controlCheck == SWITCH_TURN_ON && isControlSwitchOn) {
373         isConnectService = true;
374         RegisterListenSwitchState();
375     }
376     bool isShouldRing = (broadcastCheck == SWITCH_TURN_ON || retCode != TELEPHONY_SUCCESS);
377     if (isShouldRing && isBroadcastSwitchOn && info->stopBroadcasting == 0 && info->dialOrCome != DIALING) {
378         VoiceAssistantRingSubscriber::Initial();
379         isplay = SWITCH_TURN_ON;
380     }
381     PublishCommonEvent(isConnectService, std::string("remote_object_send_request"));
382 }
383 
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)384 void VoiceAssistantConnectCallback::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
385     const sptr<IRemoteObject> &remoteObject, int resultCode)
386 {
387     TELEPHONY_LOGI("connect callback result code, %{public}d", resultCode);
388     if (remoteObject == nullptr) {
389         TELEPHONY_LOGE("RemoteObject is nullptr");
390         return;
391     }
392     if (resultCode == TELEPHONY_SUCCESS) {
393         sptr<AAFwk::IAbilityConnection> callback = sptr<AAFwk::IAbilityConnection>(this);
394         CallVoiceAssistantManager::GetInstance()->UpdateRemoteObject(remoteObject, startId, callback);
395     }
396 };
397 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)398 void VoiceAssistantConnectCallback::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
399 {
400     TELEPHONY_LOGI("disconnect callback result code, %{public}d", resultCode);
401 };
402 
GetSendString(const std::shared_ptr<IncomingContactInformation> nowInfo)403 std::u16string CallVoiceAssistantManager::GetSendString(const std::shared_ptr<IncomingContactInformation> nowInfo)
404 {
405     if (nowInfo == nullptr) {
406         TELEPHONY_LOGE("nowInfo is nullptr");
407         return DEFAULT_U16STRING;
408     }
409     if (Str8ToStr16(nowInfo->incomingName) == DEFAULT_U16STRING) {
410         TELEPHONY_LOGE("incomingName is invalid.");
411         nowInfo->incomingName = DEFAULT_STRING;
412     }
413     if (Str8ToStr16(nowInfo->numberLocation) == DEFAULT_U16STRING) {
414         TELEPHONY_LOGE("numberLocation is invalid.");
415         nowInfo->numberLocation = DEFAULT_STRING;
416     }
417     if (Str8ToStr16(nowInfo->phoneNumber) == DEFAULT_U16STRING) {
418         TELEPHONY_LOGE("phoneNumber is invalid.");
419         nowInfo->phoneNumber = DEFAULT_STRING;
420     }
421     std::string str = DEFAULT_STRING;
422     auto fun = [&str](std::string key, std::string value, bool start = false, bool end = false) {
423         std::string first = (start) ? "{" : "";
424         std::string last = (end) ? "}" : ",";
425         str = str + first + "\"" + key + "\"" + ":" + "\"" + value + "\"" + last;
426     };
427     fun("dialOrCome", nowInfo->dialOrCome, true);
428     fun("callStatus", std::to_string(nowInfo->call_status));
429     fun("callId", std::to_string(nowInfo->callId));
430     fun("phoneNumber", nowInfo->phoneNumber);
431     fun("isContact", nowInfo->isContact);
432     fun("contactName", nowInfo->incomingName);
433     fun("sim", std::to_string(nowInfo->accountId));
434     fun("stopBroadcasting", std::to_string(nowInfo->stopBroadcasting));
435     fun("location", nowInfo->numberLocation, false, true);
436     return Str8ToStr16(str);
437 }
438 
OnChange()439 void VoiceAssistantSwitchObserver::OnChange()
440 {
441     auto voicePtr = CallVoiceAssistantManager::GetInstance();
442     if (voicePtr == nullptr) {
443         TELEPHONY_LOGE("voicePtr is nullptr");
444         return;
445     }
446     std::string switch_off = voicePtr->SWITCH_TURN_OFF;
447     auto lastControlVal = voicePtr->GetIsControlSwitchOn();
448     if (!lastControlVal) {
449         TELEPHONY_LOGI("the controlswitch already close");
450         return;
451     }
452     auto ret = voicePtr->IsSwitchOn(voicePtr->CONTROL_SWITCH);
453     if (lastControlVal && !ret) {
454         TELEPHONY_LOGI("controlswitch from true to false");
455         voicePtr->PublishCommonEvent(false, std::string("control_switch_state_on_change"));
456         voicePtr->SetIsControlSwitchOn(false);
457     }
458 }
459 
CallStateUpdated(sptr<CallBase> & callObjectPtr,TelCallState priorState,TelCallState nextState)460 void CallVoiceAssistantManager::CallStateUpdated(
461     sptr<CallBase> &callObjectPtr, TelCallState priorState, TelCallState nextState)
462 {
463     if (callObjectPtr == nullptr) {
464         TELEPHONY_LOGE("callobject is nullptr");
465         return;
466     }
467     std::lock_guard<std::mutex> lock(mutex_);
468     TelCallState callState = callObjectPtr->GetTelCallState();
469     if (callState != TelCallState::CALL_STATUS_ACTIVE && callState != TelCallState::CALL_STATUS_DIALING &&
470         callState != TelCallState::CALL_STATUS_INCOMING && callState != TelCallState::CALL_STATUS_DISCONNECTED) {
471         return;
472     }
473     int32_t callId = callObjectPtr->GetCallID();
474     int32_t accountId = callObjectPtr->GetAccountId();
475     auto info = GetContactInfo(callId);
476     if (info != nullptr) {
477         info->call_status = (int32_t)callState;
478         info->accountId = accountId;
479         info->callId = callId;
480         info->call = callObjectPtr;
481     }
482     switch (callState) {
483         case TelCallState::CALL_STATUS_ACTIVE:
484             CallStatusActive(callId, accountId);
485             break;
486         case TelCallState::CALL_STATUS_DIALING:
487             CallStatusDialing(callId, accountId);
488             break;
489         case TelCallState::CALL_STATUS_INCOMING:
490             CallStatusIncoming(callId, accountId);
491             break;
492         case TelCallState::CALL_STATUS_DISCONNECTED:
493             CallStatusDisconnected(callId, accountId);
494             break;
495         default:
496             break;
497     }
498 }
499 
UpdateVoipCallState(int32_t state)500 void CallVoiceAssistantManager::UpdateVoipCallState(int32_t state)
501 {
502     TELEPHONY_LOGI("voip callstate is %{public}d", state);
503     nowVoipCallState = state;
504 }
505 
CallStatusIncoming(const int32_t & callId,const int32_t & accountId)506 void CallVoiceAssistantManager::CallStatusIncoming(const int32_t& callId, const int32_t& accountId)
507 {
508     if (nowCallId != callId && nowAccountId != accountId) {
509         TELEPHONY_LOGI("call_status_incoming, [%{public}d][%{public}d]", accountId, callId);
510         if ((CallStateToApp)nowVoipCallState == CallStateToApp::CALL_STATE_OFFHOOK) {
511             TELEPHONY_LOGE("the meetime callstate is off_hook");
512             OnStopService();
513             return;
514         }
515         auto info = accountIds[callId];
516         if (info == nullptr) {
517             TELEPHONY_LOGE("info is nullptr");
518             return;
519         }
520         info->dialOrCome = INCOMING;
521         if (CheckTelCallState(TelCallState::CALL_STATUS_ACTIVE) != FAIL_CODE) {
522             return;
523         }
524         if (CheckTelCallState(TelCallState::CALL_STATUS_DIALING) != FAIL_CODE) {
525             info->dialOrCome = DIALING;
526         }
527         if (info->call != nullptr) {
528             ContactInfo contactInfo = info->call->GetCallerInfo();
529             info->numberLocation = info->call->GetNumberLocation();
530             info->incomingName = contactInfo.name;
531             info->phoneNumber = contactInfo.number;
532             info->isContact = (info->incomingName == "") ? SWITCH_TURN_OFF : SWITCH_TURN_ON;
533             info->isQueryComplete = contactInfo.isQueryComplete;
534         }
535         nowCallId = callId;
536         nowAccountId = accountId;
537         OnStartService(info->dialOrCome, callId);
538     }
539 }
540 
CallStatusDialing(const int32_t & callId,const int32_t & accountId)541 void CallVoiceAssistantManager::CallStatusDialing(const int32_t& callId, const int32_t& accountId)
542 {
543     auto info = accountIds[callId];
544     if (info == nullptr) {
545         TELEPHONY_LOGE("info is nullptr");
546         return;
547     }
548     if (nowCallId != callId && nowAccountId != accountId) {
549         TELEPHONY_LOGI("call_status_dialing, [%{public}d][%{public}d]", accountId, callId);
550         info->dialOrCome = DIALING;
551         info->numberLocation = DIALING;
552         info->phoneNumber = DIALING;
553         info->isQueryComplete = true;
554         nowCallId = callId;
555         nowAccountId = accountId;
556         OnStartService(info->dialOrCome, callId);
557     }
558 }
559 
CallStatusActive(const int32_t & callId,const int32_t & accountId)560 void CallVoiceAssistantManager::CallStatusActive(const int32_t& callId, const int32_t& accountId)
561 {
562     TELEPHONY_LOGI("call_status_active, [%{public}d][%{public}d]", accountId, callId);
563     VoiceAssistantRingSubscriber::Release();
564     PublishCommonEvent(false, std::string("call_status_active"));
565     mRemoteObject = nullptr;
566     isQueryedBroadcastSwitch = false;
567 }
568 
CallStatusDisconnected(const int32_t & callId,const int32_t & accountId)569 void CallVoiceAssistantManager::CallStatusDisconnected(const int32_t& callId, const int32_t& accountId)
570 {
571     TELEPHONY_LOGI("call_status_disconnected, [%{public}d][%{public}d]", accountId, callId);
572     auto lastInfo = accountIds[callId];
573     accountIds.erase(callId);
574     if (CheckTelCallState(TelCallState::CALL_STATUS_ACTIVE) != FAIL_CODE) {
575         return;
576     }
577     int32_t comeCallId = CheckTelCallState(TelCallState::CALL_STATUS_INCOMING);
578     TELEPHONY_LOGI("comeCallId, %{public}d.", comeCallId);
579     if (comeCallId != FAIL_CODE) {
580         auto nowInfo = accountIds[comeCallId];
581         if (nowInfo != nullptr && nowInfo->dialOrCome == INCOMING) {
582             nowCallId = nowInfo->callId;
583             nowAccountId = nowInfo->accountId;
584             SendRequest(nowInfo, true);
585         }
586         return;
587     }
588     TELEPHONY_LOGI("accountIds size is %{public}zu", accountIds.size());
589     SendRequest(lastInfo, false);
590     OnStopService();
591     nowCallId = FAIL_CODE;
592     nowAccountId = FAIL_CODE;
593 }
594 
CheckTelCallState(TelCallState state)595 int32_t CallVoiceAssistantManager::CheckTelCallState(TelCallState state)
596 {
597     TELEPHONY_LOGI("check state, %{public}d.", state);
598     int32_t invalid = FAIL_CODE;
599     for (auto& id : accountIds) {
600         if (id.second == nullptr) {
601             TELEPHONY_LOGE("invalid callId, %{public}d.", id.first);
602             invalid = id.first;
603             continue;
604         }
605         TELEPHONY_LOGI("callId %{public}d, state %{public}d.", id.first, id.second->call_status);
606         if ((TelCallState)id.second->call_status == state) {
607             return id.first;
608         }
609     }
610     accountIds.erase(invalid);
611     return FAIL_CODE;
612 }
613 
VoiceAssistantRingSubscriber(const EventFwk::CommonEventSubscribeInfo & subscriberInfo)614 VoiceAssistantRingSubscriber::VoiceAssistantRingSubscriber(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
615     : EventFwk::CommonEventSubscriber(subscriberInfo) {}
616 
Initial()617 bool VoiceAssistantRingSubscriber::Initial()
618 {
619     if (subscriber_ == nullptr) {
620         auto voicePtr = CallVoiceAssistantManager::GetInstance();
621         if (voicePtr == nullptr) {
622             TELEPHONY_LOGE("voicePtr is nullptr");
623             return false;
624         }
625         EventFwk::MatchingSkills matchingSkills;
626         matchingSkills.AddEvent(voicePtr->CONTROL_SWITCH_STATE_CHANGE_EVENT);
627         EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
628         subscribeInfo.SetPermission("ohos.permission.GET_TELEPHONY_STATE");
629         subscriber_ = std::make_shared<VoiceAssistantRingSubscriber>(subscribeInfo);
630         EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber_);
631     }
632     TELEPHONY_LOGI("prepare ring initial");
633     return true;
634 };
635 
Release()636 void VoiceAssistantRingSubscriber::Release()
637 {
638     if (subscriber_ != nullptr) {
639         TELEPHONY_LOGI("stop play system ring");
640         DelayedSingleton<AudioControlManager>::GetInstance()->StopRingtone();
641         EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriber_);
642         subscriber_ = nullptr;
643     }
644 }
645 
OnReceiveEvent(const EventFwk::CommonEventData & eventData)646 void VoiceAssistantRingSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
647 {
648     auto voicePtr = CallVoiceAssistantManager::GetInstance();
649     if (voicePtr == nullptr) {
650         TELEPHONY_LOGE("voicePtr is nullptr");
651         return;
652     }
653     const AAFwk::Want &want = eventData.GetWant();
654     std::string action = want.GetAction();
655     if (action != voicePtr->CONTROL_SWITCH_STATE_CHANGE_EVENT) {
656         return;
657     }
658     std::string publisher = want.GetStringParam("publisher_name");
659     if (publisher != std::string("remote_object_send_request") &&
660         publisher != std::string("connect_voice_assistant_ability_failed")) {
661         TELEPHONY_LOGE("publisher name, [%{public}s]", publisher.c_str());
662         return;
663     }
664     std::string isplay = want.GetStringParam(voicePtr->IS_PLAY_RING);
665     bool isPlayRing = voicePtr->GetIsPlayRing();
666     if (isplay == voicePtr->SWITCH_TURN_ON && isPlayRing) {
667         TELEPHONY_LOGI("broadcast switch is open, start play system ring");
668         DelayedSingleton<AudioControlManager>::GetInstance()->StopRingtone();
669         DelayedSingleton<AudioControlManager>::GetInstance()->PlayRingtone();
670     }
671 };
672 
GetIsPlayRing()673 bool CallVoiceAssistantManager::GetIsPlayRing()
674 {
675     return (isplay == SWITCH_TURN_ON) ? true : false;
676 }
677 
SetIsControlSwitchOn(bool state)678 void CallVoiceAssistantManager::SetIsControlSwitchOn(bool state)
679 {
680     isControlSwitchOn = state;
681 };
682 
GetIsControlSwitchOn()683 bool CallVoiceAssistantManager::GetIsControlSwitchOn()
684 {
685     return isControlSwitchOn;
686 };
687 
UpdateReplyData(const std::string & str)688 void CallVoiceAssistantManager::UpdateReplyData(const std::string& str)
689 {
690     TELEPHONY_LOGI("receiveData, %{public}s.", str.c_str());
691     std::size_t pos1 = 0, pos2 = 0;
692     std::map<std::string, std::string> replyData;
693     while (pos1 != std::string::npos && pos2 != std::string::npos) {
694         pos1 = str.find("\"", pos2 + 1);
695         if (pos1 == std::string::npos) {
696             break;
697         }
698         pos2 = str.find("\"", pos1 + 1);
699         if (pos2 == std::string::npos) {
700             break;
701         }
702         auto key = str.substr(pos1 + 1, pos2 -pos1 - 1);
703         pos1 = str.find("\"", pos2 + 1);
704         if (pos1 == std::string::npos) {
705             break;
706         }
707         pos2 = str.find("\"", pos1 + 1);
708         if (pos2 == std::string::npos) {
709             break;
710         }
711         auto value = str.substr(pos1 + 1, pos2 -pos1 - 1);
712         replyData.insert({key, value});
713     }
714     controlCheck = SWITCH_TURN_OFF;
715     broadcastCheck = DEFAULT_STRING;
716     auto it_control = replyData.find(CONTROL_CHECK_RESULT);
717     if (it_control != replyData.end()) {
718         controlCheck = it_control->second;
719     }
720     auto it_broadcast = replyData.find(BROADCAST_CHECK_RESULT);
721     if (it_broadcast != replyData.end()) {
722         broadcastCheck = it_broadcast->second;
723     }
724     TELEPHONY_LOGI("%{public}s, %{public}s.", broadcastCheck.c_str(), controlCheck.c_str());
725 }
726 
727 }
728 }