1 /*
2 * Copyright (C) 2024-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 "distributed_device_observer.h"
17 #include "iservice_registry.h"
18 #include "telephony_errors.h"
19 #include "telephony_log_wrapper.h"
20 #include "distributed_communication_manager.h"
21
22 namespace OHOS {
23 namespace Telephony {
24 const int32_t DISTRIBUTED_COMMUNICATION_CALL_SA_ID = 66198;
25 const int32_t DISTRIBUTED_COMMUNICATION_PHONE = 0;
26 const int32_t DISTRIBUTED_COMMUNICATION_PAD = 1;
27 const int32_t DISTRIBUTED_COMMUNICATION_PC = 2;
28
Init()29 void DistributedDeviceObserver::Init()
30 {
31 saListener_ = sptr<DistributedSystemAbilityListener>::MakeSptr();
32 if (saListener_ == nullptr) {
33 TELEPHONY_LOGE("create distributed sa listener failed");
34 return;
35 }
36 auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
37 if (saManager == nullptr) {
38 TELEPHONY_LOGE("get system ability manager failed");
39 return;
40 }
41 int32_t ret = saManager->SubscribeSystemAbility(DISTRIBUTED_COMMUNICATION_CALL_SA_ID, saListener_);
42 if (ret != TELEPHONY_SUCCESS) {
43 TELEPHONY_LOGE("subscribe distributed sa fail %{public}d", ret);
44 return;
45 }
46 }
47
RegisterDevStatusCallback(const std::shared_ptr<IDistributedDeviceStateCallback> & callback)48 void DistributedDeviceObserver::RegisterDevStatusCallback(
49 const std::shared_ptr<IDistributedDeviceStateCallback> &callback)
50 {
51 std::lock_guard<ffrt::mutex> lock(mutex_);
52 if (callback == nullptr) {
53 TELEPHONY_LOGE("reg dev status callback null");
54 return;
55 }
56 auto iter = std::find(callbacks_.begin(), callbacks_.end(), callback);
57 if (iter != callbacks_.end()) {
58 TELEPHONY_LOGI("callback already reg");
59 return;
60 }
61 callbacks_.push_back(callback);
62 TELEPHONY_LOGI("reg dev status callback");
63 }
64
UnRegisterDevStatusCallback(const std::shared_ptr<IDistributedDeviceStateCallback> & callback)65 void DistributedDeviceObserver::UnRegisterDevStatusCallback(
66 const std::shared_ptr<IDistributedDeviceStateCallback> &callback)
67 {
68 std::lock_guard<ffrt::mutex> lock(mutex_);
69 auto iter = std::find(callbacks_.begin(), callbacks_.end(), callback);
70 if (iter != callbacks_.end()) {
71 callbacks_.erase(iter);
72 }
73 TELEPHONY_LOGI("un-reg dev status callback");
74 }
75
RegisterDevCallback()76 void DistributedDeviceObserver::RegisterDevCallback()
77 {
78 if (deviceListener_ == nullptr) {
79 deviceListener_ = std::make_shared<DistributedDeviceCallback>();
80 }
81 if (deviceListener_ == nullptr) {
82 return;
83 }
84 auto distributedMgr = DelayedSingleton<DistributedCommunicationManager>::GetInstance();
85 if (distributedMgr != nullptr) {
86 auto ret = distributedMgr->RegDevCallbackWrapper(deviceListener_);
87 TELEPHONY_LOGI("reg distributed device callback result[%{public}d]", ret);
88 }
89 }
90
UnRegisterDevCallback()91 int32_t DistributedDeviceObserver::UnRegisterDevCallback()
92 {
93 int32_t res = TELEPHONY_SUCCESS;
94 if (deviceListener_ != nullptr) {
95 auto distributedMgr = DelayedSingleton<DistributedCommunicationManager>::GetInstance();
96 if (distributedMgr != nullptr) {
97 res = distributedMgr->UnRegDevCallbackWrapper();
98 TELEPHONY_LOGI("un-reg distributed device callback result[%{public}d]", res);
99 }
100 deviceListener_.reset();
101 deviceListener_ = nullptr;
102 }
103 return res;
104 }
105
OnDeviceOnline(const std::string & devId,const std::string & devName,AudioDeviceType devType)106 void DistributedDeviceObserver::OnDeviceOnline(const std::string &devId, const std::string &devName,
107 AudioDeviceType devType)
108 {
109 std::list<std::shared_ptr<IDistributedDeviceStateCallback>> callbacks;
110 {
111 std::lock_guard<ffrt::mutex> lock(mutex_);
112 callbacks = callbacks_;
113 }
114 for (auto& callback : callbacks) {
115 if (callback != nullptr) {
116 callback->OnDeviceOnline(devId, devName, devType);
117 }
118 }
119 }
120
OnDeviceOffline(const std::string & devId,const std::string & devName,AudioDeviceType devType)121 void DistributedDeviceObserver::OnDeviceOffline(const std::string &devId, const std::string &devName,
122 AudioDeviceType devType)
123 {
124 std::list<std::shared_ptr<IDistributedDeviceStateCallback>> callbacks;
125 {
126 std::lock_guard<ffrt::mutex> lock(mutex_);
127 callbacks = callbacks_;
128 }
129 for (auto& callback : callbacks) {
130 if (callback != nullptr) {
131 callback->OnDeviceOffline(devId, devName, devType);
132 }
133 }
134 }
135
OnDistributedAudioDeviceChange(const std::string & devId,const std::string & devName,AudioDeviceType devType,int32_t devRole)136 void DistributedDeviceObserver::OnDistributedAudioDeviceChange(const std::string &devId, const std::string &devName,
137 AudioDeviceType devType, int32_t devRole)
138 {
139 std::list<std::shared_ptr<IDistributedDeviceStateCallback>> callbacks;
140 {
141 std::lock_guard<ffrt::mutex> lock(mutex_);
142 callbacks = callbacks_;
143 }
144 for (auto& callback : callbacks) {
145 if (callback != nullptr) {
146 callback->OnDistributedAudioDeviceChange(devId, devName, devType, devRole);
147 }
148 }
149 }
150
OnRemoveSystemAbility()151 void DistributedDeviceObserver::OnRemoveSystemAbility()
152 {
153 std::list<std::shared_ptr<IDistributedDeviceStateCallback>> callbacks;
154 {
155 std::lock_guard<ffrt::mutex> lock(mutex_);
156 callbacks = callbacks_;
157 callbacks_.clear();
158 }
159 for (auto& callback : callbacks) {
160 if (callback != nullptr) {
161 callback->OnRemoveSystemAbility();
162 }
163 }
164 }
165
OnDistributedDeviceOnline(const std::string & devId,const std::string & devName,int32_t devType,int32_t devRole)166 int32_t DistributedDeviceCallback::OnDistributedDeviceOnline(const std::string &devId, const std::string &devName,
167 int32_t devType, int32_t devRole)
168 {
169 TELEPHONY_LOGI("dev online, type %{public}d, role %{public}d", devType, devRole);
170 AudioDeviceType deviceType = ConvertDeviceType(devType);
171 if (deviceType == AudioDeviceType::DEVICE_UNKNOWN) {
172 return TELEPHONY_ERROR;
173 }
174 auto distributedMgr = DelayedSingleton<DistributedCommunicationManager>::GetInstance();
175 if (distributedMgr == nullptr) {
176 return TELEPHONY_ERROR;
177 }
178 distributedMgr->OnDeviceOnline(devId, devName, deviceType, devRole);
179 return TELEPHONY_SUCCESS;
180 }
181
OnDistributedAudioDeviceChange(const std::string & devId,const std::string & devName,int32_t devType,int32_t devRole)182 int32_t DistributedDeviceCallback::OnDistributedAudioDeviceChange(const std::string &devId, const std::string &devName,
183 int32_t devType, int32_t devRole)
184 {
185 TELEPHONY_LOGI("distributed device change, current device[%{public}d]", devRole);
186 auto distributedMgr = DelayedSingleton<DistributedCommunicationManager>::GetInstance();
187 if (distributedMgr == nullptr) {
188 return TELEPHONY_ERROR;
189 }
190 AudioDeviceType deviceType = ConvertDeviceType(devType);
191 if (deviceType == AudioDeviceType::DEVICE_UNKNOWN) {
192 return TELEPHONY_ERROR;
193 }
194 auto deviceObserver = distributedMgr->GetDistributedDeviceObserver();
195 if (deviceObserver != nullptr) {
196 deviceObserver->OnDistributedAudioDeviceChange(devId, devName, deviceType, devRole);
197 }
198 return TELEPHONY_SUCCESS;
199 }
200
OnDistributedDeviceOffline(const std::string & devId,const std::string & devName,int32_t devType,int32_t devRole)201 int32_t DistributedDeviceCallback::OnDistributedDeviceOffline(const std::string &devId, const std::string &devName,
202 int32_t devType, int32_t devRole)
203 {
204 TELEPHONY_LOGI("dev offline, type %{public}d, role %{public}d", devType, devRole);
205 AudioDeviceType deviceType = ConvertDeviceType(devType);
206 if (deviceType == AudioDeviceType::DEVICE_UNKNOWN) {
207 return TELEPHONY_ERROR;
208 }
209 auto distributedMgr = DelayedSingleton<DistributedCommunicationManager>::GetInstance();
210 if (distributedMgr == nullptr) {
211 return TELEPHONY_ERROR;
212 }
213 distributedMgr->OnDeviceOffline(devId, devName, deviceType, devRole);
214 return TELEPHONY_SUCCESS;
215 }
216
ConvertDeviceType(int32_t devType)217 AudioDeviceType DistributedDeviceCallback::ConvertDeviceType(int32_t devType)
218 {
219 switch (devType) {
220 case DISTRIBUTED_COMMUNICATION_PAD:
221 return AudioDeviceType::DEVICE_DISTRIBUTED_PAD;
222 case DISTRIBUTED_COMMUNICATION_PC:
223 return AudioDeviceType::DEVICE_DISTRIBUTED_PC;
224 case DISTRIBUTED_COMMUNICATION_PHONE:
225 return AudioDeviceType::DEVICE_DISTRIBUTED_PHONE;
226 default:
227 return AudioDeviceType::DEVICE_UNKNOWN;
228 }
229 }
230
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)231 void DistributedSystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
232 {
233 if (systemAbilityId != DISTRIBUTED_COMMUNICATION_CALL_SA_ID) {
234 TELEPHONY_LOGE("not distributed sa id");
235 return;
236 }
237 TELEPHONY_LOGI("distribute communication sa online");
238 auto distributedMgr = DelayedSingleton<DistributedCommunicationManager>::GetInstance();
239 if (distributedMgr == nullptr) {
240 return;
241 }
242 distributedMgr->InitExtWrapper();
243 auto deviceObserver = distributedMgr->GetDistributedDeviceObserver();
244 if (deviceObserver != nullptr) {
245 deviceObserver->RegisterDevCallback();
246 }
247 }
248
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)249 void DistributedSystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
250 {
251 if (systemAbilityId != DISTRIBUTED_COMMUNICATION_CALL_SA_ID) {
252 TELEPHONY_LOGE("not distributed sa id");
253 return;
254 }
255 TELEPHONY_LOGI("distribute communication sa offline");
256 auto distributedMgr = DelayedSingleton<DistributedCommunicationManager>::GetInstance();
257 if (distributedMgr == nullptr) {
258 return;
259 }
260 auto deviceObserver = distributedMgr->GetDistributedDeviceObserver();
261 if (deviceObserver != nullptr) {
262 deviceObserver->OnRemoveSystemAbility();
263 if (deviceObserver->UnRegisterDevCallback() != TELEPHONY_SUCCESS) {
264 TELEPHONY_LOGE("un-reg distributed device callback failed, can't dlclose ext lib");
265 distributedMgr->OnRemoveSystemAbility();
266 return;
267 }
268 }
269 distributedMgr->OnRemoveSystemAbility();
270 distributedMgr->DeInitExtWrapper();
271 }
272
273 } // namespace Telephony
274 } // namespace OHOS
275