summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPeter Varga <pvarga@inf.u-szeged.hu>2022-06-20 10:16:44 +0200
committerPeter Varga <pvarga@inf.u-szeged.hu>2022-06-23 08:37:43 +0200
commit3c30a71eaca8edd76cbc15f46632a6f7bbebc7fb (patch)
tree71953c5d64cd9e97f926c5bd2db38df9c2471d87 /src
parent9b9d789fcb8f63a8998f1eefe44f2a1c8156c362 (diff)
Adapt FaviconDriverQt to Chromium 98
This change adapts upstream Chromium's favicon::ContentFaviconDriver fixes: * Call constructor that takes a WebContents for WebContentsUserData. http://crrev.com/c/3278400 * Rename RenderDocumentHostUserData to DocumentUserData http://crrev.com/c/3208909 * Make helper macros behave consistently for //content/public UserData types http://crrev.com/c/3198788 * Introduce RenderDocumentHostUserData::render_frame_host accessor. http://crrev.com/c/3176183 * [SPC] Support SVG card art icons with no intrinsic size http://crrev.com/c/3148035 * Do not request favicons on regular page reload http://crrev.com/c/3097606 * Replace blink::Manifest with blink::mojom::Manifest http://crrev.com/c/3060401 * [mparch] Move UpdateManifestURL() to PageImpl http://crrev.com/c/2972153 * [content] Introduce WebContents::GetPrimaryPage http://crrev.com/c/2969524 * [mparch] Update a manifest url on the prerendering activation http://crrev.com/c/2952744 * [mparch] Move WebContents::GetManifest to Page. http://crrev.com/c/2955119 * [content] Introduce content::Page http://crrev.com/c/2916488 * Reland "[mparch] Update ContentFaviconDriver" http://crrev.com/c/2852141 * favicons: fix manifest crash http://crrev.com/c/2343718 * favicons: adds CoreFaviconService http://crrev.com/c/2313098 Pick-to: 6.4 Change-Id: I54a3eab98a4b168b22c42a10823ea88eb8fd6f4a Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/core/favicon_driver_qt.cpp140
-rw-r--r--src/core/favicon_driver_qt.h46
2 files changed, 128 insertions, 58 deletions
diff --git a/src/core/favicon_driver_qt.cpp b/src/core/favicon_driver_qt.cpp
index 9c67b22bc..bb4a734b4 100644
--- a/src/core/favicon_driver_qt.cpp
+++ b/src/core/favicon_driver_qt.cpp
@@ -1,6 +1,11 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Based on components/favicon/content/content_favicon_driver.cc:
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
#include "favicon_driver_qt.h"
#include "type_conversion.h"
#include "web_contents_adapter_client.h"
@@ -20,16 +25,6 @@ namespace QtWebEngineCore {
namespace {
-void ExtractManifestIcons(FaviconDriverQt::ManifestDownloadCallback callback,
- const GURL &manifest_url, blink::mojom::ManifestPtr 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);
@@ -45,7 +40,7 @@ FaviconStatusQt::FaviconStatusQt()
// static
void FaviconDriverQt::CreateForWebContents(content::WebContents *webContents,
- favicon::FaviconService *faviconService,
+ favicon::CoreFaviconService *faviconService,
WebContentsAdapterClient *viewClient)
{
if (FromWebContents(webContents))
@@ -57,9 +52,10 @@ void FaviconDriverQt::CreateForWebContents(content::WebContents *webContents,
}
FaviconDriverQt::FaviconDriverQt(content::WebContents *webContents,
- favicon::FaviconService *faviconService,
+ favicon::CoreFaviconService *faviconService,
WebContentsAdapterClient *viewClient)
: content::WebContentsObserver(webContents)
+ , content::WebContentsUserData<FaviconDriverQt>(*webContents)
, m_faviconService(faviconService)
, m_viewClient(viewClient)
{
@@ -129,6 +125,13 @@ GURL FaviconDriverQt::GetActiveURL()
return entry ? entry->GetURL() : GURL();
}
+GURL FaviconDriverQt::GetManifestURL(content::RenderFrameHost *rfh)
+{
+ DocumentManifestData *document_data = DocumentManifestData::GetOrCreateForCurrentDocument(rfh);
+ return document_data->has_manifest_url ? rfh->GetPage().GetManifestUrl().value_or(GURL())
+ : GURL();
+}
+
GURL FaviconDriverQt::GetFaviconURL() const
{
content::NavigationController &controller = web_contents()->GetController();
@@ -139,20 +142,62 @@ GURL FaviconDriverQt::GetFaviconURL() const
return GURL();
}
+FaviconDriverQt::DocumentManifestData::DocumentManifestData(content::RenderFrameHost *rfh)
+ : content::DocumentUserData<DocumentManifestData>(rfh)
+{
+}
+
+FaviconDriverQt::DocumentManifestData::~DocumentManifestData() = default;
+
+FaviconDriverQt::NavigationManifestData::NavigationManifestData(
+ content::NavigationHandle &navigation_handle)
+{
+}
+
+FaviconDriverQt::NavigationManifestData::~NavigationManifestData() = default;
+
+void FaviconDriverQt::OnDidDownloadManifest(ManifestDownloadCallback callback,
+ const GURL &manifest_url,
+ blink::mojom::ManifestPtr manifest)
+{
+ Q_UNUSED(manifest_url);
+
+ // ~WebContentsImpl triggers running any pending callbacks for manifests.
+ // As we're about to be destroyed ignore the request. To do otherwise may
+ // result in calling back to this and attempting to use the WebContents, which
+ // will crash.
+ if (!web_contents())
+ return;
+
+ std::vector<favicon::FaviconURL> candidates;
+ if (manifest) {
+ for (const auto &icon : manifest->icons) {
+ candidates.emplace_back(icon.src, favicon_base::IconType::kWebManifestIcon, icon.sizes);
+ }
+ }
+ std::move(callback).Run(candidates);
+}
+
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_image_size},
- /*max_bitmap_size=*/max_image_size, bypass_cache,
- std::move(callback));
+ const gfx::Size preferred_size(max_image_size, max_image_size);
+ return web_contents()->DownloadImage(url, true, preferred_size,
+ /*max_bitmap_size=*/max_image_size,
+ bypass_cache, std::move(callback));
}
void FaviconDriverQt::DownloadManifest(const GURL &url, ManifestDownloadCallback callback)
{
- web_contents()->GetMainFrame()->GetPage().GetManifest(base::BindOnce(&ExtractManifestIcons, std::move(callback)));
+ // TODO(crbug.com/1201237): This appears to be reachable from pages other
+ // than the primary page. This code should likely be refactored so that either
+ // this is unreachable from other pages, or the correct page is plumbed in
+ // here.
+ web_contents()->GetPrimaryPage().GetManifest(base::BindOnce(
+ &FaviconDriverQt::OnDidDownloadManifest, base::Unretained(this), std::move(callback)));
}
bool FaviconDriverQt::IsOffTheRecord()
@@ -209,14 +254,12 @@ void FaviconDriverQt::OnHandlerCompleted(favicon::FaviconHandler *handler)
}
void FaviconDriverQt::DidUpdateFaviconURL(
- content::RenderFrameHost *render_frame_host,
- const std::vector<blink::mojom::FaviconURLPtr> &candidates)
+ content::RenderFrameHost *rfh, 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;
@@ -227,50 +270,45 @@ void FaviconDriverQt::DidUpdateFaviconURL(
faviconUrls.push_back(candidate.Clone());
m_faviconUrls = std::move(faviconUrls);
- if (!m_documentOnLoadCompleted)
+ if (!rfh->IsDocumentOnLoadCompletedInMainFrame())
return;
- OnUpdateCandidates(entry->GetURL(),
- favicon::FaviconURLsFromContentFaviconURLs(candidates),
- m_manifestUrl);
+ OnUpdateCandidates(rfh->GetLastCommittedURL(),
+ favicon::FaviconURLsFromContentFaviconURLs(candidates), GetManifestURL(rfh));
}
-void FaviconDriverQt::DidUpdateWebManifestURL(content::RenderFrameHost *target_frame,
+void FaviconDriverQt::DidUpdateWebManifestURL(content::RenderFrameHost *rfh,
const GURL &manifest_url)
{
- Q_UNUSED(target_frame);
+ Q_UNUSED(manifest_url);
// 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)
+ if (!entry || !rfh->IsDocumentOnLoadCompletedInMainFrame())
return;
- m_manifestUrl = manifest_url;
+ DocumentManifestData *document_data = DocumentManifestData::GetOrCreateForCurrentDocument(rfh);
+ document_data->has_manifest_url = true;
// 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);
+ if (!rfh->FaviconURLs().empty()) {
+ OnUpdateCandidates(rfh->GetLastCommittedURL(),
+ favicon::FaviconURLsFromContentFaviconURLs(rfh->FaviconURLs()),
+ GetManifestURL(rfh));
}
}
void FaviconDriverQt::DidStartNavigation(content::NavigationHandle *navigation_handle)
{
- if (!navigation_handle->IsInMainFrame())
+ if (!navigation_handle->IsInPrimaryMainFrame())
return;
- m_faviconUrls.reset();
-
if (!navigation_handle->IsSameDocument()) {
m_completedHandlersCount = 0;
m_latestFavicon = FaviconStatusQt();
- m_documentOnLoadCompleted = false;
- m_manifestUrl = GURL();
-
m_viewClient->iconChanged(QUrl());
}
@@ -278,18 +316,33 @@ void FaviconDriverQt::DidStartNavigation(content::NavigationHandle *navigation_h
if (reload_type == content::ReloadType::NONE || IsOffTheRecord())
return;
- m_bypassCachePageURL = navigation_handle->GetURL();
+ if (!navigation_handle->IsSameDocument()) {
+ NavigationManifestData *navigation_data =
+ NavigationManifestData::GetOrCreateForNavigationHandle(*navigation_handle);
+ navigation_data->has_manifest_url = false;
+ }
+
+ if (reload_type == content::ReloadType::BYPASSING_CACHE)
+ 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()
+ if (!navigation_handle->IsInPrimaryMainFrame() || !navigation_handle->HasCommitted()
|| navigation_handle->IsErrorPage()) {
return;
}
+ // Transfer in-flight navigation data to the document user data.
+ NavigationManifestData *navigation_data =
+ NavigationManifestData::GetOrCreateForNavigationHandle(*navigation_handle);
+ DocumentManifestData *document_data = DocumentManifestData::GetOrCreateForCurrentDocument(
+ navigation_handle->GetRenderFrameHost());
+ document_data->has_manifest_url = navigation_data->has_manifest_url;
+
// 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
@@ -305,11 +358,6 @@ void FaviconDriverQt::DidFinishNavigation(content::NavigationHandle *navigation_
FetchFavicon(url, navigation_handle->IsSameDocument());
}
-void FaviconDriverQt::DocumentOnLoadCompletedInMainFrame(content::RenderFrameHost * /*render_frame_host*/)
-{
- m_documentOnLoadCompleted = true;
-}
-
void FaviconDriverQt::SetFaviconOutOfDateForPage(const GURL &url, bool force_reload)
{
if (m_faviconService) {
@@ -367,6 +415,8 @@ void FaviconDriverQt::emitIconChangedIfNeeded()
m_viewClient->iconChanged(toQt(m_latestFavicon.url));
}
+NAVIGATION_HANDLE_USER_DATA_KEY_IMPL(FaviconDriverQt::NavigationManifestData);
+DOCUMENT_USER_DATA_KEY_IMPL(FaviconDriverQt::DocumentManifestData);
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
index 864291566..96bd682a2 100644
--- a/src/core/favicon_driver_qt.h
+++ b/src/core/favicon_driver_qt.h
@@ -19,7 +19,9 @@
#include "components/favicon/core/favicon_driver.h"
#include "components/favicon/core/favicon_handler.h"
+#include "content/public/browser/document_user_data.h"
#include "content/public/browser/favicon_status.h"
+#include "content/public/browser/navigation_handle_user_data.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"
@@ -29,7 +31,7 @@ class WebContents;
}
namespace favicon {
-class FaviconService;
+class CoreFaviconService;
}
namespace QtWebEngineCore {
@@ -51,7 +53,7 @@ class FaviconDriverQt : public favicon::FaviconDriver,
{
public:
static void CreateForWebContents(content::WebContents *webContents,
- favicon::FaviconService *faviconService,
+ favicon::CoreFaviconService *faviconService,
WebContentsAdapterClient *viewClient);
// FaviconDriver implementation.
@@ -60,15 +62,38 @@ public:
bool FaviconIsValid() const override;
GURL GetActiveURL() override;
+ GURL GetManifestURL(content::RenderFrameHost *rfh);
GURL GetFaviconURL() const;
protected:
- FaviconDriverQt(content::WebContents *webContent, favicon::FaviconService *faviconService,
+ FaviconDriverQt(content::WebContents *webContent, favicon::CoreFaviconService *faviconService,
WebContentsAdapterClient *viewClient);
private:
friend class content::WebContentsUserData<FaviconDriverQt>;
+ // TODO(crbug.com/1205018): these two classes are current used to ensure that
+ // we disregard manifest URL updates that arrive prior to onload firing.
+ struct DocumentManifestData : public content::DocumentUserData<DocumentManifestData>
+ {
+ explicit DocumentManifestData(content::RenderFrameHost *rfh);
+ ~DocumentManifestData() override;
+ DOCUMENT_USER_DATA_KEY_DECL();
+ bool has_manifest_url = false;
+ };
+
+ struct NavigationManifestData : public content::NavigationHandleUserData<NavigationManifestData>
+ {
+ explicit NavigationManifestData(content::NavigationHandle &navigation_handle);
+ ~NavigationManifestData() override;
+ NAVIGATION_HANDLE_USER_DATA_KEY_DECL();
+ bool has_manifest_url = false;
+ };
+
+ // Callback when a manifest is downloaded.
+ void OnDidDownloadManifest(ManifestDownloadCallback callback, const GURL &manifest_url,
+ blink::mojom::ManifestPtr manifest);
+
// FaviconHandler::Delegate implementation.
int DownloadImage(const GURL &url, int max_image_size, ImageDownloadCallback callback) override;
void DownloadManifest(const GURL &url, ManifestDownloadCallback callback) override;
@@ -83,15 +108,13 @@ private:
void OnHandlerCompleted(favicon::FaviconHandler *handler) override;
// content::WebContentsObserver implementation.
- void DidUpdateFaviconURL(content::RenderFrameHost *render_frame_host,
+ void DidUpdateFaviconURL(content::RenderFrameHost *rfh,
const std::vector<blink::mojom::FaviconURLPtr> &candidates) override;
- void DidUpdateWebManifestURL(content::RenderFrameHost *target_frame,
- const GURL &manifest_url) override;
+ void DidUpdateWebManifestURL(content::RenderFrameHost *rfh, const GURL &manifest_url) override;
void DidStartNavigation(content::NavigationHandle *navigation_handle) override;
void DidFinishNavigation(content::NavigationHandle *navigation_handle) override;
- void DocumentOnLoadCompletedInMainFrame(content::RenderFrameHost *render_frame_host) override;
- // Informs FaviconService that the favicon for |url| is out of date. If
+ // Informs CoreFaviconService 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);
@@ -105,20 +128,17 @@ private:
// KeyedService used by FaviconDriverImpl. It may be null during testing,
// but if it is defined, it must outlive the FaviconDriverImpl.
- favicon::FaviconService *m_faviconService;
+ raw_ptr<favicon::CoreFaviconService> m_faviconService;
WebContentsAdapterClient *m_viewClient;
- // FaviconHandlers used to download the different kind of favicons.
+ // FaviconHandlers are 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().
absl::optional<std::vector<blink::mojom::FaviconURLPtr>> m_faviconUrls;
- // Web Manifest URL or empty URL if none.
- GURL m_manifestUrl;
int m_completedHandlersCount = 0;
FaviconStatusQt m_latestFavicon;