diff --git a/chromium-113-constexpr-el7.patch b/chromium-113-constexpr-el7.patch new file mode 100644 index 00000000..c474e120 --- /dev/null +++ b/chromium-113-constexpr-el7.patch @@ -0,0 +1,277 @@ +diff --git a/components/version_info/version_info.cc b/components/version_info/version_info.cc +index c5b6a9ea17be1..9b1f5e4478f53 100644 +--- a/components/version_info/version_info.cc ++++ b/components/version_info/version_info.cc +@@ -4,26 +4,15 @@ + + #include "components/version_info/version_info.h" + +-#include "base/check.h" ++#include ++ + #include "base/no_destructor.h" +-#include "base/notreached.h" +-#include "base/sanitizer_buildflags.h" + #include "base/strings/strcat.h" + #include "base/strings/string_number_conversions.h" + #include "base/version.h" +-#include "build/branding_buildflags.h" +-#include "build/build_config.h" +-#include "build/chromeos_buildflags.h" +-#include "components/version_info/version_info_values.h" + + namespace version_info { + +-const std::string& GetProductNameAndVersionForUserAgent() { +- static const base::NoDestructor product_and_version( +- "Chrome/" + GetVersionNumber()); +- return *product_and_version; +-} +- + const std::string GetProductNameAndVersionForReducedUserAgent( + const std::string& build_version) { + std::string product_and_version; +@@ -32,14 +21,6 @@ const std::string GetProductNameAndVersionForReducedUserAgent( + return product_and_version; + } + +-std::string GetProductName() { +- return PRODUCT_NAME; +-} +- +-std::string GetVersionNumber() { +- return PRODUCT_VERSION; +-} +- + int GetMajorVersionNumberAsInt() { + DCHECK(GetVersion().IsValid()); + return GetVersion().components()[0]; +@@ -54,82 +35,4 @@ const base::Version& GetVersion() { + return *version; + } + +-std::string GetLastChange() { +- return LAST_CHANGE; +-} +- +-bool IsOfficialBuild() { +- return IS_OFFICIAL_BUILD; +-} +- +-std::string GetOSType() { +-#if BUILDFLAG(IS_WIN) +- return "Windows"; +-#elif BUILDFLAG(IS_IOS) +- return "iOS"; +-#elif BUILDFLAG(IS_MAC) +- return "Mac OS X"; +-#elif BUILDFLAG(IS_CHROMEOS) +-# if BUILDFLAG(GOOGLE_CHROME_BRANDING) +- return "ChromeOS"; +-# else +- return "ChromiumOS"; +-# endif +-#elif BUILDFLAG(IS_ANDROID) +- return "Android"; +-#elif BUILDFLAG(IS_LINUX) +- return "Linux"; +-#elif BUILDFLAG(IS_FREEBSD) +- return "FreeBSD"; +-#elif BUILDFLAG(IS_OPENBSD) +- return "OpenBSD"; +-#elif BUILDFLAG(IS_SOLARIS) +- return "Solaris"; +-#elif BUILDFLAG(IS_FUCHSIA) +- return "Fuchsia"; +-#else +- return "Unknown"; +-#endif +-} +- +-std::string GetChannelString(Channel channel) { +- switch (channel) { +- case Channel::STABLE: +- return "stable"; +- case Channel::BETA: +- return "beta"; +- case Channel::DEV: +- return "dev"; +- case Channel::CANARY: +- return "canary"; +- case Channel::UNKNOWN: +- return "unknown"; +- } +- NOTREACHED(); +- return std::string(); +-} +- +-std::string GetSanitizerList() { +- std::string sanitizers; +-#if defined(ADDRESS_SANITIZER) +- sanitizers += "address "; +-#endif +-#if BUILDFLAG(IS_HWASAN) +- sanitizers += "hwaddress "; +-#endif +-#if defined(LEAK_SANITIZER) +- sanitizers += "leak "; +-#endif +-#if defined(MEMORY_SANITIZER) +- sanitizers += "memory "; +-#endif +-#if defined(THREAD_SANITIZER) +- sanitizers += "thread "; +-#endif +-#if defined(UNDEFINED_SANITIZER) +- sanitizers += "undefined "; +-#endif +- return sanitizers; +-} +- + } // namespace version_info +diff --git a/components/version_info/version_info.h b/components/version_info/version_info.h +index cab516659a9e4..ffa554eed7598 100644 +--- a/components/version_info/version_info.h ++++ b/components/version_info/version_info.h +@@ -7,7 +7,12 @@ + + #include + ++#include "base/notreached.h" ++#include "base/sanitizer_buildflags.h" ++#include "build/branding_buildflags.h" ++#include "build/build_config.h" + #include "components/version_info/channel.h" ++#include "components/version_info/version_info_values.h" + + namespace base { + class Version; +@@ -15,10 +20,6 @@ class Version; + + namespace version_info { + +-// Returns the product name and version information for the User-Agent header, +-// in the format: Chrome/.... +-const std::string& GetProductNameAndVersionForUserAgent(); +- + // Returns the product name and reduced version information for the User-Agent + // header, in the format: Chrome/.0.build_version.0, where + // `build_version` is a frozen BUILD number. +@@ -26,10 +27,20 @@ const std::string GetProductNameAndVersionForReducedUserAgent( + const std::string& build_version); + + // Returns the product name, e.g. "Chromium" or "Google Chrome". +-std::string GetProductName(); ++constexpr std::string GetProductName() { ++ return PRODUCT_NAME; ++} + + // Returns the version number, e.g. "6.0.490.1". +-std::string GetVersionNumber(); ++constexpr std::string GetVersionNumber() { ++ return PRODUCT_VERSION; ++} ++ ++// Returns the product name and version information for the User-Agent header, ++// in the format: Chrome/.... ++constexpr std::string GetProductNameAndVersionForUserAgent() { ++ return "Chrome/" + GetVersionNumber(); ++} + + // Returns the major component (aka the milestone) of the version as an int, + // e.g. 6 when the version is "6.0.490.1". +@@ -42,22 +53,89 @@ std::string GetMajorVersionNumber(); + const base::Version& GetVersion(); + + // Returns a version control specific identifier of this release. +-std::string GetLastChange(); ++constexpr std::string GetLastChange() { ++ return LAST_CHANGE; ++} + + // Returns whether this is an "official" release of the current version, i.e. + // whether knowing GetVersionNumber() is enough to completely determine what + // GetLastChange() is. +-bool IsOfficialBuild(); ++constexpr bool IsOfficialBuild() { ++ return IS_OFFICIAL_BUILD; ++} + + // Returns the OS type, e.g. "Windows", "Linux", "FreeBSD", ... +-std::string GetOSType(); ++constexpr std::string GetOSType() { ++#if BUILDFLAG(IS_WIN) ++ return "Windows"; ++#elif BUILDFLAG(IS_IOS) ++ return "iOS"; ++#elif BUILDFLAG(IS_MAC) ++ return "Mac OS X"; ++#elif BUILDFLAG(IS_CHROMEOS) ++#if BUILDFLAG(GOOGLE_CHROME_BRANDING) ++ return "ChromeOS"; ++#else ++ return "ChromiumOS"; ++#endif ++#elif BUILDFLAG(IS_ANDROID) ++ return "Android"; ++#elif BUILDFLAG(IS_LINUX) ++ return "Linux"; ++#elif BUILDFLAG(IS_FREEBSD) ++ return "FreeBSD"; ++#elif BUILDFLAG(IS_OPENBSD) ++ return "OpenBSD"; ++#elif BUILDFLAG(IS_SOLARIS) ++ return "Solaris"; ++#elif BUILDFLAG(IS_FUCHSIA) ++ return "Fuchsia"; ++#else ++ return "Unknown"; ++#endif ++} + + // Returns a string equivalent of |channel|, independent of whether the build + // is branded or not and without any additional modifiers. +-std::string GetChannelString(Channel channel); ++constexpr std::string GetChannelString(Channel channel) { ++ switch (channel) { ++ case Channel::STABLE: ++ return "stable"; ++ case Channel::BETA: ++ return "beta"; ++ case Channel::DEV: ++ return "dev"; ++ case Channel::CANARY: ++ return "canary"; ++ case Channel::UNKNOWN: ++ return "unknown"; ++ } ++ NOTREACHED_NORETURN(); ++} + + // Returns a list of sanitizers enabled in this build. +-std::string GetSanitizerList(); ++constexpr std::string GetSanitizerList() { ++ return "" ++#if defined(ADDRESS_SANITIZER) ++ "address " ++#endif ++#if BUILDFLAG(IS_HWASAN) ++ "hwaddress " ++#endif ++#if defined(LEAK_SANITIZER) ++ "leak " ++#endif ++#if defined(MEMORY_SANITIZER) ++ "memory " ++#endif ++#if defined(THREAD_SANITIZER) ++ "thread " ++#endif ++#if defined(UNDEFINED_SANITIZER) ++ "undefined " ++#endif ++ ; ++} + + } // namespace version_info + diff --git a/chromium-113-v4l2-revert-el7.patch b/chromium-113-v4l2-revert-el7.patch new file mode 100644 index 00000000..c91a7c33 --- /dev/null +++ b/chromium-113-v4l2-revert-el7.patch @@ -0,0 +1,540 @@ +commit 74e41428503d16ff365bbfa93ca23332ce04215a +Author: Ilya Nikolaevskiy +Date: Wed Apr 5 16:16:22 2023 +0000 + + Revert "V4L2: media/capture: Use VIDIOC_S_EXT_CTRLS API correctly" + + This reverts commit 4301563bdea1766779b5e032d2eb2ff19959fce3. + + Reason for revert: Breaks test bot: crbug.com/1430699 + + Original change's description: + > V4L2: media/capture: Use VIDIOC_S_EXT_CTRLS API correctly + > + > This CL: + > - Uses the `which` struct v4l2_ext_controls field instead of + > the deprecated `ctrl_class` alias field. + > - Prefers the new style value of `V4L2_CTRL_WHICH_CUR_VAL` for that + > field instead of the old style value of the control class ID as long + > as the device supports the new style (detected on run-time). + > - Sets special controls only if they are supported. Trying to set + > an unsupported special control as part of a VIDIOC_S_EXT_CTRLS call + > causes the whole VIDIOC_S_EXT_CTRLS call to fail. + > - Fixes control iteration not to skip over the brightness control. + > - Skips permanently disabled and read-only controls. + > - Enables the corresponding test case. + > + > This fixes VIDIOC_S_EXT_CTRLS to work on new device drivers, too. + > + > API: https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/vidioc-g-ext-ctrls.html#c.V4L.v4l2_ext_controls + > + > Bug: 1421739, 732355 + > Change-Id: I13593bb647fe664d70a3d8ed8d2789f77397aa40 + > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4324021 + > Commit-Queue: Eero Hakkinen + > Reviewed-by: Tomas Gunnarsson + > Reviewed-by: Ilya Nikolaevskiy + > Cr-Commit-Position: refs/heads/main@{#1116416} + + Bug: 1421739, 732355 + Change-Id: I291b80009550f0c890b5203060d9283a4074af97 + Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4401592 + Commit-Queue: Tomas Gunnarsson + Auto-Submit: Ilya Nikolaevskiy + Reviewed-by: Tomas Gunnarsson + Cr-Commit-Position: refs/heads/main@{#1126615} + +diff --git a/media/capture/video/linux/v4l2_capture_delegate.cc b/media/capture/video/linux/v4l2_capture_delegate.cc +index 7efa2b1c2252c..864111f5c255e 100644 +--- a/media/capture/video/linux/v4l2_capture_delegate.cc ++++ b/media/capture/video/linux/v4l2_capture_delegate.cc +@@ -138,6 +138,47 @@ int GetControllingSpecialControl(int control_id) { + return 0; + } + ++// Determines if |control_id| is special, i.e. controls another one's state. ++bool IsSpecialControl(int control_id) { ++ switch (control_id) { ++ case V4L2_CID_AUTO_WHITE_BALANCE: ++ case V4L2_CID_EXPOSURE_AUTO: ++ case V4L2_CID_EXPOSURE_AUTO_PRIORITY: ++ case V4L2_CID_FOCUS_AUTO: ++ return true; ++ } ++ return false; ++} ++ ++// Determines if |control_id| should be skipped, https://crbug.com/697885. ++#if !defined(V4L2_CID_PAN_SPEED) ++#define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 32) ++#endif ++#if !defined(V4L2_CID_TILT_SPEED) ++#define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 33) ++#endif ++#if !defined(V4L2_CID_PANTILT_CMD) ++#define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE + 34) ++#endif ++bool IsBlockedControl(int control_id) { ++ switch (control_id) { ++ case V4L2_CID_PAN_RELATIVE: ++ case V4L2_CID_TILT_RELATIVE: ++ case V4L2_CID_PAN_RESET: ++ case V4L2_CID_TILT_RESET: ++ case V4L2_CID_PAN_ABSOLUTE: ++ case V4L2_CID_TILT_ABSOLUTE: ++ case V4L2_CID_ZOOM_ABSOLUTE: ++ case V4L2_CID_ZOOM_RELATIVE: ++ case V4L2_CID_ZOOM_CONTINUOUS: ++ case V4L2_CID_PAN_SPEED: ++ case V4L2_CID_TILT_SPEED: ++ case V4L2_CID_PANTILT_CMD: ++ return true; ++ } ++ return false; ++} ++ + bool IsNonEmptyRange(const mojom::RangePtr& range) { + return range->min < range->max; + } +@@ -211,49 +252,6 @@ std::vector V4L2CaptureDelegate::GetListOfUsableFourCcs( + return supported_formats; + } + +-// Determines if |control_id| is special, i.e. controls another one's state. +-// static +-bool V4L2CaptureDelegate::IsSpecialControl(int control_id) { +- switch (control_id) { +- case V4L2_CID_AUTO_WHITE_BALANCE: +- case V4L2_CID_EXPOSURE_AUTO: +- case V4L2_CID_EXPOSURE_AUTO_PRIORITY: +- case V4L2_CID_FOCUS_AUTO: +- return true; +- } +- return false; +-} +- +-// Determines if |control_id| should be skipped, https://crbug.com/697885. +-#if !defined(V4L2_CID_PAN_SPEED) +-#define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 32) +-#endif +-#if !defined(V4L2_CID_TILT_SPEED) +-#define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 33) +-#endif +-#if !defined(V4L2_CID_PANTILT_CMD) +-#define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE + 34) +-#endif +-// static +-bool V4L2CaptureDelegate::IsBlockedControl(int control_id) { +- switch (control_id) { +- case V4L2_CID_PAN_RELATIVE: +- case V4L2_CID_TILT_RELATIVE: +- case V4L2_CID_PAN_RESET: +- case V4L2_CID_TILT_RESET: +- case V4L2_CID_PAN_ABSOLUTE: +- case V4L2_CID_TILT_ABSOLUTE: +- case V4L2_CID_ZOOM_ABSOLUTE: +- case V4L2_CID_ZOOM_RELATIVE: +- case V4L2_CID_ZOOM_CONTINUOUS: +- case V4L2_CID_PAN_SPEED: +- case V4L2_CID_TILT_SPEED: +- case V4L2_CID_PANTILT_CMD: +- return true; +- } +- return false; +-} +- + V4L2CaptureDelegate::V4L2CaptureDelegate( + V4L2CaptureDevice* v4l2, + const VideoCaptureDeviceDescriptor& device_descriptor, +@@ -830,89 +828,100 @@ mojom::RangePtr V4L2CaptureDelegate::RetrieveUserControlRange(int control_id) { + } + + void V4L2CaptureDelegate::ResetUserAndCameraControlsToDefault() { ++ // Set V4L2_CID_AUTO_WHITE_BALANCE to false first. ++ v4l2_control auto_white_balance = {}; ++ auto_white_balance.id = V4L2_CID_AUTO_WHITE_BALANCE; ++ auto_white_balance.value = false; ++ if (!RunIoctl(VIDIOC_S_CTRL, &auto_white_balance)) ++ return; ++ ++ std::vector special_camera_controls; ++ // Set V4L2_CID_EXPOSURE_AUTO to V4L2_EXPOSURE_MANUAL. ++ v4l2_ext_control auto_exposure = {}; ++ auto_exposure.id = V4L2_CID_EXPOSURE_AUTO; ++ auto_exposure.value = V4L2_EXPOSURE_MANUAL; ++ special_camera_controls.push_back(auto_exposure); ++ // Set V4L2_CID_EXPOSURE_AUTO_PRIORITY to false. ++ v4l2_ext_control priority_auto_exposure = {}; ++ priority_auto_exposure.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY; ++ priority_auto_exposure.value = false; ++ special_camera_controls.push_back(priority_auto_exposure); ++ // Set V4L2_CID_FOCUS_AUTO to false. ++ v4l2_ext_control auto_focus = {}; ++ auto_focus.id = V4L2_CID_FOCUS_AUTO; ++ auto_focus.value = false; ++ special_camera_controls.push_back(auto_focus); ++ + struct v4l2_ext_controls ext_controls = {}; +- ext_controls.which = V4L2_CTRL_WHICH_CUR_VAL; +- ext_controls.count = 0; +- const bool use_modern_s_ext_ctrls = +- DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) == 0; ++ ext_controls.ctrl_class = V4L2_CID_CAMERA_CLASS; ++ ext_controls.count = special_camera_controls.size(); ++ ext_controls.controls = special_camera_controls.data(); ++ if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0) ++ DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS"; + + for (const auto& control : kControls) { + std::vector camera_controls; +- std::vector manual_special_camera_controls; +- std::vector special_camera_controls; + + v4l2_queryctrl range = {}; +- // Start right below the base so that the first next retrieved control ID +- // is always the first available control ID within the class even if that +- // control ID is equal to the base (V4L2_CID_BRIGHTNESS equals to +- // V4L2_CID_USER_BASE). +- range.id = (control.control_base - 1) | V4L2_CTRL_FLAG_NEXT_CTRL; ++ range.id = control.control_base | V4L2_CTRL_FLAG_NEXT_CTRL; + while (0 == DoIoctl(VIDIOC_QUERYCTRL, &range)) { + if (V4L2_CTRL_ID2CLASS(range.id) != V4L2_CTRL_ID2CLASS(control.class_id)) + break; +- +- v4l2_ext_control ext_control = {}; +- ext_control.id = range.id; +- ext_control.value = range.default_value; +- +- // Prepare to query for the next control as `range` is an in-out +- // parameter. + range.id |= V4L2_CTRL_FLAG_NEXT_CTRL; + +- if (range.flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_READ_ONLY)) { +- // Permanently disabled or permanently read-only. ++ if (IsSpecialControl(range.id & ~V4L2_CTRL_FLAG_NEXT_CTRL)) + continue; +- } +- if (IsBlockedControl(ext_control.id)) { ++ if (IsBlockedControl(range.id & ~V4L2_CTRL_FLAG_NEXT_CTRL)) + continue; +- } + +- if (IsSpecialControl(ext_control.id)) { +- special_camera_controls.push_back(ext_control); +- if (ext_control.id == V4L2_CID_EXPOSURE_AUTO) { +- ext_control.value = V4L2_EXPOSURE_MANUAL; +- } else { +- ext_control.value = false; // Not automatic but manual. +- } +- manual_special_camera_controls.push_back(ext_control); +- } else { +- camera_controls.push_back(ext_control); +- } ++ struct v4l2_ext_control ext_control = {}; ++ ext_control.id = range.id & ~V4L2_CTRL_FLAG_NEXT_CTRL; ++ ext_control.value = range.default_value; ++ camera_controls.push_back(ext_control); + } + + if (!camera_controls.empty()) { +- // Set special controls to manual modes first. +- if (!manual_special_camera_controls.empty()) { +- ext_controls.which = +- use_modern_s_ext_ctrls ? V4L2_CTRL_WHICH_CUR_VAL : control.class_id; +- ext_controls.count = manual_special_camera_controls.size(); +- ext_controls.controls = manual_special_camera_controls.data(); +- if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0) { +- DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS"; +- } +- } +- +- // Set non-special controls to the default values. +- ext_controls.which = +- use_modern_s_ext_ctrls ? V4L2_CTRL_WHICH_CUR_VAL : control.class_id; +- ext_controls.count = camera_controls.size(); +- ext_controls.controls = camera_controls.data(); +- if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0) { +- DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS"; +- } +- } +- +- // Set special controls to the default values. +- if (!special_camera_controls.empty()) { +- ext_controls.which = +- use_modern_s_ext_ctrls ? V4L2_CTRL_WHICH_CUR_VAL : control.class_id; +- ext_controls.count = special_camera_controls.size(); +- ext_controls.controls = special_camera_controls.data(); +- if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0) { ++ struct v4l2_ext_controls ext_controls2 = {}; ++ ext_controls2.ctrl_class = control.class_id; ++ ext_controls2.count = camera_controls.size(); ++ ext_controls2.controls = camera_controls.data(); ++ if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls2) < 0) + DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS"; +- } + } + } ++ ++ // Now set the special flags to the default values ++ v4l2_queryctrl range = {}; ++ range.id = V4L2_CID_AUTO_WHITE_BALANCE; ++ DoIoctl(VIDIOC_QUERYCTRL, &range); ++ auto_white_balance.value = range.default_value; ++ DoIoctl(VIDIOC_S_CTRL, &auto_white_balance); ++ ++ special_camera_controls.clear(); ++ memset(&range, 0, sizeof(range)); ++ range.id = V4L2_CID_EXPOSURE_AUTO; ++ DoIoctl(VIDIOC_QUERYCTRL, &range); ++ auto_exposure.value = range.default_value; ++ special_camera_controls.push_back(auto_exposure); ++ ++ memset(&range, 0, sizeof(range)); ++ range.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY; ++ DoIoctl(VIDIOC_QUERYCTRL, &range); ++ priority_auto_exposure.value = range.default_value; ++ special_camera_controls.push_back(priority_auto_exposure); ++ ++ memset(&range, 0, sizeof(range)); ++ range.id = V4L2_CID_FOCUS_AUTO; ++ DoIoctl(VIDIOC_QUERYCTRL, &range); ++ auto_focus.value = range.default_value; ++ special_camera_controls.push_back(auto_focus); ++ ++ memset(&ext_controls, 0, sizeof(ext_controls)); ++ ext_controls.ctrl_class = V4L2_CID_CAMERA_CLASS; ++ ext_controls.count = special_camera_controls.size(); ++ ext_controls.controls = special_camera_controls.data(); ++ if (DoIoctl(VIDIOC_S_EXT_CTRLS, &ext_controls) < 0) ++ DPLOG(INFO) << "VIDIOC_S_EXT_CTRLS"; + } + + bool V4L2CaptureDelegate::MapAndQueueBuffer(int index) { +diff --git a/media/capture/video/linux/v4l2_capture_delegate.h b/media/capture/video/linux/v4l2_capture_delegate.h +index 5eaa0cd004b81..c9be3d02f9344 100644 +--- a/media/capture/video/linux/v4l2_capture_delegate.h ++++ b/media/capture/video/linux/v4l2_capture_delegate.h +@@ -78,9 +78,6 @@ class CAPTURE_EXPORT V4L2CaptureDelegate final { + + base::WeakPtr GetWeakPtr(); + +- static bool IsBlockedControl(int control_id); +- static bool IsSpecialControl(int control_id); +- + private: + friend class V4L2CaptureDelegateTest; + +diff --git a/media/capture/video/linux/v4l2_capture_delegate_unittest.cc b/media/capture/video/linux/v4l2_capture_delegate_unittest.cc +index 06046ca45d634..4e6e38bbd5c72 100644 +--- a/media/capture/video/linux/v4l2_capture_delegate_unittest.cc ++++ b/media/capture/video/linux/v4l2_capture_delegate_unittest.cc +@@ -35,110 +35,119 @@ static struct { + } const kControls[] = {{V4L2_CID_USER_BASE, V4L2_CID_USER_CLASS}, + {V4L2_CID_CAMERA_CLASS_BASE, V4L2_CID_CAMERA_CLASS}}; + ++// Determines if |control_id| is special, i.e. controls another one's state, or ++// if it should be denied (see https://crbug.com/697885). ++#if !defined(V4L2_CID_PAN_SPEED) ++#define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 32) ++#endif ++#if !defined(V4L2_CID_TILT_SPEED) ++#define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 33) ++#endif ++#if !defined(V4L2_CID_PANTILT_CMD) ++#define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE + 34) ++#endif ++static bool IsSpecialOrBlockedControl(int control_id) { ++ switch (control_id) { ++ case V4L2_CID_AUTO_WHITE_BALANCE: ++ case V4L2_CID_EXPOSURE_AUTO: ++ case V4L2_CID_EXPOSURE_AUTO_PRIORITY: ++ case V4L2_CID_FOCUS_AUTO: ++ case V4L2_CID_PAN_RELATIVE: ++ case V4L2_CID_TILT_RELATIVE: ++ case V4L2_CID_PAN_RESET: ++ case V4L2_CID_TILT_RESET: ++ case V4L2_CID_PAN_ABSOLUTE: ++ case V4L2_CID_TILT_ABSOLUTE: ++ case V4L2_CID_ZOOM_ABSOLUTE: ++ case V4L2_CID_ZOOM_RELATIVE: ++ case V4L2_CID_ZOOM_CONTINUOUS: ++ case V4L2_CID_PAN_SPEED: ++ case V4L2_CID_TILT_SPEED: ++ case V4L2_CID_PANTILT_CMD: ++ return true; ++ } ++ return false; ++} ++ + static void SetControlsToMaxValues(int device_fd) { +- v4l2_ext_controls ext_controls; +- memset(&ext_controls, 0, sizeof(ext_controls)); +- ext_controls.which = V4L2_CTRL_WHICH_CUR_VAL; +- ext_controls.count = 0; +- const bool use_modern_s_ext_ctrls = +- HANDLE_EINTR(ioctl(device_fd, VIDIOC_S_EXT_CTRLS, &ext_controls)) == 0; ++ // Set V4L2_CID_AUTO_WHITE_BALANCE to false first. ++ v4l2_control auto_white_balance = {}; ++ auto_white_balance.id = V4L2_CID_AUTO_WHITE_BALANCE; ++ auto_white_balance.value = false; ++ if (HANDLE_EINTR(ioctl(device_fd, VIDIOC_S_CTRL, &auto_white_balance)) < 0) ++ DPLOG(ERROR) << "VIDIOC_S_CTRL"; ++ ++ std::vector special_camera_controls; ++ // Set V4L2_CID_EXPOSURE_AUTO to V4L2_EXPOSURE_MANUAL. ++ v4l2_ext_control auto_exposure = {}; ++ auto_exposure.id = V4L2_CID_EXPOSURE_AUTO; ++ auto_exposure.value = V4L2_EXPOSURE_MANUAL; ++ special_camera_controls.push_back(auto_exposure); ++ // Set V4L2_CID_EXPOSURE_AUTO_PRIORITY to false. ++ v4l2_ext_control priority_auto_exposure = {}; ++ priority_auto_exposure.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY; ++ priority_auto_exposure.value = false; ++ special_camera_controls.push_back(priority_auto_exposure); ++ // Set V4L2_CID_FOCUS_AUTO to false. ++ v4l2_ext_control auto_focus = {}; ++ auto_focus.id = V4L2_CID_FOCUS_AUTO; ++ auto_focus.value = false; ++ special_camera_controls.push_back(auto_focus); ++ ++ struct v4l2_ext_controls camera_ext_controls = {}; ++ camera_ext_controls.ctrl_class = V4L2_CID_CAMERA_CLASS; ++ camera_ext_controls.count = special_camera_controls.size(); ++ camera_ext_controls.controls = special_camera_controls.data(); ++ if (HANDLE_EINTR(ioctl(device_fd, VIDIOC_S_EXT_CTRLS, &camera_ext_controls)) < ++ 0) { ++ DPLOG(ERROR) << "VIDIOC_S_EXT_CTRLS"; ++ } + + for (const auto& control : kControls) { + std::vector camera_controls; +- std::vector manual_special_camera_controls; + + v4l2_queryctrl range = {}; +- // Start right below the base so that the first next retrieved control ID +- // is always the first available control ID within the class even if that +- // control ID is equal to the base (V4L2_CID_BRIGHTNESS equals to +- // V4L2_CID_USER_BASE). +- range.id = (control.control_base - 1) | V4L2_CTRL_FLAG_NEXT_CTRL; ++ range.id = control.control_base | V4L2_CTRL_FLAG_NEXT_CTRL; + while (0 == HANDLE_EINTR(ioctl(device_fd, VIDIOC_QUERYCTRL, &range))) { + if (V4L2_CTRL_ID2CLASS(range.id) != V4L2_CTRL_ID2CLASS(control.class_id)) + break; +- +- v4l2_ext_control ext_control = {}; +- ext_control.id = range.id; +- +- // Prepare to query for the next control as `range` is an in-out +- // parameter. + range.id |= V4L2_CTRL_FLAG_NEXT_CTRL; + +- if (range.flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_READ_ONLY)) { +- // Permanently disabled or permanently read-only. +- continue; +- } +- if (V4L2CaptureDelegate::IsBlockedControl(ext_control.id)) { ++ if (IsSpecialOrBlockedControl(range.id & ~V4L2_CTRL_FLAG_NEXT_CTRL)) + continue; +- } +- +- if (V4L2CaptureDelegate::IsSpecialControl(ext_control.id)) { +- if (ext_control.id == V4L2_CID_EXPOSURE_AUTO) { +- ext_control.value = V4L2_EXPOSURE_MANUAL; +- } else { +- ext_control.value = false; // Not automatic but manual. +- } +- manual_special_camera_controls.push_back(ext_control); +- DVLOG(1) << __func__ << " " << range.name << " set to manual"; +- } else { +- ext_control.value = range.maximum; +- camera_controls.push_back(ext_control); +- DVLOG(1) << __func__ << " " << range.name << " set to " +- << range.maximum; +- } +- } ++ DVLOG(1) << __func__ << " " << range.name << " set to " << range.maximum; + +- // Set special controls to manual modes. +- if (!manual_special_camera_controls.empty()) { +- ext_controls.which = +- use_modern_s_ext_ctrls ? V4L2_CTRL_WHICH_CUR_VAL : control.class_id; +- ext_controls.count = manual_special_camera_controls.size(); +- ext_controls.controls = manual_special_camera_controls.data(); +- if (HANDLE_EINTR(ioctl(device_fd, VIDIOC_S_EXT_CTRLS, &ext_controls)) < +- 0) { +- DPLOG(ERROR) << "VIDIOC_S_EXT_CTRLS"; +- } ++ struct v4l2_ext_control ext_control = {}; ++ ext_control.id = range.id & ~V4L2_CTRL_FLAG_NEXT_CTRL; ++ ext_control.value = range.maximum; ++ camera_controls.push_back(ext_control); + } + +- // Set non-special controls to maximum values. + if (!camera_controls.empty()) { +- ext_controls.which = +- use_modern_s_ext_ctrls ? V4L2_CTRL_WHICH_CUR_VAL : control.class_id; ++ struct v4l2_ext_controls ext_controls = {}; ++ ext_controls.ctrl_class = control.class_id; + ext_controls.count = camera_controls.size(); + ext_controls.controls = camera_controls.data(); + if (HANDLE_EINTR(ioctl(device_fd, VIDIOC_S_EXT_CTRLS, &ext_controls)) < 0) + DPLOG(ERROR) << "VIDIOC_S_EXT_CTRLS"; + } + +- // Start right below the base so that the first next retrieved control ID +- // is always the first available control ID within the class even if that +- // control ID is equal to the base (V4L2_CID_BRIGHTNESS equals to +- // V4L2_CID_USER_BASE). +- range.id = (control.control_base - 1) | V4L2_CTRL_FLAG_NEXT_CTRL; ++ range.id = control.control_base | V4L2_CTRL_FLAG_NEXT_CTRL; + while (0 == HANDLE_EINTR(ioctl(device_fd, VIDIOC_QUERYCTRL, &range))) { + if (V4L2_CTRL_ID2CLASS(range.id) != V4L2_CTRL_ID2CLASS(control.class_id)) + break; +- +- v4l2_control readback = {}; +- readback.id = range.id; +- +- // Prepare to query for the next control as `range` is an in-out +- // parameter. + range.id |= V4L2_CTRL_FLAG_NEXT_CTRL; + +- if (range.flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_READ_ONLY)) { +- // Permanently disabled or permanently read-only. ++ if (IsSpecialOrBlockedControl(range.id & ~V4L2_CTRL_FLAG_NEXT_CTRL)) + continue; +- } +- if (V4L2CaptureDelegate::IsBlockedControl(readback.id) || +- V4L2CaptureDelegate::IsSpecialControl(readback.id)) { +- continue; +- } ++ DVLOG(1) << __func__ << " " << range.name << " set to " << range.maximum; + ++ v4l2_control readback = {}; ++ readback.id = range.id & ~V4L2_CTRL_FLAG_NEXT_CTRL; + if (HANDLE_EINTR(ioctl(device_fd, VIDIOC_G_CTRL, &readback)) < 0) + DPLOG(ERROR) << range.name << ", failed to be read."; +- EXPECT_EQ(range.maximum, readback.value) +- << " control " << range.name << " didn't set correctly"; ++ EXPECT_EQ(range.maximum, readback.value) << " control " << range.name ++ << " didnt set correctly"; + } + } + } +@@ -186,7 +195,15 @@ class V4L2CaptureDelegateTest : public ::testing::Test { + + } // anonymous namespace + +-TEST_F(V4L2CaptureDelegateTest, CreateAndDestroyAndVerifyControls) { ++// Fails on Linux, see crbug/732355 ++#if BUILDFLAG(IS_LINUX) ++#define MAYBE_CreateAndDestroyAndVerifyControls \ ++ DISABLED_CreateAndDestroyAndVerifyControls ++#else ++#define MAYBE_CreateAndDestroyAndVerifyControls \ ++ CreateAndDestroyAndVerifyControls ++#endif ++TEST_F(V4L2CaptureDelegateTest, MAYBE_CreateAndDestroyAndVerifyControls) { + // Check that there is at least a video device, otherwise bail. + const base::FilePath path("/dev/"); + base::FileEnumerator enumerator(path, false, base::FileEnumerator::FILES, diff --git a/chromium.spec b/chromium.spec index 144a5a18..e50a4ff1 100644 --- a/chromium.spec +++ b/chromium.spec @@ -339,6 +339,10 @@ Patch106: chromium-98.0.4758.80-epel7-erase-fix.patch # Add additional operator== to make el7 happy. Patch107: chromium-99.0.4844.51-el7-extra-operator==.patch +# workaround for clang bug on el7 +Patch108: chromium-113-constexpr-el7.patch +# fix FTBFS on el7, old kernel +Patch109: chromium-113-v4l2-revert-el7.patch # system ffmpeg Patch114: chromium-107-ffmpeg-duration.patch @@ -941,6 +945,8 @@ udev. %patch -P105 -p1 -b .el7-old-libdrm %patch -P106 -p1 -b .el7-erase-fix %patch -P107 -p1 -b .el7-extra-operator-equalequal +%patch -P108 -p1 -R -b .constexpr-el7 +%patch -P109 -p1 -b .v4l2-revert-el7 %endif %patch -P130 -p1 -b .VirtualCursor-std-layout