• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
3  * www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <base/logging.h>
19 #include <hardware/bluetooth.h>
20 #include <hardware/bt_le_audio.h>
21 
22 #include <vector>
23 
24 #include "bta_le_audio_api.h"
25 #include "btif_common.h"
26 #include "btif_storage.h"
27 #include "stack/include/btu.h"
28 
29 using base::Bind;
30 using base::Unretained;
31 using bluetooth::le_audio::btle_audio_codec_config_t;
32 using bluetooth::le_audio::ConnectionState;
33 using bluetooth::le_audio::GroupNodeStatus;
34 using bluetooth::le_audio::GroupStatus;
35 using bluetooth::le_audio::LeAudioClientCallbacks;
36 using bluetooth::le_audio::LeAudioClientInterface;
37 
38 namespace {
39 class LeAudioClientInterfaceImpl;
40 std::unique_ptr<LeAudioClientInterface> leAudioInstance;
41 
42 class LeAudioClientInterfaceImpl : public LeAudioClientInterface,
43                                    public LeAudioClientCallbacks {
44   ~LeAudioClientInterfaceImpl() = default;
45 
OnInitialized(void)46   void OnInitialized(void) {
47     do_in_jni_thread(FROM_HERE, Bind(&LeAudioClientCallbacks::OnInitialized,
48                                      Unretained(callbacks)));
49   }
50 
OnConnectionState(ConnectionState state,const RawAddress & address)51   void OnConnectionState(ConnectionState state,
52                          const RawAddress& address) override {
53     do_in_jni_thread(FROM_HERE, Bind(&LeAudioClientCallbacks::OnConnectionState,
54                                      Unretained(callbacks), state, address));
55   }
56 
OnGroupStatus(int group_id,GroupStatus group_status)57   void OnGroupStatus(int group_id, GroupStatus group_status) override {
58     do_in_jni_thread(FROM_HERE,
59                      Bind(&LeAudioClientCallbacks::OnGroupStatus,
60                           Unretained(callbacks), group_id, group_status));
61   }
62 
OnGroupNodeStatus(const RawAddress & addr,int group_id,GroupNodeStatus node_status)63   void OnGroupNodeStatus(const RawAddress& addr, int group_id,
64                          GroupNodeStatus node_status) override {
65     do_in_jni_thread(FROM_HERE,
66                      Bind(&LeAudioClientCallbacks::OnGroupNodeStatus,
67                           Unretained(callbacks), addr, group_id, node_status));
68   }
69 
OnAudioConf(uint8_t direction,int group_id,uint32_t snk_audio_location,uint32_t src_audio_location,uint16_t avail_cont)70   void OnAudioConf(uint8_t direction, int group_id, uint32_t snk_audio_location,
71                    uint32_t src_audio_location, uint16_t avail_cont) override {
72     do_in_jni_thread(FROM_HERE,
73                      Bind(&LeAudioClientCallbacks::OnAudioConf,
74                           Unretained(callbacks), direction, group_id,
75                           snk_audio_location, src_audio_location, avail_cont));
76   }
77 
OnSinkAudioLocationAvailable(const RawAddress & address,uint32_t snk_audio_location)78   void OnSinkAudioLocationAvailable(const RawAddress& address,
79                                     uint32_t snk_audio_location) override {
80     do_in_jni_thread(FROM_HERE,
81                      Bind(&LeAudioClientCallbacks::OnSinkAudioLocationAvailable,
82                           Unretained(callbacks), address, snk_audio_location));
83   }
84 
OnAudioLocalCodecCapabilities(std::vector<btle_audio_codec_config_t> local_input_capa_codec_conf,std::vector<btle_audio_codec_config_t> local_output_capa_codec_conf)85   void OnAudioLocalCodecCapabilities(
86       std::vector<btle_audio_codec_config_t> local_input_capa_codec_conf,
87       std::vector<btle_audio_codec_config_t> local_output_capa_codec_conf)
88       override {
89     do_in_jni_thread(
90         FROM_HERE, Bind(&LeAudioClientCallbacks::OnAudioLocalCodecCapabilities,
91                         Unretained(callbacks), local_input_capa_codec_conf,
92                         local_output_capa_codec_conf));
93   }
94 
OnAudioGroupCodecConf(int group_id,btle_audio_codec_config_t input_codec_conf,btle_audio_codec_config_t output_codec_conf,std::vector<btle_audio_codec_config_t> input_selectable_codec_conf,std::vector<btle_audio_codec_config_t> output_selectable_codec_conf)95   void OnAudioGroupCodecConf(
96       int group_id, btle_audio_codec_config_t input_codec_conf,
97       btle_audio_codec_config_t output_codec_conf,
98       std::vector<btle_audio_codec_config_t> input_selectable_codec_conf,
99       std::vector<btle_audio_codec_config_t> output_selectable_codec_conf)
100       override {
101     do_in_jni_thread(FROM_HERE,
102                      Bind(&LeAudioClientCallbacks::OnAudioGroupCodecConf,
103                           Unretained(callbacks), group_id, input_codec_conf,
104                           output_codec_conf, input_selectable_codec_conf,
105                           output_selectable_codec_conf));
106   }
107 
Initialize(LeAudioClientCallbacks * callbacks,const std::vector<btle_audio_codec_config_t> & offloading_preference)108   void Initialize(LeAudioClientCallbacks* callbacks,
109                   const std::vector<btle_audio_codec_config_t>&
110                       offloading_preference) override {
111     this->callbacks = callbacks;
112 
113     for (auto codec : offloading_preference) {
114       LOG_INFO("supported codec: %s", codec.ToString().c_str());
115     }
116 
117     LeAudioClient::InitializeAudioSetConfigurationProvider();
118     do_in_main_thread(
119         FROM_HERE, Bind(&LeAudioClient::Initialize, this,
120                         jni_thread_wrapper(
121                             FROM_HERE, Bind(&btif_storage_load_bonded_leaudio)),
122                         base::Bind([]() -> bool {
123                           return LeAudioHalVerifier::SupportsLeAudio();
124                         }),
125                         offloading_preference));
126   }
127 
Cleanup(void)128   void Cleanup(void) override {
129     DVLOG(2) << __func__;
130     do_in_main_thread(
131         FROM_HERE,
132         Bind(&LeAudioClient::Cleanup,
133              jni_thread_wrapper(
134                  FROM_HERE,
135                  Bind(&LeAudioClient::CleanupAudioSetConfigurationProvider))));
136   }
137 
RemoveDevice(const RawAddress & address)138   void RemoveDevice(const RawAddress& address) override {
139     DVLOG(2) << __func__ << " address: " << address;
140     do_in_main_thread(FROM_HERE,
141                       Bind(&LeAudioClient::RemoveDevice,
142                            Unretained(LeAudioClient::Get()), address));
143 
144     do_in_jni_thread(FROM_HERE, Bind(&btif_storage_remove_leaudio, address));
145   }
146 
Connect(const RawAddress & address)147   void Connect(const RawAddress& address) override {
148     DVLOG(2) << __func__ << " address: " << address;
149     do_in_main_thread(FROM_HERE,
150                       Bind(&LeAudioClient::Connect,
151                            Unretained(LeAudioClient::Get()), address));
152   }
153 
Disconnect(const RawAddress & address)154   void Disconnect(const RawAddress& address) override {
155     DVLOG(2) << __func__ << " address: " << address;
156     do_in_main_thread(FROM_HERE,
157                       Bind(&LeAudioClient::Disconnect,
158                            Unretained(LeAudioClient::Get()), address));
159   }
160 
GroupAddNode(const int group_id,const RawAddress & address)161   void GroupAddNode(const int group_id, const RawAddress& address) override {
162     DVLOG(2) << __func__ << " group_id: " << group_id
163              << " address: " << address;
164     do_in_main_thread(
165         FROM_HERE, Bind(&LeAudioClient::GroupAddNode,
166                         Unretained(LeAudioClient::Get()), group_id, address));
167   }
168 
GroupRemoveNode(const int group_id,const RawAddress & address)169   void GroupRemoveNode(const int group_id, const RawAddress& address) override {
170     DVLOG(2) << __func__ << " group_id: " << group_id
171              << " address: " << address;
172     do_in_main_thread(
173         FROM_HERE, Bind(&LeAudioClient::GroupRemoveNode,
174                         Unretained(LeAudioClient::Get()), group_id, address));
175   }
176 
GroupSetActive(const int group_id)177   void GroupSetActive(const int group_id) override {
178     DVLOG(2) << __func__ << " group_id: " << group_id;
179     do_in_main_thread(FROM_HERE,
180                       Bind(&LeAudioClient::GroupSetActive,
181                            Unretained(LeAudioClient::Get()), group_id));
182   }
183 
SetCodecConfigPreference(int group_id,btle_audio_codec_config_t input_codec_config,btle_audio_codec_config_t output_codec_config)184   void SetCodecConfigPreference(int group_id,
185                                 btle_audio_codec_config_t input_codec_config,
186                                 btle_audio_codec_config_t output_codec_config) {
187     DVLOG(2) << __func__ << " group_id: " << group_id;
188     do_in_main_thread(FROM_HERE,
189                       Bind(&LeAudioClient::SetCodecConfigPreference,
190                            Unretained(LeAudioClient::Get()), group_id,
191                            input_codec_config, output_codec_config));
192   }
193 
SetCcidInformation(int ccid,int context_type)194   void SetCcidInformation(int ccid, int context_type) {
195     DVLOG(2) << __func__ << " ccid: " << ccid << " context_type"
196              << context_type;
197     do_in_main_thread(
198         FROM_HERE, Bind(&LeAudioClient::SetCcidInformation,
199                         Unretained(LeAudioClient::Get()), ccid, context_type));
200   }
201 
SetInCall(bool in_call)202   void SetInCall(bool in_call) {
203     DVLOG(2) << __func__ << " in_call: " << in_call;
204     do_in_main_thread(FROM_HERE,
205                       Bind(&LeAudioClient::SetInCall,
206                            Unretained(LeAudioClient::Get()), in_call));
207   }
208 
209  private:
210   LeAudioClientCallbacks* callbacks;
211 };
212 
213 } /* namespace */
214 
btif_le_audio_get_interface()215 LeAudioClientInterface* btif_le_audio_get_interface() {
216   if (!leAudioInstance) {
217     leAudioInstance.reset(new LeAudioClientInterfaceImpl());
218   }
219 
220   return leAudioInstance.get();
221 }
222