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 }