Home | History | Annotate | Download | only in shadow
      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 es;
     73 
     74     RefPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(document);
     75     m_playButton = playButton.get();
     76     panel->appendChild(playButton.release(), es, AttachLazily);
     77     if (es.hadException())
     78         return false;
     79 
     80     RefPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(document, this);
     81     m_timeline = timeline.get();
     82     panel->appendChild(timeline.release(), es, AttachLazily);
     83     if (es.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(), es, AttachLazily);
     90     if (es.hadException())
     91         return false;
     92 
     93     RefPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(document);
     94     m_durationDisplay = durationDisplay.get();
     95     panel->appendChild(durationDisplay.release(), es, AttachLazily);
     96     if (es.hadException())
     97         return false;
     98 
     99     RefPtr<MediaControlPanelMuteButtonElement> panelMuteButton = MediaControlPanelMuteButtonElement::create(document, this);
    100     m_panelMuteButton = panelMuteButton.get();
    101     panel->appendChild(panelMuteButton.release(), es, AttachLazily);
    102     if (es.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(), es, AttachLazily);
    109     if (es.hadException())
    110         return false;
    111 
    112     if (document->page()->theme()->supportsClosedCaptioning()) {
    113         RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document, this);
    114         m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
    115         panel->appendChild(toggleClosedCaptionsButton.release(), es, AttachLazily);
    116         if (es.hadException())
    117             return false;
    118     }
    119 
    120     RefPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(document);
    121     m_fullScreenButton = fullscreenButton.get();
    122     panel->appendChild(fullscreenButton.release(), es, AttachLazily);
    123     if (es.hadException())
    124         return false;
    125 
    126     m_panel = panel.get();
    127     enclosure->appendChild(panel.release(), es, AttachLazily);
    128     if (es.hadException())
    129         return false;
    130 
    131     m_enclosure = enclosure.get();
    132     appendChild(enclosure.release(), es, AttachLazily);
    133     if (es.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(page->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(page->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, ASSERT_NO_EXCEPTION, AttachLazily);
    222 }
    223 
    224 
    225 }
    226