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

Unified Diff: components/proximity_auth/webui/proximity_auth_webui_handler.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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/proximity_auth/webui/proximity_auth_webui_handler.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/proximity_auth/webui/proximity_auth_webui_handler.cc
diff --git a/components/proximity_auth/webui/proximity_auth_webui_handler.cc b/components/proximity_auth/webui/proximity_auth_webui_handler.cc
index 4a313bea86e33a1aa7d528035727deb6ab05c56a..da5f19b1805ac50de2053b76c969e366809dcfce 100644
--- a/components/proximity_auth/webui/proximity_auth_webui_handler.cc
+++ b/components/proximity_auth/webui/proximity_auth_webui_handler.cc
@@ -11,8 +11,13 @@
#include "base/prefs/pref_service.h"
#include "base/thread_task_runner_handle.h"
#include "base/time/default_clock.h"
+#include "base/time/default_tick_clock.h"
#include "base/values.h"
-#include "components/proximity_auth/bluetooth_connection.h"
+#include "components/proximity_auth/ble/bluetooth_low_energy_connection_finder.h"
+#include "components/proximity_auth/ble/bluetooth_low_energy_device_whitelist.h"
+#include "components/proximity_auth/ble/pref_names.h"
+#include "components/proximity_auth/bluetooth_connection_finder.h"
+#include "components/proximity_auth/bluetooth_throttler_impl.h"
#include "components/proximity_auth/bluetooth_util.h"
#include "components/proximity_auth/client_impl.h"
#include "components/proximity_auth/cryptauth/base64url.h"
@@ -35,8 +40,19 @@ namespace proximity_auth {
namespace {
-// The UUID of the Smart Lock Bluetooth service.
-const char kBluetoothServiceUUID[] = "704EE561-3782-405A-A14B-2D47A2DDCDDF";
+// The UUID of the Smart Lock classic Bluetooth service.
+const char kClassicBluetoothServiceUUID[] =
+ "704EE561-3782-405A-A14B-2D47A2DDCDDF";
+
+// The UUID of the Bluetooth Low Energy service.
+const char kBLESmartLockServiceUUID[] = "b3b7e28e-a000-3e17-bd86-6e97b9e28c11";
+
+// The UUID of the characteristic used to send data to the peripheral.
+const char kBLEToPeripheralCharUUID[] = "977c6674-1239-4e72-993b-502369b8bb5a";
+
+// The UUID of the characteristic used to receive data from the peripheral.
+const char kBLEFromPeripheralCharUUID[] =
+ "f4b904a2-a030-43b3-98a8-221c536c03cb";
// Keys in the JSON representation of a log message.
const char kLogMessageTextKey[] = "text";
@@ -105,7 +121,6 @@ scoped_ptr<base::DictionaryValue> CreateSyncStateDictionary(
ProximityAuthWebUIHandler::ProximityAuthWebUIHandler(
ProximityAuthUIDelegate* delegate)
: delegate_(delegate),
- web_contents_initialized_(false),
weak_ptr_factory_(this) {
cryptauth_client_factory_ = delegate_->CreateCryptAuthClientFactory();
}
@@ -313,7 +328,7 @@ void ProximityAuthWebUIHandler::ToggleConnection(const base::ListValue* args) {
if (unlock_key.public_key() == public_key) {
// Check if there is an existing connection to disconnect from first.
if (connection && connection->IsConnected() &&
- connection->remote_device().public_key == public_key) {
+ selected_remote_device_.public_key == public_key) {
PA_LOG(INFO) << "Disconnecting from "
<< unlock_key.friendly_device_name() << "["
<< unlock_key.bluetooth_address() << "]";
@@ -322,8 +337,8 @@ void ProximityAuthWebUIHandler::ToggleConnection(const base::ListValue* args) {
}
// Derive the PSK before connecting to the device.
- PA_LOG(INFO) << "Connecting to " << unlock_key.friendly_device_name()
- << "[" << unlock_key.bluetooth_address() << "]";
+ PA_LOG(INFO) << "Deriving PSK before connecting to "
+ << unlock_key.friendly_device_name();
secure_message_delegate_ = delegate_->CreateSecureMessageDelegate();
secure_message_delegate_->DeriveKey(
user_private_key_, unlock_key.public_key(),
@@ -509,7 +524,7 @@ scoped_ptr<base::ListValue> ProximityAuthWebUIHandler::GetUnlockKeysList() {
}
Connection* ProximityAuthWebUIHandler::GetConnection() {
- Connection* connection = bluetooth_connection_.get();
+ Connection* connection = connection_.get();
if (client_) {
DCHECK(!connection);
connection = client_->connection();
@@ -525,38 +540,65 @@ void ProximityAuthWebUIHandler::OnPSKDerived(
return;
}
- RemoteDevice remote_device(
- unlock_key.friendly_device_name(), unlock_key.public_key(),
- unlock_key.bluetooth_address(), persistent_symmetric_key);
-
- bluetooth_connection_.reset(new BluetoothConnection(
- remote_device, device::BluetoothUUID(kBluetoothServiceUUID)));
- bluetooth_connection_->AddObserver(this);
+ selected_remote_device_ =
+ RemoteDevice(unlock_key.friendly_device_name(), unlock_key.public_key(),
+ unlock_key.bluetooth_address(), persistent_symmetric_key);
+
+ // TODO(tengs): We distinguish whether the unlock key uses classic Bluetooth
+ // or BLE based on the presence of the |bluetooth_address| field. However, we
+ // should ideally have a separate field specifying the protocol.
+ if (selected_remote_device_.bluetooth_address.empty())
+ FindBluetoothLowEnergyConnection(selected_remote_device_);
+ else
+ FindBluetoothClassicConnection(selected_remote_device_);
+}
+
+void ProximityAuthWebUIHandler::FindBluetoothClassicConnection(
+ const RemoteDevice& remote_device) {
+ PA_LOG(INFO) << "Finding classic Bluetooth device " << remote_device.name
+ << " [" << remote_device.bluetooth_address << "].";
+
+ // TODO(tengs): Set a timeout to stop the connection finder eventually.
+ connection_finder_.reset(new BluetoothConnectionFinder(
+ remote_device, device::BluetoothUUID(kClassicBluetoothServiceUUID),
+ base::TimeDelta::FromSeconds(3)));
+ connection_finder_->Find(
+ base::Bind(&ProximityAuthWebUIHandler::OnConnectionFound,
+ weak_ptr_factory_.GetWeakPtr()));
- // This SeekDeviceByAddress operation is needed to connect to a device if
- // it is not already known to the local device.
- bluetooth_util::SeekDeviceByAddress(
- remote_device.bluetooth_address,
- base::Bind(&ProximityAuthWebUIHandler::OnSeekedDeviceByAddress,
- weak_ptr_factory_.GetWeakPtr()),
- base::Bind(&ProximityAuthWebUIHandler::OnSeekedDeviceByAddressError,
- weak_ptr_factory_.GetWeakPtr()),
- content::BrowserThread::GetBlockingPool()
- ->GetTaskRunnerWithShutdownBehavior(
- base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)
- .get());
+ web_ui()->CallJavascriptFunction("LocalStateInterface.onUnlockKeysChanged",
+ *GetUnlockKeysList());
}
-void ProximityAuthWebUIHandler::OnSeekedDeviceByAddress() {
- PA_LOG(INFO) << "Found Bluetooth device: "
- << bluetooth_connection_->remote_device().bluetooth_address;
- bluetooth_connection_->Connect();
-}
+void ProximityAuthWebUIHandler::FindBluetoothLowEnergyConnection(
+ const RemoteDevice& remote_device) {
+ PrefService* pref_service = delegate_->GetPrefService();
+ if (!pref_service->FindPreference(
+ prefs::kBluetoothLowEnergyDeviceWhitelist)) {
+ PA_LOG(ERROR) << "Please enable the BLE experiment in chrome://flags.";
+ return;
+ }
-void ProximityAuthWebUIHandler::OnSeekedDeviceByAddressError(
- const std::string& error_message) {
- PA_LOG(WARNING) << "Failed to seek device by address: "
- << bluetooth_connection_->remote_device().bluetooth_address;
+ PA_LOG(INFO) << "Finding Bluetooth Low Energy device " << remote_device.name;
+ if (!bluetooth_throttler_) {
+ bluetooth_throttler_.reset(new BluetoothThrottlerImpl(
+ make_scoped_ptr(new base::DefaultTickClock())));
+ }
+
+ ble_device_whitelist_.reset(
+ new BluetoothLowEnergyDeviceWhitelist(delegate_->GetPrefService()));
+
+ // TODO(tengs): Set a timeout to stop the connection finder eventually.
+ connection_finder_.reset(new BluetoothLowEnergyConnectionFinder(
+ kBLESmartLockServiceUUID, kBLEToPeripheralCharUUID,
+ kBLEFromPeripheralCharUUID, ble_device_whitelist_.get(),
+ bluetooth_throttler_.get(), 3));
+ connection_finder_->Find(
+ base::Bind(&ProximityAuthWebUIHandler::OnConnectionFound,
+ weak_ptr_factory_.GetWeakPtr()));
+
+ web_ui()->CallJavascriptFunction("LocalStateInterface.onUnlockKeysChanged",
+ *GetUnlockKeysList());
}
void ProximityAuthWebUIHandler::OnAuthenticationResult(
@@ -565,7 +607,7 @@ void ProximityAuthWebUIHandler::OnAuthenticationResult(
secure_context_ = secure_context.Pass();
// Create the ClientImpl asynchronously. |client_| registers itself as an
- // observer of |bluetooth_connection_|, so creating it synchronously would
+ // observer of |connection_|, so creating it synchronously would
// trigger |OnSendComplete()| as an observer call for |client_|.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
@@ -573,9 +615,29 @@ void ProximityAuthWebUIHandler::OnAuthenticationResult(
weak_ptr_factory_.GetWeakPtr()));
}
+void ProximityAuthWebUIHandler::OnConnectionFound(
+ scoped_ptr<Connection> connection) {
+ DCHECK(connection->IsConnected());
+ connection_ = connection.Pass();
+ connection_->AddObserver(this);
+
+ web_ui()->CallJavascriptFunction("LocalStateInterface.onUnlockKeysChanged",
+ *GetUnlockKeysList());
+
+ // TODO(tengs): Create an authenticator for BLE connections.
+ if (selected_remote_device_.bluetooth_address.empty())
+ return;
+
+ authenticator_.reset(new DeviceToDeviceAuthenticator(
+ connection_.get(), delegate_->GetAccountId(),
+ delegate_->CreateSecureMessageDelegate()));
+ authenticator_->Authenticate(
+ base::Bind(&ProximityAuthWebUIHandler::OnAuthenticationResult,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
void ProximityAuthWebUIHandler::CreateStatusUpdateClient() {
- client_.reset(
- new ClientImpl(bluetooth_connection_.Pass(), secure_context_.Pass()));
+ client_.reset(new ClientImpl(connection_.Pass(), secure_context_.Pass()));
client_->AddObserver(this);
}
@@ -610,19 +672,16 @@ ProximityAuthWebUIHandler::ExternalDeviceInfoToDictionary(
return unlock_key.public_key() == public_key;
});
- if (iterator == device_manager_->unlock_keys().end())
+ if (iterator == device_manager_->unlock_keys().end() ||
+ selected_remote_device_.public_key != device_info.public_key())
return dictionary;
// Fill in the current Bluetooth connection status.
- Connection* connection = GetConnection();
- if (!connection ||
- connection->remote_device().public_key != device_info.public_key())
- return dictionary;
-
std::string connection_status = kExternalDeviceDisconnected;
- if (connection->IsConnected()) {
+ Connection* connection = GetConnection();
+ if (connection && connection->IsConnected()) {
connection_status = kExternalDeviceConnected;
- } else if (connection->status() == Connection::IN_PROGRESS) {
+ } else if (connection_finder_) {
connection_status = kExternalDeviceConnecting;
}
dictionary->SetString(kExternalDeviceConnectionStatus, connection_status);
@@ -665,15 +724,11 @@ void ProximityAuthWebUIHandler::OnConnectionStatusChanged(
Connection::Status new_status) {
PA_LOG(INFO) << "Connection status changed from " << old_status << " to "
<< new_status;
- if (new_status == Connection::CONNECTED) {
- authenticator_.reset(new DeviceToDeviceAuthenticator(
- connection, delegate_->GetAccountId(),
- delegate_->CreateSecureMessageDelegate()));
- authenticator_->Authenticate(
- base::Bind(&ProximityAuthWebUIHandler::OnAuthenticationResult,
- weak_ptr_factory_.GetWeakPtr()));
- } else if (new_status == Connection::DISCONNECTED) {
+
+ if (new_status == Connection::DISCONNECTED) {
last_remote_status_update_.reset();
+ selected_remote_device_ = RemoteDevice();
+ connection_finder_.reset();
}
scoped_ptr<base::ListValue> unlock_keys = GetUnlockKeysList();
« no previous file with comments | « components/proximity_auth/webui/proximity_auth_webui_handler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698