Exposing a new easyUnlock.setupConnectionGetDeviceAddress JS API.
This CL exposes a new JS API to find the bluetooth address for the
remote device corresponding to a given connection id.
This is necesssary as the bluetooth address of a device changes after
it's paired (but it's updated in the underlying
BluetoothLowEnergyConnection object).
BUG=528277
Review URL: https://codereview.chromium.org/1370133005
Cr-Commit-Position: refs/heads/master@{#351549}
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
index 2b927349..369c231 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
@@ -1039,7 +1039,12 @@
make_scoped_ptr(new base::DefaultTickClock()))) {}
EasyUnlockPrivateFindSetupConnectionFunction::
- ~EasyUnlockPrivateFindSetupConnectionFunction() {}
+ ~EasyUnlockPrivateFindSetupConnectionFunction() {
+ // |connection_finder_| has a raw pointer to |bluetooth_throttler_|, so it
+ // should be destroyed first.
+ connection_finder_.reset();
+ bluetooth_throttler_.reset();
+}
void EasyUnlockPrivateFindSetupConnectionFunction::
OnConnectionFinderTimedOut() {
@@ -1141,4 +1146,27 @@
return true;
}
+EasyUnlockPrivateSetupConnectionGetDeviceAddressFunction::
+ EasyUnlockPrivateSetupConnectionGetDeviceAddressFunction() {}
+
+EasyUnlockPrivateSetupConnectionGetDeviceAddressFunction::
+ ~EasyUnlockPrivateSetupConnectionGetDeviceAddressFunction() {}
+
+bool EasyUnlockPrivateSetupConnectionGetDeviceAddressFunction::RunSync() {
+ scoped_ptr<easy_unlock_private::SetupConnectionGetDeviceAddress::Params>
+ params =
+ easy_unlock_private::SetupConnectionGetDeviceAddress::Params::Create(
+ *args_);
+ EXTENSION_FUNCTION_VALIDATE(params);
+ std::string device_address =
+ GetConnectionManager(browser_context())
+ ->GetDeviceAddress(extension(), params->connection_id);
+ results_ =
+ easy_unlock_private::SetupConnectionGetDeviceAddress::Results::Create(
+ device_address);
+ if (device_address.empty())
+ SetError("Invalid connectionId.");
+ return true;
+}
+
} // namespace extensions
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h
index 31c15ca..347c6606 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h
@@ -535,6 +535,24 @@
DISALLOW_COPY_AND_ASSIGN(EasyUnlockPrivateSetupConnectionSendFunction);
};
+class EasyUnlockPrivateSetupConnectionGetDeviceAddressFunction
+ : public SyncExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION(
+ "easyUnlockPrivate.setupConnectionGetDeviceAddress",
+ EASYUNLOCKPRIVATE_SETUPCONNECTIONGETDEVICEADDRESS)
+ EasyUnlockPrivateSetupConnectionGetDeviceAddressFunction();
+
+ private:
+ ~EasyUnlockPrivateSetupConnectionGetDeviceAddressFunction() override;
+
+ // SyncExtensionFunction:
+ bool RunSync() override;
+
+ DISALLOW_COPY_AND_ASSIGN(
+ EasyUnlockPrivateSetupConnectionGetDeviceAddressFunction);
+};
+
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_EASY_UNLOCK_PRIVATE_EASY_UNLOCK_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_connection_manager.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_connection_manager.cc
index 9003855f..878e6ab6 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_connection_manager.cc
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_connection_manager.cc
@@ -70,6 +70,15 @@
return api::easy_unlock_private::CONNECTION_STATUS_NONE;
}
+std::string EasyUnlockPrivateConnectionManager::GetDeviceAddress(
+ const Extension* extension,
+ int connection_id) const {
+ Connection* connection = GetConnection(extension->id(), connection_id);
+ if (!connection)
+ return std::string();
+ return connection->GetDeviceAddress();
+}
+
bool EasyUnlockPrivateConnectionManager::Disconnect(const Extension* extension,
int connection_id) {
Connection* connection = GetConnection(extension->id(), connection_id);
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_connection_manager.h b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_connection_manager.h
index 3d2f7a61..a0ca893a 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_connection_manager.h
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_connection_manager.h
@@ -52,6 +52,11 @@
int connection_id,
const std::string& payload);
+ // Returns the Bluetooth address of the device connected with a given
+ // |connection_id|, and an empty string if |connection_id| was not found.
+ std::string GetDeviceAddress(const Extension* extension,
+ int connection_id) const;
+
// proximity_auth::ConnectionObserver:
void OnConnectionStatusChanged(
proximity_auth::Connection* connection,
diff --git a/chrome/common/extensions/api/easy_unlock_private.idl b/chrome/common/extensions/api/easy_unlock_private.idl
index 1b1b9ce9..0359bd8 100644
--- a/chrome/common/extensions/api/easy_unlock_private.idl
+++ b/chrome/common/extensions/api/easy_unlock_private.idl
@@ -246,6 +246,12 @@
// |status|: The status of the connection with |connection_id|.
callback SetupConnectionStatusCallback = void(ConnectionStatus status);
+ // Callback for the |setupConnectionGetDeviceAddress()| method.
+ // |deviceAddress|: The bluetooth address of the connection with
+ // |connectionId|.
+ callback SetupConnectionGetDeviceAddressCallback = void(
+ DOMString deviceAddress);
+
interface Functions {
// Gets localized strings required to render the API.
//
@@ -420,6 +426,10 @@
static void setupConnectionSend(long connectionId,
ArrayBuffer data,
optional EmptyCallback callback);
+
+ // Gets the Bluetooth address of the connection with |connectionId|
+ static void setupConnectionGetDeviceAddress(long connectionId,
+ SetupConnectionGetDeviceAddressCallback callback);
};
interface Events {
diff --git a/components/proximity_auth/ble/bluetooth_low_energy_connection.cc b/components/proximity_auth/ble/bluetooth_low_energy_connection.cc
index d193acf..52af29b 100644
--- a/components/proximity_auth/ble/bluetooth_low_energy_connection.cc
+++ b/components/proximity_auth/ble/bluetooth_low_energy_connection.cc
@@ -219,12 +219,12 @@
BluetoothDevice* device) {
DCHECK(device);
if (sub_status() == SubStatus::DISCONNECTED ||
- device->GetAddress() != GetRemoteDeviceAddress())
+ device->GetAddress() != GetDeviceAddress())
return;
if (sub_status() != SubStatus::WAITING_GATT_CONNECTION &&
!device->IsConnected()) {
- PA_LOG(INFO) << "GATT connection dropped " << GetRemoteDeviceAddress()
+ PA_LOG(INFO) << "GATT connection dropped " << GetDeviceAddress()
<< "\ndevice connected: " << device->IsConnected()
<< "\ngatt connection: "
<< (gatt_connection_ ? gatt_connection_->IsConnected()
@@ -237,10 +237,10 @@
BluetoothDevice* device) {
DCHECK(device);
if (sub_status_ == SubStatus::DISCONNECTED ||
- device->GetAddress() != GetRemoteDeviceAddress())
+ device->GetAddress() != GetDeviceAddress())
return;
- PA_LOG(INFO) << "Device removed " << GetRemoteDeviceAddress();
+ PA_LOG(INFO) << "Device removed " << GetDeviceAddress();
Disconnect();
}
@@ -343,6 +343,9 @@
<< " created.";
PrintTimeElapsed();
+ // Informing |bluetooth_trottler_| a new connection was established.
+ bluetooth_throttler_->OnConnection(this);
+
gatt_connection_ = gatt_connection.Pass();
SetSubStatus(SubStatus::WAITING_CHARACTERISTICS);
characteristic_finder_.reset(CreateCharacteristicsFinder(
@@ -350,9 +353,6 @@
weak_ptr_factory_.GetWeakPtr()),
base::Bind(&BluetoothLowEnergyConnection::OnCharacteristicsFinderError,
weak_ptr_factory_.GetWeakPtr())));
-
- // Informing |bluetooth_trottler_| a new connection was established.
- bluetooth_throttler_->OnConnection(this);
}
BluetoothLowEnergyCharacteristicsFinder*
@@ -544,7 +544,7 @@
PA_LOG(INFO) << "Time elapsed: " << base::TimeTicks::Now() - start_time_;
}
-std::string BluetoothLowEnergyConnection::GetRemoteDeviceAddress() {
+std::string BluetoothLowEnergyConnection::GetDeviceAddress() {
// When the remote device is connected we should rely on the address given by
// |gatt_connection_|. As the device address may change if the device is
// paired. The address in |gatt_connection_| is automatically updated in this
@@ -555,15 +555,15 @@
BluetoothDevice* BluetoothLowEnergyConnection::GetRemoteDevice() {
// It's not possible to simply use
- // |adapter_->GetDevice(GetRemoteDeviceAddress())| to find the device with MAC
- // address |GetRemoteDeviceAddress()|. For paired devices,
+ // |adapter_->GetDevice(GetDeviceAddress())| to find the device with MAC
+ // address |GetDeviceAddress()|. For paired devices,
// BluetoothAdapter::GetDevice(XXX) searches for the temporary MAC address
- // XXX, whereas |GetRemoteDeviceAddress()| is the real MAC address. This is a
+ // XXX, whereas |GetDeviceAddress()| is the real MAC address. This is a
// bug in the way device::BluetoothAdapter is storing the devices (see
// crbug.com/497841).
std::vector<BluetoothDevice*> devices = adapter_->GetDevices();
for (const auto& device : devices) {
- if (device->GetAddress() == GetRemoteDeviceAddress())
+ if (device->GetAddress() == GetDeviceAddress())
return device;
}
diff --git a/components/proximity_auth/ble/bluetooth_low_energy_connection.h b/components/proximity_auth/ble/bluetooth_low_energy_connection.h
index d4d0ad8f..b316f641 100644
--- a/components/proximity_auth/ble/bluetooth_low_energy_connection.h
+++ b/components/proximity_auth/ble/bluetooth_low_energy_connection.h
@@ -96,6 +96,7 @@
// proximity_auth::Connection:
void Connect() override;
void Disconnect() override;
+ std::string GetDeviceAddress() override;
protected:
// Exposed for testing.
@@ -224,9 +225,6 @@
// Prints the time elapsed since |Connect()| was called.
void PrintTimeElapsed();
- // Returns the Bluetooth address of the remote device.
- std::string GetRemoteDeviceAddress();
-
// Returns the device corresponding to |remote_device_address_|.
device::BluetoothDevice* GetRemoteDevice();
diff --git a/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.cc b/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.cc
index ade408ff..bf50796 100644
--- a/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.cc
+++ b/components/proximity_auth/ble/bluetooth_low_energy_connection_finder.cc
@@ -269,7 +269,8 @@
// If we invoke the callback now, the callback function may install its own
// observer to |connection_|. Because we are in the ConnectionObserver
// callstack, this new observer will receive this connection event.
- // Therefore, we need to invoke the callback asynchronously.
+ // Therefore, we need to invoke the callback or restart discovery
+ // asynchronously.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(&BluetoothLowEnergyConnectionFinder::InvokeCallbackAsync,
diff --git a/components/proximity_auth/connection.cc b/components/proximity_auth/connection.cc
index 437be60..85249bb8 100644
--- a/components/proximity_auth/connection.cc
+++ b/components/proximity_auth/connection.cc
@@ -46,6 +46,10 @@
observers_.RemoveObserver(observer);
}
+std::string Connection::GetDeviceAddress() {
+ return remote_device_.bluetooth_address;
+}
+
void Connection::SetStatus(Status status) {
if (status_ == status)
return;
diff --git a/components/proximity_auth/connection.h b/components/proximity_auth/connection.h
index a79ce188..532e03d9 100644
--- a/components/proximity_auth/connection.h
+++ b/components/proximity_auth/connection.h
@@ -54,6 +54,9 @@
// Disconnects from the remote device.
virtual void Disconnect() = 0;
+ // The bluetooth address of the connected device.
+ virtual std::string GetDeviceAddress();
+
Status status() const { return status_; }
protected:
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 1e8bd72..3c918e2 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1150,6 +1150,7 @@
EASYUNLOCKPRIVATE_SETUPCONNECTIONDISCONNECT,
EASYUNLOCKPRIVATE_SETUPCONNECTIONSEND,
DATAREDUCTIONPROXY_GETDATAUSAGE,
+ EASYUNLOCKPRIVATE_SETUPCONNECTIONGETDEVICEADDRESS,
// Last entry: Add new entries above, then run:
// python tools/metrics/histograms/update_extension_histograms.py
ENUM_BOUNDARY
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 00a33bd..af2e22e 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -57919,6 +57919,7 @@
<int value="1087" label="EASYUNLOCKPRIVATE_SETUPCONNECTIONDISCONNECT"/>
<int value="1088" label="EASYUNLOCKPRIVATE_SETUPCONNECTIONSEND"/>
<int value="1089" label="DATAREDUCTIONPROXY_GETDATAUSAGE"/>
+ <int value="1090" label="EASYUNLOCKPRIVATE_SETUPCONNECTIONGETDEVICEADDRESS"/>
</enum>
<enum name="ExtensionInstallCause" type="int">