1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/fast_checkout/fast_checkout_tab_helper.h"
#include "base/trace_event/trace_event.h"
#include "chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher.h"
#include "chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_factory.h"
#include "chrome/browser/fast_checkout/fast_checkout_client_impl.h"
#include "chrome/browser/profiles/profile.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/commerce/core/heuristics/commerce_heuristics_provider.h"
#include "components/google/core/common/google_util.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
namespace {
BASE_FEATURE(kAsyncFastCheckout,
"AsyncFastCheckout",
base::FEATURE_ENABLED_BY_DEFAULT);
bool IsCartOrCheckoutUrl(const GURL& url) {
return commerce_heuristics::IsVisitCheckout(url) ||
commerce_heuristics::IsVisitCart(url);
}
} // namespace
FastCheckoutTabHelper::FastCheckoutTabHelper(content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
content::WebContentsUserData<FastCheckoutTabHelper>(*web_contents) {}
FastCheckoutTabHelper::~FastCheckoutTabHelper() = default;
void FastCheckoutTabHelper::DidStartNavigation(
content::NavigationHandle* navigation_handle) {
TRACE_EVENT("navigation", "FastCheckoutTabHelper::DidStartNavigation");
// We only care about top-level navigations.
if (!navigation_handle || !navigation_handle->IsInPrimaryMainFrame()) {
return;
}
// Shopping sites should be http or https - save heuristics if this URL
// does not satisfy that.
const GURL& url = navigation_handle->GetURL();
if (!url.SchemeIsHTTPOrHTTPS()) {
return;
}
if (base::FeatureList::IsEnabled(kAsyncFastCheckout)) {
// DidStartNavigation() locates on the navigation critical path. To avoid
// blocking navigation, we run DidStartNavigationImpl asynchronously.
//
// GoogleSearch is not the target of the Fast Checkout.
if (!google_util::IsGoogleSearchUrl(url)) {
content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT})
->PostTask(
FROM_HERE,
base::BindOnce(&FastCheckoutTabHelper::DidStartNavigationImpl,
weak_ptr_factory_.GetWeakPtr(), std::move(url)));
}
} else {
DidStartNavigationImpl(url);
}
}
void FastCheckoutTabHelper::DidStartNavigationImpl(const GURL& url) {
TRACE_EVENT("navigation", "FastCheckoutTabHelper::DidStartNavigationImpl");
FetchCapabilities(url);
if (autofill::ContentAutofillClient* client =
autofill::ContentAutofillClient::FromWebContents(web_contents())) {
if (auto* fast_checkout_client = client->GetFastCheckoutClient()) {
fast_checkout_client->OnNavigation(url, IsCartOrCheckoutUrl(url));
}
}
}
void FastCheckoutTabHelper::FetchCapabilities(const GURL& url) {
TRACE_EVENT("navigation", "FastCheckoutTabHelper::FetchCapabilities");
// Check for both checkout and cart URLs because some websites use cart URLs
// throughout their whole checkout funnel.
if (IsCartOrCheckoutUrl(url)) {
PrefService* pref_service =
Profile::FromBrowserContext(web_contents()->GetBrowserContext())
->GetPrefs();
if (!pref_service) {
return;
}
if (!autofill::prefs::IsAutofillProfileEnabled(pref_service) ||
!autofill::prefs::IsAutofillPaymentMethodsEnabled(pref_service)) {
return;
}
FastCheckoutCapabilitiesFetcher* fetcher =
FastCheckoutCapabilitiesFetcherFactory::GetForBrowserContext(
GetWebContents().GetBrowserContext());
if (!fetcher) {
return;
}
fetcher->FetchCapabilities();
}
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(FastCheckoutTabHelper);
|