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