• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 HIMSA II K/S - www.himsa.com.
3  * Represented by EHIMA - 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/bind_helpers.h>
19 #include <base/functional/bind.h>
20 #include <base/location.h>
21 #include <base/logging.h>
22 #include <hardware/bluetooth.h>
23 #include <hardware/bt_has.h>
24 
25 #include <bitset>
26 #include <string>
27 #include <vector>
28 
29 #include "bta_has_api.h"
30 #include "btif_common.h"
31 #include "btif_profile_storage.h"
32 #include "stack/include/btu.h"
33 
34 using base::Bind;
35 using base::Owned;
36 using base::Passed;
37 using base::Unretained;
38 using bluetooth::has::ConnectionState;
39 using bluetooth::has::ErrorCode;
40 using bluetooth::has::HasClientCallbacks;
41 using bluetooth::has::HasClientInterface;
42 using bluetooth::has::PresetInfo;
43 using bluetooth::has::PresetInfoReason;
44 
45 using le_audio::has::HasClient;
46 
47 namespace {
48 std::unique_ptr<HasClientInterface> has_client_instance;
49 
50 class HearingAaccessClientServiceInterfaceImpl : public HasClientInterface,
51                                                  public HasClientCallbacks {
52   ~HearingAaccessClientServiceInterfaceImpl() override = default;
53 
Init(HasClientCallbacks * callbacks)54   void Init(HasClientCallbacks* callbacks) override {
55     DVLOG(2) << __func__;
56     this->callbacks_ = callbacks;
57 
58     do_in_main_thread(
59         FROM_HERE,
60         Bind(&HasClient::Initialize, this,
61              jni_thread_wrapper(
62                  FROM_HERE,
63                  Bind(&btif_storage_load_bonded_leaudio_has_devices))));
64   }
65 
Connect(const RawAddress & addr)66   void Connect(const RawAddress& addr) override {
67     DVLOG(2) << __func__ << " addr: " << ADDRESS_TO_LOGGABLE_STR(addr);
68     do_in_main_thread(FROM_HERE, Bind(&HasClient::Connect,
69                                       Unretained(HasClient::Get()), addr));
70 
71     do_in_jni_thread(
72         FROM_HERE, Bind(&btif_storage_set_leaudio_has_acceptlist, addr, true));
73   }
74 
Disconnect(const RawAddress & addr)75   void Disconnect(const RawAddress& addr) override {
76     DVLOG(2) << __func__ << " addr: " << ADDRESS_TO_LOGGABLE_STR(addr);
77     do_in_main_thread(FROM_HERE, Bind(&HasClient::Disconnect,
78                                       Unretained(HasClient::Get()), addr));
79 
80     do_in_jni_thread(
81         FROM_HERE, Bind(&btif_storage_set_leaudio_has_acceptlist, addr, false));
82   }
83 
SelectActivePreset(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index)84   void SelectActivePreset(std::variant<RawAddress, int> addr_or_group_id,
85                           uint8_t preset_index) override {
86     DVLOG(2) << __func__ << " preset_index: " << preset_index;
87 
88     do_in_main_thread(
89         FROM_HERE,
90         Bind(&HasClient::SelectActivePreset, Unretained(HasClient::Get()),
91              std::move(addr_or_group_id), preset_index));
92   }
93 
NextActivePreset(std::variant<RawAddress,int> addr_or_group_id)94   void NextActivePreset(
95       std::variant<RawAddress, int> addr_or_group_id) override {
96     DVLOG(2) << __func__;
97 
98     do_in_main_thread(FROM_HERE, Bind(&HasClient::NextActivePreset,
99                                       Unretained(HasClient::Get()),
100                                       std::move(addr_or_group_id)));
101   }
102 
PreviousActivePreset(std::variant<RawAddress,int> addr_or_group_id)103   void PreviousActivePreset(
104       std::variant<RawAddress, int> addr_or_group_id) override {
105     DVLOG(2) << __func__;
106 
107     do_in_main_thread(FROM_HERE, Bind(&HasClient::PreviousActivePreset,
108                                       Unretained(HasClient::Get()),
109                                       std::move(addr_or_group_id)));
110   }
111 
GetPresetInfo(const RawAddress & addr,uint8_t preset_index)112   void GetPresetInfo(const RawAddress& addr, uint8_t preset_index) override {
113     DVLOG(2) << __func__ << " addr: " << ADDRESS_TO_LOGGABLE_STR(addr)
114              << " preset_index: " << preset_index;
115 
116     do_in_main_thread(
117         FROM_HERE, Bind(&HasClient::GetPresetInfo, Unretained(HasClient::Get()),
118                         addr, preset_index));
119   }
120 
SetPresetName(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index,std::string preset_name)121   void SetPresetName(std::variant<RawAddress, int> addr_or_group_id,
122                      uint8_t preset_index, std::string preset_name) override {
123     DVLOG(2) << __func__ << " preset_index: " << preset_index
124              << " preset_name: " << preset_name;
125 
126     do_in_main_thread(
127         FROM_HERE, Bind(&HasClient::SetPresetName, Unretained(HasClient::Get()),
128                         std::move(addr_or_group_id), preset_index,
129                         std::move(preset_name)));
130   }
131 
RemoveDevice(const RawAddress & addr)132   void RemoveDevice(const RawAddress& addr) override {
133     DVLOG(2) << __func__ << " addr: " << ADDRESS_TO_LOGGABLE_STR(addr);
134 
135     /* RemoveDevice can be called on devices that don't have BAS enabled */
136     if (HasClient::IsHasClientRunning()) {
137       do_in_main_thread(FROM_HERE, Bind(&HasClient::Disconnect,
138                                         Unretained(HasClient::Get()), addr));
139     }
140 
141     do_in_jni_thread(FROM_HERE, Bind(&btif_storage_remove_leaudio_has, addr));
142   }
143 
Cleanup(void)144   void Cleanup(void) override {
145     DVLOG(2) << __func__;
146     do_in_main_thread(FROM_HERE, Bind(&HasClient::CleanUp));
147   }
148 
OnConnectionState(ConnectionState state,const RawAddress & addr)149   void OnConnectionState(ConnectionState state,
150                          const RawAddress& addr) override {
151     DVLOG(2) << __func__ << " addr: " << ADDRESS_TO_LOGGABLE_STR(addr);
152     do_in_jni_thread(FROM_HERE, Bind(&HasClientCallbacks::OnConnectionState,
153                                      Unretained(callbacks_), state, addr));
154   }
155 
OnDeviceAvailable(const RawAddress & addr,uint8_t features)156   void OnDeviceAvailable(const RawAddress& addr, uint8_t features) override {
157     DVLOG(2) << __func__ << " addr: " << ADDRESS_TO_LOGGABLE_STR(addr)
158              << " features: " << features;
159 
160     do_in_jni_thread(FROM_HERE, Bind(&HasClientCallbacks::OnDeviceAvailable,
161                                      Unretained(callbacks_), addr, features));
162   }
163 
OnFeaturesUpdate(const RawAddress & addr,uint8_t features)164   void OnFeaturesUpdate(const RawAddress& addr, uint8_t features) override {
165     DVLOG(2) << __func__ << " addr: " << ADDRESS_TO_LOGGABLE_STR(addr)
166              << " ha_features: " << std::bitset<8>(features);
167 
168     do_in_jni_thread(FROM_HERE, Bind(&HasClientCallbacks::OnFeaturesUpdate,
169                                      Unretained(callbacks_), addr, features));
170   }
171 
OnActivePresetSelected(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index)172   void OnActivePresetSelected(std::variant<RawAddress, int> addr_or_group_id,
173                               uint8_t preset_index) override {
174     DVLOG(2) << __func__ << " preset_index: " << preset_index;
175 
176     do_in_jni_thread(FROM_HERE,
177                      Bind(&HasClientCallbacks::OnActivePresetSelected,
178                           Unretained(callbacks_), std::move(addr_or_group_id),
179                           preset_index));
180   }
181 
OnActivePresetSelectError(std::variant<RawAddress,int> addr_or_group_id,ErrorCode result_code)182   void OnActivePresetSelectError(std::variant<RawAddress, int> addr_or_group_id,
183                                  ErrorCode result_code) override {
184     DVLOG(2) << __func__ << " result_code: "
185              << static_cast<std::underlying_type<ErrorCode>::type>(result_code);
186 
187     do_in_jni_thread(
188         FROM_HERE,
189         Bind(&HasClientCallbacks::OnActivePresetSelectError,
190              Unretained(callbacks_), std::move(addr_or_group_id), result_code));
191   }
192 
OnPresetInfo(std::variant<RawAddress,int> addr_or_group_id,PresetInfoReason change_id,std::vector<PresetInfo> detail_records)193   void OnPresetInfo(std::variant<RawAddress, int> addr_or_group_id,
194                     PresetInfoReason change_id,
195                     std::vector<PresetInfo> detail_records) override {
196     DVLOG(2) << __func__;
197     for (const auto& rec : detail_records) {
198       DVLOG(2) << "\t index: " << +rec.preset_index << ", change_id: "
199                << (std::underlying_type<PresetInfoReason>::type)change_id
200                << ", writable: " << rec.writable
201                << ", available: " << rec.available
202                << ", name: " << rec.preset_name;
203     }
204 
205     do_in_jni_thread(FROM_HERE,
206                      Bind(&HasClientCallbacks::OnPresetInfo,
207                           Unretained(callbacks_), std::move(addr_or_group_id),
208                           change_id, std::move(detail_records)));
209   }
210 
OnPresetInfoError(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index,ErrorCode result_code)211   void OnPresetInfoError(std::variant<RawAddress, int> addr_or_group_id,
212                          uint8_t preset_index, ErrorCode result_code) override {
213     DVLOG(2) << __func__ << " result_code: "
214              << static_cast<std::underlying_type<ErrorCode>::type>(result_code);
215 
216     do_in_jni_thread(
217         FROM_HERE,
218         Bind(&HasClientCallbacks::OnPresetInfoError, Unretained(callbacks_),
219              std::move(addr_or_group_id), preset_index, result_code));
220   }
221 
OnSetPresetNameError(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index,ErrorCode result_code)222   void OnSetPresetNameError(std::variant<RawAddress, int> addr_or_group_id,
223                             uint8_t preset_index,
224                             ErrorCode result_code) override {
225     DVLOG(2) << __func__ << " result_code: "
226              << static_cast<std::underlying_type<ErrorCode>::type>(result_code);
227 
228     do_in_jni_thread(
229         FROM_HERE,
230         Bind(&HasClientCallbacks::OnSetPresetNameError, Unretained(callbacks_),
231              std::move(addr_or_group_id), preset_index, result_code));
232   }
233 
234  private:
235   HasClientCallbacks* callbacks_;
236 };
237 
238 } /* namespace */
239 
btif_has_client_get_interface(void)240 HasClientInterface* btif_has_client_get_interface(void) {
241   if (!has_client_instance)
242     has_client_instance.reset(new HearingAaccessClientServiceInterfaceImpl());
243 
244   return has_client_instance.get();
245 }
246