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

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

Issue 2779273003: [Media Controls] Add UMA for timeline scrubber (Closed)
Patch Set: Address isherman's review comments Created 3 years, 8 months 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 /* 1 /*
2 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 17 matching lines...) Expand all
28 */ 28 */
29 29
30 #include "core/html/shadow/MediaControlElements.h" 30 #include "core/html/shadow/MediaControlElements.h"
31 31
32 #include "bindings/core/v8/ExceptionState.h" 32 #include "bindings/core/v8/ExceptionState.h"
33 #include "core/InputTypeNames.h" 33 #include "core/InputTypeNames.h"
34 #include "core/dom/ClientRect.h" 34 #include "core/dom/ClientRect.h"
35 #include "core/dom/TaskRunnerHelper.h" 35 #include "core/dom/TaskRunnerHelper.h"
36 #include "core/dom/Text.h" 36 #include "core/dom/Text.h"
37 #include "core/dom/shadow/ShadowRoot.h" 37 #include "core/dom/shadow/ShadowRoot.h"
38 #include "core/events/KeyboardEvent.h"
38 #include "core/events/MouseEvent.h" 39 #include "core/events/MouseEvent.h"
39 #include "core/frame/LocalFrame.h" 40 #include "core/frame/LocalFrame.h"
40 #include "core/frame/Settings.h" 41 #include "core/frame/Settings.h"
41 #include "core/frame/UseCounter.h" 42 #include "core/frame/UseCounter.h"
42 #include "core/html/HTMLAnchorElement.h" 43 #include "core/html/HTMLAnchorElement.h"
43 #include "core/html/HTMLLabelElement.h" 44 #include "core/html/HTMLLabelElement.h"
44 #include "core/html/HTMLMediaSource.h" 45 #include "core/html/HTMLMediaSource.h"
45 #include "core/html/HTMLSpanElement.h" 46 #include "core/html/HTMLSpanElement.h"
46 #include "core/html/HTMLVideoElement.h" 47 #include "core/html/HTMLVideoElement.h"
47 #include "core/html/TimeRanges.h" 48 #include "core/html/TimeRanges.h"
48 #include "core/html/shadow/MediaControls.h" 49 #include "core/html/shadow/MediaControls.h"
50 #include "core/html/shadow/ShadowElementNames.h"
49 #include "core/html/track/TextTrackList.h" 51 #include "core/html/track/TextTrackList.h"
50 #include "core/input/EventHandler.h" 52 #include "core/input/EventHandler.h"
53 #include "core/layout/LayoutBoxModelObject.h"
51 #include "core/layout/api/LayoutSliderItem.h" 54 #include "core/layout/api/LayoutSliderItem.h"
55 #include "core/page/ChromeClient.h"
52 #include "core/page/Page.h" 56 #include "core/page/Page.h"
53 #include "platform/EventDispatchForbiddenScope.h" 57 #include "platform/EventDispatchForbiddenScope.h"
54 #include "platform/Histogram.h" 58 #include "platform/Histogram.h"
55 #include "platform/RuntimeEnabledFeatures.h" 59 #include "platform/RuntimeEnabledFeatures.h"
56 #include "platform/text/PlatformLocale.h" 60 #include "platform/text/PlatformLocale.h"
57 #include "public/platform/Platform.h" 61 #include "public/platform/Platform.h"
58 #include "public/platform/UserMetricsAction.h" 62 #include "public/platform/UserMetricsAction.h"
63 #include "public/platform/WebScreenInfo.h"
59 64
60 namespace blink { 65 namespace blink {
61 66
62 using namespace HTMLNames; 67 using namespace HTMLNames;
63 68
64 namespace { 69 namespace {
65 70
66 // This is the duration from mediaControls.css 71 // This is the duration from mediaControls.css
67 const double fadeOutDuration = 0.3; 72 const double fadeOutDuration = 0.3;
68 73
(...skipping 18 matching lines...) Expand all
87 // Sliders (the volume control and timeline) need to capture some additional 92 // Sliders (the volume control and timeline) need to capture some additional
88 // events used when dragging the thumb. 93 // events used when dragging the thumb.
89 bool isUserInteractionEventForSlider(Event* event, LayoutObject* layoutObject) { 94 bool isUserInteractionEventForSlider(Event* event, LayoutObject* layoutObject) {
90 // It is unclear if this can be converted to isUserInteractionEvent(), since 95 // It is unclear if this can be converted to isUserInteractionEvent(), since
91 // mouse* events seem to be eaten during a drag anyway. crbug.com/516416 . 96 // mouse* events seem to be eaten during a drag anyway. crbug.com/516416 .
92 if (isUserInteractionEvent(event)) 97 if (isUserInteractionEvent(event))
93 return true; 98 return true;
94 99
95 // Some events are only captured during a slider drag. 100 // Some events are only captured during a slider drag.
96 LayoutSliderItem slider = LayoutSliderItem(toLayoutSlider(layoutObject)); 101 LayoutSliderItem slider = LayoutSliderItem(toLayoutSlider(layoutObject));
102 // TODO(crbug.com/695459#c1): LayoutSliderItem::inDragMode is incorrectly
103 // false for drags that start from the track instead of the thumb.
104 // Use SliderThumbElement::m_inDragMode and
105 // SliderContainerElement::m_touchStarted instead.
97 if (!slider.isNull() && !slider.inDragMode()) 106 if (!slider.isNull() && !slider.inDragMode())
98 return false; 107 return false;
99 108
100 const AtomicString& type = event->type(); 109 const AtomicString& type = event->type();
101 return type == EventTypeNames::mouseover || 110 return type == EventTypeNames::mouseover ||
102 type == EventTypeNames::mouseout || 111 type == EventTypeNames::mouseout ||
103 type == EventTypeNames::mousemove || 112 type == EventTypeNames::mousemove ||
104 type == EventTypeNames::pointerover || 113 type == EventTypeNames::pointerover ||
105 type == EventTypeNames::pointerout || 114 type == EventTypeNames::pointerout ||
106 type == EventTypeNames::pointermove; 115 type == EventTypeNames::pointermove;
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 792
784 void MediaControlTimelineElement::defaultEventHandler(Event* event) { 793 void MediaControlTimelineElement::defaultEventHandler(Event* event) {
785 if (event->isMouseEvent() && 794 if (event->isMouseEvent() &&
786 toMouseEvent(event)->button() != 795 toMouseEvent(event)->button() !=
787 static_cast<short>(WebPointerProperties::Button::Left)) 796 static_cast<short>(WebPointerProperties::Button::Left))
788 return; 797 return;
789 798
790 if (!isConnected() || !document().isActive()) 799 if (!isConnected() || !document().isActive())
791 return; 800 return;
792 801
793 if (event->type() == EventTypeNames::mousedown) { 802 // TODO(crbug.com/706504): These should listen for pointerdown/up.
794 Platform::current()->recordAction( 803 if (event->type() == EventTypeNames::mousedown)
795 UserMetricsAction("Media.Controls.ScrubbingBegin"));
796 mediaControls().beginScrubbing(); 804 mediaControls().beginScrubbing();
805 if (event->type() == EventTypeNames::mouseup)
806 mediaControls().endScrubbing();
807
808 // Only respond to main button of primary pointer(s).
809 if (event->isPointerEvent() && toPointerEvent(event)->isPrimary() &&
810 toPointerEvent(event)->button() ==
811 static_cast<short>(WebPointerProperties::Button::Left)) {
812 if (event->type() == EventTypeNames::pointerdown) {
813 Platform::current()->recordAction(
814 UserMetricsAction("Media.Controls.ScrubbingBegin"));
815 mediaControls().beginScrubbing();
816 Element* thumb = userAgentShadowRoot()->getElementById(
817 ShadowElementNames::sliderThumb());
818 bool startedFromThumb = thumb && thumb == event->target()->toNode();
819 m_metrics.startGesture(startedFromThumb);
820 }
821 if (event->type() == EventTypeNames::pointerup) {
822 Platform::current()->recordAction(
823 UserMetricsAction("Media.Controls.ScrubbingEnd"));
824 mediaControls().endScrubbing();
825 m_metrics.recordEndGesture(timelineWidth(), mediaElement().duration());
826 }
797 } 827 }
798 828
799 if (event->type() == EventTypeNames::mouseup) { 829 if (event->type() == EventTypeNames::keydown) {
800 Platform::current()->recordAction( 830 m_metrics.startKey();
801 UserMetricsAction("Media.Controls.ScrubbingEnd")); 831 }
802 mediaControls().endScrubbing(); 832 if (event->type() == EventTypeNames::keyup && event->isKeyboardEvent()) {
833 m_metrics.recordEndKey(timelineWidth(), toKeyboardEvent(event)->keyCode());
803 } 834 }
804 835
805 MediaControlInputElement::defaultEventHandler(event); 836 MediaControlInputElement::defaultEventHandler(event);
806 837
807 if (event->type() != EventTypeNames::input) 838 if (event->type() != EventTypeNames::input)
808 return; 839 return;
809 840
810 double time = value().toDouble(); 841 double time = value().toDouble();
811 842
812 double duration = mediaElement().duration(); 843 double duration = mediaElement().duration();
813 // Workaround for floating point error - it's possible for this element's max 844 // Workaround for floating point error - it's possible for this element's max
814 // attribute to be rounded to a value slightly higher than the duration. If 845 // attribute to be rounded to a value slightly higher than the duration. If
815 // this happens and scrubber is dragged near the max, seek to duration. 846 // this happens and scrubber is dragged near the max, seek to duration.
816 if (time > duration) 847 if (time > duration)
817 time = duration; 848 time = duration;
818 849
850 m_metrics.onInput(mediaElement().currentTime(), time);
851
819 // FIXME: This will need to take the timeline offset into consideration 852 // FIXME: This will need to take the timeline offset into consideration
820 // once that concept is supported, see https://crbug.com/312699 853 // once that concept is supported, see https://crbug.com/312699
821 if (mediaElement().seekable()->contain(time)) 854 if (mediaElement().seekable()->contain(time))
822 mediaElement().setCurrentTime(time); 855 mediaElement().setCurrentTime(time);
823 856
824 // Provide immediate feedback (without waiting for media to seek) to make it 857 // Provide immediate feedback (without waiting for media to seek) to make it
825 // easier for user to seek to a precise time. 858 // easier for user to seek to a precise time.
826 mediaControls().updateCurrentTimeDisplay(); 859 mediaControls().updateCurrentTimeDisplay();
827 } 860 }
828 861
829 bool MediaControlTimelineElement::willRespondToMouseClickEvents() { 862 bool MediaControlTimelineElement::willRespondToMouseClickEvents() {
830 return isConnected() && document().isActive(); 863 return isConnected() && document().isActive();
831 } 864 }
832 865
833 void MediaControlTimelineElement::setPosition(double currentTime) { 866 void MediaControlTimelineElement::setPosition(double currentTime) {
834 setValue(String::number(currentTime)); 867 setValue(String::number(currentTime));
835 868
836 if (LayoutObject* layoutObject = this->layoutObject()) 869 if (LayoutObject* layoutObject = this->layoutObject())
837 layoutObject->setShouldDoFullPaintInvalidation(); 870 layoutObject->setShouldDoFullPaintInvalidation();
838 } 871 }
839 872
840 void MediaControlTimelineElement::setDuration(double duration) { 873 void MediaControlTimelineElement::setDuration(double duration) {
841 setFloatingPointAttribute(maxAttr, std::isfinite(duration) ? duration : 0); 874 setFloatingPointAttribute(maxAttr, std::isfinite(duration) ? duration : 0);
842 875
843 if (LayoutObject* layoutObject = this->layoutObject()) 876 if (LayoutObject* layoutObject = this->layoutObject())
844 layoutObject->setShouldDoFullPaintInvalidation(); 877 layoutObject->setShouldDoFullPaintInvalidation();
845 } 878 }
846 879
880 void MediaControlTimelineElement::onPlaying() {
881 Frame* frame = document().frame();
882 if (!frame)
883 return;
884 m_metrics.recordPlaying(frame->chromeClient().screenInfo().orientationType,
885 mediaElement().isFullscreen(), timelineWidth());
886 }
887
847 bool MediaControlTimelineElement::keepEventInNode(Event* event) { 888 bool MediaControlTimelineElement::keepEventInNode(Event* event) {
848 return isUserInteractionEventForSlider(event, layoutObject()); 889 return isUserInteractionEventForSlider(event, layoutObject());
849 } 890 }
850 891
892 int MediaControlTimelineElement::timelineWidth() {
893 if (LayoutBoxModelObject* box = layoutBoxModelObject())
894 return box->offsetWidth().round();
895 return 0;
896 }
897
851 // ---------------------------- 898 // ----------------------------
852 899
853 MediaControlVolumeSliderElement::MediaControlVolumeSliderElement( 900 MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(
854 MediaControls& mediaControls) 901 MediaControls& mediaControls)
855 : MediaControlInputElement(mediaControls, MediaVolumeSlider) {} 902 : MediaControlInputElement(mediaControls, MediaVolumeSlider) {}
856 903
857 MediaControlVolumeSliderElement* MediaControlVolumeSliderElement::create( 904 MediaControlVolumeSliderElement* MediaControlVolumeSliderElement::create(
858 MediaControls& mediaControls) { 905 MediaControls& mediaControls) {
859 MediaControlVolumeSliderElement* slider = 906 MediaControlVolumeSliderElement* slider =
860 new MediaControlVolumeSliderElement(mediaControls); 907 new MediaControlVolumeSliderElement(mediaControls);
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 MediaControlCurrentTimeDisplayElement* 1145 MediaControlCurrentTimeDisplayElement*
1099 MediaControlCurrentTimeDisplayElement::create(MediaControls& mediaControls) { 1146 MediaControlCurrentTimeDisplayElement::create(MediaControls& mediaControls) {
1100 MediaControlCurrentTimeDisplayElement* element = 1147 MediaControlCurrentTimeDisplayElement* element =
1101 new MediaControlCurrentTimeDisplayElement(mediaControls); 1148 new MediaControlCurrentTimeDisplayElement(mediaControls);
1102 element->setShadowPseudoId( 1149 element->setShadowPseudoId(
1103 AtomicString("-webkit-media-controls-current-time-display")); 1150 AtomicString("-webkit-media-controls-current-time-display"));
1104 return element; 1151 return element;
1105 } 1152 }
1106 1153
1107 } // namespace blink 1154 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698