File: bluetooth_device_floss.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (364 lines) | stat: -rw-r--r-- 15,045 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef DEVICE_BLUETOOTH_FLOSS_BLUETOOTH_DEVICE_FLOSS_H_
#define DEVICE_BLUETOOTH_FLOSS_BLUETOOTH_DEVICE_FLOSS_H_

#include <string>

#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_common.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_export.h"
#include "device/bluetooth/bluetooth_socket_thread.h"
#include "device/bluetooth/floss/bluetooth_adapter_floss.h"
#include "device/bluetooth/floss/bluetooth_pairing_floss.h"
#include "device/bluetooth/floss/bluetooth_socket_floss.h"
#include "device/bluetooth/floss/floss_adapter_client.h"
#include "device/bluetooth/floss/floss_gatt_manager_client.h"

namespace floss {

// BluetoothDeviceFloss implements device::BluetoothDevice for platforms using
// Floss (Linux front-end for Fluoride). Objects of this type should be managed
// by BluetoothAdapterFloss, which also manages device lifetimes.
//
// This class is not thread-safe but is only called from the UI thread.
class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceFloss
    : public device::BluetoothDevice,
      public FlossGattClientObserver {
 public:
  enum class ConnectingState {
    kIdle = 0,
    kACLConnecting,
    kProfilesConnecting,
    kProfilesConnected,
  };
  enum class GattConnectingState {
    kGattDisconnected = 0,
    kGattConnecting,
    kGattConnected,
    // Initial state, no prior connection built. Use direct connection.
    kGattConnectionInit,
  };
  enum PropertiesState : uint32_t {
    kNotRead = 0,
    kTriggeredByScan = 1 << 1,
    kTriggeredByInquiry = 1 << 2,
    kTriggeredbyBoth = (kTriggeredByScan | kTriggeredByInquiry)
  };

  BluetoothDeviceFloss(const BluetoothDeviceFloss&) = delete;
  BluetoothDeviceFloss& operator=(const BluetoothDeviceFloss&) = delete;

  BluetoothDeviceFloss(
      BluetoothAdapterFloss* adapter,
      const FlossDeviceId& device,
      scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
      scoped_refptr<device::BluetoothSocketThread> socket_thread);
  ~BluetoothDeviceFloss() override;

  // BluetoothDevice override
  uint32_t GetBluetoothClass() const override;
  device::BluetoothTransport GetType() const override;
  std::string GetAddress() const override;
  AddressType GetAddressType() const override;
  VendorIDSource GetVendorIDSource() const override;
  uint16_t GetVendorID() const override;
  uint16_t GetProductID() const override;
  uint16_t GetDeviceID() const override;
  uint16_t GetAppearance() const override;
  std::optional<std::string> GetName() const override;
  bool IsPaired() const override;
#if BUILDFLAG(IS_CHROMEOS)
  bool IsBonded() const override;
#endif  // BUILDFLAG(IS_CHROMEOS)
  bool IsConnected() const override;
  bool IsGattConnected() const override;
  bool IsConnectable() const override;
  bool IsConnecting() const override;
  UUIDSet GetUUIDs() const override;
  std::optional<int8_t> GetInquiryTxPower() const override;
  bool ExpectingPinCode() const override;
  bool ExpectingPasskey() const override;
  bool ExpectingConfirmation() const override;
  void GetConnectionInfo(ConnectionInfoCallback callback) override;
  void SetConnectionLatency(ConnectionLatency connection_latency,
                            base::OnceClosure callback,
                            ErrorCallback error_callback) override;
  void Connect(device::BluetoothDevice::PairingDelegate* pairing_delegate,
               ConnectCallback callback) override;
#if BUILDFLAG(IS_CHROMEOS)
  void ConnectClassic(
      device::BluetoothDevice::PairingDelegate* pairing_delegate,
      ConnectCallback callback) override;
#endif  // BUILDFLAG(IS_CHROMEOS)
  void SetPinCode(const std::string& pincode) override;
  void SetPasskey(uint32_t passkey) override;
  void ConfirmPairing() override;
  void RejectPairing() override;
  void CancelPairing() override;
  void Disconnect(base::OnceClosure callback,
                  ErrorCallback error_callback) override;
  void Forget(base::OnceClosure callback,
              ErrorCallback error_callback) override;
  void ConnectToService(const device::BluetoothUUID& uuid,
                        ConnectToServiceCallback callback,
                        ConnectToServiceErrorCallback error_callback) override;
  void ConnectToServiceInsecurely(
      const device::BluetoothUUID& uuid,
      ConnectToServiceCallback callback,
      ConnectToServiceErrorCallback error_callback) override;
  std::unique_ptr<device::BluetoothGattConnection>
  CreateBluetoothGattConnectionObject() override;
  void SetGattServicesDiscoveryComplete(bool complete) override;
  bool IsGattServicesDiscoveryComplete() const override;
  void Pair(device::BluetoothDevice::PairingDelegate* pairing_delegate,
            ConnectCallback callback) override;
  BluetoothPairingFloss* BeginPairing(
      BluetoothDevice::PairingDelegate* pairing_delegate);
#if BUILDFLAG(IS_CHROMEOS)
  bool UsingReliableWrite() const { return using_reliable_write_; }
  void BeginReliableWrite();
  void ExecuteWrite(base::OnceClosure callback,
                    ExecuteWriteErrorCallback error_callback) override;
  void AbortWrite(base::OnceClosure callback,
                  AbortWriteErrorCallback error_callback) override;
#endif  // BUILDFLAG(IS_CHROMEOS)

  FlossDeviceId AsFlossDeviceId() const;
  // Floss always distinguishes between IsBonded and IsPaired so provide
  // a publicly accessible implementation.
  bool IsBondedImpl() const;
  void SetName(const std::string& name);
  FlossAdapterClient::BondState GetBondState() { return bond_state_; }
  void SetBondState(
      FlossAdapterClient::BondState bond_state,
      std::optional<BluetoothDevice::ConnectErrorCode> error_code);
  void SetIsConnected(bool is_connected);
  void SetConnectionState(uint32_t state);
  void ResetPairing();

  BluetoothPairingFloss* pairing() const { return pairing_.get(); }

  void InitializeDeviceProperties(PropertiesState state,
                                  base::OnceClosure callback);
  bool IsReadingProperties() const {
    return property_reads_triggered_ != PropertiesState::kNotRead;
  }
  bool HasReadProperties() const {
    return property_reads_completed_ != PropertiesState::kNotRead;
  }
  PropertiesState GetPropertiesState() const {
    return property_reads_completed_;
  }

  // FlossGattClientObserver overrides
  void GattClientConnectionState(GattStatus status,
                                 int32_t client_id,
                                 bool connected,
                                 std::string address) override;
  void GattSearchComplete(std::string address,
                          const std::vector<GattService>& services,
                          GattStatus status) override;
  void GattConnectionUpdated(std::string address,
                             int32_t interval,
                             int32_t latency,
                             int32_t timeout,
                             GattStatus status) override;
  void GattConfigureMtu(std::string address,
                        int32_t mtu,
                        GattStatus status) override;
#if BUILDFLAG(IS_CHROMEOS)
  void GattServiceChanged(std::string address) override;
  void GattExecuteWrite(std::string address, GattStatus status) override;
#endif

  // Returns the adapter which owns this device instance.
  BluetoothAdapterFloss* adapter() const {
    return static_cast<BluetoothAdapterFloss*>(adapter_);
  }

  // Methods for fetching device properties.
  void FetchRemoteType(base::OnceClosure callback);
  void FetchRemoteClass(base::OnceClosure callback);
  void FetchRemoteAppearance(base::OnceClosure callback);
  void FetchRemoteUuids(base::OnceClosure callback);
  void FetchRemoteVendorProductInfo(base::OnceClosure callback);
  void FetchRemoteAddressType(base::OnceClosure callback);
  void FetchRemoteBondState(base::OnceClosure callback);
  void FetchRemoteConnectionState(base::OnceClosure callback);

  void OnDeviceConnectionFailed(FlossDBusClient::BtifStatus status);

 protected:
  // BluetoothDevice override
  void CreateGattConnectionImpl(
      std::optional<device::BluetoothUUID> service_uuid) override;
  void UpgradeToFullDiscovery() override;
  void DisconnectGatt() override;

 private:
  // Invoked when no connection established during connecting.
  void ConnectionIncomplete();
  // Connects with specified transport
  void ConnectWithTransport(
      device::BluetoothDevice::PairingDelegate* pairing_delegate,
      ConnectCallback callback,
      FlossAdapterClient::BluetoothTransport transport);
  // Method to connect profiles.
  void ConnectAllEnabledProfiles();
  // Updates the state of connecting and calls callbacks accordingly.
  void UpdateConnectingState(
      ConnectingState state,
      std::optional<BluetoothDevice::ConnectErrorCode> error);
  // Updates the state of gatt connecting.
  void UpdateGattConnectingState(GattConnectingState state);
  // Triggers the pending callback of Connect() method.
  void TriggerConnectCallback(
      std::optional<BluetoothDevice::ConnectErrorCode> error_code);

  void OnGetRemoteType(base::OnceClosure callback,
                       DBusResult<FlossAdapterClient::BluetoothDeviceType> ret);
  void OnGetRemoteClass(base::OnceClosure callback, DBusResult<uint32_t> ret);
  void OnGetRemoteAppearance(base::OnceClosure callback,
                             DBusResult<uint16_t> ret);
  void OnGetRemoteVendorProductInfo(
      base::OnceClosure callback,
      DBusResult<FlossAdapterClient::VendorProductInfo> ret);
  void OnGetRemoteUuids(base::OnceClosure callback, DBusResult<UUIDList> ret);
  void OnGetRemoteAddressType(
      base::OnceClosure callback,
      DBusResult<FlossAdapterClient::BtAddressType> ret);
  void OnGetRemoteBondState(base::OnceClosure callback,
                            DBusResult<uint32_t> ret);
  void OnGetRemoteConnectionState(base::OnceClosure callback,
                                  DBusResult<uint32_t> ret);
  void OnConnectAllEnabledProfiles(DBusResult<Void> ret);
  void OnConnectAllEnabledProfiles(DBusResult<FlossDBusClient::BtifStatus> ret);
  void OnDisconnectAllEnabledProfiles(base::OnceClosure callback,
                                      ErrorCallback error_callback,
                                      DBusResult<Void> ret);

  // Intercept errors when connecting to an L2CAP or RFCOMM socket. This keeps
  // a reference to the |socket| so that it does not go out of scope until after
  // the error is completed.
  void OnConnectToServiceError(scoped_refptr<BluetoothSocketFloss> socket,
                               ConnectToServiceErrorCallback error_callback,
                               const std::string& error_message);

  void TriggerInitDevicePropertiesCallback();
  void OnConnectGatt(DBusResult<Void> ret);
  void OnSetConnectionLatency(base::OnceClosure callback,
                              ErrorCallback error_callback,
                              DBusResult<Void> ret);
  void OnCreateBond(DBusResult<bool> ret);
  void OnCreateBond(DBusResult<FlossDBusClient::BtifStatus> ret);

#if BUILDFLAG(IS_CHROMEOS)
  void OnExecuteWrite(base::OnceClosure callback,
                      ExecuteWriteErrorCallback error_callback,
                      DBusResult<Void> ret);
#endif  // BUILDFLAG(IS_CHROMEOS)

  std::optional<ConnectCallback> pending_callback_on_connect_profiles_ =
      std::nullopt;

  // Timer to stop waiting for a successful connect complete.
  base::OneShotTimer connection_incomplete_timer_;

  std::optional<base::OnceClosure> pending_callback_on_init_props_ =
      std::nullopt;

  // Callbacks for a pending |SetConnectionLatency|.
  std::optional<std::pair<base::OnceClosure, ErrorCallback>>
      pending_set_connection_latency_ = std::nullopt;

#if BUILDFLAG(IS_CHROMEOS)
  // Callbacks for a pending |ExecuteWrite| or |AbortWrite|.
  std::optional<std::pair<base::OnceClosure, ExecuteWriteErrorCallback>>
      pending_execute_write_ = std::nullopt;

  // Writes are using reliable writes.
  bool using_reliable_write_ = false;
#endif  // BUILDFLAG(IS_CHROMEOS)

  // Number of pending device properties to initialize
  int num_pending_properties_ = 0;

  // Address of this device. Changing this should necessitate creating a new
  // BluetoothDeviceFloss object.
  const std::string address_;

  // Name of this device. Can be queried later and isn't mandatory for creation.
  std::string name_;

  // Transport type of device.
  device::BluetoothTransport transport_ =
      device::BluetoothTransport::BLUETOOTH_TRANSPORT_CLASSIC;

  // Class of device.
  uint32_t cod_ = 0;

  // Appearance of device.
  uint16_t appearance_ = 0;

  // Vendor and product info of device.
  FlossAdapterClient::VendorProductInfo vpi_;

  // Address type of device.
  AddressType address_type_ = AddressType::ADDR_TYPE_UNKNOWN;

  // Whether the device is bonded/paired.
  FlossAdapterClient::BondState bond_state_ =
      FlossAdapterClient::BondState::kNotBonded;

  // Whether the device is connected at link layer level (not profile level).
  // Updated via |SetIsConnected| only.
  bool is_acl_connected_ = false;

  // Are all services resolved? Only true if full discovery is completed. See
  // |IsGattServicesDiscoveryComplete| for more info.
  bool svc_resolved_ = false;

  // Have we triggered initial property reads?
  PropertiesState property_reads_triggered_ = PropertiesState::kNotRead;

  // Have we completed reading properties?
  PropertiesState property_reads_completed_ = PropertiesState::kNotRead;

  // Specific uuid to search for after gatt connection is established. If this
  // is not set, then we do full discovery.
  std::optional<device::BluetoothUUID> search_uuid;

  // Similar to is_acl_connected_ but contains the full connection state
  // (including encryption). This is updated when |SetConnectionState| is called
  // or when |SetIsConnected| is called.
  // (https://android.googlesource.com/platform/system/bt/+/refs/heads/android10-c2f2-release/btif/src/btif_dm.cc#737),
  // This is used for determining if the device is paired.
  uint32_t connection_state_ = 0;

  // The status of profile connecting.
  ConnectingState connecting_state_ = ConnectingState::kIdle;

  // The status of GATT connecting.
  GattConnectingState gatt_connecting_state_ =
      GattConnectingState::kGattConnectionInit;

  // UI thread task runner and socket thread used to create sockets.
  scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
  scoped_refptr<device::BluetoothSocketThread> socket_thread_;

  // Represents currently ongoing pairing with this remote device.
  std::unique_ptr<BluetoothPairingFloss> pairing_;

  base::WeakPtrFactory<BluetoothDeviceFloss> weak_ptr_factory_{this};
};

}  // namespace floss

#endif  // DEVICE_BLUETOOTH_FLOSS_BLUETOOTH_DEVICE_FLOSS_H_