| // Copyright 2020 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_SAFE_BROWSING_CONTENT_BROWSER_CLIENT_SIDE_DETECTION_HOST_H_ |
| #define COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_CLIENT_SIDE_DETECTION_HOST_H_ |
| |
| #include <stddef.h> |
| |
| #include <cstdint> |
| #include <memory> |
| #include <optional> |
| #include <string> |
| |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/time/time.h" |
| #include "base/unguessable_token.h" |
| #include "components/autofill/core/browser/foundations/scoped_autofill_managers_observation.h" |
| #include "components/permissions/permission_request_manager.h" |
| #include "components/safe_browsing/content/browser/async_check_tracker.h" |
| #include "components/safe_browsing/content/common/safe_browsing.mojom.h" |
| #include "components/safe_browsing/core/browser/client_side_detection_host_base.h" |
| #include "components/safe_browsing/core/browser/credit_card_form_event.h" |
| #include "components/safe_browsing/core/browser/intelligent_scan_delegate.h" |
| #include "components/safe_browsing/core/common/visual_utils.h" |
| #include "content/public/browser/global_routing_id.h" |
| #include "content/public/browser/web_contents_observer.h" |
| #include "mojo/public/cpp/base/proto_wrapper.h" |
| #include "mojo/public/cpp/bindings/associated_remote.h" |
| #include "net/http/http_status_code.h" |
| #include "url/gurl.h" |
| |
| #if BUILDFLAG(IS_ANDROID) |
| #include "components/safe_browsing/core/browser/referring_app_info.h" // nogncheck |
| #endif |
| |
| class PrefService; |
| class SkBitmap; |
| |
| namespace history { |
| class HistoryService; |
| } |
| |
| namespace safe_browsing { |
| class BaseUIManager; |
| class ClientPhishingRequest; |
| class ClientSideDetectionService; |
| class SafeBrowsingDatabaseManager; |
| class SafeBrowsingTokenFetcher; |
| class VerdictCacheManager; |
| |
| // This class is used to receive the IPC from the renderer which |
| // notifies the browser that a URL was classified as phishing. This |
| // class relays this information to the client-side detection service |
| // class which sends a ping to a server to validate the verdict. |
| class ClientSideDetectionHost |
| : public ClientSideDetectionHostBase, |
| public content::WebContentsObserver, |
| public permissions::PermissionRequestManager::Observer, |
| public AsyncCheckTracker::Observer { |
| public: |
| using AsyncCheckTriggerForceRequestResult = |
| ClientSideDetectionHostBase::AsyncCheckTriggerForceRequestResult; |
| |
| // ClientSideDetectionHostBase overrides: |
| GURL GetCurrentUrl() const override; |
| ClientSideDetectionFeatureCacheBase* GetFeatureCache() override; |
| std::vector<GURL> GetRedirectChain() override; |
| safe_browsing::credit_card_form::ReferringApp GetReferringApp() |
| const override; |
| ChromeUserPopulation GetUserPopulation() override; |
| bool IsAccountSignedIn() override; |
| bool IsErrorDocument() override; |
| std::optional<double> GetSiteEngagementScore(const GURL& url) const override; |
| void GetInnerText(HostInnerTextCallback callback) override; |
| void MaybeStartImageEmbedding( |
| std::unique_ptr<ClientPhishingRequest> verdict, |
| std::optional<bool> did_match_high_confidence_allowlist, |
| bool is_invalid_ip, |
| PhishingDetectorResult result) override; |
| void MaybeRunUserReportCallback() override; |
| void MaybeStartGeminiAntiscamProtection( |
| GURL url, |
| ClientSideDetectionType request_type, |
| std::optional<bool> did_match_high_confidence_allowlist) override; |
| void MaybeStartPreClassification( |
| safe_browsing::ClientSideDetectionType request_type) override; |
| |
| // These values are persisted to logs. Entries should not be renumbered and |
| // numeric values should never be reused. |
| enum class CSDObserverCalled { |
| kOnFirstContentfulPaint = 0, |
| kDidFirstVisuallyNonEmptyPaint = 1, |
| kMaxValue = kDidFirstVisuallyNonEmptyPaint, |
| }; |
| |
| // A callback via which the client of this component indicates whether the |
| // primary account is signed in. |
| using PrimaryAccountSignedIn = base::RepeatingCallback<bool()>; |
| |
| // Callback for when preclassification is started. |
| using PreclassificationStarted = |
| base::RepeatingCallback<void(ClientSideDetectionType)>; |
| |
| // Delegate which allows to provide embedder specific implementations. |
| class Delegate { |
| public: |
| virtual ~Delegate() = default; |
| |
| // Returns whether there is a SafeBrowsingUserInteractionObserver available. |
| virtual bool HasSafeBrowsingUserInteractionObserver() = 0; |
| virtual scoped_refptr<SafeBrowsingDatabaseManager> |
| GetSafeBrowsingDBManager() = 0; |
| virtual scoped_refptr<BaseUIManager> GetSafeBrowsingUIManager() = 0; |
| virtual void AddReferrerChain(ClientPhishingRequest* verdict, |
| GURL current_url, |
| const content::GlobalRenderFrameHostId& |
| current_outermost_main_frame_id) = 0; |
| // Returns the management status for current profile. |
| virtual ChromeUserPopulation GetUserPopulation() = 0; |
| // Returns the inner text from the tab, which is combined inner-text of all |
| // suitable iframes . The callback is used to retrieve a string back from |
| // the delegate when the inner text function is completed. This string is |
| // then used to provide the intelligent scan delegate the information about |
| // the page. |
| virtual void GetInnerText(HostInnerTextCallback callback) = 0; |
| // Triggers Gemini Antiscam Protection if conditions are met. |
| virtual void MaybeStartGeminiAntiscamProtection( |
| GURL url, |
| ClientSideDetectionType request_type, |
| std::optional<bool> did_match_high_confidence_allowlist) = 0; |
| |
| #if BUILDFLAG(IS_ANDROID) |
| virtual internal::ReferringAppInfo GetReferringAppInfo( |
| content::WebContents* web_contents) = 0; |
| #endif |
| }; |
| |
| static const int kMaxHighResScreenshotWidth; |
| static const int kMaxHighResScreenshotHeight; |
| |
| // The caller keeps ownership of the tab object and is responsible for |
| // ensuring that it stays valid until WebContentsDestroyed is called. |
| // The caller also keeps ownership of pref_service. The |
| // ClientSideDetectionHost takes ownership of token_fetcher. is_off_the_record |
| // indicates if the profile is incognito, and account_signed_in_callback is |
| // checked to find out if primary account is signed in. |
| static std::unique_ptr<ClientSideDetectionHost> Create( |
| content::WebContents* tab, |
| std::unique_ptr<Delegate> delegate, |
| IntelligentScanDelegate* intelligent_scan_delegate, |
| PrefService* pref_service, |
| VerdictCacheManager* cache_manager, |
| history::HistoryService* history_service, |
| base::WeakPtr<ClientSideDetectionService> csd_service, |
| std::unique_ptr<SafeBrowsingTokenFetcher> token_fetcher, |
| bool is_off_the_record, |
| const PrimaryAccountSignedIn& account_signed_in_callback); |
| |
| ClientSideDetectionHost(const ClientSideDetectionHost&) = delete; |
| ClientSideDetectionHost& operator=(const ClientSideDetectionHost&) = delete; |
| |
| ~ClientSideDetectionHost() override; |
| |
| // From content::WebContentsObserver. If we navigate away we cancel all |
| // pending callbacks that could show an interstitial, and check to see whether |
| // we should classify the new URL. If a request to lock the keyboard or |
| // pointer or vibrate the page has arrived, we will re-trigger classification. |
| void DidFinishNavigation( |
| content::NavigationHandle* navigation_handle) override; |
| void PrimaryPageChanged(content::Page& page) override; |
| void KeyboardLockRequested() override; |
| void VibrationRequested() override; |
| void OnTextCopiedToClipboard(content::RenderFrameHost* render_frame_host, |
| const std::u16string& copied_text) override; |
| void DidFirstVisuallyNonEmptyPaint() override; |
| void OnFirstContentfulPaintInPrimaryMainFrame( |
| base::TimeTicks presentation_time) override; |
| |
| // permissions::PermissionRequestManager::Observer methods: |
| void OnPromptAdded() override; |
| void OnPermissionRequestManagerDestructed() override; |
| |
| void RegisterPermissionRequestManager(); |
| |
| // AsyncCheckTracker::Observer methods: |
| void OnAsyncSafeBrowsingCheckCompleted() override; |
| void OnAsyncSafeBrowsingCheckTrackerDestructed() override; |
| |
| void RegisterAsyncCheckTracker(); |
| |
| |
| |
| void RegisterAutofillManager(); |
| |
| // User requests to report a site as unsafe. The screenshot values come from |
| // the report dialog view. |
| void ReportUnsafeSite(SkBitmap screenshot, base::OnceClosure callback); |
| |
| // Called when an unfamiliar login page is detected (e.g. via password field |
| // focus). |
| void OnUnfamiliarLoginPageDetected(); |
| |
| // Sets a callback to be notified when preclassification is started. |
| void set_preclassification_started_callback_for_testing( |
| const PreclassificationStarted& callback) { |
| preclassification_started_cb_for_testing_ = callback; |
| } |
| |
| protected: |
| explicit ClientSideDetectionHost( |
| content::WebContents* tab, |
| std::unique_ptr<Delegate> delegate, |
| IntelligentScanDelegate* intelligent_scan_delegate, |
| PrefService* pref_service, |
| VerdictCacheManager* cache_manager, |
| history::HistoryService* history_service, |
| base::WeakPtr<ClientSideDetectionService> csd_service, |
| std::unique_ptr<SafeBrowsingTokenFetcher> token_fetcher, |
| bool is_off_the_record, |
| const PrimaryAccountSignedIn& account_signed_in_callback); |
| |
| // Used for testing. |
| void set_ui_manager(BaseUIManager* ui_manager); |
| void set_database_manager(SafeBrowsingDatabaseManager* database_manager); |
| |
| private: |
| friend class ClientSideDetectionHostTestBase; |
| friend class ClientSideDetectionHostNotificationTest; |
| friend class ClientSideDetectionHostScamDetectionTest; |
| friend class ClientSideDetectionHostCreditCardFormTest; |
| friend class ClientSideDetectionHostClipboardDataTest; |
| friend class ClientSideDetectionHostGeminiAntiscamProtectionTest; |
| friend class ClientSideDetectionHostPriorityTest; |
| friend class ClientSideDetectionHostPrerenderBrowserTest; |
| friend class ClientSideDetectionHostPrerenderBrowserTest_Screenshot; |
| class ShouldClassifyUrlRequest; |
| friend class ShouldClassifyUrlRequest; |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostPrerenderBrowserTest, |
| PrerenderShouldNotAffectClientSideDetection); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostPrerenderBrowserTest, |
| SamePageNavigationShouldNotAffectClientSideDetection); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostPrerenderBrowserTest, |
| ClassifyPrerenderedPageAfterActivation); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostPrerenderBrowserTest, |
| ClassifyPrerenderedPageAfterActivationAndCheckDebuggingMetadataCache); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostPrerenderBrowserTest, |
| CheckDebuggingMetadataCacheAfterClearingCacheAfterNavigation); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostPrerenderExclusiveAccessBrowserTest, |
| KeyboardLockTriggersPreclassificationCheck); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostPrerenderExclusiveAccessBrowserTest, |
| PointerLockTriggersPreClassificationCheck); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostPrerenderExclusiveAccessBrowserTest, |
| PointerLockClassificationTriggersCSPPPing); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostPrerenderExclusiveAccessBrowserTest, |
| KeyboardLockClassificationTriggersCSPPPing); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostTest, |
| SkipsImageEmbeddingIfAlreadyPresent); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostTest, |
| TwoKeyboardLockRequestsOnSamePageOnlyLogsOnePreclassificationCheck); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostVibrateTest, |
| VibrationApiTriggersPreclassificationCheck); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostVibrateTest, |
| VibrationApiClassificationTriggersCSPPPing); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostTest, |
| TestPreClassificationCheckMatchHighConfidenceAllowlist); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostTest, |
| TestPreClassificationCheckDoesNotMatchHighConfidenceAllowlist); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostTest, |
| TestPreClassificationCheckDoesNotMatchHighConfidenceAllowlistDueToDisabledFeature); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostSkipImageClassificationScoringTest, |
| NeverSkipWhenFeatureDisabled); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostSkipImageClassificationScoringTest, |
| TriggerModelsDoesNotSkipWhenFeatureIsEnabled); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostSkipImageClassificationScoringTest, |
| AllOtherTypesSkipWhenFeatureIsEnabled); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionRTLookupResponseForceRequestTest, |
| AsyncCheckTrackerTriggersClassificationRequestOnAllowlistMatch); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostClipboardTest, |
| ClipboardApiTriggersPreclassificationCheck); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostClipboardTest, |
| ClipboardApiClassificationTriggersCSPPPing); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostCreditCardFormTest, |
| NonCreditCardFormDoesNotTriggerPreclassificationChecks); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostCreditCardFormTest, |
| UnclassifiedFormDoesNotTriggerPreclassificationChecks); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostCreditCardFormTest, |
| FeatureDisabledDoesNotTriggerPreclassificationChecks); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostCreditCardFormTest, |
| WhenESBDisabledDoesNotTriggerPreclassificationChecks); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostCreditCardFormTest, |
| EventDoesNotTriggerPreclassificationChecksWhenESBDisabled); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostCreditCardFormTest, |
| DoesNotStartPreclassificationOnRepeatSiteVisit); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostCreditCardFormTest, |
| IgnoresVisitsInPastTenMinutes); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostCreditCardFormTest, |
| DoesNotStartPreclassificationOnServerHeuristic); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostCreditCardFormReferringAppTest, |
| DoesNotStartPreclassificationBecauseOfReferringAppFilter); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostCreditCardFormTest, |
| PreclassificationIsDedupedByURL); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostCreditCardFormTest, |
| CreditCardFormTriggersPreclassificationCheck); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostCreditCardFormTest, |
| CreditCardFormClassificationTriggersCSDPing); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostBrowserTest, |
| NavigateTo404PageLogsErrorDocument); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostGeminiAntiscamProtectionTest, |
| GeminiAntiscamProtectionServiceCalledWithInnerText); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostCreditCardFormTriggerDisabledTest, |
| InteractionTriggerDisabledDoesNotTrigger); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostCreditCardFormDetectionOnlyTest, |
| CreditCardFormTriggersDetectionCheckWithoutInteraction); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostCreditCardFormDetectionTriggerDisabledTest, |
| DetectionTriggerDisabledDoesNotTrigger); |
| FRIEND_TEST_ALL_PREFIXES( |
| ClientSideDetectionHostCreditCardFormDetectionAndInteractionTest, |
| DetectionAndInteractionTriggersOnlyTriggerOnce); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostNewObserversForceRequestTest, |
| TestTriggerModelsConvertedToForceRequestAtLoad); |
| FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostNewObserversForceRequestTest, |
| TestTriggerModelsConvertedToForceRequestAtRequest); |
| |
| // ClientSideDetectionHostBase overrides: |
| void CancelPendingRequests() override; |
| void ShowBlockingPage( |
| GURL phishing_url, |
| ClientSideDetectionType request_type, |
| std::optional<IntelligentScanVerdict> intelligent_scan_verdict, |
| bool should_show_scam_warning) override; |
| void UpdateDebuggingMetadataWithNetworkResult( |
| GURL phishing_url, |
| net::HttpStatusCode response_code) override; |
| void AddReferrerChain(ClientPhishingRequest* verdict) override; |
| void MaybeFillScreenshotData(ClientPhishingRequest* request) override; |
| void AddMiscellaneousMetadataToClientPhishingRequest( |
| ClientPhishingRequest* verdict, |
| bool is_invalid_ip) override; |
| |
| // Called when pre-classification checks are done for the phishing |
| // classifiers. |request_type| is passed in to specify the process that |
| // requests the classification. |is_invalid_ip| is a temporary field to pass |
| // along the result of the local resource check. |
| // TODO: Remove the parameter is_invalid_ip once the feature flag, |
| // kClientSideDetectionLocalResourceCheckFix, is removed. |
| void OnPhishingPreClassificationDone( |
| ClientSideDetectionType request_type, |
| bool should_classify, |
| bool is_sample_ping, |
| std::optional<bool> did_match_high_confidence_allowlist, |
| bool is_invalid_ip); |
| |
| // Note: This method has the same name as the one in the base class but |
| // different parameter types (Mojo types). It converts them and calls the |
| // base class method. |
| void PhishingDetectionDone( |
| ClientSideDetectionType request_type, |
| bool is_sample_ping, |
| std::optional<bool> did_match_high_confidence_allowlist, |
| bool is_invalid_ip, |
| base::TimeTicks start_time, |
| mojom::PhishingDetectorResult result, |
| std::optional<mojo_base::ProtoWrapper> verdict); |
| |
| // Determines visual features extraction capabilities. |
| // `can_extract_visual_features_result` will be used to handle visual features |
| // in ClientPhishingRequest after. |
| visual_utils::CanExtractVisualFeaturesResult |
| DetermineVisualFeaturesExtraction(); |
| |
| // |verdict| is an encoded ClientPhishingRequest protocol message, |result| is |
| // the outcome of the renderer image embedding. The verdict is passed into |
| // this function after the renderer classification is finished. |
| // TODO: Remove the parameter is_invalid_ip once the feature flag, |
| // kClientSideDetectionLocalResourceCheckFix, is removed. |
| void PhishingImageEmbeddingDone( |
| std::unique_ptr<ClientPhishingRequest> verdict, |
| std::optional<bool> did_match_high_confidence_allowlist, |
| bool is_invalid_ip, |
| mojom::PhishingImageEmbeddingResult result, |
| std::optional<mojo_base::ProtoWrapper> image_feature_embedding, |
| std::optional<mojo_base::ProtoWrapper> visual_features); |
| |
| // Sets the primary account signed in callback for testing. |
| void set_account_signed_in_for_testing( |
| const PrimaryAccountSignedIn& account_signed_in_callback) { |
| account_signed_in_callback_ = account_signed_in_callback; |
| } |
| |
| void set_delegate_for_testing(std::unique_ptr<Delegate> delegate) { |
| delegate_ = std::move(delegate); |
| } |
| |
| // Callback for when preclassification is done. |
| using PreclassificationDone = |
| base::RepeatingCallback<void(ClientSideDetectionType)>; |
| |
| // Sets a callback to be notified when preclassification is done. |
| void set_preclassification_done_callback_for_testing( |
| const PreclassificationDone& callback) { |
| preclassification_done_cb_for_testing_ = callback; |
| } |
| |
| // Returns true if phishing detection should not proceed beyond |
| // preclassification. The purpose of triggering only preclassification is to |
| // have an initial assessment on how often we'll be hitting the allowlist and |
| // triggering the classification. Detection should not go further than |
| // recording metrics. |
| bool ShouldStopAtPreClassification(); |
| |
| // The callback for the report a scam dialog. |
| base::OnceClosure user_report_callback_; |
| |
| // Timer to call the user report callback. |
| base::OneShotTimer user_report_timeout_timer_; |
| |
| // The WebContents that the class is observing. |
| raw_ptr<content::WebContents> tab_; |
| // These pointers may be nullptr if SafeBrowsing is disabled. |
| scoped_refptr<SafeBrowsingDatabaseManager> database_manager_; |
| scoped_refptr<BaseUIManager> ui_manager_; |
| // Keep a handle to the latest classification request so that we can cancel |
| // it if necessary. |
| std::unique_ptr<ShouldClassifyUrlRequest> classification_request_; |
| // The current outermost main frame's id. |
| content::GlobalRenderFrameHostId current_outermost_main_frame_id_; |
| // The navigation ID that commits the current URL. Used to set UnsafeResource. |
| int64_t current_navigation_id_; |
| |
| // The last URL that the fullscreen API was called. This is used because the |
| // DidToggleFullscreenModeForTab can be called for both entering and exiting |
| // fullscreen. |
| GURL last_fullscreen_url_; |
| |
| // `did_first_visually_non_empty_paint_` becomes true after the first paint |
| // that is not the background color. `on_first_contentful_paint_` becomes |
| // true after the browser renders the first content from the DOM (e.g., |
| // text or an image). |
| // |
| // Client-side detection for TRIGGER_MODELS will only start after both events |
| // have occurred. This ensures that classification doesn't begin before the |
| // page has meaningfully rendered. These flags are reset on each new main |
| // frame navigation. |
| bool did_first_visually_non_empty_paint_ = false; |
| bool on_first_contentful_paint_ = false; |
| |
| std::unique_ptr<Delegate> delegate_; |
| |
| // Callback for checking if the user is signed in, before fetching |
| // acces_token. |
| PrimaryAccountSignedIn account_signed_in_callback_; |
| |
| // The remote for the currently active phishing classification. |
| mojo::AssociatedRemote<mojom::PhishingDetector> phishing_detector_; |
| |
| // The remote for the currently active phishing image embedder. |
| mojo::AssociatedRemote<mojom::PhishingImageEmbedderDetector> |
| phishing_image_embedder_; |
| |
| base::ScopedObservation<permissions::PermissionRequestManager, |
| permissions::PermissionRequestManager::Observer> |
| permission_request_observation_{this}; |
| |
| // A boolean indicates whether TRIGGER_MODELS request is sent via |
| // FORCE_REQUEST. This is used to decide whether async check is allowed to |
| |
| base::ScopedObservation<AsyncCheckTracker, AsyncCheckTracker::Observer> |
| async_check_observation_{this}; |
| |
| // Manages lifetime registration of this instance as an |
| // AutofillManager::Observer. |
| autofill::ScopedAutofillManagersObservation autofill_managers_observation_{ |
| this}; |
| |
| // Callback settable by tests for verifying whether |
| // MaybeStartPreClassification resulted in starting preclassification. |
| PreclassificationStarted preclassification_started_cb_for_testing_; |
| |
| // Callback settable by tests for verifying whether |
| // OnPhishingPreClassificationDone was called at the end of preclassification. |
| PreclassificationDone preclassification_done_cb_for_testing_; |
| |
| // The high resolution screenshot of the current tab. Should only be populated |
| // when a user reports a site as unsafe. |
| std::optional<SkBitmap> screenshot_; |
| |
| base::WeakPtrFactory<ClientSideDetectionHost> weak_factory_{this}; |
| }; |
| |
| } // namespace safe_browsing |
| |
| #endif // COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_CLIENT_SIDE_DETECTION_HOST_H_ |