Source/WebCore:
[WK2] Handle back/forward cache entry expiration in the UIProcess instead of the WebProcess
https://bugs.webkit.org/show_bug.cgi?id=203034
<rdar://problem/56332453>

Reviewed by Antti Koivisto.

Use Seconds type for backForwardCacheExpirationInterval setting instead of
double, for clarity.

* history/CachedPage.cpp:
(WebCore::CachedPage::CachedPage):
(WebCore::CachedPage::hasExpired const):
* page/Settings.yaml:

Source/WebKit:
[WK2] Handle back/forward cache entry expiration in the UIProcess instead of the WebProcess
https://bugs.webkit.org/show_bug.cgi?id=203034
<rdar://problem/56332453>

Reviewed by Antti Koivisto.

Handle back/forward cache entry expiration in the UIProcess instead of the WebProcess,
now that back/forward cache management is done in the UIProcess.

* UIProcess/WebBackForwardCacheEntry.cpp:
(WebKit::WebBackForwardCacheEntry::WebBackForwardCacheEntry):
(WebKit::WebBackForwardCacheEntry::takeSuspendedPage):
(WebKit::WebBackForwardCacheEntry::expirationTimerFired):
* UIProcess/WebBackForwardCacheEntry.h:
Add a Timer to WebBackForwardCacheEntry to make the entry expire after 30 minutes, which is what used
to happen on WebContent process side. One difference in behavior is that when the entry expires we
now remove it from the cache right away to free-up memory, instead of simply refusing to use it later
on.

* WebProcess/WebPage/WebPage.cpp:
Disable back forward cache expiration in the WebContent process when using modern
WebKit.

Source/WebKitLegacy/mac:
[WK2] Move back/forward cache entry expiration from the WebProcess to the UIProcess
https://bugs.webkit.org/show_bug.cgi?id=203034
<rdar://problem/56332453>

Reviewed by Antti Koivisto.

* WebView/WebView.mm:
(-[WebView _preferencesChanged:]):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251204 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index f47c526..33918e9 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,19 @@
+2019-10-16  Chris Dumez  <cdumez@apple.com>
+
+        [WK2] Handle back/forward cache entry expiration in the UIProcess instead of the WebProcess
+        https://bugs.webkit.org/show_bug.cgi?id=203034
+        <rdar://problem/56332453>
+
+        Reviewed by Antti Koivisto.
+
+        Use Seconds type for backForwardCacheExpirationInterval setting instead of
+        double, for clarity.
+
+        * history/CachedPage.cpp:
+        (WebCore::CachedPage::CachedPage):
+        (WebCore::CachedPage::hasExpired const):
+        * page/Settings.yaml:
+
 2019-10-16  Zalan Bujtas  <zalan@apple.com>
 
         [LFC][IFC] Fix various vertical alignment issues.
diff --git a/Source/WebCore/history/CachedPage.cpp b/Source/WebCore/history/CachedPage.cpp
index 9747a40..08af39d 100644
--- a/Source/WebCore/history/CachedPage.cpp
+++ b/Source/WebCore/history/CachedPage.cpp
@@ -55,7 +55,7 @@
 
 CachedPage::CachedPage(Page& page)
     : m_page(page)
-    , m_expirationTime(MonotonicTime::now() + Seconds(page.settings().backForwardCacheExpirationInterval()))
+    , m_expirationTime(MonotonicTime::now() + page.settings().backForwardCacheExpirationInterval())
     , m_cachedMainFrame(makeUnique<CachedFrame>(page.mainFrame()))
 {
 #ifndef NDEBUG
diff --git a/Source/WebCore/page/Settings.yaml b/Source/WebCore/page/Settings.yaml
index 0ae7742..47f0ed6 100644
--- a/Source/WebCore/page/Settings.yaml
+++ b/Source/WebCore/page/Settings.yaml
@@ -422,8 +422,8 @@
   initial: false
 
 backForwardCacheExpirationInterval:
-  type: double
-  initial: 1800
+  type: Seconds
+  initial: 30_min
 
 # Some apps could have a default video poster if it is not set.
 defaultVideoPosterURL:
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 15ecc37..4ffcebb 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,5 +1,30 @@
 2019-10-16  Chris Dumez  <cdumez@apple.com>
 
+        [WK2] Handle back/forward cache entry expiration in the UIProcess instead of the WebProcess
+        https://bugs.webkit.org/show_bug.cgi?id=203034
+        <rdar://problem/56332453>
+
+        Reviewed by Antti Koivisto.
+
+        Handle back/forward cache entry expiration in the UIProcess instead of the WebProcess,
+        now that back/forward cache management is done in the UIProcess.
+
+        * UIProcess/WebBackForwardCacheEntry.cpp:
+        (WebKit::WebBackForwardCacheEntry::WebBackForwardCacheEntry):
+        (WebKit::WebBackForwardCacheEntry::takeSuspendedPage):
+        (WebKit::WebBackForwardCacheEntry::expirationTimerFired):
+        * UIProcess/WebBackForwardCacheEntry.h:
+        Add a Timer to WebBackForwardCacheEntry to make the entry expire after 30 minutes, which is what used
+        to happen on WebContent process side. One difference in behavior is that when the entry expires we
+        now remove it from the cache right away to free-up memory, instead of simply refusing to use it later
+        on.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        Disable back forward cache expiration in the WebContent process when using modern
+        WebKit.
+
+2019-10-16  Chris Dumez  <cdumez@apple.com>
+
         [iOS] Stop terminating the prewarmed process on application suspension
         https://bugs.webkit.org/show_bug.cgi?id=203033
 
diff --git a/Source/WebKit/UIProcess/WebBackForwardCacheEntry.cpp b/Source/WebKit/UIProcess/WebBackForwardCacheEntry.cpp
index 75cdfb6..59fbed5 100644
--- a/Source/WebKit/UIProcess/WebBackForwardCacheEntry.cpp
+++ b/Source/WebKit/UIProcess/WebBackForwardCacheEntry.cpp
@@ -26,18 +26,24 @@
 #include "config.h"
 #include "WebBackForwardCacheEntry.h"
 
+#include "Logging.h"
 #include "SuspendedPageProxy.h"
+#include "WebBackForwardCache.h"
 #include "WebProcessMessages.h"
 #include "WebProcessProxy.h"
 
 namespace WebKit {
 
+static const Seconds expirationDelay { 30_min };
+
 WebBackForwardCacheEntry::WebBackForwardCacheEntry(WebBackForwardCache& backForwardCache, WebCore::BackForwardItemIdentifier backForwardItemID, WebCore::ProcessIdentifier processIdentifier, std::unique_ptr<SuspendedPageProxy>&& suspendedPage)
     : m_backForwardCache(backForwardCache)
     , m_processIdentifier(processIdentifier)
     , m_backForwardItemID(backForwardItemID)
     , m_suspendedPage(WTFMove(suspendedPage))
+    , m_expirationTimer(RunLoop::main(), this, &WebBackForwardCacheEntry::expirationTimerFired)
 {
+    m_expirationTimer.startOneShot(expirationDelay);
 }
 
 WebBackForwardCacheEntry::~WebBackForwardCacheEntry()
@@ -52,6 +58,7 @@
 {
     ASSERT(m_suspendedPage);
     m_backForwardItemID = { };
+    m_expirationTimer.stop();
     return std::exchange(m_suspendedPage, nullptr);
 }
 
@@ -63,4 +70,13 @@
     return *process;
 }
 
+void WebBackForwardCacheEntry::expirationTimerFired()
+{
+    RELEASE_LOG(BackForwardCache, "%p - WebBackForwardCacheEntry::expirationTimerFired backForwardItemID: %s, hasSuspendedPage? %d", this, m_backForwardItemID.string().utf8().data(), !!m_suspendedPage);
+    ASSERT(m_backForwardItemID);
+    auto* item = WebBackForwardListItem::itemForID(m_backForwardItemID);
+    ASSERT(item);
+    m_backForwardCache.removeEntry(*item); // Will destroy |this|.
+}
+
 } // namespace WebKit
diff --git a/Source/WebKit/UIProcess/WebBackForwardCacheEntry.h b/Source/WebKit/UIProcess/WebBackForwardCacheEntry.h
index 1f4c6a5..835a234 100644
--- a/Source/WebKit/UIProcess/WebBackForwardCacheEntry.h
+++ b/Source/WebKit/UIProcess/WebBackForwardCacheEntry.h
@@ -28,6 +28,7 @@
 #include <WebCore/BackForwardItemIdentifier.h>
 #include <WebCore/ProcessIdentifier.h>
 #include <wtf/Forward.h>
+#include <wtf/RunLoop.h>
 
 namespace WebKit {
 
@@ -49,10 +50,13 @@
     WebProcessProxy& process() const;
 
 private:
+    void expirationTimerFired();
+
     WebBackForwardCache& m_backForwardCache;
     WebCore::ProcessIdentifier m_processIdentifier;
     WebCore::BackForwardItemIdentifier m_backForwardItemID;
     std::unique_ptr<SuspendedPageProxy> m_suspendedPage;
+    RunLoop::Timer<WebBackForwardCacheEntry> m_expirationTimer;
 };
 
 } // namespace WebKit
diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
index 15cd623..0817927 100644
--- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp
+++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp
@@ -521,6 +521,10 @@
     m_page->settings().setScrollingCoordinatorEnabled(m_useAsyncScrolling);
 #endif
 
+    // Disable Back/Forward cache expiration in the WebContent process since management happens in the UIProcess
+    // in modern WebKit.
+    m_page->settings().setBackForwardCacheExpirationInterval(Seconds::infinity());
+
     m_mainFrame = WebFrame::createWithCoreMainFrame(this, &m_page->mainFrame());
     m_drawingArea->updatePreferences(parameters.store);
 
diff --git a/Source/WebKitLegacy/mac/ChangeLog b/Source/WebKitLegacy/mac/ChangeLog
index 9ef9a70..061ae1b 100644
--- a/Source/WebKitLegacy/mac/ChangeLog
+++ b/Source/WebKitLegacy/mac/ChangeLog
@@ -1,3 +1,14 @@
+2019-10-16  Chris Dumez  <cdumez@apple.com>
+
+        [WK2] Move back/forward cache entry expiration from the WebProcess to the UIProcess
+        https://bugs.webkit.org/show_bug.cgi?id=203034
+        <rdar://problem/56332453>
+
+        Reviewed by Antti Koivisto.
+
+        * WebView/WebView.mm:
+        (-[WebView _preferencesChanged:]):
+
 2019-10-15  Chris Dumez  <cdumez@apple.com>
 
         [macOS] Simplify main thread initialization
diff --git a/Source/WebKitLegacy/mac/WebView/WebView.mm b/Source/WebKitLegacy/mac/WebView/WebView.mm
index 830d216..4886c84 100644
--- a/Source/WebKitLegacy/mac/WebView/WebView.mm
+++ b/Source/WebKitLegacy/mac/WebView/WebView.mm
@@ -2913,7 +2913,7 @@
     settings.setDOMPasteAllowed([preferences isDOMPasteAllowed]);
     settings.setUsesPageCache([self usesPageCache]);
     settings.setPageCacheSupportsPlugins([preferences pageCacheSupportsPlugins]);
-    settings.setBackForwardCacheExpirationInterval([preferences _backForwardCacheExpirationInterval]);
+    settings.setBackForwardCacheExpirationInterval(Seconds { [preferences _backForwardCacheExpirationInterval] });
 
     settings.setDeveloperExtrasEnabled([preferences developerExtrasEnabled]);
     settings.setJavaScriptRuntimeFlags(JSC::RuntimeFlags([preferences javaScriptRuntimeFlags]));