2 // Copyright (C) 2015 Google, Inc.
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at:
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 #include "service/ipc/binder/bluetooth_low_energy_binder_server.h"
19 #include <base/logging.h>
21 #include "service/adapter.h"
27 const int kInvalidInstanceId = -1;
30 BluetoothLowEnergyBinderServer::BluetoothLowEnergyBinderServer(
31 bluetooth::Adapter* adapter) : adapter_(adapter) {
35 BluetoothLowEnergyBinderServer::~BluetoothLowEnergyBinderServer() {
38 bool BluetoothLowEnergyBinderServer::RegisterClient(
39 const android::sp<IBluetoothLowEnergyCallback>& callback) {
41 bluetooth::LowEnergyClientFactory* ble_factory =
42 adapter_->GetLowEnergyClientFactory();
44 return RegisterInstanceBase(callback, ble_factory);
47 void BluetoothLowEnergyBinderServer::UnregisterClient(int client_id) {
49 UnregisterInstanceBase(client_id);
52 void BluetoothLowEnergyBinderServer::UnregisterAll() {
57 bool BluetoothLowEnergyBinderServer::Connect(int client_id,
60 VLOG(2) << __func__ << " client_id: " << client_id
61 << " address: " << address
62 << " is_direct: " << is_direct;
63 std::lock_guard<std::mutex> lock(*maps_lock());
65 auto client = GetLEClient(client_id);
67 LOG(ERROR) << "Unknown client_id: " << client_id;
71 return client->Connect(std::string(address), is_direct);
74 bool BluetoothLowEnergyBinderServer::Disconnect(int client_id,
75 const char* address) {
76 VLOG(2) << __func__ << " client_id: " << client_id
77 << " address: " << address;
78 std::lock_guard<std::mutex> lock(*maps_lock());
80 auto client = GetLEClient(client_id);
82 LOG(ERROR) << "Unknown client_id: " << client_id;
86 return client->Disconnect(std::string(address));
89 bool BluetoothLowEnergyBinderServer::StartScan(
91 const bluetooth::ScanSettings& settings,
92 const std::vector<bluetooth::ScanFilter>& filters) {
93 VLOG(2) << __func__ << " client_id: " << client_id;
94 std::lock_guard<std::mutex> lock(*maps_lock());
96 auto client = GetLEClient(client_id);
98 LOG(ERROR) << "Unknown client_id: " << client_id;
102 return client->StartScan(settings, filters);
105 bool BluetoothLowEnergyBinderServer::StopScan(int client_id) {
106 VLOG(2) << __func__ << " client_id: " << client_id;
107 std::lock_guard<std::mutex> lock(*maps_lock());
109 auto client = GetLEClient(client_id);
111 LOG(ERROR) << "Unknown client_id: " << client_id;
115 return client->StopScan();
118 bool BluetoothLowEnergyBinderServer::StartMultiAdvertising(
120 const bluetooth::AdvertiseData& advertise_data,
121 const bluetooth::AdvertiseData& scan_response,
122 const bluetooth::AdvertiseSettings& settings) {
123 VLOG(2) << __func__ << " client_id: " << client_id;
124 std::lock_guard<std::mutex> lock(*maps_lock());
126 auto client = GetLEClient(client_id);
128 LOG(ERROR) << "Unknown client_id: " << client_id;
132 // Create a weak pointer and pass that to the callback to prevent a potential
134 android::wp<BluetoothLowEnergyBinderServer> weak_ptr_to_this(this);
135 auto settings_copy = settings;
136 auto callback = [=](bluetooth::BLEStatus status) {
137 auto sp_to_this = weak_ptr_to_this.promote();
138 if (!sp_to_this.get()) {
139 VLOG(2) << "BluetoothLowEnergyBinderServer was deleted";
143 std::lock_guard<std::mutex> lock(*maps_lock());
145 auto cb = GetLECallback(client_id);
147 VLOG(1) << "Client was removed before callback: " << client_id;
151 cb->OnMultiAdvertiseCallback(status, true /* is_start */, settings_copy);
154 if (!client->StartAdvertising(
155 settings, advertise_data, scan_response, callback)) {
156 LOG(ERROR) << "Failed to initiate call to start advertising";
163 bool BluetoothLowEnergyBinderServer::StopMultiAdvertising(int client_id) {
165 std::lock_guard<std::mutex> lock(*maps_lock());
167 auto client = GetLEClient(client_id);
169 LOG(ERROR) << "Unknown client_id: " << client_id;
173 // Create a weak pointer and pass that to the callback to prevent a potential
175 android::wp<BluetoothLowEnergyBinderServer> weak_ptr_to_this(this);
176 auto settings_copy = client->advertise_settings();
177 auto callback = [=](bluetooth::BLEStatus status) {
178 auto sp_to_this = weak_ptr_to_this.promote();
179 if (!sp_to_this.get()) {
180 VLOG(2) << "BluetoothLowEnergyBinderServer was deleted";
184 auto cb = GetLECallback(client_id);
186 VLOG(2) << "Client was unregistered - client_id: " << client_id;
190 std::lock_guard<std::mutex> lock(*maps_lock());
192 cb->OnMultiAdvertiseCallback(status, false /* is_start */, settings_copy);
195 if (!client->StopAdvertising(callback)) {
196 LOG(ERROR) << "Failed to initiate call to start advertising";
203 void BluetoothLowEnergyBinderServer::OnConnectionState(
204 bluetooth::LowEnergyClient* client, int status,
205 const char* address, bool connected) {
206 VLOG(2) << __func__ << " address: " << address << " connected: " << connected;
208 int client_id = client->GetInstanceId();
209 auto cb = GetLECallback(client->GetInstanceId());
211 VLOG(2) << "Client was unregistered - client_id: " << client_id;
215 cb->OnConnectionState(status, client_id, address, connected);
218 void BluetoothLowEnergyBinderServer::OnScanResult(
219 bluetooth::LowEnergyClient* client,
220 const bluetooth::ScanResult& result) {
222 std::lock_guard<std::mutex> lock(*maps_lock());
224 int client_id = client->GetInstanceId();
225 auto cb = GetLECallback(client->GetInstanceId());
227 VLOG(2) << "Client was unregistered - client_id: " << client_id;
231 cb->OnScanResult(result);
234 android::sp<IBluetoothLowEnergyCallback>
235 BluetoothLowEnergyBinderServer::GetLECallback(int client_id) {
236 auto cb = GetCallback(client_id);
237 return android::sp<IBluetoothLowEnergyCallback>(
238 static_cast<IBluetoothLowEnergyCallback*>(cb.get()));
241 std::shared_ptr<bluetooth::LowEnergyClient>
242 BluetoothLowEnergyBinderServer::GetLEClient(int client_id) {
243 return std::static_pointer_cast<bluetooth::LowEnergyClient>(
244 GetInstance(client_id));
247 void BluetoothLowEnergyBinderServer::OnRegisterInstanceImpl(
248 bluetooth::BLEStatus status,
249 android::sp<IInterface> callback,
250 bluetooth::BluetoothInstance* instance) {
251 VLOG(1) << __func__ << " status: " << status;
252 bluetooth::LowEnergyClient* le_client =
253 static_cast<bluetooth::LowEnergyClient*>(instance);
254 le_client->SetDelegate(this);
256 android::sp<IBluetoothLowEnergyCallback> cb(
257 static_cast<IBluetoothLowEnergyCallback*>(callback.get()));
258 cb->OnClientRegistered(
260 (status == bluetooth::BLE_STATUS_SUCCESS) ?
261 instance->GetInstanceId() : kInvalidInstanceId);
264 } // namespace binder