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