diff options
author | Peter Varga <pvarga@inf.u-szeged.hu> | 2020-06-19 11:17:50 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-06-04 18:41:41 +0200 |
commit | 881339e9d9054c46f2621119246de7a13c83761a (patch) | |
tree | 77db7d7188c4ac61cab939c2ccd7a9610d4a01f4 /src/core | |
parent | 4d67b9f639114ddec0521980495ba27921800e39 (diff) |
Replace FaviconManager with Chromium's Favicon Component
Task-number: QTBUG-51184
Change-Id: Ie050cb23f2c86841a66ec384bfbcdf0713cffa7c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/core')
24 files changed, 1016 insertions, 684 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 2a545f5b2..b32415028 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -91,7 +91,8 @@ foreach(config ${configs}) devtools_frontend_qt.cpp devtools_frontend_qt.h devtools_manager_delegate_qt.cpp devtools_manager_delegate_qt.h download_manager_delegate_qt.cpp download_manager_delegate_qt.h - favicon_manager.cpp favicon_manager.h + favicon_driver_qt.cpp favicon_driver_qt.h + favicon_service_factory_qt.cpp favicon_service_factory_qt.h file_picker_controller.cpp file_picker_controller.h find_text_helper.cpp find_text_helper.h global_descriptors_qt.h diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp index 6e2b37514..64b4f4d99 100644 --- a/src/core/api/qwebenginepage.cpp +++ b/src/core/api/qwebenginepage.cpp @@ -44,7 +44,6 @@ #include "authentication_dialog_controller.h" #include "profile_adapter.h" #include "color_chooser_controller.h" -#include "favicon_manager.h" #include "find_text_helper.h" #include "file_picker_controller.h" #include "javascript_dialog_controller.h" @@ -255,7 +254,7 @@ void QWebEnginePagePrivate::iconChanged(const QUrl &url) return; iconUrl = url; Q_EMIT q->iconUrlChanged(iconUrl); - Q_EMIT q->iconChanged(adapter->faviconManager()->getIcon()); + Q_EMIT q->iconChanged(iconUrl.isEmpty() ? QIcon() : adapter->icon()); } void QWebEnginePagePrivate::loadProgressChanged(int progress) @@ -1980,7 +1979,7 @@ QIcon QWebEnginePage::icon() const if (d->iconUrl.isEmpty() || !d->adapter->isInitialized()) return QIcon(); - return d->adapter->faviconManager()->getIcon(); + return d->adapter->icon(); } qreal QWebEnginePage::zoomFactor() const diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index d68cad2b0..fdcd98024 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -113,6 +113,7 @@ #include "web_contents_view_qt.h" #include "web_engine_context.h" #include "web_engine_library_info.h" +#include "web_engine_settings.h" #include "api/qwebenginecookiestore.h" #include "api/qwebenginecookiestore_p.h" diff --git a/src/core/extensions/plugin_service_filter_qt.cpp b/src/core/extensions/plugin_service_filter_qt.cpp index 94cf5cb27..778f803c3 100644 --- a/src/core/extensions/plugin_service_filter_qt.cpp +++ b/src/core/extensions/plugin_service_filter_qt.cpp @@ -43,6 +43,7 @@ #include "content/public/browser/web_contents.h" #include "web_contents_delegate_qt.h" +#include "web_engine_settings.h" using namespace QtWebEngineCore; diff --git a/src/core/favicon_driver_qt.cpp b/src/core/favicon_driver_qt.cpp new file mode 100644 index 000000000..a3bbd5939 --- /dev/null +++ b/src/core/favicon_driver_qt.cpp @@ -0,0 +1,407 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "favicon_driver_qt.h" +#include "type_conversion.h" +#include "web_contents_adapter_client.h" +#include "web_engine_settings.h" + +#include "components/favicon/content/favicon_url_util.h" +#include "components/favicon/core/favicon_service.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/favicon_status.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/navigation_handle.h" +#include "third_party/blink/public/common/manifest/manifest.h" + +namespace QtWebEngineCore { + +namespace { + +void ExtractManifestIcons(FaviconDriverQt::ManifestDownloadCallback callback, + const GURL &manifest_url, const blink::Manifest &manifest) +{ + std::vector<favicon::FaviconURL> candidates; + for (const auto &icon : manifest.icons) { + candidates.emplace_back(icon.src, favicon_base::IconType::kWebManifestIcon, icon.sizes); + } + std::move(callback).Run(candidates); +} + +int activeHandlersCount(QWebEngineSettings *settings) +{ + bool touchIconsEnabled = settings->testAttribute(QWebEngineSettings::TouchIconsEnabled); + return touchIconsEnabled ? 2 : 1; +} + +} // namespace + +FaviconStatusQt::FaviconStatusQt() + : FaviconStatus(), source(favicon::FaviconDriverObserver::NON_TOUCH_16_DIP) +{ +} + +// static +void FaviconDriverQt::CreateForWebContents(content::WebContents *webContents, + favicon::FaviconService *faviconService, + WebContentsAdapterClient *viewClient) +{ + if (FromWebContents(webContents)) + return; + + webContents->SetUserData( + UserDataKey(), + base::WrapUnique(new FaviconDriverQt(webContents, faviconService, viewClient))); +} + +FaviconDriverQt::FaviconDriverQt(content::WebContents *webContents, + favicon::FaviconService *faviconService, + WebContentsAdapterClient *viewClient) + : content::WebContentsObserver(webContents) + , m_faviconService(faviconService) + , m_viewClient(viewClient) +{ + if (!m_faviconService) + return; + + m_handlers.push_back(std::make_unique<favicon::FaviconHandler>( + m_faviconService, this, favicon::FaviconDriverObserver::NON_TOUCH_16_DIP)); + m_handlers.push_back(std::make_unique<favicon::FaviconHandler>( + m_faviconService, this, favicon::FaviconDriverObserver::NON_TOUCH_LARGEST)); + m_handlers.push_back(std::make_unique<favicon::FaviconHandler>( + m_faviconService, this, favicon::FaviconDriverObserver::TOUCH_LARGEST)); +} + +void FaviconDriverQt::FetchFavicon(const GURL &page_url, bool is_same_document) +{ + QWebEngineSettings *settings = m_viewClient->webEngineSettings(); + bool iconsEnabled = settings->testAttribute(QWebEngineSettings::AutoLoadIconsForPage); + bool touchIconsEnabled = settings->testAttribute(QWebEngineSettings::TouchIconsEnabled); + + if (!iconsEnabled) + return; + + for (const std::unique_ptr<favicon::FaviconHandler> &handler : m_handlers) { + switch (handler->Type()) { + case favicon::FaviconDriverObserver::NON_TOUCH_16_DIP: + if (touchIconsEnabled) + continue; + break; + case favicon::FaviconDriverObserver::NON_TOUCH_LARGEST: + case favicon::FaviconDriverObserver::TOUCH_LARGEST: + if (!touchIconsEnabled) + continue; + break; + } + + handler->FetchFavicon(page_url, is_same_document); + } +} + +gfx::Image FaviconDriverQt::GetFavicon() const +{ + // Like GetTitle(), we also want to use the favicon for the last committed + // entry rather than a pending navigation entry. + content::NavigationController &controller = web_contents()->GetController(); + + content::NavigationEntry *entry = controller.GetLastCommittedEntry(); + if (entry) + return entry->GetFavicon().image; + return gfx::Image(); +} + +bool FaviconDriverQt::FaviconIsValid() const +{ + content::NavigationController &controller = web_contents()->GetController(); + + content::NavigationEntry *entry = controller.GetLastCommittedEntry(); + if (entry) + return entry->GetFavicon().valid; + + return false; +} + +GURL FaviconDriverQt::GetActiveURL() +{ + content::NavigationEntry *entry = web_contents()->GetController().GetLastCommittedEntry(); + return entry ? entry->GetURL() : GURL(); +} + +GURL FaviconDriverQt::GetFaviconURL() const +{ + content::NavigationController &controller = web_contents()->GetController(); + + content::NavigationEntry *entry = controller.GetLastCommittedEntry(); + if (entry) + return entry->GetFavicon().url; + return GURL(); +} + +int FaviconDriverQt::DownloadImage(const GURL &url, int max_image_size, + ImageDownloadCallback callback) +{ + bool bypass_cache = (m_bypassCachePageURL == GetActiveURL()); + m_bypassCachePageURL = GURL(); + + return web_contents()->DownloadImage(url, true, /*preferred_size=*/max_image_size, + /*max_bitmap_size=*/max_image_size, bypass_cache, + std::move(callback)); +} + +void FaviconDriverQt::DownloadManifest(const GURL &url, ManifestDownloadCallback callback) +{ + web_contents()->GetManifest(base::BindOnce(&ExtractManifestIcons, std::move(callback))); +} + +bool FaviconDriverQt::IsOffTheRecord() +{ + DCHECK(web_contents()); + return web_contents()->GetBrowserContext()->IsOffTheRecord(); +} + +void FaviconDriverQt::OnFaviconUpdated( + const GURL &page_url, + favicon::FaviconDriverObserver::NotificationIconType notification_icon_type, + const GURL &icon_url, bool icon_url_changed, const gfx::Image &image) +{ + Q_UNUSED(page_url); + + QWebEngineSettings *settings = m_viewClient->webEngineSettings(); + bool touchIconsEnabled = settings->testAttribute(QWebEngineSettings::TouchIconsEnabled); + + // Prefer touch icons over favicons if touch icons are enabled. + if (!touchIconsEnabled + || m_latestFavicon.source != favicon::FaviconDriverObserver::TOUCH_LARGEST + || notification_icon_type == favicon::FaviconDriverObserver::TOUCH_LARGEST) { + m_latestFavicon.valid = true; + m_latestFavicon.url = icon_url; + m_latestFavicon.image = image; + m_latestFavicon.source = notification_icon_type; + } + + NotifyFaviconUpdatedObservers(notification_icon_type, icon_url, icon_url_changed, image); + emitIconChangedIfNeeded(); +} + +void FaviconDriverQt::OnFaviconDeleted( + const GURL &page_url, + favicon::FaviconDriverObserver::NotificationIconType notification_icon_type) +{ + content::NavigationEntry *entry = web_contents()->GetController().GetLastCommittedEntry(); + DCHECK(entry && entry->GetURL() == page_url); + + entry->GetFavicon() = FaviconStatusQt(); + web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); + + NotifyFaviconUpdatedObservers(notification_icon_type, /*icon_url=*/GURL(), + /*icon_url_changed=*/true, FaviconStatusQt().image); +} + +void FaviconDriverQt::OnHandlerCompleted(favicon::FaviconHandler *handler) +{ + Q_UNUSED(handler); + + if (activeHandlersCount(m_viewClient->webEngineSettings()) > m_completedHandlersCount) + ++m_completedHandlersCount; + emitIconChangedIfNeeded(); +} + +void FaviconDriverQt::DidUpdateFaviconURL( + content::RenderFrameHost *render_frame_host, + const std::vector<blink::mojom::FaviconURLPtr> &candidates) +{ + Q_UNUSED(render_frame_host); + + // Ignore the update if there is no last committed navigation entry. This can + // occur when loading an initially blank page. + content::NavigationEntry *entry = web_contents()->GetController().GetLastCommittedEntry(); + if (!entry) + return; + + // We update |m_faviconUrls| even if the list is believed to be partial + // (checked below), because callers of our getter favicon_urls() expect so. + std::vector<blink::mojom::FaviconURL> faviconUrls; + for (const auto &candidate : candidates) + faviconUrls.push_back(*candidate); + m_faviconUrls = faviconUrls; + + if (!m_documentOnLoadCompleted) + return; + + OnUpdateCandidates(entry->GetURL(), + favicon::FaviconURLsFromContentFaviconURLs( + m_faviconUrls.value_or(std::vector<blink::mojom::FaviconURL>())), + m_manifestUrl); +} + +void FaviconDriverQt::DidUpdateWebManifestURL(content::RenderFrameHost *target_frame, + const base::Optional<GURL> &manifest_url) +{ + Q_UNUSED(target_frame); + + // Ignore the update if there is no last committed navigation entry. This can + // occur when loading an initially blank page. + content::NavigationEntry *entry = web_contents()->GetController().GetLastCommittedEntry(); + if (!entry || !m_documentOnLoadCompleted) + return; + + m_manifestUrl = manifest_url.value_or(GURL()); + + // On regular page loads, DidUpdateManifestURL() is guaranteed to be called + // before DidUpdateFaviconURL(). However, a page can update the favicons via + // javascript. + if (m_faviconUrls.has_value()) { + OnUpdateCandidates(entry->GetURL(), + favicon::FaviconURLsFromContentFaviconURLs(*m_faviconUrls), + m_manifestUrl); + } +} + +void FaviconDriverQt::DidStartNavigation(content::NavigationHandle *navigation_handle) +{ + if (!navigation_handle->IsInMainFrame()) + return; + + m_faviconUrls.reset(); + m_completedHandlersCount = 0; + m_latestFavicon = FaviconStatusQt(); + + if (!navigation_handle->IsSameDocument()) { + m_documentOnLoadCompleted = false; + m_manifestUrl = GURL(); + } + + m_viewClient->iconChanged(QUrl()); + + content::ReloadType reload_type = navigation_handle->GetReloadType(); + if (reload_type == content::ReloadType::NONE || IsOffTheRecord()) + return; + + m_bypassCachePageURL = navigation_handle->GetURL(); + SetFaviconOutOfDateForPage(navigation_handle->GetURL(), + reload_type == content::ReloadType::BYPASSING_CACHE); +} + +void FaviconDriverQt::DidFinishNavigation(content::NavigationHandle *navigation_handle) +{ + if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted() + || navigation_handle->IsErrorPage()) { + return; + } + + // Wait till the user navigates to a new URL to start checking the cache + // again. The cache may be ignored for non-reload navigations (e.g. + // history.replace() in-page navigation). This is allowed to increase the + // likelihood that "reloading a page ignoring the cache" redownloads the + // favicon. In particular, a page may do an in-page navigation before + // FaviconHandler has the time to determine that the favicon needs to be + // redownloaded. + GURL url = navigation_handle->GetURL(); + if (url != m_bypassCachePageURL) + m_bypassCachePageURL = GURL(); + + // Get the favicon, either from history or request it from the net. + FetchFavicon(url, navigation_handle->IsSameDocument()); +} + +void FaviconDriverQt::DocumentOnLoadCompletedInMainFrame() +{ + m_documentOnLoadCompleted = true; +} + +void FaviconDriverQt::SetFaviconOutOfDateForPage(const GURL &url, bool force_reload) +{ + if (m_faviconService) { + m_faviconService->SetFaviconOutOfDateForPage(url); + if (force_reload) + m_faviconService->ClearUnableToDownloadFavicons(); + } +} + +void FaviconDriverQt::OnUpdateCandidates(const GURL &page_url, + const std::vector<favicon::FaviconURL> &candidates, + const GURL &manifest_url) +{ + QWebEngineSettings *settings = m_viewClient->webEngineSettings(); + bool touchIconsEnabled = settings->testAttribute(QWebEngineSettings::TouchIconsEnabled); + for (const std::unique_ptr<favicon::FaviconHandler> &handler : m_handlers) { + switch (handler->Type()) { + case favicon::FaviconDriverObserver::NON_TOUCH_16_DIP: + if (touchIconsEnabled) + continue; + break; + case favicon::FaviconDriverObserver::NON_TOUCH_LARGEST: + case favicon::FaviconDriverObserver::TOUCH_LARGEST: + if (!touchIconsEnabled) + continue; + break; + } + + // We feed in the Web Manifest URL (if any) to the instance handling type + // kWebManifestIcon, because those compete which each other (i.e. manifest + // icons override inline touch icons). + handler->OnUpdateCandidates( + page_url, candidates, + (handler->icon_types().count(favicon_base::IconType::kWebManifestIcon) != 0) + ? manifest_url + : GURL::EmptyGURL()); + } +} + +void FaviconDriverQt::emitIconChangedIfNeeded() +{ + if (activeHandlersCount(m_viewClient->webEngineSettings()) != m_completedHandlersCount) + return; + + content::NavigationEntry *entry = web_contents()->GetController().GetLastCommittedEntry(); + DCHECK(entry); + + if (entry->GetFavicon().url != m_latestFavicon.url) { + entry->GetFavicon().valid = m_latestFavicon.valid; + entry->GetFavicon().url = m_latestFavicon.url; + entry->GetFavicon().image = m_latestFavicon.image; + web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); + } + + m_viewClient->iconChanged(toQt(m_latestFavicon.url)); +} + +WEB_CONTENTS_USER_DATA_KEY_IMPL(FaviconDriverQt) + +} // namespace QtWebEngineCore diff --git a/src/core/favicon_driver_qt.h b/src/core/favicon_driver_qt.h new file mode 100644 index 000000000..b49017946 --- /dev/null +++ b/src/core/favicon_driver_qt.h @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#ifndef FAVICON_DRIVER_QT_H +#define FAVICON_DRIVER_QT_H + +#include "qtwebenginecoreglobal_p.h" + +#include "components/favicon/core/favicon_driver.h" +#include "components/favicon/core/favicon_handler.h" +#include "content/public/browser/favicon_status.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" +#include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h" + +namespace content { +class WebContents; +} + +namespace favicon { +class FaviconService; +} + +namespace QtWebEngineCore { + +class WebContentsAdapterClient; + +struct FaviconStatusQt : public content::FaviconStatus +{ + FaviconStatusQt(); + + // Type of the favicon::FaviconHandler that provided this icon. + favicon::FaviconDriverObserver::NotificationIconType source; +}; + +class FaviconDriverQt : public favicon::FaviconDriver, + public favicon::FaviconHandler::Delegate, + public content::WebContentsObserver, + public content::WebContentsUserData<FaviconDriverQt> +{ +public: + static void CreateForWebContents(content::WebContents *webContents, + favicon::FaviconService *faviconService, + WebContentsAdapterClient *viewClient); + + // FaviconDriver implementation. + void FetchFavicon(const GURL &page_url, bool is_same_document) override; + gfx::Image GetFavicon() const override; + bool FaviconIsValid() const override; + GURL GetActiveURL() override; + + GURL GetFaviconURL() const; + +protected: + FaviconDriverQt(content::WebContents *webContent, favicon::FaviconService *faviconService, + WebContentsAdapterClient *viewClient); + +private: + friend class content::WebContentsUserData<FaviconDriverQt>; + + // FaviconHandler::Delegate implementation. + int DownloadImage(const GURL &url, int max_image_size, ImageDownloadCallback callback) override; + void DownloadManifest(const GURL &url, ManifestDownloadCallback callback) override; + bool IsOffTheRecord() override; + void OnFaviconUpdated(const GURL &page_url, + favicon::FaviconDriverObserver::NotificationIconType icon_type, + const GURL &icon_url, bool icon_url_changed, + const gfx::Image &image) override; + void OnFaviconDeleted( + const GURL &page_url, + favicon::FaviconDriverObserver::NotificationIconType notification_icon_type) override; + void OnHandlerCompleted(favicon::FaviconHandler *handler) override; + + // content::WebContentsObserver implementation. + void DidUpdateFaviconURL(content::RenderFrameHost *render_frame_host, + const std::vector<blink::mojom::FaviconURLPtr> &candidates) override; + void DidUpdateWebManifestURL(content::RenderFrameHost *target_frame, + const base::Optional<GURL> &manifest_url) override; + void DidStartNavigation(content::NavigationHandle *navigation_handle) override; + void DidFinishNavigation(content::NavigationHandle *navigation_handle) override; + void DocumentOnLoadCompletedInMainFrame() override; + + // Informs FaviconService that the favicon for |url| is out of date. If + // |force_reload| is true, then discard information about favicon download + // failures. + void SetFaviconOutOfDateForPage(const GURL &url, bool force_reload); + + // Broadcasts new favicon URL candidates to FaviconHandlers. + void OnUpdateCandidates(const GURL &page_url, + const std::vector<favicon::FaviconURL> &candidates, + const GURL &manifest_url); + + void emitIconChangedIfNeeded(); + + // KeyedService used by FaviconDriverImpl. It may be null during testing, + // but if it is defined, it must outlive the FaviconDriverImpl. + favicon::FaviconService *m_faviconService; + + WebContentsAdapterClient *m_viewClient; + + // FaviconHandlers used to download the different kind of favicons. + std::vector<std::unique_ptr<favicon::FaviconHandler>> m_handlers; + + GURL m_bypassCachePageURL; + bool m_documentOnLoadCompleted = false; + + // nullopt until the actual list is reported via DidUpdateFaviconURL(). + base::Optional<std::vector<blink::mojom::FaviconURL>> m_faviconUrls; + // Web Manifest URL or empty URL if none. + GURL m_manifestUrl; + + int m_completedHandlersCount = 0; + FaviconStatusQt m_latestFavicon; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); + DISALLOW_COPY_AND_ASSIGN(FaviconDriverQt); +}; + +} // namespace QtWebEngineCore + +#endif // FAVICON_DRIVER_QT_H diff --git a/src/core/favicon_manager.cpp b/src/core/favicon_manager.cpp deleted file mode 100644 index 3cb417c4f..000000000 --- a/src/core/favicon_manager.cpp +++ /dev/null @@ -1,437 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "favicon_manager.h" -#include "type_conversion.h" -#include "web_contents_adapter_client.h" -#include "web_engine_settings.h" - -#include "base/bind.h" -#include "content/public/browser/favicon_status.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/web_contents.h" -#include "content/public/common/url_constants.h" -#include "net/base/data_url.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkPixelRef.h" -#include "ui/gfx/geometry/size.h" - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -#include <qiconengine.h> -#include <private/qicon_p.h> -#endif - -namespace QtWebEngineCore { - -static inline bool isResourceUrl(const QUrl &url) -{ - return !url.scheme().compare(QLatin1String("qrc")); -} - -static inline bool isDataUrl(const QUrl &url) -{ - return !url.scheme().compare(QLatin1String(url::kDataScheme)); -} - -static inline unsigned area(const QSize &size) -{ - return size.width() * size.height(); -} - - -FaviconManager::FaviconManager(content::WebContents *webContents, WebContentsAdapterClient *viewClient) - : m_webContents(webContents) - , m_viewClient(viewClient) - , m_candidateCount(0) - , m_weakFactory(new base::WeakPtrFactory<FaviconManager>(this)) -{ -} - -FaviconManager::~FaviconManager() -{ -} - -int FaviconManager::downloadIcon(const QUrl &url) -{ - static const uint32_t maxSize = 256; - static int fakeId = 0; - int id; - - bool cached = m_icons.contains(url); - if (isResourceUrl(url) || isDataUrl(url) || cached) { - id = --fakeId; - m_pendingRequests.insert(id, url); - } else { - id = m_webContents->DownloadImage( - toGurl(url), - true, // is_favicon - 0, // preferred_size - maxSize, - false, // normal cache policy - base::Bind(&FaviconManager::iconDownloadFinished, m_weakFactory->GetWeakPtr())); - } - - Q_ASSERT(!m_inProgressRequests.contains(id)); - m_inProgressRequests.insert(id, url); - - return id; -} - -void FaviconManager::iconDownloadFinished(int id, - int status, - const GURL &url, - const std::vector<SkBitmap> &bitmaps, - const std::vector<gfx::Size> &original_bitmap_sizes) -{ - Q_UNUSED(status); - Q_UNUSED(url); - Q_UNUSED(original_bitmap_sizes); - - storeIcon(id, toQIcon(bitmaps)); -} - -/* Pending requests are used to mark icons that are already downloaded (cached icons or icons - * stored in qrc). These requests are also stored in the m_inProgressRequests but the corresponding - * icons are stored in m_icons explicitly by this function. It is necessary to avoid - * m_inProgressRequests being emptied right before the next icon is added by a downloadIcon() call. - */ -void FaviconManager::downloadPendingRequests() -{ - for (auto it = m_pendingRequests.cbegin(), end = m_pendingRequests.cend(); it != end; ++it) { - QIcon icon; - - QUrl requestUrl = it.value(); - if (!m_icons.contains(requestUrl)) { - if (isResourceUrl(requestUrl)) { - icon = QIcon(requestUrl.toString().remove(0, 3)); - } else if (isDataUrl(requestUrl)) { - std::string mime_type, char_set, data; - if (net::DataURL::Parse(toGurl(requestUrl), &mime_type, &char_set, &data) && !data.empty()) { - const unsigned char *src_data = reinterpret_cast<const unsigned char *>(data.data()); - QImage image = QImage::fromData(src_data, data.size()); - icon.addPixmap(QPixmap::fromImage(image).copy()); - } - } - } - - storeIcon(it.key(), icon); - } - - m_pendingRequests.clear(); -} - -void FaviconManager::storeIcon(int id, const QIcon &icon) -{ - - // Icon download has been interrupted - if (!m_inProgressRequests.contains(id)) - return; - - QUrl requestUrl = m_inProgressRequests[id]; - FaviconInfo &faviconInfo = m_faviconInfoMap[requestUrl]; - - unsigned iconCount = 0; - if (!icon.isNull()) - iconCount = icon.availableSizes().count(); - - if (iconCount > 0) { - m_icons.insert(requestUrl, icon); - - faviconInfo.size = icon.availableSizes().at(0); - if (iconCount > 1) { - faviconInfo.multiSize = true; - unsigned bestArea = area(faviconInfo.size); - for (unsigned i = 1; i < iconCount; ++i) { - QSize iconSize = icon.availableSizes().at(i); - if (bestArea < area(iconSize)) { - faviconInfo.size = iconSize; - bestArea = area(iconSize); - } - } - } - } else if (id >= 0) { - // Reset size if icon cannot be downloaded - faviconInfo.size = QSize(0, 0); - } - - m_inProgressRequests.remove(id); - if (m_inProgressRequests.isEmpty()) { - QWebEngineSettings *settings = m_viewClient->webEngineSettings(); - bool touchIconsEnabled = settings->testAttribute(QWebEngineSettings::TouchIconsEnabled); - - generateCandidateIcon(touchIconsEnabled); - const QUrl &iconUrl = candidateIconUrl(touchIconsEnabled); - propagateIcon(iconUrl); - } -} - -void FaviconManager::propagateIcon(const QUrl &iconUrl) const -{ - content::NavigationEntry *entry = m_webContents->GetController().GetVisibleEntry(); - if (entry) { - content::FaviconStatus &favicon = entry->GetFavicon(); - favicon.url = toGurl(iconUrl); - favicon.valid = true; - } - - m_viewClient->iconChanged(iconUrl); -} - -QIcon FaviconManager::getIcon(const QUrl &url) const -{ - if (url.isEmpty()) - return m_candidateIcon; - - if (!m_icons.contains(url)) - return QIcon(); - - return m_icons[url]; -} - -FaviconInfo FaviconManager::getFaviconInfo(const QUrl &url) const -{ - Q_ASSERT(m_faviconInfoMap.contains(url)); - return m_faviconInfoMap[url]; -} - -QList<FaviconInfo> FaviconManager::getFaviconInfoList(bool candidatesOnly) const -{ - QList<FaviconInfo> faviconInfoList = m_faviconInfoMap.values(); - - if (candidatesOnly) { - const auto hasNoCandidate = [](const FaviconInfo &info) { return !info.candidate; }; - faviconInfoList.erase(std::remove_if(faviconInfoList.begin(), faviconInfoList.end(), - hasNoCandidate), - faviconInfoList.end()); - } - - return faviconInfoList; -} - -void FaviconManager::update(const QList<FaviconInfo> &candidates) -{ - updateCandidates(candidates); - - QWebEngineSettings *settings = m_viewClient->webEngineSettings(); - if (!settings->testAttribute(QWebEngineSettings::AutoLoadIconsForPage)) { - m_viewClient->iconChanged(QUrl()); - return; - } - - bool touchIconsEnabled = settings->testAttribute(QWebEngineSettings::TouchIconsEnabled); - - const QList<FaviconInfo> &faviconInfoList = getFaviconInfoList(true /* candidates only */); - for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) { - if (!touchIconsEnabled && !(it->type & FaviconInfo::Favicon)) - continue; - - if (it->isValid()) - downloadIcon(it->url); - } - - downloadPendingRequests(); - - // Reset icon if nothing was downloaded - if (m_inProgressRequests.isEmpty()) { - content::NavigationEntry *entry = m_webContents->GetController().GetVisibleEntry(); - if (entry && !entry->GetFavicon().valid) - m_viewClient->iconChanged(QUrl()); - } -} - -void FaviconManager::updateCandidates(const QList<FaviconInfo> &candidates) -{ - // Invalidate types of the already stored candidate icons because it might differ - // among pages. - for (FaviconInfo candidateFaviconInfo : candidates) { - const QUrl &candidateUrl = candidateFaviconInfo.url; - if (m_faviconInfoMap.contains(candidateUrl)) - m_faviconInfoMap[candidateUrl].type = FaviconInfo::InvalidIcon; - } - - m_candidateCount = candidates.count(); - for (FaviconInfo candidateFaviconInfo : candidates) { - const QUrl &candidateUrl = candidateFaviconInfo.url; - - if (!m_faviconInfoMap.contains(candidateUrl)) - m_faviconInfoMap.insert(candidateUrl, candidateFaviconInfo); - else { - // The same icon URL can be used for different types. - m_faviconInfoMap[candidateUrl].type |= candidateFaviconInfo.type; - } - - m_faviconInfoMap[candidateUrl].candidate = true; - } -} - -void FaviconManager::resetCandidates() -{ - // Interrupt in progress icon downloads - m_pendingRequests.clear(); - m_inProgressRequests.clear(); - - m_candidateCount = 0; - m_candidateIcon = QIcon(); - for (auto it = m_faviconInfoMap.begin(), end = m_faviconInfoMap.end(); it != end; ++it) - it->candidate = false; -} - -bool FaviconManager::hasCandidate() const -{ - return (m_candidateCount > 0); -} - -QUrl FaviconManager::candidateIconUrl(bool touchIconsEnabled) const -{ - QUrl iconUrl; - const QList<FaviconInfo> &faviconInfoList = getFaviconInfoList(true /* candidates only */); - - unsigned bestArea = 0; - for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) { - if (!touchIconsEnabled && !(it->type & FaviconInfo::Favicon)) - continue; - - if (it->isValid() && bestArea < area(it->size)) { - iconUrl = it->url; - bestArea = area(it->size); - } - } - - return iconUrl; -} - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -static QPixmap getUnscaledPixmap(QIcon icon, const QSize &size) -{ - QPixmap pixmap = icon.data_ptr()->engine->pixmap(size, QIcon::Normal, QIcon::Off); - pixmap.setDevicePixelRatio(1.0); - return pixmap; -} -#else -static QPixmap getUnscaledPixmap(const QIcon &icon, const QSize &size) -{ - return icon.pixmap(size, 1.0); -} -#endif - -void FaviconManager::generateCandidateIcon(bool touchIconsEnabled) -{ - Q_ASSERT(m_candidateCount); - - m_candidateIcon = QIcon(); - const QList<FaviconInfo> &faviconInfoList = getFaviconInfoList(true /* candidates only */); - - for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) { - if (!touchIconsEnabled && !(it->type & FaviconInfo::Favicon)) - continue; - - if (!it->isValid() || !it->isDownloaded()) - continue; - - const QIcon &icon = getIcon(it->url); - - if (!it->multiSize) { - if (!m_candidateIcon.availableSizes().contains(it->size)) - m_candidateIcon.addPixmap(getUnscaledPixmap(icon, it->size)); - - continue; - } - - const auto sizes = icon.availableSizes(); - for (const QSize &size : sizes) { - if (!m_candidateIcon.availableSizes().contains(size)) - m_candidateIcon.addPixmap(getUnscaledPixmap(icon, size)); - } - } -} - -void FaviconManager::copyStateFrom(FaviconManager *source) -{ - m_faviconInfoMap = source->m_faviconInfoMap; - m_icons = source->m_icons; -} - -FaviconInfo::FaviconInfo() - : url(QUrl()) - , type(FaviconInfo::InvalidIcon) - , size(QSize(0, 0)) - , candidate(false) - , multiSize(false) -{ -} - -FaviconInfo::FaviconInfo(const FaviconInfo &other) - : url(other.url) - , type(other.type) - , size(other.size) - , candidate(other.candidate) - , multiSize(other.multiSize) -{ -} - -FaviconInfo::FaviconInfo(const QUrl &url, FaviconInfo::FaviconTypeFlags type) - : url(url) - , type(type) - , size(QSize(0, 0)) - , candidate(false) - , multiSize(false) -{ -} - -FaviconInfo::~FaviconInfo() -{ -} - -bool FaviconInfo::isValid() const -{ - if (type == FaviconInfo::InvalidIcon) - return false; - - if (url.isEmpty() || !url.isValid()) - return false; - - return true; -} - -bool FaviconInfo::isDownloaded() const -{ - return area(size) > 0; -} - -} // namespace QtWebEngineCore diff --git a/src/core/favicon_manager.h b/src/core/favicon_manager.h deleted file mode 100644 index a6e5822a9..000000000 --- a/src/core/favicon_manager.h +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#ifndef FAVICON_MANAGER_H -#define FAVICON_MANAGER_H - -#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h> -#include <memory> -#include <QtCore/QMap> -#include <QtCore/QObject> -#include <QtCore/QSize> -#include <QtCore/QUrl> -#include <QtGui/QIcon> - -#include "web_engine_settings.h" - -class GURL; -class SkBitmap; - -namespace gfx { -class Size; -} - -namespace content { -class WebContents; -} - -namespace base { -template<class T> -class WeakPtrFactory; -} - -namespace QtWebEngineCore { - -class WebContentsAdapterClient; - -// Based on src/3rdparty/chromium/content/public/common/favicon_url.h -class Q_WEBENGINECORE_PRIVATE_EXPORT FaviconInfo { -public: - enum FaviconTypeFlag { - InvalidIcon = 0, - Favicon = 1 << 0, - TouchIcon = 1 << 1, - TouchPrecomposedIcon = 1 << 2 - }; - Q_DECLARE_FLAGS(FaviconTypeFlags, FaviconTypeFlag) - - FaviconInfo(); - FaviconInfo(const FaviconInfo &); - FaviconInfo(const QUrl &, FaviconInfo::FaviconTypeFlags); - ~FaviconInfo(); - - bool isValid() const; - bool isDownloaded() const; - - QUrl url; - FaviconTypeFlags type; - // Stores the largest size in case of multi-size icon - QSize size; - bool candidate; - bool multiSize; -}; - - -class Q_WEBENGINECORE_PRIVATE_EXPORT FaviconManager { - -public: - FaviconManager(content::WebContents *, WebContentsAdapterClient *); - ~FaviconManager(); - - QIcon getIcon(const QUrl &url = QUrl()) const; - FaviconInfo getFaviconInfo(const QUrl &) const; - QList<FaviconInfo> getFaviconInfoList(bool) const; - void copyStateFrom(FaviconManager *source); - -private: - void update(const QList<FaviconInfo> &); - void updateCandidates(const QList<FaviconInfo> &); - void resetCandidates(); - bool hasCandidate() const; - QUrl candidateIconUrl(bool touchIconsEnabled) const; - void generateCandidateIcon(bool touchIconsEnabled); - int downloadIcon(const QUrl &); - void iconDownloadFinished(int, int, const GURL &, const std::vector<SkBitmap> &, const std::vector<gfx::Size> &); - void storeIcon(int, const QIcon &); - void downloadPendingRequests(); - void propagateIcon(const QUrl &) const; - -private: - content::WebContents *m_webContents; - WebContentsAdapterClient *m_viewClient; - QMap<QUrl, FaviconInfo> m_faviconInfoMap; - int m_candidateCount; - QIcon m_candidateIcon; - QMap<QUrl, QIcon> m_icons; - QMap<int, QUrl> m_inProgressRequests; - QMap<int, QUrl> m_pendingRequests; - std::unique_ptr<base::WeakPtrFactory<FaviconManager>> m_weakFactory; - friend class WebContentsDelegateQt; -}; - -} // namespace QtWebEngineCore - -#endif // FAVICON_MANAGER_H diff --git a/src/core/favicon_service_factory_qt.cpp b/src/core/favicon_service_factory_qt.cpp new file mode 100644 index 000000000..898882486 --- /dev/null +++ b/src/core/favicon_service_factory_qt.cpp @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "favicon_service_factory_qt.h" + +#include "base/files/file_util.h" +#include "components/favicon/core/favicon_service_impl.h" +#include "components/history/content/browser/content_visit_delegate.h" +#include "components/history/content/browser/history_database_helper.h" +#include "components/history/core/browser/history_backend_client.h" +#include "components/history/core/browser/history_database_params.h" +#include "components/history/core/browser/history_service.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "content/public/browser/browser_context.h" +#include "url/gurl.h" + +namespace QtWebEngineCore { + +void HistoryClientQt::OnHistoryServiceCreated(history::HistoryService *history_service) +{ + Q_UNUSED(history_service); +} + +void HistoryClientQt::Shutdown() { } + +bool HistoryClientQt::CanAddURL(const GURL &url) +{ + Q_UNUSED(url); + return true; +} + +void HistoryClientQt::NotifyProfileError(sql::InitStatus init_status, + const std::string &diagnostics) +{ + Q_UNUSED(init_status); + Q_UNUSED(diagnostics); +} + +std::unique_ptr<history::HistoryBackendClient> HistoryClientQt::CreateBackendClient() +{ + return nullptr; +} + +// static +history::HistoryService * +HistoryServiceFactoryQt::GetForBrowserContext(content::BrowserContext *context) +{ + if (context->IsOffTheRecord()) + return nullptr; + + if (!base::PathExists(context->GetPath())) + return nullptr; + + return static_cast<history::HistoryService *>( + GetInstance()->GetServiceForBrowserContext(context, true)); +} + +// static +HistoryServiceFactoryQt *HistoryServiceFactoryQt::GetInstance() +{ + return base::Singleton<HistoryServiceFactoryQt>::get(); +} + +HistoryServiceFactoryQt::HistoryServiceFactoryQt() + : BrowserContextKeyedServiceFactory("HistoryService", + BrowserContextDependencyManager::GetInstance()) +{ +} + +HistoryServiceFactoryQt::~HistoryServiceFactoryQt() { } + +content::BrowserContext * +HistoryServiceFactoryQt::GetBrowserContextToUse(content::BrowserContext *context) const +{ + return context; +} + +KeyedService * +HistoryServiceFactoryQt::BuildServiceInstanceFor(content::BrowserContext *context) const +{ + Q_ASSERT(!context->IsOffTheRecord()); + Q_ASSERT(base::PathExists(context->GetPath())); + + std::unique_ptr<history::HistoryService> historyService( + new history::HistoryService(std::make_unique<HistoryClientQt>(), nullptr)); + if (!historyService->Init(history::HistoryDatabaseParamsForPath(context->GetPath()))) { + return nullptr; + } + return historyService.release(); +} + +bool FaviconClientQt::IsNativeApplicationURL(const GURL &url) +{ + Q_UNUSED(url); + return false; +} + +bool FaviconClientQt::IsReaderModeURL(const GURL &url) +{ + Q_UNUSED(url) + return false; +} + +const GURL FaviconClientQt::GetOriginalUrlFromReaderModeUrl(const GURL &url) +{ + return url; +} + +base::CancelableTaskTracker::TaskId FaviconClientQt::GetFaviconForNativeApplicationURL( + const GURL &url, const std::vector<int> &desired_sizes_in_pixel, + favicon_base::FaviconResultsCallback callback, base::CancelableTaskTracker *tracker) +{ + Q_UNUSED(url); + Q_UNUSED(desired_sizes_in_pixel); + Q_UNUSED(callback); + Q_UNUSED(tracker); + + return base::CancelableTaskTracker::kBadTaskId; +} + +// static +favicon::FaviconService * +FaviconServiceFactoryQt::GetForBrowserContext(content::BrowserContext *context) +{ + return static_cast<favicon::FaviconService *>( + GetInstance()->GetServiceForBrowserContext(context, true)); +} + +// static +FaviconServiceFactoryQt *FaviconServiceFactoryQt::GetInstance() +{ + return base::Singleton<FaviconServiceFactoryQt>::get(); +} + +FaviconServiceFactoryQt::FaviconServiceFactoryQt() + : BrowserContextKeyedServiceFactory("FaviconService", + BrowserContextDependencyManager::GetInstance()) +{ +} + +FaviconServiceFactoryQt::~FaviconServiceFactoryQt() { } + +content::BrowserContext * +FaviconServiceFactoryQt::GetBrowserContextToUse(content::BrowserContext *context) const +{ + return context; +} + +KeyedService * +FaviconServiceFactoryQt::BuildServiceInstanceFor(content::BrowserContext *context) const +{ + history::HistoryService *historyService = static_cast<history::HistoryService *>( + HistoryServiceFactoryQt::GetInstance()->GetForBrowserContext(context)); + return new favicon::FaviconServiceImpl(std::make_unique<FaviconClientQt>(), historyService); +} + +} // namespace QtWebEngineCore diff --git a/src/core/favicon_service_factory_qt.h b/src/core/favicon_service_factory_qt.h new file mode 100644 index 000000000..1ba0db076 --- /dev/null +++ b/src/core/favicon_service_factory_qt.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#ifndef FAVICON_SERVICE_FACTORY_QT_H +#define FAVICON_SERVICE_FACTORY_QT_H + +#include "qtwebenginecoreglobal_p.h" + +#include "base/memory/singleton.h" +#include "base/task/cancelable_task_tracker.h" +#include "components/favicon/core/favicon_client.h" +#include "components/history/core/browser/history_client.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +class GURL; + +namespace content { +class BrowserContext; +} + +namespace favicon { +class FaviconService; +} + +namespace history { +class HistoryBackendClient; +class HistoryService; +} + +namespace QtWebEngineCore { + +class HistoryClientQt : public history::HistoryClient +{ +public: + HistoryClientQt() { } + virtual ~HistoryClientQt() { } + + void OnHistoryServiceCreated(history::HistoryService *history_service) override; + void Shutdown() override; + bool CanAddURL(const GURL &url) override; + void NotifyProfileError(sql::InitStatus init_status, const std::string &diagnostics) override; + std::unique_ptr<history::HistoryBackendClient> CreateBackendClient() override; +}; + +class HistoryServiceFactoryQt : public BrowserContextKeyedServiceFactory +{ +public: + static history::HistoryService *GetForBrowserContext(content::BrowserContext *context); + static HistoryServiceFactoryQt *GetInstance(); + +private: + friend struct base::DefaultSingletonTraits<HistoryServiceFactoryQt>; + + HistoryServiceFactoryQt(); + ~HistoryServiceFactoryQt() override; + + // BrowserContextKeyedServiceFactory: + content::BrowserContext * + GetBrowserContextToUse(content::BrowserContext *context) const override; + KeyedService *BuildServiceInstanceFor(content::BrowserContext *context) const override; +}; + +class FaviconClientQt : public favicon::FaviconClient +{ +public: + FaviconClientQt() { } + virtual ~FaviconClientQt() { } + + bool IsNativeApplicationURL(const GURL &url) override; + bool IsReaderModeURL(const GURL &url) override; + const GURL GetOriginalUrlFromReaderModeUrl(const GURL &url) override; + base::CancelableTaskTracker::TaskId + GetFaviconForNativeApplicationURL(const GURL &url, + const std::vector<int> &desired_sizes_in_pixel, + favicon_base::FaviconResultsCallback callback, + base::CancelableTaskTracker *tracker) override; +}; + +class FaviconServiceFactoryQt : public BrowserContextKeyedServiceFactory +{ +public: + static favicon::FaviconService *GetForBrowserContext(content::BrowserContext *context); + static FaviconServiceFactoryQt *GetInstance(); + +private: + friend struct base::DefaultSingletonTraits<FaviconServiceFactoryQt>; + + FaviconServiceFactoryQt(); + ~FaviconServiceFactoryQt() override; + + // BrowserContextKeyedServiceFactory: + content::BrowserContext * + GetBrowserContextToUse(content::BrowserContext *context) const override; + KeyedService *BuildServiceInstanceFor(content::BrowserContext *context) const override; +}; + +} // namespace QtWebEngineCore + +#endif // FAVICON_SERVICE_FACTORY_QT_H diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp index bca059ae6..e01e82aa9 100644 --- a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp +++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp @@ -56,6 +56,7 @@ #include "extensions/extension_system_qt.h" #include "web_contents_delegate_qt.h" +#include "web_engine_settings.h" #include <string> diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp index 9a6275a84..204974c28 100644 --- a/src/core/profile_adapter.cpp +++ b/src/core/profile_adapter.cpp @@ -39,6 +39,10 @@ #include "profile_adapter.h" +#include "components/favicon/core/favicon_service.h" +#include "components/history/content/browser/history_database_helper.h" +#include "components/history/core/browser/history_database_params.h" +#include "components/history/core/browser/history_service.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/browsing_data_remover.h" @@ -51,6 +55,7 @@ #include "api/qwebengineurlscheme.h" #include "content_browser_client_qt.h" #include "download_manager_delegate_qt.h" +#include "favicon_service_factory_qt.h" #include "permission_manager_qt.h" #include "profile_adapter_client.h" #include "profile_io_data_qt.h" @@ -151,6 +156,8 @@ void ProfileAdapter::setStorageName(const QString &storageName) m_profile->m_profileIOData->resetNetworkContext(); if (m_visitedLinksManager) resetVisitedLinksManager(); + + reinitializeHistoryService(); } } @@ -164,6 +171,14 @@ void ProfileAdapter::setOffTheRecord(bool offTheRecord) m_profile->m_profileIOData->resetNetworkContext(); if (m_visitedLinksManager) resetVisitedLinksManager(); + + if (offTheRecord) { + favicon::FaviconService *faviconService = + FaviconServiceFactoryQt::GetForBrowserContext(m_profile.data()); + faviconService->SetHistoryService(nullptr); + } else if (!m_name.isEmpty()) { + reinitializeHistoryService(); + } } ProfileQt *ProfileAdapter::profile() @@ -273,6 +288,9 @@ void ProfileAdapter::setDataPath(const QString &path) m_profile->m_profileIOData->resetNetworkContext(); if (!m_offTheRecord && m_visitedLinksManager) resetVisitedLinksManager(); + + if (!m_offTheRecord) + reinitializeHistoryService(); } void ProfileAdapter::setDownloadPath(const QString &path) @@ -652,6 +670,21 @@ void ProfileAdapter::resetVisitedLinksManager() m_visitedLinksManager.reset(new VisitedLinksManagerQt(m_profile.data(), persistVisitedLinks())); } +void ProfileAdapter::reinitializeHistoryService() +{ + Q_ASSERT(!m_profile->IsOffTheRecord()); + if (m_profile->ensureDirectoryExists()) { + favicon::FaviconService *faviconService = + FaviconServiceFactoryQt::GetForBrowserContext(m_profile.data()); + history::HistoryService *historyService = static_cast<history::HistoryService *>( + HistoryServiceFactoryQt::GetInstance()->GetForBrowserContext(m_profile.data())); + Q_ASSERT(historyService); + faviconService->SetHistoryService(historyService); + } else { + qWarning("Favicon database is not available for this profile."); + } +} + void ProfileAdapter::setUseForGlobalCertificateVerification(bool enable) { if (m_usedForGlobalCertificateVerification == enable) diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h index fecb338ad..979316b4a 100644 --- a/src/core/profile_adapter.h +++ b/src/core/profile_adapter.h @@ -220,6 +220,7 @@ private: void updateCustomUrlSchemeHandlers(); void resetVisitedLinksManager(); bool persistVisitedLinks() const; + void reinitializeHistoryService(); QString m_name; bool m_offTheRecord; diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp index 36303605f..ae1169558 100644 --- a/src/core/profile_qt.cpp +++ b/src/core/profile_qt.cpp @@ -58,6 +58,7 @@ #include "content/public/browser/storage_partition.h" #include "base/base_paths.h" +#include "base/files/file_util.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" @@ -298,4 +299,21 @@ content::PlatformNotificationService *ProfileQt::platformNotificationService() return m_platformNotificationService.get(); } +bool ProfileQt::ensureDirectoryExists() +{ + const base::FilePath &path = GetPath(); + + if (base::PathExists(path)) + return true; + + base::File::Error error; + if (base::CreateDirectoryAndGetError(path, &error)) + return true; + + std::string errorstr = base::File::ErrorToString(error); + qWarning("Cannot create directory %s. Error: %s.", path.AsUTF8Unsafe().c_str(), + errorstr.c_str()); + return false; +} + } // namespace QtWebEngineCore diff --git a/src/core/profile_qt.h b/src/core/profile_qt.h index 11b567b97..349532939 100644 --- a/src/core/profile_qt.h +++ b/src/core/profile_qt.h @@ -119,6 +119,7 @@ public: PrefServiceAdapter &prefServiceAdapter(); const PrefServiceAdapter &prefServiceAdapter() const; + bool ensureDirectoryExists(); private: friend class ContentBrowserClientQt; diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni index 49217603f..8f3cac727 100644 --- a/src/core/qtwebengine.gni +++ b/src/core/qtwebengine.gni @@ -19,6 +19,8 @@ deps = [ "//base", "//components/cdm/renderer", "//components/error_page/common", + "//components/favicon/content", + "//components/history/content/browser", "//components/keyed_service/content", "//components/navigation_interception", "//components/network_hints/browser", diff --git a/src/core/type_conversion.cpp b/src/core/type_conversion.cpp index a4cc57b76..e8f8131b6 100644 --- a/src/core/type_conversion.cpp +++ b/src/core/type_conversion.cpp @@ -39,9 +39,11 @@ #include "type_conversion.h" +#include <components/favicon_base/favicon_util.h> #include <net/cert/x509_certificate.h> #include <net/cert/x509_util.h> #include <ui/events/event_constants.h> +#include <ui/gfx/image/image.h> #include <ui/gfx/image/image_skia.h> #include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h" @@ -216,6 +218,23 @@ SkBitmap toSkBitmap(const QImage &image) return bitmapCopy; } +QIcon toQIcon(const gfx::Image &image) +{ + // Based on ExtractSkBitmapsToStore in chromium/components/favicon/core/favicon_service_impl.cc + gfx::ImageSkia image_skia = image.AsImageSkia(); + image_skia.EnsureRepsForSupportedScales(); + const std::vector<gfx::ImageSkiaRep> &image_reps = image_skia.image_reps(); + std::vector<SkBitmap> bitmaps; + const std::vector<float> favicon_scales = favicon_base::GetFaviconScales(); + for (size_t i = 0; i < image_reps.size(); ++i) { + // Don't save if the scale isn't one of supported favicon scales. + if (!base::Contains(favicon_scales, image_reps[i].scale())) + continue; + bitmaps.push_back(image_reps[i].GetBitmap()); + } + return toQIcon(bitmaps); +} + QIcon toQIcon(const std::vector<SkBitmap> &bitmaps) { if (!bitmaps.size()) @@ -257,33 +276,6 @@ int flagsFromModifiers(Qt::KeyboardModifiers modifiers) return modifierFlags; } -FaviconInfo::FaviconTypeFlags toQt(blink::mojom::FaviconIconType type) -{ - switch (type) { - case blink::mojom::FaviconIconType::kFavicon: - return FaviconInfo::Favicon; - case blink::mojom::FaviconIconType::kTouchIcon: - return FaviconInfo::TouchIcon; - case blink::mojom::FaviconIconType::kTouchPrecomposedIcon: - return FaviconInfo::TouchPrecomposedIcon; - case blink::mojom::FaviconIconType::kInvalid: - return FaviconInfo::InvalidIcon; - } - Q_UNREACHABLE(); - return FaviconInfo::InvalidIcon; -} - -FaviconInfo toFaviconInfo(const blink::mojom::FaviconURLPtr &favicon_url) -{ - FaviconInfo info; - info.url = toQt(favicon_url->icon_url); - info.type = toQt(favicon_url->icon_type); - // TODO: Add support for rel sizes attribute (favicon_url.icon_sizes): - // http://www.w3schools.com/tags/att_link_sizes.asp - info.size = QSize(0, 0); - return info; -} - void convertToQt(const SkMatrix44 &m, QMatrix4x4 &c) { QMatrix4x4 qtMatrix( diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h index 85fd763b4..fff130218 100644 --- a/src/core/type_conversion.h +++ b/src/core/type_conversion.h @@ -52,7 +52,6 @@ #include <base/strings/nullable_string16.h> #include "base/files/file_path.h" #include "base/time/time.h" -#include "favicon_manager.h" #include "net/cookies/canonical_cookie.h" #include "third_party/blink/public/mojom/favicon/favicon_url.mojom-forward.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -68,6 +67,7 @@ QT_FORWARD_DECLARE_CLASS(QMatrix4x4) QT_FORWARD_DECLARE_CLASS(QSslCertificate) namespace gfx { +class Image; class ImageSkiaRep; } @@ -222,6 +222,7 @@ QImage toQImage(const SkBitmap &bitmap); QImage toQImage(const gfx::ImageSkiaRep &imageSkiaRep); SkBitmap toSkBitmap(const QImage &image); +QIcon toQIcon(const gfx::Image &image); QIcon toQIcon(const std::vector<SkBitmap> &bitmaps); void convertToQt(const SkMatrix44 &m, QMatrix4x4 &c); @@ -272,8 +273,6 @@ inline QStringList fromVector(const std::vector<base::string16> &vector) return result; } -FaviconInfo toFaviconInfo(const blink::mojom::FaviconURLPtr &favicon_url); - QList<QSslCertificate> toCertificateChain(net::X509Certificate *certificate); Qt::InputMethodHints toQtInputMethodHints(ui::TextInputType inputType); diff --git a/src/core/visited_links_manager_qt.cpp b/src/core/visited_links_manager_qt.cpp index 37343cc39..15f655012 100644 --- a/src/core/visited_links_manager_qt.cpp +++ b/src/core/visited_links_manager_qt.cpp @@ -90,27 +90,12 @@ bool VisitedLinksManagerQt::containsUrl(const QUrl &url) const return m_visitedLinkWriter->IsVisited(toGurl(url)); } -static void ensureDirectoryExists(const base::FilePath &path) -{ - if (base::PathExists(path)) - return; - - base::File::Error error; - if (base::CreateDirectoryAndGetError(path, &error)) - return; - - std::string errorstr = base::File::ErrorToString(error); - qWarning("Cannot create directory %s. Error: %s.", - path.AsUTF8Unsafe().c_str(), - errorstr.c_str()); -} - VisitedLinksManagerQt::VisitedLinksManagerQt(ProfileQt *profile, bool persistVisitedLinks) : m_delegate(new VisitedLinkDelegateQt) { Q_ASSERT(profile); if (persistVisitedLinks) - ensureDirectoryExists(profile->GetPath()); + profile->ensureDirectoryExists(); m_visitedLinkWriter.reset(new visitedlink::VisitedLinkWriter(profile, m_delegate.data(), persistVisitedLinks)); m_visitedLinkWriter->Init(); } diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index f5656f571..16e91e6c7 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -45,6 +45,8 @@ #include "devtools_frontend_qt.h" #include "download_manager_delegate_qt.h" +#include "favicon_driver_qt.h" +#include "favicon_service_factory_qt.h" #include "media_capture_devices_dispatcher.h" #if QT_CONFIG(webengine_printing_and_pdf) #include "printing/print_view_manager_qt.h" @@ -69,6 +71,7 @@ #include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h" #include "base/values.h" #include "chrome/browser/tab_contents/form_interaction_tab_helper.h" +#include "components/favicon/core/favicon_service.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/text_input_manager.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -532,6 +535,10 @@ void WebContentsAdapter::initialize(content::SiteInstance *site) extensions::ExtensionWebContentsObserverQt::CreateForWebContents(webContents()); #endif + content::BrowserContext *context = webContents()->GetBrowserContext(); + FaviconDriverQt::CreateForWebContents( + webContents(), FaviconServiceFactoryQt::GetForBrowserContext(context), m_adapterClient); + // Create an instance of WebEngineVisitedLinksManager to catch the first // content::NOTIFICATION_RENDERER_PROCESS_CREATED event. This event will // force to initialize visited links in VisitedLinkSlave. @@ -818,12 +825,15 @@ QUrl WebContentsAdapter::requestedUrl() const QUrl WebContentsAdapter::iconUrl() const { CHECK_INITIALIZED(QUrl()); - if (content::NavigationEntry* entry = m_webContents->GetController().GetVisibleEntry()) { - content::FaviconStatus &favicon = entry->GetFavicon(); - if (favicon.valid) - return toQt(favicon.url); - } - return QUrl(); + FaviconDriverQt *driver = FaviconDriverQt::FromWebContents(webContents()); + return toQt(driver->GetFaviconURL()); +} + +QIcon WebContentsAdapter::icon() const +{ + CHECK_INITIALIZED(QIcon()); + FaviconDriverQt *driver = FaviconDriverQt::FromWebContents(webContents()); + return toQIcon(driver->GetFavicon()); } QString WebContentsAdapter::pageTitle() const @@ -1805,12 +1815,6 @@ WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) { return status; } -FaviconManager *WebContentsAdapter::faviconManager() -{ - CHECK_INITIALIZED(nullptr); - return m_webContentsDelegate->faviconManager(); -} - FindTextHelper *WebContentsAdapter::findTextHelper() { CHECK_INITIALIZED(nullptr); diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index b05ddeb4d..f4905e1d4 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -138,6 +138,7 @@ public: QString pageTitle() const; QString selectedText() const; QUrl iconUrl() const; + QIcon icon() const; void undo(); void redo(); @@ -212,7 +213,6 @@ public: QWebChannel *webChannel() const; void setWebChannel(QWebChannel *, uint worldId); #endif - FaviconManager *faviconManager(); FindTextHelper *findTextHelper(); QPointF lastScrollOffset() const; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 5d11f43c3..34e1f7ad1 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -46,7 +46,6 @@ #include "profile_adapter.h" #include "color_chooser_controller.h" #include "color_chooser_qt.h" -#include "favicon_manager.h" #include "file_picker_controller.h" #include "media_capture_devices_dispatcher.h" #include "profile_qt.h" @@ -102,7 +101,6 @@ static WebContentsAdapterClient::JavaScriptConsoleMessageLevel mapToJavascriptCo WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents, WebContentsAdapterClient *adapterClient) : m_viewClient(adapterClient) - , m_faviconManager(new FaviconManager(webContents, adapterClient)) , m_findTextHelper(new FindTextHelper(webContents, adapterClient)) , m_loadingState(determineLoadingState(webContents)) , m_didStartLoadingSeen(m_loadingState == LoadingState::Loading) @@ -362,8 +360,6 @@ void WebContentsDelegateQt::DidStartNavigation(content::NavigationHandle *naviga if (!navigation_handle->IsInMainFrame() || !web_contents()->IsLoadingToDifferentDocument()) return; - m_faviconManager->resetCandidates(); - m_loadingInfo.url = toQt(navigation_handle->GetURL()); // IsErrorPage is only set after navigation commit, so check it otherwise: error page shouldn't have navigation entry bool isErrorPage = m_loadingInfo.triggersErrorPage && !navigation_handle->GetNavigationEntry(); @@ -426,7 +422,6 @@ void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navig // The load will succede as an error-page load later, and we reported the original error above if (navigation_handle->IsErrorPage()) { // Now report we are starting to load an error-page. - m_faviconManager->resetCandidates(); emitLoadStarted(true); // If it is already committed we will not see another DidFinishNavigation call or a DidFinishLoad call. @@ -533,9 +528,6 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame return; } - if (!m_faviconManager->hasCandidate()) - m_viewClient->iconChanged(QUrl()); - content::NavigationEntry *entry = web_contents()->GetController().GetActiveEntry(); int http_statuscode = entry ? entry->GetHttpStatusCode() : 0; bool errorPageEnabled = webEngineSettings()->testAttribute(QWebEngineSettings::ErrorPageEnabled); @@ -547,21 +539,6 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame m_loadingInfo.triggersErrorPage = triggersErrorPage; } -void WebContentsDelegateQt::DidUpdateFaviconURL(content::RenderFrameHost *render_frame_host, const std::vector<blink::mojom::FaviconURLPtr> &candidates) -{ - QList<FaviconInfo> faviconCandidates; - faviconCandidates.reserve(static_cast<int>(candidates.size())); - for (const blink::mojom::FaviconURLPtr &candidate : candidates) { - // Store invalid candidates too for later debugging via API - faviconCandidates.append(toFaviconInfo(candidate)); - } - - // Favicon URL can be changed from JavaScript too. Thus we need to reset - // the current candidate icon list to not handle previous icon as a candidate. - m_faviconManager->resetCandidates(); - m_faviconManager->update(faviconCandidates); -} - void WebContentsDelegateQt::WebContentsCreated(content::WebContents * /*source_contents*/, int /*opener_render_process_id*/, int /*opener_render_frame_id*/, const std::string &/*frame_name*/, @@ -867,11 +844,6 @@ void WebContentsDelegateQt::ResourceLoadComplete(content::RenderFrameHost* rende } } -FaviconManager *WebContentsDelegateQt::faviconManager() -{ - return m_faviconManager.data(); -} - FindTextHelper *WebContentsDelegateQt::findTextHelper() { return m_findTextHelper.data(); @@ -890,7 +862,6 @@ void WebContentsDelegateQt::copyStateFrom(WebContentsDelegateQt *source) { m_title = source->m_title; NavigationStateChanged(web_contents(), content::INVALIDATE_TYPE_URL); - m_faviconManager->copyStateFrom(source->m_faviconManager.data()); } WebContentsDelegateQt::LoadingState WebContentsDelegateQt::determineLoadingState(content::WebContents *contents) diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index c3676d996..d6adcd77c 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -49,7 +49,6 @@ #include "base/callback.h" #include "color_chooser_controller.h" -#include "favicon_manager.h" #include "find_text_helper.h" #include "javascript_dialog_manager_qt.h" #include <QtCore/qlist.h> @@ -166,7 +165,6 @@ public: void DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code) override; void DidFinishLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url) override; void BeforeUnloadFired(bool proceed, const base::TimeTicks& proceed_time) override; - void DidUpdateFaviconURL(content::RenderFrameHost *render_frame_host, const std::vector<blink::mojom::FaviconURLPtr> &candidates) override; void OnVisibilityChanged(content::Visibility visibility) override; void DidFirstVisuallyNonEmptyPaint() override; void ActivateContents(content::WebContents* contents) override; @@ -180,7 +178,6 @@ public: void selectClientCert(const QSharedPointer<ClientCertSelectController> &); void requestFeaturePermission(ProfileAdapter::PermissionType feature, const QUrl &requestingOrigin); void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture); - FaviconManager *faviconManager(); FindTextHelper *findTextHelper(); void setSavePageInfo(const SavePageInfo &spi) { m_savePageInfo = spi; } @@ -221,7 +218,6 @@ private: int &streamCount(blink::mojom::MediaStreamType type); WebContentsAdapterClient *m_viewClient; - QScopedPointer<FaviconManager> m_faviconManager; QScopedPointer<FindTextHelper> m_findTextHelper; SavePageInfo m_savePageInfo; QSharedPointer<FilePickerController> m_filePickerController; diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp index 249f50613..6b11cf0cd 100644 --- a/src/core/web_engine_library_info.cpp +++ b/src/core/web_engine_library_info.cpp @@ -38,6 +38,7 @@ ** ****************************************************************************/ +#include "qtwebenginecoreglobal_p.h" #include "web_engine_library_info.h" #include "base/base_paths.h" |