18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(VIDEO)
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLMediaElement.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "Attribute.h"
32d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "Chrome.h"
33d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "ChromeClient.h"
34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "ClientRect.h"
35231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "ClientRectList.h"
362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "ContentSecurityPolicy.h"
375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "ContentType.h"
385abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "CSSPropertyNames.h"
395abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "CSSValueKeywords.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Event.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventNames.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ExceptionCode.h"
438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "Frame.h"
448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "FrameLoader.h"
45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "FrameLoaderClient.h"
46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "FrameView.h"
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLDocument.h"
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLSourceElement.h"
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLVideoElement.h"
515abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "Logging.h"
522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "MediaControls.h"
535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "MediaDocument.h"
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MediaError.h"
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MediaList.h"
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MediaPlayer.h"
575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "MediaQueryEvaluator.h"
582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "MouseEvent.h"
595abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "MIMETypeRegistry.h"
60635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Page.h"
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderVideo.h"
62231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "RenderView.h"
630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "ScriptEventListener.h"
6421939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "Settings.h"
652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "ShadowRoot.h"
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "TimeRanges.h"
675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <limits>
685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <wtf/CurrentTime.h>
695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <wtf/MathExtras.h>
7068513a70bcd92384395513322f1b801e7bf9c729Steve Block#include <wtf/text/CString.h>
715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if USE(ACCELERATED_COMPOSITING)
730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "RenderView.h"
740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "RenderLayerCompositor.h"
750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "RenderEmbeddedObject.h"
798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "Widget.h"
808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
820676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu#if PLATFORM(ANDROID)
830676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu// For every touch, show the media control for 4 seconds.
840676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu#define TOUCH_DELAY 4
850676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu#endif
860676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
915abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#if !LOG_DISABLED
925abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickstatic String urlForLogging(const String& url)
935abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
946b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    static const unsigned maximumURLLengthForLogging = 128;
955abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
965abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (url.length() < maximumURLLengthForLogging)
975abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        return url;
985abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return url.substring(0, maximumURLLengthForLogging) + "...";
995abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
1005abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
1015abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickstatic const char *boolString(bool val)
1025abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
1035abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return val ? "true" : "false";
1045abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
1055abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#endif
1065abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
1075abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#ifndef LOG_MEDIA_EVENTS
1085abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick// Default to not logging events because so many are generated they can overwhelm the rest of
1095abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick// the logging.
1105abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#define LOG_MEDIA_EVENTS 0
1115abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#endif
1125abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
1136b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#ifndef LOG_CACHED_TIME_WARNINGS
1146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// Default to not logging warnings about excessive drift in the cached media time because it adds a
1156b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// fair amount of overhead and logging.
1166b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#define LOG_CACHED_TIME_WARNINGS 0
1176b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#endif
1186b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
1196b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic const float invalidMediaTime = -1;
1206b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1235abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain MerrickHTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* document)
1245abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    : HTMLElement(tagName, document)
1255abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    , ActiveDOMObject(document, this)
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_loadTimer(this, &HTMLMediaElement::loadTimerFired)
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_asyncEventTimer(this, &HTMLMediaElement::asyncEventTimerFired)
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
1298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFired)
1305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_playedTimeRanges()
1318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_playbackRate(1.0f)
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_defaultPlaybackRate(1.0f)
1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    , m_webkitPreservesPitch(true)
1348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_networkState(NETWORK_EMPTY)
1358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_readyState(HAVE_NOTHING)
13621939df44de1705786c545cd1bf519d47250322dBen Murdoch    , m_readyStateMaximum(HAVE_NOTHING)
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_volume(1.0f)
1385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_lastSeekTime(0)
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_previousProgress(0)
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_previousProgressTime(numeric_limits<double>::max())
1418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_lastTimeUpdateEventWallTime(0)
1428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_lastTimeUpdateEventMovieTime(numeric_limits<float>::max())
1438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_loadState(WaitingForSource)
1448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_currentSourceNode(0)
145a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_nextChildNodeToConsider(0)
1468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_player(0)
147dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
148dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    , m_proxyWidget(0)
149dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
15081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_restrictions(RequireUserGestureForFullScreenRestriction)
151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    , m_preload(MediaPlayer::Auto)
152dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    , m_displayMode(Unknown)
1538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_processingMediaPlayerCallback(0)
1546b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    , m_cachedTime(invalidMediaTime)
1556b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    , m_cachedTimeWallClockUpdateTime(0)
1566b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    , m_minimumWallClockTimeToCacheMediaTime(0)
157dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    , m_playing(false)
158dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    , m_isWaitingUntilMediaCanStart(false)
1595ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    , m_shouldDelayLoadEvent(false)
1608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_haveFiredLoadedData(false)
1618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_inActiveDocument(true)
1628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_autoplaying(true)
1638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_muted(false)
1648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_paused(true)
1658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_seeking(false)
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_sentStalledEvent(false)
1678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_sentEndEvent(false)
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_pausedInternal(false)
1698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_sendProgressEvents(true)
170231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    , m_isFullscreen(false)
171643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    , m_closedCaptionsVisible(false)
1722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    , m_mouseOver(false)
1738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_needWidgetUpdate(false)
1758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
17621939df44de1705786c545cd1bf519d47250322dBen Murdoch    , m_dispatchingCanPlayEvent(false)
177e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    , m_loadInitiatedByUserGesture(false)
178967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    , m_completelyLoaded(false)
1790676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu#if PLATFORM(ANDROID)
1800676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu    , m_lastTouch(0)
18131dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu    , m_userGestureInitiated(false)
1820676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu#endif
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
184a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    LOG(Media, "HTMLMediaElement::HTMLMediaElement");
1855abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    document->registerForDocumentActivationCallbacks(this);
1865abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    document->registerForMediaVolumeCallbacks(this);
1879921f05212aa840e1ce32e9f04fa60ca4b3bcbb7Ben Murdoch    document->registerForPrivateBrowsingStateChangedCallbacks(this);
188ad46784d9075ff6d1e11cd2be47a6169761b0eebTeng-Hui Zhu
189ad46784d9075ff6d1e11cd2be47a6169761b0eebTeng-Hui Zhu    if (document->settings() && document->settings()->mediaPlaybackRequiresUserGesture())
190ad46784d9075ff6d1e11cd2be47a6169761b0eebTeng-Hui Zhu        m_restrictions |= RequireUserGestureForRateChangeRestriction;
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLMediaElement::~HTMLMediaElement()
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
195a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    LOG(Media, "HTMLMediaElement::~HTMLMediaElement");
1966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (m_isWaitingUntilMediaCanStart)
1976c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        document()->removeMediaCanStartListener(this);
1985ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    setShouldDelayLoadEvent(false);
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    document()->unregisterForDocumentActivationCallbacks(this);
200635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    document()->unregisterForMediaVolumeCallbacks(this);
20181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    document()->unregisterForPrivateBrowsingStateChangedCallbacks(this);
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
204d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid HTMLMediaElement::willMoveToNewOwnerDocument()
205d0825bca7fe65beaee391d30da42e937db621564Steve Block{
2066c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (m_isWaitingUntilMediaCanStart)
2076c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        document()->removeMediaCanStartListener(this);
2085ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    setShouldDelayLoadEvent(false);
209d0825bca7fe65beaee391d30da42e937db621564Steve Block    document()->unregisterForDocumentActivationCallbacks(this);
210d0825bca7fe65beaee391d30da42e937db621564Steve Block    document()->unregisterForMediaVolumeCallbacks(this);
211d0825bca7fe65beaee391d30da42e937db621564Steve Block    HTMLElement::willMoveToNewOwnerDocument();
212d0825bca7fe65beaee391d30da42e937db621564Steve Block}
213d0825bca7fe65beaee391d30da42e937db621564Steve Block
214d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid HTMLMediaElement::didMoveToNewOwnerDocument()
215d0825bca7fe65beaee391d30da42e937db621564Steve Block{
2166c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (m_isWaitingUntilMediaCanStart)
2176c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        document()->addMediaCanStartListener(this);
2185ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (m_readyState < HAVE_CURRENT_DATA)
2195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        setShouldDelayLoadEvent(true);
220d0825bca7fe65beaee391d30da42e937db621564Steve Block    document()->registerForDocumentActivationCallbacks(this);
221d0825bca7fe65beaee391d30da42e937db621564Steve Block    document()->registerForMediaVolumeCallbacks(this);
222d0825bca7fe65beaee391d30da42e937db621564Steve Block    HTMLElement::didMoveToNewOwnerDocument();
223d0825bca7fe65beaee391d30da42e937db621564Steve Block}
224d0825bca7fe65beaee391d30da42e937db621564Steve Block
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::attributeChanged(Attribute* attr, bool preserveDecls)
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement::attributeChanged(attr, preserveDecls);
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const QualifiedName& attrName = attr->name();
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (attrName == srcAttr) {
231dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // Trigger a reload, as long as the 'src' attribute is present.
232dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!getAttribute(srcAttr).isEmpty())
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            scheduleLoad();
234dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
2358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    else if (attrName == controlsAttr) {
236967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
2372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (controls()) {
2382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (!hasMediaControls()) {
2394717b91d77cab5187baae5025bfa1bab4e52a907Steve Block                if (!createMediaControls())
2404717b91d77cab5187baae5025bfa1bab4e52a907Steve Block                    return;
2414717b91d77cab5187baae5025bfa1bab4e52a907Steve Block
2422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                mediaControls()->reset();
2432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            }
2442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            mediaControls()->show();
2452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        } else if (hasMediaControls())
2462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            mediaControls()->hide();
247967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#else
248967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        if (m_player)
249967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            m_player->setControls(controls());
2508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
251967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
254e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockvoid HTMLMediaElement::parseMappedAttribute(Attribute* attr)
2555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
2560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    const QualifiedName& attrName = attr->name();
2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
258dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (attrName == preloadAttr) {
259dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        String value = attr->value();
260dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
261dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (equalIgnoringCase(value, "none"))
262dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_preload = MediaPlayer::None;
263dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        else if (equalIgnoringCase(value, "metadata"))
264dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_preload = MediaPlayer::MetaData;
265dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        else {
266dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            // The spec does not define an "invalid value default" but "auto" is suggested as the
267dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            // "missing value default", so use it for everything except "none" and "metadata"
268dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_preload = MediaPlayer::Auto;
269dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
270dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
271dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // The attribute must be ignored if the autoplay attribute is present
272dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!autoplay() && m_player)
273dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_player->setPreload(m_preload);
274dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else if (attrName == onabortAttr)
2760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().abortEvent, createAttributeEventListener(this, attr));
277cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    else if (attrName == onbeforeloadAttr)
278cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, attr));
2790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == oncanplayAttr)
2800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().canplayEvent, createAttributeEventListener(this, attr));
2810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == oncanplaythroughAttr)
2820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().canplaythroughEvent, createAttributeEventListener(this, attr));
2830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == ondurationchangeAttr)
2840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().durationchangeEvent, createAttributeEventListener(this, attr));
2850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onemptiedAttr)
2860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().emptiedEvent, createAttributeEventListener(this, attr));
2870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onendedAttr)
2880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().endedEvent, createAttributeEventListener(this, attr));
2890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onerrorAttr)
2900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().errorEvent, createAttributeEventListener(this, attr));
2910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onloadeddataAttr)
2920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().loadeddataEvent, createAttributeEventListener(this, attr));
2930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onloadedmetadataAttr)
2940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().loadedmetadataEvent, createAttributeEventListener(this, attr));
2950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onloadstartAttr)
2960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().loadstartEvent, createAttributeEventListener(this, attr));
2970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onpauseAttr)
2980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().pauseEvent, createAttributeEventListener(this, attr));
2990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onplayAttr)
3000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().playEvent, createAttributeEventListener(this, attr));
3010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onplayingAttr)
3020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().playingEvent, createAttributeEventListener(this, attr));
3030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onprogressAttr)
3040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().progressEvent, createAttributeEventListener(this, attr));
3050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onratechangeAttr)
3060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().ratechangeEvent, createAttributeEventListener(this, attr));
3070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onseekedAttr)
3080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().seekedEvent, createAttributeEventListener(this, attr));
3090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onseekingAttr)
3100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().seekingEvent, createAttributeEventListener(this, attr));
3110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onstalledAttr)
3120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().stalledEvent, createAttributeEventListener(this, attr));
3130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onsuspendAttr)
3140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().suspendEvent, createAttributeEventListener(this, attr));
3150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == ontimeupdateAttr)
3160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().timeupdateEvent, createAttributeEventListener(this, attr));
3170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onvolumechangeAttr)
3180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().volumechangeEvent, createAttributeEventListener(this, attr));
3190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else if (attrName == onwaitingAttr)
3200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        setAttributeEventListener(eventNames().waitingEvent, createAttributeEventListener(this, attr));
321643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    else if (attrName == onwebkitbeginfullscreenAttr)
322643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        setAttributeEventListener(eventNames().webkitbeginfullscreenEvent, createAttributeEventListener(this, attr));
323643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    else if (attrName == onwebkitendfullscreenAttr)
324643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        setAttributeEventListener(eventNames().webkitendfullscreenEvent, createAttributeEventListener(this, attr));
3250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    else
3265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        HTMLElement::parseMappedAttribute(attr);
3275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
3285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLMediaElement::rendererIsNeeded(RenderStyle* style)
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
3328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    UNUSED_PARAM(style);
3338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Frame* frame = document()->frame();
3348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!frame)
3358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return false;
3368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return true;
3388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#else
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return controls() ? HTMLElement::rendererIsNeeded(style) : false;
3408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderObject* HTMLMediaElement::createRenderer(RenderArena* arena, RenderStyle*)
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
346dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Setup the renderer if we already have a proxy widget.
347dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    RenderEmbeddedObject* mediaRenderer = new (arena) RenderEmbeddedObject(this);
348967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (m_proxyWidget) {
349dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        mediaRenderer->setWidget(m_proxyWidget);
350967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
351967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        Frame* frame = document()->frame();
352967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        FrameLoader* loader = frame ? frame->loader() : 0;
353967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        if (loader)
354967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            loader->showMediaPlayerProxyPlugin(m_proxyWidget.get());
355967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
356dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return mediaRenderer;
3578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#else
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return new (arena) RenderMedia(this);
3598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::insertedIntoDocument()
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
364a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    LOG(Media, "HTMLMediaElement::removedFromDocument");
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement::insertedIntoDocument();
3660617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    if (!getAttribute(srcAttr).isEmpty() && m_networkState == NETWORK_EMPTY)
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        scheduleLoad();
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::removedFromDocument()
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
372a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    LOG(Media, "HTMLMediaElement::removedFromDocument");
3738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_networkState > NETWORK_EMPTY)
3745e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        pause(processingUserGesture());
375cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (m_isFullscreen)
376cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        exitFullscreen();
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement::removedFromDocument();
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::attach()
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!attached());
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
3858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_needWidgetUpdate = true;
3868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
3878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement::attach();
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer())
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        renderer()->updateFromElement();
392967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
393967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    else if (m_proxyWidget) {
394967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        Frame* frame = document()->frame();
395967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        FrameLoader* loader = frame ? frame->loader() : 0;
396967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        if (loader)
397967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            loader->hideMediaPlayerProxyPlugin(m_proxyWidget.get());
398967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
399967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#endif
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::recalcStyle(StyleChange change)
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement::recalcStyle(change);
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer())
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        renderer()->updateFromElement();
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::scheduleLoad()
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
412a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    LOG(Media, "HTMLMediaElement::scheduleLoad");
413dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
414dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    createMediaPlayerProxy();
415dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
416dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
417231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (m_loadTimer.isActive())
418231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
419231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    prepareForLoad();
420231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_loadTimer.startOneShot(0);
421231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
422231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
423231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLMediaElement::scheduleNextSourceChild()
424231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
425231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Schedule the timer to try the next <source> element WITHOUT resetting state ala prepareForLoad.
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_loadTimer.startOneShot(0);
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
4308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
4315abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#if LOG_MEDIA_EVENTS
4325abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::scheduleEvent - scheduling '%s'", eventName.string().ascii().data());
4335abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#endif
434d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_pendingEvents.append(Event::create(eventName, false, true));
4355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!m_asyncEventTimer.isActive())
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_asyncEventTimer.startOneShot(0);
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::asyncEventTimerFired(Timer<HTMLMediaElement>*)
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Vector<RefPtr<Event> > pendingEvents;
4428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ExceptionCode ec = 0;
4438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_pendingEvents.swap(pendingEvents);
4458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    unsigned count = pendingEvents.size();
44621939df44de1705786c545cd1bf519d47250322dBen Murdoch    for (unsigned ndx = 0; ndx < count; ++ndx) {
4475abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#if LOG_MEDIA_EVENTS
4485abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        LOG(Media, "HTMLMediaElement::asyncEventTimerFired - dispatching '%s'", pendingEvents[ndx]->type().string().ascii().data());
4495abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#endif
45021939df44de1705786c545cd1bf519d47250322dBen Murdoch        if (pendingEvents[ndx]->type() == eventNames().canplayEvent) {
45121939df44de1705786c545cd1bf519d47250322dBen Murdoch            m_dispatchingCanPlayEvent = true;
45221939df44de1705786c545cd1bf519d47250322dBen Murdoch            dispatchEvent(pendingEvents[ndx].release(), ec);
45321939df44de1705786c545cd1bf519d47250322dBen Murdoch            m_dispatchingCanPlayEvent = false;
45421939df44de1705786c545cd1bf519d47250322dBen Murdoch        } else
45521939df44de1705786c545cd1bf519d47250322dBen Murdoch            dispatchEvent(pendingEvents[ndx].release(), ec);
45621939df44de1705786c545cd1bf519d47250322dBen Murdoch    }
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_loadState == LoadingFromSourceElement)
4628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        loadNextSourceChild();
4638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    else
4648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        loadInternal();
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<MediaError> HTMLMediaElement::error() const
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_error;
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::setSrc(const String& url)
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setAttribute(srcAttr, url);
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLMediaElement::currentSrc() const
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_currentSrc;
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLMediaElement::NetworkState HTMLMediaElement::networkState() const
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_networkState;
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianString HTMLMediaElement::canPlayType(const String& mimeType) const
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    MediaPlayer::SupportsType support = MediaPlayer::supportsType(ContentType(mimeType));
4908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    String canPlay;
4918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // 4.8.10.3
4938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    switch (support)
4948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
4958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case MediaPlayer::IsNotSupported:
4960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            canPlay = "";
4978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
4988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case MediaPlayer::MayBeSupported:
4998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            canPlay = "maybe";
5008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
5018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        case MediaPlayer::IsSupported:
5028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            canPlay = "probably";
5038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            break;
5048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
5058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5065abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::canPlayType(%s) -> %s", mimeType.utf8().data(), canPlay.utf8().data());
5075abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
5088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return canPlay;
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5115e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockvoid HTMLMediaElement::load(bool isUserGesture, ExceptionCode& ec)
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5135abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::load(isUserGesture : %s)", boolString(isUserGesture));
5145abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
5155e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    if (m_restrictions & RequireUserGestureForLoadRestriction && !isUserGesture)
5168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ec = INVALID_STATE_ERR;
517231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    else {
518e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        m_loadInitiatedByUserGesture = isUserGesture;
51931dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu#if PLATFORM(ANDROID)
52031dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu        m_userGestureInitiated |= isUserGesture;
52131dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu#endif
522231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        prepareForLoad();
5238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        loadInternal();
524231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
5258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
5268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
527231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLMediaElement::prepareForLoad()
5288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
5295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::prepareForLoad");
5305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
531231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Perform the cleanup required for the resource load algorithm to run.
5328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    stopPeriodicTimers();
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_loadTimer.stop();
5348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_sentStalledEvent = false;
5358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_haveFiredLoadedData = false;
536967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    m_completelyLoaded = false;
537dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    m_displayMode = Unknown;
5388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
539dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // 1 - Abort any already-running instance of the resource selection algorithm for this element.
540a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_loadState = WaitingForSource;
5418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_currentSourceNode = 0;
5428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
543dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // 2 - If there are any tasks from the media element's media element event task source in
5448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // one of the task queues, then remove those tasks.
5455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    cancelPendingEventsAndCallbacks();
546231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
547d0825bca7fe65beaee391d30da42e937db621564Steve Block    // 3 - If the media element's networkState is set to NETWORK_LOADING or NETWORK_IDLE, queue
548d0825bca7fe65beaee391d30da42e937db621564Steve Block    // a task to fire a simple event named abort at the media element.
549d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE)
550d0825bca7fe65beaee391d30da42e937db621564Steve Block        scheduleEvent(eventNames().abortEvent);
5518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
552dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
553dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_player = MediaPlayer::create(this);
554dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#else
555f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (m_player)
556f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        m_player->cancelLoad();
557f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    else
558f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        createMediaPlayerProxy();
559dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
560dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
561dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps
5628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_networkState != NETWORK_EMPTY) {
5638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_networkState = NETWORK_EMPTY;
5648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_readyState = HAVE_NOTHING;
56521939df44de1705786c545cd1bf519d47250322dBen Murdoch        m_readyStateMaximum = HAVE_NOTHING;
5666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        refreshCachedTime();
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_paused = true;
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_seeking = false;
569ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        invalidateCachedTime();
570d0825bca7fe65beaee391d30da42e937db621564Steve Block        scheduleEvent(eventNames().emptiedEvent);
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
572231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
573d0825bca7fe65beaee391d30da42e937db621564Steve Block    // 5 - Set the playbackRate attribute to the value of the defaultPlaybackRate attribute.
574d0825bca7fe65beaee391d30da42e937db621564Steve Block    setPlaybackRate(defaultPlaybackRate());
575d0825bca7fe65beaee391d30da42e937db621564Steve Block
576d0825bca7fe65beaee391d30da42e937db621564Steve Block    // 6 - Set the error attribute to null and the autoplaying flag to true.
577d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_error = 0;
578d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_autoplaying = true;
579d0825bca7fe65beaee391d30da42e937db621564Steve Block
580f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // 7 - Invoke the media element's resource selection algorithm.
581f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
582f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // 8 - Note: Playback of any previously playing media resource for this element stops.
583f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
584f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // The resource selection algorithm
585f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // 1 - Set the networkState to NETWORK_NO_SOURCE
586f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    m_networkState = NETWORK_NO_SOURCE;
587f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
588f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // 2 - Asynchronously await a stable state.
589f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
590d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_playedTimeRanges = TimeRanges::create();
591d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_lastSeekTime = 0;
592d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_closedCaptionsVisible = false;
5935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
5945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // The spec doesn't say to block the load event until we actually run the asynchronous section
5955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // algorithm, but do it now because we won't start that until after the timer fires and the
5965ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // event may have already fired by then.
5975ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    setShouldDelayLoadEvent(true);
598dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
599dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
600dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid HTMLMediaElement::loadInternal()
601dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
602dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // If we can't start a load right away, start it later.
603dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Page* page = document()->page();
604dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (page && !page->canStartMedia()) {
605dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (m_isWaitingUntilMediaCanStart)
606dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return;
6076c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        document()->addMediaCanStartListener(this);
608dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_isWaitingUntilMediaCanStart = true;
609dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return;
610dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
611dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
6128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    selectMediaResource();
6138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
6148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
6158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::selectMediaResource()
6168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
6175abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::selectMediaResource");
6185abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
619e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    enum Mode { attribute, children };
620e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    Mode mode = attribute;
621e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
622d0825bca7fe65beaee391d30da42e937db621564Steve Block    // 3 - ... the media element has neither a src attribute ...
623e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!hasAttribute(srcAttr)) {
624d0825bca7fe65beaee391d30da42e937db621564Steve Block        // ... nor a source element child: ...
625d0825bca7fe65beaee391d30da42e937db621564Steve Block        Node* node;
626d0825bca7fe65beaee391d30da42e937db621564Steve Block        for (node = firstChild(); node; node = node->nextSibling()) {
627d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (node->hasTagName(sourceTag))
628d0825bca7fe65beaee391d30da42e937db621564Steve Block                break;
629d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
6308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
631d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!node) {
632d0825bca7fe65beaee391d30da42e937db621564Steve Block            m_loadState = WaitingForSource;
6335ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            setShouldDelayLoadEvent(false);
634d0825bca7fe65beaee391d30da42e937db621564Steve Block
635d0825bca7fe65beaee391d30da42e937db621564Steve Block            // ... set the networkState to NETWORK_EMPTY, and abort these steps
636d0825bca7fe65beaee391d30da42e937db621564Steve Block            m_networkState = NETWORK_EMPTY;
6375abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
6385abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            LOG(Media, "HTMLMediaElement::selectMediaResource, nothing to load");
639d0825bca7fe65beaee391d30da42e937db621564Steve Block            return;
640d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
641e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
642e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        mode = children;
6438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
6448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
6455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // 4 - Set the media element's delaying-the-load-event flag to true (this delays the load event),
6465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // and set its networkState to NETWORK_LOADING.
6475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    setShouldDelayLoadEvent(true);
6488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_networkState = NETWORK_LOADING;
6498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
650cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    // 5
651643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    scheduleEvent(eventNames().loadstartEvent);
6528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
653e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // 6 - If mode is attribute, then run these substeps
654e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (mode == attribute) {
655e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // If the src attribute's value is the empty string ... jump down to the failed step below
656e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        KURL mediaURL = getNonEmptyURLAttribute(srcAttr);
657e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (mediaURL.isEmpty()) {
658e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            noneSupported();
6595abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            LOG(Media, "HTMLMediaElement::selectMediaResource, empty 'src'");
660e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
661e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
662e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
663cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        if (isSafeToLoadURL(mediaURL, Complain) && dispatchBeforeLoadEvent(mediaURL.string())) {
664e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            ContentType contentType("");
6655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_loadState = LoadingFromSrcAttr;
6665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            loadResource(mediaURL, contentType);
6675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        } else
6685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            noneSupported();
6695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
6705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        LOG(Media, "HTMLMediaElement::selectMediaResource, 'src' not used");
6718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
6728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
6738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
6748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Otherwise, the source elements will be used
6758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_currentSourceNode = 0;
6768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    loadNextSourceChild();
6778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
6788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
6798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::loadNextSourceChild()
6808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
6818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ContentType contentType("");
6825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    KURL mediaURL = selectNextSourceChild(&contentType, Complain);
6835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!mediaURL.isValid()) {
684d0825bca7fe65beaee391d30da42e937db621564Steve Block        waitForSourceChange();
6858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
688dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
689dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Recreate the media player for the new url
690dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_player = MediaPlayer::create(this);
691dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
692dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
6938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_loadState = LoadingFromSourceElement;
6945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    loadResource(mediaURL, contentType);
6958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
6968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
697231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& contentType)
6988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
699231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    ASSERT(isSafeToLoadURL(initialURL, Complain));
700231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
7015abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::loadResource(%s, %s)", urlForLogging(initialURL.string()).utf8().data(), contentType.raw().utf8().data());
7025abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
703231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    Frame* frame = document()->frame();
704231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!frame)
705231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
706231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    FrameLoader* loader = frame->loader();
707231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!loader)
708231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
709231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
710231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    KURL url(initialURL);
711231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!loader->willLoadMediaElementURL(url))
712231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
7138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
7145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // The resource fetch algorithm
7158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_networkState = NETWORK_LOADING;
7168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
7178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_currentSrc = url;
7188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
7195abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::loadResource - m_currentSrc -> %s", urlForLogging(m_currentSrc).utf8().data());
7205abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
7218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_sendProgressEvents)
7228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        startProgressEventTimer();
7238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
72481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Settings* settings = document()->settings();
72581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool privateMode = !settings || settings->privateBrowsingEnabled();
72681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_player->setPrivateBrowsingMode(privateMode);
72781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
728dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!autoplay())
729dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_player->setPreload(m_preload);
7300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_player->setPreservesPitch(m_webkitPreservesPitch);
7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    updateVolume();
7328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
7337f493d591dfd3492d5916ca301a4dbcd61554a06Nicolas Roard#if PLATFORM(ANDROID)
7347f493d591dfd3492d5916ca301a4dbcd61554a06Nicolas Roard    if (isVideo())
7357f493d591dfd3492d5916ca301a4dbcd61554a06Nicolas Roard        m_player->setMediaElementType(MediaPlayer::Video);
7367f493d591dfd3492d5916ca301a4dbcd61554a06Nicolas Roard    else
7377f493d591dfd3492d5916ca301a4dbcd61554a06Nicolas Roard        m_player->setMediaElementType(MediaPlayer::Audio);
7387f493d591dfd3492d5916ca301a4dbcd61554a06Nicolas Roard#endif
739e4ce886038eb870713831a36af88fc4692223ebaNicolas Roard    m_player->load(m_currentSrc, contentType);
7402471bb64fd133cc64b2048b1fb90c84e08c24a16Andrei Popescu
741dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    // If there is no poster to display, allow the media engine to render video frames as soon as
742dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    // they are available.
743dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    updateDisplayState();
7442471bb64fd133cc64b2048b1fb90c84e08c24a16Andrei Popescu
7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer())
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        renderer()->updateFromElement();
7478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
7488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
7495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidSourceAction actionIfInvalid)
7505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
7515abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (!url.isValid()) {
7525abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE because url is invalid", urlForLogging(url.string()).utf8().data());
753545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return false;
75468513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
7555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
75668513a70bcd92384395513322f1b801e7bf9c729Steve Block    Frame* frame = document()->frame();
75768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!frame || !document()->securityOrigin()->canDisplay(url)) {
7585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (actionIfInvalid == Complain)
7595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            FrameLoader::reportLocalLoadFailed(frame, url.string());
7605abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE rejected by SecurityOrigin", urlForLogging(url.string()).utf8().data());
7615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return false;
7625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
76368513a70bcd92384395513322f1b801e7bf9c729Steve Block
7642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!document()->contentSecurityPolicy()->allowMediaFromSource(url))
7652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return false;
7662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
7675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return true;
7685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
7695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::startProgressEventTimer()
7718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
7728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_progressEventTimer.isActive())
7738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
7748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
775635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_previousProgressTime = WTF::currentTime();
7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_previousProgress = 0;
7778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // 350ms is not magic, it is in the spec!
7788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_progressEventTimer.startRepeating(0.350);
7798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
7808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
781d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid HTMLMediaElement::waitForSourceChange()
782d0825bca7fe65beaee391d30da42e937db621564Steve Block{
7835abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::waitForSourceChange");
7845abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
785d0825bca7fe65beaee391d30da42e937db621564Steve Block    stopPeriodicTimers();
786d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_loadState = WaitingForSource;
787d0825bca7fe65beaee391d30da42e937db621564Steve Block
788d0825bca7fe65beaee391d30da42e937db621564Steve Block    // 6.17 - Waiting: Set the element's networkState attribute to the NETWORK_NO_SOURCE value
789d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_networkState = NETWORK_NO_SOURCE;
790d0825bca7fe65beaee391d30da42e937db621564Steve Block
791d0825bca7fe65beaee391d30da42e937db621564Steve Block    // 6.18 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
7925ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    setShouldDelayLoadEvent(false);
793d0825bca7fe65beaee391d30da42e937db621564Steve Block}
794d0825bca7fe65beaee391d30da42e937db621564Steve Block
7958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::noneSupported()
7968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
7975abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::noneSupported");
7985abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
7998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    stopPeriodicTimers();
8008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_loadState = WaitingForSource;
8018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_currentSourceNode = 0;
8028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
803cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    // 5 - Reaching this step indicates that either the URL failed to resolve, or the media
804231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // resource failed to load. Set the error attribute to a new MediaError object whose
8055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // code attribute is set to MEDIA_ERR_SRC_NOT_SUPPORTED.
8065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
8078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
808cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    // 6 - Set the element's networkState attribute to the NETWORK_NO_SOURCE value.
8098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_networkState = NETWORK_NO_SOURCE;
8108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
811cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    // 7 - Queue a task to fire a progress event called error at the media element, in
812231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // the context of the fetching process that was used to try to obtain the media
813231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // resource in the resource fetch algorithm.
814643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    scheduleEvent(eventNames().errorEvent);
8158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
816231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // 8 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
8175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    setShouldDelayLoadEvent(false);
8188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
819231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // 9 -Abort these steps. Until the load() method is invoked, the element won't attempt to load another resource.
820231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
821dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    updateDisplayState();
822692e5dbf12901edacf14812a6fae25462920af42Steve Block
8238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (renderer())
8248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        renderer()->updateFromElement();
8258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
8268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::mediaEngineError(PassRefPtr<MediaError> err)
8288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
8295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::mediaEngineError(%d)", static_cast<int>(err->code()));
8305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
8318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // 1 - The user agent should cancel the fetching process.
8328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    stopPeriodicTimers();
8338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_loadState = WaitingForSource;
8348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // 2 - Set the error attribute to a new MediaError object whose code attribute is
8368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // set to MEDIA_ERR_NETWORK/MEDIA_ERR_DECODE.
8378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_error = err;
8388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8395ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // 3 - Queue a task to fire a simple event named error at the media element.
840643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    scheduleEvent(eventNames().errorEvent);
8418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
842cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    // 4 - Set the element's networkState attribute to the NETWORK_EMPTY value and queue a
8438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // task to fire a simple event called emptied at the element.
8448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_networkState = NETWORK_EMPTY;
8458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    scheduleEvent(eventNames().emptiedEvent);
8468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
847cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    // 5 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
8485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    setShouldDelayLoadEvent(false);
8498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
850cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    // 6 - Abort the overall resource selection algorithm.
8518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_currentSourceNode = 0;
8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid HTMLMediaElement::cancelPendingEventsAndCallbacks()
8555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
8565abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks");
8575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
8585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_pendingEvents.clear();
8595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    for (Node* node = firstChild(); node; node = node->nextSibling()) {
8615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (node->hasTagName(sourceTag))
8625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            static_cast<HTMLSourceElement*>(node)->cancelPendingErrorEvent();
8635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
8645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
8655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
866dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockDocument* HTMLMediaElement::mediaPlayerOwningDocument()
867dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
868dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Document* d = document();
869dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
870dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!d)
871dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        d = ownerDocument();
872dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
873dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return d;
874dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
875dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
8768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    beginProcessingMediaPlayerCallback();
8798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setNetworkState(m_player->networkState());
8808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    endProcessingMediaPlayerCallback();
8818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
8828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
8848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
8855abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::setNetworkState(%d) - current state is %d", static_cast<int>(state), static_cast<int>(m_networkState));
8865abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
8878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (state == MediaPlayer::Empty) {
888a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Just update the cached state and leave, we can't do anything.
8898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_networkState = NETWORK_EMPTY;
8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
8918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
8928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (state == MediaPlayer::FormatError || state == MediaPlayer::NetworkError || state == MediaPlayer::DecodeError) {
8948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        stopPeriodicTimers();
8958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // If we failed while trying to load a <source> element, the movie was never parsed, and there are more
8975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // <source> children, schedule the next one
8985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement) {
899a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
900a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (m_currentSourceNode)
901a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                m_currentSourceNode->scheduleErrorEvent();
902a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            else
903a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                LOG(Media, "HTMLMediaElement::setNetworkState - error event not sent, <source> was removed");
904a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
9055abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            if (havePotentialSourceChild()) {
906a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                LOG(Media, "HTMLMediaElement::setNetworkState - scheduling next <source>");
907231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                scheduleNextSourceChild();
9085abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            } else {
909a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                LOG(Media, "HTMLMediaElement::setNetworkState - no more <source> elements, waiting");
910d0825bca7fe65beaee391d30da42e937db621564Steve Block                waitForSourceChange();
9115abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            }
912d0825bca7fe65beaee391d30da42e937db621564Steve Block
9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
9148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
9158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (state == MediaPlayer::NetworkError)
9178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            mediaEngineError(MediaError::create(MediaError::MEDIA_ERR_NETWORK));
9188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        else if (state == MediaPlayer::DecodeError)
9198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            mediaEngineError(MediaError::create(MediaError::MEDIA_ERR_DECODE));
9205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else if (state == MediaPlayer::FormatError && m_loadState == LoadingFromSrcAttr)
9218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            noneSupported();
9228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
923dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        updateDisplayState();
9242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (hasMediaControls())
9252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            mediaControls()->reportedError();
9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (state == MediaPlayer::Idle) {
9305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (m_networkState > NETWORK_IDLE) {
931dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_progressEventTimer.stop();
932643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            scheduleEvent(eventNames().suspendEvent);
9332bde8e466a4451c7319e3a072d118917957d6554Steve Block            setShouldDelayLoadEvent(false);
9345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
9358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_networkState = NETWORK_IDLE;
9368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (state == MediaPlayer::Loading) {
9395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (m_networkState < NETWORK_LOADING || m_networkState == NETWORK_NO_SOURCE)
9405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            startProgressEventTimer();
9418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_networkState = NETWORK_LOADING;
9428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (state == MediaPlayer::Loaded) {
945967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        if (m_networkState != NETWORK_IDLE) {
9465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_progressEventTimer.stop();
9478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
948231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Schedule one last progress event so we guarantee that at least one is fired
949231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // for files that load very quickly.
950643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            scheduleEvent(eventNames().progressEvent);
9515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
952967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        m_networkState = NETWORK_IDLE;
953967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        m_completelyLoaded = true;
9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (hasMediaControls())
9572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        mediaControls()->changedNetworkState();
9588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::mediaPlayerReadyStateChanged(MediaPlayer*)
9618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    beginProcessingMediaPlayerCallback();
9638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setReadyState(m_player->readyState());
9658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    endProcessingMediaPlayerCallback();
9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9715abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::setReadyState(%d) - current state is %d,", static_cast<int>(state), static_cast<int>(m_readyState));
9725abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
9738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Set "wasPotentiallyPlaying" BEFORE updating m_readyState, potentiallyPlaying() uses it
9748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool wasPotentiallyPlaying = potentiallyPlaying();
9758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ReadyState oldState = m_readyState;
9778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_readyState = static_cast<ReadyState>(state);
9788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_readyState == oldState)
9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
98221939df44de1705786c545cd1bf519d47250322dBen Murdoch    if (oldState > m_readyStateMaximum)
98321939df44de1705786c545cd1bf519d47250322dBen Murdoch        m_readyStateMaximum = oldState;
98421939df44de1705786c545cd1bf519d47250322dBen Murdoch
9858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_networkState == NETWORK_EMPTY)
9868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
988231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (m_seeking) {
989bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // 4.8.10.9, step 11
990231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA)
991231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            scheduleEvent(eventNames().waitingEvent);
992231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
993bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // 4.8.10.10 step 14 & 15.
994bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (m_readyState >= HAVE_CURRENT_DATA)
995231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            finishSeek();
996231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    } else {
997231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA) {
998bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            // 4.8.10.8
999231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            scheduleTimeupdateEvent(false);
1000231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            scheduleEvent(eventNames().waitingEvent);
1001231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
10028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
10038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
10048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) {
10058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleEvent(eventNames().durationchangeEvent);
10068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleEvent(eventNames().loadedmetadataEvent);
10072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (hasMediaControls())
10082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            mediaControls()->loadedMetadata();
1009dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        if (renderer())
1010dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            renderer()->updateFromElement();
10118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_player->seek(0);
10128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
10138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1014dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool shouldUpdateDisplayState = false;
1015d0825bca7fe65beaee391d30da42e937db621564Steve Block
10168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_haveFiredLoadedData) {
10178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_haveFiredLoadedData = true;
1018dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        shouldUpdateDisplayState = true;
10198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleEvent(eventNames().loadeddataEvent);
10205ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        setShouldDelayLoadEvent(false);
10218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
10228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
10238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool isPotentiallyPlaying = potentiallyPlaying();
10248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_readyState == HAVE_FUTURE_DATA && oldState <= HAVE_CURRENT_DATA) {
10258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleEvent(eventNames().canplayEvent);
10268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (isPotentiallyPlaying)
10278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            scheduleEvent(eventNames().playingEvent);
1028dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        shouldUpdateDisplayState = true;
10298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
10308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
10318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA) {
10328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (oldState <= HAVE_CURRENT_DATA)
10338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            scheduleEvent(eventNames().canplayEvent);
10348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
10358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleEvent(eventNames().canplaythroughEvent);
10368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
10378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (isPotentiallyPlaying && oldState <= HAVE_CURRENT_DATA)
10388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            scheduleEvent(eventNames().playingEvent);
10399abcc8af97ee9c535e4d0995b564471b3866f9e4Teng-Hui Zhu#if PLATFORM(ANDROID)
10409abcc8af97ee9c535e4d0995b564471b3866f9e4Teng-Hui Zhu        // autoplay should not be honored if we require user gesture.
10419abcc8af97ee9c535e4d0995b564471b3866f9e4Teng-Hui Zhu        if (!(m_restrictions & RequireUserGestureForRateChangeRestriction))
10429abcc8af97ee9c535e4d0995b564471b3866f9e4Teng-Hui Zhu#endif
10438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_autoplaying && m_paused && autoplay()) {
10448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_paused = false;
1045ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch            invalidateCachedTime();
10468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            scheduleEvent(eventNames().playEvent);
10478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            scheduleEvent(eventNames().playingEvent);
10488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
10498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1050dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        shouldUpdateDisplayState = true;
10518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1053dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    if (shouldUpdateDisplayState)
1054dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        updateDisplayState();
1055d0825bca7fe65beaee391d30da42e937db621564Steve Block
10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    updatePlayState();
10578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
10608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_player);
1062967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (m_networkState != NETWORK_LOADING)
10638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
10648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned progress = m_player->bytesLoaded();
1066635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    double time = WTF::currentTime();
10678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double timedelta = time - m_previousProgressTime;
10688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
10698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (progress == m_previousProgress) {
10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (timedelta > 3.0 && !m_sentStalledEvent) {
1071643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            scheduleEvent(eventNames().stalledEvent);
10728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_sentStalledEvent = true;
10732bde8e466a4451c7319e3a072d118917957d6554Steve Block            setShouldDelayLoadEvent(false);
10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
10758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
1076643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        scheduleEvent(eventNames().progressEvent);
10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_previousProgress = progress;
10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_previousProgressTime = time;
10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_sentStalledEvent = false;
1080643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (renderer())
1081643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            renderer()->updateFromElement();
10828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid HTMLMediaElement::rewind(float timeDelta)
10860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
10875abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::rewind(%f)", timeDelta);
10885abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
10890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ExceptionCode e;
10900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    setCurrentTime(max(currentTime() - timeDelta, minTimeSeekable()), e);
10910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
10920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
10930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid HTMLMediaElement::returnToRealtime()
10940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
10955abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::returnToRealtime");
10960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ExceptionCode e;
10970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    setCurrentTime(maxTimeSeekable(), e);
10980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
10990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLMediaElement::addPlayedRange(float start, float end)
1101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
11025abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::addPlayedRange(%f, %f)", start, end);
1103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!m_playedTimeRanges)
1104231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_playedTimeRanges = TimeRanges::create();
1105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_playedTimeRanges->add(start, end);
1106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
1107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
11080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool HTMLMediaElement::supportsSave() const
11090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
11100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return m_player ? m_player->supportsSave() : false;
11110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
11120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
11138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::seek(float time, ExceptionCode& ec)
11148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11155abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::seek(%f)", time);
11165abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
1117967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // 4.8.9.9 Seeking
1118967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
1119967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // 1 - If the media element's readyState is HAVE_NOTHING, then raise an INVALID_STATE_ERR exception.
11208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_readyState == HAVE_NOTHING || !m_player) {
11218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INVALID_STATE_ERR;
11228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
11238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1125967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // Get the current time before setting m_seeking, m_lastSeekTime is returned once it is set.
11266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    refreshCachedTime();
1127967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    float now = currentTime();
1128967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
1129bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // 2 - If the element's seeking IDL attribute is true, then another instance of this algorithm is
1130bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // already running. Abort that other instance of the algorithm without waiting for the step that
1131bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // it is running to complete.
1132bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Nothing specific to be done here.
1133bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1134967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // 3 - Set the seeking IDL attribute to true.
1135bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // The flag will be cleared when the engine tells us the time has actually changed.
1136967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    m_seeking = true;
1137967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
1138bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // 5 - If the new playback position is later than the end of the media resource, then let it be the end
1139967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // of the media resource instead.
11408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    time = min(time, duration());
11418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1142bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // 6 - If the new playback position is less than the earliest possible position, let it be that position instead.
1143967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    float earliestTime = m_player->startTime();
1144967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    time = max(time, earliestTime);
11458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
114628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    // Ask the media engine for the time value in the movie's time scale before comparing with current time. This
114728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    // is necessary because if the seek time is not equal to currentTime but the delta is less than the movie's
114828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    // time scale, we will ask the media engine to "seek" to the current movie time, which may be a noop and
114928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    // not generate a timechanged callback. This means m_seeking will never be cleared and we will never
115028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    // fire a 'seeked' event.
115128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu#if !LOG_DISABLED
115228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    float mediaTime = m_player->mediaTimeForTimeValue(time);
115328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (time != mediaTime)
115428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        LOG(Media, "HTMLMediaElement::seek(%f) - media timeline equivalent is %f", time, mediaTime);
115528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu#endif
115628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    time = m_player->mediaTimeForTimeValue(time);
115728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
1158bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // 7 - If the (possibly now changed) new playback position is not in one of the ranges given in the
1159967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // seekable attribute, then let it be the position in one of the ranges given in the seekable attribute
1160967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // that is the nearest to the new playback position. ... If there are no ranges given in the seekable
1161967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // attribute then set the seeking IDL attribute to false and abort these steps.
11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<TimeRanges> seekableRanges = seekable();
1163bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1164bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Short circuit seeking to the current time by just firing the events if no seek is required.
1165bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Don't skip calling the media engine if we are in poster mode because a seek should always
1166bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // cancel poster display.
1167bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    bool noSeekRequired = !seekableRanges->length() || (time == now && displayMode() != Poster);
1168bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (noSeekRequired) {
1169bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (time == now) {
1170bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            scheduleEvent(eventNames().seekingEvent);
1171bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            scheduleTimeupdateEvent(false);
1172bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            scheduleEvent(eventNames().seekedEvent);
1173bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        }
1174967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        m_seeking = false;
11758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1177967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    time = seekableRanges->nearest(time);
11788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
11795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_playing) {
11805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (m_lastSeekTime < now)
1181231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            addPlayedRange(m_lastSeekTime, now);
11825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
11835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_lastSeekTime = time;
1184967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    m_sentEndEvent = false;
11858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1186bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // 8 - Set the current playback position to the given new playback position
1187967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    m_player->seek(time);
11888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1189bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // 9 - Queue a task to fire a simple event named seeking at the element.
1190bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    scheduleEvent(eventNames().seekingEvent);
1191bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1192bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // 10 - Queue a task to fire a simple event named timeupdate at the element.
1193bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    scheduleTimeupdateEvent(false);
1194bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1195bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // 11-15 are handled, if necessary, when the engine signals a readystate change.
11968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1198231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLMediaElement::finishSeek()
1199231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
12005abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::finishSeek");
12015abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
1202bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // 4.8.10.9 Seeking step 14
1203231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_seeking = false;
1204231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1205bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // 4.8.10.9 Seeking step 15
1206231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    scheduleEvent(eventNames().seekedEvent);
1207dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
1208dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    setDisplayMode(Video);
1209231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
1210231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
12118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLMediaElement::ReadyState HTMLMediaElement::readyState() const
12128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_readyState;
12148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochMediaPlayer::MovieLoadType HTMLMediaElement::movieLoadType() const
12170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
12180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return m_player ? m_player->movieLoadType() : MediaPlayer::Unknown;
12190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
12200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1221231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool HTMLMediaElement::hasAudio() const
1222231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
1223231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return m_player ? m_player->hasAudio() : false;
1224231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
1225231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
12268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLMediaElement::seeking() const
12278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_seeking;
12298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid HTMLMediaElement::refreshCachedTime() const
12326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{
12336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    m_cachedTime = m_player->currentTime();
12346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    m_cachedTimeWallClockUpdateTime = WTF::currentTime();
12356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner}
12366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
12376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid HTMLMediaElement::invalidateCachedTime()
12386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{
12396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    LOG(Media, "HTMLMediaElement::invalidateCachedTime");
12406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
12416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // Don't try to cache movie time when playback first starts as the time reported by the engine
12426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // sometimes fluctuates for a short amount of time, so the cached time will be off if we take it
12436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // too early.
12446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    static const double minimumTimePlayingBeforeCacheSnapshot = 0.5;
12456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
12466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    m_minimumWallClockTimeToCacheMediaTime = WTF::currentTime() + minimumTimePlayingBeforeCacheSnapshot;
12476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    m_cachedTime = invalidMediaTime;
12486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner}
12496b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
12508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// playback state
12518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectfloat HTMLMediaElement::currentTime() const
12528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12536b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#if LOG_CACHED_TIME_WARNINGS
12546b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    static const double minCachedDeltaForWarning = 0.01;
12556b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#endif
12566b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
12578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_player)
12588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
12596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
12606b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (m_seeking) {
12616b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        LOG(Media, "HTMLMediaElement::currentTime - seeking, returning %f", m_lastSeekTime);
12625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return m_lastSeekTime;
12636b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }
12646b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
12656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (m_cachedTime != invalidMediaTime && m_paused) {
12666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#if LOG_CACHED_TIME_WARNINGS
12676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        float delta = m_cachedTime - m_player->currentTime();
12686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (delta > minCachedDeltaForWarning)
12696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            LOG(Media, "HTMLMediaElement::currentTime - WARNING, cached time is %f seconds off of media time when paused", delta);
12706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#endif
12716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return m_cachedTime;
12726b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }
12736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
12746b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // Is it too soon use a cached time?
12756b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    double now = WTF::currentTime();
12766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    double maximumDurationToCacheMediaTime = m_player->maximumDurationToCacheMediaTime();
12776b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
12786b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (maximumDurationToCacheMediaTime && m_cachedTime != invalidMediaTime && !m_paused && now > m_minimumWallClockTimeToCacheMediaTime) {
12796b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        double wallClockDelta = now - m_cachedTimeWallClockUpdateTime;
12806b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
12816b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        // Not too soon, use the cached time only if it hasn't expired.
12826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (wallClockDelta < maximumDurationToCacheMediaTime) {
12836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            float adjustedCacheTime = static_cast<float>(m_cachedTime + (m_playbackRate * wallClockDelta));
12846b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
12856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#if LOG_CACHED_TIME_WARNINGS
12866b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            float delta = adjustedCacheTime - m_player->currentTime();
12876b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            if (delta > minCachedDeltaForWarning)
12886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner                LOG(Media, "HTMLMediaElement::currentTime - WARNING, cached time is %f seconds off of media time when playing", delta);
12896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#endif
12906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            return adjustedCacheTime;
12916b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        }
12926b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }
12936b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
12946b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#if LOG_CACHED_TIME_WARNINGS
12956b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (maximumDurationToCacheMediaTime && now > m_minimumWallClockTimeToCacheMediaTime && m_cachedTime != invalidMediaTime) {
12966b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        double wallClockDelta = now - m_cachedTimeWallClockUpdateTime;
12976b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        float delta = m_cachedTime + (m_playbackRate * wallClockDelta) - m_player->currentTime();
12986b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        LOG(Media, "HTMLMediaElement::currentTime - cached time was %f seconds off of media time when it expired", delta);
12996b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }
13006b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#endif
13016b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
13026b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    refreshCachedTime();
13036b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
13046b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    return m_cachedTime;
13058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::setCurrentTime(float time, ExceptionCode& ec)
13088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    seek(time, ec);
13108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianfloat HTMLMediaElement::startTime() const
13135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
13145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!m_player)
13155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return 0;
13165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return m_player->startTime();
13175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
13185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectfloat HTMLMediaElement::duration() const
13208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1321dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (m_player && m_readyState >= HAVE_METADATA)
13228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return m_player->duration();
13238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
13248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return numeric_limits<float>::quiet_NaN();
13258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLMediaElement::paused() const
13288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_paused;
13308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectfloat HTMLMediaElement::defaultPlaybackRate() const
13338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_defaultPlaybackRate;
13358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::setDefaultPlaybackRate(float rate)
13388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_defaultPlaybackRate != rate) {
13408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_defaultPlaybackRate = rate;
13418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleEvent(eventNames().ratechangeEvent);
13428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectfloat HTMLMediaElement::playbackRate() const
13468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13472bde8e466a4451c7319e3a072d118917957d6554Steve Block    return m_playbackRate;
13488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::setPlaybackRate(float rate)
13518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13525abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::setPlaybackRate(%f)", rate);
13535abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
13548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_playbackRate != rate) {
13558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_playbackRate = rate;
1356ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        invalidateCachedTime();
13578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleEvent(eventNames().ratechangeEvent);
13588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_player && potentiallyPlaying() && m_player->rate() != rate)
13608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_player->setRate(rate);
13618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool HTMLMediaElement::webkitPreservesPitch() const
13640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
13650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return m_webkitPreservesPitch;
13660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
13670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
13680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid HTMLMediaElement::setWebkitPreservesPitch(bool preservesPitch)
13690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
13705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::setWebkitPreservesPitch(%s)", boolString(preservesPitch));
13715abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
13720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_webkitPreservesPitch = preservesPitch;
13730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
13740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!m_player)
13750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
13760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
13770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_player->setPreservesPitch(preservesPitch);
13780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
13790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
13808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLMediaElement::ended() const
13818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1382d0825bca7fe65beaee391d30da42e937db621564Steve Block    // 4.8.10.8 Playing the media resource
1383d0825bca7fe65beaee391d30da42e937db621564Steve Block    // The ended attribute must return true if the media element has ended
1384d0825bca7fe65beaee391d30da42e937db621564Steve Block    // playback and the direction of playback is forwards, and false otherwise.
1385d0825bca7fe65beaee391d30da42e937db621564Steve Block    return endedPlayback() && m_playbackRate > 0;
13868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLMediaElement::autoplay() const
13898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return hasAttribute(autoplayAttr);
13918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::setAutoplay(bool b)
13948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13955abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::setAutoplay(%s)", boolString(b));
13968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setBooleanAttribute(autoplayAttr, b);
13978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1399dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockString HTMLMediaElement::preload() const
14005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
1401dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    switch (m_preload) {
1402dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    case MediaPlayer::None:
1403dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return "none";
1404dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        break;
1405dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    case MediaPlayer::MetaData:
1406dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return "metadata";
1407dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        break;
1408dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    case MediaPlayer::Auto:
1409dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return "auto";
1410dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        break;
1411dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
1412dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1413dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ASSERT_NOT_REACHED();
1414dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return String();
14155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
14165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1417dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid HTMLMediaElement::setPreload(const String& preload)
14185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
14195abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::setPreload(%s)", preload.utf8().data());
1420dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    setAttribute(preloadAttr, preload);
14215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
14225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
14235e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockvoid HTMLMediaElement::play(bool isUserGesture)
14248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14255abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::play(isUserGesture : %s)", boolString(isUserGesture));
14265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
142731dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu    if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture
142831dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu#if PLATFORM(ANDROID)
142931dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu        && !m_userGestureInitiated
143031dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu#endif
143131dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu        )
14328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
14338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
143431dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu#if PLATFORM(ANDROID)
143531dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu    // B/c we set the restriction to require gesture for rate change for
143631dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu    // Android, when we don't early return, we can safely set this to true.
143731dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu    m_userGestureInitiated = true;
143831dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu#endif
143931dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu
144021939df44de1705786c545cd1bf519d47250322dBen Murdoch    Document* doc = document();
144121939df44de1705786c545cd1bf519d47250322dBen Murdoch    Settings* settings = doc->settings();
1442e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (settings && settings->needsSiteSpecificQuirks() && m_dispatchingCanPlayEvent && !m_loadInitiatedByUserGesture) {
144321939df44de1705786c545cd1bf519d47250322dBen Murdoch        // It should be impossible to be processing the canplay event while handling a user gesture
144421939df44de1705786c545cd1bf519d47250322dBen Murdoch        // since it is dispatched asynchronously.
144521939df44de1705786c545cd1bf519d47250322dBen Murdoch        ASSERT(!isUserGesture);
144621939df44de1705786c545cd1bf519d47250322dBen Murdoch        String host = doc->baseURL().host();
144721939df44de1705786c545cd1bf519d47250322dBen Murdoch        if (host.endsWith(".npr.org", false) || equalIgnoringCase(host, "npr.org"))
144821939df44de1705786c545cd1bf519d47250322dBen Murdoch            return;
144921939df44de1705786c545cd1bf519d47250322dBen Murdoch    }
145021939df44de1705786c545cd1bf519d47250322dBen Murdoch
14518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    playInternal();
14528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::playInternal()
14558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14565abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::playInternal");
14575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
14588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // 4.8.10.9. Playing the media resource
14598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!m_player || m_networkState == NETWORK_EMPTY)
14608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleLoad();
14618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (endedPlayback()) {
14638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ExceptionCode unused;
14648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        seek(0, unused);
14658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
14678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_paused) {
14688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_paused = false;
1469ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        invalidateCachedTime();
14708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleEvent(eventNames().playEvent);
14718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (m_readyState <= HAVE_CURRENT_DATA)
14738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            scheduleEvent(eventNames().waitingEvent);
14748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        else if (m_readyState >= HAVE_FUTURE_DATA)
14758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            scheduleEvent(eventNames().playingEvent);
14768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
14778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_autoplaying = false;
14788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    updatePlayState();
14808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14825e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockvoid HTMLMediaElement::pause(bool isUserGesture)
14838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14845abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::pause(isUserGesture : %s)", boolString(isUserGesture));
14855abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
148631dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu    if (m_restrictions & RequireUserGestureForRateChangeRestriction && !isUserGesture
148731dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu#if PLATFORM(ANDROID)
148831dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu        && !m_userGestureInitiated
148931dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu#endif
149031dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu        )
14918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
149231dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu#if PLATFORM(ANDROID)
149331dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu    // B/c we set the restriction to require gesture for rate change for
149431dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu    // Android, when we don't early return, we can safely set this to true.
149531dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu    m_userGestureInitiated = true;
149631dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu#endif
14978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    pauseInternal();
14988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::pauseInternal()
15028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15035abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::pauseInternal");
15045abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
15058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // 4.8.10.9. Playing the media resource
15068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!m_player || m_networkState == NETWORK_EMPTY)
15078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleLoad();
15088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_autoplaying = false;
15108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
15118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!m_paused) {
15128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_paused = true;
15138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleTimeupdateEvent(false);
15148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleEvent(eventNames().pauseEvent);
15158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
15168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    updatePlayState();
15188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool HTMLMediaElement::loop() const
15218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return hasAttribute(loopAttr);
15238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::setLoop(bool b)
15268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::setLoop(%s)", boolString(b));
15288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setBooleanAttribute(loopAttr, b);
15298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLMediaElement::controls() const
15328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Frame* frame = document()->frame();
15348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
15358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // always show controls when scripting is disabled
1536dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (frame && !frame->script()->canExecuteScripts(NotAboutToExecuteScript))
15378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return true;
15388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
153981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // always show controls for video when fullscreen playback is required.
154081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (isVideo() && document()->page() && document()->page()->chrome()->requiresFullscreenForVideoPlayback())
154181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return true;
154281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
15432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Always show controls when in full screen mode.
15442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (isFullscreen())
15452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return true;
15462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
15478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return hasAttribute(controlsAttr);
15488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::setControls(bool b)
15518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15525abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::setControls(%s)", boolString(b));
15538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setBooleanAttribute(controlsAttr, b);
15548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectfloat HTMLMediaElement::volume() const
15578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_volume;
15598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::setVolume(float vol, ExceptionCode& ec)
15628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1563a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    LOG(Media, "HTMLMediaElement::setVolume(%f)", vol);
15645abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
15658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (vol < 0.0f || vol > 1.0f) {
15668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INDEX_SIZE_ERR;
15678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
15688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_volume != vol) {
15718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_volume = vol;
15728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        updateVolume();
15738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleEvent(eventNames().volumechangeEvent);
15748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLMediaElement::muted() const
15788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_muted;
15808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::setMuted(bool muted)
15838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15845abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::setMuted(%s)", boolString(muted));
15855abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
15868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_muted != muted) {
15878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_muted = muted;
15885e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        // Avoid recursion when the player reports volume changes.
15895e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        if (!processingMediaPlayerCallback()) {
1590dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (m_player) {
15915e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block                m_player->setMuted(m_muted);
15922bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (hasMediaControls())
15932bde8e466a4451c7319e3a072d118917957d6554Steve Block                    mediaControls()->changedMute();
159481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
15955e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        }
15968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleEvent(eventNames().volumechangeEvent);
15978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::togglePlayState()
16018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16025abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::togglePlayState - canPlay() is %s", boolString(canPlay()));
16035abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
16048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // We can safely call the internal play/pause methods, which don't check restrictions, because
16058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // this method is only called from the built-in media controller
16062bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (canPlay()) {
16072bde8e466a4451c7319e3a072d118917957d6554Steve Block        setPlaybackRate(defaultPlaybackRate());
16088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        playInternal();
16092bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else
16108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        pauseInternal();
16118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::beginScrubbing()
16148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16155abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::beginScrubbing - paused() is %s", boolString(paused()));
16165abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
16178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!paused()) {
16188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (ended()) {
16198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // Because a media element stays in non-paused state when it reaches end, playback resumes
16208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // when the slider is dragged from the end to another position unless we pause first. Do
16218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // a "hard pause" so an event is generated, since we want to stay paused after scrubbing finishes.
16225e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block            pause(processingUserGesture());
16238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else {
16248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // Not at the end but we still want to pause playback so the media engine doesn't try to
16258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // continue playing during scrubbing. Pause without generating an event as we will
16268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // unpause after scrubbing finishes.
16278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            setPausedInternal(true);
16288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
16298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::endScrubbing()
16338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    LOG(Media, "HTMLMediaElement::endScrubbing - m_pausedInternal is %s", boolString(m_pausedInternal));
16355abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
16368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_pausedInternal)
16378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        setPausedInternal(false);
16388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
16398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
16408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// The spec says to fire periodic timeupdate events (those sent while playing) every
16418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// "15 to 250ms", we choose the slowest frequency
16428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic const double maxTimeupdateEventFrequency = 0.25;
16438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
16448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::startPlaybackProgressTimer()
16458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
16468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_playbackProgressTimer.isActive())
16478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
16488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
16498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_previousProgressTime = WTF::currentTime();
16508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_previousProgress = 0;
16518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency);
16528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
16538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
16548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>*)
16558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
16568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(m_player);
16578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!m_playbackRate)
16588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
16598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
16608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    scheduleTimeupdateEvent(true);
16612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (hasMediaControls()) {
16620676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu#if PLATFORM(ANDROID)
1663b96809187131720dd04bfca638ae069459878157Teng-Hui Zhu        m_mouseOver = WTF::currentTime() - m_lastTouch <= TOUCH_DELAY;
16640676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu#endif
1665b96809187131720dd04bfca638ae069459878157Teng-Hui Zhu        if (!m_mouseOver && controls() && hasVideo())
16662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            mediaControls()->makeTransparent();
1667b96809187131720dd04bfca638ae069459878157Teng-Hui Zhu
16682bde8e466a4451c7319e3a072d118917957d6554Steve Block        mediaControls()->playbackProgressed();
16692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
16708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // FIXME: deal with cue ranges here
16718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
16728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent)
16748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
16758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    double now = WTF::currentTime();
16768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    double timedelta = now - m_lastTimeUpdateEventWallTime;
16778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
16788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // throttle the periodic events
16798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (periodicEvent && timedelta < maxTimeupdateEventFrequency)
16808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
16818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
16828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Some media engines make multiple "time changed" callbacks at the same time, but we only want one
16838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // event at a given time so filter here
16846b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    float movieTime = currentTime();
16858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (movieTime != m_lastTimeUpdateEventMovieTime) {
16868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        scheduleEvent(eventNames().timeupdateEvent);
16878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_lastTimeUpdateEventWallTime = now;
16888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_lastTimeUpdateEventMovieTime = movieTime;
16898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
16908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
16918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
16928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool HTMLMediaElement::canPlay() const
16938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
16948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return paused() || ended() || m_readyState < HAVE_METADATA;
16958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
16968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
16970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochfloat HTMLMediaElement::percentLoaded() const
16980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
16990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!m_player)
17000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return 0;
17010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    float duration = m_player->duration();
1702231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1703231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!duration || isinf(duration))
1704231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return 0;
1705231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1706231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    float buffered = 0;
1707231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<TimeRanges> timeRanges = m_player->buffered();
1708231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    for (unsigned i = 0; i < timeRanges->length(); ++i) {
1709231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ExceptionCode ignoredException;
1710231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        float start = timeRanges->start(i, ignoredException);
1711231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        float end = timeRanges->end(i, ignoredException);
1712231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        buffered += end - start;
1713231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1714231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return buffered / duration;
17150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
17160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
17178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool HTMLMediaElement::havePotentialSourceChild()
17188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1719a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Stash the current <source> node and next nodes so we can restore them after checking
1720a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // to see there is another potential.
17215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    HTMLSourceElement* currentSourceNode = m_currentSourceNode;
1722a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    Node* nextNode = m_nextChildNodeToConsider;
1723a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
17245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    KURL nextURL = selectNextSourceChild(0, DoNothing);
1725a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
17268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_currentSourceNode = currentSourceNode;
1727a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_nextChildNodeToConsider = nextNode;
17288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
17295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return nextURL.isValid();
17308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
17318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
17325f1ab04193ad0130ca8204aadaceae083aca9881Feng QianKURL HTMLMediaElement::selectNextSourceChild(ContentType *contentType, InvalidSourceAction actionIfInvalid)
17338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
17345abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#if !LOG_DISABLED
17355abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    // Don't log if this was just called to find out if there are any valid <source> elements.
17365abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    bool shouldLog = actionIfInvalid != DoNothing;
17375abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (shouldLog)
17385abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        LOG(Media, "HTMLMediaElement::selectNextSourceChild(contentType : \"%s\")", contentType ? contentType->raw().utf8().data() : "");
17395abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#endif
17405abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
1741a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (m_nextChildNodeToConsider == sourceChildEndOfListValue()) {
1742a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#if !LOG_DISABLED
1743a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (shouldLog)
1744a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            LOG(Media, "HTMLMediaElement::selectNextSourceChild -> 0x0000, \"\"");
1745a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif
1746a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return KURL();
1747a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1748a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
17495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    KURL mediaURL;
17505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Node* node;
1751a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    HTMLSourceElement* source = 0;
1752a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool lookingForStartNode = m_nextChildNodeToConsider;
17535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    bool canUse = false;
17548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
17555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    for (node = firstChild(); !canUse && node; node = node->nextSibling()) {
1756a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (lookingForStartNode && m_nextChildNodeToConsider != node)
17578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            continue;
1758a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        lookingForStartNode = false;
1759a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1760a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!node->hasTagName(sourceTag))
17618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            continue;
17625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1763a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        source = static_cast<HTMLSourceElement*>(node);
17645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1765e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // If candidate does not have a src attribute, or if its src attribute's value is the empty string ... jump down to the failed step below
1766e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        mediaURL = source->getNonEmptyURLAttribute(srcAttr);
17675abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#if !LOG_DISABLED
17685abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if (shouldLog)
17695abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'src' is %s", urlForLogging(mediaURL).utf8().data());
17705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#endif
1771e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (mediaURL.isEmpty())
1772e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            goto check_again;
1773e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
17748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (source->hasAttribute(mediaAttr)) {
17758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            MediaQueryEvaluator screenEval("screen", document()->frame(), renderer() ? renderer()->style() : 0);
17768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(source->media());
17775abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#if !LOG_DISABLED
17785abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            if (shouldLog)
17795abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'media' is %s", source->media().utf8().data());
17805abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#endif
17815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (!screenEval.eval(media.get()))
17825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                goto check_again;
17838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
17848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
17855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (source->hasAttribute(typeAttr)) {
17865abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#if !LOG_DISABLED
17875abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            if (shouldLog)
17885abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick                LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'type' is %s", source->type().utf8().data());
17895abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#endif
17905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (!MediaPlayer::supportsType(ContentType(source->type())))
17915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                goto check_again;
17928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
17938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // Is it safe to load this url?
1795545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (!isSafeToLoadURL(mediaURL, actionIfInvalid) || !dispatchBeforeLoadEvent(mediaURL.string()))
17965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            goto check_again;
17975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1798a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Making it this far means the <source> looks reasonable.
17995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        canUse = true;
18005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
18015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qiancheck_again:
18025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!canUse && actionIfInvalid == Complain)
18035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            source->scheduleErrorEvent();
18045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
18058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1806a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (canUse) {
1807a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (contentType)
1808a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            *contentType = ContentType(source->type());
1809a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_currentSourceNode = source;
1810a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_nextChildNodeToConsider = source->nextSibling();
1811a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!m_nextChildNodeToConsider)
1812a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            m_nextChildNodeToConsider = sourceChildEndOfListValue();
1813a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else {
18145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_currentSourceNode = 0;
1815a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_nextChildNodeToConsider = sourceChildEndOfListValue();
1816a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1817a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
18185abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#if !LOG_DISABLED
18195abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (shouldLog)
1820a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        LOG(Media, "HTMLMediaElement::selectNextSourceChild -> %p, %s", m_currentSourceNode, canUse ? urlForLogging(mediaURL.string()).utf8().data() : "");
18215abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#endif
18225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return canUse ? mediaURL : KURL();
18238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1825a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source)
1826a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1827a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    LOG(Media, "HTMLMediaElement::sourceWasAdded(%p)", source);
1828a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1829a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#if !LOG_DISABLED
1830a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (source->hasTagName(sourceTag)) {
1831a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        KURL url = source->getNonEmptyURLAttribute(srcAttr);
1832a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        LOG(Media, "HTMLMediaElement::sourceWasAdded - 'src' is %s", urlForLogging(url).utf8().data());
1833a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1834a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif
1835a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1836a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // We should only consider a <source> element when there is not src attribute at all.
1837a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (hasAttribute(srcAttr))
1838a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
1839a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1840a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // 4.8.8 - If a source element is inserted as a child of a media element that has no src
1841a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // attribute and whose networkState has the value NETWORK_EMPTY, the user agent must invoke
1842a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // the media element's resource selection algorithm.
1843a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (networkState() == HTMLMediaElement::NETWORK_EMPTY) {
1844a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        scheduleLoad();
1845a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
1846a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1847a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1848a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (m_currentSourceNode && source == m_currentSourceNode->nextSibling()) {
1849a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        LOG(Media, "HTMLMediaElement::sourceWasAdded - <source> inserted immediately after current source");
1850a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_nextChildNodeToConsider = source;
1851a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
1852a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1853a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1854a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (m_nextChildNodeToConsider != sourceChildEndOfListValue())
1855a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
1856a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1857a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // 4.8.9.5, resource selection algorithm, source elements section:
1858a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // 20 - Wait until the node after pointer is a node other than the end of the list. (This step might wait forever.)
1859a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // 21 - Asynchronously await a stable state...
1860a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // 22 - Set the element's delaying-the-load-event flag back to true (this delays the load event again, in case
1861a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // it hasn't been fired yet).
1862a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    setShouldDelayLoadEvent(true);
1863a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1864a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // 23 - Set the networkState back to NETWORK_LOADING.
1865a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_networkState = NETWORK_LOADING;
1866a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1867a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // 24 - Jump back to the find next candidate step above.
1868a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_nextChildNodeToConsider = source;
1869a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    scheduleNextSourceChild();
1870a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1871a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1872a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid HTMLMediaElement::sourceWillBeRemoved(HTMLSourceElement* source)
1873a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1874a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    LOG(Media, "HTMLMediaElement::sourceWillBeRemoved(%p)", source);
1875a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1876a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#if !LOG_DISABLED
1877a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (source->hasTagName(sourceTag)) {
1878a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        KURL url = source->getNonEmptyURLAttribute(srcAttr);
1879a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        LOG(Media, "HTMLMediaElement::sourceWillBeRemoved - 'src' is %s", urlForLogging(url).utf8().data());
1880a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1881a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif
1882a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1883a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (source != m_currentSourceNode && source != m_nextChildNodeToConsider)
1884a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
1885a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1886a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (source == m_nextChildNodeToConsider) {
1887a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_nextChildNodeToConsider = m_nextChildNodeToConsider->nextSibling();
1888a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!m_nextChildNodeToConsider)
1889a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            m_nextChildNodeToConsider = sourceChildEndOfListValue();
1890a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        LOG(Media, "HTMLMediaElement::sourceRemoved - m_nextChildNodeToConsider set to %p", m_nextChildNodeToConsider);
1891a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else if (source == m_currentSourceNode) {
1892a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // Clear the current source node pointer, but don't change the movie as the spec says:
1893a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // 4.8.8 - Dynamically modifying a source element and its attribute when the element is already
1894a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // inserted in a video or audio element will have no effect.
1895a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_currentSourceNode = 0;
1896a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        LOG(Media, "HTMLMediaElement::sourceRemoved - m_currentSourceNode set to 0");
1897a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1898a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1899a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
19008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*)
19018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
19025abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::mediaPlayerTimeChanged");
19035abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
19048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    beginProcessingMediaPlayerCallback();
19058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
19066b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    invalidateCachedTime();
1907d0825bca7fe65beaee391d30da42e937db621564Steve Block
1908bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // 4.8.10.9 step 14 & 15.  Needed if no ReadyState change is associated with the seek.
1909bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (m_seeking && m_readyState >= HAVE_CURRENT_DATA)
1910231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        finishSeek();
19118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19126b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // Always call scheduleTimeupdateEvent when the media engine reports a time discontinuity,
19136b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // it will only queue a 'timeupdate' event if we haven't already posted one at the current
19146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // movie time.
19156b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    scheduleTimeupdateEvent(false);
19166b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
19178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    float now = currentTime();
19188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    float dur = duration();
19195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!isnan(dur) && dur && now >= dur) {
19208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (loop()) {
19218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            ExceptionCode ignoredException;
19228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            m_sentEndEvent = false;
19238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            seek(0, ignoredException);
19248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else {
19258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!m_sentEndEvent) {
19268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                m_sentEndEvent = true;
19278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                scheduleEvent(eventNames().endedEvent);
19288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
19298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
19308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
19318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    else
19328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_sentEndEvent = false;
19338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    updatePlayState();
19358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    endProcessingMediaPlayerCallback();
19368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
19378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::mediaPlayerVolumeChanged(MediaPlayer*)
19398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
19405abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::mediaPlayerVolumeChanged");
19415abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
19428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    beginProcessingMediaPlayerCallback();
194381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_player) {
194481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        float vol = m_player->volume();
194581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (vol != m_volume) {
194681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            m_volume = vol;
194781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            updateVolume();
194881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            scheduleEvent(eventNames().volumechangeEvent);
194981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
195081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
19518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    endProcessingMediaPlayerCallback();
19528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
19538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
19545e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockvoid HTMLMediaElement::mediaPlayerMuteChanged(MediaPlayer*)
19555e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{
19565abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::mediaPlayerMuteChanged");
19575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
19585e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    beginProcessingMediaPlayerCallback();
19595e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    if (m_player)
19605e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        setMuted(m_player->muted());
19615e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    endProcessingMediaPlayerCallback();
19625e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block}
19635e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block
19648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::mediaPlayerDurationChanged(MediaPlayer*)
19658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
19665abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::mediaPlayerDurationChanged");
19675abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
19688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    beginProcessingMediaPlayerCallback();
19698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    scheduleEvent(eventNames().durationchangeEvent);
1970dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    if (renderer())
19718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        renderer()->updateFromElement();
19728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    endProcessingMediaPlayerCallback();
1973d29efd6d376d29ec2695f8d3bc093d683f5dd119Teng-Hui Zhu
1974d29efd6d376d29ec2695f8d3bc093d683f5dd119Teng-Hui Zhu#if PLATFORM(ANDROID)
1975d29efd6d376d29ec2695f8d3bc093d683f5dd119Teng-Hui Zhu    if (hasMediaControls())
1976d29efd6d376d29ec2695f8d3bc093d683f5dd119Teng-Hui Zhu        mediaControls()->reset();
1977d29efd6d376d29ec2695f8d3bc093d683f5dd119Teng-Hui Zhu#endif
19788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
19798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
19808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::mediaPlayerRateChanged(MediaPlayer*)
19818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
19825abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::mediaPlayerRateChanged");
19835abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
19848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    beginProcessingMediaPlayerCallback();
19856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
19866b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    invalidateCachedTime();
19876b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
19888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Stash the rate in case the one we tried to set isn't what the engine is
19898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // using (eg. it can't handle the rate we set)
19908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_playbackRate = m_player->rate();
1991ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    invalidateCachedTime();
19928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    endProcessingMediaPlayerCallback();
19938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
19948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
19955abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid HTMLMediaElement::mediaPlayerPlaybackStateChanged(MediaPlayer*)
19965abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
19975abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::mediaPlayerPlaybackStateChanged");
19985abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
19992bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!m_player || m_pausedInternal)
20005abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        return;
20015abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
20025abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    beginProcessingMediaPlayerCallback();
20035abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (m_player->paused())
20045abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        pauseInternal();
20055abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    else
20065abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        playInternal();
20075abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    endProcessingMediaPlayerCallback();
20085abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
20095abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
20100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid HTMLMediaElement::mediaPlayerSawUnsupportedTracks(MediaPlayer*)
20110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
20125abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::mediaPlayerSawUnsupportedTracks");
20135abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
20140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // The MediaPlayer came across content it cannot completely handle.
20150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // This is normally acceptable except when we are in a standalone
20160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // MediaDocument. If so, tell the document what has happened.
20170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (ownerDocument()->isMediaDocument()) {
20180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        MediaDocument* mediaDocument = static_cast<MediaDocument*>(ownerDocument());
20190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        mediaDocument->mediaElementSawUnsupportedTracks();
20200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
20210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
20220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
20230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// MediaPlayerPresentation methods
20240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid HTMLMediaElement::mediaPlayerRepaint(MediaPlayer*)
20250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
20260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    beginProcessingMediaPlayerCallback();
2027dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    updateDisplayState();
20280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (renderer())
20290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        renderer()->repaint();
20300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    endProcessingMediaPlayerCallback();
20310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
20320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
20338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::mediaPlayerSizeChanged(MediaPlayer*)
20348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
20355abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::mediaPlayerSizeChanged");
20365abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
20378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    beginProcessingMediaPlayerCallback();
2038dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    if (renderer())
2039dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        renderer()->updateFromElement();
20408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    endProcessingMediaPlayerCallback();
20418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
20428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
20430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if USE(ACCELERATED_COMPOSITING)
20440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool HTMLMediaElement::mediaPlayerRenderingCanBeAccelerated(MediaPlayer*)
20455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
20460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (renderer() && renderer()->isVideo()) {
20470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ASSERT(renderer()->view());
20480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return renderer()->view()->compositor()->canAccelerateVideoRendering(toRenderVideo(renderer()));
20495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
20500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return false;
20510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
20520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2053692e5dbf12901edacf14812a6fae25462920af42Steve Blockvoid HTMLMediaElement::mediaPlayerRenderingModeChanged(MediaPlayer*)
20540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
20555abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::mediaPlayerRenderingModeChanged");
20565abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
2057692e5dbf12901edacf14812a6fae25462920af42Steve Block    // Kick off a fake recalcStyle that will update the compositing tree.
2058692e5dbf12901edacf14812a6fae25462920af42Steve Block    setNeedsStyleRecalc(SyntheticStyleChange);
20595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
20600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
20615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2062f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid HTMLMediaElement::mediaPlayerEngineUpdated(MediaPlayer*)
2063f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
2064f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    LOG(Media, "HTMLMediaElement::mediaPlayerEngineUpdated");
20652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    beginProcessingMediaPlayerCallback();
2066f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (renderer())
2067f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        renderer()->updateFromElement();
2068f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    endProcessingMediaPlayerCallback();
2069f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
2070f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
20712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid HTMLMediaElement::mediaPlayerFirstVideoFrameAvailable(MediaPlayer*)
20722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
20732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    LOG(Media, "HTMLMediaElement::mediaPlayerFirstVideoFrameAvailable");
20742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    beginProcessingMediaPlayerCallback();
20752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (displayMode() == PosterWaitingForVideo) {
20762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        setDisplayMode(Video);
20772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if USE(ACCELERATED_COMPOSITING)
20782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        mediaPlayerRenderingModeChanged(m_player.get());
20792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif
20802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
20812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    endProcessingMediaPlayerCallback();
20822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
20832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
20848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<TimeRanges> HTMLMediaElement::buffered() const
20858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2086231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!m_player)
20878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return TimeRanges::create();
2088231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return m_player->buffered();
20898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
20908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2091231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockPassRefPtr<TimeRanges> HTMLMediaElement::played()
20928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
20935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_playing) {
20945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        float time = currentTime();
2095231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (time > m_lastSeekTime)
2096231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            addPlayedRange(m_lastSeekTime, time);
20975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2098231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2099231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!m_playedTimeRanges)
2100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_playedTimeRanges = TimeRanges::create();
2101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
21025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return m_playedTimeRanges->copy();
21038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<TimeRanges> HTMLMediaElement::seekable() const
21068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME real ranges support
21080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!maxTimeSeekable())
21098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return TimeRanges::create();
21100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return TimeRanges::create(minTimeSeekable(), maxTimeSeekable());
21118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool HTMLMediaElement::potentiallyPlaying() const
21148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
211521939df44de1705786c545cd1bf519d47250322dBen Murdoch    // "pausedToBuffer" means the media engine's rate is 0, but only because it had to stop playing
211621939df44de1705786c545cd1bf519d47250322dBen Murdoch    // when it ran out of buffered data. A movie is this state is "potentially playing", modulo the
211721939df44de1705786c545cd1bf519d47250322dBen Murdoch    // checks in couldPlayIfEnoughData().
211821939df44de1705786c545cd1bf519d47250322dBen Murdoch    bool pausedToBuffer = m_readyStateMaximum >= HAVE_FUTURE_DATA && m_readyState < HAVE_FUTURE_DATA;
211921939df44de1705786c545cd1bf519d47250322dBen Murdoch    return (pausedToBuffer || m_readyState >= HAVE_FUTURE_DATA) && couldPlayIfEnoughData();
21208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21222b3d345465fdf225609499ffc5b1732157cafa22Andrei Popescubool HTMLMediaElement::couldPlayIfEnoughData() const
21232b3d345465fdf225609499ffc5b1732157cafa22Andrei Popescu{
21242b3d345465fdf225609499ffc5b1732157cafa22Andrei Popescu    return !paused() && !endedPlayback() && !stoppedDueToErrors() && !pausedForUserInteraction();
21252b3d345465fdf225609499ffc5b1732157cafa22Andrei Popescu}
21262b3d345465fdf225609499ffc5b1732157cafa22Andrei Popescu
21278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool HTMLMediaElement::endedPlayback() const
21288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2129d0825bca7fe65beaee391d30da42e937db621564Steve Block    float dur = duration();
2130d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (!m_player || isnan(dur))
2131d0825bca7fe65beaee391d30da42e937db621564Steve Block        return false;
2132d0825bca7fe65beaee391d30da42e937db621564Steve Block
2133d0825bca7fe65beaee391d30da42e937db621564Steve Block    // 4.8.10.8 Playing the media resource
2134d0825bca7fe65beaee391d30da42e937db621564Steve Block
2135d0825bca7fe65beaee391d30da42e937db621564Steve Block    // A media element is said to have ended playback when the element's
2136d0825bca7fe65beaee391d30da42e937db621564Steve Block    // readyState attribute is HAVE_METADATA or greater,
2137d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (m_readyState < HAVE_METADATA)
21385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return false;
2139f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2140f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // and the current playback position is the end of the media resource and the direction
2141d0825bca7fe65beaee391d30da42e937db621564Steve Block    // of playback is forwards and the media element does not have a loop attribute specified,
2142d0825bca7fe65beaee391d30da42e937db621564Steve Block    float now = currentTime();
2143d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (m_playbackRate > 0)
2144f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return dur > 0 && now >= dur && !loop();
2145f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2146d0825bca7fe65beaee391d30da42e937db621564Steve Block    // or the current playback position is the earliest possible position and the direction
2147d0825bca7fe65beaee391d30da42e937db621564Steve Block    // of playback is backwards
2148d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (m_playbackRate < 0)
2149d0825bca7fe65beaee391d30da42e937db621564Steve Block        return now <= 0;
2150d0825bca7fe65beaee391d30da42e937db621564Steve Block
2151d0825bca7fe65beaee391d30da42e937db621564Steve Block    return false;
21528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool HTMLMediaElement::stoppedDueToErrors() const
21558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_readyState >= HAVE_METADATA && m_error) {
21578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RefPtr<TimeRanges> seekableRanges = seekable();
21588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!seekableRanges->contain(currentTime()))
21598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return true;
21608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
21618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
21628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return false;
21638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool HTMLMediaElement::pausedForUserInteraction() const
21668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian//    return !paused() && m_readyState >= HAVE_FUTURE_DATA && [UA requires a decitions from the user]
21688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return false;
21698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochfloat HTMLMediaElement::minTimeSeekable() const
21720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
21730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return 0;
21740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
21750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
21760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochfloat HTMLMediaElement::maxTimeSeekable() const
21770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
21780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return m_player ? m_player->maxTimeSeekable() : 0;
21790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
21800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
21818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::updateVolume()
21828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_player)
21848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
21858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Avoid recursion when the player reports volume changes.
21878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!processingMediaPlayerCallback()) {
21888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        Page* page = document()->page();
21898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        float volumeMultiplier = page ? page->mediaVolume() : 1;
21908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2191dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_player->setMuted(m_muted);
2192dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_player->setVolume(m_volume * volumeMultiplier);
21938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
21942bde8e466a4451c7319e3a072d118917957d6554Steve Block
21952bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (hasMediaControls())
21962bde8e466a4451c7319e3a072d118917957d6554Steve Block        mediaControls()->changedVolume();
21978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::updatePlayState()
22008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
22018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_player)
22028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
22038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
22048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_pausedInternal) {
22058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!m_player->paused())
22068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_player->pause();
22076b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        refreshCachedTime();
22088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_playbackProgressTimer.stop();
22092bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (hasMediaControls())
22102bde8e466a4451c7319e3a072d118917957d6554Steve Block            mediaControls()->playbackStopped();
22118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
22128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
22138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool shouldBePlaying = potentiallyPlaying();
22158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool playerPaused = m_player->paused();
22165abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
22175abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::updatePlayState - shouldBePlaying = %s, playerPaused = %s",
22185abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        boolString(shouldBePlaying), boolString(playerPaused));
22195abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
22205abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (shouldBePlaying) {
2221dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        setDisplayMode(Video);
22226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        invalidateCachedTime();
2223dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
22245abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if (playerPaused) {
2225cad810f21b803229eb11403f9209855525a25d57Steve Block            if (!m_isFullscreen && isVideo() && document() && document()->page() && document()->page()->chrome()->requiresFullscreenForVideoPlayback())
2226f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                enterFullscreen();
2227f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
22282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            // Set rate, muted before calling play in case they were set before the media engine was setup.
22292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            // The media engine should just stash the rate and muted values since it isn't already playing.
22305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            m_player->setRate(m_playbackRate);
22312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            m_player->setMuted(m_muted);
22322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
22335abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            m_player->play();
22345abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        }
22355abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
22362bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (hasMediaControls())
22372bde8e466a4451c7319e3a072d118917957d6554Steve Block            mediaControls()->playbackStarted();
22388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        startPlaybackProgressTimer();
22395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_playing = true;
22405abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
22415abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    } else { // Should not be playing right now
22425abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if (!playerPaused)
22435abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            m_player->pause();
22446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        refreshCachedTime();
22455abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
22468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_playbackProgressTimer.stop();
22475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_playing = false;
22485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        float time = currentTime();
2249231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (time > m_lastSeekTime)
2250231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            addPlayedRange(m_lastSeekTime, time);
22515abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
22525abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        if (couldPlayIfEnoughData())
22535abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick            m_player->prepareToPlay();
22542bde8e466a4451c7319e3a072d118917957d6554Steve Block
22552bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (hasMediaControls())
22562bde8e466a4451c7319e3a072d118917957d6554Steve Block            mediaControls()->playbackStopped();
22575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    }
2258231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
22598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer())
22608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        renderer()->updateFromElement();
22618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::setPausedInternal(bool b)
22648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
22658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_pausedInternal = b;
22668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    updatePlayState();
22678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::stopPeriodicTimers()
22708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
22718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_progressEventTimer.stop();
22728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_playbackProgressTimer.stop();
22738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
22748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
22758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::userCancelledLoad()
22768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
22775abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::userCancelledLoad");
2278201aaaf60289868ccc1fb389c3372d9d0cede529Teng-Hui Zhu#if PLATFORM(ANDROID)
2279201aaaf60289868ccc1fb389c3372d9d0cede529Teng-Hui Zhu    if (m_networkState == NETWORK_EMPTY)
2280201aaaf60289868ccc1fb389c3372d9d0cede529Teng-Hui Zhu#else
2281967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (m_networkState == NETWORK_EMPTY || m_completelyLoaded)
2282201aaaf60289868ccc1fb389c3372d9d0cede529Teng-Hui Zhu#endif
2283231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
22848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2285231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // If the media data fetching process is aborted by the user:
22868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2287231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // 1 - The user agent should cancel the fetching process.
22888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
2289231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_player.clear();
22908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
2291231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    stopPeriodicTimers();
22922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_loadTimer.stop();
2293a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_loadState = WaitingForSource;
22948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2295cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    // 2 - Set the error attribute to a new MediaError object whose code attribute is set to MEDIA_ERR_ABORTED.
2296231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED);
22978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
22985ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // 3 - Queue a task to fire a simple event named error at the media element.
2299643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    scheduleEvent(eventNames().abortEvent);
23008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
23015ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // 4 - If the media element's readyState attribute has a value equal to HAVE_NOTHING, set the
23025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // element's networkState attribute to the NETWORK_EMPTY value and queue a task to fire a
23035ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // simple event named emptied at the element. Otherwise, set the element's networkState
2304231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // attribute to the NETWORK_IDLE value.
2305231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (m_readyState == HAVE_NOTHING) {
2306231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_networkState = NETWORK_EMPTY;
2307231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        scheduleEvent(eventNames().emptiedEvent);
23088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2309231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    else
2310231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_networkState = NETWORK_IDLE;
2311231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
23125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // 5 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
23135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    setShouldDelayLoadEvent(false);
2314231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
23155ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // 6 - Abort the overall resource selection algorithm.
2316231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_currentSourceNode = 0;
2317dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2318dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Reset m_readyState since m_player is gone.
2319dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_readyState = HAVE_NOTHING;
23208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
23218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
23225abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickbool HTMLMediaElement::canSuspend() const
23235abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
23245abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return true;
23255abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
23265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
23275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid HTMLMediaElement::stop()
23285abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
23295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::stop");
2330cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (m_isFullscreen)
2331cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        exitFullscreen();
233268513a70bcd92384395513322f1b801e7bf9c729Steve Block
23338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_inActiveDocument = false;
23348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    userCancelledLoad();
233568513a70bcd92384395513322f1b801e7bf9c729Steve Block
23368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Stop the playback without generating events
23378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setPausedInternal(true);
233868513a70bcd92384395513322f1b801e7bf9c729Steve Block
23398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer())
23408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        renderer()->updateFromElement();
234168513a70bcd92384395513322f1b801e7bf9c729Steve Block
23420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    stopPeriodicTimers();
23430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    cancelPendingEventsAndCallbacks();
23448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
23458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
234668513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid HTMLMediaElement::suspend(ReasonForSuspension why)
234768513a70bcd92384395513322f1b801e7bf9c729Steve Block{
234868513a70bcd92384395513322f1b801e7bf9c729Steve Block    LOG(Media, "HTMLMediaElement::suspend");
234968513a70bcd92384395513322f1b801e7bf9c729Steve Block
235068513a70bcd92384395513322f1b801e7bf9c729Steve Block    switch (why)
235168513a70bcd92384395513322f1b801e7bf9c729Steve Block    {
235268513a70bcd92384395513322f1b801e7bf9c729Steve Block        case DocumentWillBecomeInactive:
235368513a70bcd92384395513322f1b801e7bf9c729Steve Block            stop();
235468513a70bcd92384395513322f1b801e7bf9c729Steve Block            break;
235568513a70bcd92384395513322f1b801e7bf9c729Steve Block        case JavaScriptDebuggerPaused:
235668513a70bcd92384395513322f1b801e7bf9c729Steve Block        case WillShowDialog:
235768513a70bcd92384395513322f1b801e7bf9c729Steve Block            // Do nothing, we don't pause media playback in these cases.
235868513a70bcd92384395513322f1b801e7bf9c729Steve Block            break;
235968513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
236068513a70bcd92384395513322f1b801e7bf9c729Steve Block}
236168513a70bcd92384395513322f1b801e7bf9c729Steve Block
23625abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid HTMLMediaElement::resume()
23638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
23645abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::resume");
23655abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
23668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_inActiveDocument = true;
23678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setPausedInternal(false);
23688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_error && m_error->code() == MediaError::MEDIA_ERR_ABORTED) {
23708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Restart the load if it was aborted in the middle by moving the document to the page cache.
23718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // m_error is only left at MEDIA_ERR_ABORTED when the document becomes inactive (it is set to
23728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        //  MEDIA_ERR_ABORTED while the abortEvent is being sent, but cleared immediately afterwards).
23738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This behavior is not specified but it seems like a sensible thing to do.
23748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ExceptionCode ec;
23755e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        load(processingUserGesture(), ec);
23768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2377231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
23788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer())
23798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        renderer()->updateFromElement();
23808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2381635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
23825abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickbool HTMLMediaElement::hasPendingActivity() const
23835abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
23845abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    // Return true when we have pending events so we can't fire events after the JS
23855abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    // object gets collected.
23865abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    bool pending = m_pendingEvents.size();
23875abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::hasPendingActivity -> %s", boolString(pending));
23885abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return pending;
23895abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
23905abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
2391635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid HTMLMediaElement::mediaVolumeDidChange()
2392635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
23935abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::mediaVolumeDidChange");
2394635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    updateVolume();
2395635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
2396635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
23978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLMediaElement::defaultEventHandler(Event* event)
23988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
23998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
24008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderObject* r = renderer();
24018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!r || !r->isWidget())
24028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
24038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
24040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    Widget* widget = toRenderWidget(r)->widget();
24058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (widget)
24068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        widget->handleEvent(event);
24078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#else
24082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (event->isMouseEvent()) {
2409b96809187131720dd04bfca638ae069459878157Teng-Hui Zhu#if PLATFORM(ANDROID)
2410b96809187131720dd04bfca638ae069459878157Teng-Hui Zhu        m_lastTouch = WTF::currentTime();
2411b96809187131720dd04bfca638ae069459878157Teng-Hui Zhu#endif
24122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
24132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (mouseEvent->relatedTarget() != this) {
24142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (event->type() == eventNames().mouseoverEvent) {
24152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                m_mouseOver = true;
24162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                if (hasMediaControls() && controls() && !canPlay())
24172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    mediaControls()->makeOpaque();
24182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            } else if (event->type() == eventNames().mouseoutEvent)
24192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                m_mouseOver = false;
24202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
24212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
24222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
24230d60bcd000865d49c38ca619815d4cd7b2afc87aBen Murdoch#if PLATFORM(ANDROID) && ENABLE(TOUCH_EVENTS)
24240676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu    if (event->isTouchEvent()) {
24250d60bcd000865d49c38ca619815d4cd7b2afc87aBen Murdoch        m_mouseOver = !(event->type() == eventNames().touchendEvent || event->type() == eventNames().touchcancelEvent);
24260676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu        if (m_mouseOver && hasMediaControls() && controls() && !canPlay()) {
24270676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu            m_lastTouch = WTF::currentTime();
24280676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu            mediaControls()->makeOpaque();
24290676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu        }
24300676d61efc26679f7a1ba9e9a72daf8e802d978cTeng-Hui Zhu    }
24310d60bcd000865d49c38ca619815d4cd7b2afc87aBen Murdoch#endif
24320d60bcd000865d49c38ca619815d4cd7b2afc87aBen Murdoch
2433d649883ce629c0de432e075254b517a50685792eTeng-Hui Zhu#if PLATFORM(ANDROID)
2434d649883ce629c0de432e075254b517a50685792eTeng-Hui Zhu    // It is really hard to hit the play/pause button on mobile devices.
2435d649883ce629c0de432e075254b517a50685792eTeng-Hui Zhu    // This allows user to click the video area to toggle play/pause state.
24369c3dbdd3eb7ea7e3f52878230326899ab7ef1dc5Teng-Hui Zhu    if (event->type() == eventNames().clickEvent
243731dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu        && !hasEventListeners(eventNames().clickEvent)) {
2438b63752ec4203caed474196849226a76c55f06714Teng-Hui Zhu        m_userGestureInitiated = processingUserGesture();
2439d649883ce629c0de432e075254b517a50685792eTeng-Hui Zhu        togglePlayState();
244031dba079cf3041945529750234190fc24ed92ab5Teng-Hui Zhu    }
2441d649883ce629c0de432e075254b517a50685792eTeng-Hui Zhu#endif
24428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement::defaultEventHandler(event);
24438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
24448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
24458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool HTMLMediaElement::processingUserGesture() const
24478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
24488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Frame* frame = document()->frame();
24498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    FrameLoader* loader = frame ? frame->loader() : 0;
24508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
24518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // return 'true' for safety if we don't know the answer
24520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return loader ? loader->isProcessingUserGesture() : true;
24538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
24548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
24558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
24560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2457dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid HTMLMediaElement::ensureMediaPlayer()
2458dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
2459dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!m_player)
2460dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_player = MediaPlayer::create(this);
2461dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
2462dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
24638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::deliverNotification(MediaPlayerProxyNotificationType notification)
24648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
24658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (notification == MediaPlayerNotificationPlayPauseButtonPressed) {
24660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        togglePlayState();
24678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return;
24688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
24698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
24708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_player)
24718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_player->deliverNotification(notification);
24728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
24738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
24748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::setMediaPlayerProxy(WebMediaPlayerProxy* proxy)
24758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2476dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ensureMediaPlayer();
2477dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_player->setMediaPlayerProxy(proxy);
24788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
24798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2480dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid HTMLMediaElement::getPluginProxyParams(KURL& url, Vector<String>& names, Vector<String>& values)
24818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2482dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Frame* frame = document()->frame();
2483dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    FrameLoader* loader = frame ? frame->loader() : 0;
24848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2485dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (isVideo()) {
24860617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        KURL posterURL = getNonEmptyURLAttribute(posterAttr);
24870617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        if (!posterURL.isEmpty() && loader && loader->willLoadMediaElementURL(posterURL)) {
24880617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            names.append("_media_element_poster_");
24890617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            values.append(posterURL.string());
2490dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
2491dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
2492dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2493dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (controls()) {
2494dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        names.append("_media_element_controls_");
2495dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        values.append("true");
2496dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
24978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2498dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    url = src();
2499545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (!isSafeToLoadURL(url, Complain))
2500dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        url = selectNextSourceChild(0, DoNothing);
2501dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2502dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_currentSrc = url.string();
2503dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (url.isValid() && loader && loader->willLoadMediaElementURL(url)) {
2504dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        names.append("_media_element_src_");
2505dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        values.append(m_currentSrc);
2506dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
25078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
25088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
25098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid HTMLMediaElement::finishParsingChildren()
25108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
25118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HTMLElement::finishParsingChildren();
25125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    document()->updateStyleIfNeeded();
2513dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    createMediaPlayerProxy();
25148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
25150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2516dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid HTMLMediaElement::createMediaPlayerProxy()
2517dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
2518dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ensureMediaPlayer();
2519dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2520967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (m_proxyWidget || (inDocument() && !m_needWidgetUpdate))
2521dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return;
2522dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2523dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Frame* frame = document()->frame();
2524dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    FrameLoader* loader = frame ? frame->loader() : 0;
2525dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!loader)
2526dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return;
2527dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
25285abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::createMediaPlayerProxy");
25295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
2530dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    KURL url;
2531dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Vector<String> paramNames;
2532dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Vector<String> paramValues;
2533dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2534dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    getPluginProxyParams(url, paramNames, paramValues);
2535dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2536dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Hang onto the proxy widget so it won't be destroyed if the plug-in is set to
2537dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // display:none
253806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    m_proxyWidget = loader->subframeLoader()->loadMediaPlayerProxyPlugin(this, url, paramNames, paramValues);
2539dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (m_proxyWidget)
2540dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_needWidgetUpdate = false;
2541dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
25425abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
25432fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid HTMLMediaElement::updateWidget(PluginCreationOption)
25445abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
25455abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    mediaElement->setNeedWidgetUpdate(false);
25465abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
25475abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    Vector<String> paramNames;
25485abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    Vector<String> paramValues;
25495abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    KURL kurl;
25505abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
25515abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    mediaElement->getPluginProxyParams(kurl, paramNames, paramValues);
25525abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
25535abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    loader->loadMediaPlayerProxyPlugin(mediaElement, kurl, paramNames, paramValues);
25545abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
25555abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
2556dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
25578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
25582bde8e466a4451c7319e3a072d118917957d6554Steve Blockbool HTMLMediaElement::isFullscreen() const
25592bde8e466a4451c7319e3a072d118917957d6554Steve Block{
25602bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (m_isFullscreen)
25612bde8e466a4451c7319e3a072d118917957d6554Steve Block        return true;
25622bde8e466a4451c7319e3a072d118917957d6554Steve Block
25632bde8e466a4451c7319e3a072d118917957d6554Steve Block#if ENABLE(FULLSCREEN_API)
25642bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == this)
25652bde8e466a4451c7319e3a072d118917957d6554Steve Block        return true;
25662bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
25672bde8e466a4451c7319e3a072d118917957d6554Steve Block
25682bde8e466a4451c7319e3a072d118917957d6554Steve Block    return false;
25692bde8e466a4451c7319e3a072d118917957d6554Steve Block}
25702bde8e466a4451c7319e3a072d118917957d6554Steve Block
2571231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLMediaElement::enterFullscreen()
2572231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
25735abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::enterFullscreen");
25742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if ENABLE(FULLSCREEN_API)
25752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (document() && document()->settings() && document()->settings()->fullScreenEnabled()) {
25762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        webkitRequestFullScreen(0);
25772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return;
25782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
25792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif
2580231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    ASSERT(!m_isFullscreen);
25816c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    m_isFullscreen = true;
25822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (hasMediaControls())
25832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        mediaControls()->enteredFullscreen();
2584643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (document() && document()->page()) {
2585231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        document()->page()->chrome()->client()->enterFullscreenForNode(this);
2586643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        scheduleEvent(eventNames().webkitbeginfullscreenEvent);
2587643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
2588231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
2589231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2590231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid HTMLMediaElement::exitFullscreen()
2591231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
25925abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::exitFullscreen");
25932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if ENABLE(FULLSCREEN_API)
25942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (document() && document()->settings() && document()->settings()->fullScreenEnabled()) {
25952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == this)
25962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            document()->webkitCancelFullScreen();
25972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return;
25982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
25992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif
2600231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    ASSERT(m_isFullscreen);
26016c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    m_isFullscreen = false;
26022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (hasMediaControls())
26032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        mediaControls()->exitedFullscreen();
2604643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (document() && document()->page()) {
2605f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (document()->page()->chrome()->requiresFullscreenForVideoPlayback())
2606f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            pauseInternal();
2607231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        document()->page()->chrome()->client()->exitFullscreenForNode(this);
2608643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        scheduleEvent(eventNames().webkitendfullscreenEvent);
2609643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
2610231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
2611231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2612231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockPlatformMedia HTMLMediaElement::platformMedia() const
2613231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
2614231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return m_player ? m_player->platformMedia() : NoPlatformMedia;
2615643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
2616643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2617692e5dbf12901edacf14812a6fae25462920af42Steve Block#if USE(ACCELERATED_COMPOSITING)
2618692e5dbf12901edacf14812a6fae25462920af42Steve BlockPlatformLayer* HTMLMediaElement::platformLayer() const
2619692e5dbf12901edacf14812a6fae25462920af42Steve Block{
2620692e5dbf12901edacf14812a6fae25462920af42Steve Block    return m_player ? m_player->platformLayer() : 0;
2621692e5dbf12901edacf14812a6fae25462920af42Steve Block}
2622692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif
2623692e5dbf12901edacf14812a6fae25462920af42Steve Block
2624643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool HTMLMediaElement::hasClosedCaptions() const
2625643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
2626643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return m_player && m_player->hasClosedCaptions();
2627643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
2628643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2629643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool HTMLMediaElement::closedCaptionsVisible() const
2630643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
2631643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return m_closedCaptionsVisible;
2632643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
2633643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2634643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid HTMLMediaElement::setClosedCaptionsVisible(bool closedCaptionVisible)
2635643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
26365abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::setClosedCaptionsVisible(%s)", boolString(closedCaptionVisible));
26375abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
2638643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!m_player ||!hasClosedCaptions())
2639643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
2640643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2641643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    m_closedCaptionsVisible = closedCaptionVisible;
2642643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    m_player->setClosedCaptionsVisible(closedCaptionVisible);
26432bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (hasMediaControls())
26442bde8e466a4451c7319e3a072d118917957d6554Steve Block        mediaControls()->changedClosedCaptionsVisibility();
2645643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
2646643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2647643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid HTMLMediaElement::setWebkitClosedCaptionsVisible(bool visible)
2648643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
2649643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    setClosedCaptionsVisible(visible);
2650643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
2651643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2652643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool HTMLMediaElement::webkitClosedCaptionsVisible() const
2653643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
2654643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return closedCaptionsVisible();
2655643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
2656643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2657643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2658643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool HTMLMediaElement::webkitHasClosedCaptions() const
2659643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
2660643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return hasClosedCaptions();
2661643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
2662643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
26632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#if ENABLE(MEDIA_STATISTICS)
266481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochunsigned HTMLMediaElement::webkitAudioDecodedByteCount() const
26652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
26662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!m_player)
26672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return 0;
266881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return m_player->audioDecodedByteCount();
26692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
26702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
267181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochunsigned HTMLMediaElement::webkitVideoDecodedByteCount() const
26722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
26732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!m_player)
26742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return 0;
267581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return m_player->videoDecodedByteCount();
26762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
26772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif
26782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2679dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid HTMLMediaElement::mediaCanStart()
2680dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
26815abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::mediaCanStart");
26825abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
2683dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ASSERT(m_isWaitingUntilMediaCanStart);
2684dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_isWaitingUntilMediaCanStart = false;
2685dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    loadInternal();
2686dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
2687dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
268806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenbool HTMLMediaElement::isURLAttribute(Attribute* attribute) const
268906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
269006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return attribute->name() == srcAttr;
269106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
269206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
26935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid HTMLMediaElement::setShouldDelayLoadEvent(bool shouldDelay)
26945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
26955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (m_shouldDelayLoadEvent == shouldDelay)
26965ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return;
26975ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
26985abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    LOG(Media, "HTMLMediaElement::setShouldDelayLoadEvent(%s)", boolString(shouldDelay));
26995abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
27005ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_shouldDelayLoadEvent = shouldDelay;
27015ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (shouldDelay)
27025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        document()->incrementLoadEventDelayCount();
27035ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    else
27045ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        document()->decrementLoadEventDelayCount();
27055ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
27065ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
270781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
270881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid HTMLMediaElement::getSitesInMediaCache(Vector<String>& sites)
270981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
271081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    MediaPlayer::getSitesInMediaCache(sites);
271181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
271281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
271381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid HTMLMediaElement::clearMediaCache()
271481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
271581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    MediaPlayer::clearMediaCache();
271681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
271781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
271881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid HTMLMediaElement::clearMediaCacheForSite(const String& site)
271981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
272081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    MediaPlayer::clearMediaCacheForSite(site);
272181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
272281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
272381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid HTMLMediaElement::privateBrowsingStateDidChange()
272481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
272581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!m_player)
272681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
272781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
272881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Settings* settings = document()->settings();
272981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool privateMode = !settings || settings->privateBrowsingEnabled();
273081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    LOG(Media, "HTMLMediaElement::privateBrowsingStateDidChange(%s)", boolString(privateMode));
273181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_player->setPrivateBrowsingMode(privateMode);
273281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
273381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
27342bde8e466a4451c7319e3a072d118917957d6554Steve BlockMediaControls* HTMLMediaElement::mediaControls()
27352bde8e466a4451c7319e3a072d118917957d6554Steve Block{
273654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    return toMediaControls(shadowRoot()->firstChild());
27372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
27382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
27392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool HTMLMediaElement::hasMediaControls()
27402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
274154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (!shadowRoot())
274254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        return false;
274354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
274454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    Node* node = shadowRoot()->firstChild();
274554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    return node && node->isMediaControls();
27462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
27472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
27484717b91d77cab5187baae5025bfa1bab4e52a907Steve Blockbool HTMLMediaElement::createMediaControls()
27492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
27502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (hasMediaControls())
27514717b91d77cab5187baae5025bfa1bab4e52a907Steve Block        return true;
27522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
27532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ExceptionCode ec;
27544717b91d77cab5187baae5025bfa1bab4e52a907Steve Block    RefPtr<MediaControls> controls = MediaControls::create(this);
27554717b91d77cab5187baae5025bfa1bab4e52a907Steve Block    if (!controls)
27564717b91d77cab5187baae5025bfa1bab4e52a907Steve Block        return false;
27574717b91d77cab5187baae5025bfa1bab4e52a907Steve Block
27584717b91d77cab5187baae5025bfa1bab4e52a907Steve Block    ensureShadowRoot()->appendChild(controls, ec);
27594717b91d77cab5187baae5025bfa1bab4e52a907Steve Block    return true;
27602bde8e466a4451c7319e3a072d118917957d6554Steve Block}
27612bde8e466a4451c7319e3a072d118917957d6554Steve Block
27622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid* HTMLMediaElement::preDispatchEventHandler(Event* event)
27632bde8e466a4451c7319e3a072d118917957d6554Steve Block{
27642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (event && event->type() == eventNames().webkitfullscreenchangeEvent) {
27652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (controls()) {
27662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (!hasMediaControls()) {
27674717b91d77cab5187baae5025bfa1bab4e52a907Steve Block                if (!createMediaControls())
27684717b91d77cab5187baae5025bfa1bab4e52a907Steve Block                    return 0;
27694717b91d77cab5187baae5025bfa1bab4e52a907Steve Block
27702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                mediaControls()->reset();
27712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            }
27722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            mediaControls()->show();
27732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        } else if (hasMediaControls())
27742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            mediaControls()->hide();
27752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
27762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return 0;
27772bde8e466a4451c7319e3a072d118917957d6554Steve Block}
27782bde8e466a4451c7319e3a072d118917957d6554Steve Block
27792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
27808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
27818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
2783