// // Copyright (C) 2017 Google, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #pragma once #include #include #include #include #include #include "service/bluetooth_instance.h" #include "service/common/bluetooth/a2dp_codec_config.h" #include "service/hal/bluetooth_av_interface.h" namespace bluetooth { class A2dpSource : public BluetoothInstance, private hal::BluetoothAvInterface::A2dpSourceObserver { public: // We only allow one instance of this object at a time. static const int kSingletonInstanceId; class Delegate { public: virtual void OnConnectionState(const std::string& device_address, int state) = 0; virtual void OnAudioState(const std::string& device_address, int state) = 0; virtual void OnAudioConfig( const std::string& device_address, A2dpCodecConfig codec_config, const std::vector& codecs_local_capabilities, const std::vector& codecs_selectable_capabilities) = 0; protected: virtual ~Delegate() = default; }; ~A2dpSource() override; void SetDelegate(Delegate* delegate); // BluetoothInstance implementation: const Uuid& GetAppIdentifier() const override; int GetInstanceId() const override; bool Enable(const std::vector& codec_priorities); void Disable(); bool Connect(const std::string& device_address); bool Disconnect(const std::string& device_address); bool ConfigCodec(const std::string& device_address, const std::vector& codec_preferences); private: friend class A2dpSourceFactory; explicit A2dpSource(const Uuid& uuid); // hal::bluetooth::hal::BluetoothAvInterface::Observer implementation: void ConnectionStateCallback(hal::BluetoothAvInterface* iface, const RawAddress& bd_addr, btav_connection_state_t state) override; void AudioStateCallback(hal::BluetoothAvInterface* iface, const RawAddress& bd_addr, btav_audio_state_t state) override; void AudioConfigCallback( hal::BluetoothAvInterface* iface, const RawAddress& bd_addr, const btav_a2dp_codec_config_t& codec_config, const std::vector codecs_local_capabilities, const std::vector codecs_selectable_capabilities) override; bool MandatoryCodecPreferredCallback(hal::BluetoothAvInterface* iface, const RawAddress& bd_addr) override; // For |GetAppIdentifier|. const Uuid app_identifier_; std::mutex mutex_; // A second mutex is used only for |delegate_|. We cannot use |mutex_| because // it may cause a deadlock if the caller and Delegate both take the same lock // 'clock'. // In that scenario, the caller may take 'clock' first and will try to take // |mutex_| second. The callback will take |mutex_| first and invoke a // delegate function which attempts to take 'clock'. std::mutex delegate_mutex_; Delegate* delegate_ = nullptr; DISALLOW_COPY_AND_ASSIGN(A2dpSource); }; class A2dpSourceFactory : public BluetoothInstanceFactory { public: A2dpSourceFactory(); ~A2dpSourceFactory() override; // BluetoothInstanceFactory override: bool RegisterInstance(const Uuid& uuid, const RegisterCallback& callback) override; private: DISALLOW_COPY_AND_ASSIGN(A2dpSourceFactory); }; } // namespace bluetooth