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