[FastCheckout] Add form cache state UMA in CapabilitiesFetcher.
This CL adds support for recording the cache state at the point
where availability for a given form signature on a given origin
is looked up.
Bug: 1350456, 1334642
Change-Id: Ib7318aee1eac2b4161fed7205609d1bb1de7249f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3829265
Commit-Queue: Jan Keitel <jkeitel@google.com>
Reviewed-by: Norge Vizcay <vizcay@google.com>
Reviewed-by: Vidhan Jain <vidhanj@google.com>
Cr-Commit-Position: refs/heads/main@{#1036577}
diff --git a/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.cc b/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.cc
index 4f73784..9b5a91a 100644
--- a/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.cc
+++ b/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.cc
@@ -27,6 +27,9 @@
constexpr char kFastCheckoutIntent[] = "CHROME_FAST_CHECKOUT";
constexpr char kUmaKeyHttpCode[] =
"Autofill.FastCheckout.CapabilitiesFetcher.HttpResponseCode";
+constexpr char kUmaKeyCacheStateIsTriggerFormSupported[] =
+ "Autofill.FastCheckout.CapabilitiesFetcher."
+ "CacheStateForIsTriggerFormSupported";
} // namespace
FastCheckoutCapabilitiesFetcherImpl::FastCheckoutCapabilitiesFetcherImpl(
@@ -73,9 +76,26 @@
bool FastCheckoutCapabilitiesFetcherImpl::IsTriggerFormSupported(
const url::Origin& origin,
autofill::FormSignature form_signature) {
- // TODO(crbug.com/1350456): Check whether there is an ongoing request. If so,
- // record a UMA to indicate that the request resolution was not fast enough.
- return cache_.ContainsTriggerForm(origin, form_signature);
+ if (cache_.ContainsTriggerForm(origin, form_signature)) {
+ base::UmaHistogramEnumeration(
+ kUmaKeyCacheStateIsTriggerFormSupported,
+ CacheStateForIsTriggerFormSupported::kEntryAvailableAndFormSupported);
+ return true;
+ }
+
+ // Analyze why the result is `false` to record the correct metric.
+ if (cache_.ContainsOrigin(origin)) {
+ base::UmaHistogramEnumeration(kUmaKeyCacheStateIsTriggerFormSupported,
+ CacheStateForIsTriggerFormSupported::
+ kEntryAvailableAndFormNotSupported);
+ } else {
+ base::UmaHistogramEnumeration(
+ kUmaKeyCacheStateIsTriggerFormSupported,
+ ongoing_requests_.contains(origin)
+ ? CacheStateForIsTriggerFormSupported::kFetchOngoing
+ : CacheStateForIsTriggerFormSupported::kNeverFetched);
+ }
+ return false;
}
void FastCheckoutCapabilitiesFetcherImpl::OnGetCapabilitiesInformationReceived(
diff --git a/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.h b/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.h
index c8d12bb..594bfa8 100644
--- a/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.h
+++ b/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.h
@@ -22,6 +22,31 @@
class FastCheckoutCapabilitiesFetcherImpl
: public FastCheckoutCapabilitiesFetcher {
public:
+ // Possible different cache states that `FastCheckoutCapabilitiesFetcherImpl`
+ // can encounter when `IsTriggerFormSupported` is called.
+ //
+ // Do not remove or renumber entries in this enum. It needs to be kept in
+ // sync with `FastCheckoutCacheStateForIsTriggerFormSupported` in `enums.xml`.
+ enum class CacheStateForIsTriggerFormSupported {
+ // Availability is currently being fetched for this entry, but the request
+ // has not completed yet.
+ kFetchOngoing = 0,
+
+ // There is a valid cache entry for this origin and the form signature that
+ // is being checked is not supported.
+ kEntryAvailableAndFormNotSupported = 1,
+
+ // There is a valid cache entry for this origin and the form signature that
+ // is being checked is supported.
+ kEntryAvailableAndFormSupported = 2,
+
+ // No availability was fetched for this origin within the lifetime of the
+ // cache.
+ kNeverFetched = 3,
+
+ kMaxValue = kNeverFetched
+ };
+
explicit FastCheckoutCapabilitiesFetcherImpl(
std::unique_ptr<autofill_assistant::AutofillAssistant>
autofill_assistant);
diff --git a/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl_unittest.cc b/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl_unittest.cc
index b5be2350..c8ce02f7 100644
--- a/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl_unittest.cc
+++ b/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl_unittest.cc
@@ -27,13 +27,18 @@
using CapabilitiesInfo =
autofill_assistant::AutofillAssistant::CapabilitiesInfo;
using autofill_assistant::MockAutofillAssistant;
-using ::base::test::RunOnceCallback;
-using ::testing::_;
+using base::test::RunOnceCallback;
+using CacheStateForIsTriggerFormSupported =
+ FastCheckoutCapabilitiesFetcherImpl::CacheStateForIsTriggerFormSupported;
+using testing::_;
constexpr uint32_t kHashPrefixSize = 15u;
constexpr char kIntent[] = "CHROME_FAST_CHECKOUT";
constexpr char kUmaKeyHttpCode[] =
"Autofill.FastCheckout.CapabilitiesFetcher.HttpResponseCode";
+constexpr char kUmaKeyCacheStateIsTriggerFormSupported[] =
+ "Autofill.FastCheckout.CapabilitiesFetcher."
+ "CacheStateForIsTriggerFormSupported";
constexpr char kUrl1[] = "https://wwww.firstpage.com/";
constexpr char kUrl2[] = "https://wwww.another-domain.co.uk/";
@@ -276,4 +281,61 @@
EXPECT_TRUE(fetcher()->IsTriggerFormSupported(origin2, kFormSignature3));
}
+TEST_F(FastCheckoutCapabilitiesFetcherImplTest,
+ IsTriggerFormSupportedRecordsUmaMetrics) {
+ url::Origin origin1 = url::Origin::Create(GURL(kUrl1));
+ uint64_t hash1 = AutofillAssistant::GetHashPrefix(kHashPrefixSize, origin1);
+
+ // The cache is empty.
+ EXPECT_FALSE(fetcher()->IsTriggerFormSupported(origin1, kFormSignature1));
+ EXPECT_FALSE(fetcher()->IsTriggerFormSupported(origin1, kFormSignature2));
+ histogram_tester().ExpectUniqueSample(
+ kUmaKeyCacheStateIsTriggerFormSupported,
+ CacheStateForIsTriggerFormSupported::kNeverFetched, 2u);
+
+ AutofillAssistant::GetCapabilitiesResponseCallback response_callback1;
+ EXPECT_CALL(*autofill_assistant(),
+ GetCapabilitiesByHashPrefix(
+ kHashPrefixSize, std::vector<uint64_t>{hash1}, kIntent, _))
+ .Times(1)
+ .WillOnce(MoveArg<3>(&response_callback1));
+
+ base::MockCallback<FastCheckoutCapabilitiesFetcher::Callback> callback1;
+ fetcher()->FetchAvailability(origin1, callback1.Get());
+
+ // While the fetch is still ongoing, there is no availability yet.
+ EXPECT_FALSE(fetcher()->IsTriggerFormSupported(origin1, kFormSignature1));
+ histogram_tester().ExpectTotalCount(kUmaKeyCacheStateIsTriggerFormSupported,
+ 3u);
+ histogram_tester().ExpectBucketCount(
+ kUmaKeyCacheStateIsTriggerFormSupported,
+ CacheStateForIsTriggerFormSupported::kNeverFetched, 2u);
+ histogram_tester().ExpectBucketCount(
+ kUmaKeyCacheStateIsTriggerFormSupported,
+ CacheStateForIsTriggerFormSupported::kFetchOngoing, 1u);
+
+ EXPECT_CALL(callback1, Run(true));
+ BundleCapabilitiesInformation capabilities;
+ capabilities.trigger_form_signatures.push_back(kFormSignature1);
+ CapabilitiesInfo info1{kUrl1, {}, capabilities};
+ std::move(response_callback1)
+ .Run(net::HttpStatusCode::HTTP_OK, std::vector<CapabilitiesInfo>{info1});
+
+ // The cache contains information for the first domain.
+ EXPECT_TRUE(fetcher()->IsTriggerFormSupported(origin1, kFormSignature1));
+ histogram_tester().ExpectTotalCount(kUmaKeyCacheStateIsTriggerFormSupported,
+ 4u);
+ histogram_tester().ExpectBucketCount(
+ kUmaKeyCacheStateIsTriggerFormSupported,
+ CacheStateForIsTriggerFormSupported::kEntryAvailableAndFormSupported, 1u);
+
+ EXPECT_FALSE(fetcher()->IsTriggerFormSupported(origin1, kFormSignature2));
+ histogram_tester().ExpectTotalCount(kUmaKeyCacheStateIsTriggerFormSupported,
+ 5u);
+ histogram_tester().ExpectBucketCount(
+ kUmaKeyCacheStateIsTriggerFormSupported,
+ CacheStateForIsTriggerFormSupported::kEntryAvailableAndFormNotSupported,
+ 1u);
+}
+
} // namespace
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index a0e884f..169d18c 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -36294,6 +36294,17 @@
<int value="4" label="Regular User"/>
</enum>
+<enum name="FastCheckoutCacheStateForIsTriggerFormSupported">
+ <summary>
+ Classifies the cache state of the FastCheckout capabilities fetcher at the
+ time of checking whether a form signature on a domain is supported.
+ </summary>
+ <int value="0" label="Cache not available and request ongoing"/>
+ <int value="1" label="Cache available and form signature not supported"/>
+ <int value="2" label="Cache available and form signature supported"/>
+ <int value="3" label="Cache not available and no request made"/>
+</enum>
+
<enum name="FastPairAccountKeyFailure">
<int value="0" label="Failed to find the Account Key GATT characteristic"/>
<int value="1"
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml
index d176de4..d4626bd 100644
--- a/tools/metrics/histograms/metadata/autofill/histograms.xml
+++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -1202,6 +1202,19 @@
</summary>
</histogram>
+<histogram
+ name="Autofill.FastCheckout.CapabilitiesFetcher.CacheStateForIsTriggerFormSupported"
+ enum="FastCheckoutCacheStateForIsTriggerFormSupported"
+ expires_after="2023-08-15">
+ <owner>bwolfgang@google.com</owner>
+ <owner>jkeitel@google.com</owner>
+ <owner>vizcay@google.com</owner>
+ <summary>
+ The state of the cache of the Fast Checkout capabilities fetcher at the
+ point of checking whether a given form signature on an origin is supported.
+ </summary>
+</histogram>
+
<histogram name="Autofill.FastCheckout.CapabilitiesFetcher.HttpResponseCode"
enum="HttpResponseCode" expires_after="2023-08-15">
<owner>bwolfgang@google.com</owner>