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

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

Issue 2475643004: Monitor the intersection of video and viewport. (Closed)
Patch Set: Addressed miu's comments from PS#5. 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"
Zhiqiang Zhang (Slow) 2016/11/15 11:29:27 nit: remove this include
xjz 2016/11/15 23:03:39 Done.
9 #include "core/events/Event.h" 9 #include "core/events/Event.h"
10 #include "core/frame/LocalDOMWindow.h" 10 #include "core/frame/LocalDOMWindow.h"
11 #include "core/frame/Settings.h" 11 #include "core/frame/Settings.h"
12 #include "core/html/HTMLMediaElement.h" 12 #include "core/html/HTMLMediaElement.h"
13 #include "platform/Histogram.h" 13 #include "platform/Histogram.h"
14 #include "wtf/CurrentTime.h" 14 #include "wtf/CurrentTime.h"
15 15
16 namespace blink { 16 namespace blink {
17 17
18 namespace { 18 namespace {
19 19
20 const int32_t maxOffscreenDurationUmaMS = 60 * 60 * 1000; 20 const int32_t maxOffscreenDurationUmaMS = 60 * 60 * 1000;
21 const int32_t offscreenDurationUmaBucketCount = 50; 21 const int32_t offscreenDurationUmaBucketCount = 50;
22 22
23 } // namespace 23 } // namespace
24 24
25 AutoplayUmaHelper* AutoplayUmaHelper::create(HTMLMediaElement* element) { 25 AutoplayUmaHelper* AutoplayUmaHelper::create(HTMLMediaElement* element) {
26 return new AutoplayUmaHelper(element); 26 return new AutoplayUmaHelper(element);
27 } 27 }
28 28
29 AutoplayUmaHelper::AutoplayUmaHelper(HTMLMediaElement* element) 29 AutoplayUmaHelper::AutoplayUmaHelper(HTMLMediaElement* element)
30 : EventListener(CPPEventListenerType), 30 : EventListener(CPPEventListenerType),
31 m_source(AutoplaySource::NumberOfSources), 31 m_source(AutoplaySource::NumberOfSources),
32 m_element(element), 32 m_element(element),
33 m_mutedVideoPlayMethodVisibilityObserver(nullptr),
34 m_mutedVideoAutoplayOffscreenStartTimeMS(0), 33 m_mutedVideoAutoplayOffscreenStartTimeMS(0),
35 m_mutedVideoAutoplayOffscreenDurationMS(0), 34 m_mutedVideoAutoplayOffscreenDurationMS(0),
36 m_isVisible(false), 35 m_isVisible(false) {}
37 m_mutedVideoOffscreenDurationVisibilityObserver(nullptr) {}
38 36
39 AutoplayUmaHelper::~AutoplayUmaHelper() = default; 37 AutoplayUmaHelper::~AutoplayUmaHelper() = default;
40 38
41 bool AutoplayUmaHelper::operator==(const EventListener& other) const { 39 bool AutoplayUmaHelper::operator==(const EventListener& other) const {
42 return this == &other; 40 return this == &other;
43 } 41 }
44 42
45 void AutoplayUmaHelper::onAutoplayInitiated(AutoplaySource source) { 43 void AutoplayUmaHelper::onAutoplayInitiated(AutoplaySource source) {
46 DEFINE_STATIC_LOCAL(EnumerationHistogram, videoHistogram, 44 DEFINE_STATIC_LOCAL(EnumerationHistogram, videoHistogram,
47 ("Media.Video.Autoplay", 45 ("Media.Video.Autoplay",
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 return; 107 return;
110 108
111 if (oldDocument.domWindow()) 109 if (oldDocument.domWindow())
112 oldDocument.domWindow()->removeEventListener(EventTypeNames::unload, this, 110 oldDocument.domWindow()->removeEventListener(EventTypeNames::unload, this,
113 false); 111 false);
114 if (m_element->document().domWindow()) 112 if (m_element->document().domWindow())
115 m_element->document().domWindow()->addEventListener(EventTypeNames::unload, 113 m_element->document().domWindow()->addEventListener(EventTypeNames::unload,
116 this, false); 114 this, false);
117 } 115 }
118 116
119 void AutoplayUmaHelper::onVisibilityChangedForMutedVideoPlayMethodBecomeVisible( 117 void AutoplayUmaHelper::visibilityMaybeChangedforMutedVideo(bool isVisible) {
120 bool isVisible) {
121 if (!isVisible || !m_mutedVideoPlayMethodVisibilityObserver)
122 return;
123
124 maybeStopRecordingMutedVideoPlayMethodBecomeVisible(true);
125 }
126
127 void AutoplayUmaHelper::onVisibilityChangedForMutedVideoOffscreenDuration(
128 bool isVisible) {
129 if (isVisible == m_isVisible) 118 if (isVisible == m_isVisible)
130 return; 119 return;
131 120
132 if (isVisible) 121 m_isVisible = isVisible;
133 m_mutedVideoAutoplayOffscreenDurationMS +=
134 static_cast<int64_t>(monotonicallyIncreasingTimeMS()) -
135 m_mutedVideoAutoplayOffscreenStartTimeMS;
136 else
137 m_mutedVideoAutoplayOffscreenStartTimeMS =
138 static_cast<int64_t>(monotonicallyIncreasingTimeMS());
139 122
140 m_isVisible = isVisible; 123 if (m_isObservingVisibilityOfMutedVideoOffscreenDuration && isVisible)
124 maybeStopRecordingMutedVideoPlayMethodBecomeVisible(true);
125
126 if (m_isObservingVisibilityOfMutedVideoOffscreenDuration) {
127 if (isVisible) {
128 m_mutedVideoAutoplayOffscreenDurationMS +=
129 static_cast<int64_t>(monotonicallyIncreasingTimeMS()) -
130 m_mutedVideoAutoplayOffscreenStartTimeMS;
131 } else {
132 m_mutedVideoAutoplayOffscreenStartTimeMS =
133 static_cast<int64_t>(monotonicallyIncreasingTimeMS());
134 }
135 }
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) 144 else if (event->type() == EventTypeNames::unload)
150 handleUnloadEvent(); 145 handleUnloadEvent();
(...skipping 15 matching lines...) Expand all
166 void AutoplayUmaHelper::handleUnloadEvent() { 161 void AutoplayUmaHelper::handleUnloadEvent() {
167 maybeStopRecordingMutedVideoPlayMethodBecomeVisible(false); 162 maybeStopRecordingMutedVideoPlayMethodBecomeVisible(false);
168 maybeStopRecordingMutedVideoOffscreenDuration(); 163 maybeStopRecordingMutedVideoOffscreenDuration();
169 } 164 }
170 165
171 void AutoplayUmaHelper::maybeStartRecordingMutedVideoPlayMethodBecomeVisible() { 166 void AutoplayUmaHelper::maybeStartRecordingMutedVideoPlayMethodBecomeVisible() {
172 if (m_source != AutoplaySource::Method || !m_element->isHTMLVideoElement() || 167 if (m_source != AutoplaySource::Method || !m_element->isHTMLVideoElement() ||
173 !m_element->muted()) 168 !m_element->muted())
174 return; 169 return;
175 170
176 m_mutedVideoPlayMethodVisibilityObserver = new ElementVisibilityObserver( 171 m_isObservingVisibilityOfMutedAutoplayVideo = true;
177 m_element,
178 WTF::bind(&AutoplayUmaHelper::
179 onVisibilityChangedForMutedVideoPlayMethodBecomeVisible,
180 wrapWeakPersistent(this)));
181 m_mutedVideoPlayMethodVisibilityObserver->start();
182 if (m_element->document().domWindow()) 172 if (m_element->document().domWindow())
183 m_element->document().domWindow()->addEventListener(EventTypeNames::unload, 173 m_element->document().domWindow()->addEventListener(EventTypeNames::unload,
184 this, false); 174 this, false);
185 } 175 }
186 176
187 void AutoplayUmaHelper::maybeStopRecordingMutedVideoPlayMethodBecomeVisible( 177 void AutoplayUmaHelper::maybeStopRecordingMutedVideoPlayMethodBecomeVisible(
188 bool visible) { 178 bool visible) {
189 if (!m_mutedVideoPlayMethodVisibilityObserver) 179 if (!m_isObservingVisibilityOfMutedAutoplayVideo)
190 return; 180 return;
191 181
192 DEFINE_STATIC_LOCAL(BooleanHistogram, histogram, 182 DEFINE_STATIC_LOCAL(BooleanHistogram, histogram,
193 ("Media.Video.Autoplay.Muted.PlayMethod.BecomesVisible")); 183 ("Media.Video.Autoplay.Muted.PlayMethod.BecomesVisible"));
194 184
195 histogram.count(visible); 185 histogram.count(visible);
196 m_mutedVideoPlayMethodVisibilityObserver->stop(); 186 m_isObservingVisibilityOfMutedAutoplayVideo = false;
197 m_mutedVideoPlayMethodVisibilityObserver = nullptr;
198 maybeUnregisterUnloadListener(); 187 maybeUnregisterUnloadListener();
199 } 188 }
200 189
201 void AutoplayUmaHelper::maybeStartRecordingMutedVideoOffscreenDuration() { 190 void AutoplayUmaHelper::maybeStartRecordingMutedVideoOffscreenDuration() {
202 if (!m_element->isHTMLVideoElement() || !m_element->muted()) 191 if (!m_element->isHTMLVideoElement() || !m_element->muted())
203 return; 192 return;
204 193
205 // Start recording muted video playing offscreen duration. 194 // Start recording muted video playing offscreen duration.
206 m_mutedVideoAutoplayOffscreenStartTimeMS = 195 m_mutedVideoAutoplayOffscreenStartTimeMS =
207 static_cast<int64_t>(monotonicallyIncreasingTimeMS()); 196 static_cast<int64_t>(monotonicallyIncreasingTimeMS());
208 m_isVisible = false; 197 m_isVisible = false;
209 m_mutedVideoOffscreenDurationVisibilityObserver = 198 m_isObservingVisibilityOfMutedVideoOffscreenDuration = true;
210 new ElementVisibilityObserver(
211 m_element,
212 WTF::bind(&AutoplayUmaHelper::
213 onVisibilityChangedForMutedVideoOffscreenDuration,
214 wrapWeakPersistent(this)));
215 m_mutedVideoOffscreenDurationVisibilityObserver->start();
216 m_element->addEventListener(EventTypeNames::pause, this, false); 199 m_element->addEventListener(EventTypeNames::pause, this, false);
217 if (m_element->document().domWindow()) 200 if (m_element->document().domWindow())
218 m_element->document().domWindow()->addEventListener(EventTypeNames::unload, 201 m_element->document().domWindow()->addEventListener(EventTypeNames::unload,
219 this, false); 202 this, false);
220 } 203 }
221 204
222 void AutoplayUmaHelper::maybeStopRecordingMutedVideoOffscreenDuration() { 205 void AutoplayUmaHelper::maybeStopRecordingMutedVideoOffscreenDuration() {
223 if (!m_mutedVideoOffscreenDurationVisibilityObserver) 206 if (!m_isObservingVisibilityOfMutedVideoOffscreenDuration)
224 return; 207 return;
225 208
226 if (!m_isVisible) 209 if (!m_isVisible)
227 m_mutedVideoAutoplayOffscreenDurationMS += 210 m_mutedVideoAutoplayOffscreenDurationMS +=
228 static_cast<int64_t>(monotonicallyIncreasingTimeMS()) - 211 static_cast<int64_t>(monotonicallyIncreasingTimeMS()) -
229 m_mutedVideoAutoplayOffscreenStartTimeMS; 212 m_mutedVideoAutoplayOffscreenStartTimeMS;
230 213
231 // Since histograms uses int32_t, the duration needs to be limited to 214 // Since histograms uses int32_t, the duration needs to be limited to
232 // std::numeric_limits<int32_t>::max(). 215 // std::numeric_limits<int32_t>::max().
233 int32_t boundedTime = static_cast<int32_t>( 216 int32_t boundedTime = static_cast<int32_t>(
234 std::min<int64_t>(m_mutedVideoAutoplayOffscreenDurationMS, 217 std::min<int64_t>(m_mutedVideoAutoplayOffscreenDurationMS,
235 std::numeric_limits<int32_t>::max())); 218 std::numeric_limits<int32_t>::max()));
236 219
237 if (m_source == AutoplaySource::Attribute) { 220 if (m_source == AutoplaySource::Attribute) {
238 DEFINE_STATIC_LOCAL( 221 DEFINE_STATIC_LOCAL(
239 CustomCountHistogram, durationHistogram, 222 CustomCountHistogram, durationHistogram,
240 ("Media.Video.Autoplay.Muted.Attribute.OffscreenDuration", 1, 223 ("Media.Video.Autoplay.Muted.Attribute.OffscreenDuration", 1,
241 maxOffscreenDurationUmaMS, offscreenDurationUmaBucketCount)); 224 maxOffscreenDurationUmaMS, offscreenDurationUmaBucketCount));
242 durationHistogram.count(boundedTime); 225 durationHistogram.count(boundedTime);
243 } else { 226 } else {
244 DEFINE_STATIC_LOCAL( 227 DEFINE_STATIC_LOCAL(
245 CustomCountHistogram, durationHistogram, 228 CustomCountHistogram, durationHistogram,
246 ("Media.Video.Autoplay.Muted.PlayMethod.OffscreenDuration", 1, 229 ("Media.Video.Autoplay.Muted.PlayMethod.OffscreenDuration", 1,
247 maxOffscreenDurationUmaMS, offscreenDurationUmaBucketCount)); 230 maxOffscreenDurationUmaMS, offscreenDurationUmaBucketCount));
248 durationHistogram.count(boundedTime); 231 durationHistogram.count(boundedTime);
249 } 232 }
250 m_mutedVideoOffscreenDurationVisibilityObserver->stop(); 233 m_isObservingVisibilityOfMutedVideoOffscreenDuration = false;
251 m_mutedVideoOffscreenDurationVisibilityObserver = nullptr;
252 m_mutedVideoAutoplayOffscreenDurationMS = 0; 234 m_mutedVideoAutoplayOffscreenDurationMS = 0;
253 m_element->removeEventListener(EventTypeNames::pause, this, false); 235 m_element->removeEventListener(EventTypeNames::pause, this, false);
254 maybeUnregisterUnloadListener(); 236 maybeUnregisterUnloadListener();
255 } 237 }
256 238
257 void AutoplayUmaHelper::maybeUnregisterUnloadListener() { 239 void AutoplayUmaHelper::maybeUnregisterUnloadListener() {
258 if (!shouldListenToUnloadEvent() && m_element->document().domWindow()) 240 if (!shouldListenToUnloadEvent() && m_element->document().domWindow())
259 m_element->document().domWindow()->removeEventListener( 241 m_element->document().domWindow()->removeEventListener(
260 EventTypeNames::unload, this, false); 242 EventTypeNames::unload, this, false);
261 } 243 }
262 244
263 bool AutoplayUmaHelper::shouldListenToUnloadEvent() const { 245 bool AutoplayUmaHelper::shouldListenToUnloadEvent() const {
264 return m_mutedVideoPlayMethodVisibilityObserver || 246 return m_isObservingVisibilityOfMutedAutoplayVideo ||
265 m_mutedVideoOffscreenDurationVisibilityObserver; 247 m_isObservingVisibilityOfMutedVideoOffscreenDuration;
266 } 248 }
267 249
268 DEFINE_TRACE(AutoplayUmaHelper) { 250 DEFINE_TRACE(AutoplayUmaHelper) {
269 EventListener::trace(visitor); 251 EventListener::trace(visitor);
270 visitor->trace(m_element); 252 visitor->trace(m_element);
271 visitor->trace(m_mutedVideoPlayMethodVisibilityObserver);
272 visitor->trace(m_mutedVideoOffscreenDurationVisibilityObserver);
273 } 253 }
274 254
275 } // namespace blink 255 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698