OSDN Git Service

f49d909d9faa3f3fbabdacb3875466f59c365941
[android-x86/system-bt.git] / service / ipc / binder / bluetooth_low_energy_binder_server.cpp
1 //
2 //  Copyright (C) 2015 Google, Inc.
3 //
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:
7 //
8 //  http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 //
16
17 #include "service/ipc/binder/bluetooth_low_energy_binder_server.h"
18
19 #include <base/logging.h>
20
21 #include "service/adapter.h"
22
23 namespace ipc {
24 namespace binder {
25
26 namespace {
27 const int kInvalidInstanceId = -1;
28 }  // namespace
29
30 BluetoothLowEnergyBinderServer::BluetoothLowEnergyBinderServer(
31     bluetooth::Adapter* adapter) : adapter_(adapter) {
32   CHECK(adapter_);
33 }
34
35 BluetoothLowEnergyBinderServer::~BluetoothLowEnergyBinderServer() {
36 }
37
38 bool BluetoothLowEnergyBinderServer::RegisterClient(
39     const android::sp<IBluetoothLowEnergyCallback>& callback) {
40   VLOG(2) << __func__;
41   bluetooth::LowEnergyClientFactory* ble_factory =
42       adapter_->GetLowEnergyClientFactory();
43
44   return RegisterInstanceBase(callback, ble_factory);
45 }
46
47 void BluetoothLowEnergyBinderServer::UnregisterClient(int client_id) {
48   VLOG(2) << __func__;
49   UnregisterInstanceBase(client_id);
50 }
51
52 void BluetoothLowEnergyBinderServer::UnregisterAll() {
53   VLOG(2) << __func__;
54   UnregisterAllBase();
55 }
56
57 bool BluetoothLowEnergyBinderServer::Connect(int client_id,
58                                              const char* address,
59                                              bool is_direct) {
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());
64
65   auto client = GetLEClient(client_id);
66   if (!client) {
67     LOG(ERROR) << "Unknown client_id: " << client_id;
68     return false;
69   }
70
71   return client->Connect(std::string(address), is_direct);
72 }
73
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());
79
80   auto client = GetLEClient(client_id);
81   if (!client) {
82     LOG(ERROR) << "Unknown client_id: " << client_id;
83     return false;
84   }
85
86   return client->Disconnect(std::string(address));
87 }
88
89 bool BluetoothLowEnergyBinderServer::StartScan(
90     int client_id,
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());
95
96   auto client = GetLEClient(client_id);
97   if (!client) {
98     LOG(ERROR) << "Unknown client_id: " << client_id;
99     return false;
100   }
101
102   return client->StartScan(settings, filters);
103 }
104
105 bool BluetoothLowEnergyBinderServer::StopScan(int client_id) {
106   VLOG(2) << __func__ << " client_id: " << client_id;
107   std::lock_guard<std::mutex> lock(*maps_lock());
108
109   auto client = GetLEClient(client_id);
110   if (!client) {
111     LOG(ERROR) << "Unknown client_id: " << client_id;
112     return false;
113   }
114
115   return client->StopScan();
116 }
117
118 bool BluetoothLowEnergyBinderServer::StartMultiAdvertising(
119     int client_id,
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());
125
126   auto client = GetLEClient(client_id);
127   if (!client) {
128     LOG(ERROR) << "Unknown client_id: " << client_id;
129     return false;
130   }
131
132   // Create a weak pointer and pass that to the callback to prevent a potential
133   // use after free.
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";
140       return;
141     }
142
143     std::lock_guard<std::mutex> lock(*maps_lock());
144
145     auto cb = GetLECallback(client_id);
146     if (!cb.get()) {
147       VLOG(1) << "Client was removed before callback: " << client_id;
148       return;
149     }
150
151     cb->OnMultiAdvertiseCallback(status, true /* is_start */, settings_copy);
152   };
153
154   if (!client->StartAdvertising(
155       settings, advertise_data, scan_response, callback)) {
156     LOG(ERROR) << "Failed to initiate call to start advertising";
157     return false;
158   }
159
160   return true;
161 }
162
163 bool BluetoothLowEnergyBinderServer::StopMultiAdvertising(int client_id) {
164   VLOG(2) << __func__;
165   std::lock_guard<std::mutex> lock(*maps_lock());
166
167   auto client = GetLEClient(client_id);
168   if (!client) {
169     LOG(ERROR) << "Unknown client_id: " << client_id;
170     return false;
171   }
172
173   // Create a weak pointer and pass that to the callback to prevent a potential
174   // use after free.
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";
181       return;
182     }
183
184     auto cb = GetLECallback(client_id);
185     if (!cb.get()) {
186       VLOG(2) << "Client was unregistered - client_id: " << client_id;
187       return;
188     }
189
190     std::lock_guard<std::mutex> lock(*maps_lock());
191
192     cb->OnMultiAdvertiseCallback(status, false /* is_start */, settings_copy);
193   };
194
195   if (!client->StopAdvertising(callback)) {
196     LOG(ERROR) << "Failed to initiate call to start advertising";
197     return false;
198   }
199
200   return true;
201 }
202
203 void BluetoothLowEnergyBinderServer::OnConnectionState(
204       bluetooth::LowEnergyClient* client, int status,
205       const char* address, bool connected) {
206   VLOG(2) << __func__ << " address: " << address << " connected: " << connected;
207
208   int client_id = client->GetInstanceId();
209   auto cb = GetLECallback(client->GetInstanceId());
210   if (!cb.get()) {
211     VLOG(2) << "Client was unregistered - client_id: " << client_id;
212     return;
213   }
214
215   cb->OnConnectionState(status, client_id, address, connected);
216 }
217
218 void BluetoothLowEnergyBinderServer::OnScanResult(
219     bluetooth::LowEnergyClient* client,
220     const bluetooth::ScanResult& result) {
221   VLOG(2) << __func__;
222   std::lock_guard<std::mutex> lock(*maps_lock());
223
224   int client_id = client->GetInstanceId();
225   auto cb = GetLECallback(client->GetInstanceId());
226   if (!cb.get()) {
227     VLOG(2) << "Client was unregistered - client_id: " << client_id;
228     return;
229   }
230
231   cb->OnScanResult(result);
232 }
233
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()));
239 }
240
241 std::shared_ptr<bluetooth::LowEnergyClient>
242 BluetoothLowEnergyBinderServer::GetLEClient(int client_id) {
243   return std::static_pointer_cast<bluetooth::LowEnergyClient>(
244       GetInstance(client_id));
245 }
246
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);
255
256   android::sp<IBluetoothLowEnergyCallback> cb(
257       static_cast<IBluetoothLowEnergyCallback*>(callback.get()));
258   cb->OnClientRegistered(
259       status,
260       (status == bluetooth::BLE_STATUS_SUCCESS) ?
261           instance->GetInstanceId() : kInvalidInstanceId);
262 }
263
264 }  // namespace binder
265 }  // namespace ipc