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