diff options
-rw-r--r-- | WebCore/html/HTMLInputElement.cpp | 10 | ||||
-rw-r--r-- | WebCore/html/HTMLMediaElement.cpp | 11 | ||||
-rw-r--r-- | WebCore/html/HTMLMediaElement.h | 3 | ||||
-rw-r--r-- | WebCore/loader/FrameLoader.cpp | 5 | ||||
-rw-r--r-- | WebCore/platform/android/RenderThemeAndroid.cpp | 10 | ||||
-rw-r--r-- | WebCore/platform/graphics/MediaPlayer.cpp | 6 | ||||
-rw-r--r-- | WebCore/platform/graphics/MediaPlayer.h | 1 | ||||
-rw-r--r-- | WebCore/platform/graphics/MediaPlayerPrivate.h | 1 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h | 17 | ||||
-rw-r--r-- | WebCore/rendering/RenderPartObject.cpp | 26 | ||||
-rw-r--r-- | WebCore/rendering/RenderWidget.cpp | 2 | ||||
-rw-r--r-- | WebKit/android/RenderSkinCombo.cpp | 9 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp | 155 |
13 files changed, 182 insertions, 74 deletions
diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp index 88e14fd..59e4e2f 100644 --- a/WebCore/html/HTMLInputElement.cpp +++ b/WebCore/html/HTMLInputElement.cpp @@ -1113,16 +1113,12 @@ void HTMLInputElement::setValue(const String& value) if (isTextField()) { unsigned max = m_data.value().length(); - if (document()->focusedNode() == this) #ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS - { - // Make sure our UI side textfield changes to match the RenderTextControl - android::WebViewCore::getWebViewCore(document()->view())->updateTextfield(this, false, value); + // Make sure our UI side textfield changes to match the RenderTextControl + android::WebViewCore::getWebViewCore(document()->view())->updateTextfield(this, false, value); #endif + if (document()->focusedNode() == this) InputElement::updateSelectionRange(this, this, max, max); -#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS - } -#endif else cacheSelection(max, max); } diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp index 17a3110..f98200d 100644 --- a/WebCore/html/HTMLMediaElement.cpp +++ b/WebCore/html/HTMLMediaElement.cpp @@ -1446,6 +1446,13 @@ bool HTMLMediaElement::potentiallyPlaying() const return !paused() && m_readyState >= HAVE_FUTURE_DATA && !endedPlayback() && !stoppedDueToErrors() && !pausedForUserInteraction(); } +#if PLATFORM(ANDROID) +bool HTMLMediaElement::couldPlayIfEnoughData() const +{ + return !paused() && !endedPlayback() && !stoppedDueToErrors() && !pausedForUserInteraction(); +} +#endif + bool HTMLMediaElement::endedPlayback() const { if (!m_player || m_readyState < HAVE_METADATA) @@ -1527,6 +1534,10 @@ void HTMLMediaElement::updatePlayState() float time = currentTime(); if (m_lastSeekTime < time) m_playedTimeRanges->add(m_lastSeekTime, time); +#if PLATFORM(ANDROID) + } else if (couldPlayIfEnoughData() && playerPaused) { + m_player->prepareToPlay(); +#endif } if (renderer()) diff --git a/WebCore/html/HTMLMediaElement.h b/WebCore/html/HTMLMediaElement.h index 27b48ea..70b686e 100644 --- a/WebCore/html/HTMLMediaElement.h +++ b/WebCore/html/HTMLMediaElement.h @@ -227,6 +227,9 @@ private: bool endedPlayback() const; bool stoppedDueToErrors() const; bool pausedForUserInteraction() const; +#if PLATFORM(ANDROID) + bool couldPlayIfEnoughData() const; +#endif float minTimeSeekable() const; float maxTimeSeekable() const; diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp index 5c81cfc..8e8540d 100644 --- a/WebCore/loader/FrameLoader.cpp +++ b/WebCore/loader/FrameLoader.cpp @@ -519,6 +519,9 @@ void FrameLoader::submitForm(const char* action, const String& url, PassRefPtr<F } FrameLoadRequest frameRequest; +#ifdef ANDROID_USER_GESTURE + frameRequest.resourceRequest().setUserGesture(isProcessingUserGesture()); +#endif String targetOrBaseTarget = target.isEmpty() ? m_frame->document()->baseTarget() : target; Frame* targetFrame = findFrameForNavigation(targetOrBaseTarget); @@ -1538,7 +1541,7 @@ void FrameLoader::loadURLIntoChildFrame(const KURL& url, const String& referer, else #endif #ifdef ANDROID_USER_GESTURE - childFrame->loader()->loadURL(workingURL, referer, String(), false, childLoadType, 0, 0, true); + childFrame->loader()->loadURL(workingURL, referer, String(), false, childLoadType, 0, 0, false); #else childFrame->loader()->loadURL(workingURL, referer, String(), false, childLoadType, 0, 0); #endif diff --git a/WebCore/platform/android/RenderThemeAndroid.cpp b/WebCore/platform/android/RenderThemeAndroid.cpp index 0f419f5..51f404e 100644 --- a/WebCore/platform/android/RenderThemeAndroid.cpp +++ b/WebCore/platform/android/RenderThemeAndroid.cpp @@ -235,7 +235,7 @@ bool RenderThemeAndroid::paintTextArea(RenderObject* obj, const RenderObject::Pa { if (obj->isMenuList()) return paintCombo(obj, info, rect); - return true; + return true; } void RenderThemeAndroid::adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle* style, Element*) const @@ -245,7 +245,7 @@ void RenderThemeAndroid::adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle* bool RenderThemeAndroid::paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { - return true; + return true; } void RenderThemeAndroid::adjustListboxStyle(CSSStyleSelector*, RenderStyle* style, Element*) const @@ -259,12 +259,6 @@ static void adjustMenuListStyleCommon(RenderStyle* style, Element* e) { // Added to make room for our arrow. style->setPaddingRight(Length(RenderSkinCombo::extraWidth(), Fixed)); - // Code copied from RenderThemeMac.mm - // Makes sure that the text shows up on our treatment - bool isEnabled = true; - if (e) - isEnabled = e->isEnabledFormControl(); - style->setColor(isEnabled ? Color::black : Color::darkGray); } void RenderThemeAndroid::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* style, Element* e) const diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp index 15815dc..531c598 100644 --- a/WebCore/platform/graphics/MediaPlayer.cpp +++ b/WebCore/platform/graphics/MediaPlayer.cpp @@ -107,6 +107,7 @@ public: #if PLATFORM(ANDROID) virtual bool canLoadPoster() const { return false; } virtual void setPoster(const String&) { } + virtual void prepareToPlay() { } #endif #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) @@ -263,6 +264,11 @@ bool MediaPlayer::canLoadPoster() const { return m_private->canLoadPoster(); } + +void MediaPlayer::prepareToPlay() +{ + m_private->prepareToPlay(); +} #endif #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) || PLATFORM(ANDROID) diff --git a/WebCore/platform/graphics/MediaPlayer.h b/WebCore/platform/graphics/MediaPlayer.h index 1cb7625..8eade50 100644 --- a/WebCore/platform/graphics/MediaPlayer.h +++ b/WebCore/platform/graphics/MediaPlayer.h @@ -187,6 +187,7 @@ public: #if PLATFORM(ANDROID) bool canLoadPoster() const; void setPoster(const String&); + void prepareToPlay(); #endif #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) diff --git a/WebCore/platform/graphics/MediaPlayerPrivate.h b/WebCore/platform/graphics/MediaPlayerPrivate.h index ba0f4b0..109ad10 100644 --- a/WebCore/platform/graphics/MediaPlayerPrivate.h +++ b/WebCore/platform/graphics/MediaPlayerPrivate.h @@ -95,6 +95,7 @@ public: #if PLATFORM(ANDROID) virtual bool canLoadPoster() const { return false; } virtual void setPoster(const String&) { } + virtual void prepareToPlay() { } #endif #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) diff --git a/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h b/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h index 2d76ebb..812a337 100644 --- a/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h +++ b/WebCore/platform/graphics/android/MediaPlayerPrivateAndroid.h @@ -28,6 +28,8 @@ #if ENABLE(VIDEO) +class SkBitmap; + #include "MediaPlayerPrivate.h" namespace WebCore { @@ -79,11 +81,13 @@ public: virtual bool canLoadPoster() const { return true; } virtual void setPoster(const String&); + virtual void prepareToPlay(); virtual void paint(GraphicsContext*, const IntRect&); void onPrepared(int duration, int width, int height); void onEnded(); + void onPosterFetched(SkBitmap*); private: // Android-specific methods and fields. static MediaPlayerPrivateInterface* create(MediaPlayer* player); @@ -97,10 +101,21 @@ private: String m_url; struct JavaGlue; JavaGlue* m_glue; + float m_duration; - IntSize m_size; float m_currentTime; + bool m_paused; + MediaPlayer::ReadyState m_readyState; + MediaPlayer::NetworkState m_networkState; + + SkBitmap* m_poster; // not owned + String m_posterUrl; + + IntSize m_naturalSize; + bool m_naturalSizeUnknown; + + bool m_isVisible; }; } // namespace WebCore diff --git a/WebCore/rendering/RenderPartObject.cpp b/WebCore/rendering/RenderPartObject.cpp index 5f6d903..72298c6 100644 --- a/WebCore/rendering/RenderPartObject.cpp +++ b/WebCore/rendering/RenderPartObject.cpp @@ -386,11 +386,13 @@ void RenderPartObject::layout() h = 0; if (w != view->width() || h != view->height()) { view->resize(w, h); - root->setNeedsLayout(true, false); } + // Layout the view. - if (view->needsLayout()) + do { view->layout(); + } while (view->layoutPending() || root->needsLayout()); + int contentHeight = view->contentsHeight(); int contentWidth = view->contentsWidth(); // Only change the width or height if scrollbars are visible or @@ -403,6 +405,20 @@ void RenderPartObject::layout() // Update one last time updateWidgetPosition(); + +#if !ASSERT_DISABLED + ASSERT(!view->layoutPending()); + ASSERT(!root->needsLayout()); + // Sanity check when assertions are enabled. + RenderObject* c = root->nextInPreOrder(); + while (c) { + ASSERT(!c->needsLayout()); + c = c->nextInPreOrder(); + } + Node* body = document()->body(); + if (body) + ASSERT(!body->renderer()->needsLayout()); +#endif } } } @@ -446,8 +462,9 @@ void RenderPartObject::calcWidth() { updateWidgetPosition(); // Layout to get the content width - while (view->needsLayout()) + do { view->layout(); + } while (view->layoutPending() || root->needsLayout()); setWidth(max(width(), view->contentsWidth() + extraWidth)); @@ -471,8 +488,9 @@ void RenderPartObject::calcHeight() { updateWidgetPosition(); // Layout to get the content height - while (view->needsLayout()) + do { view->layout(); + } while (view->layoutPending() || root->needsLayout()); int extraHeight = paddingTop() + paddingBottom() + borderTop() + borderBottom(); setHeight(max(width(), view->contentsHeight() + extraHeight)); diff --git a/WebCore/rendering/RenderWidget.cpp b/WebCore/rendering/RenderWidget.cpp index 16526ca..36f4fed 100644 --- a/WebCore/rendering/RenderWidget.cpp +++ b/WebCore/rendering/RenderWidget.cpp @@ -255,6 +255,7 @@ void RenderWidget::updateWidgetPosition() deref(arena); } +#ifndef FLATTEN_IFRAME // if the frame bounds got changed, or if view needs layout (possibly indicating // content size is wrong) we have to do a layout to set the right widget size if (m_widget->isFrameView()) { @@ -262,6 +263,7 @@ void RenderWidget::updateWidgetPosition() if (boundsChanged || frameView->needsLayout()) frameView->layout(); } +#endif } void RenderWidget::setSelectionState(SelectionState state) diff --git a/WebKit/android/RenderSkinCombo.cpp b/WebKit/android/RenderSkinCombo.cpp index 870c13e..fd6f1f2 100644 --- a/WebKit/android/RenderSkinCombo.cpp +++ b/WebKit/android/RenderSkinCombo.cpp @@ -36,9 +36,9 @@ namespace WebCore { static SkBitmap s_bitmap[2]; // Collection of assets for a combo box static bool s_decoded; // True if all assets were decoded -static const int s_margin = 2; +static const int s_margin = 0; static const SkIRect s_mar = { s_margin, s_margin, - RenderSkinCombo::extraWidth(), s_margin }; + RenderSkinCombo::extraWidth() - 2, s_margin }; RenderSkinCombo::RenderSkinCombo() { @@ -61,11 +61,8 @@ bool RenderSkinCombo::Draw(SkCanvas* canvas, Node* element, int x, int y, int wi return true; State state = (element->isElementNode() && static_cast<Element*>(element)->isEnabledFormControl()) ? kNormal : kDisabled; - if (height < (s_margin<<1) + 1) { - height = (s_margin<<1) + 1; - } SkRect bounds; - bounds.set(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + width), SkIntToScalar(y + height)); + bounds.set(SkIntToScalar(x + width), SkIntToScalar(y), SkIntToScalar(x + width), SkIntToScalar(y + height)); SkNinePatch::DrawNine(canvas, bounds, s_bitmap[state], s_mar); return false; } diff --git a/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp b/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp index 1913aef..5ca6e83 100644 --- a/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp +++ b/WebKit/android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp @@ -27,12 +27,17 @@ #if ENABLE(VIDEO) +#include "GraphicsContext.h" #include "MediaPlayerPrivateAndroid.h" +#include "SkiaUtils.h" #include "WebCoreJni.h" #include "WebViewCore.h" #include "jni_utility.h" +#include <GraphicsJNI.h> #include <JNIHelp.h> +#include <SkBitmap.h> + using namespace android; namespace WebCore { @@ -44,10 +49,8 @@ struct MediaPlayerPrivate::JavaGlue jobject m_javaProxy; jmethodID m_getInstance; jmethodID m_play; - jmethodID m_createView; - jmethodID m_attachView; - jmethodID m_removeView; - jmethodID m_setPoster; + jmethodID m_teardown; + jmethodID m_loadPoster; jmethodID m_seek; jmethodID m_pause; }; @@ -57,7 +60,7 @@ MediaPlayerPrivate::~MediaPlayerPrivate() if (m_glue->m_javaProxy) { JNIEnv* env = JSC::Bindings::getJNIEnv(); if (env) { - env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_removeView); + env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_teardown); env->DeleteGlobalRef(m_glue->m_javaProxy); } } @@ -72,19 +75,7 @@ void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar) void MediaPlayerPrivate::load(const String& url) { - // To be able to create our java player, we need a Context object. To get - // the Context object, we need a WebViewCore java object. To get a java - // WebViewCore object, we need a WebCore::FrameView pointer. To get - // the FrameView pointer, the MediaPlayer::setFrameView() must have been - // called. However, that method is called only after the MediaPlayerClient - // is called back and informed that enough data has been loaded. - // We therefore need to fake a readyStateChanged callback before creating - // the java player. - m_player->readyStateChanged(); - // We now have a RenderVideo created and the MediaPlayer must have - // been updated with a FrameView. Create our JavaPlayer. - createJavaPlayerIfNeeded(); - // Save the URl. + // Just save the URl. m_url = url; } @@ -118,7 +109,7 @@ void MediaPlayerPrivate::pause() IntSize MediaPlayerPrivate::naturalSize() const { - return m_size; + return m_naturalSize; } bool MediaPlayerPrivate::hasVideo() const @@ -126,8 +117,11 @@ bool MediaPlayerPrivate::hasVideo() const return false; } -void MediaPlayerPrivate::setVisible(bool) +void MediaPlayerPrivate::setVisible(bool visible) { + m_isVisible = visible; + if (m_isVisible) + createJavaPlayerIfNeeded(); } float MediaPlayerPrivate::duration() const @@ -156,7 +150,7 @@ bool MediaPlayerPrivate::seeking() const return false; } -void MediaPlayerPrivate::setEndTime(float time) +void MediaPlayerPrivate::setEndTime(float) { } @@ -175,12 +169,12 @@ void MediaPlayerPrivate::setVolume(float) MediaPlayer::NetworkState MediaPlayerPrivate::networkState() const { - return MediaPlayer::Loaded; + return m_networkState; } MediaPlayer::ReadyState MediaPlayerPrivate::readyState() const { - return MediaPlayer::HaveEnoughData; + return m_readyState; } float MediaPlayerPrivate::maxTimeSeekable() const @@ -214,25 +208,51 @@ void MediaPlayerPrivate::setSize(const IntSize&) void MediaPlayerPrivate::setPoster(const String& url) { + m_posterUrl = url; JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env) - return; - jstring jUrl = env->NewString((unsigned short *)url.characters(), url.length()); - env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_setPoster, jUrl); - env->DeleteLocalRef(jUrl); - checkException(env); + if (!env || !m_glue->m_javaProxy || !m_posterUrl.length()) + return; + // Send the poster + jstring jUrl = env->NewString((unsigned short *)m_posterUrl.characters(), m_posterUrl.length()); + env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_loadPoster, jUrl); + env->DeleteLocalRef(jUrl); +} + +void MediaPlayerPrivate::prepareToPlay() { + // We are about to start playing. Since our Java VideoView cannot + // buffer any data, we just simply transition to the HaveEnoughData + // state in here. This will allow the MediaPlayer to transition to + // the "play" state, at which point our VideoView will start downloading + // the content and start the playback. + m_networkState = MediaPlayer::Loaded; + m_player->networkStateChanged(); + m_readyState = MediaPlayer::HaveEnoughData; + m_player->readyStateChanged(); } -void MediaPlayerPrivate::paint(GraphicsContext*, const IntRect& r) +void MediaPlayerPrivate::paint(GraphicsContext* ctxt, const IntRect& r) { - createJavaPlayerIfNeeded(); - JNIEnv* env = JSC::Bindings::getJNIEnv(); - if (!env) + if (ctxt->paintingDisabled()) return; - IntSize size = m_player->size(); - env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_attachView, - r.x(), r.y(), size.width(), size.height()); + if (!m_isVisible) + return; + + if (!m_poster || (!m_poster->getPixels() && !m_poster->pixelRef())) + return; + + SkCanvas* canvas = ctxt->platformContext()->mCanvas; + // We paint with the following rules in mind: + // - only downscale the poster, never upscale + // - maintain the natural aspect ratio of the poster + // - the poster should be centered in the target rect + float originalRatio = static_cast<float>(m_poster->width()) / static_cast<float>(m_poster->height()); + int posterWidth = r.width() > m_poster->width() ? m_poster->width() : r.width(); + int posterHeight = posterWidth / originalRatio; + int posterX = ((r.width() - posterWidth) / 2) + r.x(); + int posterY = ((r.height() - posterHeight) / 2) + r.y(); + IntRect targetRect(posterX, posterY, posterWidth, posterHeight); + canvas->drawBitmapRect(*m_poster, 0, targetRect, 0); } MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player) @@ -250,7 +270,17 @@ MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, c } MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player) - : m_player(player), m_glue(NULL), m_duration(6000), m_size(100, 100), m_currentTime(0), m_paused(true) + : m_player(player), + m_glue(0), + m_duration(6000), + m_currentTime(0), + m_paused(true), + m_readyState(MediaPlayer::HaveNothing), + m_networkState(MediaPlayer::Empty), + m_poster(0), + m_naturalSize(100, 100), + m_naturalSizeUnknown(true), + m_isVisible(false) { JNIEnv* env = JSC::Bindings::getJNIEnv(); if (!env) @@ -263,10 +293,8 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player) m_glue = new JavaGlue; m_glue->m_getInstance = env->GetStaticMethodID(clazz, "getInstance", "(Landroid/webkit/WebViewCore;I)Landroid/webkit/HTML5VideoViewProxy;"); m_glue->m_play = env->GetMethodID(clazz, "play", "(Ljava/lang/String;)V"); - m_glue->m_createView = env->GetMethodID(clazz, "createView", "()V"); - m_glue->m_attachView = env->GetMethodID(clazz, "attachView", "(IIII)V"); - m_glue->m_removeView = env->GetMethodID(clazz, "removeView", "()V"); - m_glue->m_setPoster = env->GetMethodID(clazz, "loadPoster", "(Ljava/lang/String;)V"); + m_glue->m_teardown = env->GetMethodID(clazz, "teardown", "()V"); + m_glue->m_loadPoster = env->GetMethodID(clazz, "loadPoster", "(Ljava/lang/String;)V"); m_glue->m_seek = env->GetMethodID(clazz, "seek", "(I)V"); m_glue->m_pause = env->GetMethodID(clazz, "pause", "()V"); m_glue->m_javaProxy = NULL; @@ -299,8 +327,14 @@ void MediaPlayerPrivate::createJavaPlayerIfNeeded() // Get the HTML5VideoViewProxy instance jobject obj = env->CallStaticObjectMethod(clazz, m_glue->m_getInstance, webViewCore->getJavaObject().get(), this); m_glue->m_javaProxy = env->NewGlobalRef(obj); - // Create our VideoView object. - env->CallVoidMethod(obj, m_glue->m_createView); + // Send the poster + jstring jUrl = 0; + if (m_posterUrl.length()) + jUrl = env->NewString((unsigned short *)m_posterUrl.characters(), m_posterUrl.length()); + // Sending a NULL jUrl allows the Java side to try to load the default poster. + env->CallVoidMethod(m_glue->m_javaProxy, m_glue->m_loadPoster, jUrl); + if (jUrl) + env->DeleteLocalRef(jUrl); // Clean up. env->DeleteLocalRef(obj); env->DeleteLocalRef(clazz); @@ -309,17 +343,31 @@ void MediaPlayerPrivate::createJavaPlayerIfNeeded() void MediaPlayerPrivate::onPrepared(int duration, int width, int height) { m_duration = duration / 1000.0f; - m_size = IntSize(width, height); + m_naturalSize = IntSize(width, height); + m_naturalSizeUnknown = false; m_player->durationChanged(); m_player->sizeChanged(); } void MediaPlayerPrivate::onEnded() { m_paused = true; - m_currentTime = m_duration; - m_player->timeChanged(); - // Reset to 0. m_currentTime = 0; + m_networkState = MediaPlayer::Idle; + m_readyState = MediaPlayer::HaveNothing; +} + +void MediaPlayerPrivate::onPosterFetched(SkBitmap* poster) { + m_poster = poster; + if (m_naturalSizeUnknown) { + // We had to fake the size at startup, or else our paint + // method would not be called. If we haven't yet received + // the onPrepared event, update the intrinsic size to the size + // of the poster. That will be overriden when onPrepare comes. + // In case of an error, we should report the poster size, rather + // than our initial fake value. + m_naturalSize = IntSize(poster->width(), poster->height()); + m_player->sizeChanged(); + } } } @@ -340,6 +388,17 @@ static void OnEnded(JNIEnv* env, jobject obj, int pointer) { } } +static void OnPosterFetched(JNIEnv* env, jobject obj, jobject poster, int pointer) { + if (!pointer || !poster) + return; + + WebCore::MediaPlayerPrivate* player = reinterpret_cast<WebCore::MediaPlayerPrivate*>(pointer); + SkBitmap* posterNative = GraphicsJNI::getNativeBitmap(env, poster); + if (!posterNative) + return; + player->onPosterFetched(posterNative); +} + /* * JNI registration */ @@ -348,6 +407,8 @@ static JNINativeMethod g_MediaPlayerMethods[] = { (void*) OnPrepared }, { "nativeOnEnded", "(I)V", (void*) OnEnded }, + { "nativeOnPosterFetched", "(Landroid/graphics/Bitmap;I)V", + (void*) OnPosterFetched }, }; int register_mediaplayer(JNIEnv* env) |