| // Copyright 2024 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_PLUS_ADDRESSES_PLUS_ADDRESS_SERVICE_IMPL_H_ |
| #define COMPONENTS_PLUS_ADDRESSES_PLUS_ADDRESS_SERVICE_IMPL_H_ |
| |
| #include <memory> |
| #include <optional> |
| #include <string> |
| |
| #include "base/containers/span.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/observer_list.h" |
| #include "base/observer_list_types.h" |
| #include "base/scoped_observation.h" |
| #include "components/autofill/core/browser/integrators/password_form_classification.h" |
| #include "components/autofill/core/browser/integrators/plus_addresses/autofill_plus_address_delegate.h" |
| #include "components/plus_addresses/affiliations/plus_address_affiliation_match_helper.h" |
| #include "components/plus_addresses/metrics/plus_address_submission_logger.h" |
| #include "components/plus_addresses/plus_address_cache.h" |
| #include "components/plus_addresses/plus_address_service.h" |
| #include "components/plus_addresses/plus_address_types.h" |
| #include "components/plus_addresses/settings/plus_address_setting_service.h" |
| #include "components/plus_addresses/webdata/plus_address_webdata_service.h" |
| #include "components/signin/public/identity_manager/account_info.h" |
| #include "components/signin/public/identity_manager/identity_manager.h" |
| #include "components/signin/public/identity_manager/primary_account_change_event.h" |
| #include "components/webdata/common/web_data_service_consumer.h" |
| #include "google_apis/gaia/google_service_auth_error.h" |
| #include "url/origin.h" |
| |
| class PrefService; |
| |
| namespace affiliations { |
| class AffiliationService; |
| } |
| |
| namespace autofill { |
| class FormData; |
| } // namespace autofill |
| |
| namespace signin { |
| class IdentityManager; |
| } // namespace signin |
| |
| namespace plus_addresses { |
| |
| class PlusAddressAllocator; |
| class PlusAddressHttpClient; |
| class PlusAddressSettingService; |
| |
| // An experimental class for filling plus addresses ([email protected]). |
| // Not intended for widespread use. |
| class PlusAddressServiceImpl : public PlusAddressService, |
| public signin::IdentityManager::Observer, |
| public PlusAddressWebDataService::Observer { |
| public: |
| using FeatureEnabledForProfileCheck = |
| base::RepeatingCallback<bool(const base::Feature&)>; |
| |
| PlusAddressServiceImpl( |
| PrefService* pref_service, |
| signin::IdentityManager* identity_manager, |
| PlusAddressSettingService* setting_service, |
| std::unique_ptr<PlusAddressHttpClient> plus_address_http_client, |
| scoped_refptr<PlusAddressWebDataService> webdata_service, |
| affiliations::AffiliationService* affiliation_service, |
| FeatureEnabledForProfileCheck feature_enabled_for_profile_check); |
| ~PlusAddressServiceImpl() override; |
| |
| // autofill::AutofillPlusAddressDelegate: |
| bool IsPlusAddress(const std::string& potential_plus_address) const override; |
| bool MatchesPlusAddressFormat(const std::u16string& value) const override; |
| bool IsPlusAddressFillingEnabled(const url::Origin& origin) const override; |
| bool IsPlusAddressFullFormFillingEnabled() const override; |
| bool IsFieldEligibleForPlusAddress( |
| const autofill::AutofillField& field) const override; |
| void GetAffiliatedPlusAddresses( |
| const url::Origin& origin, |
| base::OnceCallback<void(std::vector<std::string>)> callback) override; |
| std::vector<autofill::Suggestion> GetSuggestionsFromPlusAddresses( |
| const std::vector<std::string>& plus_addresses, |
| const url::Origin& origin, |
| bool is_off_the_record, |
| const autofill::FormData& focused_form, |
| const autofill::FormFieldData& focused_field, |
| const base::flat_map<autofill::FieldGlobalId, autofill::FieldTypeGroup>& |
| form_field_type_groups, |
| const autofill::PasswordFormClassification& focused_form_classification, |
| autofill::AutofillSuggestionTriggerSource trigger_source) override; |
| autofill::Suggestion GetManagePlusAddressSuggestion() const override; |
| void RecordAutofillSuggestionEvent(SuggestionEvent suggestion_event) override; |
| void OnPlusAddressSuggestionShown( |
| autofill::AutofillManager& manager, |
| autofill::FormGlobalId form, |
| autofill::FieldGlobalId field, |
| SuggestionContext suggestion_context, |
| autofill::PasswordFormClassification::Type form_type, |
| autofill::SuggestionType suggestion_type) override; |
| void DidFillPlusAddress() override; |
| size_t GetPlusAddressesCount() override; |
| void OnClickedRefreshInlineSuggestion( |
| const url::Origin& last_committed_primary_main_frame_origin, |
| base::span<const autofill::Suggestion> current_suggestions, |
| size_t current_suggestion_index, |
| UpdateSuggestionsCallback update_suggestions_callback) override; |
| void OnShowedInlineSuggestion( |
| const url::Origin& primary_main_frame_origin, |
| base::span<const autofill::Suggestion> current_suggestions, |
| UpdateSuggestionsCallback update_suggestions_callback) override; |
| void OnAcceptedInlineSuggestion( |
| const url::Origin& primary_main_frame_origin, |
| base::span<const autofill::Suggestion> current_suggestions, |
| size_t current_suggestion_index, |
| UpdateSuggestionsCallback update_suggestions_callback, |
| HideSuggestionsCallback hide_suggestions_callback, |
| PlusAddressCallback fill_field_callback, |
| ShowAffiliationErrorDialogCallback show_affiliation_error_dialog, |
| ShowErrorDialogCallback show_error_dialog, |
| base::OnceClosure reshow_suggestions) override; |
| std::map<std::string, std::string> GetPlusAddressHatsData() const override; |
| |
| // PlusAddressWebDataService::Observer: |
| void OnWebDataChangedBySync( |
| const std::vector<PlusAddressDataChange>& changes) override; |
| |
| void OnWebDataServiceRequestDone(WebDataServiceBase::Handle handle, |
| std::unique_ptr<WDTypedResult> result); |
| |
| // PlusAddressService: |
| void AddObserver(PlusAddressService::Observer* o) override; |
| void RemoveObserver(PlusAddressService::Observer* o) override; |
| bool IsPlusAddressCreationEnabled(const url::Origin& origin, |
| bool is_off_the_record) const override; |
| void GetAffiliatedPlusProfiles(const url::Origin& origin, |
| GetPlusProfilesCallback callback) override; |
| base::span<const PlusProfile> GetPlusProfiles() const override; |
| void ReservePlusAddress(const url::Origin& origin, |
| PlusAddressRequestCallback on_completed) override; |
| void RefreshPlusAddress(const url::Origin& origin, |
| PlusAddressRequestCallback on_completed) override; |
| void ConfirmPlusAddress(const url::Origin& origin, |
| const PlusAddress& plus_address, |
| PlusAddressRequestCallback on_completed) override; |
| bool IsRefreshingSupported(const url::Origin& origin) override; |
| std::optional<PlusAddress> GetPlusAddress( |
| const affiliations::FacetURI& facet) const override; |
| std::optional<PlusProfile> GetPlusProfile( |
| const affiliations::FacetURI& facet) const override; |
| std::optional<std::string> GetPrimaryEmail() override; |
| bool ShouldShowManualFallback(const url::Origin& origin, |
| bool is_off_the_record) const override; |
| void SavePlusProfile(const PlusProfile& profile) override; |
| bool IsEnabled() const override; |
| |
| private: |
| // KeyedService. |
| void Shutdown() override; |
| |
| // signin::IdentityManager::Observer: |
| void OnPrimaryAccountChanged( |
| const signin::PrimaryAccountChangeEvent& event) override; |
| void OnErrorStateOfRefreshTokenUpdatedForAccount( |
| const CoreAccountInfo& account_info, |
| const GoogleServiceAuthError& error, |
| signin_metrics::SourceForRefreshTokenOperation token_operation_source) |
| override; |
| void OnIdentityManagerShutdown( |
| signin::IdentityManager* identity_manager) override; |
| |
| void HandleSignout(); |
| |
| // Analyzes `maybe_profile` and saves it if it is a confirmed plus profile. |
| // Returns `maybe_profile` to make for easier chaining of callbacks. |
| const PlusProfileOrError& HandleCreateOrConfirmResponse( |
| const PlusProfileOrError& maybe_profile); |
| |
| // Checks whether the `origin` supports plus address. |
| // Returns `true` when origin is not opaque, not excluded, and scheme is |
| // http or https. |
| bool IsSupportedOrigin(const url::Origin& origin) const; |
| |
| // Reacts to the server response for confirming a plus address from an inline |
| // suggestion. |
| // - In all cases, it hides the showing suggestions. |
| // - In the success case, it then fills the confirmed plus address. |
| // - In the error case, it shows a modal dialog to either |
| // * fill an affiliated plus address, or |
| // * oinform the user that their quota is exhausted, or |
| // * retry by reshowing the suggestions(e.g. on timeout). |
| void OnConfirmInlineCreation( |
| HideSuggestionsCallback hide_callback, |
| PlusAddressCallback fill_callback, |
| ShowAffiliationErrorDialogCallback show_affiliation_error, |
| ShowErrorDialogCallback show_error, |
| base::OnceClosure reshow_suggestions, |
| const PlusAddress& requested_address, |
| const PlusProfileOrError& profile_or_error); |
| |
| const raw_ref<PrefService> pref_service_; |
| |
| const raw_ref<signin::IdentityManager> identity_manager_; |
| |
| // Allows reading and writing global (i.e. across device and across |
| // application) settings state for plus addresses. |
| const raw_ref<PlusAddressSettingService> setting_service_; |
| |
| metrics::PlusAddressSubmissionLogger submission_logger_; |
| |
| // Handles requests to a remote server that this service uses. |
| std::unique_ptr<PlusAddressHttpClient> plus_address_http_client_; |
| |
| // Responsible for communicating with `PlusAddressTable`. |
| scoped_refptr<PlusAddressWebDataService> webdata_service_; |
| |
| // Responsible for allocating new plus addresses. |
| std::unique_ptr<PlusAddressAllocator> plus_address_allocator_; |
| |
| // Plus profiles in-memory cache. |
| PlusAddressCache plus_address_cache_ GUARDED_BY_CONTEXT(sequence_checker_); |
| |
| // Responsible for supplying a list of plus profiles with domains affiliated |
| // to the the originally requested facet. |
| PlusAddressAffiliationMatchHelper plus_address_match_helper_; |
| |
| // Allows checking whether a group-controlled feature is enabled for the |
| // profile associated with this `KeyedService`. |
| const FeatureEnabledForProfileCheck feature_enabled_for_profile_check_; |
| |
| base::ScopedObservation<signin::IdentityManager, |
| signin::IdentityManager::Observer> |
| identity_manager_observation_{this}; |
| |
| base::ScopedObservation<PlusAddressWebDataService, |
| PlusAddressWebDataService::Observer> |
| webdata_service_observation_{this}; |
| |
| base::ObserverList<PlusAddressService::Observer> observers_; |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| base::WeakPtrFactory<PlusAddressServiceImpl> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace plus_addresses |
| |
| #endif // COMPONENTS_PLUS_ADDRESSES_PLUS_ADDRESS_SERVICE_IMPL_H_ |