From 5cf00feaf14882c354f32e20bce188db397986a9 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gorszkowski Date: Thu, 9 Jul 2026 13:17:50 -0700 Subject: [PATCH] [WPE] don't put page with multimedia to bfCache on low-end devices https://bugs.webkit.org/show_bug.cgi?id=318851 Reviewed by Alicia Boya Garcia. Add a new WPE-only feature `BackForwardCacheWithMediaEnabled` that allows applications to control whether pages containing audio or video elements can be placed in the back/forward cache. When disabled, pages with media elements are excluded from the back/forward cache. This is particularly useful on low-end embedded devices with a limited number of hardware decoders, where keeping a suspended media pipeline alive in the cache may prevent other pages from acquiring the decoder. The feature is enabled by default (preserving existing behavior). Two new WPE layout tests verify the behavior: - page-cache-video-media-disabled.html: verifies pages with media are not cached when the feature is disabled. - page-cache-video-media-enabled.html: verifies pages with media can enter and be restored from the back/forward cache when the feature is enabled. Tests: platform/wpe/fast/history/page-cache-video-media-disabled.html platform/wpe/fast/history/page-cache-video-media-enabled.html * LayoutTests/platform/wpe/fast/history/page-cache-video-media-disabled-expected.txt: Added. * LayoutTests/platform/wpe/fast/history/page-cache-video-media-disabled.html: Added. * LayoutTests/platform/wpe/fast/history/page-cache-video-media-enabled-expected.txt: Added. * LayoutTests/platform/wpe/fast/history/page-cache-video-media-enabled.html: Added. * LayoutTests/platform/wpe/fast/history/resources/page-cache-helper.html: Added. * Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml: * Source/WebCore/history/BackForwardCache.cpp: (WebCore::canCachePage): Canonical link: https://commits.webkit.org/316840@main --- ...ge-cache-video-media-disabled-expected.txt | 11 ++++ .../page-cache-video-media-disabled.html | 46 +++++++++++++++ ...age-cache-video-media-enabled-expected.txt | 13 +++++ .../page-cache-video-media-enabled.html | 44 ++++++++++++++ .../history/resources/page-cache-helper.html | 18 ++++++ .../Scripts/Preferences/WebPreferences.yaml | 13 +++++ Source/WebCore/history/BackForwardCache.cpp | 12 ++++ .../UIProcess/API/glib/WebKitSettings.cpp | 58 +++++++++++++++++++ .../WebKit/UIProcess/API/wpe/WebKitSettings.h | 7 +++ 9 files changed, 222 insertions(+) create mode 100644 LayoutTests/platform/wpe/fast/history/page-cache-video-media-disabled-expected.txt create mode 100644 LayoutTests/platform/wpe/fast/history/page-cache-video-media-disabled.html create mode 100644 LayoutTests/platform/wpe/fast/history/page-cache-video-media-enabled-expected.txt create mode 100644 LayoutTests/platform/wpe/fast/history/page-cache-video-media-enabled.html create mode 100644 LayoutTests/platform/wpe/fast/history/resources/page-cache-helper.html diff --git a/LayoutTests/platform/wpe/fast/history/page-cache-video-media-disabled-expected.txt b/LayoutTests/platform/wpe/fast/history/page-cache-video-media-disabled-expected.txt new file mode 100644 index 0000000000000..0944f83611d72 --- /dev/null +++ b/LayoutTests/platform/wpe/fast/history/page-cache-video-media-disabled-expected.txt @@ -0,0 +1,11 @@ +Tests that a page with a video element does not go into the back/forward cache when back-forward-cache-with-media is disabled. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +pageshow - not from cache +PASS Page was not restored from the back/forward cache +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/platform/wpe/fast/history/page-cache-video-media-disabled.html b/LayoutTests/platform/wpe/fast/history/page-cache-video-media-disabled.html new file mode 100644 index 0000000000000..ddaf1768e1a3e --- /dev/null +++ b/LayoutTests/platform/wpe/fast/history/page-cache-video-media-disabled.html @@ -0,0 +1,46 @@ + + + + + + + + + diff --git a/LayoutTests/platform/wpe/fast/history/page-cache-video-media-enabled-expected.txt b/LayoutTests/platform/wpe/fast/history/page-cache-video-media-enabled-expected.txt new file mode 100644 index 0000000000000..991ac7ef2bbae --- /dev/null +++ b/LayoutTests/platform/wpe/fast/history/page-cache-video-media-enabled-expected.txt @@ -0,0 +1,13 @@ +Tests that a page with a video element goes into the back/forward cache when back-forward-cache-with-media is enabled. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +pageshow - not from cache +pagehide - entering cache +pageshow - from cache +PASS Page did enter and was restored from the back/forward cache +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/platform/wpe/fast/history/page-cache-video-media-enabled.html b/LayoutTests/platform/wpe/fast/history/page-cache-video-media-enabled.html new file mode 100644 index 0000000000000..32bb2495ad2da --- /dev/null +++ b/LayoutTests/platform/wpe/fast/history/page-cache-video-media-enabled.html @@ -0,0 +1,44 @@ + + + + + + + + + diff --git a/LayoutTests/platform/wpe/fast/history/resources/page-cache-helper.html b/LayoutTests/platform/wpe/fast/history/resources/page-cache-helper.html new file mode 100644 index 0000000000000..241100a9ee9f8 --- /dev/null +++ b/LayoutTests/platform/wpe/fast/history/resources/page-cache-helper.html @@ -0,0 +1,18 @@ +This page should go back. If a test outputs the contents of this +page, then the test page failed to enter the page cache. + diff --git a/Source/WTF/Scripts/Preferences/WebPreferences.yaml b/Source/WTF/Scripts/Preferences/WebPreferences.yaml index 18c0a3c3be400..2a005fffa6d6c 100644 --- a/Source/WTF/Scripts/Preferences/WebPreferences.yaml +++ b/Source/WTF/Scripts/Preferences/WebPreferences.yaml @@ -362,6 +362,19 @@ AuthorAndUserStylesEnabled: WebCore: default: true +BackForwardCacheWithMediaEnabled: + type: bool + humanReadableName: "Back/Forward Cache with Media" + humanReadableDescription: "Enable back/forward cache for pages with media" + condition: PLATFORM(WPE) + defaultValue: + WebKitLegacy: + default: true + WebKit: + default: true + WebCore: + default: true + BackspaceKeyNavigationEnabled: type: bool defaultValue: diff --git a/Source/WebCore/history/BackForwardCache.cpp b/Source/WebCore/history/BackForwardCache.cpp index b9bab8d5b972d..a5199c8e603e0 100644 --- a/Source/WebCore/history/BackForwardCache.cpp +++ b/Source/WebCore/history/BackForwardCache.cpp @@ -42,6 +42,7 @@ #include "FrameLoaderClient.h" #include "FrameView.h" #include "HistoryController.h" +#include "HTMLMediaElement.h" #include "IgnoreOpensDuringUnloadCountIncrementer.h" #include "Logging.h" #include "Page.h" @@ -205,6 +206,17 @@ static bool canCachePage(Page& page) logBackForwardCacheFailureDiagnosticMessage(diagnosticLoggingClient, DiagnosticLoggingKeys::isDisabledKey()); isCacheable = false; } +#if PLATFORM(WPE) + if (!page.settings().backForwardCacheWithMediaEnabled()) { + bool hasMedia = false; + page.forEachMediaElement([&](HTMLMediaElement&) { hasMedia = true; }); + if (hasMedia) { + PCLOG(" -Page contains media elements and back/forward cache with media is disabled"_s); + logBackForwardCacheFailureDiagnosticMessage(diagnosticLoggingClient, DiagnosticLoggingKeys::pageContainsMediaEngineKey()); + isCacheable = false; + } + } +#endif #if ENABLE(DEVICE_ORIENTATION) && !PLATFORM(IOS_FAMILY) if (DeviceMotionController::isActiveAt(&page)) { PCLOG(" -Page is using DeviceMotion"); diff --git a/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp b/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp index 1a96f98d80022..663fbfebc789d 100644 --- a/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp +++ b/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp @@ -191,6 +191,7 @@ enum { PROP_SCREEN_SUPPORTS_HDR, PROP_ENABLE_PAGE_LIFECYCLE, PROP_DESTROY_WINDOW_ON_FREEZE, + PROP_BACK_FORWARD_CACHE_WITH_MEDIA_ENABLED, N_PROPERTIES, }; @@ -460,6 +461,9 @@ ALLOW_DEPRECATED_DECLARATIONS_END case PROP_DESTROY_WINDOW_ON_FREEZE: webkit_settings_set_destroy_window_on_freeze(settings, g_value_get_boolean(value)); break; + case PROP_BACK_FORWARD_CACHE_WITH_MEDIA_ENABLED: + webkit_settings_set_back_forward_cache_with_media_enabled(settings, g_value_get_boolean(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); break; @@ -700,6 +704,9 @@ ALLOW_DEPRECATED_DECLARATIONS_END case PROP_DESTROY_WINDOW_ON_FREEZE: g_value_set_boolean(value, webkit_settings_get_destroy_window_on_freeze(settings)); break; + case PROP_BACK_FORWARD_CACHE_WITH_MEDIA_ENABLED: + g_value_set_boolean(value, webkit_settings_get_back_forward_cache_with_media_enabled(settings)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); break; @@ -1867,6 +1874,19 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) FALSE, readWriteConstructParamFlags); + /** + * WebKitSettings:back-forward-cache-with-media-enabled: + * + * Enable or disable the back/forward cache for pages containing audio or video elements. + * + */ + sObjProperties[PROP_BACK_FORWARD_CACHE_WITH_MEDIA_ENABLED] = g_param_spec_boolean( + "back-forward-cache-with-media-enabled", + _("Back/Forward Cache with Media"), + _("Enable back/forward cache for pages with media"), + TRUE, + readWriteConstructParamFlags); + g_object_class_install_properties(gObjectClass, N_PROPERTIES, sObjProperties); } @@ -4714,3 +4734,41 @@ void webkit_settings_set_destroy_window_on_freeze(WebKitSettings* settings, gboo priv->preferences->setPageLifecycleAPIDestroyWindowOnFreeze(destroy); g_object_notify(G_OBJECT(settings), "destroy-window-on-freeze"); } + +/** + * webkit_settings_get_back_forward_cache_with_media_enabled: + * @settings: a #WebKitSettings + * + * Get the #WebKitSettings:back-forward-cache-with-media-enabled property. + * + * Returns: %TRUE if the back/forward cache is enabled for pages with media or %FALSE otherwise. + * + * Since: 2.54 + */ +gboolean webkit_settings_get_back_forward_cache_with_media_enabled(WebKitSettings* settings) +{ + g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE); + + return settings->priv->preferences->backForwardCacheWithMediaEnabled(); +} + +/** + * webkit_settings_set_back_forward_cache_with_media_enabled: + * @settings: a #WebKitSettings + * @enabled: Value to be set + * + * Set the #WebKitSettings:back-forward-cache-with-media-enabled property. + * + * Since: 2.54 + */ +void webkit_settings_set_back_forward_cache_with_media_enabled(WebKitSettings* settings, gboolean enabled) +{ + g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); + + WebKitSettingsPrivate* priv = settings->priv; + if (priv->preferences->backForwardCacheWithMediaEnabled() == static_cast(enabled)) + return; + + priv->preferences->setBackForwardCacheWithMediaEnabled(enabled); + g_object_notify_by_pspec(G_OBJECT(settings), sObjProperties[PROP_BACK_FORWARD_CACHE_WITH_MEDIA_ENABLED]); +} diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitSettings.h b/Source/WebKit/UIProcess/API/wpe/WebKitSettings.h index 584dbbfe54731..5d94ee5b80423 100644 --- a/Source/WebKit/UIProcess/API/wpe/WebKitSettings.h +++ b/Source/WebKit/UIProcess/API/wpe/WebKitSettings.h @@ -568,6 +568,13 @@ WEBKIT_API void webkit_settings_set_destroy_window_on_freeze (WebKitSettings* settings, gboolean destroy_window); +WEBKIT_API gboolean +webkit_settings_get_back_forward_cache_with_media_enabled (WebKitSettings *settings); + +WEBKIT_API void +webkit_settings_set_back_forward_cache_with_media_enabled (WebKitSettings *settings, + gboolean enabled); + G_END_DECLS #endif /* WebKitSettings_h */