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