Service worker navigation preload can use Search Prefetch requests

The service worker navigation preload is issued as part of a Service
Worker navigation URLLoader interceptor. In a similar vein, Search
Prefetch uses the same type of interceptor, but at lower priority.

Once Service Worker has decided to intercept the navigation (generally,
this means there is a fetch handler), it issues a direct network service request to get
the resource when navigation preload is enabled in the service worker.
This means lower priority interceptors are never consulted (i.e., app
cache is not consulted, which is good; search prefetch is not consulted,
which is not ideal).

This CL adds functionality to handle synchronous interception decisions,
but stops short of copying the interception logic in the navigation
pathway that handles asynchronous decisions with multiple interceptors.


Bug: 1155330

Change-Id: Iae225c0b4926946a4ec9fccc5dc5d240dc53c058
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2570392
Commit-Queue: Ryan Sturm <[email protected]>
Reviewed-by: Matt Falkenhagen <[email protected]>
Reviewed-by: Makoto Shimazu <[email protected]>
Cr-Commit-Position: refs/heads/master@{#835364}
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 70f77a45..1f33948 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -103,6 +103,7 @@
 #include "chrome/browser/prefetch/search_prefetch/field_trial_settings.h"
 #include "chrome/browser/prefetch/search_prefetch/search_prefetch_service.h"
 #include "chrome/browser/prefetch/search_prefetch/search_prefetch_service_factory.h"
+#include "chrome/browser/prefetch/search_prefetch/search_prefetch_url_loader.h"
 #include "chrome/browser/prefetch/search_prefetch/search_prefetch_url_loader_interceptor.h"
 #include "chrome/browser/previews/previews_content_util.h"
 #include "chrome/browser/previews/previews_service.h"
@@ -4806,6 +4807,33 @@
   return interceptors;
 }
 
+content::ContentBrowserClient::URLLoaderRequestHandler
+ChromeContentBrowserClient::
+    CreateURLLoaderHandlerForServiceWorkerNavigationPreload(
+        int frame_tree_node_id,
+        const network::ResourceRequest& resource_request) {
+  content::ContentBrowserClient::URLLoaderRequestHandler callback;
+
+  // If search prefetch is disabled, nothing needs to be handled.
+  if (!SearchPrefetchServiceIsEnabled()) {
+    return callback;
+  }
+
+  std::unique_ptr<SearchPrefetchURLLoader> loader =
+      SearchPrefetchURLLoaderInterceptor::MaybeCreateLoaderForRequest(
+          resource_request, frame_tree_node_id);
+  if (!loader) {
+    return callback;
+  }
+
+  auto* raw_loader = loader.get();
+
+  // Hand ownership of the loader to the callback, when it runs, mojo will
+  // manage it. If the callback is deleted, the loader will be deleted.
+  callback = raw_loader->ServingResponseHandler(std::move(loader));
+  return callback;
+}
+
 bool ChromeContentBrowserClient::WillInterceptWebSocket(
     content::RenderFrameHost* frame) {
 #if BUILDFLAG(ENABLE_EXTENSIONS)