Attempting to De-flake resource loading browsertests

I've made the callback more in line with the specific update. I suspect
that the problem is other hints are being fed in slightly earlier than
the update from the tests. This makes sure the callback is tied to the
correct update.

Bug: 932913
Change-Id: I5f23a5321a555c925e29b9e08d50ab99afdeb5bf
Reviewed-on: https://chromium-review.googlesource.com/c/1484087
Commit-Queue: Ryan Sturm <ryansturm@chromium.org>
Reviewed-by: Doug Arnett <dougarnett@chromium.org>
Cr-Commit-Position: refs/heads/master@{#634917}
diff --git a/chrome/browser/previews/previews_browsertest.cc b/chrome/browser/previews/previews_browsertest.cc
index a502a289..3ffb076 100644
--- a/chrome/browser/previews/previews_browsertest.cc
+++ b/chrome/browser/previews/previews_browsertest.cc
@@ -249,10 +249,7 @@
 
     base::HistogramTester histogram_tester;
 
-    g_browser_process->optimization_guide_service()->MaybeUpdateHintsComponent(
-        component_info);
-
-    // Wait for hint update processing to complete.
+    // Register a QuitClosure for when the next hint update is started below.
     base::RunLoop run_loop;
     PreviewsServiceFactory::GetForProfile(
         Profile::FromBrowserContext(browser()
@@ -263,6 +260,10 @@
         ->previews_decider_impl()
         ->previews_opt_guide()
         ->ListenForNextUpdateForTesting(run_loop.QuitClosure());
+
+    g_browser_process->optimization_guide_service()->MaybeUpdateHintsComponent(
+        component_info);
+
     run_loop.Run();
 
     // Navigate to |hint_setup_url| to prime the OptimizationGuide hints for the
diff --git a/chrome/browser/previews/previews_lite_page_browsertest.cc b/chrome/browser/previews/previews_lite_page_browsertest.cc
index 06d205e..2c115d33 100644
--- a/chrome/browser/previews/previews_lite_page_browsertest.cc
+++ b/chrome/browser/previews/previews_lite_page_browsertest.cc
@@ -1685,10 +1685,7 @@
 
   void ProcessHintsComponent(
       const optimization_guide::HintsComponentInfo& component_info) {
-    g_browser_process->optimization_guide_service()->MaybeUpdateHintsComponent(
-        component_info);
-
-    // Wait for hint update processing to complete.
+    // Register a QuitClosure for when the next hint update is started below.
     base::RunLoop run_loop;
     PreviewsServiceFactory::GetForProfile(
         Profile::FromBrowserContext(browser()
@@ -1699,6 +1696,10 @@
         ->previews_decider_impl()
         ->previews_opt_guide()
         ->ListenForNextUpdateForTesting(run_loop.QuitClosure());
+
+    g_browser_process->optimization_guide_service()->MaybeUpdateHintsComponent(
+        component_info);
+
     run_loop.Run();
   }
 
diff --git a/chrome/browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc b/chrome/browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc
index e98dd233..d87116e 100644
--- a/chrome/browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc
+++ b/chrome/browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc
@@ -136,10 +136,7 @@
   // processed before returning.
   void ProcessHintsComponent(
       const optimization_guide::HintsComponentInfo& component_info) {
-    g_browser_process->optimization_guide_service()->MaybeUpdateHintsComponent(
-        component_info);
-
-    // Wait for hint update processing to complete.
+    // Register a QuitClosure for when the next hint update is started below.
     base::RunLoop run_loop;
     PreviewsServiceFactory::GetForProfile(
         Profile::FromBrowserContext(browser()
@@ -150,6 +147,9 @@
         ->previews_decider_impl()
         ->previews_opt_guide()
         ->ListenForNextUpdateForTesting(run_loop.QuitClosure());
+
+    g_browser_process->optimization_guide_service()->MaybeUpdateHintsComponent(
+        component_info);
     run_loop.Run();
   }
 
diff --git a/components/previews/content/previews_optimization_guide.cc b/components/previews/content/previews_optimization_guide.cc
index 2caf0e3..a20e0868 100644
--- a/components/previews/content/previews_optimization_guide.cc
+++ b/components/previews/content/previews_optimization_guide.cc
@@ -199,10 +199,11 @@
   if (manual_config) {
     // Allow |UpdateHints| to block startup so that the first navigation gets
     // the hints when a command line hint proto is provided.
-    UpdateHints(PreviewsHints::CreateFromHintsConfiguration(
-        std::move(manual_config),
-        hint_cache_->MaybeCreateComponentUpdateData(
-            base::Version(kManualConfigComponentVersion))));
+    UpdateHints(base::OnceClosure(),
+                PreviewsHints::CreateFromHintsConfiguration(
+                    std::move(manual_config),
+                    hint_cache_->MaybeCreateComponentUpdateData(
+                        base::Version(kManualConfigComponentVersion))));
   }
   // Register as an observer regardless of hint proto override usage. This is
   // needed as a signal during testing.
@@ -232,10 +233,12 @@
       base::BindOnce(&PreviewsHints::CreateFromHintsComponent, info,
                      hint_cache_->MaybeCreateComponentUpdateData(info.version)),
       base::BindOnce(&PreviewsOptimizationGuide::UpdateHints,
-                     ui_weak_ptr_factory_.GetWeakPtr()));
+                     ui_weak_ptr_factory_.GetWeakPtr(),
+                     std::move(next_update_closure_)));
 }
 
 void PreviewsOptimizationGuide::UpdateHints(
+    base::OnceClosure update_closure,
     std::unique_ptr<PreviewsHints> hints) {
   DCHECK(ui_task_runner_->BelongsToCurrentThread());
   hints_ = std::move(hints);
@@ -243,16 +246,18 @@
     hints_->Initialize(
         hint_cache_.get(),
         base::BindOnce(&PreviewsOptimizationGuide::OnHintsUpdated,
-                       ui_weak_ptr_factory_.GetWeakPtr()));
+                       ui_weak_ptr_factory_.GetWeakPtr(),
+                       std::move(update_closure)));
   } else {
-    OnHintsUpdated();
+    OnHintsUpdated(std::move(update_closure));
   }
 }
 
-void PreviewsOptimizationGuide::OnHintsUpdated() {
+void PreviewsOptimizationGuide::OnHintsUpdated(
+    base::OnceClosure update_closure) {
   DCHECK(ui_task_runner_->BelongsToCurrentThread());
-  if (!next_update_closure_.is_null())
-    std::move(next_update_closure_).Run();
+  if (!update_closure.is_null())
+    std::move(update_closure).Run();
 
   // Record the result of updating the hints. This is used as a signal for the
   // hints being fully processed in testing.
diff --git a/components/previews/content/previews_optimization_guide.h b/components/previews/content/previews_optimization_guide.h
index 8f8cafd3..d001eed 100644
--- a/components/previews/content/previews_optimization_guide.h
+++ b/components/previews/content/previews_optimization_guide.h
@@ -91,7 +91,8 @@
 
   PreviewsHints* GetHintsForTesting() { return hints_.get(); }
 
-  // |next_update_closure| is called the next time the hints have been updated.
+  // |next_update_closure| is called the next time OnHintsComponentAvailable is
+  // called and the corresponding hints have been updated.
   void ListenForNextUpdateForTesting(base::OnceClosure next_update_closure);
 
  private:
@@ -101,11 +102,14 @@
   void OnHintCacheInitialized();
 
   // Updates the hints to the latest hints sent by the Component Updater.
-  void UpdateHints(std::unique_ptr<PreviewsHints> hints);
+  // |update_closure| is called once the hints are updated.
+  void UpdateHints(base::OnceClosure update_closure,
+                   std::unique_ptr<PreviewsHints> hints);
 
   // Called when the hints have been fully updated with the latest hints from
   // the Component Updater. This is used as a signal during tests.
-  void OnHintsUpdated();
+  // |update_closure| is called immediately if not null.
+  void OnHintsUpdated(base::OnceClosure update_closure);
 
   // Callback when a hint is loaded.
   void OnLoadedHint(base::OnceClosure callback,