File: fast_pair_pairer_impl.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 (217 lines) | stat: -rw-r--r-- 8,780 bytes parent folder | download | duplicates (6)
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
// 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 ASH_QUICK_PAIR_PAIRING_FAST_PAIR_FAST_PAIR_PAIRER_IMPL_H_
#define ASH_QUICK_PAIR_PAIRING_FAST_PAIR_FAST_PAIR_PAIRER_IMPL_H_

#include <optional>

#include "ash/quick_pair/common/pair_failure.h"
#include "ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client.h"
#include "ash/quick_pair/pairing/fast_pair/fast_pair_pairer.h"
#include "ash/quick_pair/proto/fastpair.pb.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chromeos/ash/services/quick_pair/public/cpp/decrypted_passkey.h"
#include "chromeos/ash/services/quick_pair/public/cpp/decrypted_response.h"
#include "device/bluetooth/bluetooth_device.h"

namespace device {

class BluetoothAdapter;

}  // namespace device

namespace ash {
namespace quick_pair {

class Device;
enum class AccountKeyFailure;
enum class PairFailure;
class FastPairDataEncryptor;
class FastPairHandshake;

class FastPairPairerImpl : public FastPairPairer,
                           public device::BluetoothDevice::PairingDelegate,
                           public device::BluetoothAdapter::Observer {
 public:
  class Factory {
   public:
    static std::unique_ptr<FastPairPairer> Create(
        scoped_refptr<device::BluetoothAdapter> adapter,
        scoped_refptr<Device> device,
        base::OnceCallback<void(scoped_refptr<Device>)> paired_callback,
        base::OnceCallback<void(scoped_refptr<Device>, PairFailure)>
            pair_failed_callback,
        base::OnceCallback<void(scoped_refptr<Device>, AccountKeyFailure)>
            account_key_failure_callback,
        base::OnceCallback<void(std::u16string, uint32_t)> display_passkey,
        base::OnceCallback<void(scoped_refptr<Device>)>
            pairing_procedure_complete);

    static void SetFactoryForTesting(Factory* test_factory);

   protected:
    virtual ~Factory();

    virtual std::unique_ptr<FastPairPairer> CreateInstance(
        scoped_refptr<device::BluetoothAdapter> adapter,
        scoped_refptr<Device> device,
        base::OnceCallback<void(scoped_refptr<Device>)> paired_callback,
        base::OnceCallback<void(scoped_refptr<Device>, PairFailure)>
            pair_failed_callback,
        base::OnceCallback<void(scoped_refptr<Device>, AccountKeyFailure)>
            account_key_failure_callback,
        base::OnceCallback<void(std::u16string, uint32_t)> display_passkey,
        base::OnceCallback<void(scoped_refptr<Device>)>
            pairing_procedure_complete) = 0;

   private:
    static Factory* g_test_factory_;
  };

  FastPairPairerImpl(
      scoped_refptr<device::BluetoothAdapter> adapter,
      scoped_refptr<Device> device,
      base::OnceCallback<void(scoped_refptr<Device>)> paired_callback,
      base::OnceCallback<void(scoped_refptr<Device>, PairFailure)>
          pair_failed_callback,
      base::OnceCallback<void(scoped_refptr<Device>, AccountKeyFailure)>
          account_key_failure_callback,
      base::OnceCallback<void(std::u16string, uint32_t)> display_passkey,
      base::OnceCallback<void(scoped_refptr<Device>)>
          pairing_procedure_complete);
  FastPairPairerImpl(const FastPairPairerImpl&) = delete;
  FastPairPairerImpl& operator=(const FastPairPairerImpl&) = delete;
  FastPairPairerImpl(FastPairPairerImpl&&) = delete;
  FastPairPairerImpl& operator=(FastPairPairerImpl&&) = delete;
  ~FastPairPairerImpl() override;

 private:
  // There are two flows a device can go through for V2 pairing:
  // `device::BluetoothAdapter::ConnectDevice` and
  // `device::BluetoothDevice::Pair`. The flows for each are as follows:
  //
  // ConnectDevice : `ConnectDevice` -> `OnConnectDevice -> `ConfirmPasskey` ->
  // `WritePasskeyAsync` -> `OnPasskeyResponse` -> `DevicePairedChanged`
  //
  // Pair: `Pair` -> `ConfirmPasskey` -> `WritePasskeyAsync` ->
  // `OnPasskeyResponse` -> `DevicePairedChanged` -> `OnPairConnected` ->
  // `Connect` -> `OnConnected`
  //
  // We need to capture which flow we are using in order to correctly stop
  // the bonding timer when the flow has ended, since each has a different
  // end.
  enum class FastPairPairingFlow {
    kConnectDevice,
    kPair,
  };

  // device::BluetoothDevice::PairingDelegate
  void RequestPinCode(device::BluetoothDevice* device) override;
  void ConfirmPasskey(device::BluetoothDevice* device,
                      uint32_t passkey) override;
  void RequestPasskey(device::BluetoothDevice* device) override;
  void DisplayPinCode(device::BluetoothDevice* device,
                      const std::string& pincode) override;
  void DisplayPasskey(device::BluetoothDevice* device,
                      uint32_t passkey) override;
  void KeysEntered(device::BluetoothDevice* device, uint32_t entered) override;
  void AuthorizePairing(device::BluetoothDevice* device) override;

  // device::BluetoothAdapter::Observer
  void DevicePairedChanged(device::BluetoothAdapter* adapter,
                           device::BluetoothDevice* device,
                           bool new_paired_status) override;

  // Helper to safely stop |create_bond_timeout_timer_|.
  // If the timer can be stopped because it is running, this function returns
  // true. If the timer cannot be stopped, this function returns false,
  // informing the caller that the timer has expired and the caller should not
  // proceed with bond creation.
  bool StopCreateBondTimer(const std::string& callback_name);

  // device::BluetoothDevice::Pair callback
  void OnPairConnected(
      std::optional<device::BluetoothDevice::ConnectErrorCode> error);

  // device::BluetoothDevice::Connect callback
  void OnConnected(
      std::optional<device::BluetoothDevice::ConnectErrorCode> error);

  // device::BluetoothAdapter::ConnectDevice callbacks
  void OnConnectDevice(device::BluetoothDevice* device);
  void OnConnectError(const std::string& error_message);

  // Callback for timeout on creating a bond with |device_| in
  // StartPairing.
  void OnCreateBondTimeout();

  //  FastPairHandshakeLookup::Create callback
  void OnHandshakeComplete(scoped_refptr<Device> device,
                           std::optional<PairFailure> failure);

  // FastPairGattServiceClient::WritePasskey callback
  void OnPasskeyResponse(std::vector<uint8_t> response_bytes,
                         std::optional<PairFailure> failure);

  // FastPairDataEncryptor::ParseDecryptedPasskey callback
  void OnParseDecryptedPasskey(base::TimeTicks decrypt_start_time,
                               const std::optional<DecryptedPasskey>& passkey);

  // FastPairRepository::IsDeviceSavedToAccount callback
  void OnIsDeviceSavedToAccount(bool is_device_saved_to_account);

  // FastPairRepository::CheckOptInStatus callback
  void OnCheckOptInStatus(nearby::fastpair::OptInStatus status);

  // FastPairRepository::UpdateOptInStatus callback
  void OnUpdateOptInStatus(bool success);

  // Creates a 16-byte array of random bytes with a first byte of 0x04 to
  // signal Fast Pair account key, and then writes to the device.
  void AttemptSendAccountKey();

  // FastPairDataEncryptor::WriteAccountKey callback
  void OnWriteAccountKey(std::array<uint8_t, 16> account_key,
                         std::optional<AccountKeyFailure> error);

  void StartPairing();

  void WriteAccountKey();

  FastPairPairingFlow pairing_flow_;
  uint32_t expected_passkey_;
  scoped_refptr<device::BluetoothAdapter> adapter_;
  scoped_refptr<Device> device_;
  std::string pairing_device_address_;
  base::OnceCallback<void(scoped_refptr<Device>)> paired_callback_;
  base::OnceCallback<void(scoped_refptr<Device>, PairFailure)>
      pair_failed_callback_;
  base::OnceCallback<void(scoped_refptr<Device>, AccountKeyFailure)>
      account_key_failure_callback_;
  base::OnceCallback<void(std::u16string, uint32_t)> display_passkey_;
  base::OnceCallback<void(scoped_refptr<Device>)> pairing_procedure_complete_;
  raw_ptr<FastPairHandshake, DanglingUntriaged> fast_pair_handshake_ = nullptr;
  base::ScopedObservation<device::BluetoothAdapter,
                          device::BluetoothAdapter::Observer>
      adapter_observation_{this};

  // A timer to time the bonding with |device_| in StartPairing and invoke a
  // timeout if necessary.
  base::OneShotTimer create_bond_timeout_timer_;
  base::TimeTicks create_bond_start_time_;

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

}  // namespace quick_pair
}  // namespace ash

#endif  // ASH_QUICK_PAIR_PAIRING_FAST_PAIR_FAST_PAIR_PAIRER_IMPL_H_