aboutsummaryrefslogtreecommitdiff
path: root/devel/electron33/files/patch-services_device_hid_hid__service__freebsd.cc
diff options
context:
space:
mode:
Diffstat (limited to 'devel/electron33/files/patch-services_device_hid_hid__service__freebsd.cc')
-rw-r--r--devel/electron33/files/patch-services_device_hid_hid__service__freebsd.cc398
1 files changed, 0 insertions, 398 deletions
diff --git a/devel/electron33/files/patch-services_device_hid_hid__service__freebsd.cc b/devel/electron33/files/patch-services_device_hid_hid__service__freebsd.cc
deleted file mode 100644
index 0e12715a6312..000000000000
--- a/devel/electron33/files/patch-services_device_hid_hid__service__freebsd.cc
+++ /dev/null
@@ -1,398 +0,0 @@
---- services/device/hid/hid_service_freebsd.cc.orig 2023-04-10 14:02:12 UTC
-+++ services/device/hid/hid_service_freebsd.cc
-@@ -0,0 +1,395 @@
-+// 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.
-+
-+#include "services/device/hid/hid_service_freebsd.h"
-+
-+#include <dev/usb/usb_ioctl.h>
-+#include <stdint.h>
-+#include <sys/socket.h>
-+#include <sys/un.h>
-+
-+#include <set>
-+#include <string>
-+#include <vector>
-+
-+#include "base/files/file_descriptor_watcher_posix.h"
-+#include "base/files/file_enumerator.h"
-+#include "base/files/file_util.h"
-+#include "base/files/file.h"
-+#include "base/location.h"
-+#include "base/logging.h"
-+#include "base/posix/eintr_wrapper.h"
-+#include "base/stl_util.h"
-+#include "base/strings/pattern.h"
-+#include "base/strings/stringprintf.h"
-+#include "base/strings/sys_string_conversions.h"
-+#include "base/strings/string_util.h"
-+#include "base/strings/string_split.h"
-+#include "base/task/single_thread_task_runner.h"
-+#include "base/task/thread_pool.h"
-+#include "base/threading/scoped_blocking_call.h"
-+#include "base/threading/thread_restrictions.h"
-+#include "components/device_event_log/device_event_log.h"
-+#include "services/device/hid/hid_connection_freebsd.h"
-+
-+const int kMaxPermissionChecks = 5;
-+
-+namespace device {
-+
-+struct HidServiceFreeBSD::ConnectParams {
-+ ConnectParams(scoped_refptr<HidDeviceInfo> device_info,
-+ bool allow_protected_reports,
-+ bool allow_fido_reports,
-+ ConnectCallback callback)
-+ : device_info(std::move(device_info)),
-+ allow_protected_reports(allow_protected_reports),
-+ allow_fido_reports(allow_fido_reports),
-+ callback(std::move(callback)),
-+ task_runner(base::SequencedTaskRunner::GetCurrentDefault()),
-+ blocking_task_runner(
-+ base::ThreadPool::CreateSequencedTaskRunner(kBlockingTaskTraits)) {}
-+ ~ConnectParams() {}
-+
-+ scoped_refptr<HidDeviceInfo> device_info;
-+ bool allow_protected_reports;
-+ bool allow_fido_reports;
-+ ConnectCallback callback;
-+ scoped_refptr<base::SequencedTaskRunner> task_runner;
-+ scoped_refptr<base::SequencedTaskRunner> blocking_task_runner;
-+ base::ScopedFD fd;
-+};
-+
-+class HidServiceFreeBSD::BlockingTaskRunnerHelper {
-+ public:
-+ BlockingTaskRunnerHelper(base::WeakPtr<HidServiceFreeBSD> service)
-+ : service_(std::move(service)),
-+ task_runner_(base::SequencedTaskRunner::GetCurrentDefault()) {
-+ DETACH_FROM_SEQUENCE(sequence_checker_);
-+
-+ timer_.reset(new base::RepeatingTimer());
-+ devd_buffer_ = new net::IOBufferWithSize(1024);
-+ }
-+
-+ BlockingTaskRunnerHelper(const BlockingTaskRunnerHelper&) = delete;
-+ BlockingTaskRunnerHelper& operator=(const BlockingTaskRunnerHelper&) = delete;
-+
-+ ~BlockingTaskRunnerHelper() {
-+ }
-+
-+ void Start() {
-+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-+
-+ const base::FilePath kDevRoot("/dev");
-+ const std::string kUHIDPattern("/dev/uhid*");
-+
-+ base::FileEnumerator enumerator(kDevRoot, false, base::FileEnumerator::FILES);
-+ do {
-+ const base::FilePath next_device_path(enumerator.Next());
-+ const std::string next_device = next_device_path.value();
-+ if (next_device.empty())
-+ break;
-+
-+ if (base::MatchPattern(next_device, kUHIDPattern))
-+ OnDeviceAdded(next_device.substr(5));
-+ } while (true);
-+
-+ SetupDevdMonitor();
-+
-+ task_runner_->PostTask(
-+ FROM_HERE,
-+ base::BindOnce(&HidServiceFreeBSD::FirstEnumerationComplete, service_));
-+ }
-+
-+ bool HaveReadWritePermissions(std::string device_id) {
-+ std::string device_node = "/dev/" + device_id;
-+ base::internal::AssertBlockingAllowed();
-+
-+ base::FilePath device_path(device_node);
-+ base::File device_file;
-+ int flags =
-+ base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE;
-+ device_file.Initialize(device_path, flags);
-+ if (!device_file.IsValid())
-+ return false;
-+
-+ return true;
-+ }
-+
-+ void OnDeviceAdded(std::string device_id) {
-+ base::ScopedBlockingCall scoped_blocking_call(
-+ FROM_HERE, base::BlockingType::MAY_BLOCK);
-+ std::string device_node = "/dev/" + device_id;
-+ uint16_t vendor_id = 0xffff;
-+ uint16_t product_id = 0xffff;
-+ std::string product_name = "";
-+ std::string serial_number = "";
-+
-+ std::vector<uint8_t> report_descriptor;
-+
-+ base::internal::AssertBlockingAllowed();
-+
-+ base::FilePath device_path(device_node);
-+ base::File device_file;
-+ int flags =
-+ base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE;
-+ device_file.Initialize(device_path, flags);
-+ if (!device_file.IsValid()) {
-+ HID_LOG(ERROR) << "Failed to open '" << device_node
-+ << "': "
-+ << base::File::ErrorToString(device_file.error_details());
-+ return;
-+ }
-+
-+ base::ScopedFD fd;
-+ fd.reset(device_file.TakePlatformFile());
-+
-+ struct usb_gen_descriptor ugd;
-+ ugd.ugd_data = NULL;
-+ ugd.ugd_maxlen = 0xffff;
-+ int result = HANDLE_EINTR(
-+ ioctl(fd.get(), USB_GET_REPORT_DESC, &ugd));
-+
-+ if (result < 0) {
-+ HID_LOG(ERROR) << "Failed to get report descriptor size";
-+ return;
-+ }
-+
-+ report_descriptor.resize(ugd.ugd_actlen);
-+
-+ ugd.ugd_data = report_descriptor.data();
-+ ugd.ugd_maxlen = ugd.ugd_actlen;
-+ result = HANDLE_EINTR(
-+ ioctl(fd.get(), USB_GET_REPORT_DESC, &ugd));
-+
-+ if (result < 0) {
-+ HID_LOG(ERROR) << "Failed to get report descriptor";
-+ return;
-+ }
-+
-+ scoped_refptr<HidDeviceInfo> device_info(new HidDeviceInfo(
-+ device_id,
-+ /*physical_device_id*/"",
-+ vendor_id,
-+ product_id,
-+ product_name,
-+ serial_number,
-+ device::mojom::HidBusType::kHIDBusTypeUSB,
-+ report_descriptor,
-+ device_node));
-+
-+ task_runner_->PostTask(FROM_HERE, base::BindOnce(&HidServiceFreeBSD::AddDevice,
-+ service_, device_info));
-+ }
-+
-+ void OnDeviceRemoved(std::string device_id) {
-+ base::ScopedBlockingCall scoped_blocking_call(
-+ FROM_HERE, base::BlockingType::MAY_BLOCK);
-+ task_runner_->PostTask(
-+ FROM_HERE, base::BindOnce(&HidServiceFreeBSD::RemoveDevice, service_,
-+ device_id));
-+ }
-+
-+ private:
-+
-+ void CheckPendingPermissionChange() {
-+ base::internal::AssertBlockingAllowed();
-+ std::map<std::string, int>::iterator it;
-+ for (it = permissions_checks_attempts_.begin(); it != permissions_checks_attempts_.end();) {
-+ std::string device_name = it->first;
-+ bool keep = true;
-+ if (HaveReadWritePermissions(device_name)) {
-+ OnDeviceAdded(device_name);
-+ keep = false;
-+ }
-+ else if (it->second-- <= 0) {
-+ HID_LOG(ERROR) << "Still don't have write permissions to '" << device_name
-+ << "' after " << kMaxPermissionChecks << " attempts";
-+ keep = false;
-+ }
-+
-+ if (keep)
-+ ++it;
-+ else
-+ permissions_checks_attempts_.erase(it++);
-+ }
-+
-+ if (permissions_checks_attempts_.empty())
-+ timer_->Stop();
-+ }
-+
-+ void SetupDevdMonitor() {
-+ base::internal::AssertBlockingAllowed();
-+
-+ int devd_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-+ if (devd_fd < 0)
-+ return;
-+
-+ struct sockaddr_un sa;
-+
-+ sa.sun_family = AF_UNIX;
-+ strlcpy(sa.sun_path, "/var/run/devd.seqpacket.pipe", sizeof(sa.sun_path));
-+ if (connect(devd_fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
-+ close(devd_fd);
-+ return;
-+ }
-+
-+ devd_fd_.reset(devd_fd);
-+ file_watcher_ = base::FileDescriptorWatcher::WatchReadable(
-+ devd_fd_.get(), base::BindRepeating(&BlockingTaskRunnerHelper::OnDevdMessageCanBeRead,
-+ base::Unretained(this)));
-+ }
-+
-+ void OnDevdMessageCanBeRead() {
-+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-+ ssize_t bytes_read = HANDLE_EINTR(recv(devd_fd_.get(), devd_buffer_->data(),
-+ devd_buffer_->size() - 1, MSG_WAITALL));
-+ if (bytes_read < 0) {
-+ if (errno != EAGAIN) {
-+ HID_LOG(ERROR) << "Read failed";
-+ file_watcher_.reset();
-+ }
-+ return;
-+ }
-+
-+ devd_buffer_->data()[bytes_read] = 0;
-+ char *data = devd_buffer_->data();
-+ // It may take some time for devd to change permissions
-+ // on /dev/uhidX node. So do not fail immediately if
-+ // open fail. Retry each second for kMaxPermissionChecks
-+ // times before giving up entirely
-+ if (base::StartsWith(data, "+uhid", base::CompareCase::SENSITIVE)) {
-+ std::vector<std::string> parts = base::SplitString(
-+ data, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
-+ if (!parts.empty()) {
-+ std::string device_name = parts[0].substr(1); // skip '+'
-+ if (HaveReadWritePermissions(device_name))
-+ OnDeviceAdded(parts[0].substr(1));
-+ else {
-+ // Do not re-add to checks
-+ if (permissions_checks_attempts_.find(device_name) == permissions_checks_attempts_.end()) {
-+ permissions_checks_attempts_.insert(std::pair<std::string, int>(device_name, kMaxPermissionChecks));
-+ timer_->Start(FROM_HERE, base::Seconds(1),
-+ this, &BlockingTaskRunnerHelper::CheckPendingPermissionChange);
-+ }
-+ }
-+ }
-+ }
-+
-+ if (base::StartsWith(data, "-uhid", base::CompareCase::SENSITIVE)) {
-+ std::vector<std::string> parts = base::SplitString(
-+ data, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
-+ if (!parts.empty()) {
-+ std::string device_name = parts[0].substr(1); // skip '-'
-+ auto it = permissions_checks_attempts_.find(device_name);
-+ if (it != permissions_checks_attempts_.end()) {
-+ permissions_checks_attempts_.erase(it);
-+ if (permissions_checks_attempts_.empty())
-+ timer_->Stop();
-+ }
-+ OnDeviceRemoved(parts[0].substr(1));
-+ }
-+ }
-+ }
-+
-+ SEQUENCE_CHECKER(sequence_checker_);
-+
-+ // This weak pointer is only valid when checked on this task runner.
-+ base::WeakPtr<HidServiceFreeBSD> service_;
-+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
-+ std::unique_ptr<base::FileDescriptorWatcher::Controller> file_watcher_;
-+ std::unique_ptr<base::RepeatingTimer> timer_;
-+ base::ScopedFD devd_fd_;
-+ scoped_refptr<net::IOBufferWithSize> devd_buffer_;
-+ std::map<std::string, int> permissions_checks_attempts_;
-+};
-+
-+HidServiceFreeBSD::HidServiceFreeBSD()
-+ : blocking_task_runner_(
-+ base::ThreadPool::CreateSequencedTaskRunner(kBlockingTaskTraits)),
-+ helper_(nullptr, base::OnTaskRunnerDeleter(blocking_task_runner_)) {
-+ helper_.reset(new BlockingTaskRunnerHelper(weak_factory_.GetWeakPtr()));
-+ blocking_task_runner_->PostTask(
-+ FROM_HERE,
-+ base::BindOnce(&BlockingTaskRunnerHelper::Start, base::Unretained(helper_.get())));
-+}
-+
-+HidServiceFreeBSD::~HidServiceFreeBSD() {
-+ blocking_task_runner_->DeleteSoon(FROM_HERE, helper_.release());
-+}
-+
-+base::WeakPtr<HidService> HidServiceFreeBSD::GetWeakPtr() {
-+ return weak_factory_.GetWeakPtr();
-+}
-+
-+// static
-+void HidServiceFreeBSD::OpenOnBlockingThread(
-+ std::unique_ptr<ConnectParams> params) {
-+ base::ScopedBlockingCall scoped_blocking_call(
-+ FROM_HERE, base::BlockingType::MAY_BLOCK);
-+ scoped_refptr<base::SequencedTaskRunner> task_runner = params->task_runner;
-+
-+ base::FilePath device_path(params->device_info->device_node());
-+ base::File device_file;
-+ int flags =
-+ base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE;
-+ device_file.Initialize(device_path, flags);
-+ if (!device_file.IsValid()) {
-+ HID_LOG(EVENT) << "Failed to open '" << params->device_info->device_node()
-+ << "': "
-+ << base::File::ErrorToString(device_file.error_details());
-+ task_runner->PostTask(FROM_HERE,
-+ base::BindOnce(std::move(params->callback), nullptr));
-+ return;
-+ }
-+ params->fd.reset(device_file.TakePlatformFile());
-+ task_runner->PostTask(FROM_HERE, base::BindOnce(&HidServiceFreeBSD::FinishOpen,
-+ std::move(params)));
-+}
-+
-+void HidServiceFreeBSD::Connect(const std::string& device_guid,
-+ bool allow_protected_reports,
-+ bool allow_fido_reports,
-+ ConnectCallback callback) {
-+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-+
-+ const auto& map_entry = devices().find(device_guid);
-+ if (map_entry == devices().end()) {
-+ base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
-+ FROM_HERE, base::BindOnce(std::move(callback), nullptr));
-+ return;
-+ }
-+
-+ scoped_refptr<HidDeviceInfo> device_info = map_entry->second;
-+
-+ auto params = std::make_unique<ConnectParams>(device_info,
-+ allow_protected_reports,
-+ allow_fido_reports,
-+ std::move(callback));
-+ scoped_refptr<base::SequencedTaskRunner> blocking_task_runner =
-+ params->blocking_task_runner;
-+
-+ blocking_task_runner->PostTask(
-+ FROM_HERE, base::BindOnce(&HidServiceFreeBSD::OpenOnBlockingThread,
-+ std::move(params)));
-+}
-+
-+// static
-+void HidServiceFreeBSD::FinishOpen(std::unique_ptr<ConnectParams> params) {
-+ DCHECK(params->fd.is_valid());
-+
-+ if (!base::SetNonBlocking(params->fd.get())) {
-+ HID_PLOG(ERROR) << "Failed to set the non-blocking flag on the device fd";
-+ std::move(params->callback).Run(nullptr);
-+ }
-+
-+ std::move(params->callback).Run(base::MakeRefCounted<HidConnectionFreeBSD>(
-+ std::move(params->device_info),
-+ std::move(params->fd),
-+ std::move(params->blocking_task_runner),
-+ params->allow_protected_reports,
-+ params->allow_fido_reports
-+ ));
-+}
-+
-+} // namespace device