| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_WEBCONTENTS_OBSERVER_H_ |
| #define CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_WEBCONTENTS_OBSERVER_H_ |
| |
| #include "base/macros.h" |
| #include "base/sequence_checker.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/resource_coordinator/local_site_characteristics_data_writer.h" |
| #include "chrome/browser/resource_coordinator/page_signal_receiver.h" |
| #include "chrome/browser/resource_coordinator/tab_load_tracker.h" |
| #include "content/public/browser/visibility.h" |
| #include "content/public/browser/web_contents_observer.h" |
| #include "url/origin.h" |
| |
| namespace content { |
| class NavigationHandle; |
| } |
| |
| namespace resource_coordinator { |
| |
| // WebContents observer that manages a SiteCharacteristicsDataWriter associated |
| // with a WebContents and forwards the appropriate events to it. |
| class LocalSiteCharacteristicsWebContentsObserver |
| : public content::WebContentsObserver, |
| public TabLoadTracker::Observer, |
| public PageSignalObserver { |
| public: |
| // Allows skipping the observer registration in the constructor for the |
| // unittests that don't have all the services enabled |
| // (e.g. PageSignalReceiver), these features should be tested in integration |
| // tests instead. |
| static void SkipObserverRegistrationForTesting(); |
| |
| explicit LocalSiteCharacteristicsWebContentsObserver( |
| content::WebContents* contents); |
| ~LocalSiteCharacteristicsWebContentsObserver() override; |
| |
| // WebContentsObserver implementation. |
| void OnVisibilityChanged(content::Visibility visibility) override; |
| void WebContentsDestroyed() override; |
| void DidFinishNavigation( |
| content::NavigationHandle* navigation_handle) override; |
| void TitleWasSet(content::NavigationEntry* entry) override; |
| void DidUpdateFaviconURL( |
| const std::vector<content::FaviconURL>& candidates) override; |
| void OnAudioStateChanged(bool audible) override; |
| |
| // TabLoadTracker::Observer: |
| void OnLoadingStateChange(content::WebContents* web_contents, |
| LoadingState old_loading_state, |
| LoadingState new_loading_state) override; |
| |
| // PageSignalObserver: |
| void OnNonPersistentNotificationCreated( |
| content::WebContents* web_contents, |
| const PageNavigationIdentity& page_navigation_id) override; |
| void OnLoadTimePerformanceEstimate( |
| content::WebContents* web_contents, |
| const PageNavigationIdentity& page_navigation_id, |
| base::TimeDelta load_duration, |
| base::TimeDelta cpu_usage_estimate, |
| uint64_t private_footprint_kb_estimate) override; |
| |
| SiteCharacteristicsDataWriter* GetWriterForTesting() const { |
| return writer_.get(); |
| } |
| url::Origin GetWriterOriginForTesting() const { return writer_origin_; } |
| void ResetWriterForTesting() { writer_.reset(); } |
| |
| void SetPageSignalReceiverForTesting(PageSignalReceiver* receiver) { |
| page_signal_receiver_ = receiver; |
| } |
| |
| private: |
| enum class FeatureType { |
| kTitleChange, |
| kFaviconChange, |
| kAudioUsage, |
| kNotificationUsage, |
| }; |
| |
| // Indicates if the feature usage event just received should be ignored. |
| bool ShouldIgnoreFeatureUsageEvent(FeatureType feature_type); |
| |
| // Helper function to maybe notify |writer_| that a feature event has been |
| // received while in background. Doesn't do anything if |
| // ShouldIgnoreFeatureUsageEvent returns true. |
| void MaybeNotifyBackgroundFeatureUsage( |
| void (SiteCharacteristicsDataWriter::*method)(), |
| FeatureType feature_type); |
| |
| // Function to call when the site switch to the loaded state. |
| void OnSiteLoaded(); |
| |
| // Updates |backgrounded_time_| based on |visibility|. |
| void UpdateBackgroundedTime(TabVisibility visibility); |
| |
| // The writer that processes the event received by this class. |
| std::unique_ptr<SiteCharacteristicsDataWriter> writer_; |
| |
| // The Origin tracked by the writer. |
| url::Origin writer_origin_; |
| |
| // Favicon and title are set when a page is loaded, we only want to send |
| // signals to the database about title and favicon update from the previous |
| // title and favicon, thus we want to ignore the very first update since it is |
| // always supposed to happen. |
| bool first_time_favicon_set_ = false; |
| bool first_time_title_set_ = false; |
| |
| // The PageSignalReceiver observed by this instance. |
| PageSignalReceiver* page_signal_receiver_ = nullptr; |
| |
| // The time at which this tab switched to the loaded state, null if this tab |
| // is not currently loaded. |
| base::TimeTicks loaded_time_; |
| |
| // The time at which this tab has been backgrounded, null if this tab is |
| // currently visible. |
| base::TimeTicks backgrounded_time_; |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| DISALLOW_COPY_AND_ASSIGN(LocalSiteCharacteristicsWebContentsObserver); |
| }; |
| |
| } // namespace resource_coordinator |
| |
| #endif // CHROME_BROWSER_RESOURCE_COORDINATOR_LOCAL_SITE_CHARACTERISTICS_WEBCONTENTS_OBSERVER_H_ |