1 /*
2 * Copyright (C) 2023-2025 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 <thread>
17 #include <pthread.h>
18
19 #include "distributed_call_manager.h"
20 #include "audio_control_manager.h"
21 #include "call_object_manager.h"
22 #include "telephony_log_wrapper.h"
23 #include "nlohmann/json.hpp"
24 #include "i_distributed_device_callback.h"
25 #ifdef ABILITY_BLUETOOTH_SUPPORT
26 #include "bluetooth_device.h"
27 #endif
28
29 using json = nlohmann::json;
30
31 namespace OHOS {
32 namespace Telephony {
33 using namespace AudioStandard;
34 namespace {
35 const size_t INT32_MIN_ID_LENGTH = 3;
36 const size_t INT32_SHORT_ID_LENGTH = 20;
37 const size_t INT32_PLAINTEXT_LENGTH = 4;
38 const int32_t DCALL_SWITCH_DEVICE_TYPE_SOURCE = 0;
39 const int32_t DCALL_SWITCH_DEVICE_TYPE_SINK = 1;
40 const int32_t DISTRIBUTED_CALL_SOURCE_SA_ID = 9855;
41 const int32_t IS_CELIA_CALL = 1;
42 const int32_t DEFAULT_DCALL_HFP_FLAG_VALUE = -1;
43 const int32_t DCALL_BT_HEADSET_UNWEAR_ACTION = 1;
44 const std::string CALLBACK_NAME = "telephony";
45 const std::string DISTRIBUTED_AUDIO_DEV_CAR = "dCar";
46 const std::string DISTRIBUTED_AUDIO_DEV_PHONE = "dPhone";
47 const std::string DISTRIBUTED_AUDIO_DEV_PAD = "dPad";
48 const std::string SWITCH_ON_DCALL_THREAD_NAME = "switch on dcall";
49
GetAnonyString(const std::string & value)50 std::string GetAnonyString(const std::string &value)
51 {
52 std::string res;
53 std::string tmpStr("******");
54 size_t strLen = value.length();
55 if (strLen < INT32_MIN_ID_LENGTH) {
56 return tmpStr;
57 }
58 if (strLen <= INT32_SHORT_ID_LENGTH) {
59 res += value[0];
60 res += tmpStr;
61 res += value[strLen - 1];
62 } else {
63 res.append(value, 0, INT32_PLAINTEXT_LENGTH);
64 res += tmpStr;
65 res.append(value, strLen - INT32_PLAINTEXT_LENGTH, INT32_PLAINTEXT_LENGTH);
66 }
67 return res;
68 }
69
IsDistributedAudioDevice(const AudioDevice & device)70 bool IsDistributedAudioDevice(const AudioDevice& device)
71 {
72 if ((device.deviceType == AudioDeviceType::DEVICE_DISTRIBUTED_PHONE) ||
73 (device.deviceType == AudioDeviceType::DEVICE_DISTRIBUTED_PAD) ||
74 (device.deviceType == AudioDeviceType::DEVICE_DISTRIBUTED_AUTOMOTIVE)) {
75 return true;
76 }
77 return false;
78 }
79 }
80
DistributedCallManager()81 DistributedCallManager::DistributedCallManager()
82 {
83 TELEPHONY_LOGI("DistributedCallManager constructed.");
84 }
85
~DistributedCallManager()86 DistributedCallManager::~DistributedCallManager()
87 {
88 TELEPHONY_LOGI("DistributedCallManager destructed.");
89 }
90
Init()91 void DistributedCallManager::Init()
92 {
93 TELEPHONY_LOGI("Init start.");
94 statusChangeListener_ = new (std::nothrow) DCallSystemAbilityListener();
95 if (statusChangeListener_ == nullptr) {
96 TELEPHONY_LOGE("failed to create statusChangeListener");
97 return;
98 }
99 auto managerPtr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
100 if (managerPtr == nullptr) {
101 TELEPHONY_LOGE("get system ability manager error");
102 return;
103 }
104 int32_t ret = managerPtr->SubscribeSystemAbility(DISTRIBUTED_CALL_SOURCE_SA_ID, statusChangeListener_);
105 if (ret != TELEPHONY_SUCCESS) {
106 TELEPHONY_LOGE("failed to subscribe dcall service SA: %{public}d", DISTRIBUTED_CALL_SOURCE_SA_ID);
107 return;
108 }
109 TELEPHONY_LOGI("Init end.");
110 }
111
CreateDAudioDevice(const std::string & devId,AudioDevice & device)112 bool DistributedCallManager::CreateDAudioDevice(const std::string& devId, AudioDevice& device)
113 {
114 if (!devId.length()) {
115 TELEPHONY_LOGE("dcall devId is invalid");
116 return false;
117 }
118 OHOS::DistributedHardware::DCallDeviceInfo devInfo;
119 {
120 std::lock_guard<std::mutex> lock(dcallProxyMtx_);
121 if (dcallProxy_ == nullptr) {
122 TELEPHONY_LOGE("dcallProxy_ is nullptr");
123 return false;
124 }
125 int32_t ret = dcallProxy_->GetDCallDeviceInfo(devId, devInfo);
126 if (ret != TELEPHONY_SUCCESS) {
127 TELEPHONY_LOGI("get dcall device info failed.");
128 return false;
129 }
130 }
131 std::string devTypeName;
132 std::string devName = devInfo.devName;
133 if (devInfo.devType == OHOS::DistributedHardware::DCallDeviceType::DISTRIBUTED_DEVICE_PHONE) {
134 devTypeName = DISTRIBUTED_AUDIO_DEV_PHONE;
135 device.deviceType = AudioDeviceType::DEVICE_DISTRIBUTED_PHONE;
136 } else if (devInfo.devType == OHOS::DistributedHardware::DCallDeviceType::DISTRIBUTED_DEVICE_PAD) {
137 devTypeName = DISTRIBUTED_AUDIO_DEV_PAD;
138 device.deviceType = AudioDeviceType::DEVICE_DISTRIBUTED_PAD;
139 } else {
140 devTypeName = DISTRIBUTED_AUDIO_DEV_CAR;
141 device.deviceType = AudioDeviceType::DEVICE_DISTRIBUTED_AUTOMOTIVE;
142 }
143 json addressJson;
144 addressJson["devName"] = devName;
145 addressJson["devId"] = devId;
146 std::string addressStr = addressJson.dump();
147 if (memcpy_s(device.address, kMaxAddressLen, addressStr.c_str(), addressStr.length()) != EOK) {
148 TELEPHONY_LOGE("memcpy_s failed.");
149 return false;
150 }
151 TELEPHONY_LOGI("create distributed audio device succeed.");
152 return true;
153 }
154
GetDevIdFromAudioDevice(const AudioDevice & device)155 std::string DistributedCallManager::GetDevIdFromAudioDevice(const AudioDevice& device)
156 {
157 std::string devId = "";
158 if (!IsDistributedAudioDevice(device)) {
159 TELEPHONY_LOGE("not distributed audio device, device type: %{public}d", device.deviceType);
160 return devId;
161 }
162 std::string address = device.address;
163 if (!address.length()) {
164 TELEPHONY_LOGE("invalid address");
165 return devId;
166 }
167 json addressJson = json::parse(address, nullptr, false);
168 if (addressJson.is_null() || addressJson.is_discarded()) {
169 TELEPHONY_LOGE("json value is null or discarded.");
170 return devId;
171 }
172 if (!addressJson.contains("devId")) {
173 TELEPHONY_LOGE("json not contain devId.");
174 return devId;
175 }
176 if (!addressJson["devId"].is_string()) {
177 TELEPHONY_LOGE("json has no devId string.");
178 return devId;
179 }
180 devId = addressJson["devId"];
181 TELEPHONY_LOGI("devId: %{public}s", GetAnonyString(devId).c_str());
182 return devId;
183 }
184
AddDCallDevice(const std::string & devId)185 int32_t DistributedCallManager::AddDCallDevice(const std::string& devId)
186 {
187 TELEPHONY_LOGI("add dcall device, devId: %{public}s.", GetAnonyString(devId).c_str());
188 #ifdef ABILITY_BLUETOOTH_SUPPORT
189 {
190 std::lock_guard<std::mutex> lock(mutex_);
191 if (dcallHfpListener_ == nullptr) {
192 dcallHfpListener_ = std::make_shared<DCallHfpListener>();
193 Bluetooth::HandsFreeAudioGateway::GetProfile()->RegisterObserver(dcallHfpListener_);
194 }
195 }
196 #endif
197 std::lock_guard<std::mutex> lock(onlineDeviceMtx_);
198
199 auto iter = onlineDCallDevices_.find(devId);
200 if (iter != onlineDCallDevices_.end()) {
201 TELEPHONY_LOGW("device is already exist, devId: %{public}s", GetAnonyString(devId).c_str());
202 return TELEPHONY_SUCCESS;
203 }
204
205 AudioDevice device;
206 if (!CreateDAudioDevice(devId, device)) {
207 TELEPHONY_LOGE("failed to create distributed audio device, devId: %{public}s", GetAnonyString(devId).c_str());
208 return TELEPHONY_ERR_FAIL;
209 }
210
211 DelayedSingleton<AudioDeviceManager>::GetInstance()->AddAudioDeviceList(device.address, device.deviceType, "");
212 onlineDCallDevices_.emplace(devId, device);
213
214 if (!dCallDeviceSwitchedOn_.load() && isCallActived_.load()) {
215 if (device.deviceType == AudioDeviceType::DEVICE_DISTRIBUTED_AUTOMOTIVE && IsSelectVirtualModem()) {
216 TELEPHONY_LOGI("switch call to auto motive as it is online");
217 SwitchOnDCallDeviceAsync(device);
218 }
219 }
220 return TELEPHONY_SUCCESS;
221 }
222
RemoveDCallDevice(const std::string & devId)223 int32_t DistributedCallManager::RemoveDCallDevice(const std::string& devId)
224 {
225 TELEPHONY_LOGI("remove dcall device, devId: %{public}s.", GetAnonyString(devId).c_str());
226 std::lock_guard<std::mutex> lock(onlineDeviceMtx_);
227 auto iter = onlineDCallDevices_.find(devId);
228 if (iter != onlineDCallDevices_.end()) {
229 std::string devId = GetDevIdFromAudioDevice(iter->second);
230 std::string curDevId = GetConnectedDCallDeviceId();
231 TELEPHONY_LOGI("removed devId: %{public}s, current devId: %{public}s",
232 GetAnonyString(devId).c_str(), GetAnonyString(curDevId).c_str());
233 DelayedSingleton<AudioDeviceManager>::GetInstance()->RemoveAudioDeviceList(
234 iter->second.address, iter->second.deviceType);
235 onlineDCallDevices_.erase(iter);
236 if (curDevId == devId) {
237 TELEPHONY_LOGI("current dcall device is removed, now reinit audio device.");
238 dCallDeviceSwitchedOn_.store(false);
239 ClearConnectedDCallDevice();
240 DelayedSingleton<AudioDeviceManager>::GetInstance()->InitAudioDevice();
241 }
242 }
243 return TELEPHONY_SUCCESS;
244 }
245
ClearDCallDevices()246 void DistributedCallManager::ClearDCallDevices()
247 {
248 TELEPHONY_LOGI("clear dcall device.");
249 std::lock_guard<std::mutex> lock(onlineDeviceMtx_);
250 onlineDCallDevices_.clear();
251 }
252
NotifyOnlineDCallDevices(std::vector<std::string> devices)253 void DistributedCallManager::NotifyOnlineDCallDevices(std::vector<std::string> devices)
254 {
255 TELEPHONY_LOGI("notify online dcall devices start, size: %{public}d", static_cast<int32_t>(devices.size()));
256 for (auto item : devices) {
257 AddDCallDevice(item);
258 TELEPHONY_LOGI("notify dcall device, devId: %{public}s", GetAnonyString(item).c_str());
259 }
260 TELEPHONY_LOGI("notify online dcall devices end.");
261 }
262
GetConnectedDCallDeviceAddr()263 std::string DistributedCallManager::GetConnectedDCallDeviceAddr()
264 {
265 std::lock_guard<std::mutex> lock(connectedDevMtx_);
266 std::string addr = connectedAudioDevice_.address;
267 return addr;
268 }
269
GetConnectedDCallDeviceType()270 AudioDeviceType DistributedCallManager::GetConnectedDCallDeviceType()
271 {
272 std::lock_guard<std::mutex> lock(connectedDevMtx_);
273 AudioDeviceType type = connectedAudioDevice_.deviceType;
274 return type;
275 }
276
GetConnectedDCallDeviceId()277 std::string DistributedCallManager::GetConnectedDCallDeviceId()
278 {
279 std::lock_guard<std::mutex> lock(connectedDevMtx_);
280 std::string devId = "";
281 if (dCallDeviceSwitchedOn_.load()) {
282 devId = GetDevIdFromAudioDevice(connectedAudioDevice_);
283 }
284 return devId;
285 }
286
GetConnectedDCallDevice(AudioDevice & device)287 void DistributedCallManager::GetConnectedDCallDevice(AudioDevice& device)
288 {
289 std::lock_guard<std::mutex> lock(connectedDevMtx_);
290 device.deviceType = connectedAudioDevice_.deviceType;
291 if (memcpy_s(device.address, kMaxAddressLen, connectedAudioDevice_.address, kMaxAddressLen) != EOK) {
292 TELEPHONY_LOGE("memcpy_s failed.");
293 }
294 }
295
SetConnectedDCallDevice(const AudioDevice & device)296 void DistributedCallManager::SetConnectedDCallDevice(const AudioDevice& device)
297 {
298 std::lock_guard<std::mutex> lock(connectedDevMtx_);
299 connectedAudioDevice_.deviceType = device.deviceType;
300 if (memcpy_s(connectedAudioDevice_.address, kMaxAddressLen, device.address, kMaxAddressLen) != EOK) {
301 TELEPHONY_LOGE("memcpy_s failed.");
302 }
303 }
304
ClearConnectedDCallDevice()305 void DistributedCallManager::ClearConnectedDCallDevice()
306 {
307 std::lock_guard<std::mutex> lock(connectedDevMtx_);
308 connectedAudioDevice_.deviceType = AudioDeviceType::DEVICE_UNKNOWN;
309 if (memset_s(connectedAudioDevice_.address, kMaxAddressLen, 0, kMaxAddressLen) != EOK) {
310 TELEPHONY_LOGE("memset_s failed.");
311 }
312 }
313
SwitchOnDCallDeviceSync(const AudioDevice & device)314 bool DistributedCallManager::SwitchOnDCallDeviceSync(const AudioDevice& device)
315 {
316 TELEPHONY_LOGI("switch dcall device on sync");
317 if (!isCallActived_.load()) {
318 TELEPHONY_LOGW("call is not active, no need switch");
319 return true;
320 }
321 if (!IsDistributedAudioDevice(device)) {
322 TELEPHONY_LOGE("not distributed audio device, device type: %{public}d", device.deviceType);
323 return false;
324 }
325 std::string devId = GetDevIdFromAudioDevice(device);
326 if (!devId.length()) {
327 TELEPHONY_LOGE("dcall devId is invalid");
328 return false;
329 }
330 TELEPHONY_LOGI("switch dcall device on start, devId: %{public}s", GetAnonyString(devId).c_str());
331 int32_t ret;
332 {
333 std::lock_guard<std::mutex> lock(dcallProxyMtx_);
334 if (dcallProxy_ == nullptr) {
335 TELEPHONY_LOGE("dcallProxy_ is nullptr");
336 return false;
337 }
338 if (isSwitching_) {
339 TELEPHONY_LOGI("in switching");
340 return false;
341 }
342 isSwitching_ = true;
343 ReportDistributedDeviceInfo(device);
344 ret = dcallProxy_->SwitchDevice(devId, DCALL_SWITCH_DEVICE_TYPE_SINK);
345 isSwitching_ = false;
346 }
347 if (ret == TELEPHONY_SUCCESS) {
348 dCallDeviceSwitchedOn_.store(true);
349 SetConnectedDCallDevice(device);
350 DelayedSingleton<AudioDeviceManager>::GetInstance()->SetCurrentAudioDevice(device.deviceType);
351 TELEPHONY_LOGI("switch dcall device on succeed.");
352 return true;
353 }
354 TELEPHONY_LOGI("switch dcall device on failed, ret: %{public}d.", ret);
355 return false;
356 }
357
SetCallState(bool isActive)358 void DistributedCallManager::SetCallState(bool isActive)
359 {
360 isCallActived_.store(isActive);
361 }
362
DealDisconnectCall()363 void DistributedCallManager::DealDisconnectCall()
364 {
365 dCallDeviceSwitchedOn_.store(false);
366 ClearConnectedDCallDevice();
367 }
368
IsDistributedCarDeviceOnline()369 bool DistributedCallManager::IsDistributedCarDeviceOnline()
370 {
371 if (onlineDCallDevices_.size() > 0) {
372 return true;
373 }
374 return false;
375 }
376
isCeliaCall()377 bool DistributedCallManager::isCeliaCall()
378 {
379 sptr<CallBase> foregroundCall = CallObjectManager::GetForegroundCall(false);
380 if (foregroundCall == nullptr) {
381 TELEPHONY_LOGE("foregroundCall is nullptr!");
382 return false;
383 }
384 int32_t celiaCallType = foregroundCall->GetCeliaCallType();
385 if (celiaCallType == IS_CELIA_CALL) {
386 TELEPHONY_LOGI("current is celia call, no need switch on dcall device.");
387 return true;
388 }
389 return false;
390 }
391
SwitchOnDCallDeviceAsync(const AudioDevice & device)392 void DistributedCallManager::SwitchOnDCallDeviceAsync(const AudioDevice& device)
393 {
394 if (isCeliaCall()) {
395 return;
396 }
397 auto weak = weak_from_this();
398 TELEPHONY_LOGI("switch dcall device on async");
399 std::thread switchThread = std::thread([weak, device]() {
400 auto strong = weak.lock();
401 if (strong) {
402 strong->SwitchOnDCallDeviceSync(device);
403 if (strong->isCeliaCall()) {
404 strong->SwitchOffDCallDeviceSync();
405 strong->ReportDistributedDeviceInfoForSwitchOff();
406 }
407 }
408 });
409 pthread_setname_np(switchThread.native_handle(), SWITCH_ON_DCALL_THREAD_NAME.c_str());
410 switchThread.detach();
411 }
412
SwitchOffDCallDeviceSync()413 void DistributedCallManager::SwitchOffDCallDeviceSync()
414 {
415 TELEPHONY_LOGI("switch dcall device off sync");
416 if (!dCallDeviceSwitchedOn_.load()) {
417 TELEPHONY_LOGE("distributed audio device not connected.");
418 return;
419 }
420 std::string devId = GetConnectedDCallDeviceId();
421 if (!devId.length()) {
422 TELEPHONY_LOGE("dcall devId is invalid");
423 return;
424 }
425 TELEPHONY_LOGI("switch dcall device off start, devId: %{public}s", GetAnonyString(devId).c_str());
426 int32_t ret;
427 {
428 std::lock_guard<std::mutex> lock(dcallProxyMtx_);
429 if (dcallProxy_ == nullptr) {
430 TELEPHONY_LOGE("dcallProxy_ is nullptr");
431 return;
432 }
433 ret = dcallProxy_->SwitchDevice(devId, DCALL_SWITCH_DEVICE_TYPE_SOURCE);
434 }
435 if (ret == TELEPHONY_SUCCESS) {
436 dCallDeviceSwitchedOn_.store(false);
437 ClearConnectedDCallDevice();
438 TELEPHONY_LOGI("switch dcall device off succeed.");
439 } else {
440 TELEPHONY_LOGE("switch dcall device off failed, %{public}d", ret);
441 }
442 }
443
IsSelectVirtualModem()444 bool DistributedCallManager::IsSelectVirtualModem()
445 {
446 if (onlineDCallDevices_.size() <= 0) {
447 TELEPHONY_LOGW("no dcall device");
448 return false;
449 }
450 std::lock_guard<std::mutex> lock(dcallProxyMtx_);
451 if (dcallProxy_ == nullptr) {
452 TELEPHONY_LOGE("fail to create dcall proxy obj");
453 return false;
454 }
455 return dcallProxy_->IsSelectVirtualModem();
456 }
457
ReportDistributedDeviceInfo(const AudioDevice & device)458 void DistributedCallManager::ReportDistributedDeviceInfo(const AudioDevice& device)
459 {
460 std::string curDevId = GetDevIdFromAudioDevice(device);
461 TELEPHONY_LOGD("curDevId = %{public}s", GetAnonyString(curDevId).c_str());
462 AudioSystemManager *audioSystemMananger = AudioSystemManager::GetInstance();
463 if (audioSystemMananger == nullptr) {
464 TELEPHONY_LOGW("audioSystemMananger nullptr");
465 return;
466 }
467 std::vector<std::shared_ptr<AudioDeviceDescriptor>> descs = audioSystemMananger
468 ->GetDevices(DeviceFlag::DISTRIBUTED_OUTPUT_DEVICES_FLAG);
469 size_t size = descs.size();
470 if (descs.size() <= 0) {
471 TELEPHONY_LOGW("no distributed device");
472 return;
473 }
474 std::vector<std::shared_ptr<AudioDeviceDescriptor>> remoteDevice = descs;
475 for (auto device = descs.begin(); device != descs.end(); device++) {
476 std::string devId = (*device)->networkId_;
477 if (!devId.empty() && curDevId == devId) {
478 TELEPHONY_LOGI("curDecId is the same as devId, devId = %{public}s",
479 GetAnonyString(devId).c_str());
480 remoteDevice.clear();
481 remoteDevice.push_back(*device);
482 break;
483 }
484 }
485 sptr<AudioRendererFilter> audioRendererFilter = new(std::nothrow) AudioRendererFilter();
486 if (audioRendererFilter == nullptr) {
487 TELEPHONY_LOGE("audioRendererFilter nullptr");
488 return;
489 }
490 audioRendererFilter->rendererInfo.contentType = ContentType::CONTENT_TYPE_SPEECH;
491 audioRendererFilter->rendererInfo.streamUsage = StreamUsage::STREAM_USAGE_VOICE_MODEM_COMMUNICATION;
492 audioSystemMananger->SelectOutputDevice(audioRendererFilter, remoteDevice);
493 TELEPHONY_LOGW("ReportDistributedDeviceInfo");
494 }
495
ReportDistributedDeviceInfoForSwitchOff()496 void DistributedCallManager::ReportDistributedDeviceInfoForSwitchOff()
497 {
498 TELEPHONY_LOGI("ReportDistributedDeviceInfoForSwitchOff start.");
499 AudioSystemManager *audioSystemMananger = AudioSystemManager::GetInstance();
500 if (audioSystemMananger == nullptr) {
501 TELEPHONY_LOGW("audioSystemMananger nullptr");
502 return;
503 }
504 std::vector<std::shared_ptr<AudioDeviceDescriptor>> descs = audioSystemMananger
505 ->GetDevices(DeviceFlag::OUTPUT_DEVICES_FLAG);
506 size_t size = descs.size();
507 if (descs.size() <= 0) {
508 TELEPHONY_LOGW("no distributed device");
509 return;
510 }
511 std::vector<std::shared_ptr<AudioDeviceDescriptor>> remoteDevice = descs;
512 for (auto device = descs.begin(); device != descs.end(); device++) {
513 if ((*device)->deviceType_ == DeviceType::DEVICE_TYPE_EARPIECE) {
514 TELEPHONY_LOGI("curDecType is speaker.");
515 remoteDevice.clear();
516 remoteDevice.push_back(*device);
517 break;
518 }
519 }
520 sptr<AudioRendererFilter> audioRendererFilter = new(std::nothrow) AudioRendererFilter();
521 if (audioRendererFilter == nullptr) {
522 TELEPHONY_LOGE("audioRendererFilter nullptr");
523 return;
524 }
525 audioRendererFilter->rendererInfo.contentType = ContentType::CONTENT_TYPE_SPEECH;
526 audioRendererFilter->rendererInfo.streamUsage = StreamUsage::STREAM_USAGE_VOICE_MODEM_COMMUNICATION;
527 audioSystemMananger->SelectOutputDevice(audioRendererFilter, remoteDevice);
528 TELEPHONY_LOGI("ReportDistributedDeviceInfoForSwitchOff end.");
529 }
530
IsDCallDeviceSwitchedOn()531 bool DistributedCallManager::IsDCallDeviceSwitchedOn()
532 {
533 return dCallDeviceSwitchedOn_.load();
534 }
535
OnDCallDeviceOnline(const std::string & devId)536 int32_t DistributedCallManager::OnDCallDeviceOnline(const std::string &devId)
537 {
538 TELEPHONY_LOGI("dcall device is online, devId: %{public}s", GetAnonyString(devId).c_str());
539 return AddDCallDevice(devId);
540 }
541
OnDCallDeviceOffline(const std::string & devId)542 int32_t DistributedCallManager::OnDCallDeviceOffline(const std::string &devId)
543 {
544 TELEPHONY_LOGI("dcall device is offline, devId: %{public}s", GetAnonyString(devId).c_str());
545 auto ret = RemoveDCallDevice(devId);
546 #ifdef ABILITY_BLUETOOTH_SUPPORT
547 bool isAllDeviceOffline = true;
548 {
549 std::lock_guard<std::mutex> lock(onlineDeviceMtx_);
550 isAllDeviceOffline = onlineDCallDevices_.empty();
551 }
552 if (isAllDeviceOffline) {
553 TELEPHONY_LOGI("all dcall device offline");
554 std::lock_guard<std::mutex> lock(mutex_);
555 if (dcallHfpListener_ != nullptr) {
556 Bluetooth::HandsFreeAudioGateway::GetProfile()->DeregisterObserver(dcallHfpListener_);
557 dcallHfpListener_ = nullptr;
558 }
559 }
560 #endif
561 return ret;
562 }
563
OnDCallDeviceOnline(const std::string & devId)564 int32_t DistributedCallManager::DistributedCallDeviceListener::OnDCallDeviceOnline(const std::string &devId)
565 {
566 TELEPHONY_LOGI("dcall device is online, devId: %{public}s", GetAnonyString(devId).c_str());
567 return DelayedSingleton<DistributedCallManager>::GetInstance()->OnDCallDeviceOnline(devId);
568 }
569
OnDCallDeviceOffline(const std::string & devId)570 int32_t DistributedCallManager::DistributedCallDeviceListener::OnDCallDeviceOffline(const std::string &devId)
571 {
572 TELEPHONY_LOGI("dcall device is offline, devId: %{public}s", GetAnonyString(devId).c_str());
573 return DelayedSingleton<DistributedCallManager>::GetInstance()->OnDCallDeviceOffline(devId);
574 }
575
OnDCallSystemAbilityAdded(const std::string & deviceId)576 void DistributedCallManager::OnDCallSystemAbilityAdded(const std::string &deviceId)
577 {
578 TELEPHONY_LOGI("dcall source service is added, deviceId: %{public}s", GetAnonyString(deviceId).c_str());
579 std::vector<std::string> dcallDevices;
580 {
581 std::lock_guard<std::mutex> lock(dcallProxyMtx_);
582 dcallProxy_ = std::make_shared<DistributedCallProxy>();
583 if (dcallProxy_ == nullptr) {
584 TELEPHONY_LOGE("fail to create dcall proxy obj");
585 return;
586 }
587 if (dcallProxy_->Init() != TELEPHONY_SUCCESS) {
588 TELEPHONY_LOGE("init dcall proxy failed");
589 return;
590 }
591 dcallDeviceListener_ = std::make_shared<DistributedCallDeviceListener>();
592 if (dcallDeviceListener_ == nullptr) {
593 TELEPHONY_LOGE("dcallDeviceListener_ is nullptr");
594 return;
595 }
596 if (dcallProxy_->RegisterDeviceCallback(CALLBACK_NAME, dcallDeviceListener_) != TELEPHONY_SUCCESS) {
597 TELEPHONY_LOGE("register dcall callback failed");
598 return;
599 }
600 if (dcallProxy_->GetOnlineDeviceList(dcallDevices) != TELEPHONY_SUCCESS) {
601 TELEPHONY_LOGE("get dcall device list failed");
602 return;
603 }
604 }
605 if (dcallDevices.size() > 0) {
606 NotifyOnlineDCallDevices(dcallDevices);
607 }
608 TELEPHONY_LOGI("OnDCallSystemAbilityAdded end.");
609 }
610
OnDCallSystemAbilityRemoved(const std::string & deviceId)611 void DistributedCallManager::OnDCallSystemAbilityRemoved(const std::string &deviceId)
612 {
613 TELEPHONY_LOGI("dcall source service is removed, deviceId: %{public}s", GetAnonyString(deviceId).c_str());
614 {
615 std::lock_guard<std::mutex> lock(dcallProxyMtx_);
616 dcallDeviceListener_ = nullptr;
617 dcallProxy_ = nullptr;
618 }
619 ClearDCallDevices();
620 ClearConnectedDCallDevice();
621 DelayedSingleton<AudioDeviceManager>::GetInstance()->ResetDistributedCallDevicesList();
622 if (dCallDeviceSwitchedOn_.load()) {
623 DelayedSingleton<AudioDeviceManager>::GetInstance()->InitAudioDevice();
624 }
625 dCallDeviceSwitchedOn_.store(false);
626 TELEPHONY_LOGI("OnDCallSystemAbilityRemoved end.");
627 }
628
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)629 void DCallSystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
630 {
631 TELEPHONY_LOGI("SA: %{public}d is added!", systemAbilityId);
632 if (!CheckInputSysAbilityId(systemAbilityId)) {
633 TELEPHONY_LOGE("added SA is invalid!");
634 return;
635 }
636 if (systemAbilityId != DISTRIBUTED_CALL_SOURCE_SA_ID) {
637 TELEPHONY_LOGE("added SA is not dcall source service, ignored.");
638 return;
639 }
640 TELEPHONY_LOGI("notify dcall source service added event to distributed call manager");
641 DelayedSingleton<DistributedCallManager>::GetInstance()->OnDCallSystemAbilityAdded(deviceId);
642 }
643
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)644 void DCallSystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
645 {
646 TELEPHONY_LOGI("SA: %{public}d is removed!", systemAbilityId);
647 if (!CheckInputSysAbilityId(systemAbilityId)) {
648 TELEPHONY_LOGE("removed SA is invalid!");
649 return;
650 }
651 if (systemAbilityId != DISTRIBUTED_CALL_SOURCE_SA_ID) {
652 TELEPHONY_LOGE("removed SA is not dcall source service, ignored.");
653 return;
654 }
655 TELEPHONY_LOGI("notify dcall source service removed event to distributed call manager");
656 DelayedSingleton<DistributedCallManager>::GetInstance()->OnDCallSystemAbilityRemoved(deviceId);
657 }
658
659 #ifdef ABILITY_BLUETOOTH_SUPPORT
OnHfpStackChanged(const Bluetooth::BluetoothRemoteDevice & device,int32_t action)660 void DCallHfpListener::OnHfpStackChanged(const Bluetooth::BluetoothRemoteDevice &device, int32_t action)
661 {
662 TELEPHONY_LOGI("dcall hfp stack changed, action[%{public}d]", action);
663 int32_t cod = DEFAULT_DCALL_HFP_FLAG_VALUE;
664 int32_t majorClass = DEFAULT_DCALL_HFP_FLAG_VALUE;
665 int32_t majorMinorClass = DEFAULT_DCALL_HFP_FLAG_VALUE;
666 device.GetDeviceProductType(cod, majorClass, majorMinorClass);
667 bool isBtHeadset = (majorClass == Bluetooth::BluetoothDevice::MAJOR_AUDIO_VIDEO &&
668 (majorMinorClass == Bluetooth::BluetoothDevice::AUDIO_VIDEO_HEADPHONES ||
669 majorMinorClass == Bluetooth::BluetoothDevice::AUDIO_VIDEO_WEARABLE_HEADSET));
670 if (!isBtHeadset) {
671 return;
672 }
673 if (action == DCALL_BT_HEADSET_UNWEAR_ACTION) {
674 DelayedSingleton<AudioDeviceManager>::GetInstance()->CheckAndSwitchDistributedAudioDevice();
675 }
676 }
677 #endif
678
679 } // namespace Telephony
680 } // namespace OHOS