[OBC] Add origin-bound cookies UKMs

These UKMs check for when a cookie fails to send due to OBC.
This metric will be used to potentially alert sites that will
be affected by origin bound cookies.

They are recorded whenever a cookie is accessed by port or scheme

Approval Doc (Google only):
https://docs.google.com/document/d/1MwHB7ufUmJ2zBO-I8fjpVLOdnnrJ6ayx4tJeLe6Awrk/edit?usp=sharing&resourcekey=0--bs9LY6O-D9BopVPYNbsSQ


Bug: 377723895
Change-Id: I4f859d7d8668db71f8eb57111ed6ce07a8c64e9f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6001653
Reviewed-by: Steven Bingler <[email protected]>
Reviewed-by: Rakina Zata Amni <[email protected]>
Commit-Queue: Steven Bingler <[email protected]>
Auto-Submit: Amarjot Gill <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1381265}
diff --git a/content/browser/renderer_host/cookie_utils.cc b/content/browser/renderer_host/cookie_utils.cc
index ed7c99c83..df92d7b 100644
--- a/content/browser/renderer_host/cookie_utils.cc
+++ b/content/browser/renderer_host/cookie_utils.cc
@@ -72,6 +72,53 @@
   }
 }
 
+void PotentiallyRecordCookieOriginMismatch(
+    RenderFrameHost* rfh,
+    CookieAccessDetails::Type access_type,
+    const net::CookieInclusionStatus& status) {
+  CHECK(rfh);
+
+  if (access_type != CookieAccessDetails::Type::kRead) {
+    return;
+  }
+
+  // Our data collection policy disallows collecting UKMs while prerendering.
+  // See //content/browser/preloading/prerender/README.md and ask the team to
+  // explore options to record data for prerendering pages if we need to
+  // support the case.
+  if (rfh->IsInLifecycleState(RenderFrameHost::LifecycleState::kPrerendering)) {
+    return;
+  }
+  const bool port_mismatch =
+      status.HasWarningReason(net::CookieInclusionStatus::WARN_PORT_MISMATCH) ||
+      status.HasExclusionReason(
+          net::CookieInclusionStatus::EXCLUDE_PORT_MISMATCH);
+
+  const bool scheme_mismatch =
+      status.HasWarningReason(
+          net::CookieInclusionStatus::WARN_SCHEME_MISMATCH) ||
+      status.HasExclusionReason(
+          net::CookieInclusionStatus::EXCLUDE_SCHEME_MISMATCH);
+
+  if (port_mismatch || scheme_mismatch) {
+    ukm::SourceId source_id = rfh->GetPageUkmSourceId();
+
+    auto event = ukm::builders::Cookies_Blocked_DueToOriginMismatch(source_id);
+
+    // The event itself is what we're interested in, the value of "true" here
+    // can be ignored.
+    if (port_mismatch) {
+      event.SetPortMismatch(true);
+    }
+
+    if (scheme_mismatch) {
+      event.SetSchemeMismatch(true);
+    }
+
+    event.Record(ukm::UkmRecorder::Get());
+  }
+}
+
 // Relies on checks in RecordPartitionedCookiesUKMs to confirm that that the
 // cookie name is not "receive-cookie-deprecation", that cookie is first party
 // partitioned and the RenderFrameHost is not prerendering.
@@ -355,6 +402,8 @@
           cookie->cookie_or_line->get_cookie().Value());
     }
 
+    PotentiallyRecordCookieOriginMismatch(rfh, cookie_details->type, status);
+
     // In order to anticipate the potential effects of the expiry limit in
     // rfc6265bis, we need to check how long it's been since the cookie was
     // refreshed (if LastUpdateDate is populated). These three buckets were