summaryrefslogtreecommitdiffstats
path: root/components/proximity_auth/proximity_monitor_impl.h
blob: 1f0e8a20c6381cc3cf14e54d4924812368a78055 (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
// 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_PROXIMITY_MONITOR_IMPL_H
#define COMPONENTS_PROXIMITY_AUTH_PROXIMITY_MONITOR_IMPL_H

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "components/proximity_auth/proximity_monitor.h"
#include "components/proximity_auth/remote_device.h"
#include "device/bluetooth/bluetooth_device.h"

namespace base {
class TickClock;
class TimeTicks;
}

namespace device {
class BluetoothAdapter;
}

namespace proximity_auth {

class ProximityMonitorObserver;

// The concrete implemenation of the proximity monitor interface.
class ProximityMonitorImpl : public ProximityMonitor {
 public:
  // The |observer| is not owned, and must outlive |this| instance.
  ProximityMonitorImpl(const RemoteDevice& remote_device,
                       scoped_ptr<base::TickClock> clock,
                       ProximityMonitorObserver* observer);
  ~ProximityMonitorImpl() override;

  // ProximityMonitor:
  void Start() override;
  void Stop() override;
  Strategy GetStrategy() const override;
  bool IsUnlockAllowed() const override;
  bool IsInRssiRange() const override;
  void RecordProximityMetricsOnAuthSuccess() override;

 protected:
  // Sets the proximity detection strategy. Exposed for testing.
  // TODO(isherman): Stop exposing this for testing once prefs are properly
  // hooked up.
  virtual void SetStrategy(Strategy strategy);

 private:
  struct TransmitPowerReading {
    TransmitPowerReading(int transmit_power, int max_transmit_power);

    // Returns true if |this| transmit power reading indicates proximity.
    bool IsInProximity() const;

    // The current transmit power.
    int transmit_power;

    // The maximum possible transmit power.
    int max_transmit_power;
  };

  // Callback for asynchronous initialization of the Bluetooth adpater.
  void OnAdapterInitialized(scoped_refptr<device::BluetoothAdapter> adapter);

  // Ensures that the app is periodically polling for the proximity status
  // between the remote and the local device iff it should be, based on the
  // current app state.
  void UpdatePollingState();

  // Performs a scheduled |UpdatePollingState()| operation. This method is
  // used to distinguish periodically scheduled calls to |UpdatePollingState()|
  // from event-driven calls, which should be handled differently.
  void PerformScheduledUpdatePollingState();

  // Returns |true| iff the app should be periodically polling for the proximity
  // status between the remote and the local device.
  bool ShouldPoll() const;

  // Polls the connection information.
  void Poll();

  // Callback to received the polled-for connection info.
  void OnConnectionInfo(
      const device::BluetoothDevice::ConnectionInfo& connection_info);

  // Resets the proximity state to |false|, and clears all member variables
  // tracking the proximity state.
  void ClearProximityState();

  // Updates the proximity state with a new |connection_info| sample of the
  // current RSSI and Tx power, and the device's maximum Tx power.
  void AddSample(
      const device::BluetoothDevice::ConnectionInfo& connection_info);

  // Checks whether the proximity state has changed based on the current
  // samples. Notifies the |observer_| on a change.
  void CheckForProximityStateChange();

  const RemoteDevice remote_device_;

  // The |observer_| is not owned, and must outlive |this| instance.
  ProximityMonitorObserver* observer_;

  // The Bluetooth adapter that will be polled for connection info.
  scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;

  // The strategy used to determine whether the remote device is in proximity.
  Strategy strategy_;

  // Whether the remote device is currently in close proximity to the local
  // device.
  bool remote_device_is_in_proximity_;

  // Whether the proximity monitor is active, i.e. should possibly be scanning
  // for proximity to the remote device.
  bool is_active_;

  // The exponentailly weighted rolling average of the RSSI, used to smooth the
  // RSSI readings. Null if the monitor is inactive, has not recently observed
  // an RSSI reading, or the most recent connection info included an invalid
  // measurement.
  scoped_ptr<double> rssi_rolling_average_;

  // The last TX power reading. Null if the monitor is inactive, has not
  // recently observed a TX power reading, or the most recent connection info
  // included an invalid measurement.
  scoped_ptr<TransmitPowerReading> last_transmit_power_reading_;

  // The timestamp of the last zero RSSI reading. An RSSI value of 0 is special
  // because both devices adjust their transmit powers such that the RSSI is in
  // this golden range, if possible. Null if the monitor is inactive, has not
  // recently observed an RSSI reading, or the most recent connection info
  // included an invalid measurement.
  scoped_ptr<base::TimeTicks> last_zero_rssi_timestamp_;

  // Used to access non-decreasing time measurements.
  scoped_ptr<base::TickClock> clock_;

  // Used to vend weak pointers for polling. Using a separate factory for these
  // weak pointers allows the weak pointers to be invalidated when polling
  // stops, which effectively cancels the scheduled tasks.
  base::WeakPtrFactory<ProximityMonitorImpl> polling_weak_ptr_factory_;

  // Used to vend all other weak pointers.
  base::WeakPtrFactory<ProximityMonitorImpl> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(ProximityMonitorImpl);
};

}  // namespace proximity_auth

#endif  // COMPONENTS_PROXIMITY_AUTH_PROXIMITY_MONITOR_IMPL_H