blob: a992c32d30933991a1f45a30ed364a6e556753ac [file] [log] [blame]
//
// Copyright (C) 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_le_advertiser_binder_server.h"
#include <base/logging.h>
#include "service/adapter.h"
using android::String8;
using android::String16;
using android::binder::Status;
namespace ipc {
namespace binder {
namespace {
const int kInvalidInstanceId = -1;
} // namespace
BluetoothLeAdvertiserBinderServer::BluetoothLeAdvertiserBinderServer(
bluetooth::Adapter* adapter)
: adapter_(adapter) {
CHECK(adapter_);
}
BluetoothLeAdvertiserBinderServer::~BluetoothLeAdvertiserBinderServer() {}
Status BluetoothLeAdvertiserBinderServer::RegisterAdvertiser(
const android::sp<IBluetoothLeAdvertiserCallback>& callback,
bool* _aidl_return) {
VLOG(2) << __func__;
bluetooth::LowEnergyAdvertiserFactory* adv_factory =
adapter_->GetLeAdvertiserFactory();
*_aidl_return = RegisterInstanceBase(callback, adv_factory);
return Status::ok();
}
Status BluetoothLeAdvertiserBinderServer::UnregisterAdvertiser(int advertiser_id) {
VLOG(2) << __func__;
UnregisterInstanceBase(advertiser_id);
return Status::ok();
}
Status BluetoothLeAdvertiserBinderServer::UnregisterAll() {
VLOG(2) << __func__;
UnregisterAllBase();
return Status::ok();
}
Status BluetoothLeAdvertiserBinderServer::StartMultiAdvertising(
int advertiser_id, const android::bluetooth::AdvertiseData& advertise_data,
const android::bluetooth::AdvertiseData& scan_response,
const android::bluetooth::AdvertiseSettings& settings, bool* _aidl_return) {
VLOG(2) << __func__ << " advertiser_id: " << advertiser_id;
std::lock_guard<std::mutex> lock(*maps_lock());
auto advertiser = GetLEAdvertiser(advertiser_id);
if (!advertiser) {
LOG(ERROR) << "Unknown advertiser_id: " << advertiser_id;
*_aidl_return = false;
return Status::ok();
}
// Create a weak pointer and pass that to the callback to prevent a potential
// use after free.
android::wp<BluetoothLeAdvertiserBinderServer> weak_ptr_to_this(this);
auto settings_copy = settings;
auto callback = [=](bluetooth::BLEStatus status) {
auto sp_to_this = weak_ptr_to_this.promote();
if (!sp_to_this.get()) {
VLOG(2) << "BluetoothLeAdvertiserBinderServer was deleted";
return;
}
std::lock_guard<std::mutex> lock(*maps_lock());
auto cb = GetLECallback(advertiser_id);
if (!cb.get()) {
VLOG(1) << "Advertiser was removed before callback: " << advertiser_id;
return;
}
cb->OnMultiAdvertiseCallback(status, true /* is_start */, settings_copy);
};
if (!advertiser->StartAdvertising(settings, advertise_data, scan_response,
callback)) {
LOG(ERROR) << "Failed to initiate call to start advertising";
*_aidl_return = false;
return Status::ok();
}
*_aidl_return = true;
return Status::ok();
}
Status BluetoothLeAdvertiserBinderServer::StopMultiAdvertising(
int advertiser_id, bool* _aidl_return) {
VLOG(2) << __func__;
std::lock_guard<std::mutex> lock(*maps_lock());
auto advertiser = GetLEAdvertiser(advertiser_id);
if (!advertiser) {
LOG(ERROR) << "Unknown advertiser_id: " << advertiser_id;
*_aidl_return = false;
return Status::ok();
}
// Create a weak pointer and pass that to the callback to prevent a potential
// use after free.
android::wp<BluetoothLeAdvertiserBinderServer> weak_ptr_to_this(this);
auto settings_copy = advertiser->advertise_settings();
auto callback = [=](bluetooth::BLEStatus status) {
auto sp_to_this = weak_ptr_to_this.promote();
if (!sp_to_this.get()) {
VLOG(2) << "BluetoothLeAdvertiserBinderServer was deleted";
return;
}
auto cb = GetLECallback(advertiser_id);
if (!cb.get()) {
VLOG(2) << "Advertiser was unregistered - advertiser_id: " << advertiser_id;
return;
}
std::lock_guard<std::mutex> lock(*maps_lock());
cb->OnMultiAdvertiseCallback(status, false /* is_start */, settings_copy);
};
if (!advertiser->StopAdvertising(callback)) {
LOG(ERROR) << "Failed to initiate call to start advertising";
*_aidl_return = false;
return Status::ok();
}
*_aidl_return = true;
return Status::ok();
}
android::sp<IBluetoothLeAdvertiserCallback>
BluetoothLeAdvertiserBinderServer::GetLECallback(int advertiser_id) {
auto cb = GetCallback(advertiser_id);
return android::sp<IBluetoothLeAdvertiserCallback>(
static_cast<IBluetoothLeAdvertiserCallback*>(cb.get()));
}
std::shared_ptr<bluetooth::LowEnergyAdvertiser>
BluetoothLeAdvertiserBinderServer::GetLEAdvertiser(int advertiser_id) {
return std::static_pointer_cast<bluetooth::LowEnergyAdvertiser>(
GetInstance(advertiser_id));
}
void BluetoothLeAdvertiserBinderServer::OnRegisterInstanceImpl(
bluetooth::BLEStatus status, android::sp<IInterface> callback,
bluetooth::BluetoothInstance* instance) {
VLOG(1) << __func__ << " status: " << status;
android::sp<IBluetoothLeAdvertiserCallback> cb(
static_cast<IBluetoothLeAdvertiserCallback*>(callback.get()));
cb->OnAdvertiserRegistered(status, (status == bluetooth::BLE_STATUS_SUCCESS)
? instance->GetInstanceId()
: kInvalidInstanceId);
}
} // namespace binder
} // namespace ipc