diff options
Diffstat (limited to 'WebKit/android')
| -rw-r--r-- | WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp | 149 | ||||
| -rw-r--r-- | WebKit/android/icu/unicode/ucnv.cpp | 5 | ||||
| -rw-r--r-- | WebKit/android/jni/WebSettings.cpp | 18 | ||||
| -rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 21 | ||||
| -rw-r--r-- | WebKit/android/jni/WebViewCore.h | 4 | ||||
| -rw-r--r-- | WebKit/android/nav/CacheBuilder.cpp | 3 | ||||
| -rw-r--r-- | WebKit/android/plugins/android_npapi.h | 9 |
7 files changed, 184 insertions, 25 deletions
diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp index 10cd0b3..677f0da 100644 --- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp +++ b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp @@ -46,12 +46,14 @@ #include "IconDatabase.h" #include "MIMETypeRegistry.h" #include "NotImplemented.h" +#include "PackageNotifier.h" #include "Page.h" #include "PlatformBridge.h" #include "PlatformGraphicsContext.h" #include "PlatformString.h" #include "PluginDatabase.h" #include "PluginView.h" +#include "PluginWidget.h" #include "ProgressTracker.h" #include "RenderPart.h" #include "ResourceError.h" @@ -995,6 +997,97 @@ static bool isYouTubeUrl(const KURL& url, const String& mimeType) && equalIgnoringCase(mimeType, "application/x-shockwave-flash"); } +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, @@ -1003,8 +1096,43 @@ 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)) { + if (isYouTubeUrl(url, mimeType) && isYouTubeInstalled()) { WTF::RefPtr<Frame> frame = createFrame(blankURL(), String(), element, String(), false, 0, 0); if (frame) { @@ -1032,24 +1160,15 @@ 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) { - m_manualLoader = static_cast<PluginView*>(pluginWidget); + // Do not redirect data if the Widget is our plugin placeholder. + if (pluginWidget->isPluginView()) { + m_manualLoader = static_cast<PluginView*>(pluginWidget); + } } WTF::PassRefPtr<Widget> FrameLoaderClientAndroid::createJavaAppletWidget(const IntSize&, HTMLAppletElement*, diff --git a/WebKit/android/icu/unicode/ucnv.cpp b/WebKit/android/icu/unicode/ucnv.cpp index 1963dd2..1b40573 100644 --- a/WebKit/android/icu/unicode/ucnv.cpp +++ b/WebKit/android/icu/unicode/ucnv.cpp @@ -40,8 +40,9 @@ namespace android { U_STABLE UConverter* U_EXPORT2 ucnv_open_emoji(const char *converterName, UErrorCode *err) { if (EmojiFont::IsAvailable()) { - if (strcmp(converterName, "Shift_JIS") == 0) - converterName = "docomo-emoji"; + if (strcmp(converterName, "Shift_JIS") == 0) { + converterName = EmojiFont::GetShiftJisConverterName(); + } } return ucnv_open(converterName, err); } 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/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index a0e4642..00ac725 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -168,6 +168,27 @@ bool WebViewCore::isInstance(WebViewCore* inst) { return gInstanceList.find(inst) >= 0; } +jobject WebViewCore::getApplicationContext() { + + // check to see if there is a valid webviewcore object + if (gInstanceList.isEmpty()) + return 0; + + // get the context from the webview + jobject context = gInstanceList[0]->getContext(); + + if (!context) + return 0; + + // get the application context using JNI + JNIEnv* env = JSC::Bindings::getJNIEnv(); + jclass contextClass = env->GetObjectClass(context); + jmethodID appContextMethod = env->GetMethodID(contextClass, "getApplicationContext", "()Landroid/content/Context;"); + jobject result = env->CallObjectMethod(context, appContextMethod); + checkException(env); + return result; +} + // ---------------------------------------------------------------------------- #define GET_NATIVE_VIEW(env, obj) ((WebViewCore*)env->GetIntField(obj, gWebViewCoreFields.m_nativeClass)) diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h index abe0d8d..8c885e6 100644 --- a/WebKit/android/jni/WebViewCore.h +++ b/WebKit/android/jni/WebViewCore.h @@ -569,6 +569,10 @@ namespace android { // call only from webkit thread (like add/remove), return true if inst // is still alive static bool isInstance(WebViewCore*); + + // if there exists at least on WebViewCore instance then we return the + // application context, otherwise NULL is returned. + static jobject getApplicationContext(); }; } // namespace android 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; } diff --git a/WebKit/android/plugins/android_npapi.h b/WebKit/android/plugins/android_npapi.h index b4974f4..25cee97 100644 --- a/WebKit/android/plugins/android_npapi.h +++ b/WebKit/android/plugins/android_npapi.h @@ -126,7 +126,14 @@ typedef uint32_t ANPMatrixFlag; */ #define kSupportedDrawingModel_ANPGetValue ((NPNVariable)2000) -/** queries for the context (android.content.Context) in which the plugin resides +/** queries for the context (android.content.Context) of the plugin. If no + instance is specified the application's context is returned. If the instance + is given then the context returned is identical to the context used to + create the webview in which that instance resides. + + NOTE: Holding onto a non-application context after your instance has been + destroyed will cause a memory leak. Refer to the android documentation to + determine what context is best suited for your particular scenario. NPN_GetValue(inst, kJavaContext_ANPGetValue, jobject context) */ |
