• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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