// 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. #ifndef COMPONENTS_SUPERVISED_USER_CORE_BROWSER_PROTO_FETCHER_H_ #define COMPONENTS_SUPERVISED_USER_CORE_BROWSER_PROTO_FETCHER_H_ #include <memory> #include <optional> #include <string> #include <string_view> #include <utility> #include "base/check_op.h" #include "base/containers/id_map.h" #include "base/functional/bind.h" #include "base/functional/callback_forward.h" #include "base/memory/raw_ref.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/notreached.h" #include "base/strings/string_util.h" #include "base/time/time.h" #include "base/timer/elapsed_timer.h" #include "base/types/expected.h" #include "base/version_info/channel.h" #include "components/signin/public/identity_manager/access_token_info.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "components/supervised_user/core/browser/api_access_token_fetcher.h" #include "components/supervised_user/core/browser/fetcher_config.h" #include "components/supervised_user/core/browser/proto/kidsmanagement_messages.pb.h" #include "components/supervised_user/core/browser/proto/permissions_common.pb.h" #include "components/supervised_user/core/browser/proto/test.pb.h" #include "components/supervised_user/core/browser/proto_fetcher_status.h" #include "components/supervised_user/core/common/supervised_user_constants.h" #include "google_apis/gaia/google_service_auth_error.h" #include "net/base/backoff_entry.h" #include "net/base/request_priority.h" #include "net/http/http_status_code.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/simple_url_loader.h" #include "services/network/public/mojom/fetch_api.mojom-shared.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "third_party/protobuf/src/google/protobuf/message_lite.h" #include "url/gurl.h" namespace supervised_user { // ----------------------------------------------------------------------------- // Usage documentation // ----------------------------------------------------------------------------- // // Overview: ProtoFetcher provides an interface for generic fetchers that // use classes to represent Request and Response objects. The default mechanism // under the hood takes care of the fetch process, including: // * obtaining the right access token, // * serializing the request and parsing the response, // * submitting metrics. // // If you want to create new fetcher factory method, then some // details must be provided in order to enable fetching for said Response. The // new fetcher factory should have at least the following arguments: // signin::IdentityManager, network::SharedURLLoaderFactory, consuming callback // and must reference a static configuration. // // The static configuration should be placed in the fetcher_config.h module. // A stopwatch with two functions: // * measure total elapsed time, // * measure lap time (with automatic resetting after each lap). // The stopwatch is created started. class Stopwatch { … }; // Encapsulates metric functionalities. class Metrics { … }; // Metrics for retrying fetchers, which are aggregating individual // fetchers. class OverallMetrics final : public Metrics { … }; // Uses network::SharedURLLoaderFactory to issue network requests. // Internally, it's a two-phase process: first the access token is fetched, and // if applicable, the remote service is called and the response is processed. // This abstract class doesn't make any assumptions on the request nor response // formats and uses them as bare strings. class AbstractProtoFetcher { … }; // Overlay over ProtoFetcher that interprets successful responses as given // Response type parameter. // Use instance of TypedProtoFetcher to start request and write the result onto // the receiving delegate. Every instance of Fetcher is disposable and should be // used only once. template <typename Response> class TypedProtoFetcher : public AbstractProtoFetcher { … }; // Overlay over ProtoFetcher that only cares about status of the response. // Every instance of Fetcher is disposable and should be // used only once. class StatusFetcher : public AbstractProtoFetcher { … }; // Use instance of ProtoFetcher to create fetch process which is // unstarted yet. template <typename Response> class ProtoFetcher { … }; // A subtype of DeferredProtoFetcher that will take retrying strategy as // specified in FetcherConfig::backoff_policy. // // The retries are only performed on transient errors (see ::ShouldRetry). template <typename Response> class RetryingFetcherImpl final : public ProtoFetcher<Response> { … }; // Component for managing multiple fetches at once. // // After each fetch, the reference kept in internal map is cleared. This will // also happen when this manager is destroyed. In the latter case, callbacks // won't be executed (the pending requests will be canceled). template <typename Request, typename Response> class ParallelFetchManager { … }; // Constructs a fetcher that needs to be launched with ::Start(). The fetcher // will be either one shot or retryable, depending on the // FetcherConfig::backoff_policy setting. // // `args` are only relevant if `fetcher_config` uses template path (see // supervised_user::FetcherConfig::service_path). // // `channel` must be specified if `fetcher_config` has // `CredentialsRequirement::kBestEffort`. template <typename Response> std::unique_ptr<ProtoFetcher<Response>> CreateFetcher( signin::IdentityManager& identity_manager, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, const google::protobuf::MessageLite& request, const FetcherConfig& fetcher_config, const FetcherConfig::PathArgs& args = { … } } // namespace supervised_user #endif // COMPONENTS_SUPERVISED_USER_CORE_BROWSER_PROTO_FETCHER_H_