[freezing] Track highest CPU measurement without a CannotFreezeReason.

This CL replaces the boolean indicating whether a browsing instance
was "CPU intensive in background" with the highest CPU measurement
that occurred for a group of same-origin frames/workers within the
browsing instance while no CannotFreezeReason was applicable. This will
be used to build a UKM about freezing eligibility:
go/ukm-review-background-tab-freezing

Bug: 391646022
Change-Id: If6aed406f06b353a748e1280621183610f3cabb9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6208868
Reviewed-by: Joe Mason <joenotcharles@google.com>
Commit-Queue: Francois Pierre Doray <fdoray@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1413195}
diff --git a/components/performance_manager/freezing/freezing_policy.cc b/components/performance_manager/freezing/freezing_policy.cc
index a1a4da64..38ba425 100644
--- a/components/performance_manager/freezing/freezing_policy.cc
+++ b/components/performance_manager/freezing/freezing_policy.cc
@@ -280,6 +280,8 @@
   bool eligible_for_freezing_on_battery_saver = false;
   bool all_pages_have_freeze_vote = true;
 
+  const double high_cpu_proportion = features::kFreezingHighCPUProportion.Get();
+
   for (const PageNode* visited_page : connected_pages) {
     auto& page_freezing_state = PageFreezingState::FromPage(visited_page);
 
@@ -292,7 +294,9 @@
       CHECK(it != browsing_instances_.end());
       const BrowsingInstanceState& browsing_instance_state = it->second;
 
-      if (browsing_instance_state.cpu_intensive_in_background &&
+      if (browsing_instance_state
+                  .highest_cpu_any_interval_without_cannot_freeze_reason >=
+              high_cpu_proportion &&
           is_battery_saver_active_ &&
           // Note: Feature state is checked last so that only clients that
           // have a browsing instance that is CPU intensive in background
@@ -880,10 +884,6 @@
       cpu_proportion_map = cpu_proportion_tracker_.StartNextInterval(
           base::TimeTicks::Now(), results);
   for (const auto& [context, cpu_proportion] : cpu_proportion_map) {
-    if (cpu_proportion < high_cpu_proportion) {
-      continue;
-    }
-
     // This cast is valid because the query only targets contexts of type
     // `OriginInBrowsingInstanceContext` (verified by CHECK inside `AsContext`).
     const auto& origin_in_browsing_instance_context =
@@ -895,21 +895,31 @@
       continue;
     }
 
-    if (browsing_instance_it->second.cpu_intensive_in_background) {
-      // Already known to be CPU-intensive in background.
+    BrowsingInstanceState& state = browsing_instance_it->second;
+
+    if (!state.cannot_freeze_reasons_since_last_cpu_measurement.empty()) {
+      // Ignore CPU measurement while having a `CannotFreezeReason` (it's
+      // acceptable to use a lot of CPU while playing audio, running a
+      // videoconference call...).
       continue;
     }
 
-    if (!browsing_instance_it->second
-             .cannot_freeze_reasons_since_last_cpu_measurement.empty()) {
-      // CPU-intensive in background while having a `CannotFreezeReason` isn't
-      // recorded (it's acceptable to use a lot of CPU while playing audio,
-      // running a videoconference call...).
+    if (state.highest_cpu_any_interval_without_cannot_freeze_reason >
+        cpu_proportion) {
+      // Ignore CPU measurement without a `CannotFreezeReason` if it's not the
+      // highest one.
       continue;
     }
 
-    browsing_instance_it->second.cpu_intensive_in_background = true;
-    UpdateFrozenState(*browsing_instance_it->second.pages.begin());
+    // Store the new highest CPU measurement without a `CannotFreezeReason`.
+    state.highest_cpu_any_interval_without_cannot_freeze_reason =
+        cpu_proportion;
+
+    // If the CPU measurement is above the threshold for high CPU usage, update
+    // the frozen state.
+    if (cpu_proportion >= high_cpu_proportion) {
+      UpdateFrozenState(*state.pages.begin());
+    }
   }
 
   // Update `cannot_freeze_reasons_since_last_cpu_measurement` for all browsing
diff --git a/components/performance_manager/freezing/freezing_policy.h b/components/performance_manager/freezing/freezing_policy.h
index 9258b74..92cf0b7 100644
--- a/components/performance_manager/freezing/freezing_policy.h
+++ b/components/performance_manager/freezing/freezing_policy.h
@@ -94,9 +94,11 @@
     // but may contain an unbounded amount of pages connected via opener
     // relationship).
     base::flat_set<const PageNode*> pages;
-    // Whether a group of same-origin frames/workers associated with this
-    // browsing instance used a lot of CPU in background.
-    bool cpu_intensive_in_background = false;
+    // Highest CPU measurement for a group of same-origin frames/workers
+    // associated within this browsing instance, over any past measurement
+    // period during which no `CannotFreezeReason` was applicable.
+    // (1.0 = 100% of 1 core)
+    double highest_cpu_any_interval_without_cannot_freeze_reason = 0.0;
     // `CannotFreezeReason`s applicable to this browsing instance at any point
     // since the last CPU measurement.
     CannotFreezeReasonSet cannot_freeze_reasons_since_last_cpu_measurement;