Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(433)

Side by Side Diff: components/proximity_auth/bluetooth_connection_finder.cc

Issue 1277483007: Implement finding BLE connections in chrome://proximity-auth. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: refactor unit test Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/proximity_auth/bluetooth_connection_finder.h" 5 #include "components/proximity_auth/bluetooth_connection_finder.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 device::BluetoothAdapterFactory::GetAdapter( 48 device::BluetoothAdapterFactory::GetAdapter(
49 base::Bind(&BluetoothConnectionFinder::OnAdapterInitialized, 49 base::Bind(&BluetoothConnectionFinder::OnAdapterInitialized,
50 weak_ptr_factory_.GetWeakPtr())); 50 weak_ptr_factory_.GetWeakPtr()));
51 } 51 }
52 52
53 scoped_ptr<Connection> BluetoothConnectionFinder::CreateConnection() { 53 scoped_ptr<Connection> BluetoothConnectionFinder::CreateConnection() {
54 return scoped_ptr<Connection>(new BluetoothConnection(remote_device_, uuid_)); 54 return scoped_ptr<Connection>(new BluetoothConnection(remote_device_, uuid_));
55 } 55 }
56 56
57 void BluetoothConnectionFinder::SeekDeviceByAddress(
58 const std::string& bluetooth_address,
59 const base::Closure& callback,
60 const bluetooth_util::ErrorCallback& error_callback) {
61 bluetooth_util::SeekDeviceByAddress(
62 bluetooth_address, callback, error_callback,
63 base::ThreadTaskRunnerHandle::Get().get());
64 }
65
57 bool BluetoothConnectionFinder::IsReadyToPoll() { 66 bool BluetoothConnectionFinder::IsReadyToPoll() {
58 bool is_adapter_available = 67 bool is_adapter_available =
59 adapter_.get() && adapter_->IsPresent() && adapter_->IsPowered(); 68 adapter_.get() && adapter_->IsPresent() && adapter_->IsPowered();
60 PA_LOG(INFO) << "Readiness: adapter=" 69 PA_LOG(INFO) << "Readiness: adapter="
61 << (is_adapter_available ? "available" : "unavailable"); 70 << (is_adapter_available ? "available" : "unavailable");
62 return is_adapter_available; 71 return is_adapter_available;
63 } 72 }
64 73
65 void BluetoothConnectionFinder::PollIfReady() { 74 void BluetoothConnectionFinder::PollIfReady() {
66 if (!IsReadyToPoll()) 75 if (!IsReadyToPoll())
67 return; 76 return;
68 77
69 // If there is a pending task to poll at a later time, the time requisite 78 // If there is a pending task to poll at a later time, the time requisite
70 // timeout has not yet elapsed since the previous polling attempt. In that 79 // timeout has not yet elapsed since the previous polling attempt. In that
71 // case, keep waiting until the delayed task comes in. 80 // case, keep waiting until the delayed task comes in.
72 if (has_delayed_poll_scheduled_) 81 if (has_delayed_poll_scheduled_)
73 return; 82 return;
74 83
75 // If the |connection_| exists, wait for it to connect or fail prior to 84 // If the |connection_| exists, wait for it to connect or fail prior to
76 // polling again. 85 // polling again.
77 if (connection_) 86 if (connection_)
78 return; 87 return;
79 88
80 PA_LOG(INFO) << "Polling for connection..."; 89 // This SeekDeviceByAddress operation is needed to connect to a device if
81 connection_ = CreateConnection(); 90 // it is not already known to the adapter.
82 connection_->AddObserver(this); 91 if (!adapter_->GetDevice(remote_device_.bluetooth_address)) {
83 connection_->Connect(); 92 PA_LOG(INFO) << "Remote device [" << remote_device_.bluetooth_address
93 << "] is not known. "
94 << "Seeking device directly by address...";
95
96 SeekDeviceByAddress(
97 remote_device_.bluetooth_address,
98 base::Bind(&BluetoothConnectionFinder::OnSeekedDeviceByAddress,
99 weak_ptr_factory_.GetWeakPtr()),
100 base::Bind(&BluetoothConnectionFinder::OnSeekedDeviceByAddressError,
101 weak_ptr_factory_.GetWeakPtr()));
102 } else {
103 PA_LOG(INFO) << "Remote device known, connecting...";
104 connection_ = CreateConnection();
105 connection_->AddObserver(this);
106 connection_->Connect();
107 }
84 } 108 }
85 109
86 void BluetoothConnectionFinder::DelayedPollIfReady() { 110 void BluetoothConnectionFinder::PostDelayedPoll() {
111 if (has_delayed_poll_scheduled_) {
112 PA_LOG(WARNING) << "Delayed poll already scheduled, skipping.";
113 return;
114 }
115
116 PA_LOG(INFO) << "Posting delayed poll..";
117 has_delayed_poll_scheduled_ = true;
118 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
119 FROM_HERE, base::Bind(&BluetoothConnectionFinder::OnDelayedPoll,
120 weak_ptr_factory_.GetWeakPtr()),
121 polling_interval_);
122 }
123
124 void BluetoothConnectionFinder::OnDelayedPoll() {
87 // Note that there is no longer a pending task, and therefore polling is 125 // Note that there is no longer a pending task, and therefore polling is
88 // permitted. 126 // permitted.
89 has_delayed_poll_scheduled_ = false; 127 has_delayed_poll_scheduled_ = false;
90 PollIfReady(); 128 PollIfReady();
91 } 129 }
92 130
131 void BluetoothConnectionFinder::OnSeekedDeviceByAddress() {
132 // Sanity check that the remote device is now known by the adapter.
133 if (adapter_->GetDevice(remote_device_.bluetooth_address))
134 PollIfReady();
135 else
136 PostDelayedPoll();
137 }
138
139 void BluetoothConnectionFinder::OnSeekedDeviceByAddressError(
140 const std::string& error_message) {
141 PA_LOG(ERROR) << "Failed to seek device: " << error_message;
142 PostDelayedPoll();
143 }
144
93 void BluetoothConnectionFinder::UnregisterAsObserver() { 145 void BluetoothConnectionFinder::UnregisterAsObserver() {
94 if (connection_) { 146 if (connection_) {
95 connection_->RemoveObserver(this); 147 connection_->RemoveObserver(this);
96 // The connection is about to be released or destroyed, so no need to clear 148 // The connection is about to be released or destroyed, so no need to clear
97 // it explicitly here. 149 // it explicitly here.
98 } 150 }
99 151
100 if (adapter_.get()) { 152 if (adapter_.get()) {
101 adapter_->RemoveObserver(this); 153 adapter_->RemoveObserver(this);
102 adapter_ = NULL; 154 adapter_ = NULL;
(...skipping 21 matching lines...) Expand all
124 Connection* connection, 176 Connection* connection,
125 Connection::Status old_status, 177 Connection::Status old_status,
126 Connection::Status new_status) { 178 Connection::Status new_status) {
127 DCHECK_EQ(connection, connection_.get()); 179 DCHECK_EQ(connection, connection_.get());
128 180
129 if (connection_->IsConnected()) { 181 if (connection_->IsConnected()) {
130 base::TimeDelta elapsed = base::TimeTicks::Now() - start_time_; 182 base::TimeDelta elapsed = base::TimeTicks::Now() - start_time_;
131 PA_LOG(WARNING) << "Connection found! Elapsed Time: " 183 PA_LOG(WARNING) << "Connection found! Elapsed Time: "
132 << elapsed.InMilliseconds() << "ms."; 184 << elapsed.InMilliseconds() << "ms.";
133 UnregisterAsObserver(); 185 UnregisterAsObserver();
134 connection_callback_.Run(connection_.Pass()); 186
187 // If we invoke the callback now, the callback function may install its own
188 // observer to |connection_|. Because we are in the ConnectionObserver
189 // callstack, this new observer will receive this connection event.
190 // Therefore, we need to invoke the callback asynchronously.
191 base::ThreadTaskRunnerHandle::Get()->PostTask(
192 FROM_HERE, base::Bind(&BluetoothConnectionFinder::InvokeCallbackAsync,
193 weak_ptr_factory_.GetWeakPtr()));
135 } else if (old_status == Connection::IN_PROGRESS) { 194 } else if (old_status == Connection::IN_PROGRESS) {
136 PA_LOG(WARNING) 195 PA_LOG(WARNING)
137 << "Connection failed! Scheduling another polling iteration."; 196 << "Connection failed! Scheduling another polling iteration.";
138 connection_.reset(); 197 connection_.reset();
139 has_delayed_poll_scheduled_ = true; 198 PostDelayedPoll();
140 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
141 FROM_HERE, base::Bind(&BluetoothConnectionFinder::DelayedPollIfReady,
142 weak_ptr_factory_.GetWeakPtr()),
143 polling_interval_);
144 } 199 }
145 } 200 }
146 201
202 void BluetoothConnectionFinder::InvokeCallbackAsync() {
203 connection_callback_.Run(connection_.Pass());
204 }
205
147 } // namespace proximity_auth 206 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698