#include "components/commerce/core/shopping_service.h"
#include <vector>
#include "base/barrier_callback.h"
#include "base/check_is_test.h"
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "base/values.h"
#include "commerce_types.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/commerce/core/bookmark_update_manager.h"
#include "components/commerce/core/commerce_constants.h"
#include "components/commerce/core/commerce_feature_list.h"
#include "components/commerce/core/commerce_utils.h"
#include "components/commerce/core/compare/cluster_manager.h"
#include "components/commerce/core/compare/cluster_server_proxy.h"
#include "components/commerce/core/compare/product_group.h"
#include "components/commerce/core/compare/product_specifications_server_proxy.h"
#include "components/commerce/core/discounts_storage.h"
#include "components/commerce/core/feature_utils.h"
#include "components/commerce/core/metrics/metrics_utils.h"
#include "components/commerce/core/metrics/scheduled_metrics_manager.h"
#include "components/commerce/core/parcel/parcels_manager.h"
#include "components/commerce/core/pref_names.h"
#include "components/commerce/core/price_tracking_utils.h"
#include "components/commerce/core/product_specifications/product_specifications_service.h"
#include "components/commerce/core/proto/commerce_subscription_db_content.pb.h"
#include "components/commerce/core/proto/discounts.pb.h"
#include "components/commerce/core/proto/merchant_trust.pb.h"
#include "components/commerce/core/proto/price_insights.pb.h"
#include "components/commerce/core/proto/price_tracking.pb.h"
#include "components/commerce/core/proto/shopping_page_types.pb.h"
#include "components/commerce/core/shopping_bookmark_model_observer.h"
#include "components/commerce/core/shopping_power_bookmark_data_provider.h"
#include "components/commerce/core/subscriptions/commerce_subscription.h"
#include "components/commerce/core/subscriptions/subscriptions_manager.h"
#include "components/commerce/core/subscriptions/subscriptions_observer.h"
#include "components/commerce/core/web_wrapper.h"
#include "components/grit/components_resources.h"
#include "components/optimization_guide/core/optimization_guide_decider.h"
#include "components/optimization_guide/core/optimization_guide_features.h"
#include "components/optimization_guide/core/optimization_guide_util.h"
#include "components/optimization_guide/proto/hints.pb.h"
#include "components/power_bookmarks/core/power_bookmark_service.h"
#include "components/power_bookmarks/core/power_bookmark_utils.h"
#include "components/power_bookmarks/core/proto/power_bookmark_meta.pb.h"
#include "components/power_bookmarks/core/proto/shopping_specifics.pb.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/search/ntp_features.h"
#include "components/session_proto_db/session_proto_storage.h"
#include "components/sync/base/features.h"
#include "components/sync/service/sync_service.h"
#include "components/unified_consent/url_keyed_data_collection_consent_helper.h"
#include "net/base/url_util.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "ui/base/resource/resource_bundle.h"
#include "url/url_constants.h"
namespace commerce {
namespace {
const size_t kRecentTabsMaxSize = …;
class ProductSpecificationsUrlObserver
: public ProductSpecificationsSet::Observer { … };
}
const char kImageAvailabilityHistogramName[] = …;
const char kProductInfoLocalExtractionTime[] = …;
const uint64_t kProductInfoLocalExtractionDelayMs = …;
ShoppingService::ShoppingService(
const std::string& country_on_startup,
const std::string& locale_on_startup,
bookmarks::BookmarkModel* bookmark_model,
optimization_guide::OptimizationGuideDecider* opt_guide,
PrefService* pref_service,
signin::IdentityManager* identity_manager,
syncer::SyncService* sync_service,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
SessionProtoStorage<
commerce_subscription_db::CommerceSubscriptionContentProto>*
subscription_proto_db,
power_bookmarks::PowerBookmarkService* power_bookmark_service,
ProductSpecificationsService* product_specifications_service,
SessionProtoStorage<discounts_db::DiscountsContentProto>*
discounts_proto_db,
SessionProtoStorage<parcel_tracking_db::ParcelTrackingContent>*
parcel_tracking_proto_db,
history::HistoryService* history_service,
std::unique_ptr<commerce::WebExtractor> web_extractor)
: … { … }
AccountChecker* ShoppingService::GetAccountChecker() { … }
void ShoppingService::WebWrapperCreated(WebWrapper* web) { … }
void ShoppingService::DidNavigatePrimaryMainFrame(WebWrapper* web) { … }
void ShoppingService::HandleDidNavigatePrimaryMainFrameForProductInfo(
WebWrapper* web) { … }
void ShoppingService::DidNavigateAway(WebWrapper* web, const GURL& from_url) { … }
void ShoppingService::DidStopLoading(WebWrapper* web) { … }
void ShoppingService::ScheduleProductInfoLocalExtraction(WebWrapper* web) { … }
void ShoppingService::DidFinishLoad(WebWrapper* web) { … }
void ShoppingService::OnWebWrapperSwitched(WebWrapper* web) { … }
void ShoppingService::OnWebWrapperViewed(WebWrapper* web) { … }
void ShoppingService::TryRunningLocalExtractionForProductInfo(
base::WeakPtr<WebWrapper> web) { … }
void ShoppingService::RunLocalExtractionForProductInfoForShoppingPage(
base::WeakPtr<WebWrapper> web,
const GURL& url,
std::optional<bool> is_shopping_page) { … }
void ShoppingService::OnProductInfoLocalExtractionResult(
const GURL url,
ukm::SourceId source_id,
base::Value result) { … }
bool ShoppingService::CheckIsPDPFromMetaOnly(
const base::Value::Dict& on_page_meta_map) { … }
void ShoppingService::WebWrapperDestroyed(WebWrapper* web) { … }
void ShoppingService::UpdateProductInfoCache(
const GURL& url,
bool needs_js,
std::unique_ptr<ProductInfo> info) { … }
const ProductInfo* ShoppingService::GetFromProductInfoCache(const GURL& url) { … }
void ShoppingService::PDPMetricsCallback(
bool is_off_the_record,
optimization_guide::OptimizationGuideDecision decision,
const optimization_guide::OptimizationMetadata& metadata,
const GURL& url) { … }
void ShoppingService::GetProductInfoForUrl(const GURL& url,
ProductInfoCallback callback) { … }
std::optional<ProductInfo> ShoppingService::GetAvailableProductInfoForUrl(
const GURL& url) { … }
void ShoppingService::GetUpdatedProductInfoForBookmarks(
const std::vector<int64_t>& bookmark_ids,
BookmarkProductInfoUpdatedCallback info_updated_callback) { … }
size_t ShoppingService::GetMaxProductBookmarkUpdatesPerBatch() { … }
void ShoppingService::GetAllPriceTrackedBookmarks(
base::OnceCallback<void(std::vector<const bookmarks::BookmarkNode*>)>
callback) { … }
std::vector<const bookmarks::BookmarkNode*>
ShoppingService::GetAllShoppingBookmarks() { … }
void ShoppingService::GetMerchantInfoForUrl(const GURL& url,
MerchantInfoCallback callback) { … }
void ShoppingService::GetPriceInsightsInfoForUrl(
const GURL& url,
PriceInsightsInfoCallback callback) { … }
void ShoppingService::GetDiscountInfoForUrl(const GURL& url,
DiscountInfoCallback callback) { … }
void ShoppingService::GetProductSpecificationsForUrls(
const std::vector<GURL>& urls,
ProductSpecificationsCallback callback) { … }
void ShoppingService::IsShoppingPage(const GURL& url,
IsShoppingPageCallback callback) { … }
bool ShoppingService::IsRegionLockedFeatureEnabled(
const base::Feature& feature,
const base::Feature& region_specific_feature) { … }
bool ShoppingService::IsMerchantViewerEnabled() { … }
bool ShoppingService::IsCommercePriceTrackingEnabled() { … }
bool ShoppingService::IsPriceInsightsEligible() { … }
bool ShoppingService::IsPriceInsightsInfoApiEnabled() { … }
bool ShoppingService::IsDiscountEligibleToShowOnNavigation() { … }
bool ShoppingService::IsParcelTrackingEligible() { … }
bool ShoppingService::IsShoppingPageTypesApiEnabled() { … }
bool ShoppingService::IsDiscountInfoApiEnabled() { … }
const std::vector<UrlInfo> ShoppingService::GetUrlInfosForActiveWebWrappers() { … }
void ShoppingService::GetUrlInfosForWebWrappersWithProducts(
base::OnceCallback<void(const std::vector<UrlInfo>)> callback) { … }
const std::vector<UrlInfo>
ShoppingService::GetUrlInfosForRecentlyViewedWebWrappers() { … }
void ShoppingService::HandleOptGuideProductInfoResponse(
const GURL& url,
WebWrapper* web,
ProductInfoCallback callback,
optimization_guide::OptimizationGuideDecision decision,
const optimization_guide::OptimizationMetadata& metadata) { … }
std::unique_ptr<ProductInfo> ShoppingService::OptGuideResultToProductInfo(
const optimization_guide::OptimizationMetadata& metadata) { … }
void ShoppingService::HandleOnDemandProductInfoResponseForBookmarks(
BookmarkProductInfoUpdatedCallback callback,
std::unordered_map<std::string, int64_t> url_to_id_map,
const GURL& url,
const base::flat_map<
optimization_guide::proto::OptimizationType,
optimization_guide::OptimizationGuideDecisionWithMetadata>& decisions) { … }
void ShoppingService::HandleOnDemandProductInfoResponse(
RepeatingProductInfoCallback callback,
const GURL& url,
const base::flat_map<
optimization_guide::proto::OptimizationType,
optimization_guide::OptimizationGuideDecisionWithMetadata>& decisions) { … }
void ShoppingService::MergeProductInfoData(
ProductInfo* info,
const base::Value::Dict& on_page_data_map) { … }
void ShoppingService::HandleOptGuideMerchantInfoResponse(
const GURL& url,
MerchantInfoCallback callback,
optimization_guide::OptimizationGuideDecision decision,
const optimization_guide::OptimizationMetadata& metadata) { … }
void ShoppingService::HandleOptGuidePriceInsightsInfoResponse(
const GURL& url,
PriceInsightsInfoCallback callback,
optimization_guide::OptimizationGuideDecision decision,
const optimization_guide::OptimizationMetadata& metadata) { … }
std::unique_ptr<PriceInsightsInfo>
ShoppingService::OptGuideResultToPriceInsightsInfo(
const optimization_guide::OptimizationMetadata& metadata) { … }
void ShoppingService::HandleDidNavigatePrimaryMainFrameForPriceInsightsInfo(
WebWrapper* web) { … }
void ShoppingService::HandleOptGuideShoppingPageTypesResponse(
const GURL& url,
IsShoppingPageCallback callback,
optimization_guide::OptimizationGuideDecision decision,
const optimization_guide::OptimizationMetadata& metadata) { … }
void ShoppingService::GetDiscountInfoFromOptGuide(
const GURL& url,
DiscountInfoCallback callback) { … }
void ShoppingService::HandleOptGuideDiscountInfoResponse(
const GURL& url,
DiscountInfoCallback callback,
optimization_guide::OptimizationGuideDecision decision,
const optimization_guide::OptimizationMetadata& metadata) { … }
std::vector<DiscountInfo> ShoppingService::OptGuideResultToDiscountInfos(
const optimization_guide::OptimizationMetadata& metadata) { … }
void ShoppingService::SetDiscountsStorageForTesting(
std::unique_ptr<DiscountsStorage> storage) { … }
void ShoppingService::Subscribe(
std::unique_ptr<std::vector<CommerceSubscription>> subscriptions,
base::OnceCallback<void(bool)> callback) { … }
void ShoppingService::Unsubscribe(
std::unique_ptr<std::vector<CommerceSubscription>> subscriptions,
base::OnceCallback<void(bool)> callback) { … }
void ShoppingService::AddSubscriptionsObserver(
SubscriptionsObserver* observer) { … }
void ShoppingService::RemoveSubscriptionsObserver(
SubscriptionsObserver* observer) { … }
void ShoppingService::GetAllSubscriptions(
SubscriptionType type,
base::OnceCallback<void(std::vector<CommerceSubscription>)> callback) { … }
void ShoppingService::IsSubscribed(CommerceSubscription subscription,
base::OnceCallback<void(bool)> callback) { … }
bool ShoppingService::IsSubscribedFromCache(
const CommerceSubscription& subscription) { … }
void ShoppingService::FetchPriceEmailPref() { … }
void ShoppingService::ScheduleSavedProductUpdate() { … }
bool ShoppingService::IsShoppingListEligible() { … }
void ShoppingService::WaitForReady(
base::OnceCallback<void(ShoppingService*)> callback) { … }
void ShoppingService::StartTrackingParcels(
const std::vector<std::pair<ParcelIdentifier::Carrier, std::string>>&
parcel_identifiers,
const std::string& source_page_domain,
GetParcelStatusCallback callback) { … }
void ShoppingService::GetAllParcelStatuses(GetParcelStatusCallback callback) { … }
void ShoppingService::StopTrackingParcel(
const std::string& tracking_id,
base::OnceCallback<void(bool)> callback) { … }
void ShoppingService::StopTrackingParcels(
const std::vector<std::pair<ParcelIdentifier::Carrier, std::string>>&
parcel_identifiers,
base::OnceCallback<void(bool)> callback) { … }
void ShoppingService::StopTrackingAllParcels(
base::OnceCallback<void(bool)> callback) { … }
ProductSpecificationsService*
ShoppingService::GetProductSpecificationsService() { … }
ClusterManager* ShoppingService::GetClusterManager() { … }
void ShoppingService::GetProductIdentifierForUrl(
const GURL& url,
UrlProductIdentifierTupleCallback callback) { … }
void ShoppingService::UpdateRecentlyViewedURL(WebWrapper* web) { … }
const std::vector<ProductSpecificationsSet>
ShoppingService::GetAllProductSpecificationSets() { … }
void ShoppingService::OnGetOnDemandProductInfo(
const GURL& url,
const std::optional<const ProductInfo>& info) { … }
void ShoppingService::OnHistoryDeletions(
history::HistoryService* history_service,
const history::DeletionInfo& deletion_info) { … }
void ShoppingService::QueryHistoryForUrl(
const GURL& url,
history::HistoryService::QueryURLCallback callback) { … }
base::WeakPtr<ShoppingService> ShoppingService::AsWeakPtr() { … }
void ShoppingService::Shutdown() { … }
ShoppingService::~ShoppingService() = default;
}