blob: 650254a679a2a3ae7d12e8e8a515633b895514c1 [file] [log] [blame]
// 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 "components/commerce/core/account_checker.h"
#include "base/feature_list.h"
#include "base/json/values_util.h"
#include "base/values.h"
#include "components/commerce/core/commerce_feature_list.h"
#include "components/commerce/core/pref_names.h"
#include "components/endpoint_fetcher/endpoint_fetcher.h"
#include "components/prefs/pref_service.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/unified_consent/url_keyed_data_collection_consent_helper.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/data_decoder/public/cpp/data_decoder.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace commerce {
AccountChecker::AccountChecker(
PrefService* pref_service,
signin::IdentityManager* identity_manager,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
: pref_service_(pref_service),
identity_manager_(identity_manager),
url_loader_factory_(url_loader_factory),
weak_ptr_factory_(this) {
if (identity_manager) {
FetchWaaStatus();
scoped_identity_manager_observation_.Observe(identity_manager);
}
}
AccountChecker::~AccountChecker() = default;
bool AccountChecker::IsSignedIn() {
return identity_manager_ &&
identity_manager_->HasPrimaryAccount(signin::ConsentLevel::kSync);
}
bool AccountChecker::IsAnonymizedUrlDataCollectionEnabled() {
return pref_service_ &&
unified_consent::UrlKeyedDataCollectionConsentHelper::
NewAnonymizedDataCollectionConsentHelper(pref_service_)
->IsEnabled();
}
bool AccountChecker::IsWebAndAppActivityEnabled() {
return pref_service_ &&
pref_service_->GetBoolean(kWebAndAppActivityEnabledForShopping);
}
void AccountChecker::OnPrimaryAccountChanged(
const signin::PrimaryAccountChangeEvent& event_details) {
FetchWaaStatus();
}
void AccountChecker::FetchWaaStatus() {
// For now we need to update users' consent status on web and app activity
// only when ShoppingList feature is enabled.
if (!base::FeatureList::IsEnabled(kShoppingList) || !IsSignedIn())
return;
// TODO(crbug.com/1311754): These parameters (url, oauth_scope, etc.) are
// copied from web_history_service.cc directly, it works now but we should
// figure out a better way to keep these parameters in sync.
const char waa_oauth_name[] = "web_history";
const char waa_query_url[] =
"https://history.google.com/history/api/lookup?client=web_app";
const char waa_oauth_scope[] = "https://www.googleapis.com/auth/chromesync";
const char waa_content_type[] = "application/json; charset=UTF-8";
const char waa_get_method[] = "GET";
const int64_t waa_timeout_ms = 30000;
const char waa_post_data[] = "";
net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation("chrome_commerce_waa_fetcher",
R"(
semantics {
sender: "Chrome Shopping"
description:
"Check whether Web & App Activity is paused in My Google Activity."
"If it is paused, some Chrome Shopping features such as Price "
"Tracking Notifications become disabled."
trigger:
"On account checker initialization or every time after the user "
"changes their primary account."
data:
"The request includes an OAuth2 token authenticating the user. The "
"response includes a boolean indicating whether the feature is "
"enabled."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: NO
setting:
"This fetch is only enabled for signed-in users. There's no "
"direct Chromium's setting to disable this, but users can manage "
"their preferences by visiting myactivity.google.com."
chrome_policy {
BrowserSignin {
policy_options {mode: MANDATORY}
BrowserSignin: 0
}
}
})");
auto endpoint_fetcher = std::make_unique<EndpointFetcher>(
url_loader_factory_, waa_oauth_name, GURL(waa_query_url), waa_get_method,
waa_content_type, std::vector<std::string>{waa_oauth_scope},
waa_timeout_ms, waa_post_data, traffic_annotation, identity_manager_);
endpoint_fetcher.get()->Fetch(base::BindOnce(
&AccountChecker::HandleFetchWaaResponse, weak_ptr_factory_.GetWeakPtr(),
pref_service_, std::move(endpoint_fetcher)));
}
void AccountChecker::HandleFetchWaaResponse(
PrefService* pref_service,
std::unique_ptr<EndpointFetcher> endpoint_fetcher,
std::unique_ptr<EndpointResponse> responses) {
data_decoder::DataDecoder::ParseJsonIsolated(
responses->response,
base::BindOnce(
[](PrefService* pref_service,
data_decoder::DataDecoder::ValueOrError result) {
if (pref_service && result.has_value() && result->is_dict()) {
const char waa_response_key[] = "history_recording_enabled";
if (auto waa_enabled = result->FindBoolKey(waa_response_key)) {
pref_service->SetBoolean(kWebAndAppActivityEnabledForShopping,
*waa_enabled);
}
}
},
pref_service));
}
} // namespace commerce