summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebCore/html/HTMLBodyElement.cpp2
-rw-r--r--WebCore/loader/FrameLoader.cpp7
-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--WebCore/plugins/android/PluginViewAndroid.cpp19
-rw-r--r--WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp149
-rw-r--r--WebKit/android/icu/unicode/ucnv.cpp5
-rw-r--r--WebKit/android/jni/WebSettings.cpp18
-rw-r--r--WebKit/android/jni/WebViewCore.cpp21
-rw-r--r--WebKit/android/jni/WebViewCore.h4
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp3
-rw-r--r--WebKit/android/plugins/android_npapi.h9
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)
*/