Chromium Code Reviews| Index: components/proximity_auth/bluetooth_throttler.h |
| diff --git a/components/proximity_auth/bluetooth_throttler.h b/components/proximity_auth/bluetooth_throttler.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..6b0d244c5c5b8cf9fa2c6f8921a786ea5424fd3b |
| --- /dev/null |
| +++ b/components/proximity_auth/bluetooth_throttler.h |
| @@ -0,0 +1,113 @@ |
| +// Copyright 2014 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_BLUETOOTH_THROTTLER_H |
| +#define COMPONENTS_PROXIMITY_AUTH_BLUETOOTH_THROTTLER_H |
| + |
| +#include "base/macros.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/time/default_tick_clock.h" |
| +#include "base/time/time.h" |
| +#include "components/proximity_auth/connection_finder.h" |
| +#include "components/proximity_auth/connection_observer.h" |
| +#include "components/proximity_auth/remote_device.h" |
| + |
| +namespace base { |
| +class TaskRunner; |
| +class TickClock; |
| +} |
| + |
| +namespace device { |
| +class BluetoothUUID; |
| +} |
| + |
| +namespace proximity_auth { |
| + |
| +class Connection; |
| + |
| +// This class throttles repeated connection attempts to the same device. This |
| +// throttling is necessary to prevent a kernel race condition when connecting |
| +// before the previous connection fully closes, putting the connection in a |
| +// corrupted, and unrecoverable state. http://crbug.com/345232 |
|
Tim Song
2014/10/27 17:49:25
This is actually not entirely true now that this i
Ilya Sherman
2014/10/28 00:40:47
Hmm, but is that a valid thing to do? What if the
Tim Song
2014/11/20 23:00:09
That's true. Maybe disconnect also works. I'll hav
|
| +class BluetoothThrottler : public ConnectionObserver { |
| + public: |
| + // Creates a throttler for connections to the |remote_device|. |
| + BluetoothThrottler(const RemoteDevice& remote_device); |
| + virtual ~BluetoothThrottler(); |
| + |
| + // Attempts to find a connection to the service with the given |uuid| running |
| + // on the |remote_device| passed to the constructor. This is similar to |
| + // calling |BluetoothConnectionFinder::Find()|, but the connections will be |
| + // throttled to prevent hitting a kernel race condition. Will continue to try |
| + // to find the connection indefinitely until |StopFindingConnections()| is |
| + // called. Calls |connection_callback| with the open connection once the |
| + // remote device is connected. |
| + // Note: This method must not be called a second time prior to calling |
| + // StopFindingConnections(). |
| + void FindConnection( |
| + const device::BluetoothUUID& uuid, |
| + const ConnectionFinder::ConnectionCallback& connection_callback); |
| + |
| + // Cancels any running or pending connection searches. |
| + void StopFindingConnections(); |
| + |
| + protected: |
| + // Creates a connection finder targeting the service with the given |uuid| on |
| + // the |remote_device_|. Exposed for overriding in tests. |
| + virtual scoped_ptr<ConnectionFinder> CreateConnectionFinder( |
| + const device::BluetoothUUID& uuid); |
| + |
| + // Returns the duration to wait before reattempting a connection to the |
| + // |remote_device_|. Exposed for testing. |
| + base::TimeDelta GetCooldownTimeDelta() const; |
| + |
| + // Returns the task runner to use for posting delayed tasks. |
| + // Exposed for overriding in tests. |
| + virtual scoped_refptr<base::TaskRunner> GetTaskRunner() const; |
| + |
| + // Returns the clock to use for computing time ticks. |
| + // Exposed for overriding in tests. |
| + virtual base::TickClock* GetTickClock(); |
| + |
| + private: |
| + // Callback for a connection. |
| + void OnConnection( |
| + const ConnectionFinder::ConnectionCallback& connection_callback, |
| + scoped_ptr<Connection> connection); |
| + |
| + // ConnectionObserver: |
| + virtual void OnConnectionStatusChanged( |
| + const Connection& connection, |
| + Connection::Status old_status, |
| + Connection::Status new_status) override; |
| + |
| + // The device to connect to. |
| + const RemoteDevice remote_device_; |
| + |
| + // Tracks the last seen disconnect time for the |remote_device_|. |
| + base::TimeTicks last_disconnect_time_; |
| + |
| + // The currently running connection finder; null iff there is no currently |
| + // running connection finder. |
| + scoped_ptr<ConnectionFinder> connection_finder_; |
| + |
| + // The most current connection; null iff there is no current connection. |
| + // Stored as a weak reference, which is safe because |this| instance is |
| + // registered as an observer, and will unregister when the connection |
| + // disconnects, which is guaranteed to occur before the connection is |
| + // destroyed. |
| + Connection* connection_; |
| + |
| + // Default time source; overridable by tests. |
| + base::DefaultTickClock clock_; |
| + |
| + base::WeakPtrFactory<BluetoothThrottler> weak_ptr_factory_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(BluetoothThrottler); |
| +}; |
| + |
| +} // namespace proximity_auth |
| + |
| +#endif // COMPONENTS_PROXIMITY_AUTH_BLUETOOTH_THROTTLER_H |