1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "device/bluetooth/bluez/bluetooth_adapter_bluez.h"
6 
7 #include <algorithm>
8 #include <cstdint>
9 #include <limits>
10 #include <memory>
11 #include <set>
12 #include <string>
13 #include <utility>
14 
15 #include "base/bind.h"
16 #include "base/callback_helpers.h"
17 #include "base/location.h"
18 #include "base/logging.h"
19 #include "base/memory/ptr_util.h"
20 #include "base/metrics/histogram_macros.h"
21 #include "base/single_thread_task_runner.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/threading/thread_task_runner_handle.h"
24 #include "base/time/time.h"
25 #include "build/build_config.h"
26 #include "build/chromeos_buildflags.h"
27 #include "components/device_event_log/device_event_log.h"
28 #include "device/bluetooth/bluetooth_common.h"
29 #include "device/bluetooth/bluetooth_device.h"
30 #include "device/bluetooth/bluetooth_discovery_session_outcome.h"
31 #include "device/bluetooth/bluetooth_socket_thread.h"
32 #include "device/bluetooth/bluez/bluetooth_adapter_profile_bluez.h"
33 #include "device/bluetooth/bluez/bluetooth_advertisement_bluez.h"
34 #include "device/bluetooth/bluez/bluetooth_device_bluez.h"
35 #include "device/bluetooth/bluez/bluetooth_gatt_service_bluez.h"
36 #include "device/bluetooth/bluez/bluetooth_local_gatt_characteristic_bluez.h"
37 #include "device/bluetooth/bluez/bluetooth_local_gatt_service_bluez.h"
38 #include "device/bluetooth/bluez/bluetooth_pairing_bluez.h"
39 #include "device/bluetooth/bluez/bluetooth_socket_bluez.h"
40 #include "device/bluetooth/dbus/bluetooth_adapter_client.h"
41 #include "device/bluetooth/dbus/bluetooth_agent_manager_client.h"
42 #include "device/bluetooth/dbus/bluetooth_agent_service_provider.h"
43 #include "device/bluetooth/dbus/bluetooth_battery_client.h"
44 #include "device/bluetooth/dbus/bluetooth_device_client.h"
45 #include "device/bluetooth/dbus/bluetooth_gatt_application_service_provider.h"
46 #include "device/bluetooth/dbus/bluetooth_gatt_manager_client.h"
47 #include "device/bluetooth/dbus/bluetooth_input_client.h"
48 #include "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h"
49 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
50 #include "device/bluetooth/public/cpp/bluetooth_address.h"
51 #include "device/bluetooth/public/cpp/bluetooth_uuid.h"
52 #include "third_party/cros_system_api/dbus/service_constants.h"
53 
54 #if BUILDFLAG(IS_ASH)
55 #include "chromeos/constants/devicetype.h"
56 #include "device/bluetooth/bluetooth_adapter_factory.h"
57 #include "device/bluetooth/chromeos/bluetooth_utils.h"
58 #endif
59 
60 using device::BluetoothAdapter;
61 using device::BluetoothDevice;
62 using UUIDSet = device::BluetoothDevice::UUIDSet;
63 using device::BluetoothDiscoveryFilter;
64 using device::BluetoothSocket;
65 using device::BluetoothUUID;
66 using device::UMABluetoothDiscoverySessionOutcome;
67 
68 namespace {
69 
70 // The agent path is relatively meaningless since BlueZ only permits one to
71 // exist per D-Bus connection, it just has to be unique within Chromium.
72 const char kAgentPath[] = "/org/chromium/bluetooth_agent";
73 const char kGattApplicationObjectPath[] = "/gatt_application";
74 
OnUnregisterAgentError(const std::string & error_name,const std::string & error_message)75 void OnUnregisterAgentError(const std::string& error_name,
76                             const std::string& error_message) {
77   // It's okay if the agent didn't exist, it means we never saw an adapter.
78   if (error_name == bluetooth_agent_manager::kErrorDoesNotExist)
79     return;
80 
81   BLUETOOTH_LOG(ERROR) << "Failed to unregister pairing agent: " << error_name
82                        << ": " << error_message;
83 }
84 
TranslateDiscoveryErrorToUMA(const std::string & error_name)85 UMABluetoothDiscoverySessionOutcome TranslateDiscoveryErrorToUMA(
86     const std::string& error_name) {
87   if (error_name == bluez::BluetoothAdapterClient::kUnknownAdapterError) {
88     return UMABluetoothDiscoverySessionOutcome::BLUEZ_DBUS_UNKNOWN_ADAPTER;
89   } else if (error_name == bluez::BluetoothAdapterClient::kNoResponseError) {
90     return UMABluetoothDiscoverySessionOutcome::BLUEZ_DBUS_NO_RESPONSE;
91   } else if (error_name == bluetooth_device::kErrorInProgress) {
92     return UMABluetoothDiscoverySessionOutcome::BLUEZ_DBUS_IN_PROGRESS;
93   } else if (error_name == bluetooth_device::kErrorNotReady) {
94     return UMABluetoothDiscoverySessionOutcome::BLUEZ_DBUS_NOT_READY;
95   } else if (error_name == bluetooth_device::kErrorNotSupported) {
96     return UMABluetoothDiscoverySessionOutcome::BLUEZ_DBUS_UNSUPPORTED_DEVICE;
97   } else if (error_name == bluetooth_device::kErrorFailed) {
98     return UMABluetoothDiscoverySessionOutcome::FAILED;
99   } else {
100     BLUETOOTH_LOG(ERROR) << "Unrecognized DBus error " << error_name;
101     return UMABluetoothDiscoverySessionOutcome::UNKNOWN;
102   }
103 }
104 
105 #if BUILDFLAG(IS_ASH)
ConvertServiceDataMap(const base::flat_map<std::string,std::vector<uint8_t>> & input)106 device::BluetoothDevice::ServiceDataMap ConvertServiceDataMap(
107     const base::flat_map<std::string, std::vector<uint8_t>>& input) {
108   device::BluetoothDevice::ServiceDataMap output;
109   for (auto& i : input) {
110     output[BluetoothUUID(i.first)] = i.second;
111   }
112 
113   return output;
114 }
115 
ConvertManufacturerDataMap(const base::flat_map<uint16_t,std::vector<uint8_t>> & input)116 device::BluetoothDevice::ManufacturerDataMap ConvertManufacturerDataMap(
117     const base::flat_map<uint16_t, std::vector<uint8_t>>& input) {
118   return device::BluetoothDevice::ManufacturerDataMap(input.begin(),
119                                                       input.end());
120 }
121 #endif  // BUILDFLAG(IS_ASH)
122 
123 }  // namespace
124 
125 namespace device {
126 
127 // static
CreateAdapter()128 scoped_refptr<BluetoothAdapter> BluetoothAdapter::CreateAdapter() {
129   return bluez::BluetoothAdapterBlueZ::CreateAdapter();
130 }
131 
132 }  // namespace device
133 
134 namespace bluez {
135 
136 namespace {
137 
OnRegistrationErrorCallback(device::BluetoothGattService::ErrorCallback error_callback,bool is_register_callback,const std::string & error_name,const std::string & error_message)138 void OnRegistrationErrorCallback(
139     device::BluetoothGattService::ErrorCallback error_callback,
140     bool is_register_callback,
141     const std::string& error_name,
142     const std::string& error_message) {
143   if (is_register_callback) {
144     BLUETOOTH_LOG(ERROR) << "Failed to Register service: " << error_name << ", "
145                          << error_message;
146   } else {
147     BLUETOOTH_LOG(ERROR) << "Failed to Unregister service: " << error_name
148                          << ", " << error_message;
149   }
150   std::move(error_callback)
151       .Run(BluetoothGattServiceBlueZ::DBusErrorToServiceError(error_name));
152 }
153 
SetIntervalErrorCallbackConnector(device::BluetoothAdapter::AdvertisementErrorCallback error_callback,const std::string & error_name,const std::string & error_message)154 void SetIntervalErrorCallbackConnector(
155     device::BluetoothAdapter::AdvertisementErrorCallback error_callback,
156     const std::string& error_name,
157     const std::string& error_message) {
158   BLUETOOTH_LOG(ERROR) << "Error while registering advertisement. error_name = "
159                        << error_name << ", error_message = " << error_message;
160 
161   device::BluetoothAdvertisement::ErrorCode code = device::
162       BluetoothAdvertisement::ErrorCode::INVALID_ADVERTISEMENT_ERROR_CODE;
163   if (error_name == bluetooth_advertising_manager::kErrorInvalidArguments) {
164     code = device::BluetoothAdvertisement::ErrorCode::
165         ERROR_INVALID_ADVERTISEMENT_INTERVAL;
166   }
167   std::move(error_callback).Run(code);
168 }
169 
ResetAdvertisingErrorCallbackConnector(device::BluetoothAdapter::AdvertisementErrorCallback error_callback,const std::string & error_name,const std::string & error_message)170 void ResetAdvertisingErrorCallbackConnector(
171     device::BluetoothAdapter::AdvertisementErrorCallback error_callback,
172     const std::string& error_name,
173     const std::string& error_message) {
174   BLUETOOTH_LOG(ERROR) << "Error while resetting advertising. error_name = "
175                        << error_name << ", error_message = " << error_message;
176 
177   std::move(error_callback)
178       .Run(device::BluetoothAdvertisement::ErrorCode::ERROR_RESET_ADVERTISING);
179 }
180 
181 }  // namespace
182 
183 // static
CreateAdapter()184 scoped_refptr<BluetoothAdapterBlueZ> BluetoothAdapterBlueZ::CreateAdapter() {
185   return base::WrapRefCounted(new BluetoothAdapterBlueZ());
186 }
187 
Initialize(base::OnceClosure callback)188 void BluetoothAdapterBlueZ::Initialize(base::OnceClosure callback) {
189   init_callback_ = std::move(callback);
190 
191   // Can't initialize the adapter until DBus clients are ready.
192   if (bluez::BluezDBusManager::Get()->IsObjectManagerSupportKnown()) {
193     base::ThreadTaskRunnerHandle::Get()->PostTask(
194         FROM_HERE, base::BindOnce(&BluetoothAdapterBlueZ::Init,
195                                   weak_ptr_factory_.GetWeakPtr()));
196     return;
197   }
198   bluez::BluezDBusManager::Get()->CallWhenObjectManagerSupportIsKnown(
199       base::BindOnce(&BluetoothAdapterBlueZ::Init,
200                      weak_ptr_factory_.GetWeakPtr()));
201 }
202 
Shutdown()203 void BluetoothAdapterBlueZ::Shutdown() {
204   if (dbus_is_shutdown_)
205     return;
206 
207   BLUETOOTH_LOG(EVENT) << "BluetoothAdapterBlueZ::Shutdown";
208 
209   DCHECK(bluez::BluezDBusManager::IsInitialized())
210       << "Call BluetoothAdapterFactory::Shutdown() before "
211          "BluezDBusManager::Shutdown().";
212 
213   // Since we don't initialize anything if Object Manager is not supported,
214   // no need to do any clean up.
215   if (!bluez::BluezDBusManager::Get()->IsObjectManagerSupported()) {
216     dbus_is_shutdown_ = true;
217     return;
218   }
219 
220   if (IsPresent())
221     RemoveAdapter();  // Also deletes devices_.
222   DCHECK(devices_.empty());
223 
224   // profiles_ must be empty because all BluetoothSockets have been notified
225   // that this adapter is disappearing.
226   DCHECK(profiles_.empty());
227 
228   // Some profiles may have been released but not yet removed; it is safe to
229   // delete them.
230   for (auto& it : released_profiles_)
231     delete it.second;
232   released_profiles_.clear();
233 
234   for (auto& it : profile_queues_)
235     delete it.second;
236   profile_queues_.clear();
237 
238   // This may call unregister on advertisements that have already been
239   // unregistered but that's fine. The advertisement object keeps a track of
240   // the fact that it has been already unregistered and will call our empty
241   // error callback with an "Already unregistered" error, which we'll ignore.
242   for (auto& it : advertisements_) {
243     it->Unregister(base::DoNothing(), base::DoNothing());
244   }
245   advertisements_.clear();
246 
247   bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->RemoveObserver(
248       this);
249   bluez::BluezDBusManager::Get()->GetBluetoothBatteryClient()->RemoveObserver(
250       this);
251   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(
252       this);
253   bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->RemoveObserver(
254       this);
255   bluez::BluezDBusManager::Get()
256       ->GetBluetoothAgentManagerClient()
257       ->RemoveObserver(this);
258 
259   BLUETOOTH_LOG(EVENT) << "Unregistering pairing agent";
260   bluez::BluezDBusManager::Get()
261       ->GetBluetoothAgentManagerClient()
262       ->UnregisterAgent(dbus::ObjectPath(kAgentPath), base::DoNothing(),
263                         base::BindOnce(&OnUnregisterAgentError));
264 
265   agent_.reset();
266 
267   dbus_is_shutdown_ = true;
268 }
269 
BluetoothAdapterBlueZ()270 BluetoothAdapterBlueZ::BluetoothAdapterBlueZ()
271     : initialized_(false), dbus_is_shutdown_(false) {
272   ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
273   socket_thread_ = device::BluetoothSocketThread::Get();
274 }
275 
Init()276 void BluetoothAdapterBlueZ::Init() {
277   // We may have been shutdown already, in which case do nothing. If the
278   // platform doesn't support Object Manager then Bluez 5 is probably not
279   // present. In this case we just return without initializing anything.
280   if (dbus_is_shutdown_ ||
281       !bluez::BluezDBusManager::Get()->IsObjectManagerSupported()) {
282     initialized_ = true;
283     std::move(init_callback_).Run();
284     return;
285   }
286 
287   bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->AddObserver(
288       this);
289   bluez::BluezDBusManager::Get()->GetBluetoothBatteryClient()->AddObserver(
290       this);
291   bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->AddObserver(this);
292   bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->AddObserver(this);
293   bluez::BluezDBusManager::Get()->GetBluetoothAgentManagerClient()->AddObserver(
294       this);
295 
296   // Register the pairing agent.
297   dbus::Bus* system_bus = bluez::BluezDBusManager::Get()->GetSystemBus();
298   agent_.reset(bluez::BluetoothAgentServiceProvider::Create(
299       system_bus, dbus::ObjectPath(kAgentPath), this));
300   DCHECK(agent_.get());
301 
302   std::vector<dbus::ObjectPath> object_paths = bluez::BluezDBusManager::Get()
303                                                    ->GetBluetoothAdapterClient()
304                                                    ->GetAdapters();
305 
306   BLUETOOTH_LOG(EVENT) << "BlueZ Adapter Initialized.";
307   if (!object_paths.empty()) {
308     BLUETOOTH_LOG(EVENT) << "BlueZ Adapters available: " << object_paths.size();
309     SetAdapter(object_paths[0]);
310   }
311   initialized_ = true;
312   std::move(init_callback_).Run();
313 }
314 
~BluetoothAdapterBlueZ()315 BluetoothAdapterBlueZ::~BluetoothAdapterBlueZ() {
316   Shutdown();
317 }
318 
GetAddress() const319 std::string BluetoothAdapterBlueZ::GetAddress() const {
320   if (!IsPresent())
321     return std::string();
322 
323   bluez::BluetoothAdapterClient::Properties* properties =
324       bluez::BluezDBusManager::Get()
325           ->GetBluetoothAdapterClient()
326           ->GetProperties(object_path_);
327   DCHECK(properties);
328 
329   return device::CanonicalizeBluetoothAddress(properties->address.value());
330 }
331 
GetName() const332 std::string BluetoothAdapterBlueZ::GetName() const {
333   if (!IsPresent())
334     return std::string();
335 
336   bluez::BluetoothAdapterClient::Properties* properties =
337       bluez::BluezDBusManager::Get()
338           ->GetBluetoothAdapterClient()
339           ->GetProperties(object_path_);
340   DCHECK(properties);
341 
342   return properties->alias.value();
343 }
344 
GetSystemName() const345 std::string BluetoothAdapterBlueZ::GetSystemName() const {
346   if (!IsPresent())
347     return std::string();
348 
349   bluez::BluetoothAdapterClient::Properties* properties =
350       bluez::BluezDBusManager::Get()
351           ->GetBluetoothAdapterClient()
352           ->GetProperties(object_path_);
353   DCHECK(properties);
354 
355   return properties ? properties->name.value() : std::string();
356 }
357 
SetName(const std::string & name,base::OnceClosure callback,ErrorCallback error_callback)358 void BluetoothAdapterBlueZ::SetName(const std::string& name,
359                                     base::OnceClosure callback,
360                                     ErrorCallback error_callback) {
361   if (!IsPresent()) {
362     std::move(error_callback).Run();
363     return;
364   }
365 
366   bluez::BluezDBusManager::Get()
367       ->GetBluetoothAdapterClient()
368       ->GetProperties(object_path_)
369       ->alias.Set(name, base::BindOnce(
370                             &BluetoothAdapterBlueZ::OnPropertyChangeCompleted,
371                             weak_ptr_factory_.GetWeakPtr(), std::move(callback),
372                             std::move(error_callback)));
373 }
374 
IsInitialized() const375 bool BluetoothAdapterBlueZ::IsInitialized() const {
376   return initialized_;
377 }
378 
IsPresent() const379 bool BluetoothAdapterBlueZ::IsPresent() const {
380   return !dbus_is_shutdown_ && !object_path_.value().empty();
381 }
382 
IsPowered() const383 bool BluetoothAdapterBlueZ::IsPowered() const {
384   if (!IsPresent())
385     return false;
386 
387   bluez::BluetoothAdapterClient::Properties* properties =
388       bluez::BluezDBusManager::Get()
389           ->GetBluetoothAdapterClient()
390           ->GetProperties(object_path_);
391 
392   return properties->powered.value();
393 }
394 
SetPowered(bool powered,base::OnceClosure callback,ErrorCallback error_callback)395 void BluetoothAdapterBlueZ::SetPowered(bool powered,
396                                        base::OnceClosure callback,
397                                        ErrorCallback error_callback) {
398   if (!IsPresent()) {
399     BLUETOOTH_LOG(ERROR) << "SetPowered: " << powered << ". Not Present!";
400     std::move(error_callback).Run();
401     return;
402   }
403 
404   BLUETOOTH_LOG(EVENT) << "SetPowered: " << powered;
405 
406   bluez::BluezDBusManager::Get()
407       ->GetBluetoothAdapterClient()
408       ->GetProperties(object_path_)
409       ->powered.Set(
410           powered,
411           base::BindOnce(&BluetoothAdapterBlueZ::OnPropertyChangeCompleted,
412                          weak_ptr_factory_.GetWeakPtr(), std::move(callback),
413                          std::move(error_callback)));
414 }
415 
IsDiscoverable() const416 bool BluetoothAdapterBlueZ::IsDiscoverable() const {
417   if (!IsPresent())
418     return false;
419 
420   bluez::BluetoothAdapterClient::Properties* properties =
421       bluez::BluezDBusManager::Get()
422           ->GetBluetoothAdapterClient()
423           ->GetProperties(object_path_);
424 
425   return properties->discoverable.value();
426 }
427 
SetDiscoverable(bool discoverable,base::OnceClosure callback,ErrorCallback error_callback)428 void BluetoothAdapterBlueZ::SetDiscoverable(bool discoverable,
429                                             base::OnceClosure callback,
430                                             ErrorCallback error_callback) {
431   if (!IsPresent()) {
432     std::move(error_callback).Run();
433     return;
434   }
435 
436   BLUETOOTH_LOG(EVENT) << "SetDiscoverable: " << discoverable;
437 
438   bluez::BluezDBusManager::Get()
439       ->GetBluetoothAdapterClient()
440       ->GetProperties(object_path_)
441       ->discoverable.Set(
442           discoverable,
443           base::BindOnce(&BluetoothAdapterBlueZ::OnSetDiscoverable,
444                          weak_ptr_factory_.GetWeakPtr(), std::move(callback),
445                          std::move(error_callback)));
446 }
447 
GetDiscoverableTimeout() const448 uint32_t BluetoothAdapterBlueZ::GetDiscoverableTimeout() const {
449   if (!IsPresent())
450     return 0;
451 
452   bluez::BluetoothAdapterClient::Properties* properties =
453       bluez::BluezDBusManager::Get()
454           ->GetBluetoothAdapterClient()
455           ->GetProperties(object_path_);
456 
457   return properties->discoverable_timeout.value();
458 }
459 
IsDiscovering() const460 bool BluetoothAdapterBlueZ::IsDiscovering() const {
461   if (!IsPresent())
462     return false;
463 
464   return NumScanningDiscoverySessions() > 0;
465 }
466 
IsDiscoveringForTesting() const467 bool BluetoothAdapterBlueZ::IsDiscoveringForTesting() const {
468   if (!IsPresent())
469     return false;
470 
471   bluez::BluetoothAdapterClient::Properties* properties =
472       bluez::BluezDBusManager::Get()
473           ->GetBluetoothAdapterClient()
474           ->GetProperties(object_path_);
475   return properties->discovering.value();
476 }
477 
478 std::unordered_map<BluetoothDevice*, UUIDSet>
RetrieveGattConnectedDevicesWithDiscoveryFilter(const BluetoothDiscoveryFilter & discovery_filter)479 BluetoothAdapterBlueZ::RetrieveGattConnectedDevicesWithDiscoveryFilter(
480     const BluetoothDiscoveryFilter& discovery_filter) {
481   std::unordered_map<BluetoothDevice*, UUIDSet> connected_devices;
482 
483   std::set<BluetoothUUID> filter_uuids;
484   discovery_filter.GetUUIDs(filter_uuids);
485 
486   for (BluetoothDevice* device : GetDevices()) {
487     if (device->IsGattConnected() &&
488         (device->GetType() & device::BLUETOOTH_TRANSPORT_LE)) {
489       UUIDSet device_uuids = device->GetUUIDs();
490 
491       UUIDSet intersection;
492       for (const BluetoothUUID& uuid : filter_uuids) {
493         if (base::Contains(device_uuids, uuid)) {
494           intersection.insert(uuid);
495         }
496       }
497 
498       if (filter_uuids.empty() || !intersection.empty()) {
499         connected_devices[device] = std::move(intersection);
500       }
501     }
502   }
503 
504   return connected_devices;
505 }
506 
GetUUIDs() const507 BluetoothAdapterBlueZ::UUIDList BluetoothAdapterBlueZ::GetUUIDs() const {
508   if (!IsPresent())
509     return UUIDList();
510 
511   bluez::BluetoothAdapterClient::Properties* properties =
512       bluez::BluezDBusManager::Get()
513           ->GetBluetoothAdapterClient()
514           ->GetProperties(object_path_);
515   DCHECK(properties);
516 
517   std::vector<std::string> uuids = properties->uuids.value();
518 
519   return UUIDList(uuids.begin(), uuids.end());
520 }
521 
CreateRfcommService(const BluetoothUUID & uuid,const ServiceOptions & options,CreateServiceCallback callback,CreateServiceErrorCallback error_callback)522 void BluetoothAdapterBlueZ::CreateRfcommService(
523     const BluetoothUUID& uuid,
524     const ServiceOptions& options,
525     CreateServiceCallback callback,
526     CreateServiceErrorCallback error_callback) {
527   DCHECK(!dbus_is_shutdown_);
528   BLUETOOTH_LOG(DEBUG) << object_path_.value() << ": Creating RFCOMM service: "
529                        << uuid.canonical_value();
530   scoped_refptr<BluetoothSocketBlueZ> socket =
531       BluetoothSocketBlueZ::CreateBluetoothSocket(ui_task_runner_,
532                                                   socket_thread_);
533   socket->Listen(this, BluetoothSocketBlueZ::kRfcomm, uuid, options,
534                  base::BindOnce(std::move(callback), socket),
535                  std::move(error_callback));
536 }
537 
CreateL2capService(const BluetoothUUID & uuid,const ServiceOptions & options,CreateServiceCallback callback,CreateServiceErrorCallback error_callback)538 void BluetoothAdapterBlueZ::CreateL2capService(
539     const BluetoothUUID& uuid,
540     const ServiceOptions& options,
541     CreateServiceCallback callback,
542     CreateServiceErrorCallback error_callback) {
543   DCHECK(!dbus_is_shutdown_);
544   BLUETOOTH_LOG(DEBUG) << object_path_.value() << ": Creating L2CAP service: "
545                        << uuid.canonical_value();
546   scoped_refptr<BluetoothSocketBlueZ> socket =
547       BluetoothSocketBlueZ::CreateBluetoothSocket(ui_task_runner_,
548                                                   socket_thread_);
549   socket->Listen(this, BluetoothSocketBlueZ::kL2cap, uuid, options,
550                  base::BindOnce(std::move(callback), socket),
551                  std::move(error_callback));
552 }
553 
RegisterAdvertisement(std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement_data,CreateAdvertisementCallback callback,AdvertisementErrorCallback error_callback)554 void BluetoothAdapterBlueZ::RegisterAdvertisement(
555     std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement_data,
556     CreateAdvertisementCallback callback,
557     AdvertisementErrorCallback error_callback) {
558   scoped_refptr<BluetoothAdvertisementBlueZ> advertisement(
559       new BluetoothAdvertisementBlueZ(std::move(advertisement_data), this));
560   advertisement->Register(base::BindOnce(std::move(callback), advertisement),
561                           std::move(error_callback));
562   advertisements_.emplace_back(advertisement);
563 }
564 
SetAdvertisingInterval(const base::TimeDelta & min,const base::TimeDelta & max,base::OnceClosure callback,AdvertisementErrorCallback error_callback)565 void BluetoothAdapterBlueZ::SetAdvertisingInterval(
566     const base::TimeDelta& min,
567     const base::TimeDelta& max,
568     base::OnceClosure callback,
569     AdvertisementErrorCallback error_callback) {
570   DCHECK(bluez::BluezDBusManager::Get());
571   uint16_t min_ms = static_cast<uint16_t>(
572       std::min(static_cast<int64_t>(std::numeric_limits<uint16_t>::max()),
573                min.InMilliseconds()));
574   uint16_t max_ms = static_cast<uint16_t>(
575       std::min(static_cast<int64_t>(std::numeric_limits<uint16_t>::max()),
576                max.InMilliseconds()));
577   bluez::BluezDBusManager::Get()
578       ->GetBluetoothLEAdvertisingManagerClient()
579       ->SetAdvertisingInterval(
580           object_path_, min_ms, max_ms, std::move(callback),
581           base::BindOnce(&SetIntervalErrorCallbackConnector,
582                          std::move(error_callback)));
583 }
584 
ResetAdvertising(base::OnceClosure callback,AdvertisementErrorCallback error_callback)585 void BluetoothAdapterBlueZ::ResetAdvertising(
586     base::OnceClosure callback,
587     AdvertisementErrorCallback error_callback) {
588   DCHECK(bluez::BluezDBusManager::Get());
589   bluez::BluezDBusManager::Get()
590       ->GetBluetoothLEAdvertisingManagerClient()
591       ->ResetAdvertising(object_path_, std::move(callback),
592                          base::BindOnce(&ResetAdvertisingErrorCallbackConnector,
593                                         std::move(error_callback)));
594 }
595 
ConnectDevice(const std::string & address,const base::Optional<device::BluetoothDevice::AddressType> & address_type,ConnectDeviceCallback callback,ErrorCallback error_callback)596 void BluetoothAdapterBlueZ::ConnectDevice(
597     const std::string& address,
598     const base::Optional<device::BluetoothDevice::AddressType>& address_type,
599     ConnectDeviceCallback callback,
600     ErrorCallback error_callback) {
601   DCHECK(bluez::BluezDBusManager::Get());
602 
603   base::Optional<BluetoothAdapterClient::AddressType> client_address_type;
604   if (address_type) {
605     switch (*address_type) {
606       case device::BluetoothDevice::AddressType::ADDR_TYPE_PUBLIC:
607         client_address_type = BluetoothAdapterClient::AddressType::kPublic;
608         break;
609       case device::BluetoothDevice::AddressType::ADDR_TYPE_RANDOM:
610         client_address_type = BluetoothAdapterClient::AddressType::kRandom;
611         break;
612       case device::BluetoothDevice::AddressType::ADDR_TYPE_UNKNOWN:
613       default:
614         // Keep |client_address_type| unset.
615         break;
616     };
617   }
618 
619   bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->ConnectDevice(
620       object_path_, address, client_address_type,
621       base::BindOnce(&BluetoothAdapterBlueZ::OnConnectDevice,
622                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
623       base::BindOnce(&BluetoothAdapterBlueZ::OnConnectDeviceError,
624                      weak_ptr_factory_.GetWeakPtr(),
625                      std::move(error_callback)));
626 }
627 
GetGattService(const std::string & identifier) const628 device::BluetoothLocalGattService* BluetoothAdapterBlueZ::GetGattService(
629     const std::string& identifier) const {
630   const auto& service = owned_gatt_services_.find(dbus::ObjectPath(identifier));
631   return service == owned_gatt_services_.end() ? nullptr
632                                                : service->second.get();
633 }
634 
RemovePairingDelegateInternal(BluetoothDevice::PairingDelegate * pairing_delegate)635 void BluetoothAdapterBlueZ::RemovePairingDelegateInternal(
636     BluetoothDevice::PairingDelegate* pairing_delegate) {
637   // Check if any device is using the pairing delegate.
638   // If so, clear the pairing context which will make any responses no-ops.
639   for (auto iter = devices_.begin(); iter != devices_.end(); ++iter) {
640     BluetoothDeviceBlueZ* device_bluez =
641         static_cast<BluetoothDeviceBlueZ*>(iter->second.get());
642 
643     BluetoothPairingBlueZ* pairing = device_bluez->GetPairing();
644     if (pairing && pairing->GetPairingDelegate() == pairing_delegate)
645       device_bluez->EndPairing();
646   }
647 }
648 
AdapterAdded(const dbus::ObjectPath & object_path)649 void BluetoothAdapterBlueZ::AdapterAdded(const dbus::ObjectPath& object_path) {
650   // Set the adapter to the newly added adapter only if no adapter is present.
651   if (!IsPresent())
652     SetAdapter(object_path);
653 }
654 
AdapterRemoved(const dbus::ObjectPath & object_path)655 void BluetoothAdapterBlueZ::AdapterRemoved(
656     const dbus::ObjectPath& object_path) {
657   if (object_path == object_path_)
658     RemoveAdapter();
659 }
660 
AdapterPropertyChanged(const dbus::ObjectPath & object_path,const std::string & property_name)661 void BluetoothAdapterBlueZ::AdapterPropertyChanged(
662     const dbus::ObjectPath& object_path,
663     const std::string& property_name) {
664   if (object_path != object_path_)
665     return;
666   DCHECK(IsPresent());
667 
668   bluez::BluetoothAdapterClient::Properties* properties =
669       bluez::BluezDBusManager::Get()
670           ->GetBluetoothAdapterClient()
671           ->GetProperties(object_path_);
672 
673   if (property_name == properties->powered.name()) {
674     NotifyAdapterPoweredChanged(properties->powered.value());
675   } else if (property_name == properties->discoverable.name()) {
676     DiscoverableChanged(properties->discoverable.value());
677   } else if (property_name == properties->discovering.name()) {
678     DiscoveringChanged(properties->discovering.value());
679   }
680 }
681 
BatteryAdded(const dbus::ObjectPath & object_path)682 void BluetoothAdapterBlueZ::BatteryAdded(const dbus::ObjectPath& object_path) {
683   BLUETOOTH_LOG(DEBUG) << "Battery added " << object_path.value();
684 
685   UpdateDeviceBatteryLevelFromBatteryClient(object_path);
686 }
687 
BatteryRemoved(const dbus::ObjectPath & object_path)688 void BluetoothAdapterBlueZ::BatteryRemoved(
689     const dbus::ObjectPath& object_path) {
690   BLUETOOTH_LOG(DEBUG) << "Battery removed " << object_path.value();
691 
692   UpdateDeviceBatteryLevelFromBatteryClient(object_path);
693 }
694 
BatteryPropertyChanged(const dbus::ObjectPath & object_path,const std::string & property_name)695 void BluetoothAdapterBlueZ::BatteryPropertyChanged(
696     const dbus::ObjectPath& object_path,
697     const std::string& property_name) {
698   BLUETOOTH_LOG(DEBUG) << "Battery property changed " << object_path.value();
699 
700   if (property_name == bluetooth_battery::kPercentageProperty)
701     UpdateDeviceBatteryLevelFromBatteryClient(object_path);
702 }
703 
DeviceAdded(const dbus::ObjectPath & object_path)704 void BluetoothAdapterBlueZ::DeviceAdded(const dbus::ObjectPath& object_path) {
705   DCHECK(bluez::BluezDBusManager::Get());
706   bluez::BluetoothDeviceClient::Properties* properties =
707       bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
708           object_path);
709   if (!properties || properties->adapter.value() != object_path_)
710     return;
711   DCHECK(IsPresent());
712 
713   BluetoothDeviceBlueZ* device_bluez = new BluetoothDeviceBlueZ(
714       this, object_path, ui_task_runner_, socket_thread_);
715   DCHECK(devices_.find(device_bluez->GetAddress()) == devices_.end());
716 
717   devices_[device_bluez->GetAddress()] = base::WrapUnique(device_bluez);
718 
719   if (properties->rssi.is_valid() && properties->eir.is_valid()) {
720     NotifyDeviceAdvertisementReceived(device_bluez, properties->rssi.value(),
721                                       properties->eir.value());
722   }
723 
724   for (auto& observer : observers_)
725     observer.DeviceAdded(this, device_bluez);
726 }
727 
DeviceRemoved(const dbus::ObjectPath & object_path)728 void BluetoothAdapterBlueZ::DeviceRemoved(const dbus::ObjectPath& object_path) {
729   for (auto iter = devices_.begin(); iter != devices_.end(); ++iter) {
730     BluetoothDeviceBlueZ* device_bluez =
731         static_cast<BluetoothDeviceBlueZ*>(iter->second.get());
732     if (device_bluez->object_path() == object_path) {
733       std::unique_ptr<BluetoothDevice> scoped_device = std::move(iter->second);
734       devices_.erase(iter);
735 
736       for (auto& observer : observers_)
737         observer.DeviceRemoved(this, device_bluez);
738       return;
739     }
740   }
741 }
742 
DevicePropertyChanged(const dbus::ObjectPath & object_path,const std::string & property_name)743 void BluetoothAdapterBlueZ::DevicePropertyChanged(
744     const dbus::ObjectPath& object_path,
745     const std::string& property_name) {
746   BluetoothDeviceBlueZ* device_bluez = GetDeviceWithPath(object_path);
747   if (!device_bluez)
748     return;
749 
750   bluez::BluetoothDeviceClient::Properties* properties =
751       bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties(
752           object_path);
753 
754   if (property_name == properties->address.name()) {
755     for (auto iter = devices_.begin(); iter != devices_.end(); ++iter) {
756       if (iter->second->GetAddress() == device_bluez->GetAddress()) {
757         std::string old_address = iter->first;
758         BLUETOOTH_LOG(EVENT) << "Device changed address, old: " << old_address
759                              << " new: " << device_bluez->GetAddress();
760         std::unique_ptr<BluetoothDevice> scoped_device =
761             std::move(iter->second);
762         devices_.erase(iter);
763 
764         DCHECK(devices_.find(device_bluez->GetAddress()) == devices_.end());
765         devices_[device_bluez->GetAddress()] = std::move(scoped_device);
766         NotifyDeviceAddressChanged(device_bluez, old_address);
767         break;
768       }
769     }
770   }
771 
772   if (property_name == properties->service_data.name())
773     device_bluez->UpdateServiceData();
774   else if (property_name == properties->manufacturer_data.name())
775     device_bluez->UpdateManufacturerData();
776   else if (property_name == properties->advertising_data_flags.name())
777     device_bluez->UpdateAdvertisingDataFlags();
778 
779   if (property_name == properties->bluetooth_class.name() ||
780       property_name == properties->appearance.name() ||
781       property_name == properties->address.name() ||
782       property_name == properties->name.name() ||
783       property_name == properties->paired.name() ||
784       property_name == properties->trusted.name() ||
785       property_name == properties->connected.name() ||
786       property_name == properties->uuids.name() ||
787       property_name == properties->rssi.name() ||
788       property_name == properties->tx_power.name() ||
789       property_name == properties->service_data.name() ||
790       property_name == properties->manufacturer_data.name() ||
791       property_name == properties->advertising_data_flags.name()) {
792     NotifyDeviceChanged(device_bluez);
793   }
794 
795   if (property_name == properties->mtu.name())
796     NotifyDeviceMTUChanged(device_bluez, properties->mtu.value());
797 
798   // Bluez does not currently provide an explicit signal for an advertisement
799   // packet being received. Currently, it implicitly does so by notifying of an
800   // RSSI change. We also listen for whether the EIR packet data has changed.
801   if ((property_name == properties->rssi.name() ||
802        property_name == properties->eir.name()) &&
803       properties->rssi.is_valid() && properties->eir.is_valid()) {
804     NotifyDeviceAdvertisementReceived(device_bluez, properties->rssi.value(),
805                                       properties->eir.value());
806   }
807 
808   if (property_name == properties->connected.name())
809     NotifyDeviceConnectedStateChanged(device_bluez,
810                                       properties->connected.value());
811 
812   if (property_name == properties->services_resolved.name() &&
813       properties->services_resolved.value()) {
814     device_bluez->UpdateGattServices(object_path);
815     NotifyGattServicesDiscovered(device_bluez);
816   }
817 
818   // When a device becomes paired, mark it as trusted so that the user does
819   // not need to approve every incoming connection
820   if (property_name == properties->paired.name()) {
821     if (properties->paired.value() && !properties->trusted.value()) {
822       device_bluez->SetTrusted();
823     }
824     NotifyDevicePairedChanged(device_bluez, properties->paired.value());
825   }
826 
827   // UMA connection counting
828   if (property_name == properties->connected.name()) {
829     int count = 0;
830 
831     for (auto iter = devices_.begin(); iter != devices_.end(); ++iter) {
832       if (iter->second->IsPaired() && iter->second->IsConnected())
833         ++count;
834     }
835 
836     UMA_HISTOGRAM_COUNTS_100("Bluetooth.ConnectedDeviceCount", count);
837   }
838 }
839 
InputPropertyChanged(const dbus::ObjectPath & object_path,const std::string & property_name)840 void BluetoothAdapterBlueZ::InputPropertyChanged(
841     const dbus::ObjectPath& object_path,
842     const std::string& property_name) {
843   BluetoothDeviceBlueZ* device_bluez = GetDeviceWithPath(object_path);
844   if (!device_bluez)
845     return;
846 
847   bluez::BluetoothInputClient::Properties* properties =
848       bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->GetProperties(
849           object_path);
850 
851   // Properties structure can be removed, which triggers a change in the
852   // BluetoothDevice::IsConnectable() property, as does a change in the
853   // actual reconnect_mode property.
854   if (!properties || property_name == properties->reconnect_mode.name()) {
855     NotifyDeviceChanged(device_bluez);
856   }
857 }
858 
AgentManagerAdded(const dbus::ObjectPath & object_path)859 void BluetoothAdapterBlueZ::AgentManagerAdded(
860     const dbus::ObjectPath& object_path) {
861   BLUETOOTH_LOG(DEBUG) << "Registering pairing agent";
862   bluez::BluezDBusManager::Get()
863       ->GetBluetoothAgentManagerClient()
864       ->RegisterAgent(
865           dbus::ObjectPath(kAgentPath),
866           bluetooth_agent_manager::kKeyboardDisplayCapability,
867           base::BindOnce(&BluetoothAdapterBlueZ::OnRegisterAgent,
868                          weak_ptr_factory_.GetWeakPtr()),
869           base::BindOnce(&BluetoothAdapterBlueZ::OnRegisterAgentError,
870                          weak_ptr_factory_.GetWeakPtr()));
871 }
872 
AgentManagerRemoved(const dbus::ObjectPath & object_path)873 void BluetoothAdapterBlueZ::AgentManagerRemoved(
874     const dbus::ObjectPath& object_path) {}
875 
Released()876 void BluetoothAdapterBlueZ::Released() {
877   BLUETOOTH_LOG(EVENT) << "Released";
878   if (!IsPresent())
879     return;
880   DCHECK(agent_.get());
881 
882   // Called after we unregister the pairing agent, e.g. when changing I/O
883   // capabilities. Nothing much to be done right now.
884 }
885 
RequestPinCode(const dbus::ObjectPath & device_path,PinCodeCallback callback)886 void BluetoothAdapterBlueZ::RequestPinCode(const dbus::ObjectPath& device_path,
887                                            PinCodeCallback callback) {
888   DCHECK(IsPresent());
889   DCHECK(agent_.get());
890   BLUETOOTH_LOG(EVENT) << device_path.value() << ": RequestPinCode";
891 
892   BluetoothPairingBlueZ* pairing = GetPairing(device_path);
893   if (!pairing) {
894     std::move(callback).Run(REJECTED, "");
895     return;
896   }
897 
898   pairing->RequestPinCode(std::move(callback));
899 }
900 
DisplayPinCode(const dbus::ObjectPath & device_path,const std::string & pincode)901 void BluetoothAdapterBlueZ::DisplayPinCode(const dbus::ObjectPath& device_path,
902                                            const std::string& pincode) {
903   DCHECK(IsPresent());
904   DCHECK(agent_.get());
905   BLUETOOTH_LOG(EVENT) << device_path.value()
906                        << ": DisplayPinCode: " << pincode;
907 
908   BluetoothPairingBlueZ* pairing = GetPairing(device_path);
909   if (!pairing)
910     return;
911 
912   pairing->DisplayPinCode(pincode);
913 }
914 
RequestPasskey(const dbus::ObjectPath & device_path,PasskeyCallback callback)915 void BluetoothAdapterBlueZ::RequestPasskey(const dbus::ObjectPath& device_path,
916                                            PasskeyCallback callback) {
917   DCHECK(IsPresent());
918   DCHECK(agent_.get());
919   BLUETOOTH_LOG(EVENT) << device_path.value() << ": RequestPasskey";
920 
921   BluetoothPairingBlueZ* pairing = GetPairing(device_path);
922   if (!pairing) {
923     std::move(callback).Run(REJECTED, 0);
924     return;
925   }
926 
927   pairing->RequestPasskey(std::move(callback));
928 }
929 
DisplayPasskey(const dbus::ObjectPath & device_path,uint32_t passkey,uint16_t entered)930 void BluetoothAdapterBlueZ::DisplayPasskey(const dbus::ObjectPath& device_path,
931                                            uint32_t passkey,
932                                            uint16_t entered) {
933   DCHECK(IsPresent());
934   DCHECK(agent_.get());
935   BLUETOOTH_LOG(EVENT) << device_path.value() << ": DisplayPasskey: " << passkey
936                        << " (" << entered << " entered)";
937 
938   BluetoothPairingBlueZ* pairing = GetPairing(device_path);
939   if (!pairing)
940     return;
941 
942   if (entered == 0)
943     pairing->DisplayPasskey(passkey);
944 
945   pairing->KeysEntered(entered);
946 }
947 
RequestConfirmation(const dbus::ObjectPath & device_path,uint32_t passkey,ConfirmationCallback callback)948 void BluetoothAdapterBlueZ::RequestConfirmation(
949     const dbus::ObjectPath& device_path,
950     uint32_t passkey,
951     ConfirmationCallback callback) {
952   DCHECK(IsPresent());
953   DCHECK(agent_.get());
954   BLUETOOTH_LOG(EVENT) << device_path.value()
955                        << ": RequestConfirmation: " << passkey;
956 
957   BluetoothPairingBlueZ* pairing = GetPairing(device_path);
958   if (!pairing) {
959     std::move(callback).Run(REJECTED);
960     return;
961   }
962 
963   pairing->RequestConfirmation(passkey, std::move(callback));
964 }
965 
RequestAuthorization(const dbus::ObjectPath & device_path,ConfirmationCallback callback)966 void BluetoothAdapterBlueZ::RequestAuthorization(
967     const dbus::ObjectPath& device_path,
968     ConfirmationCallback callback) {
969   DCHECK(IsPresent());
970   DCHECK(agent_.get());
971   BLUETOOTH_LOG(EVENT) << device_path.value() << ": RequestAuthorization";
972 
973   BluetoothPairingBlueZ* pairing = GetPairing(device_path);
974   if (!pairing) {
975     std::move(callback).Run(REJECTED);
976     return;
977   }
978 
979   pairing->RequestAuthorization(std::move(callback));
980 }
981 
AuthorizeService(const dbus::ObjectPath & device_path,const std::string & uuid,ConfirmationCallback callback)982 void BluetoothAdapterBlueZ::AuthorizeService(
983     const dbus::ObjectPath& device_path,
984     const std::string& uuid,
985     ConfirmationCallback callback) {
986   DCHECK(IsPresent());
987   DCHECK(agent_.get());
988   BLUETOOTH_LOG(EVENT) << device_path.value() << ": AuthorizeService: " << uuid;
989 
990   BluetoothDeviceBlueZ* device_bluez = GetDeviceWithPath(device_path);
991   if (!device_bluez) {
992     std::move(callback).Run(CANCELLED);
993     return;
994   }
995 
996   // We always set paired devices to Trusted, so the only reason that this
997   // method call would ever be called is in the case of a race condition where
998   // our "Set('Trusted', true)" method call is still pending in the Bluetooth
999   // daemon because it's busy handling the incoming connection.
1000   if (device_bluez->IsPaired()) {
1001     std::move(callback).Run(SUCCESS);
1002     return;
1003   }
1004 
1005   // TODO(keybuk): reject service authorizations when not paired, determine
1006   // whether this is acceptable long-term.
1007   BLUETOOTH_LOG(ERROR) << "Rejecting service connection from unpaired device "
1008                        << device_bluez->GetAddress() << " for UUID " << uuid;
1009   std::move(callback).Run(REJECTED);
1010 }
1011 
Cancel()1012 void BluetoothAdapterBlueZ::Cancel() {
1013   DCHECK(IsPresent());
1014   DCHECK(agent_.get());
1015   BLUETOOTH_LOG(EVENT) << "Cancel";
1016 }
1017 
OnRegisterAgent()1018 void BluetoothAdapterBlueZ::OnRegisterAgent() {
1019   BLUETOOTH_LOG(EVENT)
1020       << "Pairing agent registered, requesting to be made default";
1021 
1022   bluez::BluezDBusManager::Get()
1023       ->GetBluetoothAgentManagerClient()
1024       ->RequestDefaultAgent(
1025           dbus::ObjectPath(kAgentPath),
1026           base::BindOnce(&BluetoothAdapterBlueZ::OnRequestDefaultAgent,
1027                          weak_ptr_factory_.GetWeakPtr()),
1028           base::BindOnce(&BluetoothAdapterBlueZ::OnRequestDefaultAgentError,
1029                          weak_ptr_factory_.GetWeakPtr()));
1030 }
1031 
OnRegisterAgentError(const std::string & error_name,const std::string & error_message)1032 void BluetoothAdapterBlueZ::OnRegisterAgentError(
1033     const std::string& error_name,
1034     const std::string& error_message) {
1035   // Our agent being already registered isn't an error.
1036   if (error_name == bluetooth_agent_manager::kErrorAlreadyExists)
1037     return;
1038 
1039   BLUETOOTH_LOG(ERROR) << "Failed to register pairing agent: " << error_name
1040                        << ": " << error_message;
1041 }
1042 
OnRequestDefaultAgent()1043 void BluetoothAdapterBlueZ::OnRequestDefaultAgent() {
1044   BLUETOOTH_LOG(EVENT) << "Pairing agent now default";
1045 }
1046 
OnRequestDefaultAgentError(const std::string & error_name,const std::string & error_message)1047 void BluetoothAdapterBlueZ::OnRequestDefaultAgentError(
1048     const std::string& error_name,
1049     const std::string& error_message) {
1050   BLUETOOTH_LOG(ERROR) << "Failed to make pairing agent default: " << error_name
1051                        << ": " << error_message;
1052 }
1053 
CreateServiceRecord(const BluetoothServiceRecordBlueZ & record,ServiceRecordCallback callback,ServiceRecordErrorCallback error_callback)1054 void BluetoothAdapterBlueZ::CreateServiceRecord(
1055     const BluetoothServiceRecordBlueZ& record,
1056     ServiceRecordCallback callback,
1057     ServiceRecordErrorCallback error_callback) {
1058   bluez::BluezDBusManager::Get()
1059       ->GetBluetoothAdapterClient()
1060       ->CreateServiceRecord(
1061           object_path_, record, std::move(callback),
1062           base::BindOnce(&BluetoothAdapterBlueZ::ServiceRecordErrorConnector,
1063                          weak_ptr_factory_.GetWeakPtr(),
1064                          std::move(error_callback)));
1065 }
1066 
RemoveServiceRecord(uint32_t handle,base::OnceClosure callback,ServiceRecordErrorCallback error_callback)1067 void BluetoothAdapterBlueZ::RemoveServiceRecord(
1068     uint32_t handle,
1069     base::OnceClosure callback,
1070     ServiceRecordErrorCallback error_callback) {
1071   bluez::BluezDBusManager::Get()
1072       ->GetBluetoothAdapterClient()
1073       ->RemoveServiceRecord(
1074           object_path_, handle, std::move(callback),
1075           base::BindOnce(&BluetoothAdapterBlueZ::ServiceRecordErrorConnector,
1076                          weak_ptr_factory_.GetWeakPtr(),
1077                          std::move(error_callback)));
1078 }
1079 
GetDeviceWithPath(const dbus::ObjectPath & object_path)1080 BluetoothDeviceBlueZ* BluetoothAdapterBlueZ::GetDeviceWithPath(
1081     const dbus::ObjectPath& object_path) {
1082   if (!IsPresent())
1083     return nullptr;
1084 
1085   for (auto iter = devices_.begin(); iter != devices_.end(); ++iter) {
1086     BluetoothDeviceBlueZ* device_bluez =
1087         static_cast<BluetoothDeviceBlueZ*>(iter->second.get());
1088     if (device_bluez->object_path() == object_path)
1089       return device_bluez;
1090   }
1091 
1092   return nullptr;
1093 }
1094 
GetPairing(const dbus::ObjectPath & object_path)1095 BluetoothPairingBlueZ* BluetoothAdapterBlueZ::GetPairing(
1096     const dbus::ObjectPath& object_path) {
1097   DCHECK(IsPresent());
1098   BluetoothDeviceBlueZ* device_bluez = GetDeviceWithPath(object_path);
1099   if (!device_bluez) {
1100     BLUETOOTH_LOG(ERROR) << "Pairing Agent request for unknown device: "
1101                          << object_path.value();
1102     return nullptr;
1103   }
1104 
1105   BluetoothPairingBlueZ* pairing = device_bluez->GetPairing();
1106   if (pairing)
1107     return pairing;
1108 
1109   // The device doesn't have its own pairing context, so this is an incoming
1110   // pairing request that should use our best default delegate (if we have one).
1111   BluetoothDevice::PairingDelegate* pairing_delegate = DefaultPairingDelegate();
1112   if (!pairing_delegate)
1113     return nullptr;
1114 
1115   return device_bluez->BeginPairing(pairing_delegate);
1116 }
1117 
SetAdapter(const dbus::ObjectPath & object_path)1118 void BluetoothAdapterBlueZ::SetAdapter(const dbus::ObjectPath& object_path) {
1119   DCHECK(!IsPresent());
1120   DCHECK(!dbus_is_shutdown_);
1121   object_path_ = object_path;
1122 
1123   BLUETOOTH_LOG(EVENT) << object_path_.value() << ": using adapter.";
1124 
1125 #if BUILDFLAG(IS_ASH)
1126   SetStandardChromeOSAdapterName();
1127 #endif
1128 
1129   bluez::BluetoothAdapterClient::Properties* properties =
1130       bluez::BluezDBusManager::Get()
1131           ->GetBluetoothAdapterClient()
1132           ->GetProperties(object_path_);
1133 
1134   PresentChanged(true);
1135 
1136   if (properties->powered.value())
1137     NotifyAdapterPoweredChanged(true);
1138   if (properties->discoverable.value())
1139     DiscoverableChanged(true);
1140   if (properties->discovering.value())
1141     DiscoveringChanged(true);
1142 
1143   std::vector<dbus::ObjectPath> device_paths =
1144       bluez::BluezDBusManager::Get()
1145           ->GetBluetoothDeviceClient()
1146           ->GetDevicesForAdapter(object_path_);
1147 
1148   for (auto iter = device_paths.begin(); iter != device_paths.end(); ++iter) {
1149     DeviceAdded(*iter);
1150   }
1151 }
1152 
1153 #if BUILDFLAG(IS_ASH)
SetStandardChromeOSAdapterName()1154 void BluetoothAdapterBlueZ::SetStandardChromeOSAdapterName() {
1155   DCHECK(IsPresent());
1156 
1157   std::string alias;
1158   switch (chromeos::GetDeviceType()) {
1159     case chromeos::DeviceType::kChromebase:
1160       alias = "Chromebase";
1161       break;
1162     case chromeos::DeviceType::kChromebit:
1163       alias = "Chromebit";
1164       break;
1165     case chromeos::DeviceType::kChromebook:
1166       alias = "Chromebook";
1167       break;
1168     case chromeos::DeviceType::kChromebox:
1169       alias = "Chromebox";
1170       break;
1171     case chromeos::DeviceType::kUnknown:
1172       alias = "Chromebook";
1173       break;
1174   }
1175   // Take the lower 2 bytes of hashed Bluetooth address and combine it with the
1176   // device type to create a more identifiable device name.
1177   const std::string address = GetAddress();
1178   alias = base::StringPrintf("%s_%04X", alias.c_str(),
1179                              base::PersistentHash(address) & 0xFFFF);
1180   SetName(alias, base::DoNothing(), base::DoNothing());
1181 }
1182 #endif
1183 
RemoveAdapter()1184 void BluetoothAdapterBlueZ::RemoveAdapter() {
1185   DCHECK(IsPresent());
1186   BLUETOOTH_LOG(EVENT) << object_path_.value() << ": adapter removed.";
1187 
1188   bluez::BluetoothAdapterClient::Properties* properties =
1189       bluez::BluezDBusManager::Get()
1190           ->GetBluetoothAdapterClient()
1191           ->GetProperties(object_path_);
1192 
1193   object_path_ = dbus::ObjectPath("");
1194 
1195   if (properties->powered.value())
1196     NotifyAdapterPoweredChanged(false);
1197   if (properties->discoverable.value())
1198     DiscoverableChanged(false);
1199 
1200   // The properties->discovering.value() may not be up to date with the real
1201   // discovering state (BlueZ bug: http://crbug.com/822104).
1202   // When the adapter is removed, make sure to clear all discovery sessions no
1203   // matter what the current properties->discovering.value() is.
1204   // DiscoveringChanged() properly handles the case where there is no discovery
1205   // sessions currently.
1206   DiscoveringChanged(false);
1207 
1208   // Move all elements of the original devices list to a new list here,
1209   // leaving the original list empty so that when we send DeviceRemoved(),
1210   // GetDevices() returns no devices.
1211   DevicesMap devices_swapped;
1212   devices_swapped.swap(devices_);
1213 
1214   for (auto& iter : devices_swapped) {
1215     for (auto& observer : observers_)
1216       observer.DeviceRemoved(this, iter.second.get());
1217   }
1218 
1219   PresentChanged(false);
1220 }
1221 
DiscoverableChanged(bool discoverable)1222 void BluetoothAdapterBlueZ::DiscoverableChanged(bool discoverable) {
1223   for (auto& observer : observers_)
1224     observer.AdapterDiscoverableChanged(this, discoverable);
1225 }
1226 
DiscoveringChanged(bool discovering)1227 void BluetoothAdapterBlueZ::DiscoveringChanged(bool discovering) {
1228   // If the adapter stopped discovery due to a reason other than a request by
1229   // us, reset the count to 0.
1230   BLUETOOTH_LOG(EVENT) << "Discovering changed: " << discovering;
1231   if (!discovering && NumScanningDiscoverySessions() > 0) {
1232     BLUETOOTH_LOG(DEBUG) << "Marking sessions as inactive.";
1233     MarkDiscoverySessionsAsInactive();
1234   }
1235 
1236   for (auto& observer : observers_)
1237     observer.AdapterDiscoveringChanged(this, discovering);
1238 }
1239 
PresentChanged(bool present)1240 void BluetoothAdapterBlueZ::PresentChanged(bool present) {
1241   for (auto& observer : observers_)
1242     observer.AdapterPresentChanged(this, present);
1243 }
1244 
NotifyDeviceAddressChanged(BluetoothDeviceBlueZ * device,const std::string & old_address)1245 void BluetoothAdapterBlueZ::NotifyDeviceAddressChanged(
1246     BluetoothDeviceBlueZ* device,
1247     const std::string& old_address) {
1248   DCHECK(device->adapter_ == this);
1249 
1250   for (auto& observer : observers_)
1251     observer.DeviceAddressChanged(this, device, old_address);
1252 }
1253 
NotifyDeviceMTUChanged(BluetoothDeviceBlueZ * device,uint16_t mtu)1254 void BluetoothAdapterBlueZ::NotifyDeviceMTUChanged(BluetoothDeviceBlueZ* device,
1255                                                    uint16_t mtu) {
1256   DCHECK(device->adapter_ == this);
1257 
1258   for (auto& observer : observers_)
1259     observer.DeviceMTUChanged(this, device, mtu);
1260 }
1261 
NotifyDeviceAdvertisementReceived(BluetoothDeviceBlueZ * device,int16_t rssi,const std::vector<uint8_t> & eir)1262 void BluetoothAdapterBlueZ::NotifyDeviceAdvertisementReceived(
1263     BluetoothDeviceBlueZ* device,
1264     int16_t rssi,
1265     const std::vector<uint8_t>& eir) {
1266   DCHECK(device->adapter_ == this);
1267 
1268   for (auto& observer : observers_)
1269     observer.DeviceAdvertisementReceived(this, device, rssi, eir);
1270 
1271 #if BUILDFLAG(IS_ASH)
1272   if (ble_scan_parser_.is_bound()) {
1273     ScanRecordCallback callback =
1274         base::BindOnce(&BluetoothAdapterBlueZ::OnAdvertisementReceived,
1275                        weak_ptr_factory_.GetWeakPtr(), device->GetAddress(),
1276                        device->GetName() ? *(device->GetName()) : std::string(),
1277                        rssi, device->GetAppearance());
1278     ble_scan_parser_->Parse(eir, std::move(callback));
1279   }
1280 #endif  // BUILDFLAG(IS_ASH)
1281 }
1282 
1283 #if BUILDFLAG(IS_ASH)
OnAdvertisementReceived(std::string device_address,std::string device_name,uint8_t rssi,uint16_t device_appearance,ScanRecordPtr scan_record)1284 void BluetoothAdapterBlueZ::OnAdvertisementReceived(std::string device_address,
1285                                                     std::string device_name,
1286                                                     uint8_t rssi,
1287                                                     uint16_t device_appearance,
1288                                                     ScanRecordPtr scan_record) {
1289   // Ignore the packet if it could not be parsed successfully.
1290   if (!scan_record)
1291     return;
1292 
1293   auto service_data_map = ConvertServiceDataMap(scan_record->service_data_map);
1294   auto manufacturer_data_map =
1295       ConvertManufacturerDataMap(scan_record->manufacturer_data_map);
1296   for (auto& observer : observers_) {
1297     observer.DeviceAdvertisementReceived(
1298         device_address, device_name, scan_record->advertisement_name, rssi,
1299         scan_record->tx_power, device_appearance, scan_record->service_uuids,
1300         service_data_map, manufacturer_data_map);
1301   }
1302 }
1303 #endif  // BUILDFLAG(IS_ASH)
1304 
NotifyDeviceConnectedStateChanged(BluetoothDeviceBlueZ * device,bool is_now_connected)1305 void BluetoothAdapterBlueZ::NotifyDeviceConnectedStateChanged(
1306     BluetoothDeviceBlueZ* device,
1307     bool is_now_connected) {
1308   DCHECK_EQ(device->adapter_, this);
1309   DCHECK_EQ(device->IsConnected(), is_now_connected);
1310 
1311   for (auto& observer : observers_)
1312     observer.DeviceConnectedStateChanged(this, device, is_now_connected);
1313 }
1314 
UseProfile(const BluetoothUUID & uuid,const dbus::ObjectPath & device_path,const bluez::BluetoothProfileManagerClient::Options & options,bluez::BluetoothProfileServiceProvider::Delegate * delegate,ProfileRegisteredCallback success_callback,ErrorCompletionCallback error_callback)1315 void BluetoothAdapterBlueZ::UseProfile(
1316     const BluetoothUUID& uuid,
1317     const dbus::ObjectPath& device_path,
1318     const bluez::BluetoothProfileManagerClient::Options& options,
1319     bluez::BluetoothProfileServiceProvider::Delegate* delegate,
1320     ProfileRegisteredCallback success_callback,
1321     ErrorCompletionCallback error_callback) {
1322   DCHECK(delegate);
1323 
1324   if (!IsPresent()) {
1325     BLUETOOTH_LOG(DEBUG) << "Adapter not present, erroring out";
1326     std::move(error_callback).Run("Adapter not present");
1327     return;
1328   }
1329 
1330   if (profiles_.find(uuid) != profiles_.end()) {
1331     // TODO(jamuraa) check that the options are the same and error when they are
1332     // not.
1333     SetProfileDelegate(uuid, device_path, delegate, std::move(success_callback),
1334                        std::move(error_callback));
1335     return;
1336   }
1337 
1338   if (profile_queues_.find(uuid) == profile_queues_.end()) {
1339     BluetoothAdapterProfileBlueZ::Register(
1340         uuid, options,
1341         base::BindOnce(&BluetoothAdapterBlueZ::OnRegisterProfile, this, uuid),
1342         base::BindOnce(&BluetoothAdapterBlueZ::OnRegisterProfileError, this,
1343                        uuid));
1344 
1345     profile_queues_[uuid] = new std::vector<RegisterProfileCompletionPair>();
1346   }
1347 
1348   auto copyable_error_callback =
1349       base::AdaptCallbackForRepeating(std::move(error_callback));
1350   profile_queues_[uuid]->push_back(std::make_pair(
1351       base::BindOnce(&BluetoothAdapterBlueZ::SetProfileDelegate, this, uuid,
1352                      device_path, delegate, std::move(success_callback),
1353                      copyable_error_callback),
1354       copyable_error_callback));
1355 }
1356 
ReleaseProfile(const dbus::ObjectPath & device_path,BluetoothAdapterProfileBlueZ * profile)1357 void BluetoothAdapterBlueZ::ReleaseProfile(
1358     const dbus::ObjectPath& device_path,
1359     BluetoothAdapterProfileBlueZ* profile) {
1360   BLUETOOTH_LOG(EVENT) << "Releasing Profile: "
1361                        << profile->uuid().canonical_value() << " from "
1362                        << device_path.value();
1363   BluetoothUUID uuid = profile->uuid();
1364   auto iter = profiles_.find(uuid);
1365   if (iter == profiles_.end()) {
1366     BLUETOOTH_LOG(ERROR) << "Profile not found for: " << uuid.canonical_value();
1367     return;
1368   }
1369   released_profiles_[uuid] = iter->second;
1370   profiles_.erase(iter);
1371   profile->RemoveDelegate(device_path,
1372                           base::BindOnce(&BluetoothAdapterBlueZ::RemoveProfile,
1373                                          weak_ptr_factory_.GetWeakPtr(), uuid));
1374 }
1375 
RemoveProfile(const BluetoothUUID & uuid)1376 void BluetoothAdapterBlueZ::RemoveProfile(const BluetoothUUID& uuid) {
1377   BLUETOOTH_LOG(EVENT) << "Remove Profile: " << uuid.canonical_value();
1378 
1379   auto iter = released_profiles_.find(uuid);
1380   if (iter == released_profiles_.end()) {
1381     BLUETOOTH_LOG(ERROR) << "Released Profile not found: "
1382                          << uuid.canonical_value();
1383     return;
1384   }
1385   delete iter->second;
1386   released_profiles_.erase(iter);
1387 }
1388 
AddLocalGattService(std::unique_ptr<BluetoothLocalGattServiceBlueZ> service)1389 void BluetoothAdapterBlueZ::AddLocalGattService(
1390     std::unique_ptr<BluetoothLocalGattServiceBlueZ> service) {
1391   owned_gatt_services_[service->object_path()] = std::move(service);
1392 }
1393 
RemoveLocalGattService(BluetoothLocalGattServiceBlueZ * service)1394 void BluetoothAdapterBlueZ::RemoveLocalGattService(
1395     BluetoothLocalGattServiceBlueZ* service) {
1396   auto service_iter = owned_gatt_services_.find(service->object_path());
1397   if (service_iter == owned_gatt_services_.end()) {
1398     BLUETOOTH_LOG(ERROR) << "Trying to remove service: "
1399                          << service->object_path().value()
1400                          << " from adapter: " << object_path_.value()
1401                          << " that doesn't own it.";
1402     return;
1403   }
1404 
1405   if (registered_gatt_services_.count(service->object_path()) != 0) {
1406     registered_gatt_services_.erase(service->object_path());
1407     UpdateRegisteredApplication(true, base::DoNothing(), base::DoNothing());
1408   }
1409 
1410   owned_gatt_services_.erase(service_iter);
1411 }
1412 
RegisterGattService(BluetoothLocalGattServiceBlueZ * service,base::OnceClosure callback,device::BluetoothGattService::ErrorCallback error_callback)1413 void BluetoothAdapterBlueZ::RegisterGattService(
1414     BluetoothLocalGattServiceBlueZ* service,
1415     base::OnceClosure callback,
1416     device::BluetoothGattService::ErrorCallback error_callback) {
1417   if (registered_gatt_services_.count(service->object_path()) > 0) {
1418     BLUETOOTH_LOG(ERROR)
1419         << "Re-registering a service that is already registered!";
1420     std::move(error_callback)
1421         .Run(device::BluetoothGattService::GATT_ERROR_FAILED);
1422     return;
1423   }
1424 
1425   registered_gatt_services_[service->object_path()] = service;
1426 
1427   // Always assume that we were already registered. If we weren't registered
1428   // we'll just get an error back which we can ignore. Any other approach will
1429   // introduce a race since we will always have a period when we may have been
1430   // registered with BlueZ, but not know that the registration succeeded
1431   // because the callback hasn't come back yet.
1432   UpdateRegisteredApplication(true, std::move(callback),
1433                               std::move(error_callback));
1434 }
1435 
UnregisterGattService(BluetoothLocalGattServiceBlueZ * service,base::OnceClosure callback,device::BluetoothGattService::ErrorCallback error_callback)1436 void BluetoothAdapterBlueZ::UnregisterGattService(
1437     BluetoothLocalGattServiceBlueZ* service,
1438     base::OnceClosure callback,
1439     device::BluetoothGattService::ErrorCallback error_callback) {
1440   DCHECK(bluez::BluezDBusManager::Get());
1441 
1442   if (registered_gatt_services_.count(service->object_path()) == 0) {
1443     BLUETOOTH_LOG(ERROR)
1444         << "Unregistering a service that isn't registered! path: "
1445         << service->object_path().value();
1446     std::move(error_callback)
1447         .Run(device::BluetoothGattService::GATT_ERROR_FAILED);
1448     return;
1449   }
1450 
1451   registered_gatt_services_.erase(service->object_path());
1452   UpdateRegisteredApplication(false, std::move(callback),
1453                               std::move(error_callback));
1454 }
1455 
IsGattServiceRegistered(BluetoothLocalGattServiceBlueZ * service)1456 bool BluetoothAdapterBlueZ::IsGattServiceRegistered(
1457     BluetoothLocalGattServiceBlueZ* service) {
1458   return registered_gatt_services_.count(service->object_path()) != 0;
1459 }
1460 
SendValueChanged(BluetoothLocalGattCharacteristicBlueZ * characteristic,const std::vector<uint8_t> & value)1461 bool BluetoothAdapterBlueZ::SendValueChanged(
1462     BluetoothLocalGattCharacteristicBlueZ* characteristic,
1463     const std::vector<uint8_t>& value) {
1464   if (registered_gatt_services_.count(
1465           static_cast<BluetoothLocalGattServiceBlueZ*>(
1466               characteristic->GetService())
1467               ->object_path()) == 0)
1468     return false;
1469   gatt_application_provider_->SendValueChanged(characteristic->object_path(),
1470                                                value);
1471   return true;
1472 }
1473 
GetApplicationObjectPath() const1474 dbus::ObjectPath BluetoothAdapterBlueZ::GetApplicationObjectPath() const {
1475   return dbus::ObjectPath(object_path_.value() + kGattApplicationObjectPath);
1476 }
1477 
OnRegisterProfile(const BluetoothUUID & uuid,std::unique_ptr<BluetoothAdapterProfileBlueZ> profile)1478 void BluetoothAdapterBlueZ::OnRegisterProfile(
1479     const BluetoothUUID& uuid,
1480     std::unique_ptr<BluetoothAdapterProfileBlueZ> profile) {
1481   profiles_[uuid] = profile.release();
1482 
1483   if (profile_queues_.find(uuid) == profile_queues_.end())
1484     return;
1485 
1486   for (auto& it : *profile_queues_[uuid])
1487     std::move(it.first).Run();
1488   delete profile_queues_[uuid];
1489   profile_queues_.erase(uuid);
1490 }
1491 
SetProfileDelegate(const BluetoothUUID & uuid,const dbus::ObjectPath & device_path,bluez::BluetoothProfileServiceProvider::Delegate * delegate,ProfileRegisteredCallback success_callback,ErrorCompletionCallback error_callback)1492 void BluetoothAdapterBlueZ::SetProfileDelegate(
1493     const BluetoothUUID& uuid,
1494     const dbus::ObjectPath& device_path,
1495     bluez::BluetoothProfileServiceProvider::Delegate* delegate,
1496     ProfileRegisteredCallback success_callback,
1497     ErrorCompletionCallback error_callback) {
1498   if (profiles_.find(uuid) == profiles_.end()) {
1499     std::move(error_callback).Run("Cannot find profile!");
1500     return;
1501   }
1502 
1503   if (profiles_[uuid]->SetDelegate(device_path, delegate)) {
1504     std::move(success_callback).Run(profiles_[uuid]);
1505     return;
1506   }
1507   // Already set
1508   std::move(error_callback).Run(bluetooth_agent_manager::kErrorAlreadyExists);
1509 }
1510 
OnRegisterProfileError(const BluetoothUUID & uuid,const std::string & error_name,const std::string & error_message)1511 void BluetoothAdapterBlueZ::OnRegisterProfileError(
1512     const BluetoothUUID& uuid,
1513     const std::string& error_name,
1514     const std::string& error_message) {
1515   BLUETOOTH_LOG(ERROR) << object_path_.value()
1516                        << ": Failed to register profile: " << error_name << ": "
1517                        << error_message;
1518   if (profile_queues_.find(uuid) == profile_queues_.end())
1519     return;
1520 
1521   for (auto& it : *profile_queues_[uuid])
1522     std::move(it.second).Run(error_message);
1523 
1524   delete profile_queues_[uuid];
1525   profile_queues_.erase(uuid);
1526 }
1527 
OnSetDiscoverable(base::OnceClosure callback,ErrorCallback error_callback,bool success)1528 void BluetoothAdapterBlueZ::OnSetDiscoverable(base::OnceClosure callback,
1529                                               ErrorCallback error_callback,
1530                                               bool success) {
1531   if (!IsPresent()) {
1532     std::move(error_callback).Run();
1533     return;
1534   }
1535 
1536   // Set the discoverable_timeout property to zero so the adapter remains
1537   // discoverable forever.
1538   bluez::BluezDBusManager::Get()
1539       ->GetBluetoothAdapterClient()
1540       ->GetProperties(object_path_)
1541       ->discoverable_timeout.Set(
1542           0, base::BindOnce(&BluetoothAdapterBlueZ::OnPropertyChangeCompleted,
1543                             weak_ptr_factory_.GetWeakPtr(), std::move(callback),
1544                             std::move(error_callback)));
1545 }
1546 
OnPropertyChangeCompleted(base::OnceClosure callback,ErrorCallback error_callback,bool success)1547 void BluetoothAdapterBlueZ::OnPropertyChangeCompleted(
1548     base::OnceClosure callback,
1549     ErrorCallback error_callback,
1550     bool success) {
1551   if (IsPresent() && success) {
1552     std::move(callback).Run();
1553   } else {
1554     std::move(error_callback).Run();
1555   }
1556 }
1557 
GetWeakPtr()1558 base::WeakPtr<BluetoothAdapter> BluetoothAdapterBlueZ::GetWeakPtr() {
1559   return weak_ptr_factory_.GetWeakPtr();
1560 }
1561 
1562 // BluetoothAdapterBlueZ should override SetPowered() instead.
SetPoweredImpl(bool powered)1563 bool BluetoothAdapterBlueZ::SetPoweredImpl(bool powered) {
1564   NOTREACHED();
1565   return false;
1566 }
1567 
UpdateFilter(std::unique_ptr<device::BluetoothDiscoveryFilter> discovery_filter,DiscoverySessionResultCallback callback)1568 void BluetoothAdapterBlueZ::UpdateFilter(
1569     std::unique_ptr<device::BluetoothDiscoveryFilter> discovery_filter,
1570     DiscoverySessionResultCallback callback) {
1571   DCHECK_GT(NumDiscoverySessions(), 0);
1572   if (!IsPresent()) {
1573     std::move(callback).Run(
1574         true, UMABluetoothDiscoverySessionOutcome::ADAPTER_NOT_PRESENT);
1575     return;
1576   }
1577 
1578   BLUETOOTH_LOG(EVENT) << __func__;
1579 
1580   auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback));
1581 
1582   // DCHECK(IsDiscovering()) is removed due to BlueZ bug
1583   // (https://crbug.com/822104).
1584   // TODO(sonnysasaka): Put it back here when BlueZ bug is fixed.
1585   SetDiscoveryFilter(
1586       std::move(discovery_filter),
1587       base::BindOnce(copyable_callback, /*is_error=*/false,
1588                      UMABluetoothDiscoverySessionOutcome::SUCCESS),
1589       base::BindOnce(copyable_callback, true));
1590   return;
1591 }
1592 
StartScanWithFilter(std::unique_ptr<device::BluetoothDiscoveryFilter> discovery_filter,DiscoverySessionResultCallback callback)1593 void BluetoothAdapterBlueZ::StartScanWithFilter(
1594     std::unique_ptr<device::BluetoothDiscoveryFilter> discovery_filter,
1595     DiscoverySessionResultCallback callback) {
1596   DCHECK(discovery_filter.get());
1597 
1598   if (!IsPresent()) {
1599     std::move(callback).Run(
1600         true, UMABluetoothDiscoverySessionOutcome::ADAPTER_NOT_PRESENT);
1601     return;
1602   }
1603 
1604   BLUETOOTH_LOG(EVENT) << __func__;
1605 
1606   auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback));
1607   SetDiscoveryFilter(
1608       std::move(discovery_filter),
1609       base::BindOnce(
1610           &BluetoothAdapterBlueZ::OnPreSetDiscoveryFilter,
1611           weak_ptr_factory_.GetWeakPtr(),
1612           base::BindOnce(copyable_callback, /*is_error=*/false,
1613                          UMABluetoothDiscoverySessionOutcome::SUCCESS),
1614           base::BindOnce(copyable_callback, true)),
1615       base::BindOnce(
1616           &BluetoothAdapterBlueZ::OnPreSetDiscoveryFilterError,
1617           weak_ptr_factory_.GetWeakPtr(),
1618           base::BindOnce(copyable_callback, /*is_error=*/false,
1619                          UMABluetoothDiscoverySessionOutcome::SUCCESS),
1620           base::BindOnce(copyable_callback, true)));
1621 }
1622 
StopScan(DiscoverySessionResultCallback callback)1623 void BluetoothAdapterBlueZ::StopScan(DiscoverySessionResultCallback callback) {
1624 #if BUILDFLAG(IS_ASH)
1625   ble_scan_parser_.reset();
1626 #endif  // BUILDFLAG(IS_ASH)
1627 
1628   // Not having an adapter qualifies as not scanning so we callback a success
1629   if (!IsPresent()) {
1630     std::move(callback).Run(
1631         /*is_error=*/false,
1632         UMABluetoothDiscoverySessionOutcome::ADAPTER_NOT_PRESENT);
1633     return;
1634   }
1635 
1636   BLUETOOTH_LOG(EVENT) << __func__;
1637 
1638   DCHECK_EQ(NumDiscoverySessions(), 0);
1639 
1640   // Confirm that there are no more discovery sessions left.
1641   DCHECK_EQ(NumDiscoverySessions(), 0);
1642   auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback));
1643   bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StopDiscovery(
1644       object_path_,
1645       base::BindOnce(
1646           &BluetoothAdapterBlueZ::OnStopDiscovery,
1647           weak_ptr_factory_.GetWeakPtr(),
1648           base::BindOnce(copyable_callback, /*is_error=*/false,
1649                          UMABluetoothDiscoverySessionOutcome::SUCCESS)),
1650       base::BindOnce(&BluetoothAdapterBlueZ::OnStopDiscoveryError,
1651                      weak_ptr_factory_.GetWeakPtr(),
1652                      base::BindOnce(copyable_callback, /*is_error=*/true)));
1653 }
1654 
SetDiscoveryFilter(std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,base::OnceClosure callback,DiscoverySessionErrorCallback error_callback)1655 void BluetoothAdapterBlueZ::SetDiscoveryFilter(
1656     std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
1657     base::OnceClosure callback,
1658     DiscoverySessionErrorCallback error_callback) {
1659   DCHECK(discovery_filter.get());
1660 
1661   if (!IsPresent()) {
1662     std::move(error_callback)
1663         .Run(UMABluetoothDiscoverySessionOutcome::ADAPTER_REMOVED);
1664     return;
1665   }
1666 
1667   bluez::BluetoothAdapterClient::DiscoveryFilter dbus_discovery_filter;
1668   uint16_t pathloss;
1669   int16_t rssi;
1670   uint8_t transport;
1671   std::set<device::BluetoothUUID> uuids;
1672 
1673   if (discovery_filter->GetPathloss(&pathloss))
1674     dbus_discovery_filter.pathloss = std::make_unique<uint16_t>(pathloss);
1675 
1676   if (discovery_filter->GetRSSI(&rssi))
1677     dbus_discovery_filter.rssi = std::make_unique<int16_t>(rssi);
1678 
1679   transport = discovery_filter->GetTransport();
1680   if (transport == device::BLUETOOTH_TRANSPORT_LE) {
1681     dbus_discovery_filter.transport = std::make_unique<std::string>("le");
1682   } else if (transport == device::BLUETOOTH_TRANSPORT_CLASSIC) {
1683     dbus_discovery_filter.transport = std::make_unique<std::string>("bredr");
1684   } else if (transport == device::BLUETOOTH_TRANSPORT_DUAL) {
1685     dbus_discovery_filter.transport = std::make_unique<std::string>("auto");
1686   }
1687 
1688   discovery_filter->GetUUIDs(uuids);
1689   if (uuids.size()) {
1690     dbus_discovery_filter.uuids = std::make_unique<std::vector<std::string>>();
1691 
1692     for (const auto& it : uuids)
1693       dbus_discovery_filter.uuids.get()->push_back(it.value());
1694   }
1695 
1696   auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback));
1697   auto copyable_error_callback =
1698       base::AdaptCallbackForRepeating(std::move(error_callback));
1699   bluez::BluezDBusManager::Get()
1700       ->GetBluetoothAdapterClient()
1701       ->SetDiscoveryFilter(
1702           object_path_, dbus_discovery_filter,
1703           base::BindOnce(&BluetoothAdapterBlueZ::OnSetDiscoveryFilter,
1704                          weak_ptr_factory_.GetWeakPtr(), copyable_callback,
1705                          copyable_error_callback),
1706           base::BindOnce(&BluetoothAdapterBlueZ::OnSetDiscoveryFilterError,
1707                          weak_ptr_factory_.GetWeakPtr(), copyable_callback,
1708                          copyable_error_callback));
1709 }
1710 
OnStartDiscovery(base::OnceClosure callback,DiscoverySessionErrorCallback error_callback)1711 void BluetoothAdapterBlueZ::OnStartDiscovery(
1712     base::OnceClosure callback,
1713     DiscoverySessionErrorCallback error_callback) {
1714   // Report success on the original request and increment the count.
1715   BLUETOOTH_LOG(EVENT) << __func__;
1716 
1717 #if BUILDFLAG(IS_ASH)
1718   device::BluetoothAdapterFactory::BleScanParserCallback
1719       ble_scan_parser_callback =
1720           device::BluetoothAdapterFactory::GetBleScanParserCallback();
1721   if (ble_scan_parser_callback) {
1722     // To avoid repeatedly restarting a crashed data decoder service,
1723     // don't add a connection error handler here. Wait to establish a
1724     // new connection after all discovery sessions are stopped.
1725     ble_scan_parser_.Bind(ble_scan_parser_callback.Run());
1726   } else {
1727 #if DCHECK_IS_ON()
1728     static bool logged_once = false;
1729     DLOG_IF(ERROR, !logged_once)
1730         << "Attempted to connect to "
1731            "unconfigured BluetoothAdapterFactory::GetBleScanParserCallback()";
1732     logged_once = true;
1733 #endif  // DCHECK_IS_ON()
1734   }
1735 #endif  // BUILDFLAG(IS_ASH)
1736 
1737   if (IsPresent()) {
1738     std::move(callback).Run();
1739   } else {
1740     std::move(error_callback)
1741         .Run(UMABluetoothDiscoverySessionOutcome::ADAPTER_REMOVED);
1742   }
1743 }
1744 
OnStartDiscoveryError(base::OnceClosure callback,DiscoverySessionErrorCallback error_callback,const std::string & error_name,const std::string & error_message)1745 void BluetoothAdapterBlueZ::OnStartDiscoveryError(
1746     base::OnceClosure callback,
1747     DiscoverySessionErrorCallback error_callback,
1748     const std::string& error_name,
1749     const std::string& error_message) {
1750   BLUETOOTH_LOG(ERROR) << object_path_.value()
1751                        << ": Failed to start discovery: " << error_name << ": "
1752                        << error_message;
1753 
1754   std::move(error_callback).Run(TranslateDiscoveryErrorToUMA(error_name));
1755 }
1756 
OnStopDiscovery(base::OnceClosure callback)1757 void BluetoothAdapterBlueZ::OnStopDiscovery(base::OnceClosure callback) {
1758   // Report success on the original request and decrement the count.
1759   BLUETOOTH_LOG(EVENT) << __func__;
1760   DCHECK_GE(NumDiscoverySessions(), 0);
1761   std::move(callback).Run();
1762 }
1763 
OnStopDiscoveryError(DiscoverySessionErrorCallback error_callback,const std::string & error_name,const std::string & error_message)1764 void BluetoothAdapterBlueZ::OnStopDiscoveryError(
1765     DiscoverySessionErrorCallback error_callback,
1766     const std::string& error_name,
1767     const std::string& error_message) {
1768   BLUETOOTH_LOG(ERROR) << object_path_.value()
1769                        << ": Failed to stop discovery: " << error_name << ": "
1770                        << error_message;
1771 
1772   std::move(error_callback).Run(TranslateDiscoveryErrorToUMA(error_name));
1773 }
1774 
OnPreSetDiscoveryFilter(base::OnceClosure callback,DiscoverySessionErrorCallback error_callback)1775 void BluetoothAdapterBlueZ::OnPreSetDiscoveryFilter(
1776     base::OnceClosure callback,
1777     DiscoverySessionErrorCallback error_callback) {
1778   auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback));
1779   auto copyable_error_callback =
1780       base::AdaptCallbackForRepeating(std::move(error_callback));
1781   bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StartDiscovery(
1782       object_path_,
1783       base::BindOnce(&BluetoothAdapterBlueZ::OnStartDiscovery,
1784                      weak_ptr_factory_.GetWeakPtr(), copyable_callback,
1785                      copyable_error_callback),
1786       base::BindOnce(&BluetoothAdapterBlueZ::OnStartDiscoveryError,
1787                      weak_ptr_factory_.GetWeakPtr(), copyable_callback,
1788                      copyable_error_callback));
1789 }
1790 
OnPreSetDiscoveryFilterError(base::OnceClosure callback,DiscoverySessionErrorCallback error_callback,UMABluetoothDiscoverySessionOutcome outcome)1791 void BluetoothAdapterBlueZ::OnPreSetDiscoveryFilterError(
1792     base::OnceClosure callback,
1793     DiscoverySessionErrorCallback error_callback,
1794     UMABluetoothDiscoverySessionOutcome outcome) {
1795   BLUETOOTH_LOG(ERROR) << object_path_.value()
1796                        << ": Failed to pre set discovery filter.";
1797 
1798   std::move(error_callback).Run(outcome);
1799 }
1800 
OnSetDiscoveryFilter(base::OnceClosure callback,DiscoverySessionErrorCallback error_callback)1801 void BluetoothAdapterBlueZ::OnSetDiscoveryFilter(
1802     base::OnceClosure callback,
1803     DiscoverySessionErrorCallback error_callback) {
1804   // Report success on the original request and increment the count.
1805   BLUETOOTH_LOG(EVENT) << __func__;
1806   if (IsPresent()) {
1807     std::move(callback).Run();
1808   } else {
1809     std::move(error_callback)
1810         .Run(UMABluetoothDiscoverySessionOutcome::ADAPTER_REMOVED);
1811   }
1812 }
1813 
OnSetDiscoveryFilterError(base::OnceClosure callback,DiscoverySessionErrorCallback error_callback,const std::string & error_name,const std::string & error_message)1814 void BluetoothAdapterBlueZ::OnSetDiscoveryFilterError(
1815     base::OnceClosure callback,
1816     DiscoverySessionErrorCallback error_callback,
1817     const std::string& error_name,
1818     const std::string& error_message) {
1819   BLUETOOTH_LOG(ERROR) << object_path_.value()
1820                        << ": Failed to set discovery filter: " << error_name
1821                        << ": " << error_message;
1822 
1823   UMABluetoothDiscoverySessionOutcome outcome =
1824       TranslateDiscoveryErrorToUMA(error_name);
1825   if (outcome == UMABluetoothDiscoverySessionOutcome::FAILED) {
1826     // bluez/doc/adapter-api.txt says "Failed" is returned from
1827     // SetDiscoveryFilter when the controller doesn't support the requested
1828     // transport.
1829     outcome = UMABluetoothDiscoverySessionOutcome::
1830         BLUEZ_DBUS_FAILED_MAYBE_UNSUPPORTED_TRANSPORT;
1831   }
1832   std::move(error_callback).Run(outcome);
1833 }
1834 
UpdateRegisteredApplication(bool ignore_unregister_failure,base::OnceClosure callback,device::BluetoothGattService::ErrorCallback error_callback)1835 void BluetoothAdapterBlueZ::UpdateRegisteredApplication(
1836     bool ignore_unregister_failure,
1837     base::OnceClosure callback,
1838     device::BluetoothGattService::ErrorCallback error_callback) {
1839   // If ignore_unregister_failure is set, we'll forward the error_callback to
1840   // the register call (to be called in case the register call fails). If not,
1841   // we'll call the error callback if this unregister itself fails.
1842   auto copyable_error_callback =
1843       base::AdaptCallbackForRepeating(std::move(error_callback));
1844   auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback));
1845   bluez::BluezDBusManager::Get()
1846       ->GetBluetoothGattManagerClient()
1847       ->UnregisterApplication(
1848           object_path_, GetApplicationObjectPath(),
1849           base::BindOnce(&BluetoothAdapterBlueZ::RegisterApplication,
1850                          weak_ptr_factory_.GetWeakPtr(), copyable_callback,
1851                          copyable_error_callback),
1852           ignore_unregister_failure
1853               ? base::BindOnce(
1854                     &BluetoothAdapterBlueZ::RegisterApplicationOnError,
1855                     weak_ptr_factory_.GetWeakPtr(), copyable_callback,
1856                     copyable_error_callback)
1857               : base::BindOnce(&OnRegistrationErrorCallback,
1858                                copyable_error_callback, false));
1859 }
1860 
RegisterApplication(base::OnceClosure callback,device::BluetoothGattService::ErrorCallback error_callback)1861 void BluetoothAdapterBlueZ::RegisterApplication(
1862     base::OnceClosure callback,
1863     device::BluetoothGattService::ErrorCallback error_callback) {
1864   // Recreate our application service provider with the currently registered
1865   // GATT services before we register it.
1866   gatt_application_provider_.reset();
1867   // If we have no services registered, then leave the application unregistered
1868   // and no application provider.
1869   if (registered_gatt_services_.size() == 0) {
1870     std::move(callback).Run();
1871     return;
1872   }
1873   gatt_application_provider_ = BluetoothGattApplicationServiceProvider::Create(
1874       bluez::BluezDBusManager::Get()->GetSystemBus(),
1875       GetApplicationObjectPath(), registered_gatt_services_);
1876 
1877   auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback));
1878   DCHECK(bluez::BluezDBusManager::Get());
1879   bluez::BluezDBusManager::Get()
1880       ->GetBluetoothGattManagerClient()
1881       ->RegisterApplication(object_path_, GetApplicationObjectPath(),
1882                             BluetoothGattManagerClient::Options(),
1883                             copyable_callback,
1884                             base::BindOnce(&OnRegistrationErrorCallback,
1885                                            std::move(error_callback),
1886                                            /*is_register_callback=*/true));
1887 }
1888 
RegisterApplicationOnError(base::OnceClosure callback,device::BluetoothGattService::ErrorCallback error_callback,const std::string &,const std::string &)1889 void BluetoothAdapterBlueZ::RegisterApplicationOnError(
1890     base::OnceClosure callback,
1891     device::BluetoothGattService::ErrorCallback error_callback,
1892     const std::string& /* error_name */,
1893     const std::string& /* error_message */) {
1894   RegisterApplication(std::move(callback), std::move(error_callback));
1895 }
1896 
ServiceRecordErrorConnector(ServiceRecordErrorCallback error_callback,const std::string & error_name,const std::string & error_message)1897 void BluetoothAdapterBlueZ::ServiceRecordErrorConnector(
1898     ServiceRecordErrorCallback error_callback,
1899     const std::string& error_name,
1900     const std::string& error_message) {
1901   BLUETOOTH_LOG(EVENT) << "Creating service record failed: error: "
1902                        << error_name << " - " << error_message;
1903 
1904   BluetoothServiceRecordBlueZ::ErrorCode code =
1905       BluetoothServiceRecordBlueZ::ErrorCode::UNKNOWN;
1906   if (error_name == bluetooth_adapter::kErrorInvalidArguments) {
1907     code = BluetoothServiceRecordBlueZ::ErrorCode::ERROR_INVALID_ARGUMENTS;
1908   } else if (error_name == bluetooth_adapter::kErrorDoesNotExist) {
1909     code = BluetoothServiceRecordBlueZ::ErrorCode::ERROR_RECORD_DOES_NOT_EXIST;
1910   } else if (error_name == bluetooth_adapter::kErrorAlreadyExists) {
1911     code = BluetoothServiceRecordBlueZ::ErrorCode::ERROR_RECORD_ALREADY_EXISTS;
1912   } else if (error_name == bluetooth_adapter::kErrorNotReady) {
1913     code = BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY;
1914   }
1915 
1916   std::move(error_callback).Run(code);
1917 }
1918 
OnConnectDevice(ConnectDeviceCallback callback,const dbus::ObjectPath & object_path)1919 void BluetoothAdapterBlueZ::OnConnectDevice(
1920     ConnectDeviceCallback callback,
1921     const dbus::ObjectPath& object_path) {
1922   std::move(callback).Run(GetDeviceWithPath(object_path));
1923 }
1924 
OnConnectDeviceError(ErrorCallback error_callback,const std::string & error_name,const std::string & error_message)1925 void BluetoothAdapterBlueZ::OnConnectDeviceError(
1926     ErrorCallback error_callback,
1927     const std::string& error_name,
1928     const std::string& error_message) {
1929   std::move(error_callback).Run();
1930 }
1931 
UpdateDeviceBatteryLevelFromBatteryClient(const dbus::ObjectPath & object_path)1932 void BluetoothAdapterBlueZ::UpdateDeviceBatteryLevelFromBatteryClient(
1933     const dbus::ObjectPath& object_path) {
1934   BluetoothDevice* device = GetDeviceWithPath(object_path);
1935 
1936   if (!device) {
1937     BLUETOOTH_LOG(ERROR) << "Trying to update battery for non-existing device";
1938     return;
1939   }
1940 
1941   bluez::BluetoothBatteryClient::Properties* properties =
1942       bluez::BluezDBusManager::Get()
1943           ->GetBluetoothBatteryClient()
1944           ->GetProperties(object_path);
1945 
1946   if (properties && properties->percentage.is_valid()) {
1947     device->SetBatteryPercentage(properties->percentage.value());
1948     return;
1949   }
1950 
1951   // |properties| is null or properties->percentage is not valid, that means
1952   // BlueZ has removed the battery info from the device and we should clear our
1953   // value as well.
1954   device->SetBatteryPercentage(base::nullopt);
1955 }
1956 
1957 }  // namespace bluez
1958