summaryrefslogtreecommitdiff
path: root/chromium/device/bluetooth/bluetooth_device_winrt.h
blob: 16d57e9b52d8352965252acff3d1366bca9aa9a3 (plain)
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
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_WINRT_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_WINRT_H_

#include <windows.devices.bluetooth.genericattributeprofile.h>
#include <windows.devices.bluetooth.h>
#include <wrl/client.h>

#include <stdint.h>

#include <memory>
#include <string>

#include "base/callback_forward.h"
#include "base/feature_list.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/win/windows_version.h"
#include "device/base/features.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_export.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace device {

class BluetoothAdapterWinrt;
class BluetoothGattDiscovererWinrt;
class BluetoothPairingWinrt;
class BluetoothUUID;

class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceWinrt : public BluetoothDevice {
 public:
  // Constants required to extract the tx power level and service data from the
  // raw advertisementment data. Reference:
  // https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
  static constexpr uint8_t kTxPowerLevelDataSection = 0x0A;
  static constexpr uint8_t k16BitServiceDataSection = 0x16;
  static constexpr uint8_t k32BitServiceDataSection = 0x20;
  static constexpr uint8_t k128BitServiceDataSection = 0x21;

  BluetoothDeviceWinrt(BluetoothAdapterWinrt* adapter, uint64_t raw_address);

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

  ~BluetoothDeviceWinrt() override;

  // BluetoothDevice:
  uint32_t GetBluetoothClass() 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;
  absl::optional<std::string> GetName() const override;
  bool IsPaired() const override;
  bool IsConnected() const override;
  bool IsGattConnected() const override;
  bool IsConnectable() const override;
  bool IsConnecting() 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(PairingDelegate* pairing_delegate,
               ConnectCallback callback) override;
  void Pair(PairingDelegate* pairing_delegate,
            ConnectCallback callback) override;
  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 BluetoothUUID& uuid,
                        ConnectToServiceCallback callback,
                        ConnectToServiceErrorCallback error_callback) override;
  void ConnectToServiceInsecurely(
      const device::BluetoothUUID& uuid,
      ConnectToServiceCallback callback,
      ConnectToServiceErrorCallback error_callback) override;

  // Returns the |address| in the canonical format: XX:XX:XX:XX:XX:XX, where
  // each 'X' is a hex digit.
  static std::string CanonicalizeAddress(uint64_t address);

  // Called by BluetoothAdapterWinrt when an advertisement packet is received.
  void UpdateLocalName(absl::optional<std::string> local_name);

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

  // Declared virtual so that it can be overridden by tests.
  virtual HRESULT GetBluetoothLEDeviceStaticsActivationFactory(
      ABI::Windows::Devices::Bluetooth::IBluetoothLEDeviceStatics** statics)
      const;

  // Declared virtual so that it can be overridden by tests.
  virtual HRESULT GetGattSessionStaticsActivationFactory(
      ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
          IGattSessionStatics** statics) const;

  Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice>
      ble_device_;
  Microsoft::WRL::ComPtr<
      ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattSession>
      gatt_session_;

 private:
  void OnBluetoothLEDeviceFromBluetoothAddress(
      Microsoft::WRL::ComPtr<
          ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice> ble_device);

  void OnGattSessionFromDeviceId(
      Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::
                                 GenericAttributeProfile::IGattSession>
          gatt_session);

  void OnGattSessionStatusChanged(
      ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattSession*
          gatt_session,
      ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
          IGattSessionStatusChangedEventArgs* event_args);

  void OnConnectionStatusChanged(
      ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice* ble_device,
      IInspectable* object);

  void OnGattServicesChanged(
      ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice* ble_device,
      IInspectable* object);

  void OnNameChanged(
      ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice* ble_device,
      IInspectable* object);

  void StartGattDiscovery();
  void OnGattDiscoveryComplete(bool success);
  void NotifyGattConnectFailure();

  void ClearGattServices();
  void ClearEventRegistrations();

  ABI::Windows::Devices::Bluetooth::BluetoothConnectionStatus
      connection_status_;
  ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattSessionStatus
      gatt_session_status_;
  uint64_t raw_address_;
  std::string address_;
  absl::optional<std::string> local_name_;

  std::unique_ptr<BluetoothPairingWinrt> pairing_;

  // Indicates whether the device should subscribe to GattSession
  // SessionStatusChanged events. Doing so requires calling
  // BluetoothLEDevice::GetDeviceId() which is only available on 1709
  // (RS3) or newer. If false, GATT connection reliability may be
  // degraded.
  bool observe_gatt_session_status_change_events_ =
      base::FeatureList::IsEnabled(kNewBLEGattSessionHandling) &&
      base::win::GetVersion() >= base::win::Version::WIN10_RS3;

  // Indicates whether a GATT service discovery is imminent. Discovery
  // begins once GattSessionStatus for the device changes to |Active|
  // if |observe_gatt_session_status_change_events_| is true, or once
  // the BluetoothLEDevice has been obtained from
  // FromBluetoothAddressAsync() otherwise.
  bool pending_gatt_service_discovery_start_ = false;

  absl::optional<BluetoothUUID> target_uuid_;
  std::unique_ptr<BluetoothGattDiscovererWinrt> gatt_discoverer_;

  absl::optional<EventRegistrationToken> connection_changed_token_;
  absl::optional<EventRegistrationToken> gatt_session_status_changed_token_;
  absl::optional<EventRegistrationToken> gatt_services_changed_token_;
  absl::optional<EventRegistrationToken> name_changed_token_;

  THREAD_CHECKER(thread_checker_);

  // Note: This should remain the last member so it'll be destroyed and
  // invalidate its weak pointers before any other members are destroyed.
  base::WeakPtrFactory<BluetoothDeviceWinrt> weak_ptr_factory_{this};
};

}  // namespace device

#endif  // DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_WINRT_H_