diff options
Diffstat (limited to 'WebKit/android/plugins/PluginWidgetAndroid.cpp')
| -rw-r--r-- | WebKit/android/plugins/PluginWidgetAndroid.cpp | 225 |
1 files changed, 160 insertions, 65 deletions
diff --git a/WebKit/android/plugins/PluginWidgetAndroid.cpp b/WebKit/android/plugins/PluginWidgetAndroid.cpp index fdc4016..113a3bc 100644 --- a/WebKit/android/plugins/PluginWidgetAndroid.cpp +++ b/WebKit/android/plugins/PluginWidgetAndroid.cpp @@ -13,7 +13,7 @@ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -36,6 +36,9 @@ #include "SkFlipPixelRef.h" #include "SkString.h" #include "WebViewCore.h" +#include "jni_utility.h" + +#define DEBUG_VISIBLE_RECTS 1 // temporary debug printfs and fixes PluginWidgetAndroid::PluginWidgetAndroid(WebCore::PluginView* view) : m_pluginView(view) { @@ -47,22 +50,28 @@ PluginWidgetAndroid::PluginWidgetAndroid(WebCore::PluginView* view) m_requestedVisibleRectCount = 0; m_requestedFrameRect.setEmpty(); m_visibleDocRect.setEmpty(); + m_pluginBounds.setEmpty(); m_hasFocus = false; + m_isFullScreen = false; + m_visible = true; m_zoomLevel = 0; - m_javaClassName = NULL; - m_childView = NULL; + m_embeddedView = NULL; } PluginWidgetAndroid::~PluginWidgetAndroid() { if (m_core) { m_core->removePlugin(this); - if (m_childView) { - m_core->destroySurface(m_childView); + if (m_embeddedView) { + m_core->destroySurface(m_embeddedView); } } - if (m_javaClassName) { - free(m_javaClassName); + + // cleanup any remaining JNI References + JNIEnv* env = JSC::Bindings::getJNIEnv(); + if (m_embeddedView) { + env->DeleteGlobalRef(m_embeddedView); } + m_flipPixelRef->safeUnref(); } @@ -77,66 +86,60 @@ static SkBitmap::Config computeConfig(bool isTransparent) { } void PluginWidgetAndroid::setWindow(NPWindow* window, bool isTransparent) { + + // store the reference locally for easy lookup m_pluginWindow = window; - if (m_drawingModel == kSurface_ANPDrawingModel) { - if (!m_childView) { - IntPoint docPoint = frameToDocumentCoords(window->x, window->y); + // make a copy of the previous bounds + SkIRect oldPluginBounds = m_pluginBounds; - const String& libName = m_pluginView->plugin()->path(); - SkString skLibName; - skLibName.setUTF16(libName.characters(), libName.length()); + // keep a local copy of the plugin bounds because the m_pluginWindow pointer + // gets updated values prior to this method being called + m_pluginBounds.set(m_pluginWindow->x, m_pluginWindow->y, + m_pluginWindow->x + m_pluginWindow->width, + m_pluginWindow->y + m_pluginWindow->height); - m_childView = m_core->createSurface(skLibName.c_str(), m_javaClassName, - m_pluginView->instance(), - docPoint.x(), docPoint.y(), - window->width, window->height); - } - } else { - m_flipPixelRef->safeUnref(); - m_flipPixelRef = new SkFlipPixelRef(computeConfig(isTransparent), - window->width, window->height); - } -} + if (m_drawingModel == kSurface_ANPDrawingModel) { -bool PluginWidgetAndroid::setPluginStubJavaClassName(const char* className) { + IntPoint docPoint = frameToDocumentCoords(window->x, window->y); - if (m_javaClassName) { - free(m_javaClassName); - } + // if the surface exists check for changes and update accordingly + if (m_embeddedView && m_pluginBounds != oldPluginBounds) { - // don't call strdup() if the className is to be set to NULL - if (!className) { - m_javaClassName = NULL; - return true; - } + m_core->updateSurface(m_embeddedView, docPoint.x(), docPoint.y(), + window->width, window->height); - // make a local copy of the className - m_javaClassName = strdup(className); - return (m_javaClassName != NULL); -} + // if the surface does not exist then create a new surface + } else if(!m_embeddedView) { -void PluginWidgetAndroid::requestFullScreenMode() { + WebCore::PluginPackage* pkg = m_pluginView->plugin(); + NPP instance = m_pluginView->instance(); - if (!m_javaClassName) { - return; - } - const String& libName = m_pluginView->plugin()->path(); - SkString skLibName; - skLibName.setUTF16(libName.characters(), libName.length()); + jobject pluginSurface; + pkg->pluginFuncs()->getvalue(instance, kJavaSurface_ANPGetValue, + static_cast<void*>(&pluginSurface)); - m_core->startFullScreenPluginActivity(skLibName.c_str(), m_javaClassName, - m_pluginView->instance()); + jobject tempObj = m_core->addSurface(pluginSurface, + docPoint.x(), docPoint.y(), + window->width, window->height); + if (tempObj) { + JNIEnv* env = JSC::Bindings::getJNIEnv(); + m_embeddedView = env->NewGlobalRef(tempObj); + } + } + if (m_isFullScreen && m_pluginBounds != oldPluginBounds) { + m_core->updateFullScreenPlugin(docPoint.x(), docPoint.y(), + window->width, window->height); + } + } else { + m_flipPixelRef->safeUnref(); + m_flipPixelRef = new SkFlipPixelRef(computeConfig(isTransparent), + window->width, window->height); + } } bool PluginWidgetAndroid::setDrawingModel(ANPDrawingModel model) { - - // disallow the surface drawing model if no java class name has been given - if (model == kSurface_ANPDrawingModel && m_javaClassName == NULL) { - return false; - } - m_drawingModel = model; return true; } @@ -264,7 +267,10 @@ bool PluginWidgetAndroid::isAcceptingEvent(ANPEventFlag flag) { } void PluginWidgetAndroid::setVisibleScreen(const ANPRectI& visibleDocRect, float zoom) { - +#if DEBUG_VISIBLE_RECTS + SkDebugf("%s (%d,%d,%d,%d)", __FUNCTION__, visibleDocRect.left, + visibleDocRect.top, visibleDocRect.right, visibleDocRect.bottom); +#endif // TODO update the bitmap size based on the zoom? (for kBitmap_ANPDrawingModel) int oldScreenW = m_visibleDocRect.width(); @@ -278,10 +284,24 @@ void PluginWidgetAndroid::setVisibleScreen(const ANPRectI& visibleDocRect, float if (oldScreenW != newScreenW || oldScreenH != newScreenH) computeVisibleFrameRect(); + + bool visible = SkIRect::Intersects(m_visibleDocRect, m_pluginBounds); + if(m_visible != visible) { + // change the visibility + m_visible = visible; + // send the event + ANPEvent event; + SkANP::InitEvent(&event, kLifecycle_ANPEventType); + event.data.lifecycle.action = visible ? kOnScreen_ANPLifecycleAction + : kOffScreen_ANPLifecycleAction; + sendEvent(event); + } } void PluginWidgetAndroid::setVisibleRects(const ANPRectI rects[], int32_t count) { - +#if DEBUG_VISIBLE_RECTS + SkDebugf("%s count=%d", __FUNCTION__, count); +#endif // ensure the count does not exceed our allocated space if (count > MAX_REQUESTED_RECTS) count = MAX_REQUESTED_RECTS; @@ -290,6 +310,24 @@ void PluginWidgetAndroid::setVisibleRects(const ANPRectI rects[], int32_t count) m_requestedVisibleRectCount = count; memcpy(m_requestedVisibleRect, rects, count * sizeof(rects[0])); +#if DEBUG_VISIBLE_RECTS // FIXME: this fixes bad data from the plugin + // take it out once plugin supplies better data + for (int index = 0; index < count; index++) { + SkDebugf("%s [%d](%d,%d,%d,%d)", __FUNCTION__, index, + m_requestedVisibleRect[index].left, + m_requestedVisibleRect[index].top, + m_requestedVisibleRect[index].right, + m_requestedVisibleRect[index].bottom); + if (m_requestedVisibleRect[index].left == + m_requestedVisibleRect[index].right) { + m_requestedVisibleRect[index].right += 1; + } + if (m_requestedVisibleRect[index].top == + m_requestedVisibleRect[index].bottom) { + m_requestedVisibleRect[index].bottom += 1; + } + } +#endif computeVisibleFrameRect(); } @@ -299,12 +337,6 @@ void PluginWidgetAndroid::computeVisibleFrameRect() { if (m_visibleDocRect.isEmpty() || !m_pluginWindow) return; - // create a rect that represents the plugin's bounds - SkIRect pluginBounds; - pluginBounds.set(m_pluginWindow->x, m_pluginWindow->y, - m_pluginWindow->x + m_pluginWindow->width, - m_pluginWindow->y + m_pluginWindow->height); - // create a rect that will contain as many of the rects that will fit on screen SkIRect visibleRect; visibleRect.setEmpty(); @@ -319,9 +351,18 @@ void PluginWidgetAndroid::computeVisibleFrameRect() { pluginRect.offset(m_pluginWindow->x, m_pluginWindow->y); // ensure the rect falls within the plugin's bounds - if (!pluginBounds.contains(pluginRect)) - continue; - + if (!m_pluginBounds.contains(pluginRect)) { +#if DEBUG_VISIBLE_RECTS + SkDebugf("%s (%d,%d,%d,%d) !contain (%d,%d,%d,%d)", __FUNCTION__, + m_pluginBounds.fLeft, m_pluginBounds.fTop, + m_pluginBounds.fRight, m_pluginBounds.fBottom, + pluginRect.fLeft, pluginRect.fTop, + pluginRect.fRight, pluginRect.fBottom); + // FIXME: assume that the desired outcome is to clamp to the container + pluginRect.intersect(m_pluginBounds); +#endif + continue; + } // combine this new rect with the higher priority rects pluginRect.join(visibleRect); @@ -342,9 +383,14 @@ void PluginWidgetAndroid::computeVisibleFrameRect() { void PluginWidgetAndroid::scrollToVisibleFrameRect() { - if (!m_hasFocus || m_requestedFrameRect.isEmpty() || m_visibleDocRect.isEmpty()) + if (!m_hasFocus || m_requestedFrameRect.isEmpty() || m_visibleDocRect.isEmpty()) { +#if DEBUG_VISIBLE_RECTS + SkDebugf("%s call m_hasFocus=%d m_requestedFrameRect.isEmpty()=%d" + " m_visibleDocRect.isEmpty()=%d", __FUNCTION__, m_hasFocus, + m_requestedFrameRect.isEmpty(), m_visibleDocRect.isEmpty()); +#endif return; - + } // if the entire rect is already visible then we don't need to scroll, which // requires converting the m_requestedFrameRect from frame to doc coordinates IntPoint pluginDocPoint = frameToDocumentCoords(m_requestedFrameRect.fLeft, @@ -371,6 +417,9 @@ void PluginWidgetAndroid::scrollToVisibleFrameRect() { ScrollView* scrollView = m_pluginView->parent(); android::WebViewCore* core = android::WebViewCore::getWebViewCore(scrollView); +#if DEBUG_VISIBLE_RECTS + SkDebugf("%s call scrollBy (%d,%d)", __FUNCTION__, deltaX, deltaY); +#endif core->scrollBy(deltaX, deltaY, true); } @@ -391,3 +440,49 @@ IntPoint PluginWidgetAndroid::frameToDocumentCoords(int frameX, int frameY) cons return docPoint; } + +void PluginWidgetAndroid::requestFullScreen() { + if (m_isFullScreen || !m_embeddedView) { + return; + } + + // send event to notify plugin of full screen change + ANPEvent event; + SkANP::InitEvent(&event, kLifecycle_ANPEventType); + event.data.lifecycle.action = kEnterFullScreen_ANPLifecycleAction; + sendEvent(event); + + // remove the embedded surface from the view hierarchy + m_core->destroySurface(m_embeddedView); + + // add the full screen view + IntPoint docPoint = frameToDocumentCoords(m_pluginWindow->x, m_pluginWindow->y); + m_core->showFullScreenPlugin(m_embeddedView, m_pluginView->instance(), + docPoint.x(), docPoint.y(), m_pluginWindow->width, + m_pluginWindow->height); + m_isFullScreen = true; +} + +void PluginWidgetAndroid::exitFullScreen(bool pluginInitiated) { + if (!m_isFullScreen || !m_embeddedView) { + return; + } + + // remove the full screen surface from the view hierarchy + if (pluginInitiated) { + m_core->hideFullScreenPlugin(); + } + + // add the embedded view back + IntPoint docPoint = frameToDocumentCoords(m_pluginWindow->x, m_pluginWindow->y); + m_core->updateSurface(m_embeddedView, docPoint.x(), docPoint.y(), + m_pluginWindow->width, m_pluginWindow->height); + + // send event to notify plugin of full screen change + ANPEvent event; + SkANP::InitEvent(&event, kLifecycle_ANPEventType); + event.data.lifecycle.action = kExitFullScreen_ANPLifecycleAction; + sendEvent(event); + + m_isFullScreen = false; +} |
