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