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

Unified Diff: content/browser/bluetooth/web_bluetooth_service_impl.cc

Issue 1922923002: bluetooth: Move requestDevice to mojo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bluetooth-separate-tests-request-device
Patch Set: Remove debug log Created 4 years, 7 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
Index: content/browser/bluetooth/web_bluetooth_service_impl.cc
diff --git a/content/browser/bluetooth/web_bluetooth_service_impl.cc b/content/browser/bluetooth/web_bluetooth_service_impl.cc
index 0a8728f10d54b3c631d23bbbcc2d1a65819dc5a5..b50f2320ce3bd14da021a7dda48f2e433f53c46f 100644
--- a/content/browser/bluetooth/web_bluetooth_service_impl.cc
+++ b/content/browser/bluetooth/web_bluetooth_service_impl.cc
@@ -4,7 +4,7 @@
// ID Not In Map Note:
// A service, characteristic, or descriptor ID not in the corresponding
-// BluetoothDispatcherHost map [service_id_to_device_address_,
+// WebBluetoothServiceImpl map [service_id_to_device_address_,
// characteristic_id_to_service_id_, descriptor_to_characteristic_] implies a
// hostile renderer because a renderer obtains the corresponding ID from this
// class and it will be added to the map at that time.
@@ -13,11 +13,15 @@
#include <algorithm>
+#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
+#include "content/browser/bluetooth/bluetooth_adapter_factory_wrapper.h"
#include "content/browser/bluetooth/bluetooth_blacklist.h"
-#include "content/browser/bluetooth/bluetooth_dispatcher_host.h"
+#include "content/browser/bluetooth/bluetooth_device_provider.h"
+#include "content/browser/bluetooth/bluetooth_metrics.h"
#include "content/browser/bluetooth/frame_connected_bluetooth_devices.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
@@ -170,13 +174,11 @@ WebBluetoothServiceImpl::WebBluetoothServiceImpl(
weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
CHECK(web_contents());
-
- GetBluetoothDispatcherHost()->AddAdapterObserver(this);
}
WebBluetoothServiceImpl::~WebBluetoothServiceImpl() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- GetBluetoothDispatcherHost()->RemoveAdapterObserver(this);
+ GetBluetoothAdapterFactoryWrapper()->ReleaseAdapter(this);
}
void WebBluetoothServiceImpl::SetClientConnectionErrorHandler(
@@ -193,11 +195,21 @@ void WebBluetoothServiceImpl::DidFinishNavigation(
}
}
-void WebBluetoothServiceImpl::AdapterPresentChanged(
+void WebBluetoothServiceImpl::AdapterPoweredChanged(
device::BluetoothAdapter* adapter,
- bool present) {
- if (!present) {
- ClearState();
Jeffrey Yasskin 2016/05/13 04:41:59 Is removing this going to bring https://crbug.com/
ortuno 2016/05/13 20:11:18 Noup! That bug happened because the adapter in Blu
+ bool powered) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (device_provider_.get()) {
+ device_provider_->AdapterPoweredChanged(powered);
+ }
+}
+
+void WebBluetoothServiceImpl::DeviceAdded(device::BluetoothAdapter* adapter,
+ device::BluetoothDevice* device) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (device_provider_.get()) {
+ VLOG(1) << "Adding device to device provider: " << device->GetAddress();
+ device_provider_->AddFilteredDevice(*device);
}
}
@@ -275,14 +287,35 @@ void WebBluetoothServiceImpl::SetClient(
client_.Bind(std::move(client));
}
+void WebBluetoothServiceImpl::RequestDevice(
+ blink::mojom::WebBluetoothRequestDeviceOptionsPtr options,
+ const RequestDeviceCallback& callback) {
+ RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::REQUEST_DEVICE);
+ RecordRequestDeviceOptions(options);
+
+ if (!GetBluetoothAdapterFactoryWrapper()->GetAdapter(this)) {
+ if (GetBluetoothAdapterFactoryWrapper()->IsBluetoothAdapterAvailable()) {
+ GetBluetoothAdapterFactoryWrapper()->AcquireAdapter(
+ this, base::Bind(&WebBluetoothServiceImpl::RequestDeviceImpl,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(std::move(options)), callback));
+ return;
+ }
+ RecordRequestDeviceOutcome(UMARequestDeviceOutcome::NO_BLUETOOTH_ADAPTER);
+ callback.Run(blink::mojom::WebBluetoothError::NO_BLUETOOTH_ADAPTER,
+ nullptr /* device */);
+ return;
+ }
+ RequestDeviceImpl(std::move(options), callback);
+}
+
void WebBluetoothServiceImpl::RemoteServerConnect(
const mojo::String& device_id,
const RemoteServerConnectCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::CONNECT_GATT);
- const CacheQueryResult query_result =
- GetBluetoothDispatcherHost()->QueryCacheForDevice(GetOrigin(), device_id);
+ const CacheQueryResult query_result = QueryCacheForDevice(device_id);
if (query_result.outcome != CacheQueryOutcome::SUCCESS) {
RecordConnectGATTOutcome(query_result.outcome);
@@ -335,16 +368,14 @@ void WebBluetoothServiceImpl::RemoteServerGetPrimaryService(
RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::GET_PRIMARY_SERVICE);
RecordGetPrimaryServiceService(device::BluetoothUUID(service_uuid));
- if (!GetBluetoothDispatcherHost()
- ->allowed_devices_map_.IsOriginAllowedToAccessService(
- GetOrigin(), device_id, service_uuid)) {
+ if (!allowed_devices_map_.IsOriginAllowedToAccessService(
+ GetOrigin(), device_id, service_uuid)) {
callback.Run(blink::mojom::WebBluetoothError::NOT_ALLOWED_TO_ACCESS_SERVICE,
nullptr /* service */);
return;
}
- const CacheQueryResult query_result =
- GetBluetoothDispatcherHost()->QueryCacheForDevice(GetOrigin(), device_id);
+ const CacheQueryResult query_result = QueryCacheForDevice(device_id);
if (query_result.outcome == CacheQueryOutcome::BAD_RENDERER) {
binding_.Close();
@@ -613,6 +644,26 @@ void WebBluetoothServiceImpl::RemoteCharacteristicStopNotifications(
weak_ptr_factory_.GetWeakPtr(), characteristic_instance_id, callback));
}
+void WebBluetoothServiceImpl::RequestDeviceImpl(
+ blink::mojom::WebBluetoothRequestDeviceOptionsPtr options,
+ const RequestDeviceCallback& callback) {
+ // requestDevice() can only be called when processing a user-gesture and
+ // any user gesture outside of a chooser should close the chooser so we should
+ // never get a request with an open chooser.
+ CHECK(!device_provider_.get());
+
+ device_provider_.reset(new BluetoothDeviceProvider(
+ render_frame_host_, GetBluetoothAdapterFactoryWrapper()->GetAdapter(this),
+ GetBluetoothAdapterFactoryWrapper()->GetScanDuration()));
+
+ device_provider_->GetDevice(
+ options->Clone(), base::Bind(&WebBluetoothServiceImpl::OnGetDeviceSuccess,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(options->Clone()), callback),
Jeffrey Yasskin 2016/05/13 04:41:59 Instead of cloning the options, would it make sens
ortuno 2016/05/13 20:11:18 Done.
+ base::Bind(&WebBluetoothServiceImpl::OnGetDeviceFailed,
+ weak_ptr_factory_.GetWeakPtr(), callback));
+}
+
void WebBluetoothServiceImpl::RemoteServerGetPrimaryServiceImpl(
const std::string& service_uuid,
const RemoteServerGetPrimaryServiceCallback& callback,
@@ -648,6 +699,60 @@ void WebBluetoothServiceImpl::RemoteServerGetPrimaryServiceImpl(
std::move(service_ptr));
}
+void WebBluetoothServiceImpl::OnGetDeviceSuccess(
+ blink::mojom::WebBluetoothRequestDeviceOptionsPtr options,
+ const RequestDeviceCallback& callback,
+ const std::string& device_address) {
+ blink::mojom::WebBluetoothDevicePtr device_ptr =
Jeffrey Yasskin 2016/05/13 04:41:59 I'd probably create this just before it's used for
ortuno 2016/05/13 20:11:18 Done.
+ blink::mojom::WebBluetoothDevice::New();
+
+ const device::BluetoothDevice* const device =
+ GetBluetoothAdapterFactoryWrapper()->GetAdapter(this)->GetDevice(
Jeffrey Yasskin 2016/05/13 04:41:59 Consider wrapping the "GetBluetoothAdapterFactoryW
ortuno 2016/05/13 20:11:18 Done.
+ device_address);
+ if (device == nullptr) {
+ VLOG(1) << "Device " << device_address << " no longer in adapter";
+ RecordRequestDeviceOutcome(UMARequestDeviceOutcome::CHOSEN_DEVICE_VANISHED);
+ callback.Run(blink::mojom::WebBluetoothError::CHOSEN_DEVICE_VANISHED,
+ nullptr /* device */);
+ device_provider_.reset();
Jeffrey Yasskin 2016/05/13 04:41:59 Can you reset this at the beginning of the functio
ortuno 2016/05/13 20:11:18 Done.
+ return;
+ }
+
+ const std::string device_id_for_origin =
+ allowed_devices_map_.AddDevice(GetOrigin(), device_address, options);
+
+ VLOG(1) << "Device: " << device->GetName();
+ VLOG(1) << "UUIDs: ";
+
+ mojo::Array<mojo::String> filtered_uuids;
+ for (const device::BluetoothUUID& uuid : device->GetUUIDs()) {
+ if (allowed_devices_map_.IsOriginAllowedToAccessService(
+ GetOrigin(), device_id_for_origin, uuid.canonical_value())) {
+ VLOG(1) << "\t Allowed: " << uuid.canonical_value();
+ filtered_uuids.push_back(uuid.canonical_value());
+ } else {
+ VLOG(1) << "\t Not Allowed: " << uuid.canonical_value();
+ }
+ }
+
+ device_ptr->id = device_id_for_origin;
+ device_ptr->name = base::UTF16ToUTF8(device->GetName());
+ device_ptr->uuids = std::move(filtered_uuids);
+
+ RecordRequestDeviceOutcome(UMARequestDeviceOutcome::SUCCESS);
+ callback.Run(blink::mojom::WebBluetoothError::SUCCESS, std::move(device_ptr));
+ device_provider_.reset();
+}
+
+void WebBluetoothServiceImpl::OnGetDeviceFailed(
+ const RequestDeviceCallback& callback,
+ blink::mojom::WebBluetoothError error) {
+ // Errors are recorded by the BluetoothDeviceProvider that called this
Jeffrey Yasskin 2016/05/13 04:41:59 Or just "by *device_provider_."?
ortuno 2016/05/13 20:11:18 Done.
+ // function.
+ callback.Run(error, nullptr /* device */);
+ device_provider_.reset();
+}
+
void WebBluetoothServiceImpl::OnCreateGATTConnectionSuccess(
const std::string& device_id,
base::TimeTicks start_time,
@@ -733,6 +838,29 @@ void WebBluetoothServiceImpl::OnStopNotifySessionComplete(
callback.Run();
}
+CacheQueryResult WebBluetoothServiceImpl::QueryCacheForDevice(
+ const std::string& device_id) {
+ const std::string& device_address =
+ allowed_devices_map_.GetDeviceAddress(GetOrigin(), device_id);
+ if (device_address.empty()) {
+ CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN);
+ return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
+ }
+
+ CacheQueryResult result;
+ result.device =
+ GetBluetoothAdapterFactoryWrapper()->GetAdapter(this)->GetDevice(
+ device_address);
+
+ // When a device can't be found in the BluetoothAdapter, that generally
+ // indicates that it's gone out of range. We reject with a NetworkError in
+ // that case.
+ if (result.device == nullptr) {
+ result.outcome = CacheQueryOutcome::NO_DEVICE;
+ }
+ return result;
+}
+
CacheQueryResult WebBluetoothServiceImpl::QueryCacheForService(
const std::string& service_instance_id) {
auto device_iter = service_id_to_device_address_.find(service_instance_id);
@@ -744,23 +872,14 @@ CacheQueryResult WebBluetoothServiceImpl::QueryCacheForService(
}
const std::string& device_id =
- GetBluetoothDispatcherHost()->allowed_devices_map_.GetDeviceId(
- GetOrigin(), device_iter->second);
+ allowed_devices_map_.GetDeviceId(GetOrigin(), device_iter->second);
// Kill the renderer if origin is not allowed to access the device.
if (device_id.empty()) {
CrashRendererAndClosePipe(bad_message::BDH_DEVICE_NOT_ALLOWED_FOR_ORIGIN);
return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
}
- CacheQueryResult result =
- GetBluetoothDispatcherHost()->QueryCacheForDevice(GetOrigin(), device_id);
-
- // TODO(ortuno): Remove once QueryCacheForDevice closes binding_.
- // http://crbug.com/508771
- if (result.outcome == CacheQueryOutcome::BAD_RENDERER) {
- binding_.Close();
- }
-
+ CacheQueryResult result = QueryCacheForDevice(device_id);
if (result.outcome != CacheQueryOutcome::SUCCESS) {
return result;
}
@@ -768,10 +887,9 @@ CacheQueryResult WebBluetoothServiceImpl::QueryCacheForService(
result.service = result.device->GetGattService(service_instance_id);
if (result.service == nullptr) {
result.outcome = CacheQueryOutcome::NO_SERVICE;
- } else if (!GetBluetoothDispatcherHost()
- ->allowed_devices_map_.IsOriginAllowedToAccessService(
- GetOrigin(), device_id,
- result.service->GetUUID().canonical_value())) {
+ } else if (!allowed_devices_map_.IsOriginAllowedToAccessService(
+ GetOrigin(), device_id,
+ result.service->GetUUID().canonical_value())) {
CrashRendererAndClosePipe(bad_message::BDH_SERVICE_NOT_ALLOWED_FOR_ORIGIN);
return CacheQueryResult(CacheQueryOutcome::BAD_RENDERER);
}
@@ -809,10 +927,11 @@ RenderProcessHost* WebBluetoothServiceImpl::GetRenderProcessHost() {
return render_frame_host_->GetProcess();
}
-BluetoothDispatcherHost* WebBluetoothServiceImpl::GetBluetoothDispatcherHost() {
+BluetoothAdapterFactoryWrapper*
+WebBluetoothServiceImpl::GetBluetoothAdapterFactoryWrapper() {
RenderProcessHostImpl* render_process_host_impl =
static_cast<RenderProcessHostImpl*>(GetRenderProcessHost());
- return render_process_host_impl->GetBluetoothDispatcherHost();
+ return render_process_host_impl->GetBluetoothAdapterFactoryWrapper();
}
void WebBluetoothServiceImpl::CrashRendererAndClosePipe(
@@ -832,6 +951,9 @@ void WebBluetoothServiceImpl::ClearState() {
service_id_to_device_address_.clear();
connected_devices_.reset(
new FrameConnectedBluetoothDevices(render_frame_host_));
+ allowed_devices_map_ = BluetoothAllowedDevicesMap();
+ device_provider_.reset();
+ GetBluetoothAdapterFactoryWrapper()->ReleaseAdapter(this);
}
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698