1 /* 2 * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include "config.h" 28 #include "core/html/shadow/MediaControlsChromium.h" 29 30 #include "bindings/v8/ExceptionState.h" 31 #include "bindings/v8/ExceptionStatePlaceholder.h" 32 33 using namespace std; 34 35 namespace WebCore { 36 37 MediaControlsChromium::MediaControlsChromium(Document& document) 38 : MediaControls(document) 39 , m_durationDisplay(0) 40 , m_enclosure(0) 41 { 42 } 43 44 // MediaControls::create() for Android is defined in MediaControlsChromiumAndroid.cpp. 45 #if !OS(ANDROID) 46 PassRefPtr<MediaControls> MediaControls::create(Document& document) 47 { 48 return MediaControlsChromium::createControls(document); 49 } 50 #endif 51 52 PassRefPtr<MediaControlsChromium> MediaControlsChromium::createControls(Document& document) 53 { 54 if (!document.page()) 55 return 0; 56 57 RefPtr<MediaControlsChromium> controls = adoptRef(new MediaControlsChromium(document)); 58 59 if (controls->initializeControls(document)) 60 return controls.release(); 61 62 return 0; 63 } 64 65 bool MediaControlsChromium::initializeControls(Document& document) 66 { 67 // Create an enclosing element for the panel so we can visually offset the controls correctly. 68 RefPtr<MediaControlPanelEnclosureElement> enclosure = MediaControlPanelEnclosureElement::create(document); 69 70 RefPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(document); 71 72 TrackExceptionState exceptionState; 73 74 RefPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(document); 75 m_playButton = playButton.get(); 76 panel->appendChild(playButton.release(), exceptionState); 77 if (exceptionState.hadException()) 78 return false; 79 80 RefPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(document, this); 81 m_timeline = timeline.get(); 82 panel->appendChild(timeline.release(), exceptionState); 83 if (exceptionState.hadException()) 84 return false; 85 86 RefPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(document); 87 m_currentTimeDisplay = currentTimeDisplay.get(); 88 m_currentTimeDisplay->hide(); 89 panel->appendChild(currentTimeDisplay.release(), exceptionState); 90 if (exceptionState.hadException()) 91 return false; 92 93 RefPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(document); 94 m_durationDisplay = durationDisplay.get(); 95 panel->appendChild(durationDisplay.release(), exceptionState); 96 if (exceptionState.hadException()) 97 return false; 98 99 RefPtr<MediaControlPanelMuteButtonElement> panelMuteButton = MediaControlPanelMuteButtonElement::create(document, this); 100 m_panelMuteButton = panelMuteButton.get(); 101 panel->appendChild(panelMuteButton.release(), exceptionState); 102 if (exceptionState.hadException()) 103 return false; 104 105 RefPtr<MediaControlPanelVolumeSliderElement> slider = MediaControlPanelVolumeSliderElement::create(document); 106 m_volumeSlider = slider.get(); 107 m_volumeSlider->setClearMutedOnUserInteraction(true); 108 panel->appendChild(slider.release(), exceptionState); 109 if (exceptionState.hadException()) 110 return false; 111 112 if (RenderTheme::theme().supportsClosedCaptioning()) { 113 RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document, this); 114 m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get(); 115 panel->appendChild(toggleClosedCaptionsButton.release(), exceptionState); 116 if (exceptionState.hadException()) 117 return false; 118 } 119 120 RefPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(document); 121 m_fullScreenButton = fullscreenButton.get(); 122 panel->appendChild(fullscreenButton.release(), exceptionState); 123 if (exceptionState.hadException()) 124 return false; 125 126 m_panel = panel.get(); 127 enclosure->appendChild(panel.release(), exceptionState); 128 if (exceptionState.hadException()) 129 return false; 130 131 m_enclosure = enclosure.get(); 132 appendChild(enclosure.release(), exceptionState); 133 if (exceptionState.hadException()) 134 return false; 135 136 return true; 137 } 138 139 void MediaControlsChromium::setMediaController(MediaControllerInterface* controller) 140 { 141 if (m_mediaController == controller) 142 return; 143 144 MediaControls::setMediaController(controller); 145 146 if (m_durationDisplay) 147 m_durationDisplay->setMediaController(controller); 148 if (m_enclosure) 149 m_enclosure->setMediaController(controller); 150 } 151 152 void MediaControlsChromium::reset() 153 { 154 Page* page = document().page(); 155 if (!page) 156 return; 157 158 double duration = m_mediaController->duration(); 159 m_durationDisplay->setInnerText(RenderTheme::theme().formatMediaControlsTime(duration), ASSERT_NO_EXCEPTION); 160 m_durationDisplay->setCurrentValue(duration); 161 162 MediaControls::reset(); 163 } 164 165 void MediaControlsChromium::playbackStarted() 166 { 167 m_currentTimeDisplay->show(); 168 m_durationDisplay->hide(); 169 170 MediaControls::playbackStarted(); 171 } 172 173 void MediaControlsChromium::updateCurrentTimeDisplay() 174 { 175 double now = m_mediaController->currentTime(); 176 double duration = m_mediaController->duration(); 177 178 Page* page = document().page(); 179 if (!page) 180 return; 181 182 // After seek, hide duration display and show current time. 183 if (now > 0) { 184 m_currentTimeDisplay->show(); 185 m_durationDisplay->hide(); 186 } 187 188 // Allow the theme to format the time. 189 m_currentTimeDisplay->setInnerText(RenderTheme::theme().formatMediaControlsCurrentTime(now, duration), IGNORE_EXCEPTION); 190 m_currentTimeDisplay->setCurrentValue(now); 191 } 192 193 void MediaControlsChromium::changedMute() 194 { 195 MediaControls::changedMute(); 196 197 if (m_mediaController->muted()) 198 m_volumeSlider->setVolume(0); 199 else 200 m_volumeSlider->setVolume(m_mediaController->volume()); 201 } 202 203 void MediaControlsChromium::createTextTrackDisplay() 204 { 205 if (m_textDisplayContainer) 206 return; 207 208 RefPtr<MediaControlTextTrackContainerElement> textDisplayContainer = MediaControlTextTrackContainerElement::create(document()); 209 m_textDisplayContainer = textDisplayContainer.get(); 210 211 if (m_mediaController) 212 m_textDisplayContainer->setMediaController(m_mediaController); 213 214 insertTextTrackContainer(textDisplayContainer.release()); 215 } 216 217 void MediaControlsChromium::insertTextTrackContainer(PassRefPtr<MediaControlTextTrackContainerElement> textTrackContainer) 218 { 219 // Insert it before the first controller element so it always displays behind the controls. 220 // In the Chromium case, that's the enclosure element. 221 insertBefore(textTrackContainer, m_enclosure); 222 } 223 224 225 } 226