1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COMPONENTS_PROXIMITY_AUTH_PROXIMITY_MONITOR_IMPL_H
6 #define COMPONENTS_PROXIMITY_AUTH_PROXIMITY_MONITOR_IMPL_H
8 #include "base/macros.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/memory/weak_ptr.h"
12 #include "components/proximity_auth/proximity_monitor.h"
13 #include "components/proximity_auth/remote_device.h"
14 #include "device/bluetooth/bluetooth_device.h"
22 class BluetoothAdapter
;
25 namespace proximity_auth
{
27 class ProximityMonitorObserver
;
29 // The concrete implemenation of the proximity monitor interface.
30 class ProximityMonitorImpl
: public ProximityMonitor
{
32 // The |observer| is not owned, and must outlive |this| instance.
33 ProximityMonitorImpl(const RemoteDevice
& remote_device
,
34 scoped_ptr
<base::TickClock
> clock
,
35 ProximityMonitorObserver
* observer
);
36 ~ProximityMonitorImpl() override
;
39 void Start() override
;
41 Strategy
GetStrategy() const override
;
42 bool IsUnlockAllowed() const override
;
43 bool IsInRssiRange() const override
;
44 void RecordProximityMetricsOnAuthSuccess() override
;
47 // Sets the proximity detection strategy. Exposed for testing.
48 // TODO(isherman): Stop exposing this for testing once prefs are properly
50 virtual void SetStrategy(Strategy strategy
);
53 struct TransmitPowerReading
{
54 TransmitPowerReading(int transmit_power
, int max_transmit_power
);
56 // Returns true if |this| transmit power reading indicates proximity.
57 bool IsInProximity() const;
59 // The current transmit power.
62 // The maximum possible transmit power.
63 int max_transmit_power
;
66 // Callback for asynchronous initialization of the Bluetooth adpater.
67 void OnAdapterInitialized(scoped_refptr
<device::BluetoothAdapter
> adapter
);
69 // Ensures that the app is periodically polling for the proximity status
70 // between the remote and the local device iff it should be, based on the
72 void UpdatePollingState();
74 // Performs a scheduled |UpdatePollingState()| operation. This method is
75 // used to distinguish periodically scheduled calls to |UpdatePollingState()|
76 // from event-driven calls, which should be handled differently.
77 void PerformScheduledUpdatePollingState();
79 // Returns |true| iff the app should be periodically polling for the proximity
80 // status between the remote and the local device.
81 bool ShouldPoll() const;
83 // Polls the connection information.
86 // Callback to received the polled-for connection info.
87 void OnConnectionInfo(
88 const device::BluetoothDevice::ConnectionInfo
& connection_info
);
90 // Resets the proximity state to |false|, and clears all member variables
91 // tracking the proximity state.
92 void ClearProximityState();
94 // Updates the proximity state with a new |connection_info| sample of the
95 // current RSSI and Tx power, and the device's maximum Tx power.
97 const device::BluetoothDevice::ConnectionInfo
& connection_info
);
99 // Checks whether the proximity state has changed based on the current
100 // samples. Notifies the |observer_| on a change.
101 void CheckForProximityStateChange();
103 const RemoteDevice remote_device_
;
105 // The |observer_| is not owned, and must outlive |this| instance.
106 ProximityMonitorObserver
* observer_
;
108 // The Bluetooth adapter that will be polled for connection info.
109 scoped_refptr
<device::BluetoothAdapter
> bluetooth_adapter_
;
111 // The strategy used to determine whether the remote device is in proximity.
114 // Whether the remote device is currently in close proximity to the local
116 bool remote_device_is_in_proximity_
;
118 // Whether the proximity monitor is active, i.e. should possibly be scanning
119 // for proximity to the remote device.
122 // The exponentailly weighted rolling average of the RSSI, used to smooth the
123 // RSSI readings. Null if the monitor is inactive, has not recently observed
124 // an RSSI reading, or the most recent connection info included an invalid
126 scoped_ptr
<double> rssi_rolling_average_
;
128 // The last TX power reading. Null if the monitor is inactive, has not
129 // recently observed a TX power reading, or the most recent connection info
130 // included an invalid measurement.
131 scoped_ptr
<TransmitPowerReading
> last_transmit_power_reading_
;
133 // The timestamp of the last zero RSSI reading. An RSSI value of 0 is special
134 // because both devices adjust their transmit powers such that the RSSI is in
135 // this golden range, if possible. Null if the monitor is inactive, has not
136 // recently observed an RSSI reading, or the most recent connection info
137 // included an invalid measurement.
138 scoped_ptr
<base::TimeTicks
> last_zero_rssi_timestamp_
;
140 // Used to access non-decreasing time measurements.
141 scoped_ptr
<base::TickClock
> clock_
;
143 // Used to vend weak pointers for polling. Using a separate factory for these
144 // weak pointers allows the weak pointers to be invalidated when polling
145 // stops, which effectively cancels the scheduled tasks.
146 base::WeakPtrFactory
<ProximityMonitorImpl
> polling_weak_ptr_factory_
;
148 // Used to vend all other weak pointers.
149 base::WeakPtrFactory
<ProximityMonitorImpl
> weak_ptr_factory_
;
151 DISALLOW_COPY_AND_ASSIGN(ProximityMonitorImpl
);
154 } // namespace proximity_auth
156 #endif // COMPONENTS_PROXIMITY_AUTH_PROXIMITY_MONITOR_IMPL_H