/* * Copyright 2021 HIMSA II K/S - www.himsa.com. * Represented by EHIMA - www.ehima.com * * 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. */ #include #include #include #include #include #include #include #include "bta_has_api.h" #include "btif_common.h" #include "btif_profile_storage.h" #include "stack/include/main_thread.h" using base::Bind; using base::Owned; using base::Passed; using base::Unretained; using bluetooth::has::ConnectionState; using bluetooth::has::ErrorCode; using bluetooth::has::HasClientCallbacks; using bluetooth::has::HasClientInterface; using bluetooth::has::PresetInfo; using bluetooth::has::PresetInfoReason; using bluetooth::le_audio::has::HasClient; namespace { std::unique_ptr has_client_instance; class HearingAaccessClientServiceInterfaceImpl : public HasClientInterface, public HasClientCallbacks { ~HearingAaccessClientServiceInterfaceImpl() override = default; void Init(HasClientCallbacks* callbacks) override { this->callbacks_ = callbacks; do_in_main_thread( FROM_HERE, Bind(&HasClient::Initialize, this, jni_thread_wrapper(Bind( &btif_storage_load_bonded_leaudio_has_devices)))); } void Connect(const RawAddress& addr) override { do_in_main_thread(FROM_HERE, Bind(&HasClient::Connect, Unretained(HasClient::Get()), addr)); do_in_jni_thread( Bind(&btif_storage_set_leaudio_has_acceptlist, addr, true)); } void Disconnect(const RawAddress& addr) override { do_in_main_thread(FROM_HERE, Bind(&HasClient::Disconnect, Unretained(HasClient::Get()), addr)); do_in_jni_thread( Bind(&btif_storage_set_leaudio_has_acceptlist, addr, false)); } void SelectActivePreset(std::variant addr_or_group_id, uint8_t preset_index) override { do_in_main_thread( FROM_HERE, Bind(&HasClient::SelectActivePreset, Unretained(HasClient::Get()), std::move(addr_or_group_id), preset_index)); } void NextActivePreset( std::variant addr_or_group_id) override { do_in_main_thread(FROM_HERE, Bind(&HasClient::NextActivePreset, Unretained(HasClient::Get()), std::move(addr_or_group_id))); } void PreviousActivePreset( std::variant addr_or_group_id) override { do_in_main_thread(FROM_HERE, Bind(&HasClient::PreviousActivePreset, Unretained(HasClient::Get()), std::move(addr_or_group_id))); } void GetPresetInfo(const RawAddress& addr, uint8_t preset_index) override { do_in_main_thread( FROM_HERE, Bind(&HasClient::GetPresetInfo, Unretained(HasClient::Get()), addr, preset_index)); } void SetPresetName(std::variant addr_or_group_id, uint8_t preset_index, std::string preset_name) override { do_in_main_thread( FROM_HERE, Bind(&HasClient::SetPresetName, Unretained(HasClient::Get()), std::move(addr_or_group_id), preset_index, std::move(preset_name))); } void RemoveDevice(const RawAddress& addr) override { /* RemoveDevice can be called on devices that don't have BAS enabled */ if (HasClient::IsHasClientRunning()) { do_in_main_thread(FROM_HERE, Bind(&HasClient::Disconnect, Unretained(HasClient::Get()), addr)); } do_in_jni_thread(Bind(&btif_storage_remove_leaudio_has, addr)); } void Cleanup(void) override { do_in_main_thread(FROM_HERE, Bind(&HasClient::CleanUp)); } void OnConnectionState(ConnectionState state, const RawAddress& addr) override { do_in_jni_thread(Bind(&HasClientCallbacks::OnConnectionState, Unretained(callbacks_), state, addr)); } void OnDeviceAvailable(const RawAddress& addr, uint8_t features) override { do_in_jni_thread(Bind(&HasClientCallbacks::OnDeviceAvailable, Unretained(callbacks_), addr, features)); } void OnFeaturesUpdate(const RawAddress& addr, uint8_t features) override { do_in_jni_thread(Bind(&HasClientCallbacks::OnFeaturesUpdate, Unretained(callbacks_), addr, features)); } void OnActivePresetSelected(std::variant addr_or_group_id, uint8_t preset_index) override { do_in_jni_thread(Bind(&HasClientCallbacks::OnActivePresetSelected, Unretained(callbacks_), std::move(addr_or_group_id), preset_index)); } void OnActivePresetSelectError(std::variant addr_or_group_id, ErrorCode result_code) override { do_in_jni_thread(Bind(&HasClientCallbacks::OnActivePresetSelectError, Unretained(callbacks_), std::move(addr_or_group_id), result_code)); } void OnPresetInfo(std::variant addr_or_group_id, PresetInfoReason change_id, std::vector detail_records) override { do_in_jni_thread(Bind(&HasClientCallbacks::OnPresetInfo, Unretained(callbacks_), std::move(addr_or_group_id), change_id, std::move(detail_records))); } void OnPresetInfoError(std::variant addr_or_group_id, uint8_t preset_index, ErrorCode result_code) override { do_in_jni_thread(Bind(&HasClientCallbacks::OnPresetInfoError, Unretained(callbacks_), std::move(addr_or_group_id), preset_index, result_code)); } void OnSetPresetNameError(std::variant addr_or_group_id, uint8_t preset_index, ErrorCode result_code) override { do_in_jni_thread(Bind(&HasClientCallbacks::OnSetPresetNameError, Unretained(callbacks_), std::move(addr_or_group_id), preset_index, result_code)); } private: HasClientCallbacks* callbacks_; }; } /* namespace */ HasClientInterface* btif_has_client_get_interface(void) { if (!has_client_instance) has_client_instance.reset(new HearingAaccessClientServiceInterfaceImpl()); return has_client_instance.get(); }