summaryrefslogtreecommitdiffstats
path: root/WebKit/android/plugins/PluginWidgetAndroid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/android/plugins/PluginWidgetAndroid.cpp')
-rw-r--r--WebKit/android/plugins/PluginWidgetAndroid.cpp225
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;
+}