| // Copyright 2020 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 ANDROID_WEBVIEW_BROWSER_METRICS_VISIBILITY_METRICS_LOGGER_H_ |
| #define ANDROID_WEBVIEW_BROWSER_METRICS_VISIBILITY_METRICS_LOGGER_H_ |
| |
| #include <map> |
| |
| #include "base/callback.h" |
| #include "base/synchronization/lock.h" |
| #include "base/time/time.h" |
| |
| namespace base { |
| |
| class HistogramBase; |
| |
| } // namespace base |
| |
| namespace android_webview { |
| |
| class VisibilityMetricsLogger { |
| public: |
| struct VisibilityInfo { |
| bool view_attached = false; |
| bool view_visible = false; |
| bool window_visible = false; |
| bool scheme_http_or_https = false; |
| |
| bool IsVisible() const; |
| bool ContainsOpenWebContent() const; |
| bool IsDisplayingOpenWebContent() const; |
| }; |
| |
| // These values are persisted to logs. Entries should not be renumbered and |
| // numeric values should never be reused. |
| enum class Visibility { |
| kVisible = 0, |
| kNotVisible = 1, |
| kMaxValue = kNotVisible |
| }; |
| |
| // These values are persisted to logs. Entries should not be renumbered and |
| // numeric values should never be reused. |
| enum class WebViewOpenWebScreenPortion { |
| kZeroPercent = 0, |
| kTenPercent = 1, |
| kTwentyPercent = 2, |
| kThirtyPercent = 3, |
| kFortyPercent = 4, |
| kFiftyPercent = 5, |
| kSixtyPercent = 6, |
| kSeventyPercent = 7, |
| kEightyPercent = 8, |
| kNinetyPercent = 9, |
| kOneHundredPercent = 10, |
| kExactlyZeroPercent = 11, |
| kMaxValue = kExactlyZeroPercent, |
| }; |
| |
| // These values are persisted to logs. Entries should not be renumbered and |
| // numeric values should never be reused. |
| enum class WebViewOpenWebVisibility { |
| kDisplayOpenWebContent = 0, |
| kNotDisplayOpenWebContent = 1, |
| kMaxValue = kNotDisplayOpenWebContent |
| }; |
| |
| class Client { |
| public: |
| virtual VisibilityInfo GetVisibilityInfo() = 0; |
| }; |
| |
| VisibilityMetricsLogger(); |
| virtual ~VisibilityMetricsLogger(); |
| |
| VisibilityMetricsLogger(const VisibilityMetricsLogger&) = delete; |
| VisibilityMetricsLogger& operator=(const VisibilityMetricsLogger&) = delete; |
| |
| void AddClient(Client* client); |
| void RemoveClient(Client* client); |
| void ClientVisibilityChanged(Client* client); |
| void UpdateOpenWebScreenArea(int pixels, int percentage); |
| |
| void RecordMetrics(); |
| |
| // Set a callback that is executed when global visibility changes, i.e. when: |
| // - false => true: no client was visible and one becomes visible. |
| // - true => false: >=1 clients were visible and all became hidden. |
| using OnVisibilityChangedCallback = |
| base::RepeatingCallback<void(bool /*visible*/)>; |
| void SetOnVisibilityChangedCallback(OnVisibilityChangedCallback); |
| |
| private: |
| static base::HistogramBase* GetGlobalVisibilityHistogram(); |
| static base::HistogramBase* GetPerWebViewVisibilityHistogram(); |
| static base::HistogramBase* GetGlobalOpenWebVisibilityHistogram(); |
| static base::HistogramBase* GetPerWebViewOpenWebVisibilityHistogram(); |
| static base::HistogramBase* GetOpenWebVisibileScreenPortionHistogram(); |
| static base::HistogramBase* CreateHistogramForDurationTracking( |
| const char* name, |
| int max_value); |
| |
| void UpdateDurations(base::TimeTicks update_time); |
| void ProcessClientUpdate(Client* client, const VisibilityInfo& info); |
| bool IsVisible(const VisibilityInfo& info); |
| bool IsDisplayingOpenWebContent(const VisibilityInfo& info); |
| void RecordVisibilityMetrics(); |
| void RecordOpenWebDisplayMetrics(); |
| void RecordScreenPortionMetrics(); |
| |
| // Counter for visible clients |
| size_t visible_client_count_ = 0; |
| // Counter for visible web clients |
| size_t visible_webcontent_client_count_ = 0; |
| |
| struct WebViewDurationTracker { |
| // Duration any WebView meets the tracking criteria |
| base::TimeDelta any_webview_tracked_duration_ = base::Seconds(0); |
| // Duration no WebViews meet the tracking criteria |
| base::TimeDelta no_webview_tracked_duration_ = base::Seconds(0); |
| // Total duration that WebViews meet the tracking criteria (i.e. if |
| // 2x WebViews meet the criteria for 1 second then increment by 2 seconds) |
| base::TimeDelta per_webview_duration_ = base::Seconds(0); |
| // Total duration that WebViews exist but do not meet the tracking criteria |
| base::TimeDelta per_webview_untracked_duration_ = base::Seconds(0); |
| }; |
| |
| WebViewDurationTracker visible_duration_tracker_; |
| WebViewDurationTracker webcontent_visible_tracker_; |
| |
| base::TimeTicks last_update_time_; |
| std::map<Client*, VisibilityInfo> client_visibility_; |
| |
| int open_web_screen_area_pixels_ = 0; |
| int open_web_screen_area_percentage_ = 0; |
| WebViewOpenWebScreenPortion current_open_web_screen_portion_ = |
| WebViewOpenWebScreenPortion::kZeroPercent; |
| base::TimeDelta open_web_screen_portion_tracked_duration_ |
| [static_cast<size_t>(WebViewOpenWebScreenPortion::kMaxValue) + 1] = {}; |
| |
| OnVisibilityChangedCallback on_visibility_changed_callback_; |
| }; |
| |
| } // namespace android_webview |
| |
| #endif // ANDROID_WEBVIEW_BROWSER_METRICS_VISIBILITY_METRICS_LOGGER_H_ |