Compare commits

..

3 Commits

Author SHA1 Message Date
377d37c311 Import from CS git 2025-01-09 11:48:53 +00:00
a93844e05b import CS firefox-128.5.1-1.el9 2024-12-04 10:13:00 +00:00
81091f5b96 import CS firefox-128.4.0-1.el8 2024-10-31 23:12:45 +00:00
22 changed files with 4674 additions and 73 deletions

View File

@ -1,7 +1,8 @@
5012b69e54cbebe3b5e74011dacf3a2097f49921 SOURCES/cbindgen-vendor.tar.xz 5012b69e54cbebe3b5e74011dacf3a2097f49921 SOURCES/cbindgen-vendor.tar.xz
6816817f0b3b42a13dfdc38af8c61dca46b54c13 SOURCES/firefox-128.3.1esr.processed-source.tar.xz e7ed7ac1b931b5fa222caef5f168fadddb86b324 SOURCES/firefox-128.6.0esr.processed-source.tar.xz
4641ad07664f375780e20200322bd5b45cd60ee8 SOURCES/firefox-langpacks-128.3.1esr-20241009.tar.xz 798d35ab0e2ca81a9978c0514684f3d7fce0e384 SOURCES/firefox-langpacks-128.6.0esr-20241218.tar.xz
2d8a6b2b30d5496735f49ffe8c8a7ede3a78a5ca SOURCES/mochitest-python.tar.gz 2d8a6b2b30d5496735f49ffe8c8a7ede3a78a5ca SOURCES/mochitest-python.tar.gz
d744f92e874688cc4b5376477dfdd639a97a6cd4 SOURCES/nspr-4.35.0-1.el8_1.src.rpm d744f92e874688cc4b5376477dfdd639a97a6cd4 SOURCES/nspr-4.35.0-1.el8_1.src.rpm
f466d7213e85773e002c48897524eaf909480046 SOURCES/nss-3.101.0-7.el8_2.src.rpm f466d7213e85773e002c48897524eaf909480046 SOURCES/nss-3.101.0-7.el8_2.src.rpm
0413d22a58ba1bba99acec9c3c2a4db56a4100c7 SOURCES/nss-3.101.0-7.el9_2.src.rpm 0413d22a58ba1bba99acec9c3c2a4db56a4100c7 SOURCES/nss-3.101.0-7.el9_2.src.rpm
0332862626d2148648ff749078c223dbd859d901 SOURCES/wasi-sdk-20.tar.gz

5
.gitignore vendored
View File

@ -1,7 +1,8 @@
SOURCES/cbindgen-vendor.tar.xz SOURCES/cbindgen-vendor.tar.xz
SOURCES/firefox-128.3.1esr.processed-source.tar.xz SOURCES/firefox-128.6.0esr.processed-source.tar.xz
SOURCES/firefox-langpacks-128.3.1esr-20241009.tar.xz SOURCES/firefox-langpacks-128.6.0esr-20241218.tar.xz
SOURCES/mochitest-python.tar.gz SOURCES/mochitest-python.tar.gz
SOURCES/nspr-4.35.0-1.el8_1.src.rpm SOURCES/nspr-4.35.0-1.el8_1.src.rpm
SOURCES/nss-3.101.0-7.el8_2.src.rpm SOURCES/nss-3.101.0-7.el8_2.src.rpm
SOURCES/nss-3.101.0-7.el9_2.src.rpm SOURCES/nss-3.101.0-7.el9_2.src.rpm
SOURCES/wasi-sdk-20.tar.gz

View File

@ -0,0 +1,116 @@
From 92643d686bed8f3e4f2c1aae194925b6dc9dea86 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Fri, 28 Jun 2024 18:13:15 +0000
Subject: [PATCH] Bug 1905335 - WebRTC backport: PipeWire capture: hide cursor
when it goes off screen or is not visible r=pehrsons,webrtc-reviewers
This is a simple backport of an WebRTC upstream change.
Upstream commit: e6ad337d633c145c48a5a4ae54968c14c16081c7
Differential Revision: https://phabricator.services.mozilla.com/D215197
---
.../wayland/mouse_cursor_monitor_pipewire.cc | 14 +++--
.../linux/wayland/shared_screencast_stream.cc | 52 +++++++++++--------
.../e6ad337d63.no-op-cherry-pick-msg | 1 +
3 files changed, 39 insertions(+), 28 deletions(-)
create mode 100644 third_party/libwebrtc/moz-patch-stack/e6ad337d63.no-op-cherry-pick-msg
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc
index 3d33b0fbb8e6e..00b07f341b16a 100644
--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc
+++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc
@@ -40,6 +40,14 @@ void MouseCursorMonitorPipeWire::Capture() {
RTC_DCHECK_RUN_ON(&sequence_checker_);
RTC_DCHECK(callback_);
+ absl::optional<DesktopVector> mouse_cursor_position =
+ options_.screencast_stream()->CaptureCursorPosition();
+ // Invalid cursor or position
+ if (!mouse_cursor_position) {
+ callback_->OnMouseCursor(nullptr);
+ return;
+ }
+
std::unique_ptr<MouseCursor> mouse_cursor =
options_.screencast_stream()->CaptureCursor();
@@ -48,11 +56,7 @@ void MouseCursorMonitorPipeWire::Capture() {
}
if (mode_ == SHAPE_AND_POSITION) {
- absl::optional<DesktopVector> mouse_cursor_position =
- options_.screencast_stream()->CaptureCursorPosition();
- if (mouse_cursor_position) {
- callback_->OnMouseCursorPosition(mouse_cursor_position.value());
- }
+ callback_->OnMouseCursorPosition(mouse_cursor_position.value());
}
}
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
index ab9054f1a1676..b8cac318ffeb9 100644
--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
+++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
@@ -690,32 +690,38 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
const struct spa_meta_cursor* cursor =
static_cast<struct spa_meta_cursor*>(spa_buffer_find_meta_data(
spa_buffer, SPA_META_Cursor, sizeof(*cursor)));
- if (cursor && spa_meta_cursor_is_valid(cursor)) {
- struct spa_meta_bitmap* bitmap = nullptr;
-
- if (cursor->bitmap_offset)
- bitmap =
- SPA_MEMBER(cursor, cursor->bitmap_offset, struct spa_meta_bitmap);
-
- if (bitmap && bitmap->size.width > 0 && bitmap->size.height > 0) {
- const uint8_t* bitmap_data =
- SPA_MEMBER(bitmap, bitmap->offset, uint8_t);
- BasicDesktopFrame* mouse_frame = new BasicDesktopFrame(
- DesktopSize(bitmap->size.width, bitmap->size.height));
- mouse_frame->CopyPixelsFrom(
- bitmap_data, bitmap->stride,
- DesktopRect::MakeWH(bitmap->size.width, bitmap->size.height));
- mouse_cursor_ = std::make_unique<MouseCursor>(
- mouse_frame, DesktopVector(cursor->hotspot.x, cursor->hotspot.y));
- if (observer_) {
- observer_->OnCursorShapeChanged();
+ if (cursor) {
+ if (spa_meta_cursor_is_valid(cursor)) {
+ struct spa_meta_bitmap* bitmap = nullptr;
+
+ if (cursor->bitmap_offset)
+ bitmap =
+ SPA_MEMBER(cursor, cursor->bitmap_offset, struct spa_meta_bitmap);
+
+ if (bitmap && bitmap->size.width > 0 && bitmap->size.height > 0) {
+ const uint8_t* bitmap_data =
+ SPA_MEMBER(bitmap, bitmap->offset, uint8_t);
+ BasicDesktopFrame* mouse_frame = new BasicDesktopFrame(
+ DesktopSize(bitmap->size.width, bitmap->size.height));
+ mouse_frame->CopyPixelsFrom(
+ bitmap_data, bitmap->stride,
+ DesktopRect::MakeWH(bitmap->size.width, bitmap->size.height));
+ mouse_cursor_ = std::make_unique<MouseCursor>(
+ mouse_frame, DesktopVector(cursor->hotspot.x, cursor->hotspot.y));
+
+ if (observer_) {
+ observer_->OnCursorShapeChanged();
+ }
}
- }
- mouse_cursor_position_.set(cursor->position.x, cursor->position.y);
+ mouse_cursor_position_.set(cursor->position.x, cursor->position.y);
- if (observer_) {
- observer_->OnCursorPositionChanged();
+ if (observer_) {
+ observer_->OnCursorPositionChanged();
+ }
+ } else {
+ // Indicate an invalid cursor
+ mouse_cursor_position_.set(-1, -1);
}
}
}

View File

@ -0,0 +1,87 @@
From fef1904f95dc592deef7044debe71a02c5d7046c Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Sat, 20 Jul 2024 07:04:27 +0000
Subject: [PATCH] Bug 1907013 - WebRTC backport: PipeWire camera: support
additional formats and fix RGB/BGR mapping r=jib,webrtc-reviewers
This is a simple backprot of an WebRTC upstream change.
Upstream commit: b1ebcfbfd6afb57f314b6689ca001aca1b13a5b4
Differential Revision: https://phabricator.services.mozilla.com/D216138
---
.../modules/video_capture/linux/pipewire_session.cc | 6 ++++++
.../video_capture/linux/video_capture_pipewire.cc | 12 ++++++++++--
.../moz-patch-stack/b1ebcfbfd6.no-op-cherry-pick-msg | 1 +
3 files changed, 17 insertions(+), 2 deletions(-)
create mode 100644 third_party/libwebrtc/moz-patch-stack/b1ebcfbfd6.no-op-cherry-pick-msg
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
index d52d6aacc8005..107ea3dfbd954 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
@@ -35,12 +35,18 @@ VideoType PipeWireRawFormatToVideoType(uint32_t id) {
return VideoType::kYUY2;
case SPA_VIDEO_FORMAT_UYVY:
return VideoType::kUYVY;
+ case SPA_VIDEO_FORMAT_RGB16:
+ return VideoType::kRGB565;
case SPA_VIDEO_FORMAT_RGB:
+ return VideoType::kBGR24;
+ case SPA_VIDEO_FORMAT_BGR:
return VideoType::kRGB24;
case SPA_VIDEO_FORMAT_BGRA:
return VideoType::kARGB;
case SPA_VIDEO_FORMAT_RGBA:
return VideoType::kABGR;
+ case SPA_VIDEO_FORMAT_ARGB:
+ return VideoType::kBGRA;
default:
return VideoType::kUnknown;
}
diff --git a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
index 9ff4fdb9b1c98..1672b7583f582 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
+++ b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
@@ -34,10 +34,15 @@ struct {
{SPA_VIDEO_FORMAT_YUY2, VideoType::kYUY2},
{SPA_VIDEO_FORMAT_UYVY, VideoType::kUYVY},
// PipeWire is big-endian for the formats, while libyuv is little-endian
- // This means that BGRA == ARGB and RGBA == ABGR
+ // This means that BGRA == ARGB, RGBA == ABGR and similar
+ // This follows mapping in libcamera PipeWire plugin:
+ // https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/spa/plugins/libcamera/libcamera-utils.cpp
{SPA_VIDEO_FORMAT_BGRA, VideoType::kARGB},
{SPA_VIDEO_FORMAT_RGBA, VideoType::kABGR},
- {SPA_VIDEO_FORMAT_RGB, VideoType::kRGB24},
+ {SPA_VIDEO_FORMAT_ARGB, VideoType::kBGRA},
+ {SPA_VIDEO_FORMAT_RGB, VideoType::kBGR24},
+ {SPA_VIDEO_FORMAT_BGR, VideoType::kRGB24},
+ {SPA_VIDEO_FORMAT_RGB16, VideoType::kRGB565},
};
VideoType VideoCaptureModulePipeWire::PipeWireRawFormatToVideoType(
@@ -302,13 +307,16 @@ void VideoCaptureModulePipeWire::OnFormatChanged(const struct spa_pod* format) {
break;
case VideoType::kYUY2:
case VideoType::kUYVY:
+ case VideoType::kRGB565:
stride = configured_capability_.width * 2;
break;
case VideoType::kRGB24:
+ case VideoType::kBGR24:
stride = configured_capability_.width * 3;
break;
case VideoType::kARGB:
case VideoType::kABGR:
+ case VideoType::kBGRA:
stride = configured_capability_.width * 4;
break;
default:
diff --git a/third_party/libwebrtc/moz-patch-stack/b1ebcfbfd6.no-op-cherry-pick-msg b/third_party/libwebrtc/moz-patch-stack/b1ebcfbfd6.no-op-cherry-pick-msg
new file mode 100644
index 0000000000000..e795b816b1382
--- /dev/null
+++ b/third_party/libwebrtc/moz-patch-stack/b1ebcfbfd6.no-op-cherry-pick-msg
@@ -0,0 +1 @@
+We cherry-picked this in bug 1907013.

View File

@ -0,0 +1,231 @@
From 286575b387cff9b3ec318d3cf90cf20d2f3c2ce4 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Mon, 2 Sep 2024 11:07:20 +0000
Subject: [PATCH] Bug 1913286 - WebRTC backport: PipeWire camera: filter out
devices with no capabilities r=pehrsons,webrtc-reviewers
Filter out devices that do not support any format supported by WebRTC.
This will for example be IR cameras that show as duplicated in the list
of cameras, but support only GRAY8 format and for that reason do not
work at all.
This is a simple backport of an WebRTC upstream change.
Upstream commit: b4aba7834e6c94adace1cb4c20e2e1ee70eb9cc5
Differential Revision: https://phabricator.services.mozilla.com/D219224
---
.../linux/device_info_pipewire.cc | 20 ++++-----
.../video_capture/linux/pipewire_session.cc | 43 +++++++++++++------
.../video_capture/linux/pipewire_session.h | 21 ++++++---
.../b4aba7834e.no-op-cherry-pick-msg | 1 +
4 files changed, 58 insertions(+), 27 deletions(-)
create mode 100644 third_party/libwebrtc/moz-patch-stack/b4aba7834e.no-op-cherry-pick-msg
diff --git a/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc b/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc
index 31d922035b3f8..db2a3c7099169 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc
+++ b/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc
@@ -57,31 +57,31 @@ int32_t DeviceInfoPipeWire::GetDeviceName(uint32_t deviceNumber,
if (deviceNumber >= NumberOfDevices())
return -1;
- const PipeWireNode& node = pipewire_session_->nodes().at(deviceNumber);
+ const auto& node = pipewire_session_->nodes().at(deviceNumber);
- if (deviceNameLength <= node.display_name().length()) {
+ if (deviceNameLength <= node->display_name().length()) {
RTC_LOG(LS_INFO) << "deviceNameUTF8 buffer passed is too small";
return -1;
}
- if (deviceUniqueIdUTF8Length <= node.unique_id().length()) {
+ if (deviceUniqueIdUTF8Length <= node->unique_id().length()) {
RTC_LOG(LS_INFO) << "deviceUniqueIdUTF8 buffer passed is too small";
return -1;
}
if (productUniqueIdUTF8 &&
- productUniqueIdUTF8Length <= node.model_id().length()) {
+ productUniqueIdUTF8Length <= node->model_id().length()) {
RTC_LOG(LS_INFO) << "productUniqueIdUTF8 buffer passed is too small";
return -1;
}
memset(deviceNameUTF8, 0, deviceNameLength);
- node.display_name().copy(deviceNameUTF8, deviceNameLength);
+ node->display_name().copy(deviceNameUTF8, deviceNameLength);
memset(deviceUniqueIdUTF8, 0, deviceUniqueIdUTF8Length);
- node.unique_id().copy(deviceUniqueIdUTF8, deviceUniqueIdUTF8Length);
+ node->unique_id().copy(deviceUniqueIdUTF8, deviceUniqueIdUTF8Length);
if (productUniqueIdUTF8) {
memset(productUniqueIdUTF8, 0, productUniqueIdUTF8Length);
- node.model_id().copy(productUniqueIdUTF8, productUniqueIdUTF8Length);
+ node->model_id().copy(productUniqueIdUTF8, productUniqueIdUTF8Length);
}
return 0;
@@ -92,11 +92,11 @@ int32_t DeviceInfoPipeWire::CreateCapabilityMap(
RTC_CHECK(pipewire_session_);
for (auto& node : pipewire_session_->nodes()) {
- if (node.unique_id().compare(deviceUniqueIdUTF8) != 0)
+ if (node->unique_id().compare(deviceUniqueIdUTF8) != 0)
continue;
- _captureCapabilities = node.capabilities();
- _lastUsedDeviceNameLength = node.unique_id().length();
+ _captureCapabilities = node->capabilities();
+ _lastUsedDeviceNameLength = node->unique_id().length();
_lastUsedDeviceName = static_cast<char*>(
realloc(_lastUsedDeviceName, _lastUsedDeviceNameLength + 1));
memcpy(_lastUsedDeviceName, deviceUniqueIdUTF8,
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
index 107ea3dfbd954..dbac09274bb31 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
@@ -52,6 +52,19 @@ VideoType PipeWireRawFormatToVideoType(uint32_t id) {
}
}
+void PipeWireNode::PipeWireNodeDeleter::operator()(
+ PipeWireNode* node) const noexcept {
+ pw_proxy_destroy(node->proxy_);
+ spa_hook_remove(&node->node_listener_);
+}
+
+// static
+PipeWireNode::PipeWireNodePtr PipeWireNode::Create(PipeWireSession* session,
+ uint32_t id,
+ const spa_dict* props) {
+ return PipeWireNodePtr(new PipeWireNode(session, id, props));
+}
+
PipeWireNode::PipeWireNode(PipeWireSession* session,
uint32_t id,
const spa_dict* props)
@@ -73,11 +86,6 @@ PipeWireNode::PipeWireNode(PipeWireSession* session,
pw_node_add_listener(proxy_, &node_listener_, &node_events, this);
}
-PipeWireNode::~PipeWireNode() {
- pw_proxy_destroy(proxy_);
- spa_hook_remove(&node_listener_);
-}
-
// static
void PipeWireNode::OnNodeInfo(void* data, const pw_node_info* info) {
PipeWireNode* that = static_cast<PipeWireNode*>(data);
@@ -99,7 +107,9 @@ void PipeWireNode::OnNodeInfo(void* data, const pw_node_info* info) {
pid.value());
that->model_id_ = model_str;
}
- } else if (info->change_mask & PW_NODE_CHANGE_MASK_PARAMS) {
+ }
+
+ if (info->change_mask & PW_NODE_CHANGE_MASK_PARAMS) {
for (uint32_t i = 0; i < info->n_params; i++) {
uint32_t id = info->params[i].id;
if (id == SPA_PARAM_EnumFormat &&
@@ -350,6 +360,14 @@ void PipeWireSession::OnCoreDone(void* data, uint32_t id, int seq) {
if (id == PW_ID_CORE) {
if (seq == that->sync_seq_) {
RTC_LOG(LS_VERBOSE) << "Enumerating PipeWire camera devices complete.";
+
+ // Remove camera devices with no capabilities
+ auto it = std::remove_if(that->nodes_.begin(), that->nodes_.end(),
+ [](const PipeWireNode::PipeWireNodePtr& node) {
+ return node->capabilities().empty();
+ });
+ that->nodes_.erase(it, that->nodes_.end());
+
that->Finish(VideoCaptureOptions::Status::SUCCESS);
}
}
@@ -366,8 +384,8 @@ void PipeWireSession::OnRegistryGlobal(void* data,
// Skip already added nodes to avoid duplicate camera entries
if (std::find_if(that->nodes_.begin(), that->nodes_.end(),
- [id](const PipeWireNode& node) {
- return node.id() == id;
+ [id](const PipeWireNode::PipeWireNodePtr& node) {
+ return node->id() == id;
}) != that->nodes_.end())
return;
@@ -381,7 +399,7 @@ void PipeWireSession::OnRegistryGlobal(void* data,
if (!node_role || strcmp(node_role, "Camera"))
return;
- that->nodes_.emplace_back(that, id, props);
+ that->nodes_.push_back(PipeWireNode::Create(that, id, props));
that->PipeWireSync();
}
@@ -389,9 +407,10 @@ void PipeWireSession::OnRegistryGlobal(void* data,
void PipeWireSession::OnRegistryGlobalRemove(void* data, uint32_t id) {
PipeWireSession* that = static_cast<PipeWireSession*>(data);
- auto it = std::remove_if(
- that->nodes_.begin(), that->nodes_.end(),
- [id](const PipeWireNode& node) { return node.id() == id; });
+ auto it = std::remove_if(that->nodes_.begin(), that->nodes_.end(),
+ [id](const PipeWireNode::PipeWireNodePtr& node) {
+ return node->id() == id;
+ });
that->nodes_.erase(it, that->nodes_.end());
}
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h
index fdc06a6b2a27a..84273ea695277 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h
@@ -37,8 +37,15 @@ class VideoCaptureModulePipeWire;
// So they all represent one camera that is available via PipeWire.
class PipeWireNode {
public:
- PipeWireNode(PipeWireSession* session, uint32_t id, const spa_dict* props);
- ~PipeWireNode();
+ struct PipeWireNodeDeleter {
+ void operator()(PipeWireNode* node) const noexcept;
+ };
+
+ using PipeWireNodePtr =
+ std::unique_ptr<PipeWireNode, PipeWireNode::PipeWireNodeDeleter>;
+ static PipeWireNodePtr Create(PipeWireSession* session,
+ uint32_t id,
+ const spa_dict* props);
uint32_t id() const { return id_; }
std::string display_name() const { return display_name_; }
@@ -48,6 +55,9 @@ class PipeWireNode {
return capabilities_;
}
+ protected:
+ PipeWireNode(PipeWireSession* session, uint32_t id, const spa_dict* props);
+
private:
static void OnNodeInfo(void* data, const pw_node_info* info);
static void OnNodeParam(void* data,
@@ -87,8 +97,9 @@ class PipeWireSession : public rtc::RefCountedNonVirtual<PipeWireSession> {
void Init(VideoCaptureOptions::Callback* callback,
int fd = kInvalidPipeWireFd);
-
- const std::deque<PipeWireNode>& nodes() const { return nodes_; }
+ const std::deque<PipeWireNode::PipeWireNodePtr>& nodes() const {
+ return nodes_;
+ }
friend class CameraPortalNotifier;
friend class PipeWireNode;
@@ -134,7 +145,7 @@ class PipeWireSession : public rtc::RefCountedNonVirtual<PipeWireSession> {
int sync_seq_ = 0;
- std::deque<PipeWireNode> nodes_;
+ std::deque<PipeWireNode::PipeWireNodePtr> nodes_;
std::unique_ptr<CameraPortal> portal_;
std::unique_ptr<CameraPortalNotifier> portal_notifier_;
};

View File

@ -0,0 +1,52 @@
From b10c1d09729794c46f9c04d04c07c18d514d396e Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 4 Sep 2024 13:43:29 +0000
Subject: [PATCH] Bug 1912785 - Always query information about camera
availability r=pehrsons
We have to always update camera availability information, even when we
don't request cameras, because the WebRTC backend automatically creates
camera video engine and not having this information we might hitting an
assert later, where we assume the status of camera availability is not
unknown.
Differential Revision: https://phabricator.services.mozilla.com/D219062
---
dom/media/MediaManager.cpp | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp
index 2ade297d31e84..3cc716e6836ac 100644
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -2153,9 +2153,15 @@ MediaManager::MaybeRequestPermissionAndEnumerateRawDevices(
}
if (!deviceAccessPromise) {
- // No device access request needed. Proceed directly.
- deviceAccessPromise =
- NativePromise::CreateAndResolve(CamerasAccessStatus::Granted, __func__);
+ // No device access request needed. We can proceed directly, but we still
+ // need to update camera availability, because the camera engine is always
+ // created together with the WebRTC backend, which is done because
+ // devicechange events must work before prompting in cases where persistent
+ // permission has already been given. Making a request to camera access not
+ // allowing a permission request does exactly what we need in this case.
+ ipc::PBackgroundChild* backgroundChild =
+ ipc::BackgroundChild::GetOrCreateForCurrentThread();
+ deviceAccessPromise = backgroundChild->SendRequestCameraAccess(false);
}
return deviceAccessPromise->Then(
@@ -2190,8 +2196,9 @@ MediaManager::MaybeRequestPermissionAndEnumerateRawDevices(
"rejected");
}
- if (aParams.mFlags.contains(EnumerationFlag::AllowPermissionRequest)) {
- MOZ_ASSERT(aValue.ResolveValue() == CamerasAccessStatus::Granted);
+ if (aParams.VideoInputType() == MediaSourceEnum::Camera &&
+ aParams.mFlags.contains(EnumerationFlag::AllowPermissionRequest) &&
+ aValue.ResolveValue() == CamerasAccessStatus::Granted) {
EnsureNoPlaceholdersInDeviceCache();
}

View File

@ -0,0 +1,293 @@
From df57b21200c7cde7ac34705e8fceab2fbe933bc5 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Tue, 3 Sep 2024 07:56:39 +0000
Subject: [PATCH] Bug 1912778 - Always register video input feedback for newly
created DeviceInfo r=pehrsons
Make sure to always register video input feedback when a new DeviceInfo
is created. We always destroy DeviceInfo once request to camera access
is resolved, making it to be created again, but this time skipping the
part where video input feedback is registered as we use already existing
VideoEngine. There is now just one place where DeviceInfo gets created
and the logic for video input feedback registration has been moved to
VideoEngine as it's the only place where we know when new DeviceInfo is
created.
Differential Revision: https://phabricator.services.mozilla.com/D219060
---
dom/media/systemservices/CamerasParent.cpp | 164 ++++++++++-----------
dom/media/systemservices/CamerasParent.h | 5 +
dom/media/systemservices/VideoEngine.cpp | 7 +-
dom/media/systemservices/VideoEngine.h | 2 +-
4 files changed, 91 insertions(+), 87 deletions(-)
diff --git a/dom/media/systemservices/CamerasParent.cpp b/dom/media/systemservices/CamerasParent.cpp
index 048d07b7fa..d6fe5986da 100644
--- a/dom/media/systemservices/CamerasParent.cpp
+++ b/dom/media/systemservices/CamerasParent.cpp
@@ -405,15 +405,25 @@ void CamerasParent::CloseEngines() {
Unused << ReleaseCapture(capEngine, streamNum);
}
- if (VideoEngine* engine = mEngines->ElementAt(CameraEngine); engine) {
- auto device_info = engine->GetOrCreateVideoCaptureDeviceInfo();
- MOZ_ASSERT(device_info);
- if (device_info) {
- device_info->DeRegisterVideoInputFeedBack(this);
- }
+ auto device_info = GetDeviceInfo(CameraEngine);
+ MOZ_ASSERT(device_info);
+ if (device_info) {
+ device_info->DeRegisterVideoInputFeedBack(this);
}
}
+std::shared_ptr<webrtc::VideoCaptureModule::DeviceInfo>
+CamerasParent::GetDeviceInfo(int aEngine) {
+ MOZ_ASSERT(mVideoCaptureThread->IsOnCurrentThread());
+ LOG_VERBOSE("CamerasParent(%p)::%s", this, __func__);
+
+ auto* engine = EnsureInitialized(aEngine);
+ if (!engine) {
+ return nullptr;
+ }
+ return engine->GetOrCreateVideoCaptureDeviceInfo(this);
+}
+
VideoEngine* CamerasParent::EnsureInitialized(int aEngine) {
MOZ_ASSERT(mVideoCaptureThread->IsOnCurrentThread());
LOG_VERBOSE("CamerasParent(%p)::%s", this, __func__);
@@ -449,14 +459,6 @@ VideoEngine* CamerasParent::EnsureInitialized(int aEngine) {
return nullptr;
}
- if (capEngine == CameraEngine) {
- auto device_info = engine->GetOrCreateVideoCaptureDeviceInfo();
- MOZ_ASSERT(device_info);
- if (device_info) {
- device_info->RegisterVideoInputFeedBack(this);
- }
- }
-
return mEngines->ElementAt(capEngine) = std::move(engine);
}
@@ -474,19 +476,16 @@ ipc::IPCResult CamerasParent::RecvNumberOfCaptureDevices(
LOG("CaptureEngine=%d", aCapEngine);
using Promise = MozPromise<int, bool, true>;
- InvokeAsync(
- mVideoCaptureThread, __func__,
- [this, self = RefPtr(this), aCapEngine] {
- int num = -1;
- if (auto* engine = EnsureInitialized(aCapEngine)) {
- if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
- num = static_cast<int>(devInfo->NumberOfDevices());
- }
- }
+ InvokeAsync(mVideoCaptureThread, __func__,
+ [this, self = RefPtr(this), aCapEngine] {
+ int num = -1;
+ if (auto devInfo = GetDeviceInfo(aCapEngine)) {
+ num = static_cast<int>(devInfo->NumberOfDevices());
+ }
- return Promise::CreateAndResolve(
- num, "CamerasParent::RecvNumberOfCaptureDevices");
- })
+ return Promise::CreateAndResolve(
+ num, "CamerasParent::RecvNumberOfCaptureDevices");
+ })
->Then(
mPBackgroundEventTarget, __func__,
[this, self = RefPtr(this)](Promise::ResolveOrRejectValue&& aValue) {
@@ -558,10 +557,8 @@ ipc::IPCResult CamerasParent::RecvNumberOfCapabilities(
mVideoCaptureThread, __func__,
[this, self = RefPtr(this), id = nsCString(aUniqueId), aCapEngine]() {
int num = -1;
- if (auto* engine = EnsureInitialized(aCapEngine)) {
- if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
- num = devInfo->NumberOfCapabilities(id.get());
- }
+ if (auto devInfo = GetDeviceInfo(aCapEngine)) {
+ num = devInfo->NumberOfCapabilities(id.get());
}
return Promise::CreateAndResolve(
num, "CamerasParent::RecvNumberOfCapabilities");
@@ -599,36 +596,34 @@ ipc::IPCResult CamerasParent::RecvGetCaptureCapability(
aIndex);
using Promise = MozPromise<webrtc::VideoCaptureCapability, int, true>;
- InvokeAsync(
- mVideoCaptureThread, __func__,
- [this, self = RefPtr(this), id = nsCString(aUniqueId), aCapEngine,
- aIndex] {
- webrtc::VideoCaptureCapability webrtcCaps;
- int error = -1;
- if (auto* engine = EnsureInitialized(aCapEngine)) {
- if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
- error = devInfo->GetCapability(id.get(), aIndex, webrtcCaps);
- }
- }
+ InvokeAsync(mVideoCaptureThread, __func__,
+ [this, self = RefPtr(this), id = nsCString(aUniqueId), aCapEngine,
+ aIndex] {
+ webrtc::VideoCaptureCapability webrtcCaps;
+ int error = -1;
+ if (auto devInfo = GetDeviceInfo(aCapEngine)) {
+ error = devInfo->GetCapability(id.get(), aIndex, webrtcCaps);
+ }
- if (!error && aCapEngine == CameraEngine) {
- auto iter = mAllCandidateCapabilities.find(id);
- if (iter == mAllCandidateCapabilities.end()) {
- std::map<uint32_t, webrtc::VideoCaptureCapability>
- candidateCapabilities;
- candidateCapabilities.emplace(aIndex, webrtcCaps);
- mAllCandidateCapabilities.emplace(id, candidateCapabilities);
- } else {
- (iter->second).emplace(aIndex, webrtcCaps);
- }
- }
- if (error) {
- return Promise::CreateAndReject(
- error, "CamerasParent::RecvGetCaptureCapability");
- }
- return Promise::CreateAndResolve(
- webrtcCaps, "CamerasParent::RecvGetCaptureCapability");
- })
+ if (!error && aCapEngine == CameraEngine) {
+ auto iter = mAllCandidateCapabilities.find(id);
+ if (iter == mAllCandidateCapabilities.end()) {
+ std::map<uint32_t, webrtc::VideoCaptureCapability>
+ candidateCapabilities;
+ candidateCapabilities.emplace(aIndex, webrtcCaps);
+ mAllCandidateCapabilities.emplace(id,
+ candidateCapabilities);
+ } else {
+ (iter->second).emplace(aIndex, webrtcCaps);
+ }
+ }
+ if (error) {
+ return Promise::CreateAndReject(
+ error, "CamerasParent::RecvGetCaptureCapability");
+ }
+ return Promise::CreateAndResolve(
+ webrtcCaps, "CamerasParent::RecvGetCaptureCapability");
+ })
->Then(
mPBackgroundEventTarget, __func__,
[this, self = RefPtr(this)](Promise::ResolveOrRejectValue&& aValue) {
@@ -664,33 +659,32 @@ ipc::IPCResult CamerasParent::RecvGetCaptureDevice(
using Data = std::tuple<nsCString, nsCString, pid_t, bool, int>;
using Promise = MozPromise<Data, bool, true>;
- InvokeAsync(
- mVideoCaptureThread, __func__,
- [this, self = RefPtr(this), aCapEngine, aDeviceIndex] {
- char deviceName[MediaEngineSource::kMaxDeviceNameLength];
- char deviceUniqueId[MediaEngineSource::kMaxUniqueIdLength];
- nsCString name;
- nsCString uniqueId;
- pid_t devicePid = 0;
- bool placeholder = false;
- int error = -1;
- if (auto* engine = EnsureInitialized(aCapEngine)) {
- if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()) {
- error = devInfo->GetDeviceName(
- aDeviceIndex, deviceName, sizeof(deviceName), deviceUniqueId,
- sizeof(deviceUniqueId), nullptr, 0, &devicePid, &placeholder);
- }
- }
- if (error == 0) {
- name.Assign(deviceName);
- uniqueId.Assign(deviceUniqueId);
- }
+ InvokeAsync(mVideoCaptureThread, __func__,
+ [this, self = RefPtr(this), aCapEngine, aDeviceIndex] {
+ char deviceName[MediaEngineSource::kMaxDeviceNameLength];
+ char deviceUniqueId[MediaEngineSource::kMaxUniqueIdLength];
+ nsCString name;
+ nsCString uniqueId;
+ pid_t devicePid = 0;
+ bool placeholder = false;
+ int error = -1;
+ if (auto devInfo = GetDeviceInfo(aCapEngine)) {
+ error = devInfo->GetDeviceName(
+ aDeviceIndex, deviceName, sizeof(deviceName),
+ deviceUniqueId, sizeof(deviceUniqueId), nullptr, 0,
+ &devicePid, &placeholder);
+ }
- return Promise::CreateAndResolve(
- std::make_tuple(std::move(name), std::move(uniqueId), devicePid,
- placeholder, error),
- "CamerasParent::RecvGetCaptureDevice");
- })
+ if (error == 0) {
+ name.Assign(deviceName);
+ uniqueId.Assign(deviceUniqueId);
+ }
+
+ return Promise::CreateAndResolve(
+ std::make_tuple(std::move(name), std::move(uniqueId),
+ devicePid, placeholder, error),
+ "CamerasParent::RecvGetCaptureDevice");
+ })
->Then(
mPBackgroundEventTarget, __func__,
[this, self = RefPtr(this)](Promise::ResolveOrRejectValue&& aValue) {
diff --git a/dom/media/systemservices/CamerasParent.h b/dom/media/systemservices/CamerasParent.h
index 9d6a6f2f35..11a5229629 100644
--- a/dom/media/systemservices/CamerasParent.h
+++ b/dom/media/systemservices/CamerasParent.h
@@ -144,6 +144,11 @@ class CamerasParent final : public PCamerasParent,
// VideoInputFeedBack
void OnDeviceChange() override;
+ // Creates a new DeviceInfo or returns an existing DeviceInfo for given
+ // capture engine. Returns a nullptr in case capture engine failed to be
+ // initialized. Video capture thread only.
+ std::shared_ptr<webrtc::VideoCaptureModule::DeviceInfo> GetDeviceInfo(
+ int aEngine);
VideoEngine* EnsureInitialized(int aEngine);
// Stops any ongoing capturing and releases resources. Called on
diff --git a/dom/media/systemservices/VideoEngine.cpp b/dom/media/systemservices/VideoEngine.cpp
index d03149e3ac..ec4657d755 100644
--- a/dom/media/systemservices/VideoEngine.cpp
+++ b/dom/media/systemservices/VideoEngine.cpp
@@ -112,7 +112,8 @@ int VideoEngine::ReleaseVideoCapture(const int32_t aId) {
}
std::shared_ptr<webrtc::VideoCaptureModule::DeviceInfo>
-VideoEngine::GetOrCreateVideoCaptureDeviceInfo() {
+VideoEngine::GetOrCreateVideoCaptureDeviceInfo(
+ webrtc::VideoInputFeedBack* callBack) {
LOG(("%s", __PRETTY_FUNCTION__));
webrtc::Timestamp currentTime = webrtc::Timestamp::Micros(0);
@@ -157,6 +158,10 @@ VideoEngine::GetOrCreateVideoCaptureDeviceInfo() {
mDeviceInfo =
mVideoCaptureFactory->CreateDeviceInfo(mId, mCaptureDevInfo.type);
+ if (mDeviceInfo && mCaptureDevInfo.type == CaptureDeviceType::Camera) {
+ mDeviceInfo->RegisterVideoInputFeedBack(callBack);
+ }
+
LOG(("EXIT %s", __PRETTY_FUNCTION__));
return mDeviceInfo;
}
diff --git a/dom/media/systemservices/VideoEngine.h b/dom/media/systemservices/VideoEngine.h
index 588be92c27..289a1ab181 100644
--- a/dom/media/systemservices/VideoEngine.h
+++ b/dom/media/systemservices/VideoEngine.h
@@ -88,7 +88,7 @@ class VideoEngine {
* @see bug 1305212 https://bugzilla.mozilla.org/show_bug.cgi?id=1305212
*/
std::shared_ptr<webrtc::VideoCaptureModule::DeviceInfo>
- GetOrCreateVideoCaptureDeviceInfo();
+ GetOrCreateVideoCaptureDeviceInfo(webrtc::VideoInputFeedBack* callBack);
/**
* Destroys existing DeviceInfo.

View File

@ -0,0 +1,36 @@
From 7dd135852be020d5755af42fa45470df259ba945 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 4 Sep 2024 13:43:40 +0000
Subject: [PATCH] Bug 1830275 - WebRTC backport: PipeWire camera: make member
variable with the PipeWire status updated r=pehrsons,webrtc-reviewers
We keep information about the PipeWire camera status as a member of the
PipeWire session, but it's never updated and remains in uninitialized
state. Make sure it gets updated once PipeWire is initialized or when it
fails. There is currently no use for this member variable, but there is
a plan to use it so I'm rather keeping it instead of removing it.
This is a simple backport of an WebRTC upstream change.
Upstream commit: 3881cb65cfcec90b6f0a56ce7223a471aa0115f2
Differential Revision: https://phabricator.services.mozilla.com/D220895
---
.../libwebrtc/modules/video_capture/linux/pipewire_session.cc | 2 ++
.../libwebrtc/moz-patch-stack/3881cb65cf.no-op-cherry-pick-msg | 1 +
2 files changed, 3 insertions(+)
create mode 100644 third_party/libwebrtc/moz-patch-stack/3881cb65cf.no-op-cherry-pick-msg
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
index dbac09274bb31..ac12d0437290e 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
@@ -415,6 +415,8 @@ void PipeWireSession::OnRegistryGlobalRemove(void* data, uint32_t id) {
}
void PipeWireSession::Finish(VideoCaptureOptions::Status status) {
+ status_ = status;
+
webrtc::MutexLock lock(&callback_lock_);
if (callback_) {

View File

@ -0,0 +1,190 @@
From a4eb4517f2bdeb6591c05a09109b4b543b83fef1 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Thu, 5 Sep 2024 16:04:48 +0000
Subject: [PATCH] Bug 1830275 - Add missing support for device change
notifications r=pehrsons,webrtc-reviewers
Registers each DeviceInfoPipeWire in PipeWireSession we use and calls
DeviceChange() for each once there is a new camera added or removed to
invoke OnDeviceChange() for every registered VideoInputFeedback.
Differential Revision: https://phabricator.services.mozilla.com/D219218
---
.../linux/device_info_pipewire.cc | 10 +++-
.../video_capture/linux/pipewire_session.cc | 47 ++++++++++++++++++-
.../video_capture/linux/pipewire_session.h | 26 +++++++++-
3 files changed, 79 insertions(+), 4 deletions(-)
diff --git a/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc b/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc
index db2a3c7099..a0607b4aba 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc
+++ b/third_party/libwebrtc/modules/video_capture/linux/device_info_pipewire.cc
@@ -29,13 +29,19 @@
namespace webrtc {
namespace videocapturemodule {
DeviceInfoPipeWire::DeviceInfoPipeWire(VideoCaptureOptions* options)
- : DeviceInfoImpl(), pipewire_session_(options->pipewire_session()) {}
+ : DeviceInfoImpl(), pipewire_session_(options->pipewire_session()) {
+ const bool ret = pipewire_session_->RegisterDeviceInfo(this);
+ RTC_CHECK(ret);
+}
int32_t DeviceInfoPipeWire::Init() {
return 0;
}
-DeviceInfoPipeWire::~DeviceInfoPipeWire() = default;
+DeviceInfoPipeWire::~DeviceInfoPipeWire() {
+ const bool ret = pipewire_session_->DeRegisterDeviceInfo(this);
+ RTC_CHECK(ret);
+}
uint32_t DeviceInfoPipeWire::NumberOfDevices() {
RTC_CHECK(pipewire_session_);
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
index ac12d04372..0b78c16df2 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
@@ -9,6 +9,7 @@
*/
#include "modules/video_capture/linux/pipewire_session.h"
+#include "modules/video_capture/linux/device_info_pipewire.h"
#include <spa/monitor/device.h>
#include <spa/param/format-utils.h>
@@ -274,6 +275,28 @@ void PipeWireSession::InitPipeWire(int fd) {
Finish(VideoCaptureOptions::Status::ERROR);
}
+bool PipeWireSession::RegisterDeviceInfo(DeviceInfoPipeWire* device_info) {
+ RTC_CHECK(device_info);
+ MutexLock lock(&device_info_lock_);
+ auto it = std::find(device_info_list_.begin(), device_info_list_.end(), device_info);
+ if (it == device_info_list_.end()) {
+ device_info_list_.push_back(device_info);
+ return true;
+ }
+ return false;
+}
+
+bool PipeWireSession::DeRegisterDeviceInfo(DeviceInfoPipeWire* device_info) {
+ RTC_CHECK(device_info);
+ MutexLock lock(&device_info_lock_);
+ auto it = std::find(device_info_list_.begin(), device_info_list_.end(), device_info);
+ if (it != device_info_list_.end()) {
+ device_info_list_.erase(it);
+ return true;
+ }
+ return false;
+}
+
bool PipeWireSession::StartPipeWire(int fd) {
pw_init(/*argc=*/nullptr, /*argv=*/nullptr);
@@ -344,6 +367,21 @@ void PipeWireSession::PipeWireSync() {
sync_seq_ = pw_core_sync(pw_core_, PW_ID_CORE, sync_seq_);
}
+void PipeWireSession::NotifyDeviceChange() {
+ RTC_LOG(LS_INFO) << "Notify about device list changes";
+ MutexLock lock(&device_info_lock_);
+
+ // It makes sense to notify about device changes only once we are
+ // properly initialized.
+ if (status_ != VideoCaptureOptions::Status::SUCCESS) {
+ return;
+ }
+
+ for (auto* deviceInfo : device_info_list_) {
+ deviceInfo->DeviceChange();
+ }
+}
+
// static
void PipeWireSession::OnCoreError(void* data,
uint32_t id,
@@ -401,6 +439,8 @@ void PipeWireSession::OnRegistryGlobal(void* data,
that->nodes_.push_back(PipeWireNode::Create(that, id, props));
that->PipeWireSync();
+
+ that->NotifyDeviceChange();
}
// static
@@ -412,10 +452,15 @@ void PipeWireSession::OnRegistryGlobalRemove(void* data, uint32_t id) {
return node->id() == id;
});
that->nodes_.erase(it, that->nodes_.end());
+
+ that->NotifyDeviceChange();
}
void PipeWireSession::Finish(VideoCaptureOptions::Status status) {
- status_ = status;
+ {
+ MutexLock lock(&device_info_lock_);
+ status_ = status;
+ }
webrtc::MutexLock lock(&callback_lock_);
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h
index 84273ea695..1f3a00614f 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.h
@@ -29,6 +29,7 @@
namespace webrtc {
namespace videocapturemodule {
+class DeviceInfoPipeWire;
class PipeWireSession;
class VideoCaptureModulePipeWire;
@@ -97,6 +98,21 @@ class PipeWireSession : public rtc::RefCountedNonVirtual<PipeWireSession> {
void Init(VideoCaptureOptions::Callback* callback,
int fd = kInvalidPipeWireFd);
+
+ // [De]Register DeviceInfo for device change updates
+ // These methods will add or remove references to DeviceInfo
+ // objects that we want to notify about device changes.
+ // NOTE: We do not take ownership of these objects and
+ // they should never be released by us. All the instances
+ // of DeviceInfoPipeWire must outlive their registration.
+
+ // Returns true when DeviceInfo was successfuly registered
+ // or false otherwise, when it was already registered before.
+ bool RegisterDeviceInfo(DeviceInfoPipeWire* device_info);
+ // Returns true when DeviceInfo was successfuly unregistered
+ // or false otherwise, when it was not previously registered.
+ bool DeRegisterDeviceInfo(DeviceInfoPipeWire* device_info);
+
const std::deque<PipeWireNode::PipeWireNodePtr>& nodes() const {
return nodes_;
}
@@ -111,6 +127,8 @@ class PipeWireSession : public rtc::RefCountedNonVirtual<PipeWireSession> {
void StopPipeWire();
void PipeWireSync();
+ void NotifyDeviceChange();
+
static void OnCoreError(void* data,
uint32_t id,
int seq,
@@ -133,7 +151,13 @@ class PipeWireSession : public rtc::RefCountedNonVirtual<PipeWireSession> {
VideoCaptureOptions::Callback* callback_ RTC_GUARDED_BY(&callback_lock_) =
nullptr;
- VideoCaptureOptions::Status status_;
+ webrtc::Mutex device_info_lock_;
+ std::vector<DeviceInfoPipeWire*> device_info_list_
+ RTC_GUARDED_BY(device_info_lock_);
+ // Guard with device_info_lock, because currently it's the only place where
+ // we use this status information.
+ VideoCaptureOptions::Status status_
+ RTC_GUARDED_BY(device_info_lock_);
struct pw_thread_loop* pw_main_loop_ = nullptr;
struct pw_context* pw_context_ = nullptr;

View File

@ -0,0 +1,52 @@
From 9d035f728745f13311ed13d057565ca3b45523aa Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Tue, 24 Sep 2024 11:20:02 +0000
Subject: [PATCH] Bug 1920460 - WebRTC backport: PipeWire camera: get max FPS
for each format when specified as list r=pehrsons,webrtc-reviewers
In many cases, the framerate can be specified as list of possible values
and in that case, we would end up with max FPS to be set to 0 as this
case was not handled.
This is a simple backport of an WebRTC upstream change.
Upstream commit: 3aa47cfd30dc965446cf1405bb062b756a62e6d1
Differential Revision: https://phabricator.services.mozilla.com/D223112
---
.../modules/video_capture/linux/pipewire_session.cc | 12 ++++++++++--
.../moz-patch-stack/3aa47cfd30.no-op-cherry-pick-msg | 1 +
2 files changed, 11 insertions(+), 2 deletions(-)
create mode 100644 third_party/libwebrtc/moz-patch-stack/3aa47cfd30.no-op-cherry-pick-msg
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
index d9bc49d521b03..e5db278ff6a99 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
@@ -17,6 +17,8 @@
#include <spa/param/video/raw.h>
#include <spa/pod/parser.h>
+#include <algorithm>
+
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "modules/video_capture/device_info_impl.h"
#include "rtc_base/logging.h"
@@ -152,9 +154,15 @@ void PipeWireNode::OnNodeParam(void* data,
fract = static_cast<spa_fraction*>(SPA_POD_BODY(val));
- if (choice == SPA_CHOICE_None)
+ if (choice == SPA_CHOICE_None) {
cap.maxFPS = 1.0 * fract[0].num / fract[0].denom;
- else if (choice == SPA_CHOICE_Range && fract[1].num > 0)
+ } else if (choice == SPA_CHOICE_Enum) {
+ for (uint32_t i = 1; i < n_items; i++) {
+ cap.maxFPS = std::max(
+ static_cast<int32_t>(1.0 * fract[i].num / fract[i].denom),
+ cap.maxFPS);
+ }
+ } else if (choice == SPA_CHOICE_Range && fract[1].num > 0)
cap.maxFPS = 1.0 * fract[1].num / fract[1].denom;
}
}

View File

@ -0,0 +1,172 @@
From ca88b4994e140370ca5795c60f46559301458a98 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Wed, 25 Sep 2024 06:52:35 +0000
Subject: [PATCH] Bug 1920472 - WebRTC backport: PipeWire camera: use exact
stream parameters specified by capability r=pehrsons,webrtc-reviewers
We currently specify stream parameters to be a range for both framerate
and resolution, where preferred value is specified. The preferred value
doesn't seem to be taken into account and we end up accepting resolution
from 1x1 to MAX_INTxMAX_INT. In case the other side tries to first match
with lower resolution than requested, we will happily match it and start
streaming low quality video. We should instead request the exact stream
parameters as specified by requested capability. This capability always
come from what has been originally reported as supported so it shouldn't
happen we don't find a matching stream. This also applies to requested
video format. We previously requested mjpg for streams with resolution
higher than 640x480, but it doesn't necessarily mean the camera supports
mjpg for the requested resolution. Again, refer to requested capability
in this case as it should indicate what is supported and we know we can
request exactly the same video format. It can happen that framerate is
set to 0 as unspecified. In that case keep using a range as before, but
with more sane values.
This is a simple backport of an WebRTC upstream change.
Upstream commit: 9703f8474f156e08e4a96dc36253f1cdccd549e1
Differential Revision: https://phabricator.services.mozilla.com/D223119
---
.../linux/video_capture_pipewire.cc | 85 +++++++++++--------
.../linux/video_capture_pipewire.h | 1 +
.../9703f8474f.no-op-cherry-pick-msg | 1 +
3 files changed, 52 insertions(+), 35 deletions(-)
create mode 100644 third_party/libwebrtc/moz-patch-stack/9703f8474f.no-op-cherry-pick-msg
diff --git a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
index 1672b7583f..2338fa6d87 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
+++ b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
@@ -51,10 +51,20 @@ VideoType VideoCaptureModulePipeWire::PipeWireRawFormatToVideoType(
if (spa_and_pixel_format.spa_format == spa_format)
return spa_and_pixel_format.video_type;
}
- RTC_LOG(LS_INFO) << "Unsupported pixel format: " << spa_format;
+ RTC_LOG(LS_WARNING) << "Unsupported pixel format: " << spa_format;
return VideoType::kUnknown;
}
+uint32_t VideoCaptureModulePipeWire::VideoTypeToPipeWireRawFormat(
+ VideoType type) {
+ for (const auto& spa_and_pixel_format : kSupportedFormats) {
+ if (spa_and_pixel_format.video_type == type)
+ return spa_and_pixel_format.spa_format;
+ }
+ RTC_LOG(LS_WARNING) << "Unsupported video type: " << static_cast<int>(type);
+ return SPA_VIDEO_FORMAT_UNKNOWN;
+}
+
VideoCaptureModulePipeWire::VideoCaptureModulePipeWire(
VideoCaptureOptions* options)
: VideoCaptureImpl(),
@@ -87,45 +97,53 @@ int32_t VideoCaptureModulePipeWire::Init(const char* deviceUniqueId) {
}
static spa_pod* BuildFormat(spa_pod_builder* builder,
- uint32_t format,
+ VideoType video_type,
uint32_t width,
uint32_t height,
float frame_rate) {
- spa_pod_frame frames[2];
+ spa_pod_frame frame;
+
+ const uint32_t media_subtype = video_type == VideoType::kMJPEG
+ ? SPA_MEDIA_SUBTYPE_mjpg
+ : SPA_MEDIA_SUBTYPE_raw;
- spa_pod_builder_push_object(builder, &frames[0], SPA_TYPE_OBJECT_Format,
+ spa_pod_builder_push_object(builder, &frame, SPA_TYPE_OBJECT_Format,
SPA_PARAM_EnumFormat);
spa_pod_builder_add(builder, SPA_FORMAT_mediaType,
SPA_POD_Id(SPA_MEDIA_TYPE_video), SPA_FORMAT_mediaSubtype,
- SPA_POD_Id(format), 0);
-
- if (format == SPA_MEDIA_SUBTYPE_raw) {
- spa_pod_builder_prop(builder, SPA_FORMAT_VIDEO_format, 0);
- spa_pod_builder_push_choice(builder, &frames[1], SPA_CHOICE_Enum, 0);
- spa_pod_builder_id(builder, kSupportedFormats[0].spa_format);
- for (const auto& spa_and_pixel_format : kSupportedFormats)
- spa_pod_builder_id(builder, spa_and_pixel_format.spa_format);
- spa_pod_builder_pop(builder, &frames[1]);
- }
+ SPA_POD_Id(media_subtype), 0);
- spa_rectangle preferred_size = spa_rectangle{width, height};
- spa_rectangle min_size = spa_rectangle{1, 1};
- spa_rectangle max_size = spa_rectangle{4096, 4096};
- spa_pod_builder_add(
- builder, SPA_FORMAT_VIDEO_size,
- SPA_POD_CHOICE_RANGE_Rectangle(&preferred_size, &min_size, &max_size), 0);
+ if (media_subtype == SPA_MEDIA_SUBTYPE_raw) {
+ const uint32_t format =
+ VideoCaptureModulePipeWire::VideoTypeToPipeWireRawFormat(video_type);
+ RTC_CHECK(format != SPA_VIDEO_FORMAT_UNKNOWN);
+ spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_format, SPA_POD_Id(format),
+ 0);
+ }
- spa_fraction preferred_frame_rate =
- spa_fraction{static_cast<uint32_t>(frame_rate), 1};
- spa_fraction min_frame_rate = spa_fraction{0, 1};
- spa_fraction max_frame_rate = spa_fraction{INT32_MAX, 1};
- spa_pod_builder_add(
- builder, SPA_FORMAT_VIDEO_framerate,
- SPA_POD_CHOICE_RANGE_Fraction(&preferred_frame_rate, &min_frame_rate,
- &max_frame_rate),
- 0);
+ spa_rectangle resolution = spa_rectangle{width, height};
+ spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_size,
+ SPA_POD_Rectangle(&resolution), 0);
+
+ // Framerate can be also set to 0 to be unspecified
+ if (frame_rate) {
+ spa_fraction framerate = spa_fraction{static_cast<uint32_t>(frame_rate), 1};
+ spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_framerate,
+ SPA_POD_Fraction(&framerate), 0);
+ } else {
+ // Default to some reasonable values
+ spa_fraction preferred_frame_rate =
+ spa_fraction{static_cast<uint32_t>(30), 1};
+ spa_fraction min_frame_rate = spa_fraction{1, 1};
+ spa_fraction max_frame_rate = spa_fraction{30, 1};
+ spa_pod_builder_add(
+ builder, SPA_FORMAT_VIDEO_framerate,
+ SPA_POD_CHOICE_RANGE_Fraction(&preferred_frame_rate, &min_frame_rate,
+ &max_frame_rate),
+ 0);
+ }
- return static_cast<spa_pod*>(spa_pod_builder_pop(builder, &frames[0]));
+ return static_cast<spa_pod*>(spa_pod_builder_pop(builder, &frame));
}
int32_t VideoCaptureModulePipeWire::StartCapture(
@@ -176,13 +194,10 @@ int32_t VideoCaptureModulePipeWire::StartCapture(
uint32_t width = capability.width;
uint32_t height = capability.height;
uint32_t frame_rate = capability.maxFPS;
- bool prefer_jpeg = (width > 640) || (height > 480);
+ VideoType video_type = capability.videoType;
params.push_back(
- BuildFormat(&builder, SPA_MEDIA_SUBTYPE_raw, width, height, frame_rate));
- params.insert(
- prefer_jpeg ? params.begin() : params.end(),
- BuildFormat(&builder, SPA_MEDIA_SUBTYPE_mjpg, width, height, frame_rate));
+ BuildFormat(&builder, video_type, width, height, frame_rate));
int res = pw_stream_connect(
stream_, PW_DIRECTION_INPUT, node_id_,
diff --git a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.h b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.h
index eeb3b9497c..789f2034d3 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.h
+++ b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.h
@@ -28,6 +28,7 @@ class VideoCaptureModulePipeWire : public VideoCaptureImpl {
int32_t CaptureSettings(VideoCaptureCapability& settings) override;
static VideoType PipeWireRawFormatToVideoType(uint32_t format);
+ static uint32_t VideoTypeToPipeWireRawFormat(VideoType type);
private:
static void OnStreamParamChanged(void* data,

View File

@ -0,0 +1,61 @@
From 12b7d28d858fdcfa80795a2af49a71d3b5142733 Mon Sep 17 00:00:00 2001
From: Jan Grulich <grulja@gmail.com>
Date: Tue, 12 Nov 2024 12:28:19 +0000
Subject: [PATCH] Bug 1930598 - WebRTC backport: PipeWire camera: use better
unique device name for camera devices r=pehrsons,webrtc-reviewers
Originally we used node id from PipeWire as an unique device name and
while this works, it will change everytime PipeWire is restarted. This
has an impact on default camera selection, where for example Firefox can
automatically request a camera device that was used before, but this can
break with the next PipeWire restart.
This is a simple backport of an WebRTC upstream change.
Upstream commit: a5d71009ac1dce7da23813dc9413c03073cfa8ca
Differential Revision: https://phabricator.services.mozilla.com/D228635
---
.../modules/video_capture/linux/pipewire_session.cc | 2 +-
.../video_capture/linux/video_capture_pipewire.cc | 11 +++++++----
.../moz-patch-stack/a5d71009ac.no-op-cherry-pick-msg | 1 +
3 files changed, 9 insertions(+), 5 deletions(-)
create mode 100644 third_party/libwebrtc/moz-patch-stack/a5d71009ac.no-op-cherry-pick-msg
diff --git a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
index 641e5238ea..dd187c0358 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
+++ b/third_party/libwebrtc/modules/video_capture/linux/pipewire_session.cc
@@ -74,7 +74,7 @@ PipeWireNode::PipeWireNode(PipeWireSession* session,
: session_(session),
id_(id),
display_name_(spa_dict_lookup(props, PW_KEY_NODE_DESCRIPTION)),
- unique_id_(rtc::ToString(id)) {
+ unique_id_(spa_dict_lookup(props, PW_KEY_NODE_NAME)) {
RTC_LOG(LS_VERBOSE) << "Found Camera: " << display_name_;
proxy_ = static_cast<pw_proxy*>(pw_registry_bind(
diff --git a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
index 2338fa6d87..888b8f386f 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
+++ b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
@@ -82,12 +82,15 @@ int32_t VideoCaptureModulePipeWire::Init(const char* deviceUniqueId) {
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
RTC_DCHECK_RUN_ON(&api_checker_);
- absl::optional<int> id;
- id = rtc::StringToNumber<int>(deviceUniqueId);
- if (id == absl::nullopt)
+ auto node =
+ std::find_if(session_->nodes_.begin(), session_->nodes_.end(),
+ [deviceUniqueId](const PipeWireNode::PipeWireNodePtr& node) {
+ return node->unique_id() == deviceUniqueId;
+ });
+ if (node == session_->nodes_.end())
return -1;
- node_id_ = id.value();
+ node_id_ = (*node)->id();
const int len = strlen(deviceUniqueId);
_deviceUniqueId = new (std::nothrow) char[len + 1];

View File

@ -0,0 +1,50 @@
diff --git a/dom/media/webrtc/transport/nricectx.cpp b/dom/media/webrtc/transport/nricectx.cpp
--- a/dom/media/webrtc/transport/nricectx.cpp
+++ b/dom/media/webrtc/transport/nricectx.cpp
@@ -124,23 +124,30 @@
static int nr_crypto_nss_hmac(UCHAR* key, size_t keyl, UCHAR* buf, size_t bufl,
UCHAR* result) {
CK_MECHANISM_TYPE mech = CKM_SHA_1_HMAC;
PK11SlotInfo* slot = nullptr;
MOZ_ASSERT(keyl > 0);
- SECItem keyi = {siBuffer, key, static_cast<unsigned int>(keyl)};
+ CK_KEY_DERIVATION_STRING_DATA idkey = {key, keyl};
+ SECItem keyi = {siBuffer, (unsigned char*)&idkey, sizeof(idkey)};
+ PK11SymKey* tmpKey = nullptr;
PK11SymKey* skey = nullptr;
PK11Context* hmac_ctx = nullptr;
SECStatus status;
unsigned int hmac_len;
SECItem param = {siBuffer, nullptr, 0};
int err = R_INTERNAL;
slot = PK11_GetInternalKeySlot();
if (!slot) goto abort;
- skey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_SIGN, &keyi,
- nullptr);
+ // HMAC is used for hash calculation only so use derive instead of import
+ // to be FIPS compliant.
+ tmpKey = PK11_KeyGen(slot, mech, NULL, keyl, nullptr);
+ if (!tmpKey) goto abort;
+
+ skey = PK11_Derive(tmpKey, CKM_CONCATENATE_DATA_AND_BASE, &keyi, mech,
+ CKA_SIGN, keyl);
if (!skey) goto abort;
hmac_ctx = PK11_CreateContextBySymKey(mech, CKA_SIGN, skey, &param);
if (!hmac_ctx) goto abort;
@@ -157,10 +164,11 @@
err = 0;
abort:
if (hmac_ctx) PK11_DestroyContext(hmac_ctx, PR_TRUE);
+ if (tmpKey) PK11_FreeSymKey(tmpKey);
if (skey) PK11_FreeSymKey(skey);
if (slot) PK11_FreeSlot(slot);
return err;
}

View File

@ -0,0 +1,224 @@
diff --git a/third_party/libsrtp/src/crypto/cipher/aes_gcm_nss.c b/third_party/libsrtp/src/crypto/cipher/aes_gcm_nss.c
--- a/third_party/libsrtp/src/crypto/cipher/aes_gcm_nss.c
+++ b/third_party/libsrtp/src/crypto/cipher/aes_gcm_nss.c
@@ -54,10 +54,11 @@
#include "crypto_types.h"
#include "cipher_types.h"
#include "cipher_test_cases.h"
#include <secerr.h>
#include <nspr.h>
+#include "nss_fips.h"
srtp_debug_module_t srtp_mod_aes_gcm = {
0, /* debugging is off by default */
"aes gcm nss" /* printable module name */
};
@@ -211,12 +212,17 @@
if (!slot) {
return (srtp_err_status_cipher_fail);
}
SECItem key_item = { siBuffer, (unsigned char *)key, c->key_size };
- c->key = PK11_ImportSymKey(slot, CKM_AES_GCM, PK11_OriginUnwrap,
- CKA_ENCRYPT, &key_item, NULL);
+ if (PK11_IsFIPS()) {
+ c->key = PK11_ImportSymKey_FIPS(slot, CKM_AES_GCM, PK11_OriginUnwrap,
+ CKA_ENCRYPT, &key_item, NULL);
+ } else {
+ c->key = PK11_ImportSymKey(slot, CKM_AES_GCM, PK11_OriginUnwrap,
+ CKA_ENCRYPT, &key_item, NULL);
+ }
PK11_FreeSlot(slot);
if (!c->key) {
return (srtp_err_status_cipher_fail);
}
diff --git a/third_party/libsrtp/src/crypto/cipher/aes_icm_nss.c b/third_party/libsrtp/src/crypto/cipher/aes_icm_nss.c
--- a/third_party/libsrtp/src/crypto/cipher/aes_icm_nss.c
+++ b/third_party/libsrtp/src/crypto/cipher/aes_icm_nss.c
@@ -51,10 +51,11 @@
#include "crypto_types.h"
#include "err.h" /* for srtp_debug */
#include "alloc.h"
#include "cipher_types.h"
#include "cipher_test_cases.h"
+#include "nss_fips.h"
srtp_debug_module_t srtp_mod_aes_icm = {
0, /* debugging is off by default */
"aes icm nss" /* printable module name */
};
@@ -252,12 +253,17 @@
if (!slot) {
return srtp_err_status_bad_param;
}
SECItem keyItem = { siBuffer, (unsigned char *)key, c->key_size };
- c->key = PK11_ImportSymKey(slot, CKM_AES_CTR, PK11_OriginUnwrap,
- CKA_ENCRYPT, &keyItem, NULL);
+ if (PK11_IsFIPS()) {
+ c->key = PK11_ImportSymKey_FIPS(slot, CKM_AES_CTR, PK11_OriginUnwrap,
+ CKA_ENCRYPT, &keyItem, NULL);
+ } else {
+ c->key = PK11_ImportSymKey(slot, CKM_AES_CTR, PK11_OriginUnwrap,
+ CKA_ENCRYPT, &keyItem, NULL);
+ }
PK11_FreeSlot(slot);
if (!c->key) {
return srtp_err_status_cipher_fail;
}
diff --git a/third_party/libsrtp/src/crypto/include/nss_fips.h b/third_party/libsrtp/src/crypto/include/nss_fips.h
new file mode 100644
--- /dev/null
+++ b/third_party/libsrtp/src/crypto/include/nss_fips.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2024, Red Hat, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Red Hat, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ Adapted from Red Hat Ceph patch by
+ Radoslaw Zarzynski <rzarzyns@redhat.com>
+
+ PK11_ImportSymKey() is a part of NSS API that becomes unavailable
+ in the FIPS mode. Apparently NSS targets stricter restrictions
+ than those coming from Level 1 of FIPS 140-2. In the consequence,
+ loading a symmetric key from plain keyring or key db fails.
+
+ A raw crypto key is in-memory wrapped with fresh, random wrapping
+ key just before being imported via PK11_UnwrapSymKey(). Of course,
+ this effectively lowers to FIPS level 1. Still, this would be no
+ different from what OpenSSL gives in the matter.
+*/
+
+#ifndef NSS_FIPS_H
+#define NSS_FIPS_H
+
+static PK11SymKey *PK11_ImportSymKey_FIPS(
+ PK11SlotInfo * const slot,
+ const CK_MECHANISM_TYPE type,
+ const PK11Origin origin,
+ const CK_ATTRIBUTE_TYPE operation,
+ SECItem * const raw_key,
+ void * const wincx)
+{
+ PK11SymKey* wrapping_key = NULL;
+ PK11Context *wrap_key_crypt_context = NULL;
+ SECItem *raw_key_aligned = NULL;
+ CK_MECHANISM_TYPE wrap_mechanism = 0;
+
+ struct {
+ unsigned char data[256];
+ int len;
+ } wrapped_key;
+
+ #define SCOPE_DATA_FREE() \
+ { \
+ PK11_FreeSymKey(wrapping_key); \
+ PK11_DestroyContext(wrap_key_crypt_context, PR_TRUE); \
+ SECITEM_FreeItem(raw_key_aligned, PR_TRUE); \
+ }
+
+ if(raw_key->len > sizeof(wrapped_key.data)) {
+ return NULL;
+ }
+
+ // getting 306 on my system which is CKM_DES3_ECB.
+ wrap_mechanism = PK11_GetBestWrapMechanism(slot);
+
+ // Generate a wrapping key. It will be used exactly twice over the scope:
+ // * to encrypt raw_key giving wrapped_key,
+ // * to decrypt wrapped_key in the internals of PK11_UnwrapSymKey().
+ wrapping_key = PK11_KeyGen(slot, wrap_mechanism, NULL,
+ PK11_GetBestKeyLength(slot, wrap_mechanism), NULL);
+ if (wrapping_key == NULL) {
+ return NULL;
+ }
+
+ // Prepare a PK11 context for the raw_key -> wrapped_key encryption.
+ SECItem tmp_sec_item;
+ memset(&tmp_sec_item, 0, sizeof(tmp_sec_item));
+ wrap_key_crypt_context = PK11_CreateContextBySymKey(
+ wrap_mechanism,
+ CKA_ENCRYPT,
+ wrapping_key,
+ &tmp_sec_item);
+ if (wrap_key_crypt_context == NULL) {
+ SCOPE_DATA_FREE();
+ return NULL;
+ }
+
+ // Finally wrap the key. Important note is that the wrapping mechanism
+ // selection (read: just grabbing a cipher) offers, at least in my NSS
+ // copy, mostly CKM_*_ECB ciphers (with 3DES as the leading one, see
+ // wrapMechanismList[] in pk11mech.c). There is no CKM_*_*_PAD variant
+ // which means that plaintext we are providing to PK11_CipherOp() must
+ // be aligned to cipher's block size. For 3DES it's 64 bits.
+ raw_key_aligned = PK11_BlockData(raw_key, PK11_GetBlockSize(wrap_mechanism, NULL));
+ if (raw_key_aligned == NULL) {
+ SCOPE_DATA_FREE();
+ return NULL;
+ }
+
+ if (PK11_CipherOp(wrap_key_crypt_context, wrapped_key.data, &wrapped_key.len,
+ sizeof(wrapped_key.data), raw_key_aligned->data,
+ raw_key_aligned->len) != SECSuccess) {
+ SCOPE_DATA_FREE();
+ return NULL;
+ }
+
+ if (PK11_Finalize(wrap_key_crypt_context) != SECSuccess) {
+ SCOPE_DATA_FREE();
+ return NULL;
+ }
+
+ // Key is wrapped now so we can acquire the ultimate PK11SymKey through
+ // unwrapping it. Of course these two opposite operations form NOP with
+ // a side effect: FIPS level 1 compatibility.
+ memset(&tmp_sec_item, 0, sizeof(tmp_sec_item));
+
+ SECItem wrapped_key_item;
+ memset(&wrapped_key_item, 0, sizeof(wrapped_key_item));
+ wrapped_key_item.data = wrapped_key.data;
+ wrapped_key_item.len = wrapped_key.len;
+
+ PK11SymKey *ret = PK11_UnwrapSymKey(wrapping_key, wrap_mechanism,
+ &tmp_sec_item, &wrapped_key_item, type,
+ operation, raw_key->len);
+ SCOPE_DATA_FREE();
+ return ret;
+ }
+
+#endif // NSS_FIPS_H

View File

@ -1,9 +0,0 @@
[Global]
id=almalinux
version=1.0
about=Mozilla Firefox for AlmaLinux
[Preferences]
app.distributor=almalinux
app.distributor.channel=almalinux
app.partner.fedora=almalinux

View File

@ -0,0 +1,9 @@
[Global]
id=__ID__
version=1.0
about=Mozilla Firefox for __NAME__
[Preferences]
app.distributor=__ID__
app.distributor.channel=__ID__
app.partner.__ID__=__ID__

View File

@ -12,9 +12,7 @@ ac_add_options --enable-official-branding
ac_add_options --enable-pulseaudio ac_add_options --enable-pulseaudio
ac_add_options --enable-release ac_add_options --enable-release
ac_add_options --enable-system-ffi ac_add_options --enable-system-ffi
ac_add_options --without-sysroot
ac_add_options --without-system-icu ac_add_options --without-system-icu
ac_add_options --without-wasm-sandboxed-libraries
ac_add_options --with-system-jpeg ac_add_options --with-system-jpeg
ac_add_options --with-system-zlib ac_add_options --with-system-zlib
ac_add_options --with-unsigned-addon-scopes=app,system ac_add_options --with-unsigned-addon-scopes=app,system

File diff suppressed because one or more lines are too long

12
SOURCES/wasi.patch Normal file
View File

@ -0,0 +1,12 @@
diff -up firefox-121.0.1/toolkit/moz.configure.wasi firefox-121.0.1/toolkit/moz.configure
--- firefox-121.0.1/toolkit/moz.configure.wasi 2024-02-01 09:14:33.816548952 +0100
+++ firefox-121.0.1/toolkit/moz.configure 2024-02-01 09:15:53.264684309 +0100
@@ -2663,7 +2663,7 @@ with only_when(requires_wasm_sandboxing
def wasi_sysroot_flags(wasi_sysroot):
if wasi_sysroot:
log.info("Using wasi sysroot in %s", wasi_sysroot)
- return ["--sysroot=%s" % wasi_sysroot]
+ return ["--sysroot=%s" % wasi_sysroot, "-nodefaultlibs", "-lc", "-lwasi-emulated-process-clocks", "-lc++", "-lc++abi", "/home/jhorak/rpmbuild/BUILDROOT/usr/share/wasi-sysroot/lib/libclang_rt.builtins-wasm32.a"]
return []
set_config("WASI_SYSROOT", wasi_sysroot)

View File

@ -0,0 +1,12 @@
diff -up firefox-121.0.1/toolkit/moz.configure.wasi firefox-121.0.1/toolkit/moz.configure
--- firefox-121.0.1/toolkit/moz.configure.wasi 2024-02-01 09:14:33.816548952 +0100
+++ firefox-121.0.1/toolkit/moz.configure 2024-02-01 09:15:53.264684309 +0100
@@ -2663,7 +2663,7 @@ with only_when(requires_wasm_sandboxing
def wasi_sysroot_flags(wasi_sysroot):
if wasi_sysroot:
log.info("Using wasi sysroot in %s", wasi_sysroot)
- return ["--sysroot=%s" % wasi_sysroot]
+ return ["--sysroot=%s" % wasi_sysroot, "-nodefaultlibs", "-lc", "-lwasi-emulated-process-clocks", "-lc++", "-lc++abi", "$LIBCLANG_RT"]
return []
set_config("WASI_SYSROOT", wasi_sysroot)

File diff suppressed because it is too large Load Diff

View File

@ -12,66 +12,89 @@
%global run_firefox_tests 0 %global run_firefox_tests 0
%endif %endif
# wasi_sdk is for sandboxing third party c/c++ libs by using rlbox, exclude s390x on the f39.
%global with_wasi_sdk 0
%{lua: %{lua:
function dist_to_rhel_minor(str, start) function dist_to_rhel_minor(str, start)
match = string.match(str, ".module%+el8.%d+") match = string.match(str, ".module%+el8.%d+")
if match then if match then
return string.sub(match, 13) return string.sub(match, 13)
end end
match = string.match(str, ".el8_%d+") match = string.match(str, ".el8_%d+")
if match then if match then
return string.sub(match, 6) return string.sub(match, 6)
end end
match = string.match(str, ".el8") match = string.match(str, ".el8")
if match then if match then
return 10 return 10
end end
match = string.match(str, ".module%+el9.%d+") match = string.match(str, ".module%+el9.%d+")
if match then if match then
return string.sub(match, 13) return string.sub(match, 13)
end end
match = string.match(str, ".el9_%d+") match = string.match(str, ".el9_%d+")
if match then if match then
return string.sub(match, 6) return string.sub(match, 6)
end end
match = string.match(str, ".el9") match = string.match(str, ".el9")
if match then if match then
return 5 return 6
end end
match = string.match(str, ".el10_%d+") match = string.match(str, ".el10_%d+")
if match then if match then
return string.sub(match, 7) return string.sub(match, 7)
end end
match = string.match(str, ".el10") match = string.match(str, ".el10")
if match then if match then
return 0 return 0
end end
return -1 return -1
end} end}
%global rhel_minor_version %{lua:print(dist_to_rhel_minor(rpm.expand("%dist")))} %global rhel_minor_version %{lua:print(dist_to_rhel_minor(rpm.expand("%dist")))}
%if 0%{?rhel} == 10
%global use_pipewire_camera 1
%else
%global use_pipewire_camera 0
%endif
# System libraries options # System libraries options
%global system_nss 1 %global system_nss 1
%global bundle_nss 0 %global bundle_nss 0
%if 0%{?rhel} == 7 %if 0%{?rhel} == 7
%global bundle_nss 0 %global bundle_nss 0
%global system_nss 0 %global system_nss 0
%endif %endif
%if 0%{?rhel} == 8 %if 0%{?rhel} == 8
%if %{rhel_minor_version} < 8 %if %{rhel_minor_version} < 8
%global bundle_nss 1 %global bundle_nss 1
%global system_nss 1 %global system_nss 1
%endif %endif
%if %{rhel_minor_version} >= 10
%ifnarch s390x
%global with_wasi_sdk 1
%endif
%endif
%endif %endif
%if 0%{?rhel} == 9 %if 0%{?rhel} == 9
%if %{rhel_minor_version} < 2 %if %{rhel_minor_version} < 2
%global bundle_nss 1 %global bundle_nss 1
%global system_nss 1 %global system_nss 1
%endif %endif
%if %{rhel_minor_version} > 5
%ifnarch s390x
%global with_wasi_sdk 1
%endif
%endif
%endif %endif
%global dts_version 11 %global dts_version 11
%global llvm_version 7.0 %global llvm_version 7.0
%global nspr_version 4.35 %global nspr_version 4.35
@ -98,11 +121,11 @@ end}
%endif %endif
%if 0%{?rhel} == 7 %if 0%{?rhel} == 7
%global use_dts 1 %global use_dts 1
%global use_nodejs_scl 1 %global use_nodejs_scl 1
%global nodejs_build_req rh-nodejs10-nodejs %global nodejs_build_req rh-nodejs10-nodejs
%global llvm_version 11.0 %global llvm_version 11.0
%global use_python3_scl 1 %global use_python3_scl 1
%endif %endif
%if 0%{?disable_toolsets} %if 0%{?disable_toolsets}
@ -113,9 +136,9 @@ end}
%global launch_wayland_compositor 0 %global launch_wayland_compositor 0
%if 0%{?run_firefox_tests} %if 0%{?run_firefox_tests}
%global test_on_wayland 1 %global test_on_wayland 1
%global launch_wayland_compositor 1 %global launch_wayland_compositor 1
%global build_tests 1 %global build_tests 1
%endif %endif
@ -137,8 +160,8 @@ end}
Summary: Mozilla Firefox Web browser Summary: Mozilla Firefox Web browser
Name: firefox Name: firefox
Version: 128.3.1 Version: 128.6.0
Release: 2%{?dist}.alma.1 Release: 1%{?dist}
URL: https://www.mozilla.org/firefox/ URL: https://www.mozilla.org/firefox/
License: MPLv1.1 or GPLv2+ or LGPLv2+ License: MPLv1.1 or GPLv2+ or LGPLv2+
@ -168,7 +191,7 @@ ExcludeArch: aarch64 s390 ppc
# Link to original tarball: https://archive.mozilla.org/pub/firefox/releases/%%{version}%%{?pre_version}/source/firefox-%%{version}%%{?pre_version}.source.tar.xz # Link to original tarball: https://archive.mozilla.org/pub/firefox/releases/%%{version}%%{?pre_version}/source/firefox-%%{version}%%{?pre_version}.source.tar.xz
Source0: firefox-%{version}%{?pre_version}%{?buildnum}.processed-source.tar.xz Source0: firefox-%{version}%{?pre_version}%{?buildnum}.processed-source.tar.xz
%if %{with langpacks} %if %{with langpacks}
Source1: firefox-langpacks-%{version}%{?pre_version}-20241009.tar.xz Source1: firefox-langpacks-%{version}%{?pre_version}-20241218.tar.xz
%endif %endif
Source2: cbindgen-vendor.tar.xz Source2: cbindgen-vendor.tar.xz
Source3: process-official-tarball Source3: process-official-tarball
@ -179,7 +202,7 @@ Source21: firefox.sh.in
Source23: firefox.1 Source23: firefox.1
Source24: mozilla-api-key Source24: mozilla-api-key
Source25: firefox-symbolic.svg Source25: firefox-symbolic.svg
Source26: distribution.ini Source26: distribution.ini.in
Source27: google-api-key Source27: google-api-key
Source30: firefox-x11.sh.in Source30: firefox-x11.sh.in
Source31: firefox-x11.desktop Source31: firefox-x11.desktop
@ -189,6 +212,11 @@ Source34: firefox-search-provider.ini
Source35: google-loc-api-key Source35: google-loc-api-key
Source36: testing.sh Source36: testing.sh
Source37: mochitest-python.tar.gz Source37: mochitest-python.tar.gz
Source38: wasi.patch.template
# Created by:
# git clone --recursive https://github.com/WebAssembly/wasi-sdk.git
# cd wasi-sdk && git-archive-all --force-submodules wasi-sdk-20.tar.gz
Source50: wasi-sdk-20.tar.gz
# Bundled libraries # Bundled libraries
Source401: nss-setup-flags-env.inc Source401: nss-setup-flags-env.inc
@ -209,6 +237,7 @@ Patch08: disable-pipewire.patch
Patch09: rhbz-2131158-webrtc-nss-fix.patch Patch09: rhbz-2131158-webrtc-nss-fix.patch
Patch10: build-ffvpx.patch Patch10: build-ffvpx.patch
Patch11: build-disable-gamepad.patch Patch11: build-disable-gamepad.patch
Patch12: firefox-system-nss-replace-xyber-with-mlkem.patch
# -- Upstreamed patches -- # -- Upstreamed patches --
Patch51: mozilla-bmo1170092.patch Patch51: mozilla-bmo1170092.patch
@ -236,6 +265,34 @@ Patch154: firefox-nss-addon-hack.patch
# ARM run-time patch # ARM run-time patch
Patch155: rhbz-1354671.patch Patch155: rhbz-1354671.patch
# --- fips webrtc fix
Patch200: webrtc-128.0.patch.patch
Patch201: D224587.1728128070.diff
Patch202: D224588.1728128098.diff
Patch203: wasi.patch
# --- Upstream PipeWire camera and screencast fixes ----
# https://phabricator.services.mozilla.com/D215197
Patch250: 001-libwebrtc-pipewire-screencast-hide-cursor-when-goes-off-screen-or-is-invisible.patch
# https://phabricator.services.mozilla.com/D216138
Patch251: 002-libwebrtc-pipewire-camera-support-additional-formats-and-fix-rgb-bgr-mapping.patch
# https://phabricator.services.mozilla.com/D219224
Patch252: 003-libwebrtc-pipewire-camera-filter-out-devices-without-capabilities.patch
# https://phabricator.services.mozilla.com/D219062
Patch253: 004-firefox-always-query-information-about-camera-availability.patch
# https://phabricator.services.mozilla.com/D219060
Patch254: 005-firefox-always-register-video-input-feedback-for-newly-created-deviceinfo.patch
# https://phabricator.services.mozilla.com/D220895
Patch255: 006-libwebrtc-pipewire-camera-make-member-variable-with-pipewire-status-updated.patch
# https://phabricator.services.mozilla.com/D219218
Patch256: 007-firefox-add-missing-support-for-device-change-notifications.patch
# https://phabricator.services.mozilla.com/D223112
Patch257: 008-libwebrtc-pipewire-camera-get-max-fps-for-each-format-when-specified-as-list.patch
# https://phabricator.services.mozilla.com/D223119
Patch258: 009-libwebrtc-pipewire-camera-use-exact-stream-parameters-specified-by-capability.patch
# https://phabricator.services.mozilla.com/D228635
Patch259: 010-libwebrtc-pipewire-camera-use-better-unique-device-name-for-camera-devices.patch
# ---- Test patches ---- # ---- Test patches ----
# Generate without context by # Generate without context by
# GENDIFF_DIFF_ARGS=-U0 gendiff firefox-xxxx .firefox-tests-xpcshell # GENDIFF_DIFF_ARGS=-U0 gendiff firefox-xxxx .firefox-tests-xpcshell
@ -353,6 +410,11 @@ BuildRequires: xmlto
BuildRequires: zlib-devel BuildRequires: zlib-devel
%endif %endif
%if %{with_wasi_sdk}
BuildRequires: lld
BuildRequires: clang cmake ninja-build
%endif
%if !0%{?flatpak} %if !0%{?flatpak}
#TODO #TODO
BuildRequires: system-bookmarks BuildRequires: system-bookmarks
@ -1117,10 +1179,15 @@ echo "system_nss %{?system_nss}"
echo "use_dts %{?use_dts}" echo "use_dts %{?use_dts}"
echo "use_nodejs_scl %{?use_nodejs_scl}" echo "use_nodejs_scl %{?use_nodejs_scl}"
echo "use_python3_scl %{?use_python3_scl}" echo "use_python3_scl %{?use_python3_scl}"
echo "with_wasi_sdk %{?with_wasi_sdk}"
echo "--------------------------------------------" echo "--------------------------------------------"
#clang -print-search-dirs #clang -print-search-dirs
%setup -q -n %{name}-%{version} %setup -q -n %{name}-%{version}
%if %{with_wasi_sdk}
%setup -q -T -D -a 50
%endif
# ---- RHEL specific patches --- # ---- RHEL specific patches ---
# -- Downstream only -- # -- Downstream only --
%patch -P1 -p1 -b .disable-elfhack %patch -P1 -p1 -b .disable-elfhack
@ -1145,6 +1212,15 @@ echo "--------------------------------------------"
%endif %endif
%patch -P9 -p1 -b .rhbz-2131158-webrtc-nss-fix %patch -P9 -p1 -b .rhbz-2131158-webrtc-nss-fix
%patch -P10 -p1 -b .build-ffvpx %patch -P10 -p1 -b .build-ffvpx
%if 0%{?rhel} == 10
%patch -P12 -p1 -b .system-nss-replace-xyber-with-mlkem
%endif
# We need to create the wasi.patch with the correct path to the wasm libclang_rt.
%if %{with_wasi_sdk}
export LIBCLANG_RT=`pwd`/wasi-sdk-20/build/compiler-rt/lib/wasi/libclang_rt.builtins-wasm32.a; cat %{SOURCE38} | envsubst > %{_sourcedir}/wasi.patch
%patch -P203 -p1 -b .wasi
%endif
# -- Upstreamed patches -- # -- Upstreamed patches --
%patch -P51 -p1 -b .mozilla-bmo1170092 %patch -P51 -p1 -b .mozilla-bmo1170092
@ -1170,6 +1246,27 @@ echo "--------------------------------------------"
%patch -P155 -p1 -b .rhbz-1354671 %patch -P155 -p1 -b .rhbz-1354671
%endif %endif
# Fips webrtc patch
%ifnarch ppc64 ppc64le s390x
%patch -P200 -p1 -b .webrtc-128.0
%patch -P201 -p1 -b .D224587
%patch -P202 -p1 -b .D224588
%endif
# --- Upstream PipeWire camera and screencast fixes ----
%if %{?use_pipewire_camera}
%patch -P250 -p1 -b .pipewire-screencast-hide-cursor-when-goes-off-screen-or-is-invisible
%patch -P251 -p1 -b .pipewire-camera-support-additional-formats-and-fix-rgb-bgr-mapping
%patch -P252 -p1 -b .pipewire-camera-filter-out-devices-without-capabilities
%patch -P253 -p1 -b .always-query-information-about-camera-availability
%patch -P254 -p1 -b .always-register-video-input-feedback-for-newly-created-deviceinfo
%patch -P255 -p1 -b .pipewire-camera-make-member-variable-with-pipewire-status-updated
%patch -P256 -p1 -b .add-missing-support-for-device-change-notifications
%patch -P257 -p1 -b .pipewire-camera-get-max-fps-for-each-format-when-specified-as-list
%patch -P258 -p1 -b .pipewire-camera-use-exact-stream-parameters-specified-by-capability
%patch -P259 -p1 -b .pipewire-camera-use-better-unique-device-name-for-camera-devices
%endif
# ---- Security patches ---- # ---- Security patches ----
%{__rm} -f .mozconfig %{__rm} -f .mozconfig
@ -1250,6 +1347,13 @@ echo "ac_add_options --with-google-safebrowsing-api-keyfile=`pwd`/google-api-key
# Clang 17 upstream's detection fails, tell it where to look. # Clang 17 upstream's detection fails, tell it where to look.
echo "ac_add_options --with-libclang-path=`llvm-config --libdir`" >> .mozconfig echo "ac_add_options --with-libclang-path=`llvm-config --libdir`" >> .mozconfig
%if %{with_wasi_sdk}
echo "ac_add_options --with-wasi-sysroot=`pwd`/wasi-sdk-20/build/install/opt/wasi-sdk/share/wasi-sysroot" >> .mozconfig
%else
echo "ac_add_options --without-sysroot" >> .mozconfig
echo "ac_add_options --without-wasm-sandboxed-libraries" >> .mozconfig
%endif
echo 'export NODEJS="%{_buildrootdir}/bin/node-stdout-nonblocking-wrapper"' >> .mozconfig echo 'export NODEJS="%{_buildrootdir}/bin/node-stdout-nonblocking-wrapper"' >> .mozconfig
# Remove executable bit to make brp-mangle-shebangs happy. # Remove executable bit to make brp-mangle-shebangs happy.
@ -1265,6 +1369,15 @@ chmod a-x third_party/rust/ash/src/extensions/nv/*.rs
# Disable LTO to work around rhbz#1883904 # Disable LTO to work around rhbz#1883904
%define _lto_cflags %{nil} %define _lto_cflags %{nil}
#WASI SDK
%if %{with_wasi_sdk}
pushd wasi-sdk-20
sed -i -e "s|VERSION=.*|VERSION=20|g" tar_from_installation.sh
cat tar_from_installation.sh
NINJA_FLAGS=-v CC=clang CXX=clang++ env -u CFLAGS -u CXXFLAGS -u FFLAGS -u VALFLAGS -u RUSTFLAGS -u LDFLAGS -u LT_SYS_LIBRARY_PATH make package
popd
%endif
export PATH="%{_buildrootdir}/bin:$PATH" export PATH="%{_buildrootdir}/bin:$PATH"
# Cleanup buildroot for existing rpms from bundled nss/nspr and other packages # Cleanup buildroot for existing rpms from bundled nss/nspr and other packages
rm -rf %{_buildrootdir}/* rm -rf %{_buildrootdir}/*
@ -1716,9 +1829,18 @@ ln -s %{_datadir}/myspell %{buildroot}%{mozappdir}/dictionaries
%{__cp} failures-* %{buildroot}/%{version}-%{release}/ || true %{__cp} failures-* %{buildroot}/%{version}-%{release}/ || true
%endif %endif
%if %{?use_pipewire_camera}
echo 'pref("media.webrtc.camera.allow-pipewire", true);' >> %{buildroot}%{mozappdir}/defaults/preferences/all-redhat.js
%endif
# Add distribution.ini # Add distribution.ini
%{__mkdir_p} %{buildroot}%{mozappdir}/distribution %{__mkdir_p} %{buildroot}%{mozappdir}/distribution
%{__cp} %{SOURCE26} %{buildroot}%{mozappdir}/distribution %{__sed} -e "s/__NAME__/%(source /etc/os-release; echo ${NAME})/g" \
-e "s/__ID__/%(source /etc/os-release; echo ${ID})/g" \
-e "s/rhel/redhat/g" \
-e "s/Fedora.*/Fedora/g" \
%{SOURCE26} > %{buildroot}%{mozappdir}/distribution/distribution.ini
# Install appdata file # Install appdata file
mkdir -p %{buildroot}%{_datadir}/metainfo mkdir -p %{buildroot}%{_datadir}/metainfo
@ -1853,8 +1975,22 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
#--------------------------------------------------------------------- #---------------------------------------------------------------------
%changelog %changelog
* Fri Oct 11 2024 Eduard Abdullin <eabdullin@almalinux.org> - 128.3.1-1.alma.1 * Wed Dec 18 2024 Eike Rathke <erack@redhat.com> - 128.6.0-1
- Debrand for AlmaLinux - Update to 128.6.0 build1
* Mon Dec 02 2024 Eike Rathke <erack@redhat.com> - 128.5.1-1
- Update to 128.5.1
* Tue Nov 19 2024 Eike Rathke <erack@redhat.com> - 128.5.0-1
- Update to 128.5.0 build1
* Mon Nov 18 2024 Jan Grulich <jgrulich@redhat.com - 128.4.0-2
- Enable PipeWire camera support for RHEL 10
+ backport upstream fixes for PipeWire camera support
Fixes: RHEL-64749
* Tue Oct 22 2024 Eike Rathke <erack@redhat.com> - 128.4.0-1
- Update to 128.4.0 build1
* Wed Oct 09 2024 Jan Horak <jhorak@redhat.com> - 128.3.1-1 * Wed Oct 09 2024 Jan Horak <jhorak@redhat.com> - 128.3.1-1
- Update to 128.3.1 - Update to 128.3.1
@ -2364,3 +2500,4 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
* Thu Dec 8 2016 Jan Horak <jhorak@redhat.com> - 52.0-0.5 * Thu Dec 8 2016 Jan Horak <jhorak@redhat.com> - 52.0-0.5
- Firefox Aurora 52 testing build - Firefox Aurora 52 testing build