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/bluetooth.h>
21 #include <hardware/bt_has.h>
22 
23 #include <bitset>
24 #include <string>
25 #include <vector>
26 
27 #include "bta_has_api.h"
28 #include "btif_common.h"
29 #include "btif_profile_storage.h"
30 #include "stack/include/main_thread.h"
31 
32 using base::Bind;
33 using base::Owned;
34 using base::Passed;
35 using base::Unretained;
36 using bluetooth::has::ConnectionState;
37 using bluetooth::has::ErrorCode;
38 using bluetooth::has::HasClientCallbacks;
39 using bluetooth::has::HasClientInterface;
40 using bluetooth::has::PresetInfo;
41 using bluetooth::has::PresetInfoReason;
42 
43 using bluetooth::le_audio::has::HasClient;
44 
45 namespace {
46 std::unique_ptr<HasClientInterface> has_client_instance;
47 
48 class HearingAaccessClientServiceInterfaceImpl : public HasClientInterface,
49                                                  public HasClientCallbacks {
50   ~HearingAaccessClientServiceInterfaceImpl() override = default;
51 
Init(HasClientCallbacks * callbacks)52   void Init(HasClientCallbacks* callbacks) override {
53     this->callbacks_ = callbacks;
54 
55     do_in_main_thread(
56         FROM_HERE, Bind(&HasClient::Initialize, this,
57                         jni_thread_wrapper(Bind(
58                             &btif_storage_load_bonded_leaudio_has_devices))));
59   }
60 
Connect(const RawAddress & addr)61   void Connect(const RawAddress& addr) override {
62     do_in_main_thread(FROM_HERE, Bind(&HasClient::Connect,
63                                       Unretained(HasClient::Get()), addr));
64 
65     do_in_jni_thread(
66         Bind(&btif_storage_set_leaudio_has_acceptlist, addr, true));
67   }
68 
Disconnect(const RawAddress & addr)69   void Disconnect(const RawAddress& addr) override {
70     do_in_main_thread(FROM_HERE, Bind(&HasClient::Disconnect,
71                                       Unretained(HasClient::Get()), addr));
72 
73     do_in_jni_thread(
74         Bind(&btif_storage_set_leaudio_has_acceptlist, addr, false));
75   }
76 
SelectActivePreset(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index)77   void SelectActivePreset(std::variant<RawAddress, int> addr_or_group_id,
78                           uint8_t preset_index) override {
79     do_in_main_thread(
80         FROM_HERE,
81         Bind(&HasClient::SelectActivePreset, Unretained(HasClient::Get()),
82              std::move(addr_or_group_id), preset_index));
83   }
84 
NextActivePreset(std::variant<RawAddress,int> addr_or_group_id)85   void NextActivePreset(
86       std::variant<RawAddress, int> addr_or_group_id) override {
87     do_in_main_thread(FROM_HERE, Bind(&HasClient::NextActivePreset,
88                                       Unretained(HasClient::Get()),
89                                       std::move(addr_or_group_id)));
90   }
91 
PreviousActivePreset(std::variant<RawAddress,int> addr_or_group_id)92   void PreviousActivePreset(
93       std::variant<RawAddress, int> addr_or_group_id) override {
94     do_in_main_thread(FROM_HERE, Bind(&HasClient::PreviousActivePreset,
95                                       Unretained(HasClient::Get()),
96                                       std::move(addr_or_group_id)));
97   }
98 
GetPresetInfo(const RawAddress & addr,uint8_t preset_index)99   void GetPresetInfo(const RawAddress& addr, uint8_t preset_index) override {
100     do_in_main_thread(
101         FROM_HERE, Bind(&HasClient::GetPresetInfo, Unretained(HasClient::Get()),
102                         addr, preset_index));
103   }
104 
SetPresetName(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index,std::string preset_name)105   void SetPresetName(std::variant<RawAddress, int> addr_or_group_id,
106                      uint8_t preset_index, std::string preset_name) override {
107     do_in_main_thread(
108         FROM_HERE, Bind(&HasClient::SetPresetName, Unretained(HasClient::Get()),
109                         std::move(addr_or_group_id), preset_index,
110                         std::move(preset_name)));
111   }
112 
RemoveDevice(const RawAddress & addr)113   void RemoveDevice(const RawAddress& addr) override {
114     /* RemoveDevice can be called on devices that don't have BAS enabled */
115     if (HasClient::IsHasClientRunning()) {
116       do_in_main_thread(FROM_HERE, Bind(&HasClient::Disconnect,
117                                         Unretained(HasClient::Get()), addr));
118     }
119 
120     do_in_jni_thread(Bind(&btif_storage_remove_leaudio_has, addr));
121   }
122 
Cleanup(void)123   void Cleanup(void) override {
124     do_in_main_thread(FROM_HERE, Bind(&HasClient::CleanUp));
125   }
126 
OnConnectionState(ConnectionState state,const RawAddress & addr)127   void OnConnectionState(ConnectionState state,
128                          const RawAddress& addr) override {
129     do_in_jni_thread(Bind(&HasClientCallbacks::OnConnectionState,
130                           Unretained(callbacks_), state, addr));
131   }
132 
OnDeviceAvailable(const RawAddress & addr,uint8_t features)133   void OnDeviceAvailable(const RawAddress& addr, uint8_t features) override {
134     do_in_jni_thread(Bind(&HasClientCallbacks::OnDeviceAvailable,
135                           Unretained(callbacks_), addr, features));
136   }
137 
OnFeaturesUpdate(const RawAddress & addr,uint8_t features)138   void OnFeaturesUpdate(const RawAddress& addr, uint8_t features) override {
139     do_in_jni_thread(Bind(&HasClientCallbacks::OnFeaturesUpdate,
140                           Unretained(callbacks_), addr, features));
141   }
142 
OnActivePresetSelected(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index)143   void OnActivePresetSelected(std::variant<RawAddress, int> addr_or_group_id,
144                               uint8_t preset_index) override {
145     do_in_jni_thread(Bind(&HasClientCallbacks::OnActivePresetSelected,
146                           Unretained(callbacks_), std::move(addr_or_group_id),
147                           preset_index));
148   }
149 
OnActivePresetSelectError(std::variant<RawAddress,int> addr_or_group_id,ErrorCode result_code)150   void OnActivePresetSelectError(std::variant<RawAddress, int> addr_or_group_id,
151                                  ErrorCode result_code) override {
152     do_in_jni_thread(Bind(&HasClientCallbacks::OnActivePresetSelectError,
153                           Unretained(callbacks_), std::move(addr_or_group_id),
154                           result_code));
155   }
156 
OnPresetInfo(std::variant<RawAddress,int> addr_or_group_id,PresetInfoReason change_id,std::vector<PresetInfo> detail_records)157   void OnPresetInfo(std::variant<RawAddress, int> addr_or_group_id,
158                     PresetInfoReason change_id,
159                     std::vector<PresetInfo> detail_records) override {
160     do_in_jni_thread(Bind(&HasClientCallbacks::OnPresetInfo,
161                           Unretained(callbacks_), std::move(addr_or_group_id),
162                           change_id, std::move(detail_records)));
163   }
164 
OnPresetInfoError(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index,ErrorCode result_code)165   void OnPresetInfoError(std::variant<RawAddress, int> addr_or_group_id,
166                          uint8_t preset_index, ErrorCode result_code) override {
167     do_in_jni_thread(Bind(&HasClientCallbacks::OnPresetInfoError,
168                           Unretained(callbacks_), std::move(addr_or_group_id),
169                           preset_index, result_code));
170   }
171 
OnSetPresetNameError(std::variant<RawAddress,int> addr_or_group_id,uint8_t preset_index,ErrorCode result_code)172   void OnSetPresetNameError(std::variant<RawAddress, int> addr_or_group_id,
173                             uint8_t preset_index,
174                             ErrorCode result_code) override {
175     do_in_jni_thread(Bind(&HasClientCallbacks::OnSetPresetNameError,
176                           Unretained(callbacks_), std::move(addr_or_group_id),
177                           preset_index, result_code));
178   }
179 
180  private:
181   HasClientCallbacks* callbacks_;
182 };
183 
184 } /* namespace */
185 
btif_has_client_get_interface(void)186 HasClientInterface* btif_has_client_get_interface(void) {
187   if (!has_client_instance)
188     has_client_instance.reset(new HearingAaccessClientServiceInterfaceImpl());
189 
190   return has_client_instance.get();
191 }
192