1 // Copyright 2020 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef ANDROID_WEBVIEW_BROWSER_METRICS_VISIBILITY_METRICS_LOGGER_H_ 6 #define ANDROID_WEBVIEW_BROWSER_METRICS_VISIBILITY_METRICS_LOGGER_H_ 7 8 #include <map> 9 10 #include "base/callback.h" 11 #include "base/synchronization/lock.h" 12 #include "base/time/time.h" 13 14 namespace base { 15 16 class HistogramBase; 17 18 } // namespace base 19 20 namespace android_webview { 21 22 class VisibilityMetricsLogger { 23 public: 24 struct VisibilityInfo { 25 bool view_attached = false; 26 bool view_visible = false; 27 bool window_visible = false; 28 bool scheme_http_or_https = false; 29 30 bool IsVisible() const; 31 bool ContainsOpenWebContent() const; 32 bool IsDisplayingOpenWebContent() const; 33 }; 34 35 // These values are persisted to logs. Entries should not be renumbered and 36 // numeric values should never be reused. 37 enum class Visibility { 38 kVisible = 0, 39 kNotVisible = 1, 40 kMaxValue = kNotVisible 41 }; 42 43 // These values are persisted to logs. Entries should not be renumbered and 44 // numeric values should never be reused. 45 enum class WebViewOpenWebScreenPortion { 46 kZeroPercent = 0, 47 kTenPercent = 1, 48 kTwentyPercent = 2, 49 kThirtyPercent = 3, 50 kFortyPercent = 4, 51 kFiftyPercent = 5, 52 kSixtyPercent = 6, 53 kSeventyPercent = 7, 54 kEightyPercent = 8, 55 kNinetyPercent = 9, 56 kOneHundredPercent = 10, 57 kMaxValue = kOneHundredPercent 58 }; 59 60 // These values are persisted to logs. Entries should not be renumbered and 61 // numeric values should never be reused. 62 enum class WebViewOpenWebVisibility { 63 kDisplayOpenWebContent = 0, 64 kNotDisplayOpenWebContent = 1, 65 kMaxValue = kNotDisplayOpenWebContent 66 }; 67 68 class Client { 69 public: 70 virtual VisibilityInfo GetVisibilityInfo() = 0; 71 }; 72 73 VisibilityMetricsLogger(); 74 virtual ~VisibilityMetricsLogger(); 75 76 VisibilityMetricsLogger(const VisibilityMetricsLogger&) = delete; 77 VisibilityMetricsLogger& operator=(const VisibilityMetricsLogger&) = delete; 78 79 void AddClient(Client* client); 80 void RemoveClient(Client* client); 81 void ClientVisibilityChanged(Client* client); 82 void UpdateOpenWebScreenArea(int pixels, int percentage); 83 84 void RecordMetrics(); 85 86 // Set a callback that is executed when global visibility changes, i.e. when: 87 // - false => true: no client was visible and one becomes visible. 88 // - true => false: >=1 clients were visible and all became hidden. 89 using OnVisibilityChangedCallback = 90 base::RepeatingCallback<void(bool /*visible*/)>; 91 void SetOnVisibilityChangedCallback(OnVisibilityChangedCallback); 92 93 private: 94 static base::HistogramBase* GetGlobalVisibilityHistogram(); 95 static base::HistogramBase* GetPerWebViewVisibilityHistogram(); 96 static base::HistogramBase* GetGlobalOpenWebVisibilityHistogram(); 97 static base::HistogramBase* GetPerWebViewOpenWebVisibilityHistogram(); 98 static base::HistogramBase* GetOpenWebVisibileScreenPortionHistogram(); 99 static base::HistogramBase* CreateHistogramForDurationTracking( 100 const char* name, 101 int max_value); 102 103 void UpdateDurations(base::TimeTicks update_time); 104 void ProcessClientUpdate(Client* client, const VisibilityInfo& info); 105 bool IsVisible(const VisibilityInfo& info); 106 bool IsDisplayingOpenWebContent(const VisibilityInfo& info); 107 void RecordVisibilityMetrics(); 108 void RecordOpenWebDisplayMetrics(); 109 void RecordScreenPortionMetrics(); 110 111 // Counter for visible clients 112 size_t visible_client_count_ = 0; 113 // Counter for visible web clients 114 size_t visible_webcontent_client_count_ = 0; 115 116 struct WebViewDurationTracker { 117 // Duration any WebView meets the tracking criteria 118 base::TimeDelta any_webview_tracked_duration_ = 119 base::TimeDelta::FromSeconds(0); 120 // Duration no WebViews meet the tracking criteria 121 base::TimeDelta no_webview_tracked_duration_ = 122 base::TimeDelta::FromSeconds(0); 123 // Total duration that WebViews meet the tracking criteria (i.e. if 124 // 2x WebViews meet the criteria for 1 second then increment by 2 seconds) 125 base::TimeDelta per_webview_duration_ = base::TimeDelta::FromSeconds(0); 126 // Total duration that WebViews exist but do not meet the tracking criteria 127 base::TimeDelta per_webview_untracked_duration_ = 128 base::TimeDelta::FromSeconds(0); 129 }; 130 131 WebViewDurationTracker visible_duration_tracker_; 132 WebViewDurationTracker webcontent_visible_tracker_; 133 134 base::TimeTicks last_update_time_; 135 std::map<Client*, VisibilityInfo> client_visibility_; 136 137 int open_web_screen_area_pixels_ = 0; 138 int open_web_screen_area_percentage_ = 0; 139 WebViewOpenWebScreenPortion current_open_web_screen_portion_ = 140 WebViewOpenWebScreenPortion::kZeroPercent; 141 base::TimeDelta open_web_screen_portion_tracked_duration_ 142 [static_cast<size_t>(WebViewOpenWebScreenPortion::kMaxValue) + 1] = {}; 143 144 OnVisibilityChangedCallback on_visibility_changed_callback_; 145 }; 146 147 } // namespace android_webview 148 149 #endif // ANDROID_WEBVIEW_BROWSER_METRICS_VISIBILITY_METRICS_LOGGER_H_ 150