blob: 5b1b55460601b01183f1cdc113afc33382660dde [file] [log] [blame]
//
// 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 <atomic>
#include <mutex>
#include <string>
#include <vector>
#include "service/bluetooth_instance.h"
#include "service/common/bluetooth/a2dp_codec_config.h"
#include "service/hal/bluetooth_av_interface.h"
#include "types/raw_address.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<A2dpCodecConfig>& codecs_local_capabilities,
const std::vector<A2dpCodecConfig>& codecs_selectable_capabilities) = 0;
protected:
virtual ~Delegate() = default;
};
A2dpSource(const A2dpSource&) = delete;
A2dpSource& operator=(const A2dpSource&) = delete;
~A2dpSource() override;
void SetDelegate(Delegate* delegate);
// BluetoothInstance implementation:
const Uuid& GetAppIdentifier() const override;
int GetInstanceId() const override;
bool Enable(const std::vector<A2dpCodecConfig>& 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<A2dpCodecConfig>& 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<btav_a2dp_codec_config_t> codecs_local_capabilities,
const std::vector<btav_a2dp_codec_config_t>
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;
};
class A2dpSourceFactory : public BluetoothInstanceFactory {
public:
A2dpSourceFactory();
A2dpSourceFactory(const A2dpSourceFactory&) = delete;
A2dpSourceFactory& operator=(const A2dpSourceFactory&) = delete;
~A2dpSourceFactory() override;
// BluetoothInstanceFactory override:
bool RegisterInstance(const Uuid& uuid,
const RegisterCallback& callback) override;
};
} // namespace bluetooth