1 /******************************************************************************
2 *
3 * Copyright 2018 The Android Open Source Project
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
19 /* Hearing Aid Profile Interface */
20
21 #include "btif_hearing_aid.h"
22
23 #include <base/functional/bind.h>
24 #include <base/location.h>
25 #include <hardware/bt_hearing_aid.h>
26
27 #include <cstdint>
28 #include <memory>
29 #include <utility>
30
31 #include "bta_hearing_aid_api.h"
32 #include "btif_common.h"
33 #include "btif_profile_storage.h"
34 #include "hardware/avrcp/avrcp.h"
35 #include "stack/include/main_thread.h"
36 #include "types/raw_address.h"
37
38 using base::Bind;
39 using base::Unretained;
40 using bluetooth::hearing_aid::ConnectionState;
41 using bluetooth::hearing_aid::HearingAidCallbacks;
42 using bluetooth::hearing_aid::HearingAidInterface;
43
44 // template specialization
45 template <>
jni_thread_wrapper(base::Callback<void ()> cb)46 base::Callback<void()> jni_thread_wrapper(base::Callback<void()> cb) {
47 return base::Bind([](base::Callback<void()> cb) { do_in_jni_thread(cb); }, std::move(cb));
48 }
49
50 namespace {
51 class HearingAidInterfaceImpl;
52 std::unique_ptr<HearingAidInterface> hearingAidInstance;
53
54 class HearingAidInterfaceImpl : public bluetooth::hearing_aid::HearingAidInterface,
55 public HearingAidCallbacks {
56 ~HearingAidInterfaceImpl() override = default;
57
Init(HearingAidCallbacks * callbacks)58 void Init(HearingAidCallbacks* callbacks) override {
59 this->callbacks = callbacks;
60 do_in_main_thread(Bind(&HearingAid::Initialize, this,
61 jni_thread_wrapper(Bind(&btif_storage_load_bonded_hearing_aids))));
62 }
63
OnConnectionState(ConnectionState state,const RawAddress & address)64 void OnConnectionState(ConnectionState state, const RawAddress& address) override {
65 do_in_jni_thread(
66 Bind(&HearingAidCallbacks::OnConnectionState, Unretained(callbacks), state, address));
67 }
68
OnDeviceAvailable(uint8_t capabilities,uint64_t hiSyncId,const RawAddress & address)69 void OnDeviceAvailable(uint8_t capabilities, uint64_t hiSyncId,
70 const RawAddress& address) override {
71 do_in_jni_thread(Bind(&HearingAidCallbacks::OnDeviceAvailable, Unretained(callbacks),
72 capabilities, hiSyncId, address));
73 }
74
Connect(const RawAddress & address)75 void Connect(const RawAddress& address) override {
76 do_in_main_thread(Bind(&HearingAid::Connect, address));
77 }
78
Disconnect(const RawAddress & address)79 void Disconnect(const RawAddress& address) override {
80 do_in_main_thread(Bind(&HearingAid::Disconnect, address));
81 do_in_jni_thread(Bind(&btif_storage_set_hearing_aid_acceptlist, address, false));
82 }
83
AddToAcceptlist(const RawAddress & address)84 void AddToAcceptlist(const RawAddress& address) override {
85 do_in_main_thread(Bind(&HearingAid::AddToAcceptlist, address));
86 do_in_jni_thread(Bind(&btif_storage_set_hearing_aid_acceptlist, address, true));
87 }
88
SetVolume(int8_t volume)89 void SetVolume(int8_t volume) override {
90 do_in_main_thread(Bind(&HearingAid::SetVolume, volume));
91 }
92
RemoveDevice(const RawAddress & address)93 void RemoveDevice(const RawAddress& address) override {
94 // RemoveDevice can be called on devices that don't have HA enabled
95 if (HearingAid::IsHearingAidRunning()) {
96 do_in_main_thread(Bind(&HearingAid::Disconnect, address));
97 }
98
99 do_in_jni_thread(Bind(&btif_storage_remove_hearing_aid, address));
100 }
101
Cleanup(void)102 void Cleanup(void) override { do_in_main_thread(Bind(&HearingAid::CleanUp)); }
103
104 private:
105 HearingAidCallbacks* callbacks;
106 };
107
108 } // namespace
109
btif_hearing_aid_get_interface()110 HearingAidInterface* btif_hearing_aid_get_interface() {
111 if (!hearingAidInstance) {
112 hearingAidInstance.reset(new HearingAidInterfaceImpl());
113 }
114
115 return hearingAidInstance.get();
116 }
117