You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
490 lines
16 KiB
490 lines
16 KiB
//
|
|
// 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 <base/logging.h>
|
|
|
|
#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<android::bluetooth::UUID>();
|
|
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<IBluetoothCallback>& 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<IBluetoothCallback>& 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<IBluetoothA2dpSink>* _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<IBluetoothA2dpSource>* _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<IBluetoothLowEnergy>* _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<IBluetoothLeAdvertiser>* _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<IBluetoothLeScanner>* _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<IBluetoothGattClient>* _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<IBluetoothGattServer>* _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<IBluetoothAvrcpControl>* _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<IBluetoothAvrcpTarget>* _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<android::String16>& 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<std::string>& bonded_devices) {
|
|
CHECK_EQ(adapter, adapter_);
|
|
VLOG(2) << "Received " << __func__;
|
|
std::vector<android::String16> 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
|