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