/****************************************************************************** * * Copyright 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ /* Hearing Aid Profile Interface */ #include "bta_hearing_aid_api.h" #include "btif_common.h" #include "btif_storage.h" #include "stack/include/btu.h" #include #include #include #include #include using base::Bind; using base::Unretained; using bluetooth::hearing_aid::ConnectionState; using bluetooth::hearing_aid::HearingAidCallbacks; using bluetooth::hearing_aid::HearingAidInterface; // template specialization template <> base::Callback jni_thread_wrapper(const base::Location& from_here, base::Callback cb) { return base::Bind( [](const base::Location& from_here, base::Callback cb) { do_in_jni_thread(from_here, cb); }, from_here, std::move(cb)); } namespace { class HearingAidInterfaceImpl; std::unique_ptr hearingAidInstance; class HearingAidInterfaceImpl : public bluetooth::hearing_aid::HearingAidInterface, public HearingAidCallbacks { ~HearingAidInterfaceImpl() override = default; void Init(HearingAidCallbacks* callbacks) override { DVLOG(2) << __func__; this->callbacks = callbacks; do_in_main_thread( FROM_HERE, Bind(&HearingAid::Initialize, this, jni_thread_wrapper(FROM_HERE, Bind(&btif_storage_load_bonded_hearing_aids)))); } void OnConnectionState(ConnectionState state, const RawAddress& address) override { DVLOG(2) << __func__ << " address: " << address; do_in_jni_thread(FROM_HERE, Bind(&HearingAidCallbacks::OnConnectionState, Unretained(callbacks), state, address)); } void OnDeviceAvailable(uint8_t capabilities, uint64_t hiSyncId, const RawAddress& address) override { DVLOG(2) << __func__ << " address: " << address << ", hiSyncId: " << loghex(hiSyncId) << ", capabilities: " << loghex(capabilities); do_in_jni_thread(FROM_HERE, Bind(&HearingAidCallbacks::OnDeviceAvailable, Unretained(callbacks), capabilities, hiSyncId, address)); } void Connect(const RawAddress& address) override { DVLOG(2) << __func__ << " address: " << address; do_in_main_thread(FROM_HERE, Bind(&HearingAid::Connect, Unretained(HearingAid::Get()), address)); } void Disconnect(const RawAddress& address) override { DVLOG(2) << __func__ << " address: " << address; do_in_main_thread(FROM_HERE, Bind(&HearingAid::Disconnect, Unretained(HearingAid::Get()), address)); do_in_jni_thread(FROM_HERE, Bind(&btif_storage_set_hearing_aid_acceptlist, address, false)); } void AddToAcceptlist(const RawAddress& address) override { VLOG(2) << __func__ << " address: " << address; do_in_main_thread(FROM_HERE, Bind(&HearingAid::AddToAcceptlist, Unretained(HearingAid::Get()), address)); do_in_jni_thread(FROM_HERE, Bind(&btif_storage_set_hearing_aid_acceptlist, address, true)); } void SetVolume(int8_t volume) override { DVLOG(2) << __func__ << " volume: " << +volume; do_in_main_thread(FROM_HERE, Bind(&HearingAid::SetVolume, Unretained(HearingAid::Get()), volume)); } void RemoveDevice(const RawAddress& address) override { DVLOG(2) << __func__ << " address: " << address; // RemoveDevice can be called on devices that don't have HA enabled if (HearingAid::IsHearingAidRunning()) { do_in_main_thread(FROM_HERE, Bind(&HearingAid::Disconnect, Unretained(HearingAid::Get()), address)); } do_in_jni_thread(FROM_HERE, Bind(&btif_storage_remove_hearing_aid, address)); } void Cleanup(void) override { DVLOG(2) << __func__; do_in_main_thread(FROM_HERE, Bind(&HearingAid::CleanUp)); } private: HearingAidCallbacks* callbacks; }; } // namespace HearingAidInterface* btif_hearing_aid_get_interface() { if (!hearingAidInstance) hearingAidInstance.reset(new HearingAidInterfaceImpl()); return hearingAidInstance.get(); }