Index: head/www/chromium/Makefile =================================================================== --- head/www/chromium/Makefile (revision 455494) +++ head/www/chromium/Makefile (revision 455495) @@ -1,301 +1,301 @@ # Created by: Florent Thoumie # $FreeBSD$ PORTNAME= chromium PORTVERSION= 61.0.3163.100 -PORTREVISION= 3 +PORTREVISION= 4 CATEGORIES?= www MASTER_SITES= https://commondatastorage.googleapis.com/chromium-browser-official/ DISTFILES= ${DISTNAME}${EXTRACT_SUFX} MAINTAINER?= chromium@FreeBSD.org COMMENT?= Google web browser based on WebKit LICENSE= BSD3CLAUSE LGPL21 MPL11 LICENSE_COMB= multi BUILD_DEPENDS= python:lang/python \ bash:shells/bash \ ${PYTHON_PKGNAMEPREFIX}Jinja2>0:devel/py-Jinja2@${PY_FLAVOR} \ ${PYTHON_PKGNAMEPREFIX}ply>0:devel/py-ply@${PY_FLAVOR} \ .if !defined(GN_ONLY) BUILD_DEPENDS+= gperf:devel/gperf \ clang40:devel/llvm40 \ yasm:devel/yasm \ ffmpeg>=3.2.2,1:multimedia/ffmpeg \ flock:sysutils/flock \ node:www/node \ ${LOCALBASE}/include/linux/videodev2.h:multimedia/v4l_compat \ ${LOCALBASE}/share/usbids/usb.ids:misc/usbids \ ${PYTHON_PKGNAMEPREFIX}html5lib>0:www/py-html5lib@${PY_FLAVOR} .endif .if !defined(GN_ONLY) LIB_DEPENDS= libspeechd.so:accessibility/speech-dispatcher \ libsnappy.so:archivers/snappy \ libFLAC.so:audio/flac \ libspeex.so:audio/speex \ libdbus-1.so:devel/dbus \ libdbus-glib-1.so:devel/dbus-glib \ libicuuc.so:devel/icu \ libjsoncpp.so:devel/jsoncpp \ libpci.so:devel/libpci \ libnspr4.so:devel/nspr \ libre2.so:devel/re2 \ libcairo.so:graphics/cairo \ libdrm.so:graphics/libdrm \ libexif.so:graphics/libexif \ libpng.so:graphics/png \ libwebp.so:graphics/webp \ libavcodec.so:multimedia/ffmpeg \ libcups.so:print/cups \ libharfbuzz.so:print/harfbuzz \ libharfbuzz-icu.so:print/harfbuzz-icu \ libgcrypt.so:security/libgcrypt \ libgnome-keyring.so:security/libgnome-keyring \ libnss3.so:security/nss \ libexpat.so:textproc/expat2 \ libxml2.so:textproc/libxml2 \ libfontconfig.so:x11-fonts/fontconfig RUN_DEPENDS= xdg-open:devel/xdg-utils \ droid-fonts-ttf>0:x11-fonts/droid-fonts-ttf ONLY_FOR_ARCHS= aarch64 amd64 i386 .endif .if defined(GN_ONLY) USES= compiler:c++14-lang ninja pkgconfig python:2,build shebangfix tar:xz .else USES= bison cpe desktop-file-utils jpeg ninja perl5 pkgconfig \ python:2,build shebangfix tar:xz .endif MAKE_ARGS= -C out/${BUILDTYPE} .if !defined(GN_ONLY) CPE_VENDOR= google CPE_PRODUCT= chrome USE_LDCONFIG= ${DATADIR} USE_PERL5= build USE_XORG= scrnsaverproto x11 xcb xcomposite xcursor xext xdamage xfixes xi \ xproto xrandr xrender xscrnsaver xtst USE_GNOME= atk dconf glib20 gtk30 libxml2 libxslt SHEBANG_FILES= chrome/tools/build/linux/chrome-wrapper ALL_TARGET= chrome INSTALLS_ICONS= yes CC= clang40 CXX= clang++40 .endif EXTRA_PATCHES+= ${FILESDIR}/extra-patch-clang # TODO bz@ : install libwidevinecdm.so (see third_party/widevine/cdm/BUILD.gn) # # Run "./out/${BUILDTYPE}/gn args out/${BUILDTYPE} --list" for all variables. # Some parts don't have use_system_* flag, and can be turned on/off by using # replace_gn_files.py script, some parts just turned on/off for target host # OS "target_os == is_bsd", like libusb, libpci. GN_ARGS+= clang_use_chrome_plugins=false \ enable_nacl=false \ enable_one_click_signin=true \ enable_remoting=false \ enable_webrtc=false \ fieldtrial_testing_like_official_build=true \ is_clang=true \ toolkit_views=true \ treat_warnings_as_errors=false \ use_allocator="none" \ use_allocator_shim=false \ use_aura=true \ use_cups=true \ use_gtk3=true \ use_lld=true \ use_sysroot=false \ use_system_libjpeg=true \ use_system_sqlite=false # chrome has additional patches # TODO: investigate building with these options: # use_system_icu use_system_harfbuzz use_system_minigbm GN_BOOTSTRAP_FLAGS= --no-clean --no-rebuild # FreeBSD Chromium Api Key # Set up Google API keys, see http://www.chromium.org/developers/how-tos/api-keys . # Note: these are for FreeBSD use ONLY. For your own distribution, # please get your own set of keys. GN_ARGS+= google_api_key="AIzaSyBsp9n41JLW8jCokwn7vhoaMejDFRd1mp8" \ google_default_client_id="996322985003.apps.googleusercontent.com" \ google_default_client_secret="IR1za9-1VK0zZ0f_O8MVFicn" .if !defined(GN_ONLY) SUB_FILES= chromium-browser.desktop chrome SUB_LIST+= COMMENT="${COMMENT}" OPTIONS_DEFINE= CODECS GCONF KERBEROS DRIVER CODECS_DESC= Compile and enable patented codecs like H.264 DRIVER_DESC= Install chromedriver OPTIONS_GROUP= AUDIO TESTS OPTIONS_GROUP_AUDIO= ALSA PULSEAUDIO SNDIO OPTIONS_GROUP_TESTS= DEBUG TEST OPTIONS_DEFAULT= ALSA CODECS DRIVER GCONF KERBEROS OPTIONS_SUB= yes ALSA_LIB_DEPENDS= libasound.so:audio/alsa-lib ALSA_RUN_DEPENDS= ${LOCALBASE}/lib/alsa-lib/libasound_module_pcm_oss.so:audio/alsa-plugins \ alsa-lib>=1.1.1_1:audio/alsa-lib ALSA_VARS= GN_ARGS+=use_alsa=true ALSA_VARS_OFF= GN_ARGS+=use_alsa=false CODECS_VARS= GN_ARGS+=ffmpeg_branding="Chrome" \ GN_ARGS+=proprietary_codecs=true \ GN_ARGS+=enable_hevc_demuxing=true CODECS_VARS_OFF= GN_ARGS+=ffmpeg_branding="Chromium" \ GN_ARGS+=proprietary_codecs=false \ GN_ARGS+=enable_hevc_demuxing=false DEBUG_VARS= BUILDTYPE=Debug \ GN_ARGS+=is_debug=true \ GN_BOOTSTRAP_FLAGS+=--debug \ WANTSPACE="lots of free diskspace (~ 8.5GB)" DEBUG_VARS_OFF= BUILDTYPE=Release \ GN_ARGS+=is_debug=false \ GN_ARGS+=symbol_level=0 \ GN_ARGS+=remove_webcore_debug_symbols=true \ WANTSPACE="a fair amount of free diskspace (~ 3.7GB)" DRIVER_MAKE_ARGS= chromedriver GCONF_USE= GNOME=gconf2 GCONF_VARS= GN_ARGS+=use_gconf=true GCONF_VARS_OFF= GN_ARGS+=use_gconf=false KERBEROS_VARS= GN_ARGS+=use_kerberos=true KERBEROS_VARS_OFF= GN_ARGS+=use_kerberos=false PULSEAUDIO_LIB_DEPENDS= libpulse.so:audio/pulseaudio PULSEAUDIO_VARS= GN_ARGS+=use_pulseaudio=true PULSEAUDIO_VARS_OFF= GN_ARGS+=use_pulseaudio=false # With SNDIO=on we exclude audio_manager_linux from the build (see # media/audio/BUILD.gn) and use audio_manager_openbsd which does not # support falling back to ALSA or PulseAudio. SNDIO_PREVENTS= ALSA PULSEAUDIO SNDIO_LIB_DEPENDS= libsndio.so:audio/sndio SNDIO_VARS= GN_ARGS+=use_sndio=true SNDIO_VARS_OFF= GN_ARGS+=use_sndio=false .endif .include "Makefile.tests" TEST_ALL_TARGET= ${TEST_TARGETS} TEST_DISTFILES= ${PORTNAME}-${DISTVERSION}-testdata${EXTRACT_SUFX} .include # TODO: -isystem, would be just as ugly as this approach, but more reliably # build would fail without C_INCLUDE_PATH/CPLUS_INCLUDE_PATH env var set. MAKE_ENV+= C_INCLUDE_PATH=${LOCALBASE}/include \ CPLUS_INCLUDE_PATH=${LOCALBASE}/include # Work around base r261801 .if ${OPSYS} == FreeBSD && ${OSVERSION} < 1100508 GN_ARGS+= extra_cxxflags="-D_LIBCPP_TRIVIAL_PAIR_COPY_CTOR=1" EXTRA_PATCHES+= ${FILESDIR}/extra-patch-libc++-old .else EXTRA_PATCHES+= ${FILESDIR}/extra-patch-libc++-new .endif .if ${ARCH} == aarch64 GN_ARGS+= use_vulcanize=false .endif .if !defined(GN_ONLY) pre-everything:: @${ECHO_MSG} @${ECHO_MSG} "To build Chromium, you should have around 2GB of memory" @${ECHO_MSG} "and ${WANTSPACE}." @${ECHO_MSG} post-patch-SNDIO-on: @${MKDIR} ${WRKSRC}/media/audio/sndio ${WRKSRC}/media/audio/openbsd @${CP} ${FILESDIR}/sndio_output.* ${WRKSRC}/media/audio/sndio @${CP} ${FILESDIR}/sndio_input.* ${WRKSRC}/media/audio/sndio @${CP} ${FILESDIR}/audio_manager_openbsd.* ${WRKSRC}/media/audio/openbsd pre-configure: # We used to remove bundled libraries to be sure that chromium uses # system libraries and not shipped ones. # cd ${WRKSRC} && ${PYTHON_CMD} \ #./build/linux/unbundle/remove_bundled_libraries.py [list of preserved] cd ${WRKSRC} && ${PYTHON_CMD} \ ./build/linux/unbundle/replace_gn_files.py --system-libraries \ ffmpeg flac harfbuzz-ng libwebp libxml libxslt snappy yasm || ${FALSE} .endif do-configure: # GN generator bootstrapping and generating ninja files cd ${WRKSRC} && ${SETENV} CC=${CC} CXX=${CXX} LD=${CXX} \ READELF=${READELF} AR=${AR} NM=${NM} ${PYTHON_CMD} \ ./tools/gn/bootstrap/bootstrap.py ${GN_BOOTSTRAP_FLAGS} .if !defined(GN_ONLY) cd ${WRKSRC} && ${SETENV} ./out/${BUILDTYPE}/gn \ gen --args='${GN_ARGS}' out/${BUILDTYPE} # Setup nodejs dependency @${MKDIR} ${WRKSRC}/third_party/node/freebsd/node-freebsd-x64/bin ${LN} -sf ${LOCALBASE}/bin/node ${WRKSRC}/third_party/node/freebsd/node-freebsd-x64/bin/node .endif do-test-TEST-on: .for t in ${TEST_TARGETS} cd ${WRKSRC}/out/${BUILDTYPE} && ${SETENV} LC_ALL=en_US.UTF-8 \ ./${t} --gtest_filter=-${EXCLUDE_${t}:ts:} || ${TRUE} .endfor .if !defined(GN_ONLY) do-install: @${MKDIR} ${STAGEDIR}${DATADIR} ${INSTALL_MAN} ${WRKSRC}/out/${BUILDTYPE}/chrome.1 ${STAGEDIR}${MANPREFIX}/man/man1 .for m in font_service test_ime_driver ui ${INSTALL_DATA} ${WRKSRC}/out/${BUILDTYPE}/${m}.service \ ${STAGEDIR}${DATADIR} .endfor .for s in 22 24 48 64 128 256 @${MKDIR} ${STAGEDIR}${PREFIX}/share/icons/hicolor/${s}x${s}/apps ${INSTALL_DATA} ${WRKSRC}/chrome/app/theme/chromium/product_logo_${s}.png \ ${STAGEDIR}${PREFIX}/share/icons/hicolor/${s}x${s}/apps/chrome.png .endfor ${INSTALL_SCRIPT} ${WRKSRC}/chrome/tools/build/linux/chrome-wrapper \ ${STAGEDIR}${DATADIR} .for p in chrome_100_percent chrome_200_percent headless_lib keyboard_resources \ resources mus_app_resources_100 mus_app_resources_200 mus_app_resources_strings \ views_mus_resources ${INSTALL_DATA} ${WRKSRC}/out/${BUILDTYPE}/${p}.pak \ ${STAGEDIR}${DATADIR} .endfor .for d in icudtl.dat natives_blob.bin snapshot_blob.bin ${INSTALL_DATA} ${WRKSRC}/out/${BUILDTYPE}/${d} ${STAGEDIR}${DATADIR} .endfor ${INSTALL_PROGRAM} ${WRKSRC}/out/${BUILDTYPE}/chrome \ ${STAGEDIR}${DATADIR} cd ${WRKSRC}/out/${BUILDTYPE} && \ ${COPYTREE_SHARE} "locales resources" ${STAGEDIR}${DATADIR} @${MKDIR} ${STAGEDIR}${DESKTOPDIR} ${INSTALL_DATA} ${WRKDIR}/chromium-browser.desktop \ ${STAGEDIR}${DESKTOPDIR} ${INSTALL_SCRIPT} ${WRKDIR}/chrome ${STAGEDIR}${PREFIX}/bin ${INSTALL_PROGRAM} ${WRKSRC}/out/${BUILDTYPE}/mksnapshot \ ${STAGEDIR}${DATADIR} post-install-DEBUG-on: ${INSTALL_LIB} ${WRKSRC}/out/${BUILDTYPE}/*.so \ ${STAGEDIR}${DATADIR} ${INSTALL_PROGRAM} ${WRKSRC}/out/${BUILDTYPE}/character_data_generator \ ${STAGEDIR}${DATADIR} post-install-DRIVER-on: ${INSTALL_PROGRAM} ${WRKSRC}/out/${BUILDTYPE}/chromedriver \ ${STAGEDIR}${PREFIX}/bin .endif .include Index: head/www/chromium/files/patch-device_hid_BUILD.gn =================================================================== --- head/www/chromium/files/patch-device_hid_BUILD.gn (revision 455494) +++ head/www/chromium/files/patch-device_hid_BUILD.gn (revision 455495) @@ -1,16 +1,24 @@ ---- device/hid/BUILD.gn.orig 2017-04-19 19:06:34 UTC -+++ device/hid/BUILD.gn -@@ -56,6 +56,13 @@ source_set("hid") { - deps += [ "//device/udev_linux" ] +--- device/hid/BUILD.gn.orig 2017-12-03 15:37:09.320721000 -0800 ++++ device/hid/BUILD.gn 2017-12-03 15:37:32.146570000 -0800 +@@ -63,6 +63,21 @@ + ] } + if (is_bsd) { + sources -= [ + "hid_connection_linux.cc", + "hid_connection_linux.h", ++ ] ++ sources += [ ++ "hid_connection_freebsd.cc", ++ "hid_connection_freebsd.h", ++ "hid_device_info_freebsd.cc", ++ "hid_device_info_freebsd.h", ++ "hid_service_freebsd.cc", ++ "hid_service_freebsd.h", + ] + } + if (is_chromeos) { deps += [ "//chromeos" ] } Index: head/www/chromium/files/patch-device_hid_hid__connection__freebsd.cc =================================================================== --- head/www/chromium/files/patch-device_hid_hid__connection__freebsd.cc (nonexistent) +++ head/www/chromium/files/patch-device_hid_hid__connection__freebsd.cc (revision 455495) @@ -0,0 +1,281 @@ +--- device/hid/hid_connection_freebsd.cc.orig 2017-12-03 15:37:32.146994000 -0800 ++++ device/hid/hid_connection_freebsd.cc 2017-12-03 15:37:32.154605000 -0800 +@@ -0,0 +1,278 @@ ++// 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. ++ ++#include "device/hid/hid_connection_freebsd.h" ++ ++#include ++#include ++ ++#include "base/bind.h" ++#include "base/files/file_descriptor_watcher_posix.h" ++#include "base/location.h" ++#include "base/numerics/safe_math.h" ++#include "base/posix/eintr_wrapper.h" ++#include "base/single_thread_task_runner.h" ++#include "base/strings/stringprintf.h" ++#include "base/task_scheduler/post_task.h" ++#include "base/threading/thread_restrictions.h" ++#include "base/threading/thread_task_runner_handle.h" ++#include "components/device_event_log/device_event_log.h" ++#include "device/hid/hid_service.h" ++ ++namespace device { ++ ++class HidConnectionFreeBSD::BlockingTaskHelper { ++ public: ++ BlockingTaskHelper(base::ScopedFD fd, ++ scoped_refptr device_info, ++ base::WeakPtr connection) ++ : fd_(std::move(fd)), ++ connection_(connection), ++ origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) { ++ DETACH_FROM_SEQUENCE(sequence_checker_); ++ // Report buffers must always have room for the report ID. ++ report_buffer_size_ = device_info->max_input_report_size() + 1; ++ has_report_id_ = device_info->has_report_id(); ++ } ++ ++ ~BlockingTaskHelper() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } ++ ++ // Starts the FileDescriptorWatcher that reads input events from the device. ++ // Must be called on a thread that has a base::MessageLoopForIO. ++ void Start() { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ base::ThreadRestrictions::AssertIOAllowed(); ++ ++ file_watcher_ = base::FileDescriptorWatcher::WatchReadable( ++ fd_.get(), base::Bind(&BlockingTaskHelper::OnFileCanReadWithoutBlocking, ++ base::Unretained(this))); ++ } ++ ++ void Write(scoped_refptr buffer, ++ size_t size, ++ const WriteCallback& callback) { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ char *data = buffer->data(); ++ // if report id is 0, it shouldn't be included ++ if (data[0] == 0) { ++ data++; ++ size--; ++ } ++ ++ ssize_t result = HANDLE_EINTR(write(fd_.get(), data, size)); ++ if (result < 0) { ++ HID_PLOG(EVENT) << "Write failed"; ++ origin_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); ++ } else { ++ if (static_cast(result) != size) ++ HID_LOG(EVENT) << "Incomplete HID write: " << result << " != " << size; ++ origin_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); ++ } ++ } ++ ++ void GetFeatureReport(uint8_t report_id, ++ scoped_refptr buffer, ++ const ReadCallback& callback) { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ struct usb_gen_descriptor ugd; ++ ugd.ugd_report_type = UHID_FEATURE_REPORT; ++ ugd.ugd_data = buffer->data(); ++ ugd.ugd_maxlen = buffer->size(); ++ int result = HANDLE_EINTR( ++ ioctl(fd_.get(), USB_GET_REPORT, &ugd)); ++ if (result < 0) { ++ HID_PLOG(EVENT) << "Failed to get feature report"; ++ origin_task_runner_->PostTask(FROM_HERE, ++ base::Bind(callback, false, nullptr, 0)); ++ } else if (result == 0) { ++ HID_LOG(EVENT) << "Get feature result too short."; ++ origin_task_runner_->PostTask(FROM_HERE, ++ base::Bind(callback, false, nullptr, 0)); ++ } else { ++ origin_task_runner_->PostTask(FROM_HERE, ++ base::Bind(callback, true, buffer, result)); ++ } ++ } ++ ++ void SendFeatureReport(scoped_refptr buffer, ++ size_t size, ++ const WriteCallback& callback) { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ struct usb_gen_descriptor ugd; ++ ugd.ugd_report_type = UHID_FEATURE_REPORT; ++ ugd.ugd_data = buffer->data(); ++ ugd.ugd_maxlen = size; ++ // FreeBSD does not require report id if it's not used ++ if (buffer->data()[0] == 0) { ++ ugd.ugd_data = buffer->data() + 1; ++ ugd.ugd_maxlen = size - 1; ++ } else { ++ ugd.ugd_data = buffer->data(); ++ ugd.ugd_maxlen = size; ++ } ++ int result = HANDLE_EINTR( ++ ioctl(fd_.get(), USB_SET_REPORT, &ugd)); ++ if (result < 0) { ++ HID_PLOG(EVENT) << "Failed to send feature report"; ++ origin_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); ++ } else { ++ origin_task_runner_->PostTask(FROM_HERE, base::Bind(callback, true)); ++ } ++ } ++ ++ private: ++ void OnFileCanReadWithoutBlocking() { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ ++ scoped_refptr buffer(new net::IOBuffer(report_buffer_size_)); ++ char* data = buffer->data(); ++ 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::Bind(&HidConnectionFreeBSD::ProcessInputReport, ++ connection_, buffer, bytes_read)); ++ } ++ ++ SEQUENCE_CHECKER(sequence_checker_); ++ base::ScopedFD fd_; ++ size_t report_buffer_size_; ++ bool has_report_id_; ++ base::WeakPtr connection_; ++ const scoped_refptr origin_task_runner_; ++ std::unique_ptr file_watcher_; ++ ++ DISALLOW_COPY_AND_ASSIGN(BlockingTaskHelper); ++}; ++ ++HidConnectionFreeBSD::HidConnectionFreeBSD( ++ scoped_refptr device_info, ++ base::ScopedFD fd, ++ scoped_refptr blocking_task_runner) ++ : HidConnection(device_info), ++ blocking_task_runner_(std::move(blocking_task_runner)), ++ weak_factory_(this) { ++ helper_ = base::MakeUnique(std::move(fd), device_info, ++ weak_factory_.GetWeakPtr()); ++ blocking_task_runner_->PostTask( ++ FROM_HERE, ++ base::Bind(&BlockingTaskHelper::Start, base::Unretained(helper_.get()))); ++} ++ ++HidConnectionFreeBSD::~HidConnectionFreeBSD() {} ++ ++void HidConnectionFreeBSD::PlatformClose() { ++ // By closing the device on the blocking task runner 1) the requirement that ++ // base::ScopedFD is destroyed on a thread where I/O is allowed is satisfied ++ // and 2) any tasks posted to this task runner that refer to this file will ++ // complete before it is closed. ++ blocking_task_runner_->DeleteSoon(FROM_HERE, helper_.release()); ++ ++ while (!pending_reads_.empty()) { ++ pending_reads_.front().callback.Run(false, NULL, 0); ++ pending_reads_.pop(); ++ } ++} ++ ++void HidConnectionFreeBSD::PlatformRead(const ReadCallback& callback) { ++ DCHECK(thread_checker().CalledOnValidThread()); ++ PendingHidRead pending_read; ++ pending_read.callback = callback; ++ pending_reads_.push(pending_read); ++ ProcessReadQueue(); ++} ++ ++void HidConnectionFreeBSD::PlatformWrite(scoped_refptr buffer, ++ size_t size, ++ const WriteCallback& callback) { ++ ++ blocking_task_runner_->PostTask( ++ FROM_HERE, ++ base::Bind(&BlockingTaskHelper::Write, base::Unretained(helper_.get()), ++ buffer, size, callback)); ++} ++ ++void HidConnectionFreeBSD::PlatformGetFeatureReport(uint8_t report_id, ++ const ReadCallback& callback) { ++ // The first byte of the destination buffer is the report ID being requested ++ // and is overwritten by the feature report. ++ DCHECK_GT(device_info()->max_feature_report_size(), 0u); ++ scoped_refptr buffer( ++ new net::IOBufferWithSize(device_info()->max_feature_report_size() + 1)); ++ if (report_id != 0) ++ buffer->data()[0] = report_id; ++ ++ blocking_task_runner_->PostTask( ++ FROM_HERE, ++ base::Bind(&BlockingTaskHelper::GetFeatureReport, ++ base::Unretained(helper_.get()), report_id, buffer, callback)); ++} ++ ++void HidConnectionFreeBSD::PlatformSendFeatureReport( ++ scoped_refptr buffer, ++ size_t size, ++ const WriteCallback& callback) { ++ blocking_task_runner_->PostTask( ++ FROM_HERE, ++ base::Bind(&BlockingTaskHelper::SendFeatureReport, ++ base::Unretained(helper_.get()), buffer, size, callback)); ++} ++ ++void HidConnectionFreeBSD::ProcessInputReport( ++ scoped_refptr buffer, ++ size_t size) { ++ DCHECK(thread_checker().CalledOnValidThread()); ++ DCHECK_GE(size, 1u); ++ ++ uint8_t report_id = buffer->data()[0]; ++ if (IsReportIdProtected(report_id)) ++ return; ++ ++ PendingHidReport report; ++ report.buffer = buffer; ++ report.size = size; ++ pending_reports_.push(report); ++ ProcessReadQueue(); ++} ++ ++void HidConnectionFreeBSD::ProcessReadQueue() { ++ DCHECK(thread_checker().CalledOnValidThread()); ++ ++ // Hold a reference to |this| to prevent a callback from freeing this object ++ // during the loop. ++ scoped_refptr self(this); ++ while (pending_reads_.size() && pending_reports_.size()) { ++ PendingHidRead read = pending_reads_.front(); ++ PendingHidReport report = pending_reports_.front(); ++ ++ pending_reads_.pop(); ++ pending_reports_.pop(); ++ read.callback.Run(true, report.buffer, report.size); ++ } ++} ++ ++} // namespace device Property changes on: head/www/chromium/files/patch-device_hid_hid__connection__freebsd.cc ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/www/chromium/files/patch-device_hid_hid__connection__freebsd.h =================================================================== --- head/www/chromium/files/patch-device_hid_hid__connection__freebsd.h (nonexistent) +++ head/www/chromium/files/patch-device_hid_hid__connection__freebsd.h (revision 455495) @@ -0,0 +1,79 @@ +--- device/hid/hid_connection_freebsd.h.orig 2017-12-03 15:37:32.155357000 -0800 ++++ device/hid/hid_connection_freebsd.h 2017-12-03 15:37:32.159062000 -0800 +@@ -0,0 +1,76 @@ ++// 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. ++ ++#ifndef DEVICE_HID_HID_CONNECTION_FREEBSD_H_ ++#define DEVICE_HID_HID_CONNECTION_FREEBSD_H_ ++ ++#include ++#include ++ ++#include ++ ++#include "base/files/scoped_file.h" ++#include "base/macros.h" ++#include "base/memory/weak_ptr.h" ++#include "base/sequence_checker.h" ++#include "device/hid/hid_connection.h" ++ ++namespace base { ++class SequencedTaskRunner; ++} ++ ++namespace net { ++class IOBuffer; ++} ++ ++namespace device { ++ ++class HidConnectionFreeBSD : public HidConnection { ++ public: ++ HidConnectionFreeBSD( ++ scoped_refptr device_info, ++ base::ScopedFD fd, ++ scoped_refptr blocking_task_runner); ++ ++ private: ++ friend class base::RefCountedThreadSafe; ++ class BlockingTaskHelper; ++ ++ ~HidConnectionFreeBSD() override; ++ ++ // HidConnection implementation. ++ void PlatformClose() override; ++ void PlatformRead(const ReadCallback& callback) override; ++ void PlatformWrite(scoped_refptr buffer, ++ size_t size, ++ const WriteCallback& callback) override; ++ void PlatformGetFeatureReport(uint8_t report_id, ++ const ReadCallback& callback) override; ++ void PlatformSendFeatureReport(scoped_refptr buffer, ++ size_t size, ++ const WriteCallback& callback) override; ++ void ProcessInputReport(scoped_refptr buffer, size_t size); ++ void ProcessReadQueue(); ++ ++ // |helper_| lives on the sequence to which |blocking_task_runner_| posts ++ // tasks so all calls must be posted there including this object's ++ // destruction. ++ std::unique_ptr helper_; ++ ++ const scoped_refptr blocking_task_runner_; ++ ++ std::queue pending_reports_; ++ std::queue pending_reads_; ++ const scoped_refptr task_runner_; ++ ++ SEQUENCE_CHECKER(sequence_checker_); ++ ++ base::WeakPtrFactory weak_factory_; ++ ++ DISALLOW_COPY_AND_ASSIGN(HidConnectionFreeBSD); ++}; ++ ++} // namespace device ++ ++#endif // DEVICE_HID_HID_CONNECTION_FREEBSD_H_ Property changes on: head/www/chromium/files/patch-device_hid_hid__connection__freebsd.h ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/www/chromium/files/patch-device_hid_hid__device__info__freebsd.cc =================================================================== --- head/www/chromium/files/patch-device_hid_hid__device__info__freebsd.cc (nonexistent) +++ head/www/chromium/files/patch-device_hid_hid__device__info__freebsd.cc (revision 455495) @@ -0,0 +1,33 @@ +--- device/hid/hid_device_info_freebsd.cc.orig 2017-12-03 15:37:32.159794000 -0800 ++++ device/hid/hid_device_info_freebsd.cc 2017-12-03 15:37:32.162092000 -0800 +@@ -0,0 +1,30 @@ ++// Copyright 2015 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 "hid_device_info_freebsd.h" ++ ++namespace device { ++ ++HidDeviceInfoFreeBSD::HidDeviceInfoFreeBSD( ++ const HidDeviceId& device_id, ++ const std::string& device_node, ++ uint16_t vendor_id, ++ uint16_t product_id, ++ const std::string& product_name, ++ const std::string& serial_number, ++ HidBusType bus_type, ++ const std::vector report_descriptor) ++ : HidDeviceInfo(device_id, ++ vendor_id, ++ product_id, ++ product_name, ++ serial_number, ++ bus_type, ++ report_descriptor), ++ device_node_(device_node) {} ++ ++HidDeviceInfoFreeBSD::~HidDeviceInfoFreeBSD() { ++} ++ ++} // namespace device Property changes on: head/www/chromium/files/patch-device_hid_hid__device__info__freebsd.cc ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/www/chromium/files/patch-device_hid_hid__device__info__freebsd.h =================================================================== --- head/www/chromium/files/patch-device_hid_hid__device__info__freebsd.h (nonexistent) +++ head/www/chromium/files/patch-device_hid_hid__device__info__freebsd.h (revision 455495) @@ -0,0 +1,38 @@ +--- device/hid/hid_device_info_freebsd.h.orig 2017-12-03 15:37:32.162846000 -0800 ++++ device/hid/hid_device_info_freebsd.h 2017-12-03 15:37:32.165247000 -0800 +@@ -0,0 +1,35 @@ ++// Copyright 2015 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. ++ ++#ifndef DEVICE_HID_HID_DEVICE_INFO_LINUX_H_ ++#define DEVICE_HID_HID_DEVICE_INFO_LINUX_H_ ++ ++#include ++ ++#include "device/hid/hid_device_info.h" ++ ++namespace device { ++ ++class HidDeviceInfoFreeBSD : public HidDeviceInfo { ++ public: ++ HidDeviceInfoFreeBSD(const HidDeviceId& device_id, ++ const std::string& device_node, ++ uint16_t vendor_id, ++ uint16_t product_id, ++ const std::string& product_name, ++ const std::string& serial_number, ++ HidBusType bus_type, ++ const std::vector report_descriptor); ++ ++ const std::string& device_node() const { return device_node_; } ++ ++ private: ++ ~HidDeviceInfoFreeBSD() override; ++ ++ std::string device_node_; ++}; ++ ++} // namespace device ++ ++#endif // DEVICE_HID_HID_DEVICE_INFO_LINUX_H_ Property changes on: head/www/chromium/files/patch-device_hid_hid__device__info__freebsd.h ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/www/chromium/files/patch-device_hid_hid__service.cc =================================================================== --- head/www/chromium/files/patch-device_hid_hid__service.cc (nonexistent) +++ head/www/chromium/files/patch-device_hid_hid__service.cc (revision 455495) @@ -0,0 +1,20 @@ +--- device/hid/hid_service.cc.orig 2017-09-21 15:04:58.000000000 -0700 ++++ device/hid/hid_service.cc 2017-12-03 15:37:32.167748000 -0800 +@@ -16,6 +16,8 @@ + + #if defined(OS_LINUX) && defined(USE_UDEV) + #include "device/hid/hid_service_linux.h" ++#elif defined(OS_BSD) ++#include "device/hid/hid_service_freebsd.h" + #elif defined(OS_MACOSX) + #include "device/hid/hid_service_mac.h" + #elif defined(OS_WIN) +@@ -42,6 +44,8 @@ + std::unique_ptr HidService::Create() { + #if defined(OS_LINUX) && defined(USE_UDEV) + return base::WrapUnique(new HidServiceLinux()); ++#elif defined(OS_BSD) ++ return base::WrapUnique(new HidServiceFreeBSD()); + #elif defined(OS_MACOSX) + return base::WrapUnique(new HidServiceMac()); + #elif defined(OS_WIN) Property changes on: head/www/chromium/files/patch-device_hid_hid__service.cc ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/www/chromium/files/patch-device_hid_hid__service__freebsd.cc =================================================================== --- head/www/chromium/files/patch-device_hid_hid__service__freebsd.cc (nonexistent) +++ head/www/chromium/files/patch-device_hid_hid__service__freebsd.cc (revision 455495) @@ -0,0 +1,373 @@ +--- device/hid/hid_service_freebsd.cc.orig 2017-12-03 15:37:32.168519000 -0800 ++++ device/hid/hid_service_freebsd.cc 2017-12-03 15:37:32.179514000 -0800 +@@ -0,0 +1,370 @@ ++// 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 "device/hid/hid_service_freebsd.h" ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "base/bind.h" ++#include "base/files/file_descriptor_watcher_posix.h" ++#include "base/files/file_enumerator.h" ++#include "base/location.h" ++#include "base/logging.h" ++#include "base/posix/eintr_wrapper.h" ++#include "base/single_thread_task_runner.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_scheduler/post_task.h" ++#include "base/threading/thread_restrictions.h" ++#include "base/threading/thread_task_runner_handle.h" ++#include "components/device_event_log/device_event_log.h" ++#include "device/hid/hid_connection_freebsd.h" ++#include "device/hid/hid_device_info_freebsd.h" ++ ++const int kMaxPermissionChecks = 5; ++ ++namespace device { ++ ++struct HidServiceFreeBSD::ConnectParams { ++ ConnectParams(scoped_refptr device_info, ++ const ConnectCallback& callback) ++ : device_info(std::move(device_info)), ++ callback(callback), ++ task_runner(base::ThreadTaskRunnerHandle::Get()), ++ blocking_task_runner( ++ base::CreateSequencedTaskRunnerWithTraits(kBlockingTaskTraits)) {} ++ ~ConnectParams() {} ++ ++ scoped_refptr device_info; ++ ConnectCallback callback; ++ scoped_refptr task_runner; ++ scoped_refptr blocking_task_runner; ++ base::ScopedFD fd; ++}; ++ ++class HidServiceFreeBSD::BlockingTaskHelper { ++ public: ++ BlockingTaskHelper(base::WeakPtr service) ++ : service_(std::move(service)), ++ task_runner_(base::ThreadTaskRunnerHandle::Get()) { ++ DETACH_FROM_SEQUENCE(sequence_checker_); ++ ++ timer_.reset(new base::RepeatingTimer()); ++ devd_buffer_ = new net::IOBufferWithSize(1024); ++ } ++ ++ ~BlockingTaskHelper() { ++ } ++ ++ void Start() { ++ base::ThreadRestrictions::AssertIOAllowed(); ++ 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::Bind(&HidServiceFreeBSD::FirstEnumerationComplete, service_)); ++ } ++ ++ bool HaveReadWritePermissions(std::string device_id) { ++ std::string device_node = "/dev/" + device_id; ++ base::ThreadRestrictions::AssertIOAllowed(); ++ ++ 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) { ++ 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 report_descriptor; ++ ++ base::ThreadRestrictions::AssertIOAllowed(); ++ ++ 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 device_info(new HidDeviceInfoFreeBSD( ++ device_id, device_node, vendor_id, product_id, product_name, ++ serial_number, ++ kHIDBusTypeUSB, ++ report_descriptor)); ++ ++ task_runner_->PostTask(FROM_HERE, base::Bind(&HidServiceFreeBSD::AddDevice, ++ service_, device_info)); ++ } ++ ++ void OnDeviceRemoved(std::string device_id) { ++ task_runner_->PostTask( ++ FROM_HERE, base::Bind(&HidServiceFreeBSD::RemoveDevice, service_, ++ device_id)); ++ } ++ ++ private: ++ ++ void CheckPendingPermissionChange() { ++ base::ThreadRestrictions::AssertIOAllowed(); ++ std::map::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::ThreadRestrictions::AssertIOAllowed(); ++ ++ 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::Bind(&BlockingTaskHelper::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 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(device_name, kMaxPermissionChecks)); ++ timer_->Start(FROM_HERE, base::TimeDelta::FromSeconds(1), ++ this, &BlockingTaskHelper::CheckPendingPermissionChange); ++ } ++ } ++ } ++ } ++ ++ if (base::StartsWith(data, "-uhid", base::CompareCase::SENSITIVE)) { ++ std::vector 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 service_; ++ scoped_refptr task_runner_; ++ std::unique_ptr file_watcher_; ++ std::unique_ptr timer_; ++ base::ScopedFD devd_fd_; ++ scoped_refptr devd_buffer_; ++ std::map permissions_checks_attempts_; ++ ++ DISALLOW_COPY_AND_ASSIGN(BlockingTaskHelper); ++}; ++ ++HidServiceFreeBSD::HidServiceFreeBSD() ++ : task_runner_(base::ThreadTaskRunnerHandle::Get()), ++ blocking_task_runner_( ++ base::CreateSequencedTaskRunnerWithTraits(kBlockingTaskTraits)), ++ weak_factory_(this) { ++ helper_ = base::MakeUnique(weak_factory_.GetWeakPtr()); ++ blocking_task_runner_->PostTask( ++ FROM_HERE, ++ base::Bind(&BlockingTaskHelper::Start, base::Unretained(helper_.get()))); ++} ++ ++HidServiceFreeBSD::~HidServiceFreeBSD() { ++ blocking_task_runner_->DeleteSoon(FROM_HERE, helper_.release()); ++} ++ ++// static ++void HidServiceFreeBSD::OpenOnBlockingThread( ++ std::unique_ptr params) { ++ base::ThreadRestrictions::AssertIOAllowed(); ++ scoped_refptr 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::Bind(params->callback, nullptr)); ++ return; ++ } ++ params->fd.reset(device_file.TakePlatformFile()); ++ FinishOpen(std::move(params)); ++} ++ ++void HidServiceFreeBSD::Connect(const HidDeviceId& device_id, ++ const ConnectCallback& callback) { ++ DCHECK(thread_checker_.CalledOnValidThread()); ++ ++ const auto& map_entry = devices().find(device_id); ++ if (map_entry == devices().end()) { ++ base::ThreadTaskRunnerHandle::Get()->PostTask( ++ FROM_HERE, base::Bind(callback, nullptr)); ++ return; ++ } ++ ++ scoped_refptr device_info = ++ static_cast(map_entry->second.get()); ++ ++ auto params = base::MakeUnique(device_info, callback); ++ ++ scoped_refptr blocking_task_runner = ++ params->blocking_task_runner; ++ blocking_task_runner->PostTask( ++ FROM_HERE, base::Bind(&HidServiceFreeBSD::OpenOnBlockingThread, ++ base::Passed(¶ms))); ++} ++ ++// static ++void HidServiceFreeBSD::FinishOpen(std::unique_ptr params) { ++ base::ThreadRestrictions::AssertIOAllowed(); ++ scoped_refptr task_runner = params->task_runner; ++ ++ task_runner->PostTask( ++ FROM_HERE, ++ base::Bind(&HidServiceFreeBSD::CreateConnection, base::Passed(¶ms))); ++} ++ ++// static ++void HidServiceFreeBSD::CreateConnection(std::unique_ptr params) { ++ DCHECK(params->fd.is_valid()); ++ params->callback.Run(base::MakeRefCounted( ++ std::move(params->device_info), std::move(params->fd), ++ std::move(params->blocking_task_runner))); ++} ++ ++} // namespace device Property changes on: head/www/chromium/files/patch-device_hid_hid__service__freebsd.cc ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/www/chromium/files/patch-device_hid_hid__service__freebsd.h =================================================================== --- head/www/chromium/files/patch-device_hid_hid__service__freebsd.h (nonexistent) +++ head/www/chromium/files/patch-device_hid_hid__service__freebsd.h (revision 455495) @@ -0,0 +1,50 @@ +--- device/hid/hid_service_freebsd.h.orig 2017-12-03 15:37:32.180261000 -0800 ++++ device/hid/hid_service_freebsd.h 2017-12-03 15:37:32.183647000 -0800 +@@ -0,0 +1,47 @@ ++// 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. ++ ++#ifndef DEVICE_HID_HID_SERVICE_FREEBSD_H_ ++#define DEVICE_HID_HID_SERVICE_FREEBSD_H_ ++ ++#include ++ ++#include "base/macros.h" ++#include "base/memory/ref_counted.h" ++#include "base/memory/weak_ptr.h" ++#include "base/timer/timer.h" ++#include "device/hid/hid_service.h" ++#include "net/base/io_buffer.h" ++ ++namespace device { ++ ++class HidServiceFreeBSD : public HidService { ++ public: ++ HidServiceFreeBSD(); ++ ~HidServiceFreeBSD() override; ++ ++ void Connect(const HidDeviceId& device_id, ++ const ConnectCallback& connect) override; ++ ++ private: ++ struct ConnectParams; ++ class BlockingTaskHelper; ++ ++ static void OpenOnBlockingThread(std::unique_ptr params); ++ static void FinishOpen(std::unique_ptr params); ++ static void CreateConnection(std::unique_ptr params); ++ ++ const scoped_refptr task_runner_; ++ const scoped_refptr blocking_task_runner_; ++ // |helper_| lives on the sequence |blocking_task_runner_| posts to and holds ++ // a weak reference back to the service that owns it. ++ std::unique_ptr helper_; ++ base::WeakPtrFactory weak_factory_; ++ ++ DISALLOW_COPY_AND_ASSIGN(HidServiceFreeBSD); ++}; ++ ++} // namespace device ++ ++#endif // DEVICE_HID_HID_SERVICE_FREEBSD_H_ Property changes on: head/www/chromium/files/patch-device_hid_hid__service__freebsd.h ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property