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