• 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/functional/bind.h>
19 #include <base/location.h>
20 #include <hardware/bt_has.h>
21 
22 #include <cstdint>
23 #include <memory>
24 #include <string>
25 #include <utility>
26 #include <variant>
27 #include <vector>
28 
29 #include "bta_has_api.h"
30 #include "btif_common.h"
31 #include "btif_le_audio.h"
32 #include "btif_profile_storage.h"
33 #include "stack/include/main_thread.h"
34 #include "types/raw_address.h"
35 
36 using base::Bind;
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 bluetooth::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     this->callbacks_ = callbacks;
56 
57     do_in_main_thread(
58             Bind(&HasClient::Initialize, this,
59                  jni_thread_wrapper(Bind(&btif_storage_load_bonded_leaudio_has_devices))));
60   }
61 
Connect(const RawAddress & addr)62   void Connect(const RawAddress& addr) override {
63     do_in_main_thread(Bind(&HasClient::Connect, Unretained(HasClient::Get()), addr));
64 
65     do_in_jni_thread(Bind(&btif_storage_set_leaudio_has_acceptlist, addr, true));
66   }
67 
Disconnect(const RawAddress & addr)68   void Disconnect(const RawAddress& addr) override {
69     do_in_main_thread(Bind(&HasClient::Disconnect, Unretained(HasClient::Get()), addr));
70 
71     do_in_jni_thread(Bind(&btif_storage_set_leaudio_has_acceptlist, addr, false));
72   }
73 
SelectActivePreset(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index)74   void SelectActivePreset(std::variant<RawAddress, int> addr_or_group_id,
75                           uint8_t preset_index) override {
76     do_in_main_thread(Bind(&HasClient::SelectActivePreset, Unretained(HasClient::Get()),
77                            std::move(addr_or_group_id), preset_index));
78   }
79 
NextActivePreset(std::variant<RawAddress,int> addr_or_group_id)80   void NextActivePreset(std::variant<RawAddress, int> addr_or_group_id) override {
81     do_in_main_thread(Bind(&HasClient::NextActivePreset, Unretained(HasClient::Get()),
82                            std::move(addr_or_group_id)));
83   }
84 
PreviousActivePreset(std::variant<RawAddress,int> addr_or_group_id)85   void PreviousActivePreset(std::variant<RawAddress, int> addr_or_group_id) override {
86     do_in_main_thread(Bind(&HasClient::PreviousActivePreset, Unretained(HasClient::Get()),
87                            std::move(addr_or_group_id)));
88   }
89 
GetPresetInfo(const RawAddress & addr,uint8_t preset_index)90   void GetPresetInfo(const RawAddress& addr, uint8_t preset_index) override {
91     do_in_main_thread(
92             Bind(&HasClient::GetPresetInfo, Unretained(HasClient::Get()), addr, preset_index));
93   }
94 
SetPresetName(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index,std::string preset_name)95   void SetPresetName(std::variant<RawAddress, int> addr_or_group_id, uint8_t preset_index,
96                      std::string preset_name) override {
97     do_in_main_thread(Bind(&HasClient::SetPresetName, Unretained(HasClient::Get()),
98                            std::move(addr_or_group_id), preset_index, std::move(preset_name)));
99   }
100 
RemoveDevice(const RawAddress & addr)101   void RemoveDevice(const RawAddress& addr) override {
102     /* RemoveDevice can be called on devices that don't have BAS enabled */
103     if (HasClient::IsHasClientRunning()) {
104       do_in_main_thread(Bind(&HasClient::Disconnect, Unretained(HasClient::Get()), addr));
105     }
106 
107     do_in_jni_thread(Bind(&btif_storage_remove_leaudio_has, addr));
108   }
109 
Cleanup(void)110   void Cleanup(void) override { do_in_main_thread(Bind(&HasClient::CleanUp)); }
111 
OnConnectionState(ConnectionState state,const RawAddress & addr)112   void OnConnectionState(ConnectionState state, const RawAddress& addr) override {
113     do_in_jni_thread(
114             Bind(&HasClientCallbacks::OnConnectionState, Unretained(callbacks_), state, addr));
115   }
116 
OnDeviceAvailable(const RawAddress & addr,uint8_t features)117   void OnDeviceAvailable(const RawAddress& addr, uint8_t features) override {
118     do_in_jni_thread(
119             Bind(&HasClientCallbacks::OnDeviceAvailable, Unretained(callbacks_), addr, features));
120   }
121 
OnFeaturesUpdate(const RawAddress & addr,uint8_t features)122   void OnFeaturesUpdate(const RawAddress& addr, uint8_t features) override {
123     do_in_jni_thread(
124             Bind(&HasClientCallbacks::OnFeaturesUpdate, Unretained(callbacks_), addr, features));
125   }
126 
OnActivePresetSelected(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index)127   void OnActivePresetSelected(std::variant<RawAddress, int> addr_or_group_id,
128                               uint8_t preset_index) override {
129     do_in_jni_thread(Bind(&HasClientCallbacks::OnActivePresetSelected, Unretained(callbacks_),
130                           std::move(addr_or_group_id), preset_index));
131   }
132 
OnActivePresetSelectError(std::variant<RawAddress,int> addr_or_group_id,ErrorCode result_code)133   void OnActivePresetSelectError(std::variant<RawAddress, int> addr_or_group_id,
134                                  ErrorCode result_code) override {
135     do_in_jni_thread(Bind(&HasClientCallbacks::OnActivePresetSelectError, Unretained(callbacks_),
136                           std::move(addr_or_group_id), result_code));
137   }
138 
OnPresetInfo(std::variant<RawAddress,int> addr_or_group_id,PresetInfoReason change_id,std::vector<PresetInfo> detail_records)139   void OnPresetInfo(std::variant<RawAddress, int> addr_or_group_id, PresetInfoReason change_id,
140                     std::vector<PresetInfo> detail_records) override {
141     do_in_jni_thread(Bind(&HasClientCallbacks::OnPresetInfo, Unretained(callbacks_),
142                           std::move(addr_or_group_id), change_id, std::move(detail_records)));
143   }
144 
OnPresetInfoError(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index,ErrorCode result_code)145   void OnPresetInfoError(std::variant<RawAddress, int> addr_or_group_id, uint8_t preset_index,
146                          ErrorCode result_code) override {
147     do_in_jni_thread(Bind(&HasClientCallbacks::OnPresetInfoError, Unretained(callbacks_),
148                           std::move(addr_or_group_id), preset_index, result_code));
149   }
150 
OnSetPresetNameError(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index,ErrorCode result_code)151   void OnSetPresetNameError(std::variant<RawAddress, int> addr_or_group_id, uint8_t preset_index,
152                             ErrorCode result_code) override {
153     do_in_jni_thread(Bind(&HasClientCallbacks::OnSetPresetNameError, Unretained(callbacks_),
154                           std::move(addr_or_group_id), preset_index, result_code));
155   }
156 
157 private:
158   HasClientCallbacks* callbacks_;
159 };
160 
161 } /* namespace */
162 
btif_has_client_get_interface(void)163 HasClientInterface* btif_has_client_get_interface(void) {
164   if (!has_client_instance) {
165     has_client_instance.reset(new HearingAaccessClientServiceInterfaceImpl());
166   }
167 
168   return has_client_instance.get();
169 }
170