summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebCore/page/Settings.cpp3
-rw-r--r--WebCore/page/Settings.h8
-rw-r--r--WebCore/platform/android/TemporaryLinkStubs.cpp5
-rw-r--r--WebCore/platform/android/WidgetAndroid.cpp5
-rw-r--r--WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp137
-rw-r--r--WebKit/android/jni/WebSettings.cpp18
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp3
7 files changed, 156 insertions, 23 deletions
diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp
index 7b5da91..c495a23 100644
--- a/WebCore/page/Settings.cpp
+++ b/WebCore/page/Settings.cpp
@@ -136,6 +136,9 @@ Settings::Settings(Page* page)
, m_webGLEnabled(false)
, m_geolocationEnabled(true)
, m_loadDeferringEnabled(true)
+#ifdef ANDROID_PLUGINS
+ , m_pluginsOnDemand(false)
+#endif
{
// A Frame may not have been created yet, so we initialize the AtomicString
// hash before trying to use it.
diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h
index fc99ac8..652c13d 100644
--- a/WebCore/page/Settings.h
+++ b/WebCore/page/Settings.h
@@ -147,6 +147,11 @@ namespace WebCore {
void setPluginsEnabled(bool);
bool arePluginsEnabled() const { return m_arePluginsEnabled; }
+#ifdef ANDROID_PLUGINS
+ void setPluginsOnDemand(bool onDemand) { m_pluginsOnDemand = onDemand; }
+ bool arePluginsOnDemand() const { return m_pluginsOnDemand; }
+#endif
+
void setDatabasesEnabled(bool);
bool databasesEnabled() const { return m_databasesEnabled; }
@@ -458,6 +463,9 @@ namespace WebCore {
bool m_webGLEnabled : 1;
bool m_geolocationEnabled : 1;
bool m_loadDeferringEnabled : 1;
+#ifdef ANDROID_PLUGINS
+ bool m_pluginsOnDemand : 1;
+#endif
#if USE(SAFARI_THEME)
static bool gShouldPaintNativeControls;
diff --git a/WebCore/platform/android/TemporaryLinkStubs.cpp b/WebCore/platform/android/TemporaryLinkStubs.cpp
index 9741ad5..6dac5ef 100644
--- a/WebCore/platform/android/TemporaryLinkStubs.cpp
+++ b/WebCore/platform/android/TemporaryLinkStubs.cpp
@@ -67,6 +67,7 @@
#include "Pasteboard.h"
#include "Path.h"
#include "PluginInfoStore.h"
+#include "PluginWidget.h"
#include "ResourceError.h"
#include "ResourceHandle.h"
#include "ResourceLoader.h"
@@ -144,6 +145,10 @@ void refreshPlugins(bool)
#endif // !defined(ANDROID_PLUGINS)
+// Needed to link with PluginWidget as a parent class of PluginToggleWidget. Mac
+// defines this in plugins/mac/PluginWidgetMac.mm
+void PluginWidget::invalidateRect(const IntRect&) {}
+
// This function tells the bridge that a resource was loaded from the cache and thus
// the app may update progress with the amount of data loaded.
void CheckCacheObjectStatus(DocLoader*, CachedResource*)
diff --git a/WebCore/platform/android/WidgetAndroid.cpp b/WebCore/platform/android/WidgetAndroid.cpp
index d122ef7..9ab0b2c 100644
--- a/WebCore/platform/android/WidgetAndroid.cpp
+++ b/WebCore/platform/android/WidgetAndroid.cpp
@@ -49,9 +49,8 @@ Widget::~Widget()
IntRect Widget::frameRect() const
{
- // FIXME: use m_frame instead?
if (!platformWidget())
- return IntRect(0, 0, 0, 0);
+ return m_frame;
return platformWidget()->getBounds();
}
@@ -95,7 +94,7 @@ void Widget::hide()
void Widget::setFrameRect(const IntRect& rect)
{
- // FIXME: set m_frame instead?
+ m_frame = rect;
// platformWidget() is 0 when called from Scrollbar
if (!platformWidget())
return;
diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
index 6e42d47..5fb7d29 100644
--- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
@@ -53,6 +53,7 @@
#include "PlatformString.h"
#include "PluginDatabase.h"
#include "PluginView.h"
+#include "PluginWidget.h"
#include "ProgressTracker.h"
#include "RenderPart.h"
#include "ResourceError.h"
@@ -1000,6 +1001,93 @@ static bool isYouTubeInstalled() {
return WebCore::packageNotifier().isPackageInstalled("com.google.android.youtube");
}
+// Use PluginWidget as it is not used by Android for real plugins.
+class PluginToggleWidget : public PluginWidget {
+public:
+ PluginToggleWidget(Frame* parent, const IntSize& size,
+ HTMLPlugInElement* elem, const KURL& url,
+ const WTF::Vector<String>& paramNames,
+ const WTF::Vector<String>& paramValues, const String& mimeType,
+ bool loadManually)
+ : m_parent(parent)
+ , m_size(size)
+ , m_element(elem)
+ , m_url(url)
+ , m_paramNames(paramNames)
+ , m_paramValues(paramValues)
+ , m_mimeType(mimeType)
+ , m_loadManually(loadManually)
+ {
+ resize(size);
+ }
+
+ virtual void paint(GraphicsContext* ctx, const IntRect& rect)
+ {
+ // Most of this code is copied from PluginView::paintMissingPluginIcon
+ // with slight modification.
+
+ static RefPtr<Image> image;
+ static RefPtr<Image> bg;
+ if (!image || !bg) {
+ image = Image::loadPlatformResource("togglePlugin");
+ bg = Image::loadPlatformResource("togglePluginBg");
+ }
+
+ IntRect imageRect(x(), y(), image->width(), image->height());
+
+ int xOffset = (width() - imageRect.width()) >> 1;
+ int yOffset = (height() - imageRect.height()) >> 1;
+
+ imageRect.move(xOffset, yOffset);
+
+ if (!rect.intersects(imageRect))
+ return;
+
+ // FIXME: We need to clip similarly to paintMissingPluginIcon but it is
+ // way screwed up right now. It has something to do with how we tell
+ // webkit the scroll position and it causes the placeholder to get
+ // clipped very badly. http://b/issue?id=2533303
+
+ ctx->save();
+ ctx->clip(frameRect());
+ ctx->drawTiledImage(bg.get(), DeviceColorSpace, frameRect(),
+ IntPoint(), IntSize(bg->width(), bg->height()));
+ ctx->drawImage(image.get(), DeviceColorSpace, imageRect.location());
+ ctx->restore();
+ }
+
+ virtual void handleEvent(Event* event)
+ {
+ if (event->type() != eventNames().clickEvent)
+ return;
+
+ WTF::PassRefPtr<PluginView> prpWidget =
+ PluginView::create(m_parent.get(),
+ m_size,
+ m_element,
+ m_url,
+ m_paramNames,
+ m_paramValues,
+ m_mimeType,
+ m_loadManually);
+ RefPtr<Widget> myProtector(this);
+ RenderWidget* renderer =
+ static_cast<RenderWidget*>(m_element->renderer());
+ prpWidget->focusPluginElement();
+ renderer->setWidget(prpWidget);
+ }
+
+private:
+ RefPtr<Frame> m_parent;
+ IntSize m_size;
+ HTMLPlugInElement* m_element;
+ KURL m_url;
+ WTF::Vector<String> m_paramNames;
+ WTF::Vector<String> m_paramValues;
+ String m_mimeType;
+ bool m_loadManually;
+};
+
WTF::PassRefPtr<Widget> FrameLoaderClientAndroid::createPlugin(
const IntSize& size,
HTMLPlugInElement* element,
@@ -1008,6 +1096,41 @@ WTF::PassRefPtr<Widget> FrameLoaderClientAndroid::createPlugin(
const WTF::Vector<String>& values,
const String& mimeType,
bool loadManually) {
+ WTF::PassRefPtr<PluginView> prpWidget = 0;
+#ifdef ANDROID_PLUGINS
+ // This is copied from PluginView.cpp. We need to determine if a plugin
+ // will be found before doing some of the work in PluginView.
+ String mimeTypeCopy = mimeType;
+ PluginPackage* plugin =
+ PluginDatabase::installedPlugins()->findPlugin(url, mimeTypeCopy);
+ if (!plugin && PluginDatabase::installedPlugins()->refresh()) {
+ mimeTypeCopy = mimeType;
+ plugin = PluginDatabase::installedPlugins()->findPlugin(url,
+ mimeTypeCopy);
+ }
+ Settings* settings = m_frame->settings();
+ // Do the placeholder if plugins are on-demand and there is a plugin for the
+ // given mime type.
+ if (settings && settings->arePluginsOnDemand() && plugin) {
+ return adoptRef(new PluginToggleWidget(m_frame, size, element, url,
+ names, values, mimeType, loadManually));
+ }
+ prpWidget = PluginView::create(m_frame,
+ size,
+ element,
+ url,
+ names,
+ values,
+ mimeType,
+ loadManually);
+ // Return the plugin if it was loaded successfully. Otherwise, fallback to
+ // the youtube placeholder if possible. No need to check prpWidget as
+ // PluginView::create will create a PluginView for missing plugins.
+ // Note: this check really only checks if the plugin was found and not if
+ // the plugin was loaded.
+ if (prpWidget->status() == PluginStatusLoadedSuccessfully)
+ return prpWidget;
+#endif
// Create an iframe for youtube urls.
if (isYouTubeUrl(url, mimeType) && isYouTubeInstalled()) {
WTF::RefPtr<Frame> frame = createFrame(blankURL(), String(), element,
@@ -1037,20 +1160,8 @@ WTF::PassRefPtr<Widget> FrameLoaderClientAndroid::createPlugin(
WTF::RefPtr<Widget> widget(frame->view());
return widget.release();
}
- return NULL;
}
-#ifdef ANDROID_PLUGINS
- return PluginView::create(m_frame,
- size,
- element,
- url,
- names,
- values,
- mimeType,
- loadManually);
-#else
- return NULL;
-#endif
+ return prpWidget;
}
void FrameLoaderClientAndroid::redirectDataToPlugin(Widget* pluginWidget) {
diff --git a/WebKit/android/jni/WebSettings.cpp b/WebKit/android/jni/WebSettings.cpp
index 91ed8cc..70ecded 100644
--- a/WebKit/android/jni/WebSettings.cpp
+++ b/WebKit/android/jni/WebSettings.cpp
@@ -83,7 +83,8 @@ struct FieldIds {
mBlockNetworkImage = env->GetFieldID(clazz, "mBlockNetworkImage", "Z");
#endif
mJavaScriptEnabled = env->GetFieldID(clazz, "mJavaScriptEnabled", "Z");
- mPluginsEnabled = env->GetFieldID(clazz, "mPluginsEnabled", "Z");
+ mPluginState = env->GetFieldID(clazz, "mPluginState",
+ "Landroid/webkit/WebSettings$PluginState;");
#if ENABLE(DATABASE)
mDatabaseEnabled = env->GetFieldID(clazz, "mDatabaseEnabled", "Z");
#endif
@@ -133,7 +134,7 @@ struct FieldIds {
LOG_ASSERT(mBlockNetworkImage, "Could not find field mBlockNetworkImage");
#endif
LOG_ASSERT(mJavaScriptEnabled, "Could not find field mJavaScriptEnabled");
- LOG_ASSERT(mPluginsEnabled, "Could not find field mPluginsEnabled");
+ LOG_ASSERT(mPluginState, "Could not find field mPluginState");
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
LOG_ASSERT(mAppCacheEnabled, "Could not find field mAppCacheEnabled");
LOG_ASSERT(mAppCachePath, "Could not find field mAppCachePath");
@@ -179,7 +180,7 @@ struct FieldIds {
jfieldID mBlockNetworkImage;
#endif
jfieldID mJavaScriptEnabled;
- jfieldID mPluginsEnabled;
+ jfieldID mPluginState;
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
jfieldID mAppCacheEnabled;
jfieldID mAppCachePath;
@@ -313,8 +314,15 @@ public:
flag = env->GetBooleanField(obj, gFieldIds->mJavaScriptEnabled);
s->setJavaScriptEnabled(flag);
- flag = env->GetBooleanField(obj, gFieldIds->mPluginsEnabled);
- s->setPluginsEnabled(flag);
+ // ON = 0
+ // ON_DEMAND = 1
+ // OFF = 2
+ jobject pluginState = env->GetObjectField(obj, gFieldIds->mPluginState);
+ int state = env->CallIntMethod(pluginState, gFieldIds->mOrdinal);
+ s->setPluginsEnabled(state < 2);
+#ifdef ANDROID_PLUGINS
+ s->setPluginsOnDemand(state == 1);
+#endif
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
flag = env->GetBooleanField(obj, gFieldIds->mAppCacheEnabled);
diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp
index d1d36df..a3aeede 100644
--- a/WebKit/android/nav/CacheBuilder.cpp
+++ b/WebKit/android/nav/CacheBuilder.cpp
@@ -878,8 +878,7 @@ static Node* OneAfter(Node* node)
static bool checkForPluginViewThatWantsFocus(RenderObject* renderer) {
if (renderer->isWidget()) {
Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
- if (widget && widget->isPluginView()) {
- PluginView* pv = static_cast<PluginView*>(widget);
+ if (widget && (widget->isPluginView() || widget->isPluginWidget())) {
// check if this plugin really wants key events (TODO)
return true;
}