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

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

Powered by Google App Engine
This is Rietveld 408576698