1 // Copyright (c) 2012 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 #ifndef DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_H_
6 #define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <memory>
12 #include <set>
13 #include <string>
14 #include <unordered_map>
15 #include <unordered_set>
16 #include <vector>
17 
18 #include "base/callback.h"
19 #include "base/containers/flat_set.h"
20 #include "base/containers/span.h"
21 #include "base/gtest_prod_util.h"
22 #include "base/macros.h"
23 #include "base/memory/ref_counted.h"
24 #include "base/optional.h"
25 #include "base/strings/string16.h"
26 #include "base/strings/string_piece_forward.h"
27 #include "base/time/time.h"
28 #include "build/build_config.h"
29 #include "build/chromeos_buildflags.h"
30 #include "device/bluetooth/bluetooth_common.h"
31 #include "device/bluetooth/bluetooth_export.h"
32 #include "device/bluetooth/bluetooth_remote_gatt_service.h"
33 #include "device/bluetooth/public/cpp/bluetooth_uuid.h"
34 
35 namespace device {
36 
37 class BluetoothAdapter;
38 class BluetoothGattConnection;
39 class BluetoothSocket;
40 
41 // BluetoothDevice represents a remote Bluetooth device, both its properties and
42 // capabilities as discovered by a local adapter and actions that may be
43 // performed on the remove device such as pairing, connection and disconnection.
44 //
45 // The class is instantiated and managed by the BluetoothAdapter class
46 // and pointers should only be obtained from that class and not cached,
47 // instead use the GetAddress() method as a unique key for a device.
48 //
49 // Since the lifecycle of BluetoothDevice instances is managed by
50 // BluetoothAdapter, that class rather than this provides observer methods
51 // for devices coming and going, as well as properties being updated.
52 class DEVICE_BLUETOOTH_EXPORT BluetoothDevice {
53  public:
54   // Possible values that may be returned by GetVendorIDSource(),
55   // indicating different organisations that allocate the identifiers returned
56   // by GetVendorID().
57   enum VendorIDSource {
58     VENDOR_ID_UNKNOWN,
59     VENDOR_ID_BLUETOOTH,
60     VENDOR_ID_USB,
61     VENDOR_ID_MAX_VALUE = VENDOR_ID_USB
62   };
63 
64   // Possible values that may be returned by GetAddressType().
65   enum AddressType {
66     ADDR_TYPE_UNKNOWN,
67     ADDR_TYPE_PUBLIC,
68     ADDR_TYPE_RANDOM,
69   };
70 
71   // The value returned if the RSSI or transmit power cannot be read.
72   static const int kUnknownPower = 127;
73   // The value returned if the appearance is not present.
74   static const uint16_t kAppearanceNotPresent = 0xffc0;
75 
76   struct DEVICE_BLUETOOTH_EXPORT ConnectionInfo {
77     int rssi;
78     int transmit_power;
79     int max_transmit_power;
80 
81     ConnectionInfo();
82     ConnectionInfo(int rssi, int transmit_power, int max_transmit_power);
83     ~ConnectionInfo();
84   };
85 
86   // Possible connection latency values to pass to SetConnectionLatency().
87   enum ConnectionLatency {
88     CONNECTION_LATENCY_LOW,
89     CONNECTION_LATENCY_MEDIUM,
90     CONNECTION_LATENCY_HIGH,
91   };
92 
93   // Possible errors passed back to an error callback function in case of a
94   // failed call to Connect().
95   enum ConnectErrorCode {
96     ERROR_AUTH_CANCELED,
97     ERROR_AUTH_FAILED,
98     ERROR_AUTH_REJECTED,
99     ERROR_AUTH_TIMEOUT,
100     ERROR_FAILED,
101     ERROR_INPROGRESS,
102     ERROR_UNKNOWN,
103     ERROR_UNSUPPORTED_DEVICE,
104     NUM_CONNECT_ERROR_CODES  // Keep as last enum.
105   };
106 
107   typedef std::vector<BluetoothUUID> UUIDList;
108   typedef base::flat_set<BluetoothUUID> UUIDSet;
109   typedef std::unordered_map<BluetoothUUID,
110                              std::vector<uint8_t>,
111                              BluetoothUUIDHash>
112       ServiceDataMap;
113   typedef uint16_t ManufacturerId;
114   typedef std::unordered_map<ManufacturerId, std::vector<uint8_t>>
115       ManufacturerDataMap;
116   typedef std::unordered_set<ManufacturerId> ManufacturerIDSet;
117 
118   // Mapping from the platform-specific GATT service identifiers to
119   // BluetoothRemoteGattService objects.
120   typedef std::unordered_map<std::string,
121                              std::unique_ptr<BluetoothRemoteGattService>>
122       GattServiceMap;
123 
124   // Interface for negotiating pairing of bluetooth devices.
125   class PairingDelegate {
126    public:
~PairingDelegate()127     virtual ~PairingDelegate() {}
128 
129     // This method will be called when the Bluetooth daemon requires a
130     // PIN Code for authentication of the device |device|, the delegate should
131     // obtain the code from the user and call SetPinCode() on the device to
132     // provide it, or RejectPairing() or CancelPairing() to reject or cancel
133     // the request.
134     //
135     // PIN Codes are generally required for Bluetooth 2.0 and earlier devices
136     // for which there is no automatic pairing or special handling.
137     virtual void RequestPinCode(BluetoothDevice* device) = 0;
138 
139     // This method will be called when the Bluetooth daemon requires a
140     // Passkey for authentication of the device |device|, the delegate should
141     // obtain the passkey from the user (a numeric in the range 0-999999) and
142     // call SetPasskey() on the device to provide it, or RejectPairing() or
143     // CancelPairing() to reject or cancel the request.
144     //
145     // Passkeys are generally required for Bluetooth 2.1 and later devices
146     // which cannot provide input or display on their own, and don't accept
147     // passkey-less pairing.
148     virtual void RequestPasskey(BluetoothDevice* device) = 0;
149 
150     // This method will be called when the Bluetooth daemon requires that the
151     // user enter the PIN code |pincode| into the device |device| so that it
152     // may be authenticated.
153     //
154     // This is used for Bluetooth 2.0 and earlier keyboard devices, the
155     // |pincode| will always be a six-digit numeric in the range 000000-999999
156     // for compatibility with later specifications.
157     virtual void DisplayPinCode(BluetoothDevice* device,
158                                 const std::string& pincode) = 0;
159 
160     // This method will be called when the Bluetooth daemon requires that the
161     // user enter the Passkey |passkey| into the device |device| so that it
162     // may be authenticated.
163     //
164     // This is used for Bluetooth 2.1 and later devices that support input
165     // but not display, such as keyboards. The Passkey is a numeric in the
166     // range 0-999999 and should be always presented zero-padded to six
167     // digits.
168     virtual void DisplayPasskey(BluetoothDevice* device, uint32_t passkey) = 0;
169 
170     // This method will be called when the Bluetooth daemon gets a notification
171     // of a key entered on the device |device| while pairing with the device
172     // using a PIN code or a Passkey.
173     //
174     // This method will be called only after DisplayPinCode() or
175     // DisplayPasskey() method is called, but is not warranted to be called
176     // on every pairing process that requires a PIN code or a Passkey because
177     // some device may not support this feature.
178     //
179     // The |entered| value describes the number of keys entered so far,
180     // including the last [enter] key. A first call to KeysEntered() with
181     // |entered| as 0 will be sent when the device supports this feature.
182     virtual void KeysEntered(BluetoothDevice* device, uint32_t entered) = 0;
183 
184     // This method will be called when the Bluetooth daemon requires that the
185     // user confirm that the Passkey |passkey| is displayed on the screen
186     // of the device |device| so that it may be authenticated. The delegate
187     // should display to the user and ask for confirmation, then call
188     // ConfirmPairing() on the device to confirm, RejectPairing() on the device
189     // to reject or CancelPairing() on the device to cancel authentication
190     // for any other reason.
191     //
192     // This is used for Bluetooth 2.1 and later devices that support display,
193     // such as other computers or phones. The Passkey is a numeric in the
194     // range 0-999999 and should be always present zero-padded to six
195     // digits.
196     virtual void ConfirmPasskey(BluetoothDevice* device, uint32_t passkey) = 0;
197 
198     // This method will be called when the Bluetooth daemon requires that a
199     // pairing request, usually only incoming, using the just-works model is
200     // authorized. The delegate should decide whether the user should confirm
201     // or not, then call ConfirmPairing() on the device to confirm the pairing
202     // (whether by user action or by default), RejectPairing() on the device to
203     // reject or CancelPairing() on the device to cancel authorization for
204     // any other reason.
205     virtual void AuthorizePairing(BluetoothDevice* device) = 0;
206   };
207 
208   virtual ~BluetoothDevice();
209 
210   // Clamps numbers less than -128 to -128 and numbers greater than 127 to 127.
211   static int8_t ClampPower(int power);
212 
213   // Returns the Bluetooth class of the device, used by GetDeviceType()
214   // and metrics logging,
215   virtual uint32_t GetBluetoothClass() const = 0;
216 
217 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
218   // Returns the transport type of the device. Some devices only support one
219   // of BR/EDR or LE, and some support both.
220   virtual BluetoothTransport GetType() const = 0;
221 #endif
222 
223   // Returns the identifier of the bluetooth device.
224   virtual std::string GetIdentifier() const;
225 
226   // Returns the Bluetooth of address the device. This should be used as
227   // a unique key to identify the device and copied where needed.
228   virtual std::string GetAddress() const = 0;
229 
230   // Returns the Bluetooth address type of the device. Currently available on
231   // Linux and Chrome OS.
232   virtual AddressType GetAddressType() const = 0;
233 
234   // Returns the allocation source of the identifier returned by GetVendorID(),
235   // where available, or VENDOR_ID_UNKNOWN where not.
236   virtual VendorIDSource GetVendorIDSource() const = 0;
237 
238   // Returns the Vendor ID of the device, where available.
239   virtual uint16_t GetVendorID() const = 0;
240 
241   // Returns the Product ID of the device, where available.
242   virtual uint16_t GetProductID() const = 0;
243 
244   // Returns the Device ID of the device, typically the release or version
245   // number in BCD format, where available.
246   virtual uint16_t GetDeviceID() const = 0;
247 
248   // Returns the appearance of the device.
249   virtual uint16_t GetAppearance() const = 0;
250 
251   // Returns the name of the device, which may be empty.
252   virtual base::Optional<std::string> GetName() const = 0;
253 
254   // Returns the name of the device suitable for displaying, this may
255   // be a synthesized string containing the address and localized type name
256   // if the device has no obtained name.
257   virtual base::string16 GetNameForDisplay() const;
258 
259   // Returns the type of the device, limited to those we support or are
260   // aware of, by decoding the bluetooth class information. The returned
261   // values are unique, and do not overlap, so DEVICE_KEYBOARD is not also
262   // DEVICE_PERIPHERAL.
263   //
264   // Returns the type of the device, limited to those we support or are aware
265   // of, by decoding the bluetooth class information for Classic devices or
266   // by decoding the device's appearance for LE devices. For example,
267   // Microsoft Universal Foldable Keyboard only advertises the appearance.
268   virtual BluetoothDeviceType GetDeviceType() const;
269 
270   // Indicates whether the device is known to support pairing based on its
271   // device class and address.
272   bool IsPairable() const;
273 
274   // Indicates whether the device is paired with the adapter.
275   virtual bool IsPaired() const = 0;
276 
277   // Indicates whether the device is currently connected to the adapter.
278   // Note that if IsConnected() is true, does not imply that the device is
279   // connected to any application or service. If the device is not paired, it
280   // could be still connected to the adapter for other reason, for example, to
281   // request the adapter's SDP records. The same holds for paired devices, since
282   // they could be connected to the adapter but not to an application.
283   virtual bool IsConnected() const = 0;
284 
285   // Indicates whether an active GATT connection exists to the device.
286   virtual bool IsGattConnected() const = 0;
287 
288   // Indicates whether the paired device accepts connections initiated from the
289   // adapter. This value is undefined for unpaired devices. Only available for
290   // Chrome OS.
291   virtual bool IsConnectable() const = 0;
292 
293   // Indicates whether there is a call to Connect() ongoing. For this attribute,
294   // we consider a call is ongoing if none of the callbacks passed to Connect()
295   // were called after the corresponding call to Connect().
296   virtual bool IsConnecting() const = 0;
297 
298   // Returns the set of UUIDs that this device supports.
299   //  * For classic Bluetooth devices this data is collected from both the EIR
300   //    data and SDP tables.
301   //  * For non-connected and connected Low Energy Devices for which services
302   //    have not been discovered returns the latest advertised UUIDs.
303   //  * For connected Low Energy Devices for which services have been discovered
304   //    returns the UUIDs of the device's services and the latest advertised
305   //    UUIDs.
306   //  * For dual mode devices this may be collected from both.
307   //
308   // Note: On Android, Mac and WinRT advertised UUIDs are cleared when the
309   // adapter stops discovering, as otherwise stale data might be returned.
310   //
311   // Note: On ChromeOS and Linux, BlueZ persists all services meaning if
312   // a device stops advertising a service this function will still return
313   // its UUID.
314   virtual UUIDSet GetUUIDs() const;
315 
316   // Returns the last advertised Service Data. Returns an empty map if the
317   // adapter is not discovering.
318   //
319   // Note: On ChromeOS and Linux, BlueZ persists all service data meaning if
320   // a device stops advertising service data for a UUID, this function will
321   // still return the cached value for that UUID.
322   const ServiceDataMap& GetServiceData() const;
323 
324   // Returns the UUIDs of services for which the device advertises Service Data.
325   // Returns an empty set if the adapter is not discovering.
326   UUIDSet GetServiceDataUUIDs() const;
327 
328   // Returns a pointer to the Service Data for Service with |uuid|. Returns
329   // nullptr if |uuid| has no Service Data.
330   const std::vector<uint8_t>* GetServiceDataForUUID(
331       const BluetoothUUID& uuid) const;
332 
333   // Returns advertised Manufacturer Data. Keys are 16 bits Manufacturer IDs
334   // followed by its byte array value. Returns an empty map if the device
335   // does not advertise any Manufacturer Data.
336   // Returns cached value if the adapter is not discovering.
337   //
338   // Note: On ChromeOS and Linux, BlueZ persists all manufacturer data meaning
339   // if a device stops advertising manufacturer data for a Manufacturer Id, this
340   // function will still return the cached value for that Id.
341   //
342   // TODO(crbug.com/661814) Support this on platforms that don't use BlueZ.
343   // Only BlueZ supports this now. This method returns an empty map on platforms
344   // that don't use BlueZ.
345   const ManufacturerDataMap& GetManufacturerData() const;
346 
347   // Returns the Manufacturer Data IDs of Manufacturers for which the device
348   // advertises Manufacturer Data.
349   // Returns cached value if the adapter is not discovering.
350   ManufacturerIDSet GetManufacturerDataIDs() const;
351 
352   // Returns a pointer to the Manufacturer Data for Manufacturer with
353   // |manufacturerID|. Returns nullptr if |manufacturerID| has no Manufacturer
354   // Data. Returns cached value if the adapter is not discovering.
355   const std::vector<uint8_t>* GetManufacturerDataForID(
356       const ManufacturerId manufacturerID) const;
357 
358   // The received signal strength, in dBm. This field is avaliable and valid
359   // only during discovery.
360   // TODO(http://crbug.com/580406): Devirtualize once BlueZ sets inquiry_rssi_.
361   virtual base::Optional<int8_t> GetInquiryRSSI() const;
362 
363   // The transmitted power level. This field is avaliable only for LE devices
364   // that include this field in AD. It is avaliable and valid only during
365   // discovery.
366   // TODO(http://crbug.com/580406): Devirtualize once BlueZ sets
367   // inquiry_tx_power_.
368   virtual base::Optional<int8_t> GetInquiryTxPower() const;
369 
370   // Returns Advertising Data Flags.
371   // Returns cached value if the adapter is not discovering.
372   //
373   // Only Chrome OS and WinRT support this now. Upstream BlueZ has this feature
374   // as experimental. This method returns base::nullopt on platforms that don't
375   // support this feature.
376   base::Optional<uint8_t> GetAdvertisingDataFlags() const;
377 
378   // The ErrorCallback is used for methods that can fail in which case it
379   // is called, in the success case the callback is simply not called.
380   using ErrorCallback = base::OnceClosure;
381 
382   // The ConnectErrorCallback is used for methods that can fail with an error,
383   // passed back as an error code argument to this callback.
384   // In the success case this callback is not called.
385   using ConnectErrorCallback = base::OnceCallback<void(enum ConnectErrorCode)>;
386 
387   using ConnectionInfoCallback =
388       base::OnceCallback<void(const ConnectionInfo&)>;
389 
390   // Indicates whether the device is currently pairing and expecting a
391   // PIN Code to be returned.
392   virtual bool ExpectingPinCode() const = 0;
393 
394   // Indicates whether the device is currently pairing and expecting a
395   // Passkey to be returned.
396   virtual bool ExpectingPasskey() const = 0;
397 
398   // Indicates whether the device is currently pairing and expecting
399   // confirmation of a displayed passkey.
400   virtual bool ExpectingConfirmation() const = 0;
401 
402   // Returns the RSSI and TX power of the active connection to the device:
403   //
404   // The RSSI indicates the power present in the received radio signal, measured
405   // in dBm, to a resolution of 1dBm. Larger (typically, less negative) values
406   // indicate a stronger signal.
407   //
408   // The transmit power indicates the strength of the signal broadcast from the
409   // host's Bluetooth antenna when communicating with the device, measured in
410   // dBm, to a resolution of 1dBm. Larger (typically, less negative) values
411   // indicate a stronger signal.
412   //
413   // If the device isn't connected, then the ConnectionInfo struct passed into
414   // the callback will be populated with |kUnknownPower|.
415   virtual void GetConnectionInfo(ConnectionInfoCallback callback) = 0;
416 
417   // Sets the connection latency for the device. This API is only valid for LE
418   // devices.
419   virtual void SetConnectionLatency(ConnectionLatency connection_latency,
420                                     base::OnceClosure callback,
421                                     ErrorCallback error_callback) = 0;
422 
423   // Initiates a connection to the device, pairing first if necessary.
424   //
425   // Method calls will be made on the supplied object |pairing_delegate|
426   // to indicate what display, and in response should make method calls
427   // back to the device object. Not all devices require user responses
428   // during pairing, so it is normal for |pairing_delegate| to receive no
429   // calls. To explicitly force a low-security connection without bonding,
430   // pass NULL, though this is ignored if the device is already paired.
431   //
432   // If the request fails, |error_callback| will be called; otherwise,
433   // |callback| is called when the request is complete.
434   // After calling Connect, CancelPairing should be called to cancel the pairing
435   // process and release the pairing delegate if user cancels the pairing and
436   // closes the pairing UI.
437   virtual void Connect(PairingDelegate* pairing_delegate,
438                        base::OnceClosure callback,
439                        ConnectErrorCallback error_callback) = 0;
440 
441   // Pairs the device. This method triggers pairing unconditially, i.e. it
442   // ignores the |IsPaired()| value.
443   //
444   // In most cases |Connect()| should be preferred. This method is only
445   // implemented on ChromeOS, Linux and Windows 10. On Windows, only pairing
446   // with a pin code is currently supported.
447   virtual void Pair(PairingDelegate* pairing_delegate,
448                     base::OnceClosure callback,
449                     ConnectErrorCallback error_callback);
450 
451   // Sends the PIN code |pincode| to the remote device during pairing.
452   //
453   // PIN Codes are generally required for Bluetooth 2.0 and earlier devices
454   // for which there is no automatic pairing or special handling.
455   virtual void SetPinCode(const std::string& pincode) = 0;
456 
457   // Sends the Passkey |passkey| to the remote device during pairing.
458   //
459   // Passkeys are generally required for Bluetooth 2.1 and later devices
460   // which cannot provide input or display on their own, and don't accept
461   // passkey-less pairing, and are a numeric in the range 0-999999.
462   virtual void SetPasskey(uint32_t passkey) = 0;
463 
464   // Confirms to the remote device during pairing that a passkey provided by
465   // the ConfirmPasskey() delegate call is displayed on both devices.
466   virtual void ConfirmPairing() = 0;
467 
468   // Rejects a pairing or connection request from a remote device.
469   virtual void RejectPairing() = 0;
470 
471   // Cancels a pairing or connection attempt to a remote device, releasing
472   // the pairing delegate.
473   virtual void CancelPairing() = 0;
474 
475   // Disconnects the device, terminating the low-level ACL connection
476   // and any application connections using it. Link keys and other pairing
477   // information are not discarded, and the device object is not deleted.
478   // If the request fails, |error_callback| will be called; otherwise,
479   // |callback| is called when the request is complete.
480   virtual void Disconnect(base::OnceClosure callback,
481                           ErrorCallback error_callback) = 0;
482 
483   // Disconnects the device, terminating the low-level ACL connection
484   // and any application connections using it, and then discards link keys
485   // and other pairing information. The device object remains valid until
486   // returning from the calling function, after which it should be assumed to
487   // have been deleted. If the request fails, |error_callback| will be called.
488   // On success |callback| will be invoked, but note that the BluetoothDevice
489   // object will have been deleted at that point.
490   virtual void Forget(base::OnceClosure callback,
491                       ErrorCallback error_callback) = 0;
492 
493   // Attempts to initiate an outgoing L2CAP or RFCOMM connection to the
494   // advertised service on this device matching |uuid|, performing an SDP lookup
495   // if necessary to determine the correct protocol and channel for the
496   // connection. |callback| will be called on a successful connection with a
497   // BluetoothSocket instance that is to be owned by the receiver.
498   // |error_callback| will be called on failure with a message indicating the
499   // cause.
500   using ConnectToServiceCallback =
501       base::OnceCallback<void(scoped_refptr<BluetoothSocket>)>;
502   using ConnectToServiceErrorCallback =
503       base::OnceCallback<void(const std::string& message)>;
504   virtual void ConnectToService(
505       const BluetoothUUID& uuid,
506       ConnectToServiceCallback callback,
507       ConnectToServiceErrorCallback error_callback) = 0;
508 
509   // Attempts to initiate an insecure outgoing L2CAP or RFCOMM connection to the
510   // advertised service on this device matching |uuid|, performing an SDP lookup
511   // if necessary to determine the correct protocol and channel for the
512   // connection. Unlike ConnectToService, the outgoing connection will request
513   // no bonding rather than general bonding. |callback| will be called on a
514   // successful connection with a BluetoothSocket instance that is to be owned
515   // by the receiver. |error_callback| will be called on failure with a message
516   // indicating the cause.
517   virtual void ConnectToServiceInsecurely(
518       const device::BluetoothUUID& uuid,
519       ConnectToServiceCallback callback,
520       ConnectToServiceErrorCallback error_callback) = 0;
521 
522   // Opens a new GATT connection to this device. On success, a new
523   // BluetoothGattConnection will be handed to the caller via |callback|. On
524   // error, |error_callback| will be called. The connection will be kept alive,
525   // as long as there is at least one active GATT connection. In the case that
526   // the underlying connection gets terminated, either due to a call to
527   // BluetoothDevice::Disconnect or other unexpected circumstances, the
528   // returned BluetoothGattConnection will be automatically marked as inactive.
529   // To monitor the state of the connection, observe the
530   // BluetoothAdapter::Observer::DeviceChanged method.
531   //
532   // If |service_uuid| is given, potentially only the service with the given
533   // UUID will be discovered. This may speed up GATT discovery times if the
534   // platform can take advantage of this optimisation. Note that passing
535   // |service_uuid| may cause full GATT service discovery to be skipped. In that
536   // case, |IsGattServicesDiscoveryComplete| will not become true but
537   // |BluetoothAdapter::Observer::GattServicesDiscovered| is still the correct
538   // event to watch for.
539   using GattConnectionCallback =
540       base::OnceCallback<void(std::unique_ptr<BluetoothGattConnection>)>;
541   virtual void CreateGattConnection(
542       GattConnectionCallback callback,
543       ConnectErrorCallback error_callback,
544       base::Optional<BluetoothUUID> service_uuid = base::nullopt);
545 
546   // Set the gatt services discovery complete flag for this device.
547   virtual void SetGattServicesDiscoveryComplete(bool complete);
548 
549   // Indicates whether full service discovery is complete for this device. If a
550   // |service_uuid| was passed to |CreateGattConnection| and a focused discovery
551   // was performed, then this will continue to return false even after discovery
552   // is complete.
553   virtual bool IsGattServicesDiscoveryComplete() const;
554 
555   // Returns the list of discovered GATT services.
556   virtual std::vector<BluetoothRemoteGattService*> GetGattServices() const;
557 
558   // Returns the GATT service with device-specific identifier |identifier|.
559   // Returns NULL, if no such service exists.
560   virtual BluetoothRemoteGattService* GetGattService(
561       const std::string& identifier) const;
562 
563   // Update the last time this device was seen.
564   void UpdateTimestamp();
565 
566   // Returns the time of the last call to UpdateTimestamp(), or base::Time() if
567   // it hasn't been called yet.
568   virtual base::Time GetLastUpdateTime() const;
569 
570   // Called by BluetoothAdapter when a new Advertisement is seen for this
571   // device. This replaces previously seen Advertisement Data. The order of
572   // arguments matches the order of their corresponding Data Type specified in
573   // https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile.
574   void UpdateAdvertisementData(int8_t rssi,
575                                base::Optional<uint8_t> flags,
576                                UUIDList advertised_uuids,
577                                base::Optional<int8_t> tx_power,
578                                ServiceDataMap service_data,
579                                ManufacturerDataMap manufacturer_data);
580 
581   // Called by BluetoothAdapter when it stops discoverying.
582   void ClearAdvertisementData();
583 
584   // Return associated BluetoothAdapter.
GetAdapter()585   BluetoothAdapter* GetAdapter() { return adapter_; }
586 
587   std::vector<BluetoothRemoteGattService*> GetPrimaryServices();
588 
589   std::vector<BluetoothRemoteGattService*> GetPrimaryServicesByUUID(
590       const BluetoothUUID& service_uuid);
591 
592 #if BUILDFLAG(IS_ASH)
593   using ExecuteWriteErrorCallback =
594       base::OnceCallback<void(device::BluetoothGattService::GattErrorCode)>;
595   using AbortWriteErrorCallback =
596       base::OnceCallback<void(device::BluetoothGattService::GattErrorCode)>;
597   // Executes all the previous prepare writes in a reliable write session.
598   virtual void ExecuteWrite(base::OnceClosure callback,
599                             ExecuteWriteErrorCallback error_callback) = 0;
600   // Aborts all the previous prepare writes in a reliable write session.
601   virtual void AbortWrite(base::OnceClosure callback,
602                           AbortWriteErrorCallback error_callback) = 0;
603 #endif
604 
605 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
606   // Set the remaining battery of the device to show in the UI. This value must
607   // be between 0 and 100, inclusive.
608   // TODO(http://b/160905785): Battery percentage is populated by
609   // ash::HfpBatteryListener, ash::HidBatteryListener, and
610   // device::BluetoothAdapterBlueZ. When Battery information is entirely
611   // consolidated in BlueZ's Battery API, only device::BluetoothAdapterBlueZ
612   // should have control over this field with the value originating from a
613   // single source, the BlueZ Battery API..
614   void SetBatteryPercentage(base::Optional<uint8_t> battery_percentage);
615 
616   // Returns the remaining battery for the device.
battery_percentage()617   const base::Optional<uint8_t>& battery_percentage() const {
618     return battery_percentage_;
619   }
620 #endif
621 
622   // Returns whether this device supports discovering specific services, i.e.
623   // whether the |service_uuid| argument to |CreateGattConnection| is
624   // meaningful. This should only be called by tests. Non-test code should
625   // optimistically pass a |service_uuid| argument if appropriate for the need.
626   bool supports_service_specific_discovery() const;
627 
628  protected:
629   // BluetoothGattConnection is a friend to call Add/RemoveGattConnection.
630   friend BluetoothGattConnection;
631   FRIEND_TEST_ALL_PREFIXES(
632       BluetoothTest,
633       BluetoothGattConnection_DisconnectGatt_SimulateConnect);
634   FRIEND_TEST_ALL_PREFIXES(
635       BluetoothTest,
636       BluetoothGattConnection_DisconnectGatt_SimulateDisconnect);
637   FRIEND_TEST_ALL_PREFIXES(BluetoothTest,
638                            BluetoothGattConnection_ErrorAfterConnection);
639   FRIEND_TEST_ALL_PREFIXES(BluetoothTest,
640                            BluetoothGattConnection_DisconnectGatt_Cleanup);
641   FRIEND_TEST_ALL_PREFIXES(BluetoothTest, GetName_NullName);
642   FRIEND_TEST_ALL_PREFIXES(BluetoothTest, RemoveOutdatedDevices);
643   FRIEND_TEST_ALL_PREFIXES(BluetoothTest, RemoveOutdatedDeviceGattConnect);
644 
645   FRIEND_TEST_ALL_PREFIXES(
646       BluetoothTestWinrtOnly,
647       BluetoothGattConnection_DisconnectGatt_SimulateConnect);
648   FRIEND_TEST_ALL_PREFIXES(
649       BluetoothTestWinrtOnly,
650       BluetoothGattConnection_DisconnectGatt_SimulateDisconnect);
651   FRIEND_TEST_ALL_PREFIXES(BluetoothTestWinrtOnly,
652                            BluetoothGattConnection_ErrorAfterConnection);
653   FRIEND_TEST_ALL_PREFIXES(BluetoothTestWinrtOnly,
654                            BluetoothGattConnection_DisconnectGatt_Cleanup);
655 
656   // Helper class to easily update the sets of UUIDs and keep them in sync with
657   // the set of all the device's UUIDs.
658   class DEVICE_BLUETOOTH_EXPORT DeviceUUIDs {
659    public:
660     DeviceUUIDs();
661     ~DeviceUUIDs();
662 
663     DeviceUUIDs(const DeviceUUIDs& other);
664     DeviceUUIDs& operator=(const DeviceUUIDs& other);
665 
666     // Advertised Service UUIDs functions
667     void ReplaceAdvertisedUUIDs(UUIDList new_advertised_uuids);
668 
669     void ClearAdvertisedUUIDs();
670 
671     // Service UUIDs functions
672     void ReplaceServiceUUIDs(
673         const BluetoothDevice::GattServiceMap& gatt_services);
674 
675     void ClearServiceUUIDs();
676 
677     // Returns the union of Advertised UUIDs and Service UUIDs.
678     const UUIDSet& GetUUIDs() const;
679 
680    private:
681     void UpdateDeviceUUIDs();
682 
683     BluetoothDevice::UUIDSet advertised_uuids_;
684     BluetoothDevice::UUIDSet service_uuids_;
685     BluetoothDevice::UUIDSet device_uuids_;
686   };
687 
688   explicit BluetoothDevice(BluetoothAdapter* adapter);
689 
690   // Implements platform specific operations to initiate a GATT connection.
691   // Subclasses must also call DidConnectGatt, DidFailToConnectGatt, or
692   // DidDisconnectGatt immediately or asynchronously as the connection state
693   // changes.
694   virtual void CreateGattConnectionImpl(
695       base::Optional<BluetoothUUID> service_uuid) = 0;
696 
697   // UpgradeToFullDiscovery is called when there is a pending or current GATT
698   // connection that was created with a service UUID, but now discovery of all
699   // services is required because of a new connection request. This will only
700   // be called if the subclass sets |supports_service_specific_discovery_|.
701   virtual void UpgradeToFullDiscovery();
702 
703   // Disconnects GATT connection on platforms that maintain a specific GATT
704   // connection.
705   virtual void DisconnectGatt() = 0;
706 
707   // Returns a |BluetoothGattConnection| object that represents a reference to a
708   // GATT connection to this device.
709   virtual std::unique_ptr<BluetoothGattConnection>
710   CreateBluetoothGattConnectionObject();
711 
712   // Calls any pending callbacks for CreateGattConnection based on result of
713   // subclasses actions initiated in CreateGattConnectionImpl or related
714   // disconnection events. These may be called at any time, even multiple times,
715   // to ensure a change in platform state is correctly tracked.
716   //
717   // Under normal behavior it is expected that after CreateGattConnectionImpl
718   // an platform will call DidConnectGatt or DidFailToConnectGatt, but not
719   // DidDisconnectGatt.
720   void DidConnectGatt();
721   void DidFailToConnectGatt(ConnectErrorCode);
722   void DidDisconnectGatt();
723 
724   // Tracks BluetoothGattConnection instances that act as a reference count
725   // keeping the GATT connection open. Instances call Add/RemoveGattConnection
726   // at creation & deletion.
727   void AddGattConnection(BluetoothGattConnection*);
728   void RemoveGattConnection(BluetoothGattConnection*);
729 
730   // Update last_update_time_ so that the device appears as expired.
731   void SetAsExpiredForTesting();
732 
733   // Raw pointer to adapter owning this device object. Subclasses use platform
734   // specific pointers via adapter_.
735   BluetoothAdapter* const adapter_;
736 
737   // Indicates whether this device supports limited discovery of a specific
738   // service. This is configured by the constructor of subclasses. If false,
739   // the UUID argument to |CreateGattConnection| is ignored.
740   bool supports_service_specific_discovery_ = false;
741 
742   // Contains the specified service that was targeted for discovery. Only ever
743   // contains a value if |supports_service_specific_discovery_| is true.
744   base::Optional<BluetoothUUID> target_service_;
745 
746   // Callbacks for pending success and error result of CreateGattConnection.
747   std::vector<GattConnectionCallback> create_gatt_connection_success_callbacks_;
748   std::vector<ConnectErrorCallback> create_gatt_connection_error_callbacks_;
749 
750   // BluetoothGattConnection objects keeping the GATT connection alive.
751   std::set<BluetoothGattConnection*> gatt_connections_;
752 
753   GattServiceMap gatt_services_;
754   bool gatt_services_discovery_complete_;
755 
756   // Received Signal Strength Indicator of the advertisement received.
757   base::Optional<int8_t> inquiry_rssi_;
758 
759   // Advertising Data flags of the device.
760   base::Optional<uint8_t> advertising_data_flags_;
761 
762   // Tx Power advertised by the device.
763   base::Optional<int8_t> inquiry_tx_power_;
764 
765   // Class that holds the union of Advertised UUIDs and Service UUIDs.
766   DeviceUUIDs device_uuids_;
767 
768   // Map of BluetoothUUIDs to their advertised Service Data.
769   ServiceDataMap service_data_;
770 
771   // Map of Manufacturer IDs to their advertised Manufacturer Data.
772   ManufacturerDataMap manufacturer_data_;
773 
774   // Timestamp for when an advertisement was last seen.
775   base::Time last_update_time_;
776 
777  private:
778   // Returns a localized string containing the device's bluetooth address and
779   // a device type for display when |name_| is empty.
780   base::string16 GetAddressWithLocalizedDeviceTypeName() const;
781 
782 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
783   // Remaining battery level of the device.
784   // TODO(https://crbug.com/973237): This field is different from others because
785   // it is not filled by the platform. In the future, when there is a unified
786   // Mojo service, this field will be moved to BluetoothDeviceInfo.
787   base::Optional<uint8_t> battery_percentage_;
788 #endif
789 
790   DISALLOW_COPY_AND_ASSIGN(BluetoothDevice);
791 };
792 
793 }  // namespace device
794 
795 #endif  // DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_H_
796