1/* 2 * Copyright (C) 2021-2022 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#include "bluetooth_a2dp_snk.h" 16#include <cstdint> 17#include "bluetooth_a2dp_sink_observer_stub.h" 18#include "bluetooth_def.h" 19#include "bluetooth_host.h" 20#include "bluetooth_profile_manager.h" 21#include "bluetooth_log.h" 22#include "bluetooth_observer_list.h" 23#include "bluetooth_remote_device.h" 24#include "bluetooth_types.h" 25#include "bluetooth_utils.h" 26#include "functional" 27#include "i_bluetooth_a2dp_sink.h" 28#include "i_bluetooth_a2dp_sink_observer.h" 29#include "i_bluetooth_host.h" 30#include "if_system_ability_manager.h" 31#include "iosfwd" 32#include "iremote_broker.h" 33#include "iremote_object.h" 34#include "iservice_registry.h" 35#include "list" 36#include "memory" 37#include "new" 38#include "raw_address.h" 39#include "refbase.h" 40#include "string" 41#include "system_ability_definition.h" 42#include "vector" 43 44namespace OHOS { 45namespace Bluetooth { 46using namespace OHOS::bluetooth; 47std::mutex g_a2dpSnkProxyMutex; 48struct A2dpSink::impl { 49 impl(); 50 ~impl(); 51 BluetoothObserverList<A2dpSinkObserver> observers_; 52 class BluetoothA2dpSinkObserverImp; 53 sptr<BluetoothA2dpSinkObserverImp> observerImp_ = nullptr; 54 int32_t profileRegisterId = 0; 55}; 56 57class A2dpSink::impl::BluetoothA2dpSinkObserverImp : public BluetoothA2dpSinkObserverStub { 58public: 59 explicit BluetoothA2dpSinkObserverImp(A2dpSink::impl &a2dpSink) : a2dpSink_(a2dpSink) 60 {}; 61 ~BluetoothA2dpSinkObserverImp() override 62 {}; 63 64 void Register(std::shared_ptr<A2dpSinkObserver> &observer) 65 { 66 HILOGI("enter"); 67 a2dpSink_.observers_.Register(observer); 68 } 69 70 void Deregister(std::shared_ptr<A2dpSinkObserver> &observer) 71 { 72 HILOGI("enter"); 73 a2dpSink_.observers_.Deregister(observer); 74 } 75 76 void OnConnectionStateChanged(const RawAddress &device, int state, int cause) override 77 { 78 HILOGD("device: %{public}s, state: %{public}d, cause: %{public}d", 79 GET_ENCRYPT_RAW_ADDR(device), state, cause); 80 a2dpSink_.observers_.ForEach([device, state, cause](std::shared_ptr<A2dpSinkObserver> observer) { 81 observer->OnConnectionStateChanged(BluetoothRemoteDevice(device.GetAddress(), 0), state, cause); 82 }); 83 } 84 85private: 86 A2dpSink::impl &a2dpSink_; 87 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothA2dpSinkObserverImp); 88}; 89 90A2dpSink::impl::impl() 91{ 92 observerImp_ = new (std::nothrow) BluetoothA2dpSinkObserverImp(*this); 93 CHECK_AND_RETURN_LOG(observerImp_ != nullptr, "observerImp_ is nullptr"); 94 profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_A2DP_SINK, 95 [this](sptr<IRemoteObject> remote) { 96 sptr<IBluetoothA2dpSink> proxy = iface_cast<IBluetoothA2dpSink>(remote); 97 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy"); 98 proxy->RegisterObserver(observerImp_); 99 }); 100}; 101 102A2dpSink::impl::~impl() 103{ 104 HILOGD("start"); 105 BluetoothProfileManager::GetInstance().DeregisterFunc(profileRegisterId); 106 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK); 107 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy"); 108 proxy->DeregisterObserver(observerImp_); 109} 110 111A2dpSink::A2dpSink() 112{ 113 pimpl = std::make_unique<impl>(); 114 if (!pimpl) { 115 HILOGE("fails: no pimpl"); 116 } 117} 118 119A2dpSink::~A2dpSink() 120{ 121 HILOGD("start"); 122} 123 124void A2dpSink::RegisterObserver(std::shared_ptr<A2dpSinkObserver> observer) 125{ 126 HILOGD("enter"); 127 CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null."); 128 pimpl->observers_.Register(observer); 129} 130 131void A2dpSink::DeregisterObserver(std::shared_ptr<A2dpSinkObserver> observer) 132{ 133 HILOGD("enter"); 134 CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null."); 135 pimpl->observers_.Deregister(observer); 136} 137 138int A2dpSink::GetDeviceState(const BluetoothRemoteDevice &device) const 139{ 140 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device)); 141 if (!IS_BT_ENABLED()) { 142 HILOGE("bluetooth is off."); 143 return RET_BAD_STATUS; 144 } 145 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK); 146 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr"); 147 if (!device.IsValidBluetoothRemoteDevice()) { 148 HILOGE("input parameter error."); 149 return RET_BAD_PARAM; 150 } 151 152 return proxy->GetDeviceState(RawAddress(device.GetDeviceAddr())); 153} 154 155std::vector<BluetoothRemoteDevice> A2dpSink::GetDevicesByStates(std::vector<int> states) const 156{ 157 HILOGI("enter"); 158 159 if (!IS_BT_ENABLED()) { 160 HILOGE("bluetooth is off."); 161 return std::vector<BluetoothRemoteDevice>(); 162 } 163 164 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK); 165 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, std::vector<BluetoothRemoteDevice>(), 166 "A2dpSink proxy is nullptr"); 167 168 std::vector<int32_t> convertStates; 169 for (auto state : states) { 170 convertStates.push_back(static_cast<int32_t>(state)); 171 } 172 std::vector<BluetoothRemoteDevice> devices; 173 std::vector<RawAddress> rawAddrs = proxy->GetDevicesByStates(convertStates); 174 for (auto rawAddr : rawAddrs) { 175 BluetoothRemoteDevice device(rawAddr.GetAddress(), BTTransport::ADAPTER_BREDR); 176 devices.push_back(device); 177 } 178 return devices; 179} 180 181int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device) const 182{ 183 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device)); 184 if (!IS_BT_ENABLED()) { 185 HILOGE("bluetooth is off."); 186 return RET_BAD_STATUS; 187 } 188 189 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK); 190 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr"); 191 192 if (!device.IsValidBluetoothRemoteDevice()) { 193 HILOGE("input parameter error."); 194 return RET_BAD_PARAM; 195 } 196 197 int ret = RET_BAD_STATUS; 198 proxy->GetPlayingState(RawAddress(device.GetDeviceAddr()), ret); 199 return ret; 200} 201 202int A2dpSink::GetPlayingState(const BluetoothRemoteDevice &device, int &state) const 203{ 204 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device)); 205 if (!IS_BT_ENABLED()) { 206 HILOGE("bluetooth is off."); 207 return RET_BAD_STATUS; 208 } 209 210 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK); 211 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr"); 212 213 if (!device.IsValidBluetoothRemoteDevice()) { 214 HILOGE("input parameter error."); 215 return RET_BAD_PARAM; 216 } 217 218 return proxy->GetPlayingState(RawAddress(device.GetDeviceAddr()), state); 219} 220 221bool A2dpSink::Connect(const BluetoothRemoteDevice &device) 222{ 223 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device)); 224 if (!IS_BT_ENABLED()) { 225 HILOGE("bluetooth is off."); 226 return false; 227 } 228 229 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK); 230 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr"); 231 232 if (!device.IsValidBluetoothRemoteDevice()) { 233 HILOGE("input parameter error."); 234 return false; 235 } 236 237 int ret = proxy->Connect(RawAddress(device.GetDeviceAddr())); 238 return (ret == RET_NO_ERROR); 239} 240 241bool A2dpSink::Disconnect(const BluetoothRemoteDevice &device) 242{ 243 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device)); 244 if (!IS_BT_ENABLED()) { 245 HILOGE("bluetooth is off."); 246 return false; 247 } 248 249 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK); 250 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr"); 251 252 if (!device.IsValidBluetoothRemoteDevice()) { 253 HILOGE("input parameter error."); 254 return false; 255 } 256 257 int ret = proxy->Disconnect(RawAddress(device.GetDeviceAddr())); 258 return (ret == RET_NO_ERROR); 259} 260 261A2dpSink *A2dpSink::GetProfile() 262{ 263 HILOGI("enter"); 264#ifdef DTFUZZ_TEST 265 static BluetoothNoDestructor<A2dpSink> service; 266 return service.get(); 267#else 268 static A2dpSink service; 269 return &service; 270#endif 271} 272 273bool A2dpSink::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy) 274{ 275 HILOGI("enter, device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy); 276 if (!IS_BT_ENABLED()) { 277 HILOGE("bluetooth is off."); 278 return false; 279 } 280 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK); 281 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr"); 282 283 if ((!device.IsValidBluetoothRemoteDevice()) || 284 ((strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) && 285 (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) { 286 HILOGE("input parameter error."); 287 return false; 288 } 289 290 int ret = proxy->SetConnectStrategy(RawAddress(device.GetDeviceAddr()), strategy); 291 return (ret == RET_NO_ERROR); 292} 293 294int A2dpSink::GetConnectStrategy(const BluetoothRemoteDevice &device) const 295{ 296 HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device)); 297 if (!IS_BT_ENABLED()) { 298 HILOGE("bluetooth is off."); 299 return RET_BAD_STATUS; 300 } 301 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK); 302 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, RET_BAD_STATUS, "A2dpSink proxy is nullptr"); 303 304 if (!device.IsValidBluetoothRemoteDevice()) { 305 HILOGE("input parameter error."); 306 return RET_BAD_PARAM; 307 } 308 309 int ret = proxy->GetConnectStrategy(RawAddress(device.GetDeviceAddr())); 310 return ret; 311} 312 313bool A2dpSink::SendDelay(const BluetoothRemoteDevice &device, uint16_t delayValue) 314{ 315 HILOGI("enter, device: %{public}s, delayValue: %{public}d", GET_ENCRYPT_ADDR(device), delayValue); 316 if (!IS_BT_ENABLED()) { 317 HILOGE("bluetooth is off."); 318 return false; 319 } 320 sptr<IBluetoothA2dpSink> proxy = GetRemoteProxy<IBluetoothA2dpSink>(PROFILE_A2DP_SINK); 321 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "A2dpSink proxy is nullptr"); 322 323 if (!device.IsValidBluetoothRemoteDevice()) { 324 HILOGE("input parameter error."); 325 return false; 326 } 327 328 int ret = proxy->SendDelay(RawAddress(device.GetDeviceAddr()), (int32_t)delayValue); 329 return (ret == RET_NO_ERROR); 330} 331} // namespace Bluetooth 332} // namespace OHOS