1 // 2 // Copyright (C) 2017 Google, Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #pragma once 18 19 #include <atomic> 20 #include <mutex> 21 #include <string> 22 #include <vector> 23 24 #include <base/macros.h> 25 26 #include "service/bluetooth_instance.h" 27 #include "service/common/bluetooth/a2dp_codec_config.h" 28 #include "service/hal/bluetooth_av_interface.h" 29 30 namespace bluetooth { 31 32 class A2dpSource : public BluetoothInstance, 33 private hal::BluetoothAvInterface::A2dpSourceObserver { 34 public: 35 // We only allow one instance of this object at a time. 36 static const int kSingletonInstanceId; 37 38 class Delegate { 39 public: 40 virtual void OnConnectionState(const std::string& device_address, 41 int state) = 0; 42 virtual void OnAudioState(const std::string& device_address, int state) = 0; 43 virtual void OnAudioConfig( 44 const std::string& device_address, A2dpCodecConfig codec_config, 45 const std::vector<A2dpCodecConfig>& codecs_local_capabilities, 46 const std::vector<A2dpCodecConfig>& codecs_selectable_capabilities) = 0; 47 48 protected: 49 virtual ~Delegate() = default; 50 }; 51 52 ~A2dpSource() override; 53 54 void SetDelegate(Delegate* delegate); 55 56 // BluetoothInstance implementation: 57 const Uuid& GetAppIdentifier() const override; 58 int GetInstanceId() const override; 59 60 bool Enable(const std::vector<A2dpCodecConfig>& codec_priorities); 61 void Disable(); 62 bool Connect(const std::string& device_address); 63 bool Disconnect(const std::string& device_address); 64 bool ConfigCodec(const std::string& device_address, 65 const std::vector<A2dpCodecConfig>& codec_preferences); 66 67 private: 68 friend class A2dpSourceFactory; 69 70 explicit A2dpSource(const Uuid& uuid); 71 72 // hal::bluetooth::hal::BluetoothAvInterface::Observer implementation: 73 void ConnectionStateCallback(hal::BluetoothAvInterface* iface, 74 const RawAddress& bd_addr, 75 btav_connection_state_t state) override; 76 void AudioStateCallback(hal::BluetoothAvInterface* iface, 77 const RawAddress& bd_addr, 78 btav_audio_state_t state) override; 79 void AudioConfigCallback( 80 hal::BluetoothAvInterface* iface, const RawAddress& bd_addr, 81 const btav_a2dp_codec_config_t& codec_config, 82 const std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities, 83 const std::vector<btav_a2dp_codec_config_t> 84 codecs_selectable_capabilities) override; 85 bool MandatoryCodecPreferredCallback(hal::BluetoothAvInterface* iface, 86 const RawAddress& bd_addr) override; 87 88 // For |GetAppIdentifier|. 89 const Uuid app_identifier_; 90 91 std::mutex mutex_; 92 93 // A second mutex is used only for |delegate_|. We cannot use |mutex_| because 94 // it may cause a deadlock if the caller and Delegate both take the same lock 95 // 'clock'. 96 // In that scenario, the caller may take 'clock' first and will try to take 97 // |mutex_| second. The callback will take |mutex_| first and invoke a 98 // delegate function which attempts to take 'clock'. 99 std::mutex delegate_mutex_; 100 Delegate* delegate_ = nullptr; 101 102 DISALLOW_COPY_AND_ASSIGN(A2dpSource); 103 }; 104 105 class A2dpSourceFactory : public BluetoothInstanceFactory { 106 public: 107 A2dpSourceFactory(); 108 ~A2dpSourceFactory() override; 109 110 // BluetoothInstanceFactory override: 111 bool RegisterInstance(const Uuid& uuid, 112 const RegisterCallback& callback) override; 113 114 private: 115 DISALLOW_COPY_AND_ASSIGN(A2dpSourceFactory); 116 }; 117 118 } // namespace bluetooth 119