// // Copyright 2015 Google, Inc. // // 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 "service/ipc/binder/bluetooth_binder_server.h" #include #include "service/ipc/binder/bluetooth_a2dp_sink_binder_server.h" #include "service/ipc/binder/bluetooth_a2dp_source_binder_server.h" #include "service/ipc/binder/bluetooth_avrcp_control_binder_server.h" #include "service/ipc/binder/bluetooth_avrcp_target_binder_server.h" #include "service/ipc/binder/bluetooth_gatt_client_binder_server.h" #include "service/ipc/binder/bluetooth_gatt_server_binder_server.h" #include "service/ipc/binder/bluetooth_le_advertiser_binder_server.h" #include "service/ipc/binder/bluetooth_le_scanner_binder_server.h" #include "service/ipc/binder/bluetooth_low_energy_binder_server.h" #include "service/hal/bluetooth_interface.h" using android::sp; using android::String8; using android::String16; using android::bluetooth::IBluetoothCallback; using android::bluetooth::IBluetoothGattClient; using android::bluetooth::IBluetoothGattServer; namespace ipc { namespace binder { BluetoothBinderServer::BluetoothBinderServer(bluetooth::Adapter* adapter) : adapter_(adapter) { CHECK(adapter_); adapter_->AddObserver(this); } BluetoothBinderServer::~BluetoothBinderServer() { adapter_->RemoveObserver(this); } // binder::BnBluetooth overrides: Status BluetoothBinderServer::IsEnabled(bool* _aidl_return) { VLOG(2) << __func__; *_aidl_return = adapter_->IsEnabled(); return Status::ok(); } Status BluetoothBinderServer::GetState(int32_t* _aidl_return) { VLOG(2) << __func__; *_aidl_return = adapter_->GetState(); return Status::ok(); } Status BluetoothBinderServer::Enable(bool* _aidl_return) { VLOG(2) << __func__; *_aidl_return = adapter_->Enable(); return Status::ok(); } Status BluetoothBinderServer::EnableNoAutoConnect(bool* _aidl_return) { VLOG(2) << __func__; // TODO(armansito): Implement. *_aidl_return = false; return Status::ok(); } Status BluetoothBinderServer::Disable(bool* _aidl_return) { VLOG(2) << __func__; *_aidl_return = adapter_->Disable(); return Status::ok(); } Status BluetoothBinderServer::GetAddress(::android::String16* _aidl_return) { VLOG(2) << __func__; *_aidl_return = String16(String8(adapter_->GetAddress().c_str())); return Status::ok(); } Status BluetoothBinderServer::GetUUIDs( ::std::vector<::android::bluetooth::UUID>* _aidl_return) { VLOG(2) << __func__; // TODO(armansito): Implement. *_aidl_return = std::vector(); return Status::ok(); } Status BluetoothBinderServer::SetName(const ::android::String16& name, bool* _aidl_return) { VLOG(2) << __func__; *_aidl_return = adapter_->SetName(std::string(String8(name).string())); return Status::ok(); } Status BluetoothBinderServer::GetName(::android::String16* _aidl_return) { VLOG(2) << __func__; *_aidl_return = String16(String8(adapter_->GetName().c_str())); return Status::ok(); } Status BluetoothBinderServer::SetScanMode(int32_t scan_mode, bool* _aidl_return) { VLOG(2) << __func__; *_aidl_return = adapter_->SetScanMode(scan_mode); return Status::ok(); } Status BluetoothBinderServer::SetScanEnable(bool scan_enable, bool* _aidl_return) { VLOG(2) << __func__; *_aidl_return = adapter_->SetScanEnable(scan_enable); return Status::ok(); } Status BluetoothBinderServer::SspReply( const ::android::String16& device_address, int32_t variant, bool accept, int32_t passkey, bool* _aidl_return) { VLOG(2) << __func__; *_aidl_return = adapter_->SspReply(String8(device_address).string(), variant, accept, passkey); return Status::ok(); } Status BluetoothBinderServer::CreateBond( const ::android::String16& device_address, int32_t transport, bool* _aidl_return) { VLOG(2) << __func__; *_aidl_return = adapter_->CreateBond(String8(device_address).string(), transport); return Status::ok(); } Status BluetoothBinderServer::GetBondedDevices(bool* _aidl_return) { VLOG(2) << __func__; *_aidl_return = adapter_->GetBondedDevices(); return Status::ok(); } Status BluetoothBinderServer::RemoveBond( const ::android::String16& device_address, bool* _aidl_return) { VLOG(2) << __func__; *_aidl_return = adapter_->RemoveBond(String8(device_address).string()); return Status::ok(); } Status BluetoothBinderServer::GetRemoteDeviceProperties( const ::android::String16& device_address, bool* _aidl_return) { VLOG(2) << __func__; *_aidl_return = adapter_->GetRemoteDeviceProperties(String8(device_address).string()); return Status::ok(); } Status BluetoothBinderServer::RegisterCallback( const ::android::sp& callback) { VLOG(2) << __func__; if (!callback.get()) { LOG(ERROR) << "RegisterCallback called with NULL binder. Ignoring."; return Status::ok(); } callbacks_.Register(callback); return Status::ok(); } Status BluetoothBinderServer::UnregisterCallback( const ::android::sp& callback) { VLOG(2) << __func__; if (!callback.get()) { LOG(ERROR) << "UnregisterCallback called with NULL binder. Ignoring."; return Status::ok(); } callbacks_.Unregister(callback); return Status::ok(); } Status BluetoothBinderServer::IsMultiAdvertisementSupported( bool* _aidl_return) { VLOG(2) << __func__; *_aidl_return = adapter_->IsMultiAdvertisementSupported(); return Status::ok(); } Status BluetoothBinderServer::GetA2dpSinkInterface( ::android::sp* _aidl_return) { VLOG(2) << __func__; if (!adapter_->IsEnabled()) { LOG(ERROR) << "Cannot obtain IBluetoothA2dpSink interface while disabled"; *_aidl_return = nullptr; return Status::ok(); } if (!a2dp_sink_interface_.get()) a2dp_sink_interface_ = new BluetoothA2dpSinkBinderServer(adapter_); if (a2dp_sink_interface_->HasInstance()) { LOG(ERROR) << "Only one A2dpSink interface allowed at a time"; *_aidl_return = nullptr; return Status::ok(); } *_aidl_return = a2dp_sink_interface_; return Status::ok(); } Status BluetoothBinderServer::GetA2dpSourceInterface( ::android::sp* _aidl_return) { VLOG(2) << __func__; if (!adapter_->IsEnabled()) { LOG(ERROR) << "Cannot obtain IBluetoothA2dpSource interface while disabled"; *_aidl_return = nullptr; return Status::ok(); } if (!a2dp_source_interface_.get()) a2dp_source_interface_ = new BluetoothA2dpSourceBinderServer(adapter_); if (a2dp_source_interface_->HasInstance()) { LOG(ERROR) << "Only one A2dpSource interface allowed at a time"; *_aidl_return = nullptr; return Status::ok(); } *_aidl_return = a2dp_source_interface_; return Status::ok(); } Status BluetoothBinderServer::GetLowEnergyInterface( ::android::sp* _aidl_return) { VLOG(2) << __func__; if (!adapter_->IsEnabled()) { LOG(ERROR) << "Cannot obtain IBluetoothLowEnergy interface while disabled"; *_aidl_return = NULL; return Status::ok(); } if (!low_energy_interface_.get()) low_energy_interface_ = new BluetoothLowEnergyBinderServer(adapter_); *_aidl_return = low_energy_interface_; return Status::ok(); } Status BluetoothBinderServer::GetLeAdvertiserInterface( ::android::sp* _aidl_return) { VLOG(2) << __func__; if (!adapter_->IsEnabled()) { LOG(ERROR) << "Cannot obtain IBluetoothLeAdvertiser interface while disabled"; *_aidl_return = NULL; return Status::ok(); } if (!le_advertiser_interface_.get()) le_advertiser_interface_ = new BluetoothLeAdvertiserBinderServer(adapter_); *_aidl_return = le_advertiser_interface_; return Status::ok(); } Status BluetoothBinderServer::GetLeScannerInterface( ::android::sp* _aidl_return) { VLOG(2) << __func__; if (!adapter_->IsEnabled()) { LOG(ERROR) << "Cannot obtain IBluetoothLeScanner interface while disabled"; *_aidl_return = NULL; return Status::ok(); } if (!le_scanner_interface_.get()) le_scanner_interface_ = new BluetoothLeScannerBinderServer(adapter_); *_aidl_return = le_scanner_interface_; return Status::ok(); } Status BluetoothBinderServer::GetGattClientInterface( ::android::sp* _aidl_return) { VLOG(2) << __func__; if (!adapter_->IsEnabled()) { LOG(ERROR) << "Cannot obtain IBluetoothGattClient interface while disabled"; *_aidl_return = NULL; return Status::ok(); } if (!gatt_client_interface_.get()) gatt_client_interface_ = new BluetoothGattClientBinderServer(adapter_); *_aidl_return = gatt_client_interface_; return Status::ok(); } Status BluetoothBinderServer::GetGattServerInterface( ::android::sp* _aidl_return) { VLOG(2) << __func__; if (!adapter_->IsEnabled()) { LOG(ERROR) << "Cannot obtain IBluetoothGattServer interface while disabled"; *_aidl_return = NULL; return Status::ok(); } if (!gatt_server_interface_.get()) gatt_server_interface_ = new BluetoothGattServerBinderServer(adapter_); *_aidl_return = gatt_server_interface_; return Status::ok(); } Status BluetoothBinderServer::GetAvrcpControlInterface( ::android::sp* _aidl_return) { VLOG(2) << __func__; if (!adapter_->IsEnabled()) { LOG(ERROR) << "Cannot obtain IBluetoothAvrcpControl interface while disabled"; *_aidl_return = NULL; return Status::ok(); } if (!avrcp_control_interface_.get()) avrcp_control_interface_ = new BluetoothAvrcpControlBinderServer(adapter_); *_aidl_return = avrcp_control_interface_; return Status::ok(); } Status BluetoothBinderServer::GetAvrcpTargetInterface( ::android::sp* _aidl_return) { VLOG(2) << __func__; if (!adapter_->IsEnabled()) { LOG(ERROR) << "Cannot obtain IBluetoothAvrcpTarget interface while disabled"; *_aidl_return = NULL; return Status::ok(); } if (!avrcp_target_interface_.get()) avrcp_target_interface_ = new BluetoothAvrcpTargetBinderServer(adapter_); if (avrcp_target_interface_->HasInstance()) { LOG(ERROR) << "Only one AVRCP target interface allowed at a time"; *_aidl_return = nullptr; return Status::ok(); } *_aidl_return = avrcp_target_interface_; return Status::ok(); } android::status_t BluetoothBinderServer::dump( int fd, const android::Vector& args) { VLOG(2) << __func__ << " called with fd " << fd; if (args.size() > 0) { // TODO (jamuraa): Parse arguments and switch on --proto, --proto_text for (const auto& x : args) { VLOG(2) << __func__ << "argument: " << x.string(); } } // TODO (jamuraa): enumerate profiles and dump profile information const bt_interface_t* iface = bluetooth::hal::BluetoothInterface::Get()->GetHALInterface(); iface->dump(fd, NULL); return android::NO_ERROR; } void BluetoothBinderServer::OnAdapterStateChanged( bluetooth::Adapter* adapter, bluetooth::AdapterState prev_state, bluetooth::AdapterState new_state) { CHECK_EQ(adapter, adapter_); VLOG(2) << "Received adapter state update - prev: " << prev_state << " new: " << new_state; callbacks_.ForEach([prev_state, new_state](IBluetoothCallback* callback) { callback->OnBluetoothStateChange(prev_state, new_state); }); } void BluetoothBinderServer::OnDeviceConnectionStateChanged( bluetooth::Adapter* adapter, const std::string& device_address, bool connected) { CHECK_EQ(adapter, adapter_); auto addr_s16 = String16(device_address.c_str(), device_address.size()); callbacks_.ForEach([&addr_s16, connected](IBluetoothCallback* callback) { callback->OnDeviceConnectionStateChanged(addr_s16, connected); }); } void BluetoothBinderServer::OnScanEnableChanged(bluetooth::Adapter* adapter, bool scan_enabled) { CHECK_EQ(adapter, adapter_); callbacks_.ForEach([scan_enabled](IBluetoothCallback* callback) { callback->OnScanEnableChanged(scan_enabled); }); } void BluetoothBinderServer::OnSspRequest(bluetooth::Adapter* adapter, const std::string& device_address, const std::string& device_name, int cod, int pairing_variant, int pass_key) { CHECK_EQ(adapter, adapter_); VLOG(2) << "Received ssp request: device_address: " << device_address << ", device_name: " << device_name << ", cod: " << cod << ", pairing_variant: " << pairing_variant << ", pass_key: " << pass_key; android::String16 addr_s16(device_address.c_str()); android::String16 name_s16(device_name.c_str()); callbacks_.ForEach([&addr_s16, &name_s16, cod, pairing_variant, pass_key](IBluetoothCallback* callback) { callback->OnSspRequest(addr_s16, name_s16, cod, pairing_variant, pass_key); }); } void BluetoothBinderServer::OnBondStateChanged( bluetooth::Adapter* adapter, int status, const std::string& device_address, int state) { CHECK_EQ(adapter, adapter_); VLOG(2) << "Received " << __func__ << " " << "status: " << status << ", device_address: " << device_address << ", state: " << state; android::String16 addr_s16(device_address.c_str(), device_address.size()); callbacks_.ForEach([status, &addr_s16, state](IBluetoothCallback* callback) { callback->OnBondStateChanged(status, addr_s16, state); }); } void BluetoothBinderServer::OnGetBondedDevices( bluetooth::Adapter* adapter, int status, const std::vector& bonded_devices) { CHECK_EQ(adapter, adapter_); VLOG(2) << "Received " << __func__; std::vector devices_s16; devices_s16.reserve(bonded_devices.size()); for (const auto& device : bonded_devices) devices_s16.emplace_back(device.c_str(), device.size()); callbacks_.ForEach([status, &devices_s16](IBluetoothCallback* callback) { callback->OnGetBondedDevices(status, devices_s16); }); } void BluetoothBinderServer::OnGetRemoteDeviceProperties( bluetooth::Adapter* adapter, int status, const std::string& device_address, const bluetooth::RemoteDeviceProps& properties) { CHECK_EQ(adapter, adapter_); VLOG(2) << "Received " << __func__ << " " << "status: " << status << ", device_address: " << device_address; android::String16 addr_s16(device_address.c_str(), device_address.size()); auto binder_props = android::bluetooth::BluetoothRemoteDeviceProps(properties); callbacks_.ForEach( [status, &addr_s16, &binder_props](IBluetoothCallback* callback) { callback->OnGetRemoteDeviceProperties(status, addr_s16, binder_props); }); } void BluetoothBinderServer::OnDeviceFound( bluetooth::Adapter* adapter, const bluetooth::RemoteDeviceProps& properties) { CHECK_EQ(adapter, adapter_); VLOG(2) << "Received " << __func__ << " "; auto binder_props = android::bluetooth::BluetoothRemoteDeviceProps(properties); callbacks_.ForEach([&binder_props](IBluetoothCallback* callback) { callback->OnDeviceFound(binder_props); }); } } // namespace binder } // namespace ipc