diff options
Diffstat (limited to 'mozilla-1634293.patch')
-rw-r--r-- | mozilla-1634293.patch | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/mozilla-1634293.patch b/mozilla-1634293.patch new file mode 100644 index 0000000..09a3274 --- /dev/null +++ b/mozilla-1634293.patch @@ -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; + |