diff options
| author | Patrick Scott <phanna@android.com> | 2010-03-23 13:36:20 -0700 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-03-23 13:36:20 -0700 |
| commit | 4aa28f1f5940594c38e46f06d720f07852b17112 (patch) | |
| tree | 609bdadee80410507b6d601294ab90d1a23ab54e | |
| parent | e34f81fbe92e8ec4045613ae8e3e0e2f3b7360e3 (diff) | |
| parent | 8216a0e796895ec6e736aebbeacee9567ae85515 (diff) | |
| download | external_webkit-4aa28f1f5940594c38e46f06d720f07852b17112.zip external_webkit-4aa28f1f5940594c38e46f06d720f07852b17112.tar.gz external_webkit-4aa28f1f5940594c38e46f06d720f07852b17112.tar.bz2 | |
Merge "Add on-demand plugin support."
| -rw-r--r-- | WebCore/page/Settings.cpp | 3 | ||||
| -rw-r--r-- | WebCore/page/Settings.h | 8 | ||||
| -rw-r--r-- | WebCore/platform/android/TemporaryLinkStubs.cpp | 5 | ||||
| -rw-r--r-- | WebCore/platform/android/WidgetAndroid.cpp | 5 | ||||
| -rw-r--r-- | WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp | 137 | ||||
| -rw-r--r-- | WebKit/android/jni/WebSettings.cpp | 18 | ||||
| -rw-r--r-- | WebKit/android/nav/CacheBuilder.cpp | 3 |
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; } |
