summaryrefslogtreecommitdiffstats
path: root/components/proximity_auth/ble/proximity_auth_ble_system.h
blob: 2a82aead279ace681d3a02aa0bf1fb6a4639c1f9 (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
// Copyright 2015 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 COMPONENTS_PROXIMITY_AUTH_BLE_PROXIMITY_AUTH_BLE_SYSTEM_H_
#define COMPONENTS_PROXIMITY_AUTH_BLE_PROXIMITY_AUTH_BLE_SYSTEM_H_

#include <map>
#include <string>

#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "components/proximity_auth/connection_observer.h"
#include "components/proximity_auth/cryptauth/cryptauth_client.h"
#include "components/proximity_auth/screenlock_bridge.h"

class PrefRegistrySimple;
class PrefService;

namespace device {
class BluetoothGattConnection;
}

namespace proximity_auth {

class BluetoothLowEnergyConnection;
class BluetoothLowEnergyConnectionFinder;
class BluetoothLowEnergyDeviceWhitelist;
class BluetoothThrottler;
class Connection;
class ConnectionFinder;
class ProximityAuthClient;

// This is the main entry point to start Proximity Auth over Bluetooth Low
// Energy. This is the underlying system for the Smart Lock features. It will
// discover Bluetooth Low Energy phones and unlock the lock screen if the phone
// passes an authorization and authentication protocol.
class ProximityAuthBleSystem : public ScreenlockBridge::Observer,
                               public ConnectionObserver {
 public:
  ProximityAuthBleSystem(
      ScreenlockBridge* screenlock_bridge,
      ProximityAuthClient* proximity_auth_client,
      scoped_ptr<CryptAuthClientFactory> cryptauth_client_factory,
      PrefService* pref_service);
  ~ProximityAuthBleSystem() override;

  // Registers the prefs used by this class
  static void RegisterPrefs(PrefRegistrySimple* registry);

  // ScreenlockBridge::Observer:
  void OnScreenDidLock(
      ScreenlockBridge::LockHandler::ScreenType screen_type) override;
  void OnScreenDidUnlock(
      ScreenlockBridge::LockHandler::ScreenType screen_type) override;
  void OnFocusedUserChanged(const std::string& user_id) override;

  // proximity_auth::ConnectionObserver:
  void OnConnectionStatusChanged(Connection* connection,
                                 Connection::Status old_status,
                                 Connection::Status new_status) override;
  void OnMessageReceived(const Connection& connection,
                         const WireMessage& message) override;

 protected:
  class ScreenlockBridgeAdapter {
   public:
    ScreenlockBridgeAdapter(ScreenlockBridge* screenlock_bridge);
    virtual ~ScreenlockBridgeAdapter();

    virtual void AddObserver(ScreenlockBridge::Observer* observer);
    virtual void RemoveObserver(ScreenlockBridge::Observer* observer);
    virtual void Unlock(ProximityAuthClient* client);

   protected:
    ScreenlockBridgeAdapter();

   private:
    // Not owned. Must outlive this object.
    ScreenlockBridge* screenlock_bridge_;
  };

  // Used for testing.
  ProximityAuthBleSystem(scoped_ptr<ScreenlockBridgeAdapter> screenlock_bridge,
                         ProximityAuthClient* proximity_auth_client);

  // Virtual for testing.
  virtual ConnectionFinder* CreateConnectionFinder();

 private:
  // Fetches the the public keys of devices that can be used as unlock keys.
  void GetUnlockKeys();

  // Checks if the devices in |device_whitelist_| have their public keys
  // registered in CryptAuth (|unlock_keys_|), removes the ones that do not.
  void RemoveStaleWhitelistedDevices();

  // Callbacks for cryptauth::CryptAuthClient::GetMyDevices.
  void OnGetMyDevices(const cryptauth::GetMyDevicesResponse& response);
  void OnGetMyDevicesError(const std::string& error);

  // Handler for a new connection found event.
  void OnConnectionFound(scoped_ptr<Connection> connection);

  // Start (recurrently) polling every |polling_interval_| ms for the screen
  // state of the remote device.
  void StartPollingScreenState();

  // Stop polling for screen state of the remote device, if currently active.
  void StopPollingScreenState();

  // Checks if |message| contains a valid public key (registered in
  // |unlock_keys_|). If so, returns the public key in |out_public_key|.
  bool HasUnlockKey(const std::string& message, std::string* out_public_key);

  scoped_ptr<ScreenlockBridgeAdapter> screenlock_bridge_;

  // Not owned. Must outlive this object.
  ProximityAuthClient* proximity_auth_client_;

  // Creates CryptAuth client instances to make API calls.
  scoped_ptr<CryptAuthClientFactory> cryptauth_client_factory_;

  // We only support one concurrent API call.
  scoped_ptr<CryptAuthClient> cryptauth_client_;

  // Maps devices public keys to the device friendly name.
  std::map<std::string, std::string> unlock_keys_;

  scoped_ptr<ConnectionFinder> connection_finder_;

  scoped_ptr<Connection> connection_;

  scoped_ptr<BluetoothLowEnergyDeviceWhitelist> device_whitelist_;

  scoped_ptr<BluetoothThrottler> bluetooth_throttler_;

  const base::TimeDelta polling_interval_;

  // True if the remote device sent public key contained in |unlock_keyes_| or
  // |device_whitelist_|.
  bool device_authenticated_;

  // True if the screen is locked and call to |screenlock_bridge_->Unlock()| was
  // made, but |OnScreenDidUnlock| was not called yet. This is a guard to avoid
  // a double |screenlock_bridge_->Unlock()| call.
  bool unlock_requested_;

  bool is_polling_screen_state_;

  // True if a call to |GetUnlockKeys()| was already made.
  bool unlock_keys_requested_;

  base::WeakPtrFactory<ProximityAuthBleSystem> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(ProximityAuthBleSystem);
};

}  // namespace proximity_auth

#endif  // COMPONENTS_PROXIMITY_AUTH_BLE_PROXIMITY_AUTH_BLE_SYSTEM_H_