diff options
| -rw-r--r-- | WebCore/html/HTMLBodyElement.cpp | 2 | ||||
| -rw-r--r-- | WebCore/loader/FrameLoader.cpp | 7 | ||||
| -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-- | WebCore/plugins/android/PluginViewAndroid.cpp | 19 | ||||
| -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 |
14 files changed, 218 insertions, 40 deletions
diff --git a/WebCore/html/HTMLBodyElement.cpp b/WebCore/html/HTMLBodyElement.cpp index b9e2c75..e5a16cb 100644 --- a/WebCore/html/HTMLBodyElement.cpp +++ b/WebCore/html/HTMLBodyElement.cpp @@ -191,7 +191,7 @@ void HTMLBodyElement::insertedIntoDocument() if (settings) { String host = document()->baseURI().host().lower(); if (settings->viewportWidth() == -1 && (host.startsWith("m.") || host.startsWith("mobile.") - || host.contains(".m.") || host.contains(".mobile."))) { + || host.startsWith("wap.") || host.contains(".m.") || host.contains(".mobile." || host.contains(".wap.")))) { // fit mobile sites directly in the screen settings->setMetadataSettings("width", "device-width"); // update the meta data if it is the top document diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp index 945cd90..be782f1 100644 --- a/WebCore/loader/FrameLoader.cpp +++ b/WebCore/loader/FrameLoader.cpp @@ -3502,14 +3502,7 @@ void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequ return; bool isRedirect = m_quickRedirectComing || policyChecker()->loadType() == FrameLoadTypeRedirectWithLockedBackForwardList; -#ifdef ANDROID_USER_GESTURE - // Do not add history items for a fragment scroll not initiated by the - // user. http://bugs.webkit.org/show_bug.cgi?id=30224 - loadInSameDocument(request.url(), 0, !isRedirect && - (isProcessingUserGesture() || request.getUserGesture())); -#else loadInSameDocument(request.url(), 0, !isRedirect); -#endif } bool FrameLoader::shouldScrollToAnchor(bool isFormSubmission, FrameLoadType loadType, const KURL& url) 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/WebCore/plugins/android/PluginViewAndroid.cpp b/WebCore/plugins/android/PluginViewAndroid.cpp index 5b7aea9..452c9fb 100644 --- a/WebCore/plugins/android/PluginViewAndroid.cpp +++ b/WebCore/plugins/android/PluginViewAndroid.cpp @@ -369,11 +369,22 @@ NPError PluginView::getValueStatic(NPNVariable variable, void* value) { // our interface query is valid with no NPP instance NPError error = NPERR_GENERIC_ERROR; - if ((value != NULL) && (variable == NPNVisOfflineBool)) { - bool* retValue = static_cast<bool*>(value); - *retValue = !networkStateNotifier().onLine(); - return NPERR_NO_ERROR; + + switch (variable) { + case NPNVisOfflineBool: { + if (value != NULL) { + bool* retValue = static_cast<bool*>(value); + *retValue = !networkStateNotifier().onLine(); + return NPERR_NO_ERROR; + } + } + case kJavaContext_ANPGetValue: { + jobject* retObject = static_cast<jobject*>(value); + *retObject = android::WebViewCore::getApplicationContext(); + return NPERR_NO_ERROR; + } } + (void)anp_getInterface(variable, value, &error); return error; } 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) */ |
