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