Updated to 77.0
This commit is contained in:
parent
41962ee4b4
commit
5116ef14ae
1
.gitignore
vendored
1
.gitignore
vendored
@ -397,3 +397,4 @@ firefox-3.6.4.source.tar.bz2
|
||||
/firefox-langpacks-76.0-20200502.tar.xz
|
||||
/firefox-76.0.1.source.tar.xz
|
||||
/firefox-langpacks-76.0.1-20200508.tar.xz
|
||||
/firefox-77.0.source.tar.xz
|
||||
|
32
firefox.spec
32
firefox.spec
@ -117,13 +117,13 @@ ExcludeArch: s390x
|
||||
|
||||
Summary: Mozilla Firefox Web browser
|
||||
Name: firefox
|
||||
Version: 76.0.1
|
||||
Release: 7%{?nss_tag}%{?dist}
|
||||
Version: 77.0
|
||||
Release: 1%{?nss_tag}%{?dist}
|
||||
URL: https://www.mozilla.org/firefox/
|
||||
License: MPLv1.1 or GPLv2+ or LGPLv2+
|
||||
Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}%{?pre_version}/source/firefox-%{version}%{?pre_version}.source.tar.xz
|
||||
%if %{with langpacks}
|
||||
Source1: firefox-langpacks-%{version}%{?pre_version}-20200508.tar.xz
|
||||
Source1: firefox-langpacks-%{version}%{?pre_version}-20200529.tar.xz
|
||||
%endif
|
||||
Source2: cbindgen-vendor.tar.xz
|
||||
Source10: firefox-mozconfig
|
||||
@ -172,10 +172,6 @@ Patch224: mozilla-1170092.patch
|
||||
#ARM run-time patch
|
||||
Patch226: rhbz-1354671.patch
|
||||
Patch227: firefox-locale-debug.patch
|
||||
Patch239: mozilla-gnome-shell-search-provider.patch
|
||||
Patch240: mozilla-gnome-shell-search-provider-icons.patch
|
||||
Patch241: kiosk-workaround.patch
|
||||
Patch242: mozilla-gnome-shell-search-fixes.patch
|
||||
|
||||
# Upstream patches
|
||||
Patch402: mozilla-1196777.patch
|
||||
@ -183,6 +179,8 @@ Patch412: mozilla-1337988.patch
|
||||
Patch415: Bug-1238661---fix-mozillaSignalTrampoline-to-work-.patch
|
||||
Patch417: bug1375074-save-restore-x28.patch
|
||||
Patch422: mozilla-1580174-webrtc-popup.patch
|
||||
Patch500: mozilla-1634293.patch
|
||||
Patch501: mozilla-1639197.patch
|
||||
|
||||
# Wayland specific upstream patches
|
||||
Patch574: firefox-pipewire-0-2.patch
|
||||
@ -190,10 +188,6 @@ Patch575: firefox-pipewire-0-3.patch
|
||||
|
||||
#VA-API patches
|
||||
Patch579: mozilla-1625431.patch
|
||||
Patch580: mozilla-1628690.patch
|
||||
Patch581: mozilla-1630754.patch
|
||||
Patch582: mozilla-1619543.patch
|
||||
Patch583: mozilla-1632059.patch
|
||||
Patch584: firefox-disable-ffvpx-with-vapi.patch
|
||||
Patch585: firefox-vaapi-extra-frames.patch
|
||||
Patch586: mozilla-1619882-1.patch
|
||||
@ -388,18 +382,15 @@ This package contains results of tests executed during build.
|
||||
%patch226 -p1 -b .1354671
|
||||
%endif
|
||||
%patch227 -p1 -b .locale-debug
|
||||
%patch239 -p1 -b .gnome-shell-search-provider
|
||||
%patch240 -p1 -b .gnome-shell-search-provider-icons
|
||||
# Workaround for kiosk mode
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=1594738
|
||||
#%patch241 -p1 -b .kiosk-workaround
|
||||
%patch242 -p1 -b .gnome-shell-search-fixes
|
||||
|
||||
%patch402 -p1 -b .1196777
|
||||
%ifarch %{arm}
|
||||
%patch415 -p1 -b .1238661
|
||||
%endif
|
||||
|
||||
%patch500 -p1 -b .mozilla-1634293
|
||||
%patch501 -p1 -b .mozilla-1639197
|
||||
|
||||
# Wayland specific upstream patches
|
||||
%if 0%{?fedora} < 32
|
||||
%patch574 -p1 -b .firefox-pipewire-0-2
|
||||
@ -407,11 +398,7 @@ This package contains results of tests executed during build.
|
||||
%patch575 -p1 -b .firefox-pipewire-0-3
|
||||
%endif
|
||||
|
||||
%patch580 -p1 -b .mozilla-1628690
|
||||
%patch582 -p1 -b .mozilla-1619543
|
||||
%patch579 -p1 -b .mozilla-1625431
|
||||
%patch581 -p1 -b .mozilla-1630754
|
||||
%patch583 -p1 -b .mozilla-1632059
|
||||
%patch584 -p1 -b .firefox-disable-ffvpx-with-vapi
|
||||
%patch585 -p1 -b .firefox-vaapi-extra-frames
|
||||
%patch586 -p1 -b .mozilla-1619882-1
|
||||
@ -993,6 +980,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
%changelog
|
||||
* Fri May 29 2020 Martin Stransky <stransky@redhat.com> - 77.0-1
|
||||
- Updated to Firefox 77.0
|
||||
|
||||
* Mon May 25 2020 Martin Stransky <stransky@redhat.com> - 76.0.1-7
|
||||
- Added fix for mozbz#1632456
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
diff -up firefox-71.0/browser/base/content/browser.css.old firefox-71.0/browser/base/content/browser.css
|
||||
--- firefox-71.0/browser/base/content/browser.css.old 2019-12-04 18:15:20.059908708 +0100
|
||||
+++ firefox-71.0/browser/base/content/browser.css 2019-12-04 18:15:23.181905115 +0100
|
||||
@@ -841,7 +841,7 @@ window[chromehidden~="toolbar"] toolbar:
|
||||
/* Full Screen UI */
|
||||
|
||||
#fullscr-toggler {
|
||||
- height: 1px;
|
||||
+ height: 0px;
|
||||
background: black;
|
||||
}
|
||||
|
@ -1,97 +0,0 @@
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
|
||||
@@ -101,17 +101,22 @@
|
||||
: LinkResult::UnknownFutureLibAVVersion;
|
||||
}
|
||||
|
||||
-#define AV_FUNC_OPTION(func, ver) \
|
||||
+#define AV_FUNC_OPTION_SILENT(func, ver) \
|
||||
if ((ver)&version) { \
|
||||
if (!(func = (decltype(func))PR_FindSymbol( \
|
||||
((ver)&AV_FUNC_AVUTIL_MASK) ? mAVUtilLib : mAVCodecLib, \
|
||||
#func))) { \
|
||||
- FFMPEG_LOG("Couldn't load function " #func); \
|
||||
} \
|
||||
} else { \
|
||||
func = (decltype(func)) nullptr; \
|
||||
}
|
||||
|
||||
+#define AV_FUNC_OPTION(func, ver) \
|
||||
+ AV_FUNC_OPTION_SILENT(func, ver) \
|
||||
+ if ((ver)&version && (func) == (decltype(func)) nullptr) { \
|
||||
+ FFMPEG_LOG("Couldn't load function " #func); \
|
||||
+ }
|
||||
+
|
||||
#define AV_FUNC(func, ver) \
|
||||
AV_FUNC_OPTION(func, ver) \
|
||||
if ((ver)&version && !func) { \
|
||||
@@ -153,30 +158,29 @@
|
||||
AV_FUNC_OPTION(av_frame_get_colorspace, AV_FUNC_AVUTIL_ALL)
|
||||
AV_FUNC_OPTION(av_frame_get_color_range, AV_FUNC_AVUTIL_ALL)
|
||||
#ifdef MOZ_WAYLAND
|
||||
- AV_FUNC_OPTION(avcodec_get_hw_config, AV_FUNC_58)
|
||||
- AV_FUNC_OPTION(av_hwdevice_ctx_create, AV_FUNC_58)
|
||||
- AV_FUNC_OPTION(av_buffer_ref, AV_FUNC_AVUTIL_58)
|
||||
- AV_FUNC_OPTION(av_buffer_unref, AV_FUNC_AVUTIL_58)
|
||||
- AV_FUNC_OPTION(av_hwframe_transfer_get_formats, AV_FUNC_58)
|
||||
- AV_FUNC_OPTION(av_hwdevice_ctx_create_derived, AV_FUNC_58)
|
||||
- AV_FUNC_OPTION(av_hwframe_ctx_alloc, AV_FUNC_58)
|
||||
- AV_FUNC_OPTION(av_dict_set, AV_FUNC_58)
|
||||
- AV_FUNC_OPTION(av_dict_free, AV_FUNC_58)
|
||||
+ AV_FUNC_OPTION_SILENT(avcodec_get_hw_config, AV_FUNC_58)
|
||||
+ AV_FUNC_OPTION_SILENT(av_hwdevice_ctx_create, AV_FUNC_58)
|
||||
+ AV_FUNC_OPTION_SILENT(av_buffer_ref, AV_FUNC_AVUTIL_58)
|
||||
+ AV_FUNC_OPTION_SILENT(av_buffer_unref, AV_FUNC_AVUTIL_58)
|
||||
+ AV_FUNC_OPTION_SILENT(av_hwframe_transfer_get_formats, AV_FUNC_58)
|
||||
+ AV_FUNC_OPTION_SILENT(av_hwdevice_ctx_create_derived, AV_FUNC_58)
|
||||
+ AV_FUNC_OPTION_SILENT(av_hwframe_ctx_alloc, AV_FUNC_58)
|
||||
+ AV_FUNC_OPTION_SILENT(av_dict_set, AV_FUNC_58)
|
||||
+ AV_FUNC_OPTION_SILENT(av_dict_free, AV_FUNC_58)
|
||||
#endif
|
||||
#undef AV_FUNC
|
||||
#undef AV_FUNC_OPTION
|
||||
|
||||
#ifdef MOZ_WAYLAND
|
||||
-# define VA_FUNC_OPTION(func) \
|
||||
+# define VA_FUNC_OPTION_SILENT(func) \
|
||||
if (!(func = (decltype(func))PR_FindSymbol(mVALib, #func))) { \
|
||||
- FFMPEG_LOG("Couldn't load function " #func); \
|
||||
func = (decltype(func)) nullptr; \
|
||||
}
|
||||
|
||||
// mVALib is optional and may not be present.
|
||||
if (mVALib) {
|
||||
- VA_FUNC_OPTION(vaExportSurfaceHandle)
|
||||
- VA_FUNC_OPTION(vaSyncSurface)
|
||||
+ VA_FUNC_OPTION_SILENT(vaExportSurfaceHandle)
|
||||
+ VA_FUNC_OPTION_SILENT(vaSyncSurface)
|
||||
}
|
||||
# undef VA_FUNC_OPTION
|
||||
#endif
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
|
||||
@@ -66,6 +66,9 @@
|
||||
PR_UnloadLibrary(sLibAV.mVALib);
|
||||
sLibAV.mVALib = nullptr;
|
||||
}
|
||||
+ if (!sLibAV.mVALib) {
|
||||
+ FFMPEG_LOG("VA-API support: Missing or old %s library.\n", lib);
|
||||
+ }
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
@@ -173,7 +173,7 @@
|
||||
FFMPEG_LOG("Initialising VA-API FFmpeg decoder");
|
||||
|
||||
if (!mLib->IsVAAPIAvailable()) {
|
||||
- FFMPEG_LOG("libva library is missing");
|
||||
+ FFMPEG_LOG("libva library or symbols are missing.");
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
|
@ -13,60 +13,75 @@ diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces
|
||||
diff --git a/widget/gtk/WaylandDMABufSurface.h b/widget/gtk/WaylandDMABufSurface.h
|
||||
--- a/widget/gtk/WaylandDMABufSurface.h
|
||||
+++ b/widget/gtk/WaylandDMABufSurface.h
|
||||
@@ -40,6 +40,23 @@
|
||||
@@ -49,9 +49,14 @@
|
||||
SURFACE_NV12,
|
||||
};
|
||||
|
||||
class WaylandDMABufSurfaceRGBA;
|
||||
+ // Import surface from SurfaceDescriptor. This is usually
|
||||
+ // used to copy surface from another process over IPC.
|
||||
+ // When a global reference counter was created for the surface
|
||||
+ // (see bellow) it's automatically referenced.
|
||||
static already_AddRefed<WaylandDMABufSurface> CreateDMABufSurface(
|
||||
const mozilla::layers::SurfaceDescriptor& aDesc);
|
||||
|
||||
+class DMABufRefcount {
|
||||
+ public:
|
||||
+ DMABufRefcount();
|
||||
+ DMABufRefcount(int aFd);
|
||||
+
|
||||
+ bool Created() { return mFd > 0; };
|
||||
+ int GetFD() { return mFd; }
|
||||
+ uint64_t GetRefcount();
|
||||
+ void RefAdd();
|
||||
+ void Release();
|
||||
+
|
||||
+ ~DMABufRefcount();
|
||||
+
|
||||
+ private:
|
||||
+ int mFd;
|
||||
+};
|
||||
+
|
||||
class WaylandDMABufSurface {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WaylandDMABufSurface)
|
||||
@@ -82,6 +99,14 @@
|
||||
+ // Export surface to another process via. SurfaceDescriptor.
|
||||
virtual bool Serialize(
|
||||
mozilla::layers::SurfaceDescriptor& aOutDescriptor) = 0;
|
||||
|
||||
@@ -82,6 +87,35 @@
|
||||
void FenceWait();
|
||||
void FenceDelete();
|
||||
|
||||
+ // Set and get a global surface UID. The UID is shared across process
|
||||
+ // and it's used to track surface lifetime in various parts of rendering
|
||||
+ // engine.
|
||||
+ void SetUID(uint32_t aUID) { mUID = aUID; };
|
||||
+ uint32_t GetUID() { return mUID; };
|
||||
+ uint32_t GetUID() const { return mUID; };
|
||||
+
|
||||
+ // Creates a global reference counter objects attached to the surface.
|
||||
+ // It's created as unreferenced, i.e. IsGlobalRefSet() returns false
|
||||
+ // right after GlobalRefCountCreate() call.
|
||||
+ //
|
||||
+ // The counter is shared by all surface instances across processes
|
||||
+ // so it tracks global surface usage.
|
||||
+ //
|
||||
+ // The counter is automatically referenced when a new surface instance is
|
||||
+ // created with SurfaceDescriptor (usually copied to another process over IPC)
|
||||
+ // and it's unreferenced when surface is deleted.
|
||||
+ //
|
||||
+ // So without any additional GlobalRefAdd()/GlobalRefRelease() calls
|
||||
+ // the IsGlobalRefSet() returns true if any other process use the surface.
|
||||
+ void GlobalRefCountCreate();
|
||||
+ bool IsGlobalRefSet();
|
||||
+
|
||||
+ // If global reference counter was created by GlobalRefCountCreate()
|
||||
+ // returns true when there's an active surface reference.
|
||||
+ bool IsGlobalRefSet() const;
|
||||
+
|
||||
+ // Add/Remove additional reference to the surface global reference counter.
|
||||
+ void GlobalRefAdd();
|
||||
+ void GlobalRefRelease();
|
||||
+
|
||||
WaylandDMABufSurface(SurfaceType aSurfaceType);
|
||||
|
||||
protected:
|
||||
@@ -89,6 +114,8 @@
|
||||
@@ -89,7 +123,10 @@
|
||||
virtual void ReleaseSurface() = 0;
|
||||
bool FenceCreate(int aFd);
|
||||
|
||||
+ bool GlobalRefCountImport(int aFd);
|
||||
- virtual ~WaylandDMABufSurface() { FenceDelete(); };
|
||||
+ void GlobalRefCountImport(int aFd);
|
||||
+ void GlobalRefCountDelete();
|
||||
+
|
||||
virtual ~WaylandDMABufSurface() { FenceDelete(); };
|
||||
+ virtual ~WaylandDMABufSurface();
|
||||
|
||||
SurfaceType mSurfaceType;
|
||||
@@ -102,6 +129,9 @@
|
||||
uint64_t mBufferModifier;
|
||||
@@ -102,6 +139,9 @@
|
||||
|
||||
EGLSyncKHR mSync;
|
||||
RefPtr<mozilla::gl::GLContext> mGL;
|
||||
+
|
||||
+ mozilla::UniquePtr<DMABufRefcount> mGlobalRefCount;
|
||||
+ int mGlobalRefCountFd;
|
||||
+ uint32_t mUID;
|
||||
};
|
||||
|
||||
@ -74,101 +89,100 @@ diff --git a/widget/gtk/WaylandDMABufSurface.h b/widget/gtk/WaylandDMABufSurface
|
||||
diff --git a/widget/gtk/WaylandDMABufSurface.cpp b/widget/gtk/WaylandDMABufSurface.cpp
|
||||
--- a/widget/gtk/WaylandDMABufSurface.cpp
|
||||
+++ b/widget/gtk/WaylandDMABufSurface.cpp
|
||||
@@ -17,6 +17,8 @@
|
||||
@@ -17,6 +17,9 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <dlfcn.h>
|
||||
+#include <sys/mman.h>
|
||||
+#include <sys/eventfd.h>
|
||||
+#include <poll.h>
|
||||
|
||||
#include "mozilla/widget/gbm.h"
|
||||
#include "mozilla/widget/va_drmcommon.h"
|
||||
@@ -57,6 +59,73 @@
|
||||
@@ -57,6 +60,61 @@
|
||||
# define VA_FOURCC_NV12 0x3231564E
|
||||
#endif
|
||||
|
||||
+void DMABufRefcount::RefAdd() {
|
||||
+ uint64_t counter;
|
||||
+ read(mFd, &counter, sizeof(counter));
|
||||
+ counter++;
|
||||
+ write(mFd, &counter, sizeof(counter));
|
||||
+bool WaylandDMABufSurface::IsGlobalRefSet() const {
|
||||
+ if (!mGlobalRefCountFd) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ struct pollfd pfd;
|
||||
+ pfd.fd = mGlobalRefCountFd;
|
||||
+ pfd.events = POLLIN;
|
||||
+ return poll(&pfd, 1, 0) == 1;
|
||||
+}
|
||||
+
|
||||
+void DMABufRefcount::Release() {
|
||||
+void WaylandDMABufSurface::GlobalRefRelease() {
|
||||
+ MOZ_ASSERT(mGlobalRefCountFd);
|
||||
+ uint64_t counter;
|
||||
+ read(mFd, &counter, sizeof(counter));
|
||||
+ counter--;
|
||||
+ write(mFd, &counter, sizeof(counter));
|
||||
+ if (read(mGlobalRefCountFd, &counter, sizeof(counter)) != sizeof(counter)) {
|
||||
+ // EAGAIN means the refcount is already zero. It happens when we release
|
||||
+ // last reference to the surface.
|
||||
+ if (errno != EAGAIN) {
|
||||
+ NS_WARNING("Failed to unref dmabuf global ref count!");
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+uint64_t DMABufRefcount::GetRefcount() {
|
||||
+ uint64_t counter;
|
||||
+ read(mFd, &counter, sizeof(counter));
|
||||
+ write(mFd, &counter, sizeof(counter));
|
||||
+ return counter;
|
||||
+}
|
||||
+
|
||||
+DMABufRefcount::DMABufRefcount()
|
||||
+ : mFd(eventfd(1, EFD_CLOEXEC | EFD_NONBLOCK)) {}
|
||||
+
|
||||
+DMABufRefcount::DMABufRefcount(int aFd) : mFd(aFd) {}
|
||||
+
|
||||
+DMABufRefcount::~DMABufRefcount() {
|
||||
+ if (mFd > 0) {
|
||||
+ close(mFd);
|
||||
+void WaylandDMABufSurface::GlobalRefAdd() {
|
||||
+ MOZ_ASSERT(mGlobalRefCountFd);
|
||||
+ uint64_t counter = 1;
|
||||
+ if (write(mGlobalRefCountFd, &counter, sizeof(counter)) != sizeof(counter)) {
|
||||
+ NS_WARNING("Failed to ref dmabuf global ref count!");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void WaylandDMABufSurface::GlobalRefCountCreate() {
|
||||
+ MOZ_ASSERT(!mGlobalRefCount);
|
||||
+ mGlobalRefCount = MakeUnique<DMABufRefcount>();
|
||||
+ if (!mGlobalRefCount->Created()) {
|
||||
+ MOZ_ASSERT(!mGlobalRefCountFd);
|
||||
+ mGlobalRefCountFd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE);
|
||||
+ if (mGlobalRefCountFd < 0) {
|
||||
+ NS_WARNING("Failed to create dmabuf global ref count!");
|
||||
+ mGlobalRefCount = nullptr;
|
||||
+ mGlobalRefCountFd = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+bool WaylandDMABufSurface::GlobalRefCountImport(int aFd) {
|
||||
+ MOZ_ASSERT(!mGlobalRefCount);
|
||||
+ mGlobalRefCount = MakeUnique<DMABufRefcount>(aFd);
|
||||
+ if (!mGlobalRefCount->Created()) {
|
||||
+ NS_WARNING("Failed to import dmabuf global ref count!");
|
||||
+ mGlobalRefCount = nullptr;
|
||||
+ return false;
|
||||
+void WaylandDMABufSurface::GlobalRefCountImport(int aFd) {
|
||||
+ MOZ_ASSERT(!mGlobalRefCountFd);
|
||||
+ mGlobalRefCountFd = aFd;
|
||||
+ GlobalRefAdd();
|
||||
+}
|
||||
+
|
||||
+void WaylandDMABufSurface::GlobalRefCountDelete() {
|
||||
+ MOZ_ASSERT(mGlobalRefCountFd);
|
||||
+ if (mGlobalRefCountFd) {
|
||||
+ GlobalRefRelease();
|
||||
+ close(mGlobalRefCountFd);
|
||||
+ mGlobalRefCountFd = 0;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+bool WaylandDMABufSurface::IsGlobalRefSet() {
|
||||
+ MOZ_ASSERT(mGlobalRefCount);
|
||||
+ return mGlobalRefCount->GetRefcount() > 1;
|
||||
+}
|
||||
+
|
||||
+void WaylandDMABufSurface::GlobalRefAdd() {
|
||||
+ MOZ_ASSERT(mGlobalRefCount);
|
||||
+ mGlobalRefCount->RefAdd();
|
||||
+}
|
||||
+
|
||||
+void WaylandDMABufSurface::GlobalRefRelease() {
|
||||
+ MOZ_ASSERT(mGlobalRefCount);
|
||||
+ mGlobalRefCount->Release();
|
||||
+}
|
||||
+
|
||||
WaylandDMABufSurface::WaylandDMABufSurface(SurfaceType aSurfaceType)
|
||||
: mSurfaceType(aSurfaceType),
|
||||
mBufferModifier(DRM_FORMAT_MOD_INVALID),
|
||||
@@ -64,7 +133,9 @@
|
||||
@@ -64,12 +122,19 @@
|
||||
mDrmFormats(),
|
||||
mStrides(),
|
||||
mOffsets(),
|
||||
- mSync(0) {
|
||||
+ mSync(0),
|
||||
+ mGlobalRefCount(nullptr),
|
||||
+ mGlobalRefCountFd(0),
|
||||
+ mUID(0) {
|
||||
for (auto& slot : mDmabufFds) {
|
||||
slot = -1;
|
||||
}
|
||||
@@ -316,6 +387,7 @@
|
||||
}
|
||||
|
||||
+WaylandDMABufSurface::~WaylandDMABufSurface() {
|
||||
+ FenceDelete();
|
||||
+ GlobalRefCountDelete();
|
||||
+}
|
||||
+
|
||||
already_AddRefed<WaylandDMABufSurface>
|
||||
WaylandDMABufSurface::CreateDMABufSurface(
|
||||
const mozilla::layers::SurfaceDescriptor& aDesc) {
|
||||
@@ -316,6 +381,7 @@
|
||||
mBufferPlaneCount = desc.fds().Length();
|
||||
mGbmBufferFlags = desc.flags();
|
||||
MOZ_RELEASE_ASSERT(mBufferPlaneCount <= DMABUF_BUFFER_PLANES);
|
||||
@ -176,21 +190,18 @@ diff --git a/widget/gtk/WaylandDMABufSurface.cpp b/widget/gtk/WaylandDMABufSurfa
|
||||
|
||||
for (int i = 0; i < mBufferPlaneCount; i++) {
|
||||
mDmabufFds[i] = desc.fds()[i].ClonePlatformHandle().release();
|
||||
@@ -329,6 +401,13 @@
|
||||
@@ -329,6 +395,10 @@
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ if (desc.refCount().Length() > 0) {
|
||||
+ int fd = desc.refCount()[0].ClonePlatformHandle().release();
|
||||
+ if (!GlobalRefCountImport(fd)) {
|
||||
+ close(fd);
|
||||
+ }
|
||||
+ GlobalRefCountImport(desc.refCount()[0].ClonePlatformHandle().release());
|
||||
+ }
|
||||
}
|
||||
|
||||
bool WaylandDMABufSurfaceRGBA::Create(const SurfaceDescriptor& aDesc) {
|
||||
@@ -346,6 +425,7 @@
|
||||
@@ -346,6 +416,7 @@
|
||||
AutoTArray<uint32_t, DMABUF_BUFFER_PLANES> offsets;
|
||||
AutoTArray<uintptr_t, DMABUF_BUFFER_PLANES> images;
|
||||
AutoTArray<ipc::FileDescriptor, 1> fenceFDs;
|
||||
@ -198,15 +209,15 @@ diff --git a/widget/gtk/WaylandDMABufSurface.cpp b/widget/gtk/WaylandDMABufSurfa
|
||||
|
||||
width.AppendElement(mWidth);
|
||||
height.AppendElement(mHeight);
|
||||
@@ -362,9 +442,14 @@
|
||||
@@ -362,9 +433,14 @@
|
||||
egl->fDupNativeFenceFDANDROID(egl->Display(), mSync)));
|
||||
}
|
||||
|
||||
- aOutDescriptor = SurfaceDescriptorDMABuf(
|
||||
- mSurfaceType, mBufferModifier, mGbmBufferFlags, fds, width, height,
|
||||
- format, strides, offsets, GetYUVColorSpace(), fenceFDs);
|
||||
+ if (mGlobalRefCount) {
|
||||
+ refCountFDs.AppendElement(ipc::FileDescriptor(mGlobalRefCount->GetFD()));
|
||||
+ if (mGlobalRefCountFd) {
|
||||
+ refCountFDs.AppendElement(ipc::FileDescriptor(mGlobalRefCountFd));
|
||||
+ }
|
||||
+
|
||||
+ aOutDescriptor =
|
||||
@ -216,7 +227,7 @@ diff --git a/widget/gtk/WaylandDMABufSurface.cpp b/widget/gtk/WaylandDMABufSurfa
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -693,6 +778,7 @@
|
||||
@@ -693,6 +769,7 @@
|
||||
mBufferPlaneCount = aDesc.fds().Length();
|
||||
mBufferModifier = aDesc.modifier();
|
||||
mColorSpace = aDesc.yUVColorSpace();
|
||||
@ -224,21 +235,18 @@ diff --git a/widget/gtk/WaylandDMABufSurface.cpp b/widget/gtk/WaylandDMABufSurfa
|
||||
|
||||
MOZ_RELEASE_ASSERT(mBufferPlaneCount <= DMABUF_BUFFER_PLANES);
|
||||
for (int i = 0; i < mBufferPlaneCount; i++) {
|
||||
@@ -710,6 +796,13 @@
|
||||
@@ -710,6 +787,10 @@
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ if (aDesc.refCount().Length() > 0) {
|
||||
+ int fd = aDesc.refCount()[0].ClonePlatformHandle().release();
|
||||
+ if (!GlobalRefCountImport(fd)) {
|
||||
+ close(fd);
|
||||
+ }
|
||||
+ GlobalRefCountImport(aDesc.refCount()[0].ClonePlatformHandle().release());
|
||||
+ }
|
||||
}
|
||||
|
||||
bool WaylandDMABufSurfaceNV12::Serialize(
|
||||
@@ -721,6 +814,7 @@
|
||||
@@ -721,6 +802,7 @@
|
||||
AutoTArray<uint32_t, DMABUF_BUFFER_PLANES> strides;
|
||||
AutoTArray<uint32_t, DMABUF_BUFFER_PLANES> offsets;
|
||||
AutoTArray<ipc::FileDescriptor, 1> fenceFDs;
|
||||
@ -246,12 +254,12 @@ diff --git a/widget/gtk/WaylandDMABufSurface.cpp b/widget/gtk/WaylandDMABufSurfa
|
||||
|
||||
for (int i = 0; i < mBufferPlaneCount; i++) {
|
||||
width.AppendElement(mWidth[i]);
|
||||
@@ -737,9 +831,13 @@
|
||||
@@ -737,9 +819,13 @@
|
||||
egl->fDupNativeFenceFDANDROID(egl->Display(), mSync)));
|
||||
}
|
||||
|
||||
+ if (mGlobalRefCount) {
|
||||
+ refCountFDs.AppendElement(ipc::FileDescriptor(mGlobalRefCount->GetFD()));
|
||||
+ if (mGlobalRefCountFd) {
|
||||
+ refCountFDs.AppendElement(ipc::FileDescriptor(mGlobalRefCountFd));
|
||||
+ }
|
||||
+
|
||||
aOutDescriptor = SurfaceDescriptorDMABuf(
|
||||
|
@ -1,7 +1,7 @@
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
|
||||
@@ -10,17 +10,26 @@
|
||||
@@ -10,21 +10,45 @@
|
||||
#include "FFmpegLibWrapper.h"
|
||||
#include "FFmpegDataDecoder.h"
|
||||
#include "SimpleMap.h"
|
||||
@ -13,31 +13,56 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platfor
|
||||
namespace mozilla {
|
||||
|
||||
#ifdef MOZ_WAYLAND_USE_VAAPI
|
||||
-class VAAPIFrameHolder {
|
||||
+// When VA-API decoding is running, ffmpeg allocates AVHWFramesContext - a pool
|
||||
+// of "hardware" frames. Every "hardware" frame (VASurface) is backed
|
||||
+// by actual piece of GPU memory which holds the decoded image data.
|
||||
+//
|
||||
+// The VASurface is wrapped by WaylandDMABufSurface and transferred to
|
||||
+// rendering queue by WaylandDMABUFSurfaceImage, where TextureClient is
|
||||
+// created and VASurface is used as a texture there.
|
||||
+//
|
||||
+// As there's a limited number of VASurfaces, ffmpeg reuses them to decode
|
||||
+// next frames ASAP even if they are still attached to WaylandDMABufSurface
|
||||
+// and used as a texture in our rendering engine.
|
||||
+//
|
||||
+// Unfortunately there isn't any obvious way how to mark particular VASurface
|
||||
+// as used. The best we can do is to hold a reference to particular AVBuffer
|
||||
+// from decoded AVFrame and AVHWFramesContext which owns the AVBuffer.
|
||||
+
|
||||
class VAAPIFrameHolder {
|
||||
+class VAAPIFrameHolder final {
|
||||
public:
|
||||
- VAAPIFrameHolder(FFmpegLibWrapper* aLib, AVBufferRef* aVAAPIDeviceContext,
|
||||
+ VAAPIFrameHolder(RefPtr<WaylandDMABufSurface> aSurface,
|
||||
+ FFmpegLibWrapper* aLib, AVBufferRef* aVAAPIDeviceContext,
|
||||
AVBufferRef* aAVHWFramesContext, AVBufferRef* aHWFrame);
|
||||
- AVBufferRef* aAVHWFramesContext, AVBufferRef* aHWFrame);
|
||||
+ VAAPIFrameHolder(FFmpegLibWrapper* aLib, WaylandDMABufSurface* aSurface,
|
||||
+ AVCodecContext* aAVCodecContext, AVFrame* aAVFrame);
|
||||
~VAAPIFrameHolder();
|
||||
|
||||
+ bool IsUsed() { return mSurface->IsGlobalRefSet(); }
|
||||
+ // Check if WaylandDMABufSurface is used by any gecko rendering process
|
||||
+ // (WebRender or GL compositor) or by WaylandDMABUFSurfaceImage/VideoData.
|
||||
+ bool IsUsed() const { return mSurface->IsGlobalRefSet(); }
|
||||
+
|
||||
private:
|
||||
+ RefPtr<WaylandDMABufSurface> mSurface;
|
||||
FFmpegLibWrapper* mLib;
|
||||
AVBufferRef* mVAAPIDeviceContext;
|
||||
- FFmpegLibWrapper* mLib;
|
||||
- AVBufferRef* mVAAPIDeviceContext;
|
||||
+ const FFmpegLibWrapper* mLib;
|
||||
+ const RefPtr<WaylandDMABufSurface> mSurface;
|
||||
AVBufferRef* mAVHWFramesContext;
|
||||
@@ -97,6 +106,7 @@
|
||||
- AVBufferRef* mHWFrame;
|
||||
+ AVBufferRef* mHWAVBuffer;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -97,6 +121,8 @@
|
||||
|
||||
MediaResult CreateImageVAAPI(int64_t aOffset, int64_t aPts, int64_t aDuration,
|
||||
MediaDataDecoder::DecodedData& aResults);
|
||||
+ void ReleaseUnusedVAAPIFrames();
|
||||
+ void ReleaseAllVAAPIFrames();
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -112,6 +122,7 @@
|
||||
@@ -112,6 +138,7 @@
|
||||
AVBufferRef* mVAAPIDeviceContext;
|
||||
const bool mDisableHardwareDecoding;
|
||||
VADisplay mDisplay;
|
||||
@ -48,41 +73,43 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platfor
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
@@ -122,19 +122,30 @@
|
||||
return AV_PIX_FMT_NONE;
|
||||
@@ -123,18 +123,27 @@
|
||||
}
|
||||
|
||||
-VAAPIFrameHolder::VAAPIFrameHolder(FFmpegLibWrapper* aLib,
|
||||
+VAAPIFrameHolder::VAAPIFrameHolder(RefPtr<WaylandDMABufSurface> aSurface,
|
||||
+ FFmpegLibWrapper* aLib,
|
||||
AVBufferRef* aVAAPIDeviceContext,
|
||||
AVBufferRef* aAVHWFramesContext,
|
||||
AVBufferRef* aHWFrame)
|
||||
- : mLib(aLib),
|
||||
+ : mSurface(aSurface),
|
||||
+ mLib(aLib),
|
||||
mVAAPIDeviceContext(mLib->av_buffer_ref(aVAAPIDeviceContext)),
|
||||
mAVHWFramesContext(mLib->av_buffer_ref(aAVHWFramesContext)),
|
||||
VAAPIFrameHolder::VAAPIFrameHolder(FFmpegLibWrapper* aLib,
|
||||
- AVBufferRef* aVAAPIDeviceContext,
|
||||
- AVBufferRef* aAVHWFramesContext,
|
||||
- AVBufferRef* aHWFrame)
|
||||
+ WaylandDMABufSurface* aSurface,
|
||||
+ AVCodecContext* aAVCodecContext,
|
||||
+ AVFrame* aAVFrame)
|
||||
: mLib(aLib),
|
||||
- mVAAPIDeviceContext(mLib->av_buffer_ref(aVAAPIDeviceContext)),
|
||||
- mAVHWFramesContext(mLib->av_buffer_ref(aAVHWFramesContext)),
|
||||
- mHWFrame(mLib->av_buffer_ref(aHWFrame)){};
|
||||
+ mHWFrame(mLib->av_buffer_ref(aHWFrame)) {
|
||||
+ mSurface(aSurface),
|
||||
+ mAVHWFramesContext(mLib->av_buffer_ref(aAVCodecContext->hw_frames_ctx)),
|
||||
+ mHWAVBuffer(mLib->av_buffer_ref(aAVFrame->buf[0])) {
|
||||
+ FFMPEG_LOG("VAAPIFrameHolder is adding dmabuf surface UID = %d\n",
|
||||
+ mSurface->GetUID());
|
||||
+
|
||||
+ // Create global refcount object to track mSurface usage over
|
||||
+ // processes.
|
||||
+ // gects rendering engine. We can't release it until it's used
|
||||
+ // by GL compositor / WebRender.
|
||||
+ mSurface->GlobalRefCountCreate();
|
||||
+}
|
||||
|
||||
VAAPIFrameHolder::~VAAPIFrameHolder() {
|
||||
- mLib->av_buffer_unref(&mHWFrame);
|
||||
+ FFMPEG_LOG("VAAPIFrameHolder is releasing dmabuf surface UID = %d\n",
|
||||
+ mSurface->GetUID());
|
||||
mLib->av_buffer_unref(&mHWFrame);
|
||||
+ mLib->av_buffer_unref(&mHWAVBuffer);
|
||||
mLib->av_buffer_unref(&mAVHWFramesContext);
|
||||
mLib->av_buffer_unref(&mVAAPIDeviceContext);
|
||||
+ mSurface = nullptr;
|
||||
- mLib->av_buffer_unref(&mVAAPIDeviceContext);
|
||||
}
|
||||
|
||||
AVCodec* FFmpegVideoDecoder<LIBAV_VER>::FindVAAPICodec() {
|
||||
@@ -418,6 +428,13 @@
|
||||
@@ -422,6 +431,13 @@
|
||||
NS_WARNING("FFmpeg h264 decoder failed to allocate frame.");
|
||||
return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
|
||||
}
|
||||
@ -96,7 +123,7 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platf
|
||||
res = mLib->avcodec_receive_frame(mCodecContext, mFrame);
|
||||
if (res == int(AVERROR_EOF)) {
|
||||
return NS_ERROR_DOM_MEDIA_END_OF_STREAM;
|
||||
@@ -624,9 +641,16 @@
|
||||
@@ -628,9 +644,20 @@
|
||||
}
|
||||
|
||||
#ifdef MOZ_WAYLAND_USE_VAAPI
|
||||
@ -113,10 +140,14 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platf
|
||||
+ holder++;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void FFmpegVideoDecoder<LIBAV_VER>::ReleaseAllVAAPIFrames() {
|
||||
+ mFrameHolders.clear();
|
||||
}
|
||||
|
||||
MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImageVAAPI(
|
||||
@@ -663,20 +687,28 @@
|
||||
@@ -667,20 +694,20 @@
|
||||
RESULT_DETAIL("Unable to allocate WaylandDMABufSurfaceNV12."));
|
||||
}
|
||||
|
||||
@ -128,28 +159,32 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platf
|
||||
+
|
||||
surface->SetYUVColorSpace(GetFrameColorSpace());
|
||||
|
||||
// mFrame->buf[0] is a reference to H264 VASurface for this mFrame.
|
||||
- // mFrame->buf[0] is a reference to H264 VASurface for this mFrame.
|
||||
- // We need create WaylandDMABUFSurfaceImage on top of it,
|
||||
+ // We need create WaylandDMABUFSurface on top of it,
|
||||
// create EGLImage/Texture on top of it and render it by GL.
|
||||
- // create EGLImage/Texture on top of it and render it by GL.
|
||||
+ // Store reference to the decoded HW buffer, see VAAPIFrameHolder struct.
|
||||
+ auto holder =
|
||||
+ MakeUnique<VAAPIFrameHolder>(mLib, surface, mCodecContext, mFrame);
|
||||
+ mFrameHolders.push_back(std::move(holder));
|
||||
|
||||
// FFmpeg tends to reuse the particual VASurface for another frame
|
||||
// even when the mFrame is not released. To keep VASurface as is
|
||||
- // FFmpeg tends to reuse the particual VASurface for another frame
|
||||
- // even when the mFrame is not released. To keep VASurface as is
|
||||
- // we explicitly reference it and keep until WaylandDMABUFSurfaceImage
|
||||
- // is live.
|
||||
- RefPtr<layers::Image> im = new layers::WaylandDMABUFSurfaceImage(
|
||||
- surface, VAAPIFrameReleaseCallback,
|
||||
- new VAAPIFrameHolder(mLib, mVAAPIDeviceContext,
|
||||
- mCodecContext->hw_frames_ctx, mFrame->buf[0]));
|
||||
+ // we explicitly reference it and keep until there's any reference to
|
||||
+ // attached WaylandDMABUFSurface.
|
||||
+ auto holder = MakeUnique<VAAPIFrameHolder>(surface, mLib, mVAAPIDeviceContext,
|
||||
+ mCodecContext->hw_frames_ctx,
|
||||
+ mFrame->buf[0]);
|
||||
+ mFrameHolders.push_back(std::move(holder));
|
||||
+
|
||||
+ RefPtr<layers::Image> im = new layers::WaylandDMABUFSurfaceImage(surface);
|
||||
|
||||
RefPtr<VideoData> vp = VideoData::CreateFromImage(
|
||||
mInfo.mDisplay, aOffset, TimeUnit::FromMicroseconds(aPts),
|
||||
@@ -732,6 +759,7 @@
|
||||
void FFmpegVideoDecoder<LIBAV_VER>::ProcessShutdown() {
|
||||
#ifdef MOZ_WAYLAND_USE_VAAPI
|
||||
if (mVAAPIDeviceContext) {
|
||||
+ ReleaseAllVAAPIFrames();
|
||||
mLib->av_buffer_unref(&mVAAPIDeviceContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1,67 +0,0 @@
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h b/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
|
||||
@@ -49,7 +49,9 @@
|
||||
RefPtr<MediaDataDecoder> decoder = new FFmpegVideoDecoder<V>(
|
||||
mLib, aParams.mTaskQueue, aParams.VideoConfig(),
|
||||
aParams.mKnowsCompositor, aParams.mImageContainer,
|
||||
- aParams.mOptions.contains(CreateDecoderParams::Option::LowLatency));
|
||||
+ aParams.mOptions.contains(CreateDecoderParams::Option::LowLatency),
|
||||
+ aParams.mOptions.contains(
|
||||
+ CreateDecoderParams::Option::HardwareDecoderNotAllowed));
|
||||
return decoder.forget();
|
||||
}
|
||||
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
|
||||
@@ -48,7 +48,8 @@
|
||||
public:
|
||||
FFmpegVideoDecoder(FFmpegLibWrapper* aLib, TaskQueue* aTaskQueue,
|
||||
const VideoInfo& aConfig, KnowsCompositor* aAllocator,
|
||||
- ImageContainer* aImageContainer, bool aLowLatency);
|
||||
+ ImageContainer* aImageContainer, bool aLowLatency,
|
||||
+ bool aDisableHardwareDecoding);
|
||||
|
||||
RefPtr<InitPromise> Init() override;
|
||||
void InitCodecContext() override;
|
||||
@@ -109,6 +110,7 @@
|
||||
|
||||
#ifdef MOZ_WAYLAND_USE_VAAPI
|
||||
AVBufferRef* mVAAPIDeviceContext;
|
||||
+ const bool mDisableHardwareDecoding;
|
||||
#endif
|
||||
RefPtr<KnowsCompositor> mImageAllocator;
|
||||
RefPtr<ImageContainer> mImageContainer;
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
@@ -270,10 +270,11 @@
|
||||
FFmpegVideoDecoder<LIBAV_VER>::FFmpegVideoDecoder(
|
||||
FFmpegLibWrapper* aLib, TaskQueue* aTaskQueue, const VideoInfo& aConfig,
|
||||
KnowsCompositor* aAllocator, ImageContainer* aImageContainer,
|
||||
- bool aLowLatency)
|
||||
+ bool aLowLatency, bool aDisableHardwareDecoding)
|
||||
: FFmpegDataDecoder(aLib, aTaskQueue, GetCodecId(aConfig.mMimeType)),
|
||||
#ifdef MOZ_WAYLAND_USE_VAAPI
|
||||
mVAAPIDeviceContext(nullptr),
|
||||
+ mDisableHardwareDecoding(aDisableHardwareDecoding),
|
||||
#endif
|
||||
mImageAllocator(aAllocator),
|
||||
mImageContainer(aImageContainer),
|
||||
@@ -289,9 +290,11 @@
|
||||
MediaResult rv;
|
||||
|
||||
#ifdef MOZ_WAYLAND_USE_VAAPI
|
||||
- rv = InitVAAPIDecoder();
|
||||
- if (NS_SUCCEEDED(rv)) {
|
||||
- return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
|
||||
+ if (!mDisableHardwareDecoding) {
|
||||
+ rv = InitVAAPIDecoder();
|
||||
+ if (NS_SUCCEEDED(rv)) {
|
||||
+ return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
|
||||
+ }
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1,298 +0,0 @@
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
|
||||
@@ -116,9 +116,9 @@
|
||||
#ifdef MOZ_WAYLAND
|
||||
const AVCodecHWConfig* (*avcodec_get_hw_config)(const AVCodec* codec,
|
||||
int index);
|
||||
- int (*av_hwdevice_ctx_create)(AVBufferRef** device_ctx, int type,
|
||||
- const char* device, AVDictionary* opts,
|
||||
- int flags);
|
||||
+ AVBufferRef* (*av_hwdevice_ctx_alloc)(int);
|
||||
+ int (*av_hwdevice_ctx_init)(AVBufferRef* ref);
|
||||
+
|
||||
AVBufferRef* (*av_buffer_ref)(AVBufferRef* buf);
|
||||
void (*av_buffer_unref)(AVBufferRef** buf);
|
||||
int (*av_hwframe_transfer_get_formats)(AVBufferRef* hwframe_ctx, int dir,
|
||||
@@ -132,12 +132,16 @@
|
||||
|
||||
int (*vaExportSurfaceHandle)(void*, unsigned int, uint32_t, uint32_t, void*);
|
||||
int (*vaSyncSurface)(void*, unsigned int);
|
||||
+ int (*vaInitialize)(void* dpy, int* major_version, int* minor_version);
|
||||
+ int (*vaTerminate)(void* dpy);
|
||||
+ void* (*vaGetDisplayWl)(struct wl_display* display);
|
||||
#endif
|
||||
|
||||
PRLibrary* mAVCodecLib;
|
||||
PRLibrary* mAVUtilLib;
|
||||
#ifdef MOZ_WAYLAND
|
||||
PRLibrary* mVALib;
|
||||
+ PRLibrary* mVALibWayland;
|
||||
#endif
|
||||
|
||||
private:
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
|
||||
@@ -159,7 +159,8 @@
|
||||
AV_FUNC_OPTION(av_frame_get_color_range, AV_FUNC_AVUTIL_ALL)
|
||||
#ifdef MOZ_WAYLAND
|
||||
AV_FUNC_OPTION_SILENT(avcodec_get_hw_config, AV_FUNC_58)
|
||||
- AV_FUNC_OPTION_SILENT(av_hwdevice_ctx_create, AV_FUNC_58)
|
||||
+ AV_FUNC_OPTION_SILENT(av_hwdevice_ctx_init, AV_FUNC_58)
|
||||
+ AV_FUNC_OPTION_SILENT(av_hwdevice_ctx_alloc, AV_FUNC_58)
|
||||
AV_FUNC_OPTION_SILENT(av_buffer_ref, AV_FUNC_AVUTIL_58)
|
||||
AV_FUNC_OPTION_SILENT(av_buffer_unref, AV_FUNC_AVUTIL_58)
|
||||
AV_FUNC_OPTION_SILENT(av_hwframe_transfer_get_formats, AV_FUNC_58)
|
||||
@@ -181,8 +182,21 @@
|
||||
if (mVALib) {
|
||||
VA_FUNC_OPTION_SILENT(vaExportSurfaceHandle)
|
||||
VA_FUNC_OPTION_SILENT(vaSyncSurface)
|
||||
+ VA_FUNC_OPTION_SILENT(vaInitialize)
|
||||
+ VA_FUNC_OPTION_SILENT(vaTerminate)
|
||||
}
|
||||
-# undef VA_FUNC_OPTION
|
||||
+# undef VA_FUNC_OPTION_SILENT
|
||||
+
|
||||
+# define VAW_FUNC_OPTION_SILENT(func) \
|
||||
+ if (!(func = (decltype(func))PR_FindSymbol(mVALibWayland, #func))) { \
|
||||
+ FFMPEG_LOG("Couldn't load function " #func); \
|
||||
+ }
|
||||
+
|
||||
+ // mVALibWayland is optional and may not be present.
|
||||
+ if (mVALibWayland) {
|
||||
+ VAW_FUNC_OPTION_SILENT(vaGetDisplayWl)
|
||||
+ }
|
||||
+# undef VAW_FUNC_OPTION_SILENT
|
||||
#endif
|
||||
|
||||
avcodec_register_all();
|
||||
@@ -218,6 +232,9 @@
|
||||
if (mVALib) {
|
||||
PR_UnloadLibrary(mVALib);
|
||||
}
|
||||
+ if (mVALibWayland) {
|
||||
+ PR_UnloadLibrary(mVALibWayland);
|
||||
+ }
|
||||
#endif
|
||||
PodZero(this);
|
||||
}
|
||||
@@ -226,13 +243,16 @@
|
||||
bool FFmpegLibWrapper::IsVAAPIAvailable() {
|
||||
# define VA_FUNC_LOADED(func) (func != nullptr)
|
||||
return VA_FUNC_LOADED(avcodec_get_hw_config) &&
|
||||
- VA_FUNC_LOADED(av_hwdevice_ctx_create) &&
|
||||
+ VA_FUNC_LOADED(av_hwdevice_ctx_alloc) &&
|
||||
+ VA_FUNC_LOADED(av_hwdevice_ctx_init) &&
|
||||
VA_FUNC_LOADED(av_buffer_ref) && VA_FUNC_LOADED(av_buffer_unref) &&
|
||||
VA_FUNC_LOADED(av_hwframe_transfer_get_formats) &&
|
||||
VA_FUNC_LOADED(av_hwdevice_ctx_create_derived) &&
|
||||
VA_FUNC_LOADED(av_hwframe_ctx_alloc) && VA_FUNC_LOADED(av_dict_set) &&
|
||||
VA_FUNC_LOADED(av_dict_free) &&
|
||||
- VA_FUNC_LOADED(vaExportSurfaceHandle) && VA_FUNC_LOADED(vaSyncSurface);
|
||||
+ VA_FUNC_LOADED(vaExportSurfaceHandle) &&
|
||||
+ VA_FUNC_LOADED(vaSyncSurface) && VA_FUNC_LOADED(vaInitialize) &&
|
||||
+ VA_FUNC_LOADED(vaTerminate) && VA_FUNC_LOADED(vaGetDisplayWl);
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
|
||||
@@ -9,6 +9,9 @@
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "FFmpegLog.h"
|
||||
#include "prlink.h"
|
||||
+#ifdef MOZ_WAYLAND
|
||||
+# include "gfxPlatformGtk.h"
|
||||
+#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -54,21 +57,33 @@
|
||||
}
|
||||
|
||||
#ifdef MOZ_WAYLAND
|
||||
- {
|
||||
- const char* lib = "libva.so.2";
|
||||
+ if (gfxPlatformGtk::GetPlatform()->UseWaylandHardwareVideoDecoding()) {
|
||||
+ const char* libWayland = "libva-wayland.so.2";
|
||||
PRLibSpec lspec;
|
||||
lspec.type = PR_LibSpec_Pathname;
|
||||
- lspec.value.pathname = lib;
|
||||
- sLibAV.mVALib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL);
|
||||
- // Don't use libva when it's missing vaExportSurfaceHandle.
|
||||
- if (sLibAV.mVALib &&
|
||||
- !PR_FindSymbol(sLibAV.mVALib, "vaExportSurfaceHandle")) {
|
||||
- PR_UnloadLibrary(sLibAV.mVALib);
|
||||
- sLibAV.mVALib = nullptr;
|
||||
+ lspec.value.pathname = libWayland;
|
||||
+ sLibAV.mVALibWayland =
|
||||
+ PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL);
|
||||
+ if (!sLibAV.mVALibWayland) {
|
||||
+ FFMPEG_LOG("VA-API support: Missing or old %s library.\n", libWayland);
|
||||
}
|
||||
- if (!sLibAV.mVALib) {
|
||||
- FFMPEG_LOG("VA-API support: Missing or old %s library.\n", lib);
|
||||
+
|
||||
+ if (sLibAV.mVALibWayland) {
|
||||
+ const char* lib = "libva.so.2";
|
||||
+ lspec.value.pathname = lib;
|
||||
+ sLibAV.mVALib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL);
|
||||
+ // Don't use libva when it's missing vaExportSurfaceHandle.
|
||||
+ if (sLibAV.mVALib &&
|
||||
+ !PR_FindSymbol(sLibAV.mVALib, "vaExportSurfaceHandle")) {
|
||||
+ PR_UnloadLibrary(sLibAV.mVALib);
|
||||
+ sLibAV.mVALib = nullptr;
|
||||
+ }
|
||||
+ if (!sLibAV.mVALib) {
|
||||
+ FFMPEG_LOG("VA-API support: Missing or old %s library.\n", lib);
|
||||
+ }
|
||||
}
|
||||
+ } else {
|
||||
+ FFMPEG_LOG("VA-API FFmpeg is disabled by platform");
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
|
||||
@@ -111,6 +111,7 @@
|
||||
#ifdef MOZ_WAYLAND_USE_VAAPI
|
||||
AVBufferRef* mVAAPIDeviceContext;
|
||||
const bool mDisableHardwareDecoding;
|
||||
+ VADisplay mDisplay;
|
||||
#endif
|
||||
RefPtr<KnowsCompositor> mImageAllocator;
|
||||
RefPtr<ImageContainer> mImageContainer;
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
@@ -154,14 +154,44 @@
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
+class VAAPIDisplayHolder {
|
||||
+ public:
|
||||
+ VAAPIDisplayHolder(FFmpegLibWrapper* aLib, VADisplay aDisplay)
|
||||
+ : mLib(aLib), mDisplay(aDisplay){};
|
||||
+ ~VAAPIDisplayHolder() { mLib->vaTerminate(mDisplay); }
|
||||
+
|
||||
+ private:
|
||||
+ FFmpegLibWrapper* mLib;
|
||||
+ VADisplay mDisplay;
|
||||
+};
|
||||
+
|
||||
+static void VAAPIDisplayReleaseCallback(struct AVHWDeviceContext* hwctx) {
|
||||
+ auto displayHolder = static_cast<VAAPIDisplayHolder*>(hwctx->user_opaque);
|
||||
+ delete displayHolder;
|
||||
+}
|
||||
+
|
||||
bool FFmpegVideoDecoder<LIBAV_VER>::CreateVAAPIDeviceContext() {
|
||||
- AVDictionary* opts = nullptr;
|
||||
- mLib->av_dict_set(&opts, "connection_type", "drm", 0);
|
||||
- bool ret =
|
||||
- (mLib->av_hwdevice_ctx_create(
|
||||
- &mVAAPIDeviceContext, AV_HWDEVICE_TYPE_VAAPI, NULL, NULL, 0) == 0);
|
||||
- mLib->av_dict_free(&opts);
|
||||
- if (!ret) {
|
||||
+ mVAAPIDeviceContext = mLib->av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VAAPI);
|
||||
+ if (!mVAAPIDeviceContext) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ AVHWDeviceContext* hwctx = (AVHWDeviceContext*)mVAAPIDeviceContext->data;
|
||||
+ AVVAAPIDeviceContext* vactx = (AVVAAPIDeviceContext*)hwctx->hwctx;
|
||||
+
|
||||
+ mDisplay = mLib->vaGetDisplayWl(widget::WaylandDisplayGet()->GetDisplay());
|
||||
+
|
||||
+ hwctx->user_opaque = new VAAPIDisplayHolder(mLib, mDisplay);
|
||||
+ hwctx->free = VAAPIDisplayReleaseCallback;
|
||||
+
|
||||
+ int major, minor;
|
||||
+ int status = mLib->vaInitialize(mDisplay, &major, &minor);
|
||||
+ if (status != VA_STATUS_SUCCESS) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ vactx->display = mDisplay;
|
||||
+
|
||||
+ if (mLib->av_hwdevice_ctx_init(mVAAPIDeviceContext) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -172,6 +202,11 @@
|
||||
MediaResult FFmpegVideoDecoder<LIBAV_VER>::InitVAAPIDecoder() {
|
||||
FFMPEG_LOG("Initialising VA-API FFmpeg decoder");
|
||||
|
||||
+ if (!mLib->IsVAAPIAvailable()) {
|
||||
+ FFMPEG_LOG("libva library or symbols are missing.");
|
||||
+ return NS_ERROR_NOT_AVAILABLE;
|
||||
+ }
|
||||
+
|
||||
auto layersBackend = mImageAllocator
|
||||
? mImageAllocator->GetCompositorBackendType()
|
||||
: layers::LayersBackend::LAYERS_BASIC;
|
||||
@@ -181,16 +216,6 @@
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
- if (!mLib->IsVAAPIAvailable()) {
|
||||
- FFMPEG_LOG("libva library or symbols are missing.");
|
||||
- return NS_ERROR_NOT_AVAILABLE;
|
||||
- }
|
||||
-
|
||||
- if (!gfxPlatformGtk::GetPlatform()->UseWaylandHardwareVideoDecoding()) {
|
||||
- FFMPEG_LOG("VA-API FFmpeg is disabled by platform");
|
||||
- return NS_ERROR_NOT_AVAILABLE;
|
||||
- }
|
||||
-
|
||||
AVCodec* codec = FindVAAPICodec();
|
||||
if (!codec) {
|
||||
FFMPEG_LOG("Couldn't find ffmpeg VA-API decoder");
|
||||
@@ -275,6 +300,7 @@
|
||||
#ifdef MOZ_WAYLAND_USE_VAAPI
|
||||
mVAAPIDeviceContext(nullptr),
|
||||
mDisableHardwareDecoding(aDisableHardwareDecoding),
|
||||
+ mDisplay(nullptr),
|
||||
#endif
|
||||
mImageAllocator(aAllocator),
|
||||
mImageContainer(aImageContainer),
|
||||
@@ -606,16 +632,10 @@
|
||||
" duration=%" PRId64 " opaque=%" PRId64,
|
||||
aPts, mFrame->pkt_dts, aDuration, mCodecContext->reordered_opaque);
|
||||
|
||||
- AVHWDeviceContext* device_ctx = (AVHWDeviceContext*)mVAAPIDeviceContext->data;
|
||||
- AVVAAPIDeviceContext* VAAPIDeviceContext =
|
||||
- (AVVAAPIDeviceContext*)device_ctx->hwctx;
|
||||
VADRMPRIMESurfaceDescriptor va_desc;
|
||||
-
|
||||
VASurfaceID surface_id = (VASurfaceID)(uintptr_t)mFrame->data[3];
|
||||
-
|
||||
VAStatus vas = mLib->vaExportSurfaceHandle(
|
||||
- VAAPIDeviceContext->display, surface_id,
|
||||
- VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
|
||||
+ mDisplay, surface_id, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
|
||||
VA_EXPORT_SURFACE_READ_ONLY | VA_EXPORT_SURFACE_SEPARATE_LAYERS,
|
||||
&va_desc);
|
||||
if (vas != VA_STATUS_SUCCESS) {
|
||||
@@ -623,7 +643,7 @@
|
||||
NS_ERROR_OUT_OF_MEMORY,
|
||||
RESULT_DETAIL("Unable to get frame by vaExportSurfaceHandle()"));
|
||||
}
|
||||
- vas = mLib->vaSyncSurface(VAAPIDeviceContext->display, surface_id);
|
||||
+ vas = mLib->vaSyncSurface(mDisplay, surface_id);
|
||||
if (vas != VA_STATUS_SUCCESS) {
|
||||
NS_WARNING("vaSyncSurface() failed.");
|
||||
}
|
||||
diff --git a/dom/media/platforms/ffmpeg/moz.build b/dom/media/platforms/ffmpeg/moz.build
|
||||
--- a/dom/media/platforms/ffmpeg/moz.build
|
||||
+++ b/dom/media/platforms/ffmpeg/moz.build
|
||||
@@ -20,4 +20,7 @@
|
||||
'FFmpegRuntimeLinker.cpp',
|
||||
]
|
||||
|
||||
+if CONFIG['MOZ_WAYLAND']:
|
||||
+ include('/ipc/chromium/chromium-config.mozbuild')
|
||||
+
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
@ -1,41 +0,0 @@
|
||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
||||
@@ -178,7 +178,12 @@
|
||||
AVHWDeviceContext* hwctx = (AVHWDeviceContext*)mVAAPIDeviceContext->data;
|
||||
AVVAAPIDeviceContext* vactx = (AVVAAPIDeviceContext*)hwctx->hwctx;
|
||||
|
||||
- mDisplay = mLib->vaGetDisplayWl(widget::WaylandDisplayGet()->GetDisplay());
|
||||
+ wl_display* display = widget::WaylandDisplayGetWLDisplay();
|
||||
+ if (!display) {
|
||||
+ FFMPEG_LOG("Can't get default wayland display.");
|
||||
+ return false;
|
||||
+ }
|
||||
+ mDisplay = mLib->vaGetDisplayWl(display);
|
||||
|
||||
hwctx->user_opaque = new VAAPIDisplayHolder(mLib, mDisplay);
|
||||
hwctx->free = VAAPIDisplayReleaseCallback;
|
||||
diff --git a/widget/gtk/nsWaylandDisplay.cpp b/widget/gtk/nsWaylandDisplay.cpp
|
||||
--- a/widget/gtk/nsWaylandDisplay.cpp
|
||||
+++ b/widget/gtk/nsWaylandDisplay.cpp
|
||||
@@ -35,6 +35,9 @@
|
||||
wl_display* WaylandDisplayGetWLDisplay(GdkDisplay* aGdkDisplay) {
|
||||
if (!aGdkDisplay) {
|
||||
aGdkDisplay = gdk_display_get_default();
|
||||
+ if (!aGdkDisplay || GDK_IS_X11_DISPLAY(aGdkDisplay)) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
}
|
||||
|
||||
// Available as of GTK 3.8+
|
||||
@@ -537,8 +540,7 @@
|
||||
StaticPrefs::widget_wayland_dmabuf_webgl_enabled();
|
||||
}
|
||||
bool nsWaylandDisplay::IsDMABufVAAPIEnabled() {
|
||||
- return IsDMABufEnabled() &&
|
||||
- StaticPrefs::widget_wayland_dmabuf_vaapi_enabled();
|
||||
+ return StaticPrefs::widget_wayland_dmabuf_vaapi_enabled();
|
||||
}
|
||||
|
||||
void* nsGbmLib::sGbmLibHandle = nullptr;
|
||||
|
406
mozilla-1634293.patch
Normal file
406
mozilla-1634293.patch
Normal file
@ -0,0 +1,406 @@
|
||||
diff --git a/browser/components/shell/nsGNOMEShellDBusHelper.h b/browser/components/shell/nsGNOMEShellDBusHelper.h
|
||||
--- a/browser/components/shell/nsGNOMEShellDBusHelper.h
|
||||
+++ b/browser/components/shell/nsGNOMEShellDBusHelper.h
|
||||
@@ -19,6 +19,8 @@
|
||||
#define DBUS_BUS_NAME "org.mozilla.Firefox.SearchProvider"
|
||||
#define DBUS_OBJECT_PATH "/org/mozilla/Firefox/SearchProvider"
|
||||
|
||||
+class nsGNOMEShellHistorySearchResult;
|
||||
+
|
||||
DBusHandlerResult DBusIntrospect(DBusConnection* aConnection,
|
||||
DBusMessage* aMsg);
|
||||
DBusHandlerResult DBusHandleInitialResultSet(
|
||||
diff --git a/browser/components/shell/nsGNOMEShellDBusHelper.cpp b/browser/components/shell/nsGNOMEShellDBusHelper.cpp
|
||||
--- a/browser/components/shell/nsGNOMEShellDBusHelper.cpp
|
||||
+++ b/browser/components/shell/nsGNOMEShellDBusHelper.cpp
|
||||
@@ -6,7 +6,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsGNOMEShellSearchProvider.h"
|
||||
-#include "nsGNOMEShellDBusHelper.h"
|
||||
|
||||
#include "nsPrintfCString.h"
|
||||
#include "RemoteUtils.h"
|
||||
@@ -174,6 +173,49 @@
|
||||
dbus_message_iter_close_container(aIter, &iterDict);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ "icon-data": a tuple of type (iiibiiay) describing a pixbuf with width,
|
||||
+ height, rowstride, has-alpha,
|
||||
+ bits-per-sample, channels,
|
||||
+ image data
|
||||
+*/
|
||||
+static void DBusAppendIcon(GnomeHistoryIcon* aIcon, DBusMessageIter* aIter) {
|
||||
+ DBusMessageIter iterDict, iterVar, iterStruct;
|
||||
+ dbus_message_iter_open_container(aIter, DBUS_TYPE_DICT_ENTRY, nullptr,
|
||||
+ &iterDict);
|
||||
+ const char* key = "icon-data";
|
||||
+ dbus_message_iter_append_basic(&iterDict, DBUS_TYPE_STRING, &key);
|
||||
+ dbus_message_iter_open_container(&iterDict, DBUS_TYPE_VARIANT, "(iiibiiay)",
|
||||
+ &iterVar);
|
||||
+ dbus_message_iter_open_container(&iterVar, DBUS_TYPE_STRUCT, nullptr,
|
||||
+ &iterStruct);
|
||||
+
|
||||
+ int width = aIcon->GetWidth();
|
||||
+ int height = aIcon->GetHeight();
|
||||
+ dbus_message_iter_append_basic(&iterStruct, DBUS_TYPE_INT32, &width);
|
||||
+ dbus_message_iter_append_basic(&iterStruct, DBUS_TYPE_INT32, &height);
|
||||
+ int rowstride = width * 4;
|
||||
+ dbus_message_iter_append_basic(&iterStruct, DBUS_TYPE_INT32, &rowstride);
|
||||
+ int hasAlpha = true;
|
||||
+ dbus_message_iter_append_basic(&iterStruct, DBUS_TYPE_BOOLEAN, &hasAlpha);
|
||||
+ int bitsPerSample = 8;
|
||||
+ dbus_message_iter_append_basic(&iterStruct, DBUS_TYPE_INT32, &bitsPerSample);
|
||||
+ int channels = 4;
|
||||
+ dbus_message_iter_append_basic(&iterStruct, DBUS_TYPE_INT32, &channels);
|
||||
+
|
||||
+ DBusMessageIter iterArray;
|
||||
+ dbus_message_iter_open_container(&iterStruct, DBUS_TYPE_ARRAY, "y",
|
||||
+ &iterArray);
|
||||
+ unsigned char* array = aIcon->GetData();
|
||||
+ dbus_message_iter_append_fixed_array(&iterArray, DBUS_TYPE_BYTE, &array,
|
||||
+ width * height * 4);
|
||||
+ dbus_message_iter_close_container(&iterStruct, &iterArray);
|
||||
+
|
||||
+ dbus_message_iter_close_container(&iterVar, &iterStruct);
|
||||
+ dbus_message_iter_close_container(&iterDict, &iterVar);
|
||||
+ dbus_message_iter_close_container(aIter, &iterDict);
|
||||
+}
|
||||
+
|
||||
/* Appends history search results to the DBUS reply.
|
||||
|
||||
We can return those fields at GetResultMetas:
|
||||
@@ -188,11 +230,14 @@
|
||||
"description": an optional short description (1-2 lines)
|
||||
*/
|
||||
static void DBusAppendResultID(
|
||||
- nsCOMPtr<nsINavHistoryContainerResultNode> aHistResultContainer,
|
||||
+ RefPtr<nsGNOMEShellHistorySearchResult> aSearchResult,
|
||||
DBusMessageIter* aIter, const char* aID) {
|
||||
+ nsCOMPtr<nsINavHistoryContainerResultNode> container =
|
||||
+ aSearchResult->GetSearchResultContainer();
|
||||
+
|
||||
+ int index = DBusGetIndexFromIDKey(aID);
|
||||
nsCOMPtr<nsINavHistoryResultNode> child;
|
||||
- aHistResultContainer->GetChild(DBusGetIndexFromIDKey(aID),
|
||||
- getter_AddRefs(child));
|
||||
+ container->GetChild(index, getter_AddRefs(child));
|
||||
nsAutoCString title;
|
||||
if (NS_FAILED(child->GetTitle(title))) {
|
||||
return;
|
||||
@@ -207,7 +252,13 @@
|
||||
const char* titleStr = title.get();
|
||||
appendStringDictionary(aIter, "id", aID);
|
||||
appendStringDictionary(aIter, "name", titleStr);
|
||||
- appendStringDictionary(aIter, "gicon", "text-html");
|
||||
+
|
||||
+ GnomeHistoryIcon* icon = aSearchResult->GetHistoryIcon(index);
|
||||
+ if (icon) {
|
||||
+ DBusAppendIcon(icon, aIter);
|
||||
+ } else {
|
||||
+ appendStringDictionary(aIter, "gicon", "text-html");
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Search the web for: "searchTerm" to the DBUS reply.
|
||||
@@ -265,8 +316,7 @@
|
||||
KEYWORD_SEARCH_STRING_LEN) == 0) {
|
||||
DBusAppendSearchID(&iterArray2, stringArray[i]);
|
||||
} else {
|
||||
- DBusAppendResultID(aSearchResult->GetSearchResultContainer(),
|
||||
- &iterArray2, stringArray[i]);
|
||||
+ DBusAppendResultID(aSearchResult, &iterArray2, stringArray[i]);
|
||||
}
|
||||
dbus_message_iter_close_container(&iterArray, &iterArray2);
|
||||
}
|
||||
diff --git a/browser/components/shell/nsGNOMEShellSearchProvider.h b/browser/components/shell/nsGNOMEShellSearchProvider.h
|
||||
--- a/browser/components/shell/nsGNOMEShellSearchProvider.h
|
||||
+++ b/browser/components/shell/nsGNOMEShellSearchProvider.h
|
||||
@@ -12,9 +12,37 @@
|
||||
#include "nsINavHistoryService.h"
|
||||
#include "nsUnixRemoteServer.h"
|
||||
#include "nsCOMPtr.h"
|
||||
+#include "mozilla/UniquePtr.h"
|
||||
+#include "nsGNOMEShellDBusHelper.h"
|
||||
|
||||
class nsGNOMEShellSearchProvider;
|
||||
|
||||
+class GnomeHistoryIcon {
|
||||
+ public:
|
||||
+ GnomeHistoryIcon() : mTimeStamp(-1), mWidth(0), mHeight(0){};
|
||||
+
|
||||
+ // From which search is this icon
|
||||
+ void Set(int aTimeStamp, mozilla::UniquePtr<uint8_t[]> aData, int aWidth,
|
||||
+ int aHeight) {
|
||||
+ mTimeStamp = aTimeStamp;
|
||||
+ mWidth = aWidth;
|
||||
+ mHeight = aHeight;
|
||||
+ mData = std::move(aData);
|
||||
+ }
|
||||
+
|
||||
+ bool IsLoaded() { return mData && mWidth > 0 && mHeight > 0; }
|
||||
+ int GetTimeStamp() { return mTimeStamp; }
|
||||
+ uint8_t* GetData() { return mData.get(); }
|
||||
+ int GetWidth() { return mWidth; }
|
||||
+ int GetHeight() { return mHeight; }
|
||||
+
|
||||
+ private:
|
||||
+ int mTimeStamp;
|
||||
+ mozilla::UniquePtr<uint8_t[]> mData;
|
||||
+ int mWidth;
|
||||
+ int mHeight;
|
||||
+};
|
||||
+
|
||||
// nsGNOMEShellHistorySearchResult is a container with contains search results
|
||||
// which are files asynchronously by nsGNOMEShellHistoryService.
|
||||
// The search results can be opened by Firefox then.
|
||||
@@ -34,11 +62,16 @@
|
||||
mSearchTerm = nsAutoCString(aSearchTerm);
|
||||
}
|
||||
DBusConnection* GetDBusConnection() { return mConnection; }
|
||||
+ void SetTimeStamp(int aTimeStamp) { mTimeStamp = aTimeStamp; }
|
||||
int GetTimeStamp() { return mTimeStamp; }
|
||||
- void SetTimeStamp(int aTimeStamp) { mTimeStamp = aTimeStamp; }
|
||||
nsAutoCString& GetSearchTerm() { return mSearchTerm; }
|
||||
- void SetSearchResultContainer(
|
||||
+
|
||||
+ // Receive (asynchronously) history search results from history service.
|
||||
+ // This is called asynchronously by nsGNOMEShellHistoryService
|
||||
+ // when we have search results available.
|
||||
+ void ReceiveSearchResultContainer(
|
||||
nsCOMPtr<nsINavHistoryContainerResultNode> aHistResultContainer);
|
||||
+
|
||||
nsCOMPtr<nsINavHistoryContainerResultNode> GetSearchResultContainer() {
|
||||
return mHistResultContainer;
|
||||
}
|
||||
@@ -46,8 +79,12 @@
|
||||
nsUnixRemoteServer::HandleCommandLine(aBuffer, aTimestamp);
|
||||
}
|
||||
|
||||
+ void SetHistoryIcon(int aTimeStamp, mozilla::UniquePtr<uint8_t[]> aData,
|
||||
+ int aWidth, int aHeight, int aIconIndex);
|
||||
+ GnomeHistoryIcon* GetHistoryIcon(int aIconIndex);
|
||||
+
|
||||
private:
|
||||
- void SendDBusSearchResultReply();
|
||||
+ void HandleSearchResultReply();
|
||||
|
||||
~nsGNOMEShellHistorySearchResult() = default;
|
||||
|
||||
@@ -58,6 +95,7 @@
|
||||
DBusMessage* mReply;
|
||||
DBusConnection* mConnection;
|
||||
int mTimeStamp;
|
||||
+ GnomeHistoryIcon mHistoryIcons[MAX_SEARCH_RESULTS_NUM];
|
||||
};
|
||||
|
||||
class nsGNOMEShellHistoryService {
|
||||
diff --git a/browser/components/shell/nsGNOMEShellSearchProvider.cpp b/browser/components/shell/nsGNOMEShellSearchProvider.cpp
|
||||
--- a/browser/components/shell/nsGNOMEShellSearchProvider.cpp
|
||||
+++ b/browser/components/shell/nsGNOMEShellSearchProvider.cpp
|
||||
@@ -6,7 +6,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsGNOMEShellSearchProvider.h"
|
||||
-#include "nsGNOMEShellDBusHelper.h"
|
||||
|
||||
#include "nsIWidget.h"
|
||||
#include "nsToolkitCompsCID.h"
|
||||
@@ -14,10 +13,113 @@
|
||||
#include "RemoteUtils.h"
|
||||
#include "base/message_loop.h" // for MessageLoop
|
||||
#include "base/task.h" // for NewRunnableMethod, etc
|
||||
+#include "nsIServiceManager.h"
|
||||
+#include "nsNetCID.h"
|
||||
+#include "nsIIOService.h"
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
#include <dbus/dbus-glib-lowlevel.h>
|
||||
|
||||
+#include "imgIContainer.h"
|
||||
+#include "imgITools.h"
|
||||
+#include "mozilla/gfx/DataSurfaceHelpers.h"
|
||||
+
|
||||
+using namespace mozilla;
|
||||
+using namespace mozilla::gfx;
|
||||
+
|
||||
+class AsyncFaviconDataReady final : public nsIFaviconDataCallback {
|
||||
+ public:
|
||||
+ NS_DECL_ISUPPORTS
|
||||
+ NS_DECL_NSIFAVICONDATACALLBACK
|
||||
+
|
||||
+ AsyncFaviconDataReady(RefPtr<nsGNOMEShellHistorySearchResult> aSearchResult,
|
||||
+ int aIconIndex, int aTimeStamp)
|
||||
+ : mSearchResult(aSearchResult),
|
||||
+ mIconIndex(aIconIndex),
|
||||
+ mTimeStamp(aTimeStamp){};
|
||||
+
|
||||
+ private:
|
||||
+ ~AsyncFaviconDataReady() {}
|
||||
+
|
||||
+ RefPtr<nsGNOMEShellHistorySearchResult> mSearchResult;
|
||||
+ int mIconIndex;
|
||||
+ int mTimeStamp;
|
||||
+};
|
||||
+
|
||||
+NS_IMPL_ISUPPORTS(AsyncFaviconDataReady, nsIFaviconDataCallback)
|
||||
+
|
||||
+// Inspired by SurfaceToPackedBGRA
|
||||
+static UniquePtr<uint8_t[]> SurfaceToPackedRGBA(DataSourceSurface* aSurface) {
|
||||
+ IntSize size = aSurface->GetSize();
|
||||
+ CheckedInt<size_t> bufferSize =
|
||||
+ CheckedInt<size_t>(size.width * 4) * CheckedInt<size_t>(size.height);
|
||||
+ if (!bufferSize.isValid()) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ UniquePtr<uint8_t[]> imageBuffer(new (std::nothrow)
|
||||
+ uint8_t[bufferSize.value()]);
|
||||
+ if (!imageBuffer) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ DataSourceSurface::MappedSurface map;
|
||||
+ if (!aSurface->Map(DataSourceSurface::MapType::READ, &map)) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ // Convert BGRA to RGBA
|
||||
+ uint32_t* aSrc = (uint32_t*)map.mData;
|
||||
+ uint32_t* aDst = (uint32_t*)imageBuffer.get();
|
||||
+ for (int i = 0; i < size.width * size.height; i++, aDst++, aSrc++) {
|
||||
+ *aDst = *aSrc & 0xff00ff00;
|
||||
+ *aDst |= (*aSrc & 0xff) << 16;
|
||||
+ *aDst |= (*aSrc & 0xff0000) >> 16;
|
||||
+ }
|
||||
+
|
||||
+ aSurface->Unmap();
|
||||
+
|
||||
+ return imageBuffer;
|
||||
+}
|
||||
+
|
||||
+NS_IMETHODIMP
|
||||
+AsyncFaviconDataReady::OnComplete(nsIURI* aFaviconURI, uint32_t aDataLen,
|
||||
+ const uint8_t* aData,
|
||||
+ const nsACString& aMimeType,
|
||||
+ uint16_t aWidth) {
|
||||
+ // This is a callback from some previous search so we don't want it
|
||||
+ if (mTimeStamp != mSearchResult->GetTimeStamp() || !aData || !aDataLen) {
|
||||
+ return NS_ERROR_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ // Decode the image from the format it was returned to us in (probably PNG)
|
||||
+ nsCOMPtr<imgIContainer> container;
|
||||
+ nsCOMPtr<imgITools> imgtool = do_CreateInstance("@mozilla.org/image/tools;1");
|
||||
+ nsresult rv = imgtool->DecodeImageFromBuffer(
|
||||
+ reinterpret_cast<const char*>(aData), aDataLen, aMimeType,
|
||||
+ getter_AddRefs(container));
|
||||
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||
+
|
||||
+ RefPtr<SourceSurface> surface = container->GetFrame(
|
||||
+ imgIContainer::FRAME_FIRST,
|
||||
+ imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_ASYNC_NOTIFY);
|
||||
+
|
||||
+ if (!surface || surface->GetFormat() != SurfaceFormat::B8G8R8A8) {
|
||||
+ return NS_ERROR_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ // Allocate a new buffer that we own.
|
||||
+ RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
|
||||
+ UniquePtr<uint8_t[]> data = SurfaceToPackedRGBA(dataSurface);
|
||||
+ if (!data) {
|
||||
+ return NS_ERROR_OUT_OF_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ mSearchResult->SetHistoryIcon(mTimeStamp, std::move(data),
|
||||
+ surface->GetSize().width,
|
||||
+ surface->GetSize().height, mIconIndex);
|
||||
+ return NS_OK;
|
||||
+}
|
||||
+
|
||||
DBusHandlerResult nsGNOMEShellSearchProvider::HandleSearchResultSet(
|
||||
DBusMessage* aMsg, bool aInitialSearch) {
|
||||
// Discard any existing search results.
|
||||
@@ -179,7 +281,7 @@
|
||||
static void DispatchSearchResults(
|
||||
RefPtr<nsGNOMEShellHistorySearchResult> aSearchResult,
|
||||
nsCOMPtr<nsINavHistoryContainerResultNode> aHistResultContainer) {
|
||||
- aSearchResult->SetSearchResultContainer(aHistResultContainer);
|
||||
+ aSearchResult->ReceiveSearchResultContainer(aHistResultContainer);
|
||||
}
|
||||
|
||||
nsresult nsGNOMEShellHistoryService::QueryHistory(
|
||||
@@ -242,7 +344,7 @@
|
||||
aIDKey = nsPrintfCString("%.2d:%s", aIndex, aUri.get());
|
||||
}
|
||||
|
||||
-void nsGNOMEShellHistorySearchResult::SendDBusSearchResultReply() {
|
||||
+void nsGNOMEShellHistorySearchResult::HandleSearchResultReply() {
|
||||
MOZ_ASSERT(mReply);
|
||||
|
||||
uint32_t childCount = 0;
|
||||
@@ -254,6 +356,11 @@
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &iterArray);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && childCount > 0) {
|
||||
+ // Obtain the favicon service and get the favicon for the specified page
|
||||
+ nsCOMPtr<nsIFaviconService> favIconSvc(
|
||||
+ do_GetService("@mozilla.org/browser/favicon-service;1"));
|
||||
+ nsCOMPtr<nsIIOService> ios(do_GetService(NS_IOSERVICE_CONTRACTID));
|
||||
+
|
||||
if (childCount > MAX_SEARCH_RESULTS_NUM) {
|
||||
childCount = MAX_SEARCH_RESULTS_NUM;
|
||||
}
|
||||
@@ -271,6 +378,12 @@
|
||||
nsAutoCString uri;
|
||||
child->GetUri(uri);
|
||||
|
||||
+ nsCOMPtr<nsIURI> iconIri;
|
||||
+ ios->NewURI(uri, nullptr, nullptr, getter_AddRefs(iconIri));
|
||||
+ nsCOMPtr<nsIFaviconDataCallback> callback =
|
||||
+ new AsyncFaviconDataReady(this, i, mTimeStamp);
|
||||
+ favIconSvc->GetFaviconDataForPage(iconIri, callback, 0);
|
||||
+
|
||||
nsAutoCString idKey;
|
||||
DBusGetIDKeyForURI(i, uri, idKey);
|
||||
|
||||
@@ -292,14 +405,36 @@
|
||||
mReply = nullptr;
|
||||
}
|
||||
|
||||
-void nsGNOMEShellHistorySearchResult::SetSearchResultContainer(
|
||||
+void nsGNOMEShellHistorySearchResult::ReceiveSearchResultContainer(
|
||||
nsCOMPtr<nsINavHistoryContainerResultNode> aHistResultContainer) {
|
||||
+ // Propagate search results to nsGNOMEShellSearchProvider.
|
||||
+ // SetSearchResult() checks this is up-to-date search (our time stamp matches
|
||||
+ // latest requested search timestamp).
|
||||
if (mSearchProvider->SetSearchResult(this)) {
|
||||
mHistResultContainer = aHistResultContainer;
|
||||
- SendDBusSearchResultReply();
|
||||
+ HandleSearchResultReply();
|
||||
}
|
||||
}
|
||||
|
||||
+void nsGNOMEShellHistorySearchResult::SetHistoryIcon(int aTimeStamp,
|
||||
+ UniquePtr<uint8_t[]> aData,
|
||||
+ int aWidth, int aHeight,
|
||||
+ int aIconIndex) {
|
||||
+ MOZ_ASSERT(mTimeStamp == aTimeStamp);
|
||||
+ MOZ_RELEASE_ASSERT(aIconIndex < MAX_SEARCH_RESULTS_NUM);
|
||||
+ mHistoryIcons[aIconIndex].Set(mTimeStamp, std::move(aData), aWidth, aHeight);
|
||||
+}
|
||||
+
|
||||
+GnomeHistoryIcon* nsGNOMEShellHistorySearchResult::GetHistoryIcon(
|
||||
+ int aIconIndex) {
|
||||
+ MOZ_RELEASE_ASSERT(aIconIndex < MAX_SEARCH_RESULTS_NUM);
|
||||
+ if (mHistoryIcons[aIconIndex].GetTimeStamp() == mTimeStamp &&
|
||||
+ mHistoryIcons[aIconIndex].IsLoaded()) {
|
||||
+ return mHistoryIcons + aIconIndex;
|
||||
+ }
|
||||
+ return nullptr;
|
||||
+}
|
||||
+
|
||||
nsGNOMEShellHistoryService* GetGNOMEShellHistoryService() {
|
||||
static nsGNOMEShellHistoryService gGNOMEShellHistoryService;
|
||||
return &gGNOMEShellHistoryService;
|
||||
|
15
mozilla-1639197.patch
Normal file
15
mozilla-1639197.patch
Normal file
@ -0,0 +1,15 @@
|
||||
diff --git a/browser/components/shell/nsGNOMEShellDBusHelper.cpp b/browser/components/shell/nsGNOMEShellDBusHelper.cpp
|
||||
--- a/browser/components/shell/nsGNOMEShellDBusHelper.cpp
|
||||
+++ b/browser/components/shell/nsGNOMEShellDBusHelper.cpp
|
||||
@@ -285,7 +285,9 @@
|
||||
nsAutoCString gnomeSearchTitle;
|
||||
if (GetGnomeSearchTitle(searchTerm.get(), gnomeSearchTitle)) {
|
||||
appendStringDictionary(aIter, "name", gnomeSearchTitle.get());
|
||||
- appendStringDictionary(aIter, "gicon", "org.mozilla.Firefox");
|
||||
+ // TODO: When running on flatpak/snap we may need to use
|
||||
+ // icon like org.mozilla.Firefox or so.
|
||||
+ appendStringDictionary(aIter, "gicon", "firefox");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,157 +0,0 @@
|
||||
diff -up firefox-75.0/browser/components/shell/nsGNOMEShellSearchProvider.cpp.gnome-shell-search-fixes firefox-75.0/browser/components/shell/nsGNOMEShellSearchProvider.cpp
|
||||
--- firefox-75.0/browser/components/shell/nsGNOMEShellSearchProvider.cpp.gnome-shell-search-fixes 2020-04-07 08:01:50.587124776 +0200
|
||||
+++ firefox-75.0/browser/components/shell/nsGNOMEShellSearchProvider.cpp 2020-04-07 10:14:02.530380225 +0200
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "nsIStringBundle.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgITools.h"
|
||||
+#include "nsNetCID.h"
|
||||
+#include "nsIIOService.h"
|
||||
|
||||
#include "mozilla/gfx/DataSurfaceHelpers.h"
|
||||
|
||||
@@ -289,20 +291,12 @@ AsyncFaviconDataReady::OnComplete(nsIURI
|
||||
}
|
||||
|
||||
void nsGNOMEShellSearchProvider::ComposeSearchResultReply(
|
||||
- DBusMessage* reply, const char* aSearchTerm) {
|
||||
+ DBusMessage* reply, const char* aSearchTerm, bool aSearchOnly) {
|
||||
uint32_t childCount = 0;
|
||||
- nsresult rv = mHistResultContainer->GetChildCount(&childCount);
|
||||
- if (NS_FAILED(rv) || childCount == 0) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- // Obtain the favicon service and get the favicon for the specified page
|
||||
- nsCOMPtr<nsIFaviconService> favIconSvc(
|
||||
- do_GetService("@mozilla.org/browser/favicon-service;1"));
|
||||
- nsCOMPtr<nsIIOService> ios(do_GetService(NS_IOSERVICE_CONTRACTID));
|
||||
+ nsresult rv = NS_OK;
|
||||
|
||||
- if (childCount > MAX_SEARCH_RESULTS_NUM) {
|
||||
- childCount = MAX_SEARCH_RESULTS_NUM;
|
||||
+ if (!aSearchOnly) {
|
||||
+ nsresult rv = mHistResultContainer->GetChildCount(&childCount);
|
||||
}
|
||||
|
||||
DBusMessageIter iter;
|
||||
@@ -310,30 +304,41 @@ void nsGNOMEShellSearchProvider::Compose
|
||||
DBusMessageIter iterArray;
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &iterArray);
|
||||
|
||||
- for (uint32_t i = 0; i < childCount; i++) {
|
||||
- nsCOMPtr<nsINavHistoryResultNode> child;
|
||||
- mHistResultContainer->GetChild(i, getter_AddRefs(child));
|
||||
- if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
- continue;
|
||||
- }
|
||||
- if (!IsHistoryResultNodeURI(child)) {
|
||||
- continue;
|
||||
+ if (NS_SUCCEEDED(rv) && childCount > 0) {
|
||||
+ // Obtain the favicon service and get the favicon for the specified page
|
||||
+ nsCOMPtr<nsIFaviconService> favIconSvc(
|
||||
+ do_GetService("@mozilla.org/browser/favicon-service;1"));
|
||||
+ nsCOMPtr<nsIIOService> ios(do_GetService(NS_IOSERVICE_CONTRACTID));
|
||||
+
|
||||
+ if (childCount > MAX_SEARCH_RESULTS_NUM) {
|
||||
+ childCount = MAX_SEARCH_RESULTS_NUM;
|
||||
}
|
||||
|
||||
- nsAutoCString uri;
|
||||
- child->GetUri(uri);
|
||||
+ for (uint32_t i = 0; i < childCount; i++) {
|
||||
+ nsCOMPtr<nsINavHistoryResultNode> child;
|
||||
+ mHistResultContainer->GetChild(i, getter_AddRefs(child));
|
||||
+ if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (!child || !IsHistoryResultNodeURI(child)) {
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- nsCOMPtr<nsIURI> iconIri;
|
||||
- ios->NewURI(uri, nullptr, nullptr, getter_AddRefs(iconIri));
|
||||
- nsCOMPtr<nsIFaviconDataCallback> callback =
|
||||
- new AsyncFaviconDataReady(this, i, mSearchSerial);
|
||||
- favIconSvc->GetFaviconDataForPage(iconIri, callback, 0);
|
||||
+ nsAutoCString uri;
|
||||
+ child->GetUri(uri);
|
||||
|
||||
- nsAutoCString idKey;
|
||||
- GetIDKeyForURI(i, uri, idKey);
|
||||
+ nsCOMPtr<nsIURI> iconIri;
|
||||
+ ios->NewURI(uri, nullptr, nullptr, getter_AddRefs(iconIri));
|
||||
+ nsCOMPtr<nsIFaviconDataCallback> callback =
|
||||
+ new AsyncFaviconDataReady(this, i, mSearchSerial);
|
||||
+ favIconSvc->GetFaviconDataForPage(iconIri, callback, 0);
|
||||
|
||||
- const char* id = idKey.get();
|
||||
- dbus_message_iter_append_basic(&iterArray, DBUS_TYPE_STRING, &id);
|
||||
+ nsAutoCString idKey;
|
||||
+ GetIDKeyForURI(i, uri, idKey);
|
||||
+
|
||||
+ const char* id = idKey.get();
|
||||
+ dbus_message_iter_append_basic(&iterArray, DBUS_TYPE_STRING, &id);
|
||||
+ }
|
||||
}
|
||||
|
||||
nsPrintfCString searchString("%s:%s", KEYWORD_SEARCH_STRING, aSearchTerm);
|
||||
@@ -346,7 +351,7 @@ void nsGNOMEShellSearchProvider::Compose
|
||||
DBusHandlerResult nsGNOMEShellSearchProvider::GetInitialResultSet(
|
||||
DBusMessage* aMsg) {
|
||||
DBusMessage* reply;
|
||||
- char** stringArray;
|
||||
+ char** stringArray = nullptr;
|
||||
int elements;
|
||||
|
||||
if (!dbus_message_get_args(aMsg, nullptr, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
|
||||
@@ -356,9 +361,10 @@ DBusHandlerResult nsGNOMEShellSearchProv
|
||||
} else {
|
||||
reply = dbus_message_new_method_return(aMsg);
|
||||
nsresult rv = NewHistorySearch(stringArray[0]);
|
||||
- if (NS_SUCCEEDED(rv)) {
|
||||
- ComposeSearchResultReply(reply, stringArray[0]);
|
||||
- }
|
||||
+ ComposeSearchResultReply(reply, stringArray[0],
|
||||
+ /* search only */ NS_FAILED(rv));
|
||||
+ }
|
||||
+ if (stringArray) {
|
||||
dbus_free_string_array(stringArray);
|
||||
}
|
||||
|
||||
@@ -384,9 +390,8 @@ DBusHandlerResult nsGNOMEShellSearchProv
|
||||
} else {
|
||||
reply = dbus_message_new_method_return(aMsg);
|
||||
nsresult rv = NewHistorySearch(stringArray[0]);
|
||||
- if (NS_SUCCEEDED(rv)) {
|
||||
- ComposeSearchResultReply(reply, stringArray[0]);
|
||||
- }
|
||||
+ ComposeSearchResultReply(reply, stringArray[0],
|
||||
+ /* search only */ NS_FAILED(rv));
|
||||
}
|
||||
|
||||
if (unusedArray) {
|
||||
@@ -556,6 +561,10 @@ void nsGNOMEShellSearchProvider::LaunchW
|
||||
nsCOMPtr<nsINavHistoryResultNode> child;
|
||||
mHistResultContainer->GetChild(keyIndex, getter_AddRefs(child));
|
||||
|
||||
+ if (!child) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
nsAutoCString uri;
|
||||
nsresult rv = child->GetUri(uri);
|
||||
if (NS_FAILED(rv)) {
|
||||
diff -up firefox-75.0/browser/components/shell/nsGNOMEShellSearchProvider.h.gnome-shell-search-fixes firefox-75.0/browser/components/shell/nsGNOMEShellSearchProvider.h
|
||||
--- firefox-75.0/browser/components/shell/nsGNOMEShellSearchProvider.h.gnome-shell-search-fixes 2020-04-07 08:01:50.587124776 +0200
|
||||
+++ firefox-75.0/browser/components/shell/nsGNOMEShellSearchProvider.h 2020-04-07 09:56:30.857553820 +0200
|
||||
@@ -70,7 +70,8 @@ class nsGNOMEShellSearchProvider : publi
|
||||
bool IsHistoryResultNodeURI(nsINavHistoryResultNode* aHistoryNode);
|
||||
void AppendResultID(DBusMessageIter* aIter, const char* aID);
|
||||
void AppendSearchID(DBusMessageIter* aIter, const char* aID);
|
||||
- void ComposeSearchResultReply(DBusMessage* aReply, const char* aSearchTerm);
|
||||
+ void ComposeSearchResultReply(DBusMessage* aReply, const char* aSearchTerm,
|
||||
+ bool aSearchOnly);
|
||||
void LaunchWithID(const char* aID, uint32_t aTimeStamp);
|
||||
void LaunchWithAllResults(uint32_t aTimeStamp);
|
||||
|
@ -1,453 +0,0 @@
|
||||
changeset: 504680:441b26f2d4f4
|
||||
parent: 504674:5a55ac856fc4
|
||||
user: Martin Stransky <stransky@redhat.com>
|
||||
date: Mon Dec 02 12:21:08 2019 +0100
|
||||
files: browser/components/shell/nsGNOMEShellSearchProvider.cpp browser/components/shell/nsGNOMEShellSearchProvider.h
|
||||
description:
|
||||
Bug 1239694 Use history icons with Gnome shell search provider, r?jhorak
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D55434
|
||||
|
||||
|
||||
diff --git a/browser/components/shell/nsGNOMEShellSearchProvider.cpp b/browser/components/shell/nsGNOMEShellSearchProvider.cpp
|
||||
--- a/browser/components/shell/nsGNOMEShellSearchProvider.cpp
|
||||
+++ b/browser/components/shell/nsGNOMEShellSearchProvider.cpp
|
||||
@@ -19,21 +19,27 @@
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsGTKToolkit.h"
|
||||
#include "nsINavHistoryService.h"
|
||||
#include "nsToolkitCompsCID.h"
|
||||
#include "nsIFaviconService.h"
|
||||
#include "RemoteUtils.h"
|
||||
#include "nsIStringBundle.h"
|
||||
+#include "imgIContainer.h"
|
||||
+#include "imgITools.h"
|
||||
+
|
||||
+#include "mozilla/gfx/DataSurfaceHelpers.h"
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
#include <dbus/dbus-glib-lowlevel.h>
|
||||
|
||||
-#define MAX_SEARCH_RESULTS_NUM 9
|
||||
+using namespace mozilla;
|
||||
+using namespace mozilla::gfx;
|
||||
+
|
||||
#define KEYWORD_SEARCH_STRING "special:search"
|
||||
#define KEYWORD_SEARCH_STRING_LEN 14
|
||||
|
||||
#define DBUS_BUS_NAME "org.mozilla.Firefox.SearchProvider"
|
||||
#define DBUS_OBJECT_PATH "/org/mozilla/Firefox/SearchProvider"
|
||||
|
||||
static const char* introspect_template =
|
||||
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection "
|
||||
@@ -81,17 +87,35 @@ DBusHandlerResult nsGNOMEShellSearchProv
|
||||
DBUS_TYPE_INVALID);
|
||||
|
||||
dbus_connection_send(mConnection, reply, nullptr);
|
||||
dbus_message_unref(reply);
|
||||
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
-nsresult nsGNOMEShellSearchProvider::QueryHistory(const char* aSearchTerm) {
|
||||
+nsGNOMEShellSearchProvider::nsGNOMEShellSearchProvider()
|
||||
+ : mConnection(nullptr), mSearchSerial(0) {
|
||||
+ memset(mHistoryIcons, 0, sizeof(mHistoryIcons));
|
||||
+}
|
||||
+
|
||||
+void nsGNOMEShellSearchProvider::SetHistoryIcon(int aSearchSerial,
|
||||
+ UniquePtr<uint8_t[]> aData,
|
||||
+ int aWidth, int aHeight,
|
||||
+ int aIconIndex) {
|
||||
+ MOZ_ASSERT(mSearchSerial == aSearchSerial);
|
||||
+ MOZ_ASSERT(aIconIndex < MAX_SEARCH_RESULTS_NUM);
|
||||
+ mHistoryIcons[aIconIndex].Set(aSearchSerial, std::move(aData), aWidth,
|
||||
+ aHeight);
|
||||
+}
|
||||
+
|
||||
+nsresult nsGNOMEShellSearchProvider::NewHistorySearch(const char* aSearchTerm) {
|
||||
+ // Initialize new search which invalidates all preview ones
|
||||
+ mSearchSerial++;
|
||||
+
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsINavHistoryQuery> histQuery;
|
||||
rv = mHistoryService->GetNewQuery(getter_AddRefs(histQuery));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoCString searchTerm(aSearchTerm);
|
||||
rv = histQuery->SetSearchTerms(NS_ConvertUTF8toUTF16(searchTerm));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@@ -165,24 +189,123 @@ void nsGNOMEShellSearchProvider::GetIDKe
|
||||
|
||||
int nsGNOMEShellSearchProvider::GetIndexFromIDKey(const char* aIDKey) {
|
||||
// ID is NN:URL where NN is index to our current history
|
||||
// result container.
|
||||
char tmp[] = {aIDKey[0], aIDKey[1], '\0'};
|
||||
return atoi(tmp);
|
||||
}
|
||||
|
||||
+class AsyncFaviconDataReady final : public nsIFaviconDataCallback {
|
||||
+ public:
|
||||
+ NS_DECL_ISUPPORTS
|
||||
+ NS_DECL_NSIFAVICONDATACALLBACK
|
||||
+
|
||||
+ AsyncFaviconDataReady(nsGNOMEShellSearchProvider* aSearchProvider,
|
||||
+ int aIconIndex, int aSearchSerial)
|
||||
+ : mSearchProvider(aSearchProvider),
|
||||
+ mIconIndex(aIconIndex),
|
||||
+ mSearchSerial(aSearchSerial){};
|
||||
+
|
||||
+ private:
|
||||
+ ~AsyncFaviconDataReady() {}
|
||||
+
|
||||
+ nsGNOMEShellSearchProvider* mSearchProvider;
|
||||
+ int mIconIndex;
|
||||
+ int mSearchSerial;
|
||||
+};
|
||||
+
|
||||
+NS_IMPL_ISUPPORTS(AsyncFaviconDataReady, nsIFaviconDataCallback)
|
||||
+
|
||||
+// Inspired by SurfaceToPackedBGRA
|
||||
+static UniquePtr<uint8_t[]> SurfaceToPackedRGBA(DataSourceSurface* aSurface) {
|
||||
+ IntSize size = aSurface->GetSize();
|
||||
+ CheckedInt<size_t> bufferSize =
|
||||
+ CheckedInt<size_t>(size.width * 4) * CheckedInt<size_t>(size.height);
|
||||
+ if (!bufferSize.isValid()) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ UniquePtr<uint8_t[]> imageBuffer(new (std::nothrow)
|
||||
+ uint8_t[bufferSize.value()]);
|
||||
+ if (!imageBuffer) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ DataSourceSurface::MappedSurface map;
|
||||
+ if (!aSurface->Map(DataSourceSurface::MapType::READ, &map)) {
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+
|
||||
+ // Convert BGRA to RGBA
|
||||
+ uint32_t* aSrc = (uint32_t*)map.mData;
|
||||
+ uint32_t* aDst = (uint32_t*)imageBuffer.get();
|
||||
+ for (int i = 0; i < size.width * size.height; i++, aDst++, aSrc++) {
|
||||
+ *aDst = *aSrc & 0xff00ff00;
|
||||
+ *aDst |= (*aSrc & 0xff) << 16;
|
||||
+ *aDst |= (*aSrc & 0xff0000) >> 16;
|
||||
+ }
|
||||
+
|
||||
+ aSurface->Unmap();
|
||||
+
|
||||
+ return imageBuffer;
|
||||
+}
|
||||
+
|
||||
+NS_IMETHODIMP
|
||||
+AsyncFaviconDataReady::OnComplete(nsIURI* aFaviconURI, uint32_t aDataLen,
|
||||
+ const uint8_t* aData,
|
||||
+ const nsACString& aMimeType,
|
||||
+ uint16_t aWidth) {
|
||||
+ // This is a callback from some previous search so we don't want it
|
||||
+ if (mSearchSerial != mSearchProvider->GetSearchSerial() || !aData ||
|
||||
+ !aDataLen) {
|
||||
+ return NS_ERROR_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ // Decode the image from the format it was returned to us in (probably PNG)
|
||||
+ nsCOMPtr<imgIContainer> container;
|
||||
+ nsCOMPtr<imgITools> imgtool = do_CreateInstance("@mozilla.org/image/tools;1");
|
||||
+ nsresult rv = imgtool->DecodeImageFromBuffer(
|
||||
+ reinterpret_cast<const char*>(aData), aDataLen, aMimeType,
|
||||
+ getter_AddRefs(container));
|
||||
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||
+
|
||||
+ RefPtr<SourceSurface> surface = container->GetFrame(
|
||||
+ imgIContainer::FRAME_FIRST,
|
||||
+ imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_ASYNC_NOTIFY);
|
||||
+
|
||||
+ if (!surface || surface->GetFormat() != SurfaceFormat::B8G8R8A8) {
|
||||
+ return NS_ERROR_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ // Allocate a new buffer that we own.
|
||||
+ RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
|
||||
+ UniquePtr<uint8_t[]> data = SurfaceToPackedRGBA(dataSurface);
|
||||
+ if (!data) {
|
||||
+ return NS_ERROR_OUT_OF_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ mSearchProvider->SetHistoryIcon(mSearchSerial, std::move(data),
|
||||
+ surface->GetSize().width,
|
||||
+ surface->GetSize().height, mIconIndex);
|
||||
+ return NS_OK;
|
||||
+}
|
||||
+
|
||||
void nsGNOMEShellSearchProvider::ComposeSearchResultReply(
|
||||
DBusMessage* reply, const char* aSearchTerm) {
|
||||
uint32_t childCount = 0;
|
||||
nsresult rv = mHistResultContainer->GetChildCount(&childCount);
|
||||
if (NS_FAILED(rv) || childCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
+ // Obtain the favicon service and get the favicon for the specified page
|
||||
+ nsCOMPtr<nsIFaviconService> favIconSvc(
|
||||
+ do_GetService("@mozilla.org/browser/favicon-service;1"));
|
||||
+ nsCOMPtr<nsIIOService> ios(do_GetService(NS_IOSERVICE_CONTRACTID));
|
||||
+
|
||||
if (childCount > MAX_SEARCH_RESULTS_NUM) {
|
||||
childCount = MAX_SEARCH_RESULTS_NUM;
|
||||
}
|
||||
|
||||
DBusMessageIter iter;
|
||||
dbus_message_iter_init_append(reply, &iter);
|
||||
DBusMessageIter iterArray;
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &iterArray);
|
||||
@@ -195,16 +318,22 @@ void nsGNOMEShellSearchProvider::Compose
|
||||
}
|
||||
if (!IsHistoryResultNodeURI(child)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAutoCString uri;
|
||||
child->GetUri(uri);
|
||||
|
||||
+ nsCOMPtr<nsIURI> iconIri;
|
||||
+ ios->NewURI(uri, nullptr, nullptr, getter_AddRefs(iconIri));
|
||||
+ nsCOMPtr<nsIFaviconDataCallback> callback =
|
||||
+ new AsyncFaviconDataReady(this, i, mSearchSerial);
|
||||
+ favIconSvc->GetFaviconDataForPage(iconIri, callback, 0);
|
||||
+
|
||||
nsAutoCString idKey;
|
||||
GetIDKeyForURI(i, uri, idKey);
|
||||
|
||||
const char* id = idKey.get();
|
||||
dbus_message_iter_append_basic(&iterArray, DBUS_TYPE_STRING, &id);
|
||||
}
|
||||
|
||||
nsPrintfCString searchString("%s:%s", KEYWORD_SEARCH_STRING, aSearchTerm);
|
||||
@@ -221,17 +350,17 @@ DBusHandlerResult nsGNOMEShellSearchProv
|
||||
int elements;
|
||||
|
||||
if (!dbus_message_get_args(aMsg, nullptr, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
|
||||
&stringArray, &elements, DBUS_TYPE_INVALID) ||
|
||||
elements == 0) {
|
||||
reply = dbus_message_new_error(aMsg, DBUS_BUS_NAME, "Wrong argument");
|
||||
} else {
|
||||
reply = dbus_message_new_method_return(aMsg);
|
||||
- nsresult rv = QueryHistory(stringArray[0]);
|
||||
+ nsresult rv = NewHistorySearch(stringArray[0]);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
ComposeSearchResultReply(reply, stringArray[0]);
|
||||
}
|
||||
dbus_free_string_array(stringArray);
|
||||
}
|
||||
|
||||
dbus_connection_send(mConnection, reply, nullptr);
|
||||
dbus_message_unref(reply);
|
||||
@@ -249,17 +378,17 @@ DBusHandlerResult nsGNOMEShellSearchProv
|
||||
if (!dbus_message_get_args(aMsg, nullptr, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
|
||||
&unusedArray, &unusedNum, DBUS_TYPE_ARRAY,
|
||||
DBUS_TYPE_STRING, &stringArray, &elements,
|
||||
DBUS_TYPE_INVALID) ||
|
||||
elements == 0) {
|
||||
reply = dbus_message_new_error(aMsg, DBUS_BUS_NAME, "Wrong argument");
|
||||
} else {
|
||||
reply = dbus_message_new_method_return(aMsg);
|
||||
- nsresult rv = QueryHistory(stringArray[0]);
|
||||
+ nsresult rv = NewHistorySearch(stringArray[0]);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
ComposeSearchResultReply(reply, stringArray[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (unusedArray) {
|
||||
dbus_free_string_array(unusedArray);
|
||||
}
|
||||
@@ -280,45 +409,88 @@ static void appendStringDictionary(DBusM
|
||||
&iterDict);
|
||||
dbus_message_iter_append_basic(&iterDict, DBUS_TYPE_STRING, &aKey);
|
||||
dbus_message_iter_open_container(&iterDict, DBUS_TYPE_VARIANT, "s", &iterVar);
|
||||
dbus_message_iter_append_basic(&iterVar, DBUS_TYPE_STRING, &aValue);
|
||||
dbus_message_iter_close_container(&iterDict, &iterVar);
|
||||
dbus_message_iter_close_container(aIter, &iterDict);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ "icon-data": a tuple of type (iiibiiay) describing a pixbuf with width,
|
||||
+ height, rowstride, has-alpha,
|
||||
+ bits-per-sample, channels,
|
||||
+ image data
|
||||
+*/
|
||||
+void GnomeHistoryIcon::AppendIcon(DBusMessageIter* aIter) {
|
||||
+ DBusMessageIter iterDict, iterVar, iterStruct;
|
||||
+ dbus_message_iter_open_container(aIter, DBUS_TYPE_DICT_ENTRY, nullptr,
|
||||
+ &iterDict);
|
||||
+ const char* key = "icon-data";
|
||||
+ dbus_message_iter_append_basic(&iterDict, DBUS_TYPE_STRING, &key);
|
||||
+ dbus_message_iter_open_container(&iterDict, DBUS_TYPE_VARIANT, "(iiibiiay)",
|
||||
+ &iterVar);
|
||||
+ dbus_message_iter_open_container(&iterVar, DBUS_TYPE_STRUCT, nullptr,
|
||||
+ &iterStruct);
|
||||
+
|
||||
+ dbus_message_iter_append_basic(&iterStruct, DBUS_TYPE_INT32, &mWidth);
|
||||
+ dbus_message_iter_append_basic(&iterStruct, DBUS_TYPE_INT32, &mHeight);
|
||||
+ int rowstride = mWidth * 4;
|
||||
+ dbus_message_iter_append_basic(&iterStruct, DBUS_TYPE_INT32, &rowstride);
|
||||
+ int hasAlpha = true;
|
||||
+ dbus_message_iter_append_basic(&iterStruct, DBUS_TYPE_BOOLEAN, &hasAlpha);
|
||||
+ int bitsPerSample = 8;
|
||||
+ dbus_message_iter_append_basic(&iterStruct, DBUS_TYPE_INT32, &bitsPerSample);
|
||||
+ int channels = 4;
|
||||
+ dbus_message_iter_append_basic(&iterStruct, DBUS_TYPE_INT32, &channels);
|
||||
+
|
||||
+ DBusMessageIter iterArray;
|
||||
+ dbus_message_iter_open_container(&iterStruct, DBUS_TYPE_ARRAY, "y",
|
||||
+ &iterArray);
|
||||
+ unsigned char* array = mData.get();
|
||||
+ dbus_message_iter_append_fixed_array(&iterArray, DBUS_TYPE_BYTE, &array,
|
||||
+ mWidth * mHeight * 4);
|
||||
+ dbus_message_iter_close_container(&iterStruct, &iterArray);
|
||||
+
|
||||
+ dbus_message_iter_close_container(&iterVar, &iterStruct);
|
||||
+ dbus_message_iter_close_container(&iterDict, &iterVar);
|
||||
+ dbus_message_iter_close_container(aIter, &iterDict);
|
||||
+}
|
||||
+
|
||||
/* We can return those fields at GetResultMetas:
|
||||
"id": the result ID
|
||||
"name": the display name for the result
|
||||
"icon": a serialized GIcon (see g_icon_serialize()), or alternatively,
|
||||
"gicon": a textual representation of a GIcon (see g_icon_to_string()),
|
||||
or alternativly,
|
||||
"icon-data": a tuple of type (iiibiiay) describing a pixbuf with width,
|
||||
height, rowstride, has-alpha, bits-per-sample, and image data
|
||||
"description": an optional short description (1-2 lines)
|
||||
*/
|
||||
void nsGNOMEShellSearchProvider::AppendResultID(DBusMessageIter* aIter,
|
||||
const char* aID) {
|
||||
+ int index = GetIndexFromIDKey(aID);
|
||||
nsCOMPtr<nsINavHistoryResultNode> child;
|
||||
- mHistResultContainer->GetChild(GetIndexFromIDKey(aID), getter_AddRefs(child));
|
||||
+ mHistResultContainer->GetChild(index, getter_AddRefs(child));
|
||||
nsAutoCString title;
|
||||
- if (NS_FAILED(child->GetTitle(title))) {
|
||||
- return;
|
||||
- }
|
||||
+ nsAutoCString uri;
|
||||
+ child->GetTitle(title);
|
||||
+ child->GetUri(uri);
|
||||
|
||||
- if (title.IsEmpty()) {
|
||||
- if (NS_FAILED(child->GetUri(title)) || title.IsEmpty()) {
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
+ const char* titleStr = !(title.IsEmpty()) ? title.get() : uri.get();
|
||||
+ const char* descStr = uri.get();
|
||||
|
||||
- const char* titleStr = title.get();
|
||||
appendStringDictionary(aIter, "id", aID);
|
||||
appendStringDictionary(aIter, "name", titleStr);
|
||||
- appendStringDictionary(aIter, "gicon", "text-html");
|
||||
+ appendStringDictionary(aIter, "description", descStr);
|
||||
+ if (mHistoryIcons[index].GetSearchSerial() == mSearchSerial) {
|
||||
+ mHistoryIcons[index].AppendIcon(aIter);
|
||||
+ } else {
|
||||
+ appendStringDictionary(aIter, "gicon", "text-html");
|
||||
+ }
|
||||
}
|
||||
|
||||
void nsGNOMEShellSearchProvider::AppendSearchID(DBusMessageIter* aIter,
|
||||
const char* aID) {
|
||||
if (strlen(aID) < KEYWORD_SEARCH_STRING_LEN + 2) {
|
||||
return;
|
||||
}
|
||||
appendStringDictionary(aIter, "id", KEYWORD_SEARCH_STRING);
|
||||
diff --git a/browser/components/shell/nsGNOMEShellSearchProvider.h b/browser/components/shell/nsGNOMEShellSearchProvider.h
|
||||
--- a/browser/components/shell/nsGNOMEShellSearchProvider.h
|
||||
+++ b/browser/components/shell/nsGNOMEShellSearchProvider.h
|
||||
@@ -7,49 +7,81 @@
|
||||
|
||||
#ifndef __nsGNOMEShellSearchProvider_h__
|
||||
#define __nsGNOMEShellSearchProvider_h__
|
||||
|
||||
#include "mozilla/DBusHelpers.h"
|
||||
#include "nsINavHistoryService.h"
|
||||
#include "nsUnixRemoteServer.h"
|
||||
#include "nsCOMPtr.h"
|
||||
+#include "mozilla/UniquePtr.h"
|
||||
+
|
||||
+#define MAX_SEARCH_RESULTS_NUM 9
|
||||
+
|
||||
+class GnomeHistoryIcon {
|
||||
+ public:
|
||||
+ GnomeHistoryIcon() : mSearchSerial(-1), mWidth(0), mHeight(0){};
|
||||
+
|
||||
+ // From which search is this icon
|
||||
+ void Set(int aSearchSerial, mozilla::UniquePtr<uint8_t[]> aData, int aWidth,
|
||||
+ int aHeight) {
|
||||
+ mSearchSerial = aSearchSerial;
|
||||
+ mWidth = aWidth;
|
||||
+ mHeight = aHeight;
|
||||
+ mData = std::move(aData);
|
||||
+ }
|
||||
+
|
||||
+ int GetSearchSerial() { return mSearchSerial; }
|
||||
+ void AppendIcon(DBusMessageIter* aIter);
|
||||
+
|
||||
+ private:
|
||||
+ int mSearchSerial;
|
||||
+ mozilla::UniquePtr<uint8_t[]> mData;
|
||||
+ int mWidth;
|
||||
+ int mHeight;
|
||||
+};
|
||||
|
||||
class nsGNOMEShellSearchProvider : public nsUnixRemoteServer {
|
||||
public:
|
||||
- nsGNOMEShellSearchProvider() : mConnection(nullptr) {}
|
||||
+ nsGNOMEShellSearchProvider();
|
||||
~nsGNOMEShellSearchProvider() { Shutdown(); }
|
||||
|
||||
nsresult Startup();
|
||||
void Shutdown();
|
||||
|
||||
DBusHandlerResult HandleDBusMessage(DBusConnection* aConnection,
|
||||
DBusMessage* msg);
|
||||
void UnregisterDBusInterface(DBusConnection* aConnection);
|
||||
|
||||
+ int GetSearchSerial() { return mSearchSerial; }
|
||||
+ void SetHistoryIcon(int aSearchSerial, mozilla::UniquePtr<uint8_t[]> aData,
|
||||
+ int aWidth, int aHeight, int aIconIndex);
|
||||
+
|
||||
private:
|
||||
DBusHandlerResult Introspect(DBusMessage* msg);
|
||||
|
||||
DBusHandlerResult GetInitialResultSet(DBusMessage* msg);
|
||||
DBusHandlerResult GetSubsearchResultSet(DBusMessage* msg);
|
||||
DBusHandlerResult GetResultMetas(DBusMessage* msg);
|
||||
DBusHandlerResult ActivateResult(DBusMessage* msg);
|
||||
DBusHandlerResult LaunchSearch(DBusMessage* msg);
|
||||
|
||||
- nsresult QueryHistory(const char* aSearchTerm);
|
||||
+ nsresult NewHistorySearch(const char* aSearchTerm);
|
||||
void GetIDKeyForURI(int aIndex, nsAutoCString& aUri, nsAutoCString& aIDKey);
|
||||
int GetIndexFromIDKey(const char* aIDKey);
|
||||
bool IsHistoryResultNodeURI(nsINavHistoryResultNode* aHistoryNode);
|
||||
void AppendResultID(DBusMessageIter* aIter, const char* aID);
|
||||
void AppendSearchID(DBusMessageIter* aIter, const char* aID);
|
||||
void ComposeSearchResultReply(DBusMessage* aReply, const char* aSearchTerm);
|
||||
void LaunchWithID(const char* aID, uint32_t aTimeStamp);
|
||||
void LaunchWithAllResults(uint32_t aTimeStamp);
|
||||
|
||||
// The connection is owned by DBus library
|
||||
RefPtr<DBusConnection> mConnection;
|
||||
nsCOMPtr<nsINavHistoryContainerResultNode> mHistResultContainer;
|
||||
nsCOMPtr<nsINavHistoryService> mHistoryService;
|
||||
nsAutoCStringN<32> mSearchTerm;
|
||||
nsAutoCString mGnomeSearchTitle;
|
||||
+ int mSearchSerial;
|
||||
+ GnomeHistoryIcon mHistoryIcons[MAX_SEARCH_RESULTS_NUM];
|
||||
};
|
||||
|
||||
#endif // __nsGNOMEShellSearchProvider_h__
|
||||
|
@ -1,786 +0,0 @@
|
||||
diff -up firefox-73.0/browser/components/shell/moz.build.gnome-shell-search-provider firefox-73.0/browser/components/shell/moz.build
|
||||
--- firefox-73.0/browser/components/shell/moz.build.gnome-shell-search-provider 2020-02-07 22:12:59.000000000 +0100
|
||||
+++ firefox-73.0/browser/components/shell/moz.build 2020-02-11 09:03:31.638803105 +0100
|
||||
@@ -34,6 +34,11 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gt
|
||||
SOURCES += [
|
||||
'nsGNOMEShellService.cpp',
|
||||
]
|
||||
+ if CONFIG['MOZ_ENABLE_DBUS']:
|
||||
+ SOURCES += [
|
||||
+ 'nsGNOMEShellSearchProvider.cpp',
|
||||
+ ]
|
||||
+
|
||||
elif CONFIG['OS_ARCH'] == 'WINNT':
|
||||
XPIDL_SOURCES += [
|
||||
'nsIWindowsShellService.idl',
|
||||
@@ -60,6 +65,8 @@ for var in ('MOZ_APP_NAME', 'MOZ_APP_VER
|
||||
DEFINES[var] = '"%s"' % CONFIG[var]
|
||||
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
+if CONFIG['MOZ_ENABLE_DBUS']:
|
||||
+ CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Firefox', 'Shell Integration')
|
||||
diff -up firefox-73.0/browser/components/shell/nsGNOMEShellSearchProvider.cpp.gnome-shell-search-provider firefox-73.0/browser/components/shell/nsGNOMEShellSearchProvider.cpp
|
||||
--- firefox-73.0/browser/components/shell/nsGNOMEShellSearchProvider.cpp.gnome-shell-search-provider 2020-02-11 09:00:59.350512802 +0100
|
||||
+++ firefox-73.0/browser/components/shell/nsGNOMEShellSearchProvider.cpp 2020-02-11 09:00:59.350512802 +0100
|
||||
@@ -0,0 +1,621 @@
|
||||
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
+/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
+ */
|
||||
+/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
+
|
||||
+#include "nsGNOMEShellSearchProvider.h"
|
||||
+
|
||||
+#include "nsIBaseWindow.h"
|
||||
+#include "nsIDocShell.h"
|
||||
+#include "nsPIDOMWindow.h"
|
||||
+#include "mozilla/ModuleUtils.h"
|
||||
+#include "mozilla/Base64.h"
|
||||
+#include "nsIServiceManager.h"
|
||||
+#include "nsIWidget.h"
|
||||
+#include "nsIAppShellService.h"
|
||||
+#include "nsAppShellCID.h"
|
||||
+#include "nsPrintfCString.h"
|
||||
+#include "nsCOMPtr.h"
|
||||
+#include "nsGTKToolkit.h"
|
||||
+#include "nsINavHistoryService.h"
|
||||
+#include "nsToolkitCompsCID.h"
|
||||
+#include "nsIFaviconService.h"
|
||||
+#include "RemoteUtils.h"
|
||||
+#include "nsIStringBundle.h"
|
||||
+
|
||||
+#include <dbus/dbus.h>
|
||||
+#include <dbus/dbus-glib-lowlevel.h>
|
||||
+
|
||||
+#define MAX_SEARCH_RESULTS_NUM 9
|
||||
+#define KEYWORD_SEARCH_STRING "special:search"
|
||||
+#define KEYWORD_SEARCH_STRING_LEN 14
|
||||
+
|
||||
+#define DBUS_BUS_NAME "org.mozilla.Firefox.SearchProvider"
|
||||
+#define DBUS_OBJECT_PATH "/org/mozilla/Firefox/SearchProvider"
|
||||
+
|
||||
+static const char* introspect_template =
|
||||
+ "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection "
|
||||
+ "1.0//EN\"\n"
|
||||
+ "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\";>\n"
|
||||
+ "<node>\n"
|
||||
+ " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
|
||||
+ " <method name=\"Introspect\">\n"
|
||||
+ " <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
|
||||
+ " </method>\n"
|
||||
+ " </interface>\n"
|
||||
+ " <interface name=\"org.gnome.Shell.SearchProvider2\">\n"
|
||||
+ " <method name=\"GetInitialResultSet\">\n"
|
||||
+ " <arg type=\"as\" name=\"terms\" direction=\"in\" />\n"
|
||||
+ " <arg type=\"as\" name=\"results\" direction=\"out\" />\n"
|
||||
+ " </method>\n"
|
||||
+ " <method name=\"GetSubsearchResultSet\">\n"
|
||||
+ " <arg type=\"as\" name=\"previous_results\" direction=\"in\" />\n"
|
||||
+ " <arg type=\"as\" name=\"terms\" direction=\"in\" />\n"
|
||||
+ " <arg type=\"as\" name=\"results\" direction=\"out\" />\n"
|
||||
+ " </method>\n"
|
||||
+ " <method name=\"GetResultMetas\">\n"
|
||||
+ " <arg type=\"as\" name=\"identifiers\" direction=\"in\" />\n"
|
||||
+ " <arg type=\"aa{sv}\" name=\"metas\" direction=\"out\" />\n"
|
||||
+ " </method>\n"
|
||||
+ " <method name=\"ActivateResult\">\n"
|
||||
+ " <arg type=\"s\" name=\"identifier\" direction=\"in\" />\n"
|
||||
+ " <arg type=\"as\" name=\"terms\" direction=\"in\" />\n"
|
||||
+ " <arg type=\"u\" name=\"timestamp\" direction=\"in\" />\n"
|
||||
+ " </method>\n"
|
||||
+ " <method name=\"LaunchSearch\">\n"
|
||||
+ " <arg type=\"as\" name=\"terms\" direction=\"in\" />\n"
|
||||
+ " <arg type=\"u\" name=\"timestamp\" direction=\"in\" />\n"
|
||||
+ " </method>\n"
|
||||
+ "</interface>\n"
|
||||
+ "</node>\n";
|
||||
+
|
||||
+DBusHandlerResult nsGNOMEShellSearchProvider::Introspect(DBusMessage* aMsg) {
|
||||
+ DBusMessage* reply;
|
||||
+
|
||||
+ reply = dbus_message_new_method_return(aMsg);
|
||||
+ if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY;
|
||||
+
|
||||
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspect_template,
|
||||
+ DBUS_TYPE_INVALID);
|
||||
+
|
||||
+ dbus_connection_send(mConnection, reply, nullptr);
|
||||
+ dbus_message_unref(reply);
|
||||
+
|
||||
+ return DBUS_HANDLER_RESULT_HANDLED;
|
||||
+}
|
||||
+
|
||||
+nsresult nsGNOMEShellSearchProvider::QueryHistory(const char* aSearchTerm) {
|
||||
+ nsresult rv;
|
||||
+ nsCOMPtr<nsINavHistoryQuery> histQuery;
|
||||
+ rv = mHistoryService->GetNewQuery(getter_AddRefs(histQuery));
|
||||
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||
+
|
||||
+ nsAutoCString searchTerm(aSearchTerm);
|
||||
+ rv = histQuery->SetSearchTerms(NS_ConvertUTF8toUTF16(searchTerm));
|
||||
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||
+
|
||||
+ nsCOMPtr<nsINavHistoryQueryOptions> histQueryOpts;
|
||||
+ rv = mHistoryService->GetNewQueryOptions(getter_AddRefs(histQueryOpts));
|
||||
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||
+
|
||||
+ // We want to get the URIs for every item in the user's history with the
|
||||
+ // given host
|
||||
+ rv = histQueryOpts->SetResultType(nsINavHistoryQueryOptions::RESULTS_AS_URI);
|
||||
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||
+
|
||||
+ rv = histQueryOpts->SetSortingMode(
|
||||
+ nsINavHistoryQueryOptions::SORT_BY_VISITCOUNT_DESCENDING);
|
||||
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||
+
|
||||
+ rv = histQueryOpts->SetMaxResults(MAX_SEARCH_RESULTS_NUM);
|
||||
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||
+
|
||||
+ // We only search history, because searching both bookmarks and history
|
||||
+ // is not supported, and history tends to be more comprehensive.
|
||||
+ rv = histQueryOpts->SetQueryType(
|
||||
+ nsINavHistoryQueryOptions::QUERY_TYPE_HISTORY);
|
||||
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||
+
|
||||
+ nsCOMPtr<nsINavHistoryResult> histResult;
|
||||
+ rv = mHistoryService->ExecuteQuery(histQuery, histQueryOpts,
|
||||
+ getter_AddRefs(histResult));
|
||||
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||
+
|
||||
+ // Delete former search results
|
||||
+ mHistResultContainer = nullptr;
|
||||
+
|
||||
+ rv = histResult->GetRoot(getter_AddRefs(mHistResultContainer));
|
||||
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||
+
|
||||
+ rv = mHistResultContainer->SetContainerOpen(true);
|
||||
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||
+
|
||||
+ uint32_t childCount = 0;
|
||||
+ rv = mHistResultContainer->GetChildCount(&childCount);
|
||||
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||
+
|
||||
+ return childCount != 0 ? NS_OK : NS_ERROR_FAILURE;
|
||||
+}
|
||||
+
|
||||
+bool nsGNOMEShellSearchProvider::IsHistoryResultNodeURI(
|
||||
+ nsINavHistoryResultNode* aHistoryNode) {
|
||||
+ uint32_t type;
|
||||
+ nsresult rv = aHistoryNode->GetType(&type);
|
||||
+ if (NS_FAILED(rv) || type != nsINavHistoryResultNode::RESULT_TYPE_URI)
|
||||
+ return false;
|
||||
+
|
||||
+ nsAutoCString title;
|
||||
+ rv = aHistoryNode->GetTitle(title);
|
||||
+ if (NS_SUCCEEDED(rv) && !title.IsEmpty()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ rv = aHistoryNode->GetUri(title);
|
||||
+ return NS_SUCCEEDED(rv) && !title.IsEmpty();
|
||||
+}
|
||||
+
|
||||
+void nsGNOMEShellSearchProvider::GetIDKeyForURI(int aIndex, nsAutoCString& aUri,
|
||||
+ nsAutoCString& aIDKey) {
|
||||
+ // Compose ID as NN:URL where NN is index to our current history
|
||||
+ // result container.
|
||||
+ aIDKey = nsPrintfCString("%.2d:%s", aIndex, aUri.get());
|
||||
+}
|
||||
+
|
||||
+int nsGNOMEShellSearchProvider::GetIndexFromIDKey(const char* aIDKey) {
|
||||
+ // ID is NN:URL where NN is index to our current history
|
||||
+ // result container.
|
||||
+ char tmp[] = {aIDKey[0], aIDKey[1], '\0'};
|
||||
+ return atoi(tmp);
|
||||
+}
|
||||
+
|
||||
+void nsGNOMEShellSearchProvider::ComposeSearchResultReply(
|
||||
+ DBusMessage* reply, const char* aSearchTerm) {
|
||||
+ uint32_t childCount = 0;
|
||||
+ nsresult rv = mHistResultContainer->GetChildCount(&childCount);
|
||||
+ if (NS_FAILED(rv) || childCount == 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (childCount > MAX_SEARCH_RESULTS_NUM) {
|
||||
+ childCount = MAX_SEARCH_RESULTS_NUM;
|
||||
+ }
|
||||
+
|
||||
+ DBusMessageIter iter;
|
||||
+ dbus_message_iter_init_append(reply, &iter);
|
||||
+ DBusMessageIter iterArray;
|
||||
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &iterArray);
|
||||
+
|
||||
+ for (uint32_t i = 0; i < childCount; i++) {
|
||||
+ nsCOMPtr<nsINavHistoryResultNode> child;
|
||||
+ mHistResultContainer->GetChild(i, getter_AddRefs(child));
|
||||
+ if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (!IsHistoryResultNodeURI(child)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ nsAutoCString uri;
|
||||
+ child->GetUri(uri);
|
||||
+
|
||||
+ nsAutoCString idKey;
|
||||
+ GetIDKeyForURI(i, uri, idKey);
|
||||
+
|
||||
+ const char* id = idKey.get();
|
||||
+ dbus_message_iter_append_basic(&iterArray, DBUS_TYPE_STRING, &id);
|
||||
+ }
|
||||
+
|
||||
+ nsPrintfCString searchString("%s:%s", KEYWORD_SEARCH_STRING, aSearchTerm);
|
||||
+ const char* search = searchString.get();
|
||||
+ dbus_message_iter_append_basic(&iterArray, DBUS_TYPE_STRING, &search);
|
||||
+
|
||||
+ dbus_message_iter_close_container(&iter, &iterArray);
|
||||
+}
|
||||
+
|
||||
+DBusHandlerResult nsGNOMEShellSearchProvider::GetInitialResultSet(
|
||||
+ DBusMessage* aMsg) {
|
||||
+ DBusMessage* reply;
|
||||
+ char** stringArray;
|
||||
+ int elements;
|
||||
+
|
||||
+ if (!dbus_message_get_args(aMsg, nullptr, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
|
||||
+ &stringArray, &elements, DBUS_TYPE_INVALID) ||
|
||||
+ elements == 0) {
|
||||
+ reply = dbus_message_new_error(aMsg, DBUS_BUS_NAME, "Wrong argument");
|
||||
+ } else {
|
||||
+ reply = dbus_message_new_method_return(aMsg);
|
||||
+ nsresult rv = QueryHistory(stringArray[0]);
|
||||
+ if (NS_SUCCEEDED(rv)) {
|
||||
+ ComposeSearchResultReply(reply, stringArray[0]);
|
||||
+ }
|
||||
+ dbus_free_string_array(stringArray);
|
||||
+ }
|
||||
+
|
||||
+ dbus_connection_send(mConnection, reply, nullptr);
|
||||
+ dbus_message_unref(reply);
|
||||
+
|
||||
+ return DBUS_HANDLER_RESULT_HANDLED;
|
||||
+}
|
||||
+
|
||||
+DBusHandlerResult nsGNOMEShellSearchProvider::GetSubsearchResultSet(
|
||||
+ DBusMessage* aMsg) {
|
||||
+ DBusMessage* reply;
|
||||
+
|
||||
+ char **unusedArray = nullptr, **stringArray = nullptr;
|
||||
+ int unusedNum, elements;
|
||||
+
|
||||
+ if (!dbus_message_get_args(aMsg, nullptr, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
|
||||
+ &unusedArray, &unusedNum, DBUS_TYPE_ARRAY,
|
||||
+ DBUS_TYPE_STRING, &stringArray, &elements,
|
||||
+ DBUS_TYPE_INVALID) ||
|
||||
+ elements == 0) {
|
||||
+ reply = dbus_message_new_error(aMsg, DBUS_BUS_NAME, "Wrong argument");
|
||||
+ } else {
|
||||
+ reply = dbus_message_new_method_return(aMsg);
|
||||
+ nsresult rv = QueryHistory(stringArray[0]);
|
||||
+ if (NS_SUCCEEDED(rv)) {
|
||||
+ ComposeSearchResultReply(reply, stringArray[0]);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (unusedArray) {
|
||||
+ dbus_free_string_array(unusedArray);
|
||||
+ }
|
||||
+ if (stringArray) {
|
||||
+ dbus_free_string_array(stringArray);
|
||||
+ }
|
||||
+
|
||||
+ dbus_connection_send(mConnection, reply, nullptr);
|
||||
+ dbus_message_unref(reply);
|
||||
+
|
||||
+ return DBUS_HANDLER_RESULT_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static void appendStringDictionary(DBusMessageIter* aIter, const char* aKey,
|
||||
+ const char* aValue) {
|
||||
+ DBusMessageIter iterDict, iterVar;
|
||||
+ dbus_message_iter_open_container(aIter, DBUS_TYPE_DICT_ENTRY, nullptr,
|
||||
+ &iterDict);
|
||||
+ dbus_message_iter_append_basic(&iterDict, DBUS_TYPE_STRING, &aKey);
|
||||
+ dbus_message_iter_open_container(&iterDict, DBUS_TYPE_VARIANT, "s", &iterVar);
|
||||
+ dbus_message_iter_append_basic(&iterVar, DBUS_TYPE_STRING, &aValue);
|
||||
+ dbus_message_iter_close_container(&iterDict, &iterVar);
|
||||
+ dbus_message_iter_close_container(aIter, &iterDict);
|
||||
+}
|
||||
+
|
||||
+/* We can return those fields at GetResultMetas:
|
||||
+ "id": the result ID
|
||||
+ "name": the display name for the result
|
||||
+ "icon": a serialized GIcon (see g_icon_serialize()), or alternatively,
|
||||
+ "gicon": a textual representation of a GIcon (see g_icon_to_string()),
|
||||
+ or alternativly,
|
||||
+ "icon-data": a tuple of type (iiibiiay) describing a pixbuf with width,
|
||||
+ height, rowstride, has-alpha, bits-per-sample, and image data
|
||||
+ "description": an optional short description (1-2 lines)
|
||||
+*/
|
||||
+void nsGNOMEShellSearchProvider::AppendResultID(DBusMessageIter* aIter,
|
||||
+ const char* aID) {
|
||||
+ nsCOMPtr<nsINavHistoryResultNode> child;
|
||||
+ mHistResultContainer->GetChild(GetIndexFromIDKey(aID), getter_AddRefs(child));
|
||||
+ nsAutoCString title;
|
||||
+ if (NS_FAILED(child->GetTitle(title))) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (title.IsEmpty()) {
|
||||
+ if (NS_FAILED(child->GetUri(title)) || title.IsEmpty()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ const char* titleStr = title.get();
|
||||
+ appendStringDictionary(aIter, "id", aID);
|
||||
+ appendStringDictionary(aIter, "name", titleStr);
|
||||
+ appendStringDictionary(aIter, "gicon", "text-html");
|
||||
+}
|
||||
+
|
||||
+void nsGNOMEShellSearchProvider::AppendSearchID(DBusMessageIter* aIter,
|
||||
+ const char* aID) {
|
||||
+ if (strlen(aID) < KEYWORD_SEARCH_STRING_LEN + 2) {
|
||||
+ return;
|
||||
+ }
|
||||
+ appendStringDictionary(aIter, "id", KEYWORD_SEARCH_STRING);
|
||||
+ mSearchTerm = nsAutoCStringN<32>(aID + KEYWORD_SEARCH_STRING_LEN + 1);
|
||||
+ nsPrintfCString searchString(mGnomeSearchTitle.get(), mSearchTerm.get());
|
||||
+ appendStringDictionary(aIter, "name", searchString.get());
|
||||
+ appendStringDictionary(aIter, "gicon", "org.mozilla.Firefox");
|
||||
+}
|
||||
+
|
||||
+DBusHandlerResult nsGNOMEShellSearchProvider::GetResultMetas(
|
||||
+ DBusMessage* aMsg) {
|
||||
+ DBusMessage* reply;
|
||||
+ char** stringArray;
|
||||
+ int elements;
|
||||
+
|
||||
+ if (!dbus_message_get_args(aMsg, nullptr, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
|
||||
+ &stringArray, &elements, DBUS_TYPE_INVALID) ||
|
||||
+ elements == 0) {
|
||||
+ reply = dbus_message_new_error(aMsg, DBUS_BUS_NAME, "Wrong argument");
|
||||
+ } else {
|
||||
+ reply = dbus_message_new_method_return(aMsg);
|
||||
+
|
||||
+ DBusMessageIter iter;
|
||||
+ dbus_message_iter_init_append(reply, &iter);
|
||||
+ DBusMessageIter iterArray;
|
||||
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "a{sv}",
|
||||
+ &iterArray);
|
||||
+
|
||||
+ DBusMessageIter iterArray2;
|
||||
+ for (int i = 0; i < elements; i++) {
|
||||
+ dbus_message_iter_open_container(&iterArray, DBUS_TYPE_ARRAY, "{sv}",
|
||||
+ &iterArray2);
|
||||
+ if (strncmp(stringArray[i], KEYWORD_SEARCH_STRING,
|
||||
+ KEYWORD_SEARCH_STRING_LEN) == 0) {
|
||||
+ AppendSearchID(&iterArray2, stringArray[i]);
|
||||
+ } else {
|
||||
+ AppendResultID(&iterArray2, stringArray[i]);
|
||||
+ }
|
||||
+ dbus_message_iter_close_container(&iterArray, &iterArray2);
|
||||
+ }
|
||||
+
|
||||
+ dbus_message_iter_close_container(&iter, &iterArray);
|
||||
+ dbus_free_string_array(stringArray);
|
||||
+ }
|
||||
+
|
||||
+ dbus_connection_send(mConnection, reply, nullptr);
|
||||
+ dbus_message_unref(reply);
|
||||
+
|
||||
+ return DBUS_HANDLER_RESULT_HANDLED;
|
||||
+}
|
||||
+
|
||||
+void nsGNOMEShellSearchProvider::LaunchWithID(const char* aID,
|
||||
+ uint32_t aTimeStamp) {
|
||||
+ char* commandLine = nullptr;
|
||||
+ int tmp;
|
||||
+
|
||||
+ if (strncmp(aID, KEYWORD_SEARCH_STRING, KEYWORD_SEARCH_STRING_LEN) == 0) {
|
||||
+ nsPrintfCString searchString("search:%s", mSearchTerm.get());
|
||||
+ const char* urlList[2] = {"unused", searchString.get()};
|
||||
+ commandLine = ConstructCommandLine(2, (char**)urlList, 0, &tmp);
|
||||
+ } else {
|
||||
+ int keyIndex = atoi(aID);
|
||||
+ nsCOMPtr<nsINavHistoryResultNode> child;
|
||||
+ mHistResultContainer->GetChild(keyIndex, getter_AddRefs(child));
|
||||
+
|
||||
+ nsAutoCString uri;
|
||||
+ nsresult rv = child->GetUri(uri);
|
||||
+ if (NS_FAILED(rv)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ const char* urlList[2] = {"unused", uri.get()};
|
||||
+ commandLine = ConstructCommandLine(2, (char**)urlList, 0, &tmp);
|
||||
+ }
|
||||
+
|
||||
+ if (commandLine) {
|
||||
+ HandleCommandLine(commandLine, aTimeStamp);
|
||||
+ free(commandLine);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void nsGNOMEShellSearchProvider::LaunchWithAllResults(uint32_t aTimeStamp) {
|
||||
+ uint32_t childCount = 0;
|
||||
+ nsresult rv = mHistResultContainer->GetChildCount(&childCount);
|
||||
+ if (NS_FAILED(rv) || childCount == 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (childCount > MAX_SEARCH_RESULTS_NUM) {
|
||||
+ childCount = MAX_SEARCH_RESULTS_NUM;
|
||||
+ }
|
||||
+
|
||||
+ char** urlList = (char**)moz_xmalloc(sizeof(char*) * (childCount + 2));
|
||||
+ int urlListElements = 0;
|
||||
+
|
||||
+ urlList[urlListElements++] = strdup("unused");
|
||||
+
|
||||
+ for (uint32_t i = 0; i < childCount; i++) {
|
||||
+ nsCOMPtr<nsINavHistoryResultNode> child;
|
||||
+ mHistResultContainer->GetChild(i, getter_AddRefs(child));
|
||||
+
|
||||
+ if (!IsHistoryResultNodeURI(child)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ nsAutoCString uri;
|
||||
+ nsresult rv = child->GetUri(uri);
|
||||
+ if (NS_FAILED(rv)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ urlList[urlListElements++] = strdup(uri.get());
|
||||
+ }
|
||||
+
|
||||
+ nsPrintfCString searchString("search:%s", mSearchTerm.get());
|
||||
+ urlList[urlListElements++] = strdup(searchString.get());
|
||||
+
|
||||
+ int tmp;
|
||||
+ char* commandLine = ConstructCommandLine(urlListElements, urlList, 0, &tmp);
|
||||
+ if (commandLine) {
|
||||
+ HandleCommandLine(commandLine, aTimeStamp);
|
||||
+ free(commandLine);
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < urlListElements; i++) {
|
||||
+ free(urlList[i]);
|
||||
+ }
|
||||
+ free(urlList);
|
||||
+}
|
||||
+
|
||||
+DBusHandlerResult nsGNOMEShellSearchProvider::ActivateResult(
|
||||
+ DBusMessage* aMsg) {
|
||||
+ DBusMessage* reply;
|
||||
+ char* resultID;
|
||||
+ char** stringArray;
|
||||
+ int elements;
|
||||
+ uint32_t timestamp;
|
||||
+
|
||||
+ if (!dbus_message_get_args(aMsg, nullptr, DBUS_TYPE_STRING, &resultID,
|
||||
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &stringArray,
|
||||
+ &elements, DBUS_TYPE_UINT32, ×tamp,
|
||||
+ DBUS_TYPE_INVALID) ||
|
||||
+ resultID == nullptr) {
|
||||
+ reply = dbus_message_new_error(aMsg, DBUS_BUS_NAME, "Wrong argument");
|
||||
+ } else {
|
||||
+ reply = dbus_message_new_method_return(aMsg);
|
||||
+ LaunchWithID(resultID, timestamp);
|
||||
+ dbus_free_string_array(stringArray);
|
||||
+ }
|
||||
+
|
||||
+ dbus_connection_send(mConnection, reply, nullptr);
|
||||
+ dbus_message_unref(reply);
|
||||
+
|
||||
+ return DBUS_HANDLER_RESULT_HANDLED;
|
||||
+}
|
||||
+
|
||||
+DBusHandlerResult nsGNOMEShellSearchProvider::LaunchSearch(DBusMessage* aMsg) {
|
||||
+ DBusMessage* reply;
|
||||
+ char** stringArray;
|
||||
+ int elements;
|
||||
+ uint32_t timestamp;
|
||||
+
|
||||
+ if (!dbus_message_get_args(aMsg, nullptr, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
|
||||
+ &stringArray, &elements, DBUS_TYPE_UINT32,
|
||||
+ ×tamp, DBUS_TYPE_INVALID) ||
|
||||
+ elements == 0) {
|
||||
+ reply = dbus_message_new_error(aMsg, DBUS_BUS_NAME, "Wrong argument");
|
||||
+ } else {
|
||||
+ reply = dbus_message_new_method_return(aMsg);
|
||||
+ LaunchWithAllResults(timestamp);
|
||||
+ dbus_free_string_array(stringArray);
|
||||
+ }
|
||||
+
|
||||
+ dbus_connection_send(mConnection, reply, nullptr);
|
||||
+ dbus_message_unref(reply);
|
||||
+
|
||||
+ return DBUS_HANDLER_RESULT_HANDLED;
|
||||
+}
|
||||
+
|
||||
+DBusHandlerResult nsGNOMEShellSearchProvider::HandleDBusMessage(
|
||||
+ DBusConnection* aConnection, DBusMessage* aMsg) {
|
||||
+ NS_ASSERTION(mConnection == aConnection, "Wrong D-Bus connection.");
|
||||
+
|
||||
+ const char* method = dbus_message_get_member(aMsg);
|
||||
+ const char* iface = dbus_message_get_interface(aMsg);
|
||||
+
|
||||
+ if ((strcmp("Introspect", method) == 0) &&
|
||||
+ (strcmp("org.freedesktop.DBus.Introspectable", iface) == 0)) {
|
||||
+ return Introspect(aMsg);
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp("org.gnome.Shell.SearchProvider2", iface) == 0) {
|
||||
+ if (strcmp("GetInitialResultSet", method) == 0) {
|
||||
+ return GetInitialResultSet(aMsg);
|
||||
+ }
|
||||
+ if (strcmp("GetSubsearchResultSet", method) == 0) {
|
||||
+ return GetSubsearchResultSet(aMsg);
|
||||
+ }
|
||||
+ if (strcmp("GetResultMetas", method) == 0) {
|
||||
+ return GetResultMetas(aMsg);
|
||||
+ }
|
||||
+ if (strcmp("ActivateResult", method) == 0) {
|
||||
+ return ActivateResult(aMsg);
|
||||
+ }
|
||||
+ if (strcmp("LaunchSearch", method) == 0) {
|
||||
+ return LaunchSearch(aMsg);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
+}
|
||||
+
|
||||
+void nsGNOMEShellSearchProvider::UnregisterDBusInterface(
|
||||
+ DBusConnection* aConnection) {
|
||||
+ NS_ASSERTION(mConnection == aConnection, "Wrong D-Bus connection.");
|
||||
+ // Not implemented
|
||||
+}
|
||||
+
|
||||
+static DBusHandlerResult message_handler(DBusConnection* conn,
|
||||
+ DBusMessage* aMsg, void* user_data) {
|
||||
+ auto interface = static_cast<nsGNOMEShellSearchProvider*>(user_data);
|
||||
+ return interface->HandleDBusMessage(conn, aMsg);
|
||||
+}
|
||||
+
|
||||
+static void unregister(DBusConnection* conn, void* user_data) {
|
||||
+ auto interface = static_cast<nsGNOMEShellSearchProvider*>(user_data);
|
||||
+ interface->UnregisterDBusInterface(conn);
|
||||
+}
|
||||
+
|
||||
+static DBusObjectPathVTable remoteHandlersTable = {
|
||||
+ .unregister_function = unregister,
|
||||
+ .message_function = message_handler,
|
||||
+};
|
||||
+
|
||||
+nsresult nsGNOMEShellSearchProvider::Startup() {
|
||||
+ if (mConnection && dbus_connection_get_is_connected(mConnection)) {
|
||||
+ // We're already connected so we don't need to reconnect
|
||||
+ return NS_ERROR_ALREADY_INITIALIZED;
|
||||
+ }
|
||||
+
|
||||
+ nsCOMPtr<nsIStringBundleService> sbs =
|
||||
+ do_GetService(NS_STRINGBUNDLE_CONTRACTID);
|
||||
+ if (NS_WARN_IF(!sbs)) {
|
||||
+ return NS_ERROR_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ nsCOMPtr<nsIStringBundle> bundle;
|
||||
+ sbs->CreateBundle("chrome://browser/locale/browser.properties",
|
||||
+ getter_AddRefs(bundle));
|
||||
+ if (NS_WARN_IF(!bundle)) {
|
||||
+ return NS_ERROR_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ nsAutoString searchTitle;
|
||||
+ bundle->GetStringFromName("gnomeSearchProviderSearch", searchTitle);
|
||||
+ mGnomeSearchTitle = NS_ConvertUTF16toUTF8(searchTitle);
|
||||
+
|
||||
+ mHistoryService = do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID);
|
||||
+ if (!mHistoryService) {
|
||||
+ return NS_ERROR_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ mConnection =
|
||||
+ already_AddRefed<DBusConnection>(dbus_bus_get(DBUS_BUS_SESSION, nullptr));
|
||||
+ if (!mConnection) {
|
||||
+ return NS_ERROR_FAILURE;
|
||||
+ }
|
||||
+ dbus_connection_set_exit_on_disconnect(mConnection, false);
|
||||
+ dbus_connection_setup_with_g_main(mConnection, nullptr);
|
||||
+
|
||||
+ DBusError err;
|
||||
+ dbus_error_init(&err);
|
||||
+ dbus_bus_request_name(mConnection, DBUS_BUS_NAME, DBUS_NAME_FLAG_DO_NOT_QUEUE,
|
||||
+ &err);
|
||||
+ // The interface is already owned - there is another application/profile
|
||||
+ // instance already running.
|
||||
+ if (dbus_error_is_set(&err)) {
|
||||
+ dbus_error_free(&err);
|
||||
+ mConnection = nullptr;
|
||||
+ return NS_ERROR_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ if (!dbus_connection_register_object_path(mConnection, DBUS_OBJECT_PATH,
|
||||
+ &remoteHandlersTable, this)) {
|
||||
+ mConnection = nullptr;
|
||||
+ return NS_ERROR_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ return NS_OK;
|
||||
+}
|
||||
+
|
||||
+void nsGNOMEShellSearchProvider::Shutdown() {
|
||||
+ if (!mConnection) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ dbus_connection_unregister_object_path(mConnection, DBUS_OBJECT_PATH);
|
||||
+
|
||||
+ // dbus_connection_unref() will be called by RefPtr here.
|
||||
+ mConnection = nullptr;
|
||||
+}
|
||||
diff -up firefox-73.0/browser/components/shell/nsGNOMEShellSearchProvider.h.gnome-shell-search-provider firefox-73.0/browser/components/shell/nsGNOMEShellSearchProvider.h
|
||||
--- firefox-73.0/browser/components/shell/nsGNOMEShellSearchProvider.h.gnome-shell-search-provider 2020-02-11 09:00:59.350512802 +0100
|
||||
+++ firefox-73.0/browser/components/shell/nsGNOMEShellSearchProvider.h 2020-02-11 09:00:59.350512802 +0100
|
||||
@@ -0,0 +1,55 @@
|
||||
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
+/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
+ */
|
||||
+/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
+
|
||||
+#ifndef __nsGNOMEShellSearchProvider_h__
|
||||
+#define __nsGNOMEShellSearchProvider_h__
|
||||
+
|
||||
+#include "mozilla/DBusHelpers.h"
|
||||
+#include "nsINavHistoryService.h"
|
||||
+#include "nsUnixRemoteServer.h"
|
||||
+#include "nsCOMPtr.h"
|
||||
+
|
||||
+class nsGNOMEShellSearchProvider : public nsUnixRemoteServer {
|
||||
+ public:
|
||||
+ nsGNOMEShellSearchProvider() : mConnection(nullptr) {}
|
||||
+ ~nsGNOMEShellSearchProvider() { Shutdown(); }
|
||||
+
|
||||
+ nsresult Startup();
|
||||
+ void Shutdown();
|
||||
+
|
||||
+ DBusHandlerResult HandleDBusMessage(DBusConnection* aConnection,
|
||||
+ DBusMessage* msg);
|
||||
+ void UnregisterDBusInterface(DBusConnection* aConnection);
|
||||
+
|
||||
+ private:
|
||||
+ DBusHandlerResult Introspect(DBusMessage* msg);
|
||||
+
|
||||
+ DBusHandlerResult GetInitialResultSet(DBusMessage* msg);
|
||||
+ DBusHandlerResult GetSubsearchResultSet(DBusMessage* msg);
|
||||
+ DBusHandlerResult GetResultMetas(DBusMessage* msg);
|
||||
+ DBusHandlerResult ActivateResult(DBusMessage* msg);
|
||||
+ DBusHandlerResult LaunchSearch(DBusMessage* msg);
|
||||
+
|
||||
+ nsresult QueryHistory(const char* aSearchTerm);
|
||||
+ void GetIDKeyForURI(int aIndex, nsAutoCString& aUri, nsAutoCString& aIDKey);
|
||||
+ int GetIndexFromIDKey(const char* aIDKey);
|
||||
+ bool IsHistoryResultNodeURI(nsINavHistoryResultNode* aHistoryNode);
|
||||
+ void AppendResultID(DBusMessageIter* aIter, const char* aID);
|
||||
+ void AppendSearchID(DBusMessageIter* aIter, const char* aID);
|
||||
+ void ComposeSearchResultReply(DBusMessage* aReply, const char* aSearchTerm);
|
||||
+ void LaunchWithID(const char* aID, uint32_t aTimeStamp);
|
||||
+ void LaunchWithAllResults(uint32_t aTimeStamp);
|
||||
+
|
||||
+ // The connection is owned by DBus library
|
||||
+ RefPtr<DBusConnection> mConnection;
|
||||
+ nsCOMPtr<nsINavHistoryContainerResultNode> mHistResultContainer;
|
||||
+ nsCOMPtr<nsINavHistoryService> mHistoryService;
|
||||
+ nsAutoCStringN<32> mSearchTerm;
|
||||
+ nsAutoCString mGnomeSearchTitle;
|
||||
+};
|
||||
+
|
||||
+#endif // __nsGNOMEShellSearchProvider_h__
|
||||
diff -up firefox-73.0/browser/components/shell/nsGNOMEShellService.cpp.gnome-shell-search-provider firefox-73.0/browser/components/shell/nsGNOMEShellService.cpp
|
||||
--- firefox-73.0/browser/components/shell/nsGNOMEShellService.cpp.gnome-shell-search-provider 2020-02-07 22:12:59.000000000 +0100
|
||||
+++ firefox-73.0/browser/components/shell/nsGNOMEShellService.cpp 2020-02-11 09:00:59.350512802 +0100
|
||||
@@ -89,6 +89,14 @@ nsresult nsGNOMEShellService::Init() {
|
||||
|
||||
if (!giovfs && !gsettings) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
+#ifdef MOZ_ENABLE_DBUS
|
||||
+ const char* currentDesktop = getenv("XDG_CURRENT_DESKTOP");
|
||||
+ if (currentDesktop && strstr(currentDesktop, "GNOME") != nullptr &&
|
||||
+ Preferences::GetBool("browser.gnome-search-provider.enabled", false)) {
|
||||
+ mSearchProvider.Startup();
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
// Check G_BROKEN_FILENAMES. If it's set, then filenames in glib use
|
||||
// the locale encoding. If it's not set, they use UTF-8.
|
||||
mUseLocaleFilenames = PR_GetEnv("G_BROKEN_FILENAMES") != nullptr;
|
||||
diff -up firefox-73.0/browser/components/shell/nsGNOMEShellService.h.gnome-shell-search-provider firefox-73.0/browser/components/shell/nsGNOMEShellService.h
|
||||
--- firefox-73.0/browser/components/shell/nsGNOMEShellService.h.gnome-shell-search-provider 2020-02-07 22:12:59.000000000 +0100
|
||||
+++ firefox-73.0/browser/components/shell/nsGNOMEShellService.h 2020-02-11 09:00:59.350512802 +0100
|
||||
@@ -10,6 +10,9 @@
|
||||
#include "nsToolkitShellService.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
+#ifdef MOZ_ENABLE_DBUS
|
||||
+# include "nsGNOMEShellSearchProvider.h"
|
||||
+#endif
|
||||
|
||||
class nsGNOMEShellService final : public nsIGNOMEShellService,
|
||||
public nsToolkitShellService {
|
||||
@@ -28,6 +31,9 @@ class nsGNOMEShellService final : public
|
||||
bool KeyMatchesAppName(const char* aKeyValue) const;
|
||||
bool CheckHandlerMatchesAppName(const nsACString& handler) const;
|
||||
|
||||
+#ifdef MOZ_ENABLE_DBUS
|
||||
+ nsGNOMEShellSearchProvider mSearchProvider;
|
||||
+#endif
|
||||
bool GetAppPathFromLauncher();
|
||||
bool mUseLocaleFilenames;
|
||||
nsCString mAppPath;
|
||||
diff -up firefox-73.0/browser/locales/en-US/chrome/browser/browser.properties.gnome-shell-search-provider firefox-73.0/browser/locales/en-US/chrome/browser/browser.properties
|
||||
--- firefox-73.0/browser/locales/en-US/chrome/browser/browser.properties.gnome-shell-search-provider 2020-02-07 22:13:00.000000000 +0100
|
||||
+++ firefox-73.0/browser/locales/en-US/chrome/browser/browser.properties 2020-02-11 09:00:59.350512802 +0100
|
||||
@@ -1047,3 +1047,7 @@ confirmationHint.breakageReport.label =
|
||||
# Used by the export of user's live bookmarks to an OPML file as a title for the file.
|
||||
# %S will be replaced with brandShortName
|
||||
livebookmarkMigration.title = %S Live Bookmarks
|
||||
+
|
||||
+# LOCALIZATION NOTE (gnomeSearchProviderSearch):
|
||||
+# Used for search by Gnome Shell activity screen, %s is a searched string.
|
||||
+gnomeSearchProviderSearch=Search the web for “%s”
|
||||
diff -up firefox-73.0/toolkit/components/remote/moz.build.gnome-shell-search-provider firefox-73.0/toolkit/components/remote/moz.build
|
||||
--- firefox-73.0/toolkit/components/remote/moz.build.gnome-shell-search-provider 2020-02-07 22:13:54.000000000 +0100
|
||||
+++ firefox-73.0/toolkit/components/remote/moz.build 2020-02-11 09:00:59.351512811 +0100
|
||||
@@ -25,6 +25,10 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk'
|
||||
'nsDBusRemoteServer.cpp',
|
||||
]
|
||||
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
|
||||
+ EXPORTS += [
|
||||
+ 'nsUnixRemoteServer.h',
|
||||
+ 'RemoteUtils.h',
|
||||
+ ]
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
diff -up firefox-73.0/toolkit/components/remote/nsDBusRemoteServer.cpp.gnome-shell-search-provider firefox-73.0/toolkit/components/remote/nsDBusRemoteServer.cpp
|
||||
--- firefox-73.0/toolkit/components/remote/nsDBusRemoteServer.cpp.gnome-shell-search-provider 2020-02-07 22:13:54.000000000 +0100
|
||||
+++ firefox-73.0/toolkit/components/remote/nsDBusRemoteServer.cpp 2020-02-11 09:00:59.351512811 +0100
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
-const char* introspect_template =
|
||||
+static const char* introspect_template =
|
||||
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection "
|
||||
"1.0//EN\"\n"
|
||||
"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\";>\n"
|
1
sources
1
sources
@ -1,3 +1,4 @@
|
||||
SHA512 (cbindgen-vendor.tar.xz) = a12d9dd45301614f3a7fcd77f61e3f731718fc418fcf84b0ac7363ef4ddd8ff60e057febef917620ac89d2d47d76b8dccfa71405935e346b849b93425732016a
|
||||
SHA512 (firefox-76.0.1.source.tar.xz) = 188d7dc51200662048f808e32eced55979a69059bf88eac8386307f9371adad4ca524819d99a001b6d900147b8f216d5d330430f15f11eae0b01cccf8f39681f
|
||||
SHA512 (firefox-langpacks-76.0.1-20200508.tar.xz) = 86ff8486282914fdb6203bd099f6bcaf266c4453dd56c1876768c26d281ab0089ad0f141f86f912bfebc9677cc0b82583f86231bb2612ae2d5820078666fc9dc
|
||||
SHA512 (firefox-77.0.source.tar.xz) = 5d530d936786019a27c6bd057e01c303f58728d11927ba5c40be6f23718c206d4d1691a91c3d46bd5dce3050d32f728bb7c94d6385819a744af44aa18cbc561b
|
||||
|
Loading…
Reference in New Issue
Block a user