Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: third_party/WebKit/Source/core/html/AutoplayUmaHelper.cpp

Issue 2463113002: Let AutoplayUmaHelper listen to visibilitychange instead of unload (Closed)
Patch Set: ContextLifecycleObserver Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/html/AutoplayUmaHelper.h" 5 #include "core/html/AutoplayUmaHelper.h"
6 6
7 #include "core/dom/Document.h" 7 #include "core/dom/Document.h"
8 #include "core/dom/ElementVisibilityObserver.h" 8 #include "core/dom/ElementVisibilityObserver.h"
9 #include "core/events/Event.h" 9 #include "core/events/Event.h"
10 #include "core/frame/LocalDOMWindow.h"
11 #include "core/frame/Settings.h" 10 #include "core/frame/Settings.h"
12 #include "core/html/HTMLMediaElement.h" 11 #include "core/html/HTMLMediaElement.h"
13 #include "platform/Histogram.h" 12 #include "platform/Histogram.h"
14 #include "wtf/CurrentTime.h" 13 #include "wtf/CurrentTime.h"
15 14
16 namespace blink { 15 namespace blink {
17 16
18 namespace { 17 namespace {
19 18
20 const int32_t maxOffscreenDurationUmaMS = 60 * 60 * 1000; 19 const int32_t maxOffscreenDurationUmaMS = 60 * 60 * 1000;
21 const int32_t offscreenDurationUmaBucketCount = 50; 20 const int32_t offscreenDurationUmaBucketCount = 50;
22 21
23 } // namespace 22 } // namespace
24 23
25 AutoplayUmaHelper* AutoplayUmaHelper::create(HTMLMediaElement* element) { 24 AutoplayUmaHelper* AutoplayUmaHelper::create(HTMLMediaElement* element) {
26 return new AutoplayUmaHelper(element); 25 return new AutoplayUmaHelper(element);
27 } 26 }
28 27
29 AutoplayUmaHelper::AutoplayUmaHelper(HTMLMediaElement* element) 28 AutoplayUmaHelper::AutoplayUmaHelper(HTMLMediaElement* element)
30 : EventListener(CPPEventListenerType), 29 : EventListener(CPPEventListenerType),
30 ContextLifecycleObserver(nullptr),
31 m_source(AutoplaySource::NumberOfSources), 31 m_source(AutoplaySource::NumberOfSources),
32 m_element(element), 32 m_element(element),
33 m_mutedVideoPlayMethodVisibilityObserver(nullptr), 33 m_mutedVideoPlayMethodVisibilityObserver(nullptr),
34 m_mutedVideoAutoplayOffscreenStartTimeMS(0), 34 m_mutedVideoAutoplayOffscreenStartTimeMS(0),
35 m_mutedVideoAutoplayOffscreenDurationMS(0), 35 m_mutedVideoAutoplayOffscreenDurationMS(0),
36 m_isVisible(false), 36 m_isVisible(false),
37 m_mutedVideoOffscreenDurationVisibilityObserver(nullptr) {} 37 m_mutedVideoOffscreenDurationVisibilityObserver(nullptr) {}
38 38
39 AutoplayUmaHelper::~AutoplayUmaHelper() = default; 39 AutoplayUmaHelper::~AutoplayUmaHelper() = default;
40 40
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 AutoplayUnmuteActionStatus status) { 98 AutoplayUnmuteActionStatus status) {
99 DEFINE_STATIC_LOCAL( 99 DEFINE_STATIC_LOCAL(
100 EnumerationHistogram, autoplayUnmuteHistogram, 100 EnumerationHistogram, autoplayUnmuteHistogram,
101 ("Media.Video.Autoplay.Muted.UnmuteAction", 101 ("Media.Video.Autoplay.Muted.UnmuteAction",
102 static_cast<int>(AutoplayUnmuteActionStatus::NumberOfStatus))); 102 static_cast<int>(AutoplayUnmuteActionStatus::NumberOfStatus)));
103 103
104 autoplayUnmuteHistogram.count(static_cast<int>(status)); 104 autoplayUnmuteHistogram.count(static_cast<int>(status));
105 } 105 }
106 106
107 void AutoplayUmaHelper::didMoveToNewDocument(Document& oldDocument) { 107 void AutoplayUmaHelper::didMoveToNewDocument(Document& oldDocument) {
108 if (!shouldListenToUnloadEvent()) 108 if (!shouldListenToContextDestroyed())
109 return; 109 return;
110 110
111 if (oldDocument.domWindow()) 111 setContext(&m_element->document());
112 oldDocument.domWindow()->removeEventListener(EventTypeNames::unload, this,
113 false);
114 if (m_element->document().domWindow())
115 m_element->document().domWindow()->addEventListener(EventTypeNames::unload,
116 this, false);
117 } 112 }
118 113
119 void AutoplayUmaHelper::onVisibilityChangedForMutedVideoPlayMethodBecomeVisible( 114 void AutoplayUmaHelper::onVisibilityChangedForMutedVideoPlayMethodBecomeVisible(
120 bool isVisible) { 115 bool isVisible) {
121 if (!isVisible || !m_mutedVideoPlayMethodVisibilityObserver) 116 if (!isVisible || !m_mutedVideoPlayMethodVisibilityObserver)
122 return; 117 return;
123 118
124 maybeStopRecordingMutedVideoPlayMethodBecomeVisible(true); 119 maybeStopRecordingMutedVideoPlayMethodBecomeVisible(true);
125 } 120 }
126 121
(...skipping 12 matching lines...) Expand all
139 134
140 m_isVisible = isVisible; 135 m_isVisible = isVisible;
141 } 136 }
142 137
143 void AutoplayUmaHelper::handleEvent(ExecutionContext* executionContext, 138 void AutoplayUmaHelper::handleEvent(ExecutionContext* executionContext,
144 Event* event) { 139 Event* event) {
145 if (event->type() == EventTypeNames::playing) 140 if (event->type() == EventTypeNames::playing)
146 handlePlayingEvent(); 141 handlePlayingEvent();
147 else if (event->type() == EventTypeNames::pause) 142 else if (event->type() == EventTypeNames::pause)
148 handlePauseEvent(); 143 handlePauseEvent();
149 else if (event->type() == EventTypeNames::unload)
150 handleUnloadEvent();
151 else 144 else
152 NOTREACHED(); 145 NOTREACHED();
153 } 146 }
154 147
155 void AutoplayUmaHelper::handlePlayingEvent() { 148 void AutoplayUmaHelper::handlePlayingEvent() {
156 maybeStartRecordingMutedVideoPlayMethodBecomeVisible(); 149 maybeStartRecordingMutedVideoPlayMethodBecomeVisible();
157 maybeStartRecordingMutedVideoOffscreenDuration(); 150 maybeStartRecordingMutedVideoOffscreenDuration();
158 151
159 m_element->removeEventListener(EventTypeNames::playing, this, false); 152 m_element->removeEventListener(EventTypeNames::playing, this, false);
160 } 153 }
161 154
162 void AutoplayUmaHelper::handlePauseEvent() { 155 void AutoplayUmaHelper::handlePauseEvent() {
163 maybeStopRecordingMutedVideoOffscreenDuration(); 156 maybeStopRecordingMutedVideoOffscreenDuration();
164 } 157 }
165 158
166 void AutoplayUmaHelper::handleUnloadEvent() { 159 void AutoplayUmaHelper::contextDestroyed() {
160 handleContextDestroyed();
161 }
162
163 void AutoplayUmaHelper::handleContextDestroyed() {
167 maybeStopRecordingMutedVideoPlayMethodBecomeVisible(false); 164 maybeStopRecordingMutedVideoPlayMethodBecomeVisible(false);
168 maybeStopRecordingMutedVideoOffscreenDuration(); 165 maybeStopRecordingMutedVideoOffscreenDuration();
166
167 setContext(nullptr);
mlamouri (slow - plz ping) 2016/11/04 18:16:49 I don't think you need this.
Zhiqiang Zhang (Slow) 2016/11/04 20:29:32 Done.
169 } 168 }
170 169
171 void AutoplayUmaHelper::maybeStartRecordingMutedVideoPlayMethodBecomeVisible() { 170 void AutoplayUmaHelper::maybeStartRecordingMutedVideoPlayMethodBecomeVisible() {
172 if (m_source != AutoplaySource::Method || !m_element->isHTMLVideoElement() || 171 if (m_source != AutoplaySource::Method || !m_element->isHTMLVideoElement() ||
173 !m_element->muted()) 172 !m_element->muted())
174 return; 173 return;
175 174
176 m_mutedVideoPlayMethodVisibilityObserver = new ElementVisibilityObserver( 175 m_mutedVideoPlayMethodVisibilityObserver = new ElementVisibilityObserver(
177 m_element, 176 m_element,
178 WTF::bind(&AutoplayUmaHelper:: 177 WTF::bind(&AutoplayUmaHelper::
179 onVisibilityChangedForMutedVideoPlayMethodBecomeVisible, 178 onVisibilityChangedForMutedVideoPlayMethodBecomeVisible,
180 wrapWeakPersistent(this))); 179 wrapWeakPersistent(this)));
181 m_mutedVideoPlayMethodVisibilityObserver->start(); 180 m_mutedVideoPlayMethodVisibilityObserver->start();
182 if (m_element->document().domWindow()) 181 setContext(&m_element->document());
183 m_element->document().domWindow()->addEventListener(EventTypeNames::unload,
184 this, false);
185 } 182 }
186 183
187 void AutoplayUmaHelper::maybeStopRecordingMutedVideoPlayMethodBecomeVisible( 184 void AutoplayUmaHelper::maybeStopRecordingMutedVideoPlayMethodBecomeVisible(
188 bool visible) { 185 bool visible) {
189 if (!m_mutedVideoPlayMethodVisibilityObserver) 186 if (!m_mutedVideoPlayMethodVisibilityObserver)
190 return; 187 return;
191 188
192 DEFINE_STATIC_LOCAL(BooleanHistogram, histogram, 189 DEFINE_STATIC_LOCAL(BooleanHistogram, histogram,
193 ("Media.Video.Autoplay.Muted.PlayMethod.BecomesVisible")); 190 ("Media.Video.Autoplay.Muted.PlayMethod.BecomesVisible"));
194 191
195 histogram.count(visible); 192 histogram.count(visible);
196 m_mutedVideoPlayMethodVisibilityObserver->stop(); 193 m_mutedVideoPlayMethodVisibilityObserver->stop();
197 m_mutedVideoPlayMethodVisibilityObserver = nullptr; 194 m_mutedVideoPlayMethodVisibilityObserver = nullptr;
198 maybeUnregisterUnloadListener(); 195 maybeUnregisterContextDestroyedObserver();
199 } 196 }
200 197
201 void AutoplayUmaHelper::maybeStartRecordingMutedVideoOffscreenDuration() { 198 void AutoplayUmaHelper::maybeStartRecordingMutedVideoOffscreenDuration() {
202 if (!m_element->isHTMLVideoElement() || !m_element->muted()) 199 if (!m_element->isHTMLVideoElement() || !m_element->muted())
203 return; 200 return;
204 201
205 // Start recording muted video playing offscreen duration. 202 // Start recording muted video playing offscreen duration.
206 m_mutedVideoAutoplayOffscreenStartTimeMS = 203 m_mutedVideoAutoplayOffscreenStartTimeMS =
207 static_cast<int64_t>(monotonicallyIncreasingTimeMS()); 204 static_cast<int64_t>(monotonicallyIncreasingTimeMS());
208 m_isVisible = false; 205 m_isVisible = false;
209 m_mutedVideoOffscreenDurationVisibilityObserver = 206 m_mutedVideoOffscreenDurationVisibilityObserver =
210 new ElementVisibilityObserver( 207 new ElementVisibilityObserver(
211 m_element, 208 m_element,
212 WTF::bind(&AutoplayUmaHelper:: 209 WTF::bind(&AutoplayUmaHelper::
213 onVisibilityChangedForMutedVideoOffscreenDuration, 210 onVisibilityChangedForMutedVideoOffscreenDuration,
214 wrapWeakPersistent(this))); 211 wrapWeakPersistent(this)));
215 m_mutedVideoOffscreenDurationVisibilityObserver->start(); 212 m_mutedVideoOffscreenDurationVisibilityObserver->start();
216 m_element->addEventListener(EventTypeNames::pause, this, false); 213 m_element->addEventListener(EventTypeNames::pause, this, false);
217 if (m_element->document().domWindow()) 214 setContext(&m_element->document());
218 m_element->document().domWindow()->addEventListener(EventTypeNames::unload,
219 this, false);
220 } 215 }
221 216
222 void AutoplayUmaHelper::maybeStopRecordingMutedVideoOffscreenDuration() { 217 void AutoplayUmaHelper::maybeStopRecordingMutedVideoOffscreenDuration() {
223 if (!m_mutedVideoOffscreenDurationVisibilityObserver) 218 if (!m_mutedVideoOffscreenDurationVisibilityObserver)
224 return; 219 return;
225 220
226 if (!m_isVisible) 221 if (!m_isVisible)
227 m_mutedVideoAutoplayOffscreenDurationMS += 222 m_mutedVideoAutoplayOffscreenDurationMS +=
228 static_cast<int64_t>(monotonicallyIncreasingTimeMS()) - 223 static_cast<int64_t>(monotonicallyIncreasingTimeMS()) -
229 m_mutedVideoAutoplayOffscreenStartTimeMS; 224 m_mutedVideoAutoplayOffscreenStartTimeMS;
(...skipping 14 matching lines...) Expand all
244 DEFINE_STATIC_LOCAL( 239 DEFINE_STATIC_LOCAL(
245 CustomCountHistogram, durationHistogram, 240 CustomCountHistogram, durationHistogram,
246 ("Media.Video.Autoplay.Muted.PlayMethod.OffscreenDuration", 1, 241 ("Media.Video.Autoplay.Muted.PlayMethod.OffscreenDuration", 1,
247 maxOffscreenDurationUmaMS, offscreenDurationUmaBucketCount)); 242 maxOffscreenDurationUmaMS, offscreenDurationUmaBucketCount));
248 durationHistogram.count(boundedTime); 243 durationHistogram.count(boundedTime);
249 } 244 }
250 m_mutedVideoOffscreenDurationVisibilityObserver->stop(); 245 m_mutedVideoOffscreenDurationVisibilityObserver->stop();
251 m_mutedVideoOffscreenDurationVisibilityObserver = nullptr; 246 m_mutedVideoOffscreenDurationVisibilityObserver = nullptr;
252 m_mutedVideoAutoplayOffscreenDurationMS = 0; 247 m_mutedVideoAutoplayOffscreenDurationMS = 0;
253 m_element->removeEventListener(EventTypeNames::pause, this, false); 248 m_element->removeEventListener(EventTypeNames::pause, this, false);
254 maybeUnregisterUnloadListener(); 249 maybeUnregisterContextDestroyedObserver();
255 } 250 }
256 251
257 void AutoplayUmaHelper::maybeUnregisterUnloadListener() { 252 void AutoplayUmaHelper::maybeUnregisterContextDestroyedObserver() {
258 if (!shouldListenToUnloadEvent() && m_element->document().domWindow()) 253 if (!shouldListenToContextDestroyed()) {
259 m_element->document().domWindow()->removeEventListener( 254 setContext(nullptr);
260 EventTypeNames::unload, this, false); 255 }
261 } 256 }
262 257
263 bool AutoplayUmaHelper::shouldListenToUnloadEvent() const { 258 bool AutoplayUmaHelper::shouldListenToContextDestroyed() const {
264 return m_mutedVideoPlayMethodVisibilityObserver || 259 return m_mutedVideoPlayMethodVisibilityObserver ||
265 m_mutedVideoOffscreenDurationVisibilityObserver; 260 m_mutedVideoOffscreenDurationVisibilityObserver;
266 } 261 }
267 262
268 DEFINE_TRACE(AutoplayUmaHelper) { 263 DEFINE_TRACE(AutoplayUmaHelper) {
269 EventListener::trace(visitor); 264 EventListener::trace(visitor);
265 ContextLifecycleObserver::trace(visitor);
270 visitor->trace(m_element); 266 visitor->trace(m_element);
271 visitor->trace(m_mutedVideoPlayMethodVisibilityObserver); 267 visitor->trace(m_mutedVideoPlayMethodVisibilityObserver);
272 visitor->trace(m_mutedVideoOffscreenDurationVisibilityObserver); 268 visitor->trace(m_mutedVideoOffscreenDurationVisibilityObserver);
273 } 269 }
274 270
275 } // namespace blink 271 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/AutoplayUmaHelper.h ('k') | third_party/WebKit/Source/core/html/AutoplayUmaHelperTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698