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 }