--- www/chromium/files/patch-services_device_hid_hid__connection__freebsd.cc (revision 497386) +++ www/chromium/files/patch-services_device_hid_hid__connection__freebsd.cc (working copy) @@ -1,6 +1,6 @@ ---- services/device/hid/hid_connection_freebsd.cc.orig 2019-02-01 16:07:39.214979000 +0100 -+++ services/device/hid/hid_connection_freebsd.cc 2019-02-02 01:21:12.648154000 +0100 -@@ -0,0 +1,191 @@ +--- services/device/hid/hid_connection_freebsd.cc.orig 2019-03-30 17:42:59.718158000 -0700 ++++ services/device/hid/hid_connection_freebsd.cc 2019-03-30 21:54:38.653951000 -0700 +@@ -0,0 +1,240 @@ +// Copyright (c) 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. @@ -18,6 +18,7 @@ +#include "base/single_thread_task_runner.h" +#include "base/strings/stringprintf.h" +#include "base/task/post_task.h" ++#include "base/threading/scoped_blocking_call.h" +#include "base/threading/thread_restrictions.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/device_event_log/device_event_log.h" @@ -46,11 +47,18 @@ + void Start() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::internal::AssertBlockingAllowed(); ++ ++ file_watcher_ = base::FileDescriptorWatcher::WatchReadable( ++ fd_.get(), base::Bind(&BlockingTaskHelper::OnFileCanReadWithoutBlocking, ++ base::Unretained(this))); + } + + void Write(scoped_refptr buffer, + WriteCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ base::ScopedBlockingCall scoped_blocking_call( ++ base::BlockingType::MAY_BLOCK); ++ + auto data = buffer->front(); + size_t size = buffer->size(); + // if report id is 0, it shouldn't be included @@ -74,6 +82,8 @@ + scoped_refptr buffer, + ReadCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ base::ScopedBlockingCall scoped_blocking_call( ++ base::BlockingType::MAY_BLOCK); + struct usb_gen_descriptor ugd; + ugd.ugd_report_type = UHID_FEATURE_REPORT; + ugd.ugd_data = buffer->front(); @@ -122,6 +132,42 @@ + } + + private: ++ void OnFileCanReadWithoutBlocking() { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ ++ scoped_refptr buffer(new base::RefCountedBytes(report_buffer_size_)); ++ unsigned char* data = buffer->front(); ++ size_t length = report_buffer_size_; ++ if (!has_report_id_) { ++ // FreeBSD will not prefix the buffer with a report ID if report IDs are not ++ // used by the device. Prefix the buffer with 0. ++ *data++ = 0; ++ length--; ++ } ++ ++ ssize_t bytes_read = HANDLE_EINTR(read(fd_.get(), data, length)); ++ if (bytes_read < 0) { ++ if (errno != EAGAIN) { ++ HID_PLOG(EVENT) << "Read failed"; ++ // This assumes that the error is unrecoverable and disables reading ++ // from the device until it has been re-opened. ++ // TODO(reillyg): Investigate starting and stopping the file descriptor ++ // watcher in response to pending read requests so that per-request ++ // errors can be returned to the client. ++ file_watcher_.reset(); ++ } ++ return; ++ } ++ if (!has_report_id_) { ++ // Behave as if the byte prefixed above as the the report ID was read. ++ bytes_read++; ++ } ++ ++ origin_task_runner_->PostTask( ++ FROM_HERE, base::BindOnce(&HidConnectionFreeBSD::ProcessInputReport, ++ connection_, buffer, bytes_read)); ++ } ++ + SEQUENCE_CHECKER(sequence_checker_); + base::ScopedFD fd_; + size_t report_buffer_size_; @@ -128,6 +174,7 @@ + bool has_report_id_; + base::WeakPtr connection_; + const scoped_refptr origin_task_runner_; ++ std::unique_ptr file_watcher_; + + DISALLOW_COPY_AND_ASSIGN(BlockingTaskHelper); +}; @@ -185,6 +232,8 @@ +void HidConnectionFreeBSD::PlatformSendFeatureReport( + scoped_refptr buffer, + WriteCallback callback) { ++ base::ScopedBlockingCall scoped_blocking_call( ++ base::BlockingType::MAY_BLOCK); + blocking_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&BlockingTaskHelper::SendFeatureReport, --- www/chromium/files/patch-services_device_hid_hid__connection__freebsd.h (revision 497386) +++ www/chromium/files/patch-services_device_hid_hid__connection__freebsd.h (working copy) @@ -1,6 +1,6 @@ ---- services/device/hid/hid_connection_freebsd.h.orig 2018-12-27 21:14:54.190483000 +0100 -+++ services/device/hid/hid_connection_freebsd.h 2018-12-28 15:27:41.475526000 +0100 -@@ -0,0 +1,70 @@ +--- services/device/hid/hid_connection_freebsd.h.orig 2019-03-30 17:42:59.719257000 -0700 ++++ services/device/hid/hid_connection_freebsd.h 2019-03-30 21:53:54.126040000 -0700 +@@ -0,0 +1,68 @@ +// Copyright (c) 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. @@ -50,8 +50,6 @@ + ReadCallback callback) override; + void PlatformSendFeatureReport(scoped_refptr buffer, + WriteCallback callback) override; -+ void ProcessInputReport(scoped_refptr buffer, -+ size_t size); + + // |helper_| lives on the sequence to which |blocking_task_runner_| posts + // tasks so all calls must be posted there including this object's --- www/chromium/files/patch-services_device_hid_hid__service__freebsd.cc (revision 497386) +++ www/chromium/files/patch-services_device_hid_hid__service__freebsd.cc (working copy) @@ -1,6 +1,6 @@ ---- services/device/hid/hid_service_freebsd.cc.orig 2019-02-01 16:07:39.219688000 +0100 -+++ services/device/hid/hid_service_freebsd.cc 2019-02-02 00:41:58.747111000 +0100 -@@ -0,0 +1,371 @@ +--- services/device/hid/hid_service_freebsd.cc.orig 2019-03-30 17:42:59.721025000 -0700 ++++ services/device/hid/hid_service_freebsd.cc 2019-03-30 22:02:19.316167000 -0700 +@@ -0,0 +1,373 @@ +// 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. @@ -30,7 +30,7 @@ +#include "base/strings/string_util.h" +#include "base/strings/string_split.h" +#include "base/task/post_task.h" -+#include "base/threading/thread_restrictions.h" ++#include "base/threading/scoped_blocking_call.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/device_event_log/device_event_log.h" +#include "services/device/hid/hid_connection_freebsd.h" @@ -71,7 +71,6 @@ + } + + void Start() { -+ base::internal::AssertBlockingAllowed(); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + const base::FilePath kDevRoot("/dev"); @@ -111,6 +110,8 @@ + } + + void OnDeviceAdded(std::string device_id) { ++ base::ScopedBlockingCall scoped_blocking_call( ++ base::BlockingType::MAY_BLOCK); + std::string device_node = "/dev/" + device_id; + uint16_t vendor_id = 0xffff; + uint16_t product_id = 0xffff; @@ -169,6 +170,8 @@ + } + + void OnDeviceRemoved(std::string device_id) { ++ base::ScopedBlockingCall scoped_blocking_call( ++ base::BlockingType::MAY_BLOCK); + task_runner_->PostTask( + FROM_HERE, base::Bind(&HidServiceFreeBSD::RemoveDevice, service_, + device_id)); @@ -312,7 +315,7 @@ +// static +void HidServiceFreeBSD::OpenOnBlockingThread( + std::unique_ptr params) { -+ base::internal::AssertBlockingAllowed(); ++ base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); + scoped_refptr task_runner = params->task_runner; + + base::FilePath device_path(params->device_info->device_node()); @@ -355,7 +358,6 @@ + +// static +void HidServiceFreeBSD::FinishOpen(std::unique_ptr params) { -+ base::internal::AssertBlockingAllowed(); + scoped_refptr task_runner = params->task_runner; + + task_runner->PostTask(