summaryrefslogtreecommitdiffstats
path: root/WebKit/android/jni
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/android/jni')
-rwxr-xr-xWebKit/android/jni/GeolocationPermissionsBridge.cpp2
-rw-r--r--WebKit/android/jni/JavaBridge.cpp31
-rw-r--r--WebKit/android/jni/JavaSharedClient.cpp11
-rw-r--r--WebKit/android/jni/JavaSharedClient.h2
-rwxr-xr-xWebKit/android/jni/MockGeolocation.cpp2
-rw-r--r--WebKit/android/jni/PictureSet.cpp8
-rw-r--r--WebKit/android/jni/PictureSet.h2
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.cpp495
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.h19
-rw-r--r--WebKit/android/jni/WebCoreJni.cpp38
-rw-r--r--WebKit/android/jni/WebCoreJni.h8
-rw-r--r--WebKit/android/jni/WebCoreJniOnLoad.cpp183
-rw-r--r--WebKit/android/jni/WebCoreRefObject.h2
-rw-r--r--WebKit/android/jni/WebCoreResourceLoader.cpp17
-rw-r--r--WebKit/android/jni/WebCoreResourceLoader.h19
-rw-r--r--WebKit/android/jni/WebCoreViewBridge.h2
-rw-r--r--WebKit/android/jni/WebFrameView.cpp3
-rw-r--r--WebKit/android/jni/WebFrameView.h2
-rw-r--r--WebKit/android/jni/WebHistory.cpp131
-rw-r--r--WebKit/android/jni/WebHistory.h37
-rw-r--r--WebKit/android/jni/WebIconDatabase.cpp18
-rw-r--r--WebKit/android/jni/WebIconDatabase.h5
-rw-r--r--WebKit/android/jni/WebSettings.cpp16
-rw-r--r--WebKit/android/jni/WebStorage.cpp9
-rw-r--r--WebKit/android/jni/WebViewCore.cpp1025
-rw-r--r--WebKit/android/jni/WebViewCore.h88
26 files changed, 1172 insertions, 1003 deletions
diff --git a/WebKit/android/jni/GeolocationPermissionsBridge.cpp b/WebKit/android/jni/GeolocationPermissionsBridge.cpp
index 0eeab3a..a9f79b0 100755
--- a/WebKit/android/jni/GeolocationPermissionsBridge.cpp
+++ b/WebKit/android/jni/GeolocationPermissionsBridge.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/WebKit/android/jni/JavaBridge.cpp b/WebKit/android/jni/JavaBridge.cpp
index f1b532d..049a7da 100644
--- a/WebKit/android/jni/JavaBridge.cpp
+++ b/WebKit/android/jni/JavaBridge.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -101,7 +101,7 @@ public:
static void UpdatePluginDirectories(JNIEnv* env, jobject obj, jobjectArray array, jboolean reload);
private:
- jobject mJavaObject;
+ jweak mJavaObject;
jmethodID mSetSharedTimer;
jmethodID mStopSharedTimer;
jmethodID mSetCookies;
@@ -118,7 +118,7 @@ static void (*sSharedTimerFiredCallback)();
JavaBridge::JavaBridge(JNIEnv* env, jobject obj)
{
- mJavaObject = adoptGlobalRef(env, obj);
+ mJavaObject = env->NewWeakGlobalRef(obj);
jclass clazz = env->GetObjectClass(obj);
mSetSharedTimer = env->GetMethodID(clazz, "setSharedTimer", "(J)V");
@@ -152,7 +152,7 @@ JavaBridge::~JavaBridge()
{
if (mJavaObject) {
JNIEnv* env = JSC::Bindings::getJNIEnv();
- env->DeleteGlobalRef(mJavaObject);
+ env->DeleteWeakGlobalRef(mJavaObject);
mJavaObject = 0;
}
@@ -167,8 +167,6 @@ JavaBridge::setSharedTimer(long long timemillis)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
AutoJObject obj = getRealObject(env, mJavaObject);
- if (!obj.get())
- return;
env->CallVoidMethod(obj.get(), mSetSharedTimer, timemillis);
}
@@ -177,8 +175,6 @@ JavaBridge::stopSharedTimer()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
AutoJObject obj = getRealObject(env, mJavaObject);
- if (!obj.get())
- return;
env->CallVoidMethod(obj.get(), mStopSharedTimer);
}
@@ -186,13 +182,11 @@ void
JavaBridge::setCookies(WebCore::KURL const& url, WebCore::String const& value)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = getRealObject(env, mJavaObject);
- if (!obj.get())
- return;
const WebCore::String& urlStr = url.string();
jstring jUrlStr = env->NewString(urlStr.characters(), urlStr.length());
jstring jValueStr = env->NewString(value.characters(), value.length());
+ AutoJObject obj = getRealObject(env, mJavaObject);
env->CallVoidMethod(obj.get(), mSetCookies, jUrlStr, jValueStr);
env->DeleteLocalRef(jUrlStr);
env->DeleteLocalRef(jValueStr);
@@ -203,10 +197,9 @@ JavaBridge::cookies(WebCore::KURL const& url)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
const WebCore::String& urlStr = url.string();
- AutoJObject obj = getRealObject(env, mJavaObject);
- if (!obj.get())
- return WebCore::String();
jstring jUrlStr = env->NewString(urlStr.characters(), urlStr.length());
+
+ AutoJObject obj = getRealObject(env, mJavaObject);
jstring string = (jstring)(env->CallObjectMethod(obj.get(), mCookies, jUrlStr));
WebCore::String ret = to_string(env, string);
@@ -220,8 +213,6 @@ JavaBridge::cookiesEnabled()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
AutoJObject obj = getRealObject(env, mJavaObject);
- if (!obj.get())
- return false;
jboolean ret = env->CallBooleanMethod(obj.get(), mCookiesEnabled);
return (ret != 0);
}
@@ -232,8 +223,6 @@ JavaBridge::getPluginDirectories()
WTF::Vector<WebCore::String> directories;
JNIEnv* env = JSC::Bindings::getJNIEnv();
AutoJObject obj = getRealObject(env, mJavaObject);
- if (!obj.get())
- return directories;
jobjectArray array = (jobjectArray)
env->CallObjectMethod(obj.get(), mGetPluginDirectories);
int count = env->GetArrayLength(array);
@@ -252,8 +241,6 @@ JavaBridge::getPluginSharedDataDirectory()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
AutoJObject obj = getRealObject(env, mJavaObject);
- if (!obj.get())
- return WebCore::String();
jstring ret = (jstring)env->CallObjectMethod(obj.get(), mGetPluginSharedDataDirectory);
WebCore::String path = to_string(env, ret);
checkException(env);
@@ -276,8 +263,6 @@ void JavaBridge::signalServiceFuncPtrQueue()
// environment is setup.
JNIEnv* env = JSC::Bindings::getJNIEnv();
AutoJObject obj = getRealObject(env, mJavaObject);
- if (!obj.get())
- return;
env->CallVoidMethod(obj.get(), mSignalFuncPtrQueue);
}
@@ -285,8 +270,6 @@ WTF::Vector<WebCore::String>JavaBridge::getSupportedKeyStrengthList() {
WTF::Vector<WebCore::String> list;
JNIEnv* env = JSC::Bindings::getJNIEnv();
AutoJObject obj = getRealObject(env, mJavaObject);
- if (!obj.get())
- return list;
jobjectArray array = (jobjectArray) env->CallObjectMethod(obj.get(),
mGetKeyStrengthList);
int count = env->GetArrayLength(array);
diff --git a/WebKit/android/jni/JavaSharedClient.cpp b/WebKit/android/jni/JavaSharedClient.cpp
index 2eec7b9..ce46570 100644
--- a/WebKit/android/jni/JavaSharedClient.cpp
+++ b/WebKit/android/jni/JavaSharedClient.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -102,24 +102,23 @@ namespace android {
void JavaSharedClient::ServiceFunctionPtrQueue()
{
for (;;) {
- void (*proc)(void*);
- void* payload;
+ void (*proc)(void*) = 0;
+ void* payload = 0;
const FuncPtrRec* rec;
// we have to copy the proc/payload (if present). we do this so we
// don't call the proc inside the mutex (possible deadlock!)
gFuncPtrQMutex.acquire();
rec = (const FuncPtrRec*)gFuncPtrQ.front();
- if (NULL != rec) {
+ if (rec) {
proc = rec->fProc;
payload = rec->fPayload;
gFuncPtrQ.pop_front();
}
gFuncPtrQMutex.release();
- if (NULL == rec) {
+ if (!rec)
break;
- }
proc(payload);
}
}
diff --git a/WebKit/android/jni/JavaSharedClient.h b/WebKit/android/jni/JavaSharedClient.h
index bf59969..d33df67 100644
--- a/WebKit/android/jni/JavaSharedClient.h
+++ b/WebKit/android/jni/JavaSharedClient.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/WebKit/android/jni/MockGeolocation.cpp b/WebKit/android/jni/MockGeolocation.cpp
index 3e79680..e76b1c1 100755
--- a/WebKit/android/jni/MockGeolocation.cpp
+++ b/WebKit/android/jni/MockGeolocation.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/WebKit/android/jni/PictureSet.cpp b/WebKit/android/jni/PictureSet.cpp
index e8fcba5..22f57a3 100644
--- a/WebKit/android/jni/PictureSet.cpp
+++ b/WebKit/android/jni/PictureSet.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -36,7 +36,7 @@
#include "SkRect.h"
#include "SkRegion.h"
#include "SkStream.h"
-#include <wtf/CurrentTime.h>
+#include "TimeCounter.h"
#define MAX_DRAW_TIME 100
#define MIN_SPLITTABLE 400
@@ -270,9 +270,9 @@ bool PictureSet::draw(SkCanvas* canvas)
}
canvas->translate(pathBounds.fLeft, pathBounds.fTop);
canvas->save();
- uint32_t startTime = WTF::get_thread_msec();
+ uint32_t startTime = getThreadMsec();
canvas->drawPicture(*working->mPicture);
- size_t elapsed = working->mElapsed = WTF::get_thread_msec() - startTime;
+ size_t elapsed = working->mElapsed = getThreadMsec() - startTime;
working->mWroteElapsed = true;
if (maxElapsed < elapsed && (pathBounds.width() >= MIN_SPLITTABLE ||
pathBounds.height() >= MIN_SPLITTABLE))
diff --git a/WebKit/android/jni/PictureSet.h b/WebKit/android/jni/PictureSet.h
index 51ff0b5..b177958 100644
--- a/WebKit/android/jni/PictureSet.h
+++ b/WebKit/android/jni/PictureSet.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp
index 745cc57..150c428 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,6 +28,7 @@
#include <config.h>
#include <wtf/Platform.h>
+#include <wtf/CurrentTime.h>
#include "android_graphics.h"
#include "Arena.h"
@@ -63,10 +64,8 @@
#if USE(JSC)
#include "GCController.h"
#include "JSDOMWindow.h"
-#include <runtime/InitializeThreading.h>
#include <runtime/JSLock.h>
#elif USE(V8)
-#include "InitializeThreading.h"
#include "jni_npobject.h"
#include "jni_instance.h"
#endif // USE(JSC)
@@ -82,6 +81,7 @@
#include "ResourceHandle.h"
#include "ScriptController.h"
#include "ScriptValue.h"
+#include "SecurityOrigin.h"
#include "SelectionController.h"
#include "Settings.h"
#include "SubstituteData.h"
@@ -116,6 +116,51 @@
#include "TimeCounter.h"
#endif
+using namespace JSC::Bindings;
+
+static String* gUploadFileLabel;
+static String* gResetLabel;
+static String* gSubmitLabel;
+
+String* WebCore::PlatformBridge::globalLocalizedName(
+ WebCore::PlatformBridge::rawResId resId)
+{
+ switch (resId) {
+ case WebCore::PlatformBridge::FileUploadLabel:
+ return gUploadFileLabel;
+ case WebCore::PlatformBridge::ResetLabel:
+ return gResetLabel;
+ case WebCore::PlatformBridge::SubmitLabel:
+ return gSubmitLabel;
+ default:
+ return 0;
+ }
+}
+/**
+ * Instantiate the localized name desired.
+ */
+void initGlobalLocalizedName(WebCore::PlatformBridge::rawResId resId,
+ android::WebFrame* webFrame)
+{
+ String** pointer;
+ switch (resId) {
+ case WebCore::PlatformBridge::FileUploadLabel:
+ pointer = &gUploadFileLabel;
+ break;
+ case WebCore::PlatformBridge::ResetLabel:
+ pointer = &gResetLabel;
+ break;
+ case WebCore::PlatformBridge::SubmitLabel:
+ pointer = &gSubmitLabel;
+ break;
+ default:
+ return;
+ }
+ if (!(*pointer) && webFrame) {
+ (*pointer) = new String(webFrame->getRawResourceFilename(resId).impl());
+ }
+}
+
namespace android {
// ----------------------------------------------------------------------------
@@ -126,8 +171,8 @@ namespace android {
struct WebFrame::JavaBrowserFrame
{
- jobject mObj;
- jobject mHistoryList; // WebBackForwardList object
+ jweak mObj;
+ jweak mHistoryList; // WebBackForwardList object
jmethodID mStartLoadingResource;
jmethodID mLoadStarted;
jmethodID mTransitionToCommitted;
@@ -146,6 +191,8 @@ struct WebFrame::JavaBrowserFrame
jmethodID mRequestFocus;
jmethodID mGetRawResFilename;
jmethodID mDensity;
+ jmethodID mGetFileSize;
+ jmethodID mGetFile;
AutoJObject frame(JNIEnv* env) {
return getRealObject(env, mObj);
}
@@ -165,10 +212,10 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
{
jclass clazz = env->GetObjectClass(obj);
mJavaFrame = new JavaBrowserFrame;
- mJavaFrame->mObj = adoptGlobalRef(env, obj);
- mJavaFrame->mHistoryList = adoptGlobalRef(env, historyList);
+ mJavaFrame->mObj = env->NewWeakGlobalRef(obj);
+ mJavaFrame->mHistoryList = env->NewWeakGlobalRef(historyList);
mJavaFrame->mStartLoadingResource = env->GetMethodID(clazz, "startLoadingResource",
- "(ILjava/lang/String;Ljava/lang/String;Ljava/util/HashMap;[BIZ)Landroid/webkit/LoadListener;");
+ "(ILjava/lang/String;Ljava/lang/String;Ljava/util/HashMap;[BJIZZZ)Landroid/webkit/LoadListener;");
mJavaFrame->mLoadStarted = env->GetMethodID(clazz, "loadStarted",
"(Ljava/lang/String;Landroid/graphics/Bitmap;IZ)V");
mJavaFrame->mTransitionToCommitted = env->GetMethodID(clazz, "transitionToCommitted",
@@ -202,6 +249,8 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
mJavaFrame->mGetRawResFilename = env->GetMethodID(clazz, "getRawResFilename",
"(I)Ljava/lang/String;");
mJavaFrame->mDensity = env->GetMethodID(clazz, "density","()F");
+ mJavaFrame->mGetFileSize = env->GetMethodID(clazz, "getFileSize", "(Ljava/lang/String;)I");
+ mJavaFrame->mGetFile = env->GetMethodID(clazz, "getFile", "(Ljava/lang/String;[BII)I");
LOG_ASSERT(mJavaFrame->mStartLoadingResource, "Could not find method startLoadingResource");
LOG_ASSERT(mJavaFrame->mLoadStarted, "Could not find method loadStarted");
@@ -221,6 +270,8 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
LOG_ASSERT(mJavaFrame->mRequestFocus, "Could not find method requestFocus");
LOG_ASSERT(mJavaFrame->mGetRawResFilename, "Could not find method getRawResFilename");
LOG_ASSERT(mJavaFrame->mDensity, "Could not find method density");
+ LOG_ASSERT(mJavaFrame->mGetFileSize, "Could not find method getFileSize");
+ LOG_ASSERT(mJavaFrame->mGetFile, "Could not find method getFile");
mUserAgent = WebCore::String();
mUserInitiatedClick = false;
@@ -229,9 +280,9 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
WebFrame::~WebFrame()
{
if (mJavaFrame->mObj) {
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- env->DeleteGlobalRef(mJavaFrame->mObj);
- env->DeleteGlobalRef(mJavaFrame->mHistoryList);
+ JNIEnv* env = getJNIEnv();
+ env->DeleteWeakGlobalRef(mJavaFrame->mObj);
+ env->DeleteWeakGlobalRef(mJavaFrame->mHistoryList);
mJavaFrame->mObj = 0;
}
delete mJavaFrame;
@@ -274,9 +325,50 @@ static jobject createJavaMapFromHTTPHeaders(JNIEnv* env, const WebCore::HTTPHead
return hashMap;
}
-WebCoreResourceLoader*
+// In WebViewCore.java, we artificially append the filename to the URI so that
+// webkit treats the actual display name of the file as the filename, rather
+// than the last segment of the URI (which will simply be a number). When we
+// pass the URI up to BrowserFrame, we no longer need the appended name (in fact
+// it causes problems), so remove it here.
+// FIXME: If we rewrite pathGetFileName (the current version is in
+// FileSystemPOSIX), we can get the filename that way rather than appending it.
+static jstring uriFromUriFileName(JNIEnv* env, const WebCore::String& name)
+{
+ const WebCore::String fileName = name.left(name.reverseFind('/'));
+ return env->NewString(fileName.characters(), fileName.length());
+}
+
+// This class stores the URI and the size of each file for upload. The URI is
+// stored so we do not have to create it again. The size is stored so we can
+// compare the actual size of the file with the stated size. If the actual size
+// is larger, we will not copy it, since we will not have enough space in our
+// buffer.
+class FileInfo {
+public:
+ FileInfo(JNIEnv* env, const WebCore::String& name) {
+ m_uri = uriFromUriFileName(env, name);
+ checkException(env);
+ m_size = 0;
+ m_env = env;
+ }
+ ~FileInfo() {
+ m_env->DeleteLocalRef(m_uri);
+ }
+ int getSize() { return m_size; }
+ jstring getUri() { return m_uri; }
+ void setSize(int size) { m_size = size; }
+private:
+ // This is only a pointer to the JNIEnv* returned by
+ // JSC::Bindings::getJNIEnv(). Used to delete the jstring when finished.
+ JNIEnv* m_env;
+ jstring m_uri;
+ int m_size;
+};
+
+PassRefPtr<WebCore::ResourceLoaderAndroid>
WebFrame::startLoadingResource(WebCore::ResourceHandle* loader,
const WebCore::ResourceRequest& request,
+ bool mainResource,
bool synchronous)
{
#ifdef ANDROID_INSTRUMENT
@@ -288,11 +380,7 @@ WebFrame::startLoadingResource(WebCore::ResourceHandle* loader,
WebCore::String method = request.httpMethod();
WebCore::HTTPHeaderMap headers = request.httpHeaderFields();
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return 0;
-
+ JNIEnv* env = getJNIEnv();
WebCore::String urlStr = request.url().string();
int colon = urlStr.find(':');
bool allLower = true;
@@ -313,6 +401,7 @@ WebFrame::startLoadingResource(WebCore::ResourceHandle* loader,
jMethodStr = env->NewString(method.characters(), method.length());
jbyteArray jPostDataStr = NULL;
WebCore::FormData* formdata = request.httpBody();
+ AutoJObject obj = mJavaFrame->frame(env);
if (formdata) {
// We can use the formdata->flatten() but it will result in two
// memcpys, first through loading up the vector with the form data
@@ -325,10 +414,19 @@ WebFrame::startLoadingResource(WebCore::ResourceHandle* loader,
// Sizing pass
int size = 0;
size_t n = elements.size();
+ FileInfo** fileinfos = new FileInfo*[n];
for (size_t i = 0; i < n; ++i) {
+ fileinfos[i] = 0;
const WebCore::FormDataElement& e = elements[i];
if (e.m_type == WebCore::FormDataElement::data) {
size += e.m_data.size();
+ } else if (e.m_type == WebCore::FormDataElement::encodedFile) {
+ fileinfos[i] = new FileInfo(env, e.m_filename);
+ int delta = env->CallIntMethod(obj.get(),
+ mJavaFrame->mGetFileSize, fileinfos[i]->getUri());
+ checkException(env);
+ fileinfos[i]->setSize(delta);
+ size += delta;
}
}
@@ -347,11 +445,19 @@ WebFrame::startLoadingResource(WebCore::ResourceHandle* loader,
int delta = e.m_data.size();
memcpy(bytes + offset, e.m_data.data(), delta);
offset += delta;
+ } else if (e.m_type
+ == WebCore::FormDataElement::encodedFile) {
+ int delta = env->CallIntMethod(obj.get(),
+ mJavaFrame->mGetFile, fileinfos[i]->getUri(),
+ jPostDataStr, offset, fileinfos[i]->getSize());
+ checkException(env);
+ offset += delta;
}
}
env->ReleaseByteArrayElements(jPostDataStr, bytes, 0);
}
}
+ delete[] fileinfos;
}
jobject jHeaderMap = createJavaMapFromHTTPHeaders(env, headers);
@@ -378,8 +484,10 @@ WebFrame::startLoadingResource(WebCore::ResourceHandle* loader,
jobject jLoadListener =
env->CallObjectMethod(obj.get(), mJavaFrame->mStartLoadingResource,
- (int)loader, jUrlStr, jMethodStr, jHeaderMap,
- jPostDataStr, cacheMode, synchronous);
+ (int)loader, jUrlStr, jMethodStr, jHeaderMap,
+ jPostDataStr, formdata ? formdata->identifier(): 0,
+ cacheMode, mainResource, request.getUserGesture(),
+ synchronous);
env->DeleteLocalRef(jUrlStr);
env->DeleteLocalRef(jMethodStr);
@@ -388,9 +496,9 @@ WebFrame::startLoadingResource(WebCore::ResourceHandle* loader,
if (checkException(env))
return NULL;
- WebCoreResourceLoader* h = NULL;
+ PassRefPtr<WebCore::ResourceLoaderAndroid> h;
if (jLoadListener)
- h = new WebCoreResourceLoader(env, jLoadListener);
+ h = WebCoreResourceLoader::create(env, jLoadListener);
env->DeleteLocalRef(jLoadListener);
return h;
}
@@ -403,14 +511,12 @@ WebFrame::reportError(int errorCode, const WebCore::String& description,
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
LOGV("::WebCore:: reportError(%d, %s)", errorCode, description.ascii().data());
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return;
+ JNIEnv* env = getJNIEnv();
jstring descStr = env->NewString((unsigned short*)description.characters(), description.length());
jstring failUrl = env->NewString((unsigned short*)failingUrl.characters(), failingUrl.length());
- env->CallVoidMethod(obj.get(), mJavaFrame->mReportError, errorCode, descStr, failUrl);
+ env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mReportError,
+ errorCode, descStr, failUrl);
env->DeleteLocalRef(descStr);
env->DeleteLocalRef(failUrl);
}
@@ -435,10 +541,7 @@ WebFrame::loadStarted(WebCore::Frame* frame)
!isMainFrame))
return;
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return;
+ JNIEnv* env = getJNIEnv();
WebCore::String urlString(url.string());
// If this is the main frame and we already have a favicon in the database,
// send it along with the page started notification.
@@ -451,7 +554,7 @@ WebFrame::loadStarted(WebCore::Frame* frame)
}
jstring urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length());
- env->CallVoidMethod(obj.get(), mJavaFrame->mLoadStarted, urlStr, favicon,
+ env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mLoadStarted, urlStr, favicon,
(int)loadType, isMainFrame);
checkException(env);
env->DeleteLocalRef(urlStr);
@@ -475,13 +578,10 @@ WebFrame::transitionToCommitted(WebCore::Frame* frame)
#ifdef ANDROID_INSTRUMENT
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return;
+ JNIEnv* env = getJNIEnv();
WebCore::FrameLoadType loadType = frame->loader()->loadType();
bool isMainFrame = (!frame->tree() || !frame->tree()->parent());
- env->CallVoidMethod(obj.get(), mJavaFrame->mTransitionToCommitted,
+ env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mTransitionToCommitted,
(int)loadType, isMainFrame);
checkException(env);
}
@@ -492,10 +592,7 @@ WebFrame::didFinishLoad(WebCore::Frame* frame)
#ifdef ANDROID_INSTRUMENT
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return;
+ JNIEnv* env = getJNIEnv();
WebCore::FrameLoader* loader = frame->loader();
const WebCore::KURL& url = loader->activeDocumentLoader()->url();
if (url.isEmpty())
@@ -506,7 +603,7 @@ WebFrame::didFinishLoad(WebCore::Frame* frame)
WebCore::FrameLoadType loadType = loader->loadType();
WebCore::String urlString(url.string());
jstring urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length());
- env->CallVoidMethod(obj.get(), mJavaFrame->mLoadFinished, urlStr,
+ env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mLoadFinished, urlStr,
(int)loadType, isMainFrame);
checkException(env);
env->DeleteLocalRef(urlStr);
@@ -519,7 +616,7 @@ WebFrame::addHistoryItem(WebCore::HistoryItem* item)
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
LOGV("::WebCore:: addHistoryItem");
- JNIEnv* env = JSC::Bindings::getJNIEnv();
+ JNIEnv* env = getJNIEnv();
WebHistory::AddItem(mJavaFrame->history(env), item);
}
@@ -530,7 +627,7 @@ WebFrame::removeHistoryItem(int index)
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
LOGV("::WebCore:: removeHistoryItem at %d", index);
- JNIEnv* env = JSC::Bindings::getJNIEnv();
+ JNIEnv* env = getJNIEnv();
WebHistory::RemoveItem(mJavaFrame->history(env), index);
}
@@ -541,7 +638,7 @@ WebFrame::updateHistoryIndex(int newIndex)
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
LOGV("::WebCore:: updateHistoryIndex to %d", newIndex);
- JNIEnv* env = JSC::Bindings::getJNIEnv();
+ JNIEnv* env = getJNIEnv();
WebHistory::UpdateHistoryIndex(mJavaFrame->history(env), newIndex);
}
@@ -554,13 +651,10 @@ WebFrame::setTitle(const WebCore::String& title)
#ifndef NDEBUG
LOGV("setTitle(%s)", title.ascii().data());
#endif
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return;
+ JNIEnv* env = getJNIEnv();
jstring jTitleStr = env->NewString((unsigned short *)title.characters(), title.length());
- env->CallVoidMethod(obj.get(), mJavaFrame->mSetTitle,
+ env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mSetTitle,
jTitleStr);
checkException(env);
env->DeleteLocalRef(jTitleStr);
@@ -573,12 +667,9 @@ WebFrame::windowObjectCleared(WebCore::Frame* frame)
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
LOGV("::WebCore:: windowObjectCleared");
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return;
+ JNIEnv* env = getJNIEnv();
- env->CallVoidMethod(obj.get(), mJavaFrame->mWindowObjectCleared, (int)frame);
+ env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mWindowObjectCleared, (int)frame);
checkException(env);
}
@@ -588,12 +679,9 @@ WebFrame::setProgress(float newProgress)
#ifdef ANDROID_INSTRUMENT
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return;
+ JNIEnv* env = getJNIEnv();
int progress = (int) (100 * newProgress);
- env->CallVoidMethod(obj.get(), mJavaFrame->mSetProgress, progress);
+ env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mSetProgress, progress);
checkException(env);
}
@@ -610,15 +698,12 @@ WebFrame::didReceiveIcon(WebCore::Image* icon)
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
LOG_ASSERT(icon, "DidReceiveIcon called without an image!");
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return;
+ JNIEnv* env = getJNIEnv();
jobject bitmap = webcoreImageToJavaBitmap(env, icon);
if (!bitmap)
return;
- env->CallVoidMethod(obj.get(), mJavaFrame->mDidReceiveIcon, bitmap);
+ env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDidReceiveIcon, bitmap);
env->DeleteLocalRef(bitmap);
checkException(env);
}
@@ -629,14 +714,11 @@ WebFrame::didReceiveTouchIconURL(const WebCore::String& url, bool precomposed)
#ifdef ANDROID_INSTRUMENT
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return;
+ JNIEnv* env = getJNIEnv();
jstring jUrlStr = env->NewString((unsigned short*)url.characters(),
url.length());
- env->CallVoidMethod(obj.get(),
+ env->CallVoidMethod(mJavaFrame->frame(env).get(),
mJavaFrame->mDidReceiveTouchIconUrl, jUrlStr, precomposed);
checkException(env);
}
@@ -648,14 +730,10 @@ WebFrame::updateVisitedHistory(const WebCore::KURL& url, bool reload)
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
WebCore::String urlStr(url.string());
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return;
-
+ JNIEnv* env = getJNIEnv();
jstring jUrlStr = env->NewString((unsigned short*)urlStr.characters(), urlStr.length());
- env->CallVoidMethod(obj.get(), mJavaFrame->mUpdateVisitedHistory, jUrlStr, reload);
+ env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mUpdateVisitedHistory, jUrlStr, reload);
checkException(env);
}
@@ -678,15 +756,12 @@ WebFrame::canHandleRequest(const WebCore::ResourceRequest& request)
// Empty urls should not be sent to java
if (url.isEmpty())
return true;
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return true;
+ JNIEnv* env = getJNIEnv();
jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length());
// check to see whether browser app wants to hijack url loading.
// if browser app handles the url, we will return false to bail out WebCore loading
- jboolean ret = env->CallBooleanMethod(obj.get(), mJavaFrame->mHandleUrl, jUrlStr);
+ jboolean ret = env->CallBooleanMethod(mJavaFrame->frame(env).get(), mJavaFrame->mHandleUrl, jUrlStr);
checkException(env);
return (ret == 0);
}
@@ -697,14 +772,11 @@ WebFrame::createWindow(bool dialog, bool userGesture)
#ifdef ANDROID_INSTRUMENT
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return NULL;
- jobject jobj = env->CallObjectMethod(obj.get(),
+ JNIEnv* env = getJNIEnv();
+ jobject obj = env->CallObjectMethod(mJavaFrame->frame(env).get(),
mJavaFrame->mCreateWindow, dialog, userGesture);
- if (jobj) {
- WebCore::Frame* frame = GET_NATIVE_FRAME(env, jobj);
+ if (obj) {
+ WebCore::Frame* frame = GET_NATIVE_FRAME(env, obj);
return frame;
}
return NULL;
@@ -716,11 +788,8 @@ WebFrame::requestFocus() const
#ifdef ANDROID_INSTRUMENT
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), mJavaFrame->mRequestFocus);
+ JNIEnv* env = getJNIEnv();
+ env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mRequestFocus);
checkException(env);
}
@@ -731,11 +800,8 @@ WebFrame::closeWindow(WebViewCore* webViewCore)
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
assert(webViewCore);
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), mJavaFrame->mCloseWindow,
+ JNIEnv* env = getJNIEnv();
+ env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mCloseWindow,
webViewCore->getJavaObject().get());
}
@@ -749,23 +815,17 @@ WebFrame::decidePolicyForFormResubmission(WebCore::FramePolicyFunction func)
#ifdef ANDROID_INSTRUMENT
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return;
+ JNIEnv* env = getJNIEnv();
PolicyFunctionWrapper* p = new PolicyFunctionWrapper;
p->func = func;
- env->CallVoidMethod(obj.get(), mJavaFrame->mDecidePolicyForFormResubmission, p);
+ env->CallVoidMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDecidePolicyForFormResubmission, p);
}
WebCore::String
-WebFrame::getRawResourceFilename(RAW_RES_ID id) const
+WebFrame::getRawResourceFilename(WebCore::PlatformBridge::rawResId id) const
{
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return WebCore::String();
- jstring ret = (jstring) env->CallObjectMethod(obj.get(),
+ JNIEnv* env = getJNIEnv();
+ jstring ret = (jstring) env->CallObjectMethod(mJavaFrame->frame(env).get(),
mJavaFrame->mGetRawResFilename, (int)id);
return to_string(env, ret);
@@ -774,11 +834,8 @@ WebFrame::getRawResourceFilename(RAW_RES_ID id) const
float
WebFrame::density() const
{
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = mJavaFrame->frame(env);
- if (!obj.get())
- return 1.0;
- jfloat dpi = env->CallFloatMethod(obj.get(), mJavaFrame->mDensity);
+ JNIEnv* env = getJNIEnv();
+ jfloat dpi = env->CallFloatMethod(mJavaFrame->frame(env).get(), mJavaFrame->mDensity);
checkException(env);
return dpi;
}
@@ -798,16 +855,12 @@ static void CallPolicyFunction(JNIEnv* env, jobject obj, jint func, jint decisio
if (decision == WebCore::PolicyUse)
pFrame->loader()->resetMultipleFormSubmissionProtection();
- (pFrame->loader()->*(pFunc->func))((WebCore::PolicyAction)decision);
+ (pFrame->loader()->policyChecker()->*(pFunc->func))((WebCore::PolicyAction)decision);
}
static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAssetManager, jobject historyList)
{
-#if USE(JSC)
- JSC::initializeThreading();
-#elif USE(V8)
- V8::initializeThreading();
-#endif
+ ScriptController::initializeThreading();
#ifdef ANDROID_INSTRUMENT
TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
@@ -818,18 +871,10 @@ static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAss
WebCore::DragClient* dragC = new DragClientAndroid;
InspectorClientAndroid* inspectorC = new InspectorClientAndroid;
// Create a new page
- WebCore::Page* page = new WebCore::Page(chromeC, contextMenuC, editorC, dragC, inspectorC);
+ WebCore::Page* page = new WebCore::Page(chromeC, contextMenuC, editorC, dragC, inspectorC, 0);
// css files without explicit MIMETYPE is treated as generic text files in
// the Java side. So we can't enforce CSS MIMETYPE.
page->settings()->setEnforceCSSMIMETypeInStrictMode(false);
- /* TODO: Don't turn on PageCache until we can restore the ScrollView State.
- * This caused bug http://b/issue?id=1202983
- page->settings()->setUsesPageCache(true);
- // 10 is a random number chosen because it is small enough to give the user
- // a good back/forward page cache without allowing the page cache to get too
- // big.
- WebCore::pageCache()->setCapacity(10);
- */
editorC->setPage(page);
page->setGroupName("android.webkit");
@@ -865,15 +910,16 @@ static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAss
frame->selection()->setFocused(true);
// Allow local access to file:/// and substitute data
- WebCore::FrameLoader::setLocalLoadPolicy(
- WebCore::FrameLoader::AllowLocalLoadsForLocalAndSubstituteData);
+ WebCore::SecurityOrigin::setLocalLoadPolicy(
+ WebCore::SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData);
LOGV("::WebCore:: createFrame %p", frame);
// Set the mNativeFrame field in Frame
SET_NATIVE_FRAME(env, obj, (int)frame);
- String directory = webFrame->getRawResourceFilename(WebFrame::DRAWABLEDIR);
+ String directory = webFrame->getRawResourceFilename(
+ WebCore::PlatformBridge::DrawableDir);
if (directory.isEmpty())
LOGE("Can't find the drawable directory");
else {
@@ -882,6 +928,10 @@ static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAss
// Initialize our skinning classes
WebCore::RenderSkinAndroid::Init(am, directory);
}
+ for (int i = WebCore::PlatformBridge::FileUploadLabel;
+ i <= WebCore::PlatformBridge::SubmitLabel; i++)
+ initGlobalLocalizedName(
+ static_cast<WebCore::PlatformBridge::rawResId>(i), webFrame);
}
static void DestroyFrame(JNIEnv* env, jobject obj)
@@ -942,13 +992,17 @@ static void PostUrl(JNIEnv *env, jobject obj, jstring url, jbyteArray postData)
if (postData) {
jsize size = env->GetArrayLength(postData);
jbyte* bytes = env->GetByteArrayElements(postData, NULL);
- request.setHTTPBody(WebCore::FormData::create((const void*)bytes, size));
+ RefPtr<FormData> formData = FormData::create((const void*)bytes, size);
+ // the identifier uses the same logic as generateFormDataIdentifier() in
+ // HTMLFormElement.cpp
+ formData->setIdentifier(static_cast<int64_t>(WTF::currentTime() * 1000000.0));
+ request.setHTTPBody(formData);
env->ReleaseByteArrayElements(postData, bytes, 0);
}
LOGV("PostUrl %s", kurl.string().latin1().data());
WebCore::FrameLoadRequest frameRequest(request);
- pFrame->loader()->loadFrameRequest(frameRequest, false, false, 0, 0);
+ pFrame->loader()->loadFrameRequest(frameRequest, false, false, 0, 0, WebCore::SendReferrer);
}
static void LoadData(JNIEnv *env, jobject obj, jstring baseUrl, jstring data,
@@ -973,7 +1027,7 @@ static void LoadData(JNIEnv *env, jobject obj, jstring baseUrl, jstring data,
WebCore::SubstituteData substituteData(sharedBuffer,
to_string(env, mimeType), to_string(env, encoding),
- WebCore::KURL(to_string(env, failUrl)));
+ WebCore::KURL(ParsedURLString, to_string(env, failUrl)));
// Perform the load
pFrame->loader()->load(request, substituteData, false);
@@ -1001,7 +1055,7 @@ static jstring ExternalRepresentation(JNIEnv *env, jobject obj)
LOG_ASSERT(pFrame, "android_webcore_nativeExternalRepresentation must take a valid frame pointer!");
// Request external representation of the render tree
- WebCore::String renderDump = WebCore::externalRepresentation(pFrame->contentRenderer());
+ WebCore::String renderDump = WebCore::externalRepresentation(pFrame);
unsigned len = renderDump.length();
if (!len)
return NULL;
@@ -1060,7 +1114,7 @@ static void GoBackOrForward(JNIEnv *env, jobject obj, jint pos)
else if (pos == -1)
pFrame->page()->goBack();
else
- pFrame->loader()->goBackOrForward(pos);
+ pFrame->page()->goBackOrForward(pos);
}
static jobject StringByEvaluatingJavaScriptFromString(JNIEnv *env, jobject obj, jstring script)
@@ -1072,9 +1126,14 @@ static jobject StringByEvaluatingJavaScriptFromString(JNIEnv *env, jobject obj,
LOG_ASSERT(pFrame, "stringByEvaluatingJavaScriptFromString must take a valid frame pointer!");
WebCore::ScriptValue value =
- pFrame->loader()->executeScript(to_string(env, script), true);
+ pFrame->script()->executeScript(to_string(env, script), true);
WebCore::String result = WebCore::String();
- if (!value.getString(result))
+#if USE(JSC)
+ ScriptState* scriptState = pFrame->script()->globalObject(mainThreadNormalWorld())->globalExec();
+#elif USE(V8)
+ ScriptState* scriptState = pFrame->script()->mainWorldScriptState();
+#endif
+ if (!value.getString(scriptState, result))
return NULL;
unsigned len = result.length();
if (len == 0)
@@ -1082,31 +1141,55 @@ static jobject StringByEvaluatingJavaScriptFromString(JNIEnv *env, jobject obj,
return env->NewString((unsigned short*)result.characters(), len);
}
-#if USE(JSC)
// Wrap the JavaInstance used when binding custom javascript interfaces. Use a
// weak reference so that the gc can collect the WebView. Override virtualBegin
// and virtualEnd and swap the weak reference for the real object.
-class WeakJavaInstance : public JSC::Bindings::JavaInstance {
+class WeakJavaInstance : public JavaInstance {
public:
- static PassRefPtr<WeakJavaInstance> create(jobject obj,
- PassRefPtr<JSC::Bindings::RootObject> root) {
+#if USE(JSC)
+ static PassRefPtr<WeakJavaInstance> create(jobject obj, PassRefPtr<RootObject> root)
+ {
return adoptRef(new WeakJavaInstance(obj, root));
}
+#elif USE(V8)
+ static PassRefPtr<WeakJavaInstance> create(jobject obj)
+ {
+ return adoptRef(new WeakJavaInstance(obj));
+ }
+#endif
-protected:
- WeakJavaInstance(jobject instance, PassRefPtr<JSC::Bindings::RootObject> rootObject)
- : JSC::Bindings::JavaInstance(instance, rootObject)
+private:
+#if USE(JSC)
+ WeakJavaInstance(jobject instance, PassRefPtr<RootObject> rootObject)
+ : JavaInstance(instance, rootObject)
+#elif USE(V8)
+ WeakJavaInstance(jobject instance) : JavaInstance(instance)
+#endif
{
- JNIEnv* env = JSC::Bindings::getJNIEnv();
+ JNIEnv* env = getJNIEnv();
// JavaInstance creates a global ref to instance in its constructor.
- env->DeleteGlobalRef(_instance->_instance);
- // Set the object to our WeakReference wrapper.
- _instance->_instance = adoptGlobalRef(env, instance);
+ env->DeleteGlobalRef(_instance->instance());
+ // Set the object to a weak reference.
+ _instance->setInstance(env->NewWeakGlobalRef(instance));
+ }
+ ~WeakJavaInstance()
+ {
+ JNIEnv* env = getJNIEnv();
+ // Store the weak reference so we can delete it later.
+ jweak weak = _instance->instance();
+ // The JavaInstance destructor attempts to delete the global ref stored
+ // in _instance. Since we replaced it in our constructor with a weak
+ // reference, restore the global ref here so the vm will not complain.
+ _instance->setInstance(env->NewGlobalRef(
+ getRealObject(env, _instance->instance()).get()));
+ // Delete the weak reference.
+ env->DeleteWeakGlobalRef(weak);
}
- virtual void virtualBegin() {
- _weakRef = _instance->_instance;
- JNIEnv* env = JSC::Bindings::getJNIEnv();
+ virtual void virtualBegin()
+ {
+ _weakRef = _instance->instance();
+ JNIEnv* env = getJNIEnv();
// This is odd. getRealObject returns an AutoJObject which is used to
// cleanly create and delete a local reference. But, here we need to
// maintain the local reference across calls to virtualBegin() and
@@ -1114,26 +1197,26 @@ protected:
// and delete the local reference in virtualEnd().
_realObject = getRealObject(env, _weakRef).release();
// Point to the real object
- _instance->_instance = _realObject;
+ _instance->setInstance(_realObject);
// Call the base class method
INHERITED::virtualBegin();
}
- virtual void virtualEnd() {
+ virtual void virtualEnd()
+ {
// Call the base class method first to pop the local frame.
INHERITED::virtualEnd();
// Get rid of the local reference to the real object.
- JSC::Bindings::getJNIEnv()->DeleteLocalRef(_realObject);
+ getJNIEnv()->DeleteLocalRef(_realObject);
// Point back to the WeakReference.
- _instance->_instance = _weakRef;
+ _instance->setInstance(_weakRef);
}
private:
- typedef JSC::Bindings::JavaInstance INHERITED;
+ typedef JavaInstance INHERITED;
jobject _realObject;
- jobject _weakRef;
+ jweak _weakRef;
};
-#endif // USE(JSC)
static void AddJavascriptInterface(JNIEnv *env, jobject obj, jint nativeFramePointer,
jobject javascriptObj, jstring interfaceName)
@@ -1155,39 +1238,44 @@ static void AddJavascriptInterface(JNIEnv *env, jobject obj, jint nativeFramePoi
#if USE(JSC)
// Copied from qwebframe.cpp
JSC::JSLock lock(false);
- WebCore::JSDOMWindow *window = WebCore::toJSDOMWindow(pFrame);
+ WebCore::JSDOMWindow *window = WebCore::toJSDOMWindow(pFrame, mainThreadNormalWorld());
if (window) {
- JSC::Bindings::RootObject *root = pFrame->script()->bindingRootObject();
- JSC::Bindings::setJavaVM(vm);
+ RootObject *root = pFrame->script()->bindingRootObject();
+ setJavaVM(vm);
// Add the binding to JS environment
JSC::ExecState* exec = window->globalExec();
- JSC::JSObject *addedObject = WeakJavaInstance::create(javascriptObj,
+ JSC::JSObject* addedObject = WeakJavaInstance::create(javascriptObj,
root)->createRuntimeObject(exec);
const jchar* s = env->GetStringChars(interfaceName, NULL);
if (s) {
// Add the binding name to the window's table of child objects.
JSC::PutPropertySlot slot;
- window->put(exec, JSC::Identifier(exec, (const UChar *)s,
+ window->put(exec, JSC::Identifier(exec, (const UChar *)s,
env->GetStringLength(interfaceName)), addedObject, slot);
env->ReleaseStringChars(interfaceName, s);
checkException(env);
}
}
-#endif // USE(JSC)
-
-#if USE(V8)
+#elif USE(V8)
if (pFrame) {
- const char* name = JSC::Bindings::getCharactersFromJStringInEnv(env, interfaceName);
- NPObject* obj = JSC::Bindings::JavaInstanceToNPObject(new JSC::Bindings::JavaInstance(javascriptObj));
+ PassRefPtr<JavaInstance> addedObject = WeakJavaInstance::create(javascriptObj);
+ const char* name = getCharactersFromJStringInEnv(env, interfaceName);
+ // Pass ownership of the added object to bindToWindowObject.
+ NPObject* obj = JavaInstanceToNPObject(addedObject.releaseRef());
pFrame->script()->bindToWindowObject(pFrame, name, obj);
- // JavaInstanceToNPObject calls NPN_RetainObject on the
- // returned one (see CreateV8ObjectForNPObject in V8NPObject.cpp).
- // BindToWindowObject also increases obj's ref count and decrease
+ // bindToWindowObject calls NPN_RetainObject on the
+ // returned one (see createV8ObjectForNPObject in V8NPObject.cpp).
+ // bindToWindowObject also increases obj's ref count and decreases
// the ref count when the object is not reachable from JavaScript
// side. Code here must release the reference count increased by
- // JavaInstanceToNPObject.
- _NPN_ReleaseObject(obj);
- JSC::Bindings::releaseCharactersForJString(interfaceName, name);
+ // bindToWindowObject.
+
+ // Note that while this function is declared in WebCore/bridge/npruntime.h, for V8 builds
+ // we use WebCore/bindings/v8/npruntime.cpp (rather than
+ // WebCore/bridge/npruntime.cpp), so the function is implemented there.
+ // TODO: Combine the two versions of these NPAPI files.
+ NPN_ReleaseObject(obj);
+ releaseCharactersForJString(interfaceName, name);
}
#endif
@@ -1228,6 +1316,14 @@ static void ClearCache(JNIEnv *env, jobject obj)
WebCore::cache()->setDisabled(true);
WebCore::cache()->setDisabled(false);
}
+
+ // clear page cache
+ int pageCapacity = WebCore::pageCache()->capacity();
+ // Setting size to 0, makes all pages be released.
+ WebCore::pageCache()->setCapacity(0);
+ WebCore::pageCache()->releaseAutoreleasedPagesNow();
+ WebCore::pageCache()->setCapacity(pageCapacity);
+
#if USE(JSC)
// force JavaScript to GC when clear cache
WebCore::gcController().garbageCollectSoon();
@@ -1381,9 +1477,6 @@ static jobject GetFormTextData(JNIEnv *env, jobject obj)
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
LOG_ASSERT(put, "Could not find put method on HashMap");
- static const WebCore::AtomicString text("text");
- static const WebCore::AtomicString off("off");
-
WebCore::HTMLFormElement* form;
WebCore::HTMLInputElement* input;
for (WebCore::Node* node = collection->firstItem(); node; node = collection->nextItem()) {
@@ -1393,23 +1486,21 @@ static jobject GetFormTextData(JNIEnv *env, jobject obj)
size_t size = elements.size();
for (size_t i = 0; i < size; i++) {
WebCore::HTMLFormControlElement* e = elements[i];
- if (e->type() == text) {
- if (e->hasAttribute(WebCore::HTMLNames::autocompleteAttr)) {
- const WebCore::AtomicString& attr = e->getAttribute(WebCore::HTMLNames::autocompleteAttr);
- if (attr == off)
- continue;
- }
- input = (WebCore::HTMLInputElement*) e;
- WebCore::String value = input->value();
- int len = value.length();
- if (len) {
- const WebCore::AtomicString& name = input->name();
- jstring key = env->NewString((jchar *)name.characters(), name.length());
- jstring val = env->NewString((jchar *)value.characters(), len);
- LOG_ASSERT(key && val, "name or value not set");
- env->CallObjectMethod(hashMap, put, key, val);
- env->DeleteLocalRef(key);
- env->DeleteLocalRef(val);
+ if (e->hasTagName(WebCore::HTMLNames::inputTag)) {
+ input = static_cast<WebCore::HTMLInputElement*>(e);
+ if (input->isTextField() && !input->isPasswordField()
+ && input->autoComplete()) {
+ WebCore::String value = input->value();
+ int len = value.length();
+ if (len) {
+ const WebCore::AtomicString& name = input->name();
+ jstring key = env->NewString((jchar *)name.characters(), name.length());
+ jstring val = env->NewString((jchar *)value.characters(), len);
+ LOG_ASSERT(key && val, "name or value not set");
+ env->CallObjectMethod(hashMap, put, key, val);
+ env->DeleteLocalRef(key);
+ env->DeleteLocalRef(val);
+ }
}
}
}
@@ -1421,6 +1512,16 @@ static jobject GetFormTextData(JNIEnv *env, jobject obj)
return hashMap;
}
+static void OrientationChanged(JNIEnv *env, jobject obj, int orientation)
+{
+#ifdef ANDROID_INSTRUMENT
+ TimeCounterAuto counter(TimeCounter::NativeCallbackTimeCounter);
+#endif
+ WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
+ LOGE("Sending orientation: %d", orientation);
+ pFrame->sendOrientationChangeEvent(orientation);
+}
+
// ----------------------------------------------------------------------------
/*
@@ -1470,7 +1571,9 @@ static JNINativeMethod gBrowserFrameNativeMethods[] = {
{ "setUsernamePassword", "(Ljava/lang/String;Ljava/lang/String;)V",
(void*) SetUsernamePassword },
{ "getFormTextData", "()Ljava/util/HashMap;",
- (void*) GetFormTextData }
+ (void*) GetFormTextData },
+ { "nativeOrientationChanged", "(I)V",
+ (void*) OrientationChanged }
};
int register_webframe(JNIEnv* env)
diff --git a/WebKit/android/jni/WebCoreFrameBridge.h b/WebKit/android/jni/WebCoreFrameBridge.h
index 7b49981..657ebf1 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.h
+++ b/WebKit/android/jni/WebCoreFrameBridge.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -29,9 +29,10 @@
#define WEBFRAME_H
#include "FrameLoaderClient.h"
-#include "PlatformString.h"
+#include "PlatformBridge.h"
#include "WebCoreRefObject.h"
#include <jni.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
class HistoryItem;
@@ -39,31 +40,25 @@ namespace WebCore {
class Page;
class RenderPart;
class ResourceHandle;
+ class ResourceLoaderAndroid;
class ResourceRequest;
}
namespace android {
-class WebCoreResourceLoader;
class WebViewCore;
// one instance of WebFrame per Page for calling into Java's BrowserFrame
class WebFrame : public WebCoreRefObject {
public:
- // these ids need to be in sync with the constants in BrowserFrame.java
- enum RAW_RES_ID {
- NODOMAIN = 1,
- LOADERROR,
- DRAWABLEDIR,
- };
WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page* page);
~WebFrame();
// helper function
static WebFrame* getWebFrame(const WebCore::Frame* frame);
- virtual WebCoreResourceLoader* startLoadingResource(WebCore::ResourceHandle*,
- const WebCore::ResourceRequest& request,
+ virtual PassRefPtr<WebCore::ResourceLoaderAndroid> startLoadingResource(WebCore::ResourceHandle*,
+ const WebCore::ResourceRequest& request, bool mainResource,
bool synchronous);
void reportError(int errorCode, const WebCore::String& description,
@@ -107,7 +102,7 @@ class WebFrame : public WebCoreRefObject {
void setUserAgent(WebCore::String userAgent) { mUserAgent = userAgent; }
- WebCore::String getRawResourceFilename(RAW_RES_ID) const;
+ WebCore::String getRawResourceFilename(WebCore::PlatformBridge::rawResId) const;
float density() const;
diff --git a/WebKit/android/jni/WebCoreJni.cpp b/WebKit/android/jni/WebCoreJni.cpp
index e7088b2..ef33cc0 100644
--- a/WebKit/android/jni/WebCoreJni.cpp
+++ b/WebKit/android/jni/WebCoreJni.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -22,6 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#define LOG_TAG "webcoreglue"
#include "config.h"
@@ -34,25 +35,10 @@
namespace android {
-// Class, constructor, and get method on WeakReference
-jclass gWeakRefClass;
-jmethodID gWeakRefInit;
-jmethodID gWeakRefGet;
-
-jobject adoptGlobalRef(JNIEnv* env, jobject obj)
-{
- // Create a WeakReference object
- jobject ref = env->NewObject(gWeakRefClass, gWeakRefInit, obj);
- // Increment the ref count of the WeakReference
- ref = env->NewGlobalRef(ref);
- return ref;
-}
-
AutoJObject getRealObject(JNIEnv* env, jobject obj)
{
- jobject real = env->CallObjectMethod(obj, gWeakRefGet);
- if (!real)
- LOGE("The real object has been deleted");
+ jobject real = env->NewLocalRef(obj);
+ LOG_ASSERT(real, "The real object has been deleted!");
return AutoJObject(env, real);
}
@@ -85,20 +71,4 @@ WebCore::String to_string(JNIEnv* env, jstring str)
return ret;
}
-int register_webcorejni(JNIEnv* env) {
- // Instantiate the WeakReference fields.
- jclass weakRef = env->FindClass("java/lang/ref/WeakReference");
- LOG_ASSERT(weakRef, "Could not find WeakReference");
- android::gWeakRefClass = (jclass)env->NewGlobalRef(weakRef);
- android::gWeakRefInit = env->GetMethodID(android::gWeakRefClass,
- "<init>", "(Ljava/lang/Object;)V");
- LOG_ASSERT(android::gWeakRefInit,
- "Could not find constructor for WeakReference");
- android::gWeakRefGet = env->GetMethodID(android::gWeakRefClass, "get",
- "()Ljava/lang/Object;");
- LOG_ASSERT(android::gWeakRefInit,
- "Could not find get method for WeakReference");
- return JNI_OK;
-}
-
}
diff --git a/WebKit/android/jni/WebCoreJni.h b/WebKit/android/jni/WebCoreJni.h
index 0b55497..1a1bfc0 100644
--- a/WebKit/android/jni/WebCoreJni.h
+++ b/WebKit/android/jni/WebCoreJni.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -61,14 +61,10 @@ private:
friend AutoJObject getRealObject(JNIEnv*, jobject);
};
-// Get the real object stored in the WeakReference returned as an
+// Get the real object stored in the weak reference returned as an
// AutoJObject.
AutoJObject getRealObject(JNIEnv*, jobject);
-// Convert the given jobject to a WeakReference and create a new global
-// reference to that WeakReference.
-jobject adoptGlobalRef(JNIEnv*, jobject);
-
// Helper method for check java exceptions. Returns true if an exception
// occurred and logs the exception.
bool checkException(JNIEnv* env);
diff --git a/WebKit/android/jni/WebCoreJniOnLoad.cpp b/WebKit/android/jni/WebCoreJniOnLoad.cpp
index 0d2b61f..d69177e 100644
--- a/WebKit/android/jni/WebCoreJniOnLoad.cpp
+++ b/WebKit/android/jni/WebCoreJniOnLoad.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -22,10 +22,49 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#define LOG_TAG "webcoreglue"
#include "config.h"
+#include "BackForwardList.h"
+#include "ChromeClientAndroid.h"
+#include "ContextMenuClientAndroid.h"
+#include "CookieClient.h"
+#include "DragClientAndroid.h"
+#include "EditorClientAndroid.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClientAndroid.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "HistoryItem.h"
+#include "InspectorClientAndroid.h"
+#include "IntRect.h"
+#include "JavaSharedClient.h"
+#include "jni_utility.h"
+#include "Page.h"
+#include "PlatformGraphicsContext.h"
+#include "ResourceRequest.h"
+#include "ScriptController.h"
+#include "SecurityOrigin.h"
+#include "SelectionController.h"
+#include "Settings.h"
+#include "SharedBuffer.h"
+#include "SubstituteData.h"
+#include "TimerClient.h"
+#include "TextEncoding.h"
+#include "WebCoreViewBridge.h"
+#include "WebFrameView.h"
+#include "WebViewCore.h"
+
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkImageEncoder.h"
+
+#include "benchmark/Intercept.h"
+#include "benchmark/MyJavaVM.h"
+
#include "jni_utility.h"
#include <jni.h>
#include <utils/Log.h>
@@ -40,7 +79,6 @@ extern int register_webhistory(JNIEnv*);
extern int register_webicondatabase(JNIEnv*);
extern int register_websettings(JNIEnv*);
extern int register_webview(JNIEnv*);
-extern int register_webcorejni(JNIEnv*);
#if ENABLE(DATABASE)
extern int register_webstorage(JNIEnv*);
#endif
@@ -61,7 +99,6 @@ static RegistrationMethod gWebCoreRegMethods[] = {
{ "JavaBridge", android::register_javabridge },
{ "WebFrame", android::register_webframe },
{ "WebCoreResourceLoader", android::register_resource_loader },
- { "WebCoreJni", android::register_webcorejni },
{ "WebViewCore", android::register_webviewcore },
{ "WebHistory", android::register_webhistory },
{ "WebIconDatabase", android::register_webicondatabase },
@@ -107,3 +144,143 @@ EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
return JNI_VERSION_1_4;
}
+
+class MyJavaSharedClient : public TimerClient, public CookieClient {
+public:
+ MyJavaSharedClient() : m_hasTimer(false) {}
+ virtual void setSharedTimer(long long timemillis) { m_hasTimer = true; }
+ virtual void stopSharedTimer() { m_hasTimer = false; }
+ virtual void setSharedTimerCallback(void (*f)()) { m_func = f; }
+ virtual void signalServiceFuncPtrQueue() {}
+
+ // Cookie methods that do nothing.
+ virtual void setCookies(const KURL&, const String&) {}
+ virtual String cookies(const KURL&) { return ""; }
+ virtual bool cookiesEnabled() { return false; }
+
+ bool m_hasTimer;
+ void (*m_func)();
+};
+
+static void historyItemChanged(HistoryItem* i) {
+ if (i->bridge())
+ i->bridge()->updateHistoryItem(i);
+}
+
+namespace android {
+
+EXPORT void benchmark(const char* url, int reloadCount, int width, int height) {
+ ScriptController::initializeThreading();
+
+ // Setting this allows data: urls to load from a local file.
+ SecurityOrigin::setLocalLoadPolicy(SecurityOrigin::AllowLocalLoadsForAll);
+
+ // Create the fake JNIEnv and JavaVM
+ InitializeJavaVM();
+
+ // The real function is private to libwebcore but we know what it does.
+ notifyHistoryItemChanged = historyItemChanged;
+
+ // Implement the shared timer callback
+ MyJavaSharedClient client;
+ JavaSharedClient::SetTimerClient(&client);
+ JavaSharedClient::SetCookieClient(&client);
+
+ // Create the page with all the various clients
+ ChromeClientAndroid* chrome = new ChromeClientAndroid;
+ EditorClientAndroid* editor = new EditorClientAndroid;
+ Page* page = new Page(chrome, new ContextMenuClientAndroid, editor,
+ new DragClientAndroid, new InspectorClientAndroid, NULL);
+ editor->setPage(page);
+
+ // Create MyWebFrame that intercepts network requests
+ MyWebFrame* webFrame = new MyWebFrame(page);
+ webFrame->setUserAgent("Performance testing"); // needs to be non-empty
+ chrome->setWebFrame(webFrame);
+ // ChromeClientAndroid maintains the reference.
+ Release(webFrame);
+
+ // Create the Frame and the FrameLoaderClient
+ FrameLoaderClientAndroid* loader = new FrameLoaderClientAndroid(webFrame);
+ RefPtr<Frame> frame = Frame::create(page, NULL, loader);
+ loader->setFrame(frame.get());
+
+ // Build our View system, resize it to the given dimensions and release our
+ // references. Note: We keep a referenec to frameView so we can layout and
+ // draw later without risk of it being deleted.
+ WebViewCore* webViewCore = new WebViewCore(JSC::Bindings::getJNIEnv(),
+ MY_JOBJECT, frame.get());
+ RefPtr<FrameView> frameView = FrameView::create(frame.get());
+ WebFrameView* webFrameView = new WebFrameView(frameView.get(), webViewCore);
+ frame->setView(frameView);
+ frameView->resize(width, height);
+ Release(webViewCore);
+ Release(webFrameView);
+
+ // Initialize the frame and turn of low-bandwidth display (it fails an
+ // assertion in the Cache code)
+ frame->init();
+ frame->selection()->setFocused(true);
+
+ // Set all the default settings the Browser normally uses.
+ Settings* s = frame->settings();
+ s->setLayoutAlgorithm(Settings::kLayoutNormal); // Normal layout for now
+ s->setStandardFontFamily("sans-serif");
+ s->setFixedFontFamily("monospace");
+ s->setSansSerifFontFamily("sans-serif");
+ s->setSerifFontFamily("serif");
+ s->setCursiveFontFamily("cursive");
+ s->setFantasyFontFamily("fantasy");
+ s->setMinimumFontSize(8);
+ s->setMinimumLogicalFontSize(8);
+ s->setDefaultFontSize(16);
+ s->setDefaultFixedFontSize(13);
+ s->setLoadsImagesAutomatically(true);
+ s->setJavaScriptEnabled(true);
+ s->setDefaultTextEncodingName("latin1");
+ s->setPluginsEnabled(false);
+ s->setShrinksStandaloneImagesToFit(false);
+ s->setUseWideViewport(false);
+
+ // Finally, load the actual data
+ ResourceRequest req(url);
+ frame->loader()->load(req, false);
+
+ do {
+ // Layout the page and service the timer
+ frame->view()->layout();
+ while (client.m_hasTimer) {
+ client.m_func();
+ JavaSharedClient::ServiceFunctionPtrQueue();
+ }
+ JavaSharedClient::ServiceFunctionPtrQueue();
+
+ // Layout more if needed.
+ while (frame->view()->needsLayout())
+ frame->view()->layout();
+ JavaSharedClient::ServiceFunctionPtrQueue();
+
+ if (reloadCount)
+ frame->loader()->reload(true);
+ } while (reloadCount--);
+
+ // Draw into an offscreen bitmap
+ SkBitmap bmp;
+ bmp.setConfig(SkBitmap::kARGB_8888_Config, width, height);
+ bmp.allocPixels();
+ SkCanvas canvas(bmp);
+ PlatformGraphicsContext ctx(&canvas, NULL);
+ GraphicsContext gc(&ctx);
+ frame->view()->paintContents(&gc, IntRect(0, 0, width, height));
+
+ // Write the bitmap to the sdcard
+ SkImageEncoder* enc = SkImageEncoder::Create(SkImageEncoder::kPNG_Type);
+ enc->encodeFile("/sdcard/webcore_test.png", bmp, 100);
+ delete enc;
+
+ // Tear down the world.
+ frame->loader()->detachFromParent();
+ delete page;
+}
+
+} // namespace android
diff --git a/WebKit/android/jni/WebCoreRefObject.h b/WebKit/android/jni/WebCoreRefObject.h
index 3e9f840..4228db6 100644
--- a/WebKit/android/jni/WebCoreRefObject.h
+++ b/WebKit/android/jni/WebCoreRefObject.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/WebKit/android/jni/WebCoreResourceLoader.cpp b/WebKit/android/jni/WebCoreResourceLoader.cpp
index 5ccd09c..55af52d 100644
--- a/WebKit/android/jni/WebCoreResourceLoader.cpp
+++ b/WebKit/android/jni/WebCoreResourceLoader.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -68,6 +68,11 @@ static struct resourceloader_t {
//-----------------------------------------------------------------------------
// ResourceLoadHandler
+PassRefPtr<WebCore::ResourceLoaderAndroid> WebCoreResourceLoader::create(JNIEnv *env, jobject jLoadListener)
+{
+ return adoptRef<WebCore::ResourceLoaderAndroid>(new WebCoreResourceLoader(env, jLoadListener));
+}
+
WebCoreResourceLoader::WebCoreResourceLoader(JNIEnv *env, jobject jLoadListener)
{
mJLoader = env->NewGlobalRef(jLoadListener);
@@ -100,14 +105,14 @@ void WebCoreResourceLoader::downloadFile()
* the cache. This may be slow, but is only used during a navigation to
* a POST response.
*/
-bool WebCoreResourceLoader::willLoadFromCache(const WebCore::KURL& url)
+bool WebCoreResourceLoader::willLoadFromCache(const WebCore::KURL& url, int64_t identifier)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
WebCore::String urlStr = url.string();
jstring jUrlStr = env->NewString(urlStr.characters(), urlStr.length());
jclass resourceLoader = env->FindClass("android/webkit/LoadListener");
bool val = env->CallStaticBooleanMethod(resourceLoader,
- gResourceLoader.mWillLoadFromCacheMethodID, jUrlStr);
+ gResourceLoader.mWillLoadFromCacheMethodID, jUrlStr, identifier);
checkException(env);
env->DeleteLocalRef(jUrlStr);
@@ -140,7 +145,7 @@ jint WebCoreResourceLoader::CreateResponse(JNIEnv* env, jobject obj, jstring url
TimeCounterAuto counter(TimeCounter::ResourceTimeCounter);
#endif
LOG_ASSERT(url, "Must have a url in the response!");
- WebCore::KURL kurl(to_string(env, url));
+ WebCore::KURL kurl(WebCore::ParsedURLString, to_string(env, url));
WebCore::String encodingStr;
WebCore::String mimeTypeStr;
if (mimeType) {
@@ -235,7 +240,7 @@ jstring WebCoreResourceLoader::RedirectedToUrl(JNIEnv* env, jobject obj,
LOG_ASSERT(handle->client(), "Why do we not have a client?");
WebCore::ResourceRequest r = handle->request();
- WebCore::KURL url(WebCore::KURL(to_string(env, baseUrl)),
+ WebCore::KURL url(WebCore::KURL(WebCore::ParsedURLString, to_string(env, baseUrl)),
to_string(env, redirectTo));
r.setURL(url);
if (r.httpMethod() == "POST") {
@@ -318,7 +323,7 @@ int register_resource_loader(JNIEnv* env)
"Could not find method downloadFile on LoadListener");
gResourceLoader.mWillLoadFromCacheMethodID =
- env->GetStaticMethodID(resourceLoader, "willLoadFromCache", "(Ljava/lang/String;)Z");
+ env->GetStaticMethodID(resourceLoader, "willLoadFromCache", "(Ljava/lang/String;J)Z");
LOG_FATAL_IF(gResourceLoader.mWillLoadFromCacheMethodID == NULL,
"Could not find static method willLoadFromCache on LoadListener");
diff --git a/WebKit/android/jni/WebCoreResourceLoader.h b/WebKit/android/jni/WebCoreResourceLoader.h
index 60c0d0e..d24a43e 100644
--- a/WebKit/android/jni/WebCoreResourceLoader.h
+++ b/WebKit/android/jni/WebCoreResourceLoader.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,34 +26,33 @@
#ifndef ANDROID_WEBKIT_RESOURCELOADLISTENER_H
#define ANDROID_WEBKIT_RESOURCELOADLISTENER_H
-#include "KURL.h"
-
-#include "WebCoreRefObject.h"
+#include <KURL.h>
+#include <ResourceLoaderAndroid.h>
#include <jni.h>
namespace android {
-class WebCoreResourceLoader : public WebCoreRefObject
+class WebCoreResourceLoader : public WebCore::ResourceLoaderAndroid
{
public:
- WebCoreResourceLoader(JNIEnv *env, jobject jLoadListener);
+ static PassRefPtr<WebCore::ResourceLoaderAndroid> create(JNIEnv *env, jobject jLoadListener);
virtual ~WebCoreResourceLoader();
/**
* Call to java to cancel the current load.
*/
- void cancel();
+ virtual void cancel();
/**
* Call to java to download the current load rather than feed it
* back to WebCore
*/
- void downloadFile();
+ virtual void downloadFile();
/**
* Call to java to find out if this URL is in the cache
*/
- static bool willLoadFromCache(const WebCore::KURL& url);
+ static bool willLoadFromCache(const WebCore::KURL& url, int64_t identifier);
// Native jni functions
static void SetResponseHeader(JNIEnv*, jobject, jint, jstring, jstring);
@@ -65,6 +64,8 @@ public:
static jstring RedirectedToUrl(JNIEnv*, jobject, jstring, jstring, jint);
static void Error(JNIEnv*, jobject, jint, jstring, jstring);
+protected:
+ WebCoreResourceLoader(JNIEnv *env, jobject jLoadListener);
private:
jobject mJLoader;
};
diff --git a/WebKit/android/jni/WebCoreViewBridge.h b/WebKit/android/jni/WebCoreViewBridge.h
index db79a37..61990af 100644
--- a/WebKit/android/jni/WebCoreViewBridge.h
+++ b/WebKit/android/jni/WebCoreViewBridge.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/WebKit/android/jni/WebFrameView.cpp b/WebKit/android/jni/WebFrameView.cpp
index 0ab7410..8e5eac4 100644
--- a/WebKit/android/jni/WebFrameView.cpp
+++ b/WebKit/android/jni/WebFrameView.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -102,4 +102,3 @@ void WebFrameView::setView(WebCore::FrameView* frameView) {
}
} // namespace android
-
diff --git a/WebKit/android/jni/WebFrameView.h b/WebKit/android/jni/WebFrameView.h
index 2347071..d83def1 100644
--- a/WebKit/android/jni/WebFrameView.h
+++ b/WebKit/android/jni/WebFrameView.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/WebKit/android/jni/WebHistory.cpp b/WebKit/android/jni/WebHistory.cpp
index d7aacfb..76a310b 100644
--- a/WebKit/android/jni/WebHistory.cpp
+++ b/WebKit/android/jni/WebHistory.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -44,6 +44,7 @@
#include "TextEncoding.h"
#include "WebCoreFrameBridge.h"
#include "WebCoreJni.h"
+#include "WebIconDatabase.h"
#include "jni_utility.h"
#include <JNIHelp.h>
@@ -90,7 +91,7 @@ static void WebHistoryClose(JNIEnv* env, jobject obj, jint frame)
list->removeItem(entries[i].get());
// Add the current item back to the list.
if (current) {
- current->setBridge(NULL);
+ current->setBridge(0);
// addItem will update the children to match the newly created bridge
list->addItem(current);
@@ -113,7 +114,7 @@ static void WebHistoryClose(JNIEnv* env, jobject obj, jint frame)
// Keep a small list of child frames to traverse.
WTF::Vector<WebCore::Frame*> frameQueue;
// Fix the top-level item.
- pFrame->loader()->setCurrentHistoryItem(current);
+ pFrame->loader()->history()->setCurrentItem(current.get());
WebCore::Frame* child = pFrame->tree()->firstChild();
// Remember the parent history item so we can search for a child item.
RefPtr<WebCore::HistoryItem> parent = current;
@@ -121,10 +122,13 @@ static void WebHistoryClose(JNIEnv* env, jobject obj, jint frame)
// Use the old history item since the current one may have a
// deleted parent.
WebCore::HistoryItem* item = parent->childItemWithTarget(child->tree()->name());
- child->loader()->setCurrentHistoryItem(item);
- // Append the first child to the queue if it exists.
- if (WebCore::Frame* f = child->tree()->firstChild())
- frameQueue.append(f);
+ child->loader()->history()->setCurrentItem(item);
+ // Append the first child to the queue if it exists. If there is no
+ // item, then we do not need to traverse the children since there
+ // will be no parent history item.
+ WebCore::Frame* firstChild;
+ if (item && (firstChild = child->tree()->firstChild()))
+ frameQueue.append(firstChild);
child = child->tree()->nextSibling();
// If we don't have a sibling for this frame and the queue isn't
// empty, use the next entry in the queue.
@@ -133,7 +137,7 @@ static void WebHistoryClose(JNIEnv* env, jobject obj, jint frame)
frameQueue.remove(0);
// Figure out the parent history item used when searching for
// the history item to use.
- parent = child->tree()->parent()->loader()->currentHistoryItem();
+ parent = child->tree()->parent()->loader()->history()->currentItem();
}
}
}
@@ -152,7 +156,7 @@ static void WebHistoryRestoreIndex(JNIEnv* env, jobject obj, jint frame, jint in
// Update the current and previous history item.
WebCore::FrameLoader* loader = pFrame->loader();
- loader->setCurrentHistoryItem(currentItem);
+ loader->history()->setCurrentItem(currentItem);
// load the current page with FrameLoadTypeIndexedBackForward so that it
// will use cache when it is possible
@@ -171,10 +175,9 @@ static void WebHistoryInflate(JNIEnv* env, jobject obj, jint frame, jbyteArray d
// Inflate the history tree into one HistoryItem or null if the inflation
// failed.
RefPtr<WebCore::HistoryItem> newItem = WebCore::HistoryItem::create();
-#ifdef ANDROID_HISTORY_CLIENT
RefPtr<WebHistoryItem> bridge = new WebHistoryItem(env, obj, newItem.get());
newItem->setBridge(bridge.get());
-#endif
+
// Inflate the item recursively. If it fails, that is ok. We'll have an
// incomplete HistoryItem but that is better than crashing due to a null
// item.
@@ -184,28 +187,19 @@ static void WebHistoryInflate(JNIEnv* env, jobject obj, jint frame, jbyteArray d
const char* ptr = reinterpret_cast<const char*>(bytes);
read_item_recursive(newItem.get(), &ptr, (int)size);
env->ReleaseByteArrayElements(data, const_cast<jbyte*>(bytes), JNI_ABORT);
-#ifdef ANDROID_HISTORY_CLIENT
bridge->setActive();
-#endif
// Add the new item to the back/forward list.
WebCore::Frame* pFrame = (WebCore::Frame*)frame;
pFrame->page()->backForwardList()->addItem(newItem);
-#ifdef ANDROID_HISTORY_CLIENT
// Update the item.
bridge->updateHistoryItem(newItem.get());
-#endif
}
// 6 empty strings + no document state + children count = 8 unsigned values
-// 1 char for isTargetItem
-// ANDROID_HISTORY_CLIENT adds 1 int for scale.
-#ifdef ANDROID_HISTORY_CLIENT
+// 1 char for isTargetItem and 1 char is for scale.
#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 9 + sizeof(char)))
-#else
-#define HISTORY_MIN_SIZE ((int)(sizeof(unsigned) * 8 + sizeof(char)))
-#endif
jbyteArray WebHistory::Flatten(JNIEnv* env, WTF::Vector<char>& v, WebCore::HistoryItem* item)
{
@@ -217,9 +211,7 @@ jbyteArray WebHistory::Flatten(JNIEnv* env, WTF::Vector<char>& v, WebCore::Histo
// Write the top-level history item and then write all the children
// recursively.
-#ifdef ANDROID_HISTORY_CLIENT
LOG_ASSERT(item->bridge(), "Why don't we have a bridge object here?");
-#endif
write_item(v, item);
write_children_recursive(v, item);
@@ -234,33 +226,29 @@ jbyteArray WebHistory::Flatten(JNIEnv* env, WTF::Vector<char>& v, WebCore::Histo
}
WebHistoryItem::WebHistoryItem(JNIEnv* env, jobject obj,
- WebCore::HistoryItem* item) {
- mObject = adoptGlobalRef(env, obj);
- mScale = 100;
- mActive = false;
- mParent = NULL;
- mHistoryItem = item;
+ WebCore::HistoryItem* item) : WebCore::AndroidWebHistoryBridge(item) {
+ m_object = env->NewWeakGlobalRef(obj);
+ m_parent = 0;
}
WebHistoryItem::~WebHistoryItem() {
- if (mObject) {
+ if (m_object) {
JNIEnv* env = JSC::Bindings::getJNIEnv();
if (!env)
return;
- env->DeleteGlobalRef(mObject);
+ env->DeleteWeakGlobalRef(m_object);
}
}
void WebHistoryItem::updateHistoryItem(WebCore::HistoryItem* item) {
-#ifdef ANDROID_HISTORY_CLIENT
// Do not want to update during inflation.
- if (!mActive)
+ if (!m_active)
return;
WebHistoryItem* webItem = this;
// Now we need to update the top-most WebHistoryItem based on the top-most
// HistoryItem.
- if (mParent) {
- webItem = mParent.get();
+ if (m_parent) {
+ webItem = m_parent.get();
if (webItem->hasOneRef()) {
// if the parent only has one ref, it is from this WebHistoryItem.
// This means that the matching WebCore::HistoryItem has been freed.
@@ -271,13 +259,20 @@ void WebHistoryItem::updateHistoryItem(WebCore::HistoryItem* item) {
while (webItem->parent())
webItem = webItem->parent();
item = webItem->historyItem();
+ if (!item) {
+ // If a HistoryItem only exists for page cache, it is possible that
+ // the parent HistoryItem destroyed before the child HistoryItem. If
+ // it happens, skip updating.
+ LOGW("Can't updateHistoryItem as the top HistoryItem is gone");
+ return;
+ }
}
JNIEnv* env = JSC::Bindings::getJNIEnv();
if (!env)
return;
// Don't do anything if the item has been gc'd already
- AutoJObject realItem = getRealObject(env, webItem->mObject);
+ AutoJObject realItem = getRealObject(env, webItem->m_object);
if (!realItem.get())
return;
@@ -322,21 +317,17 @@ void WebHistoryItem::updateHistoryItem(WebCore::HistoryItem* item) {
if (favicon)
env->DeleteLocalRef(favicon);
env->DeleteLocalRef(array);
-#endif
}
static void historyItemChanged(WebCore::HistoryItem* item) {
-#ifdef ANDROID_HISTORY_CLIENT
- LOG_ASSERT(item,
- "historyItemChanged called with a null item");
+ LOG_ASSERT(item, "historyItemChanged called with a null item");
+
if (item->bridge())
item->bridge()->updateHistoryItem(item);
-#endif
}
void WebHistory::AddItem(const AutoJObject& list, WebCore::HistoryItem* item)
{
-#ifdef ANDROID_HISTORY_CLIENT
LOG_ASSERT(item, "newItem must take a valid HistoryItem!");
// Item already added. Should only happen when we are inflating the list.
if (item->bridge() || !list.get())
@@ -361,7 +352,6 @@ void WebHistory::AddItem(const AutoJObject& list, WebCore::HistoryItem* item)
// Delete our local reference.
env->DeleteLocalRef(newItem);
-#endif
}
void WebHistory::RemoveItem(const AutoJObject& list, int index)
@@ -420,22 +410,23 @@ static void write_item(WTF::Vector<char>& v, WebCore::HistoryItem* item)
// Form data
const WebCore::FormData* formData = item->formData();
- if (formData)
+ if (formData) {
write_string(v, formData->flattenToString());
- else
+ // save the identifier as it is not included in the flatten data
+ int64_t id = formData->identifier();
+ v.append((char*)&id, sizeof(int64_t));
+ } else
write_string(v, WebCore::String()); // Empty constructor does not allocate a buffer.
// Target
write_string(v, item->target());
-#ifdef ANDROID_HISTORY_CLIENT
- WebHistoryItem* bridge = item->bridge();
+ AndroidWebHistoryBridge* bridge = item->bridge();
LOG_ASSERT(bridge, "We should have a bridge here!");
// Screen scale
int scale = bridge->scale();
LOGV("Writing scale %d", scale);
v.append((char*)&scale, sizeof(int));
-#endif
// Document state
const WTF::Vector<WebCore::String>& docState = item->documentState();
@@ -463,23 +454,23 @@ static void write_children_recursive(WTF::Vector<char>& v, WebCore::HistoryItem*
WebCore::HistoryItemVector::const_iterator end = children.end();
for (WebCore::HistoryItemVector::const_iterator i = children.begin(); i != end; ++i) {
WebCore::HistoryItem* item = (*i).get();
-#ifdef ANDROID_HISTORY_CLIENT
LOG_ASSERT(parent->bridge(),
"The parent item should have a bridge object!");
if (!item->bridge()) {
- WebHistoryItem* bridge = new WebHistoryItem(parent->bridge());
+ WebHistoryItem* bridge = new WebHistoryItem(static_cast<WebHistoryItem*>(parent->bridge()));
item->setBridge(bridge);
bridge->setActive();
} else {
// The only time this item's parent may not be the same as the
// parent's bridge is during history close. In that case, the
// parent must not have a parent bridge.
- LOG_ASSERT(parent->bridge()->parent() == NULL ||
- item->bridge()->parent() == parent->bridge(),
+ WebHistoryItem* bridge = static_cast<WebHistoryItem*>(item->bridge());
+ WebHistoryItem* parentBridge = static_cast<WebHistoryItem*>(parent->bridge());
+ LOG_ASSERT(parentBridge->parent() == 0 ||
+ bridge->parent() == parentBridge,
"Somehow this item has an incorrect parent");
- item->bridge()->setParent(parent->bridge());
+ bridge->setParent(parentBridge);
}
-#endif
write_item(v, item);
write_children_recursive(v, item);
}
@@ -573,6 +564,15 @@ static bool read_item_recursive(WebCore::HistoryItem* newItem,
else
return false;
data += l;
+ // Read the identifier
+ {
+ int64_t id;
+ int size = (int)sizeof(int64_t);
+ memcpy(&id, data, size);
+ data += size;
+ if (id)
+ formData->setIdentifier(id);
+ }
}
if (end - data < sizeofUnsigned)
return false;
@@ -600,8 +600,7 @@ static bool read_item_recursive(WebCore::HistoryItem* newItem,
if (end - data < sizeofUnsigned)
return false;
-#ifdef ANDROID_HISTORY_CLIENT
- WebHistoryItem* bridge = newItem->bridge();
+ AndroidWebHistoryBridge* bridge = newItem->bridge();
LOG_ASSERT(bridge, "There should be a bridge object during inflate");
// Read the screen scale
memcpy(&l, data, sizeofUnsigned);
@@ -610,7 +609,6 @@ static bool read_item_recursive(WebCore::HistoryItem* newItem,
data += sizeofUnsigned;
if (end - data < sizeofUnsigned)
return false;
-#endif
// Read the document state
memcpy(&l, data, sizeofUnsigned);
@@ -670,18 +668,14 @@ static bool read_item_recursive(WebCore::HistoryItem* newItem,
// No need to check the length each time because read_item_recursive
// will return null if there isn't enough data left to parse.
WTF::PassRefPtr<WebCore::HistoryItem> child = WebCore::HistoryItem::create();
-#ifdef ANDROID_HISTORY_CLIENT
// Set a bridge that will not call into java.
- child->setBridge(new WebHistoryItem(bridge));
-#endif
+ child->setBridge(new WebHistoryItem(static_cast<WebHistoryItem*>(bridge)));
// Read the child item.
if (!read_item_recursive(child.get(), pData, end - data)) {
child.clear();
return false;
}
-#ifdef ANDROID_HISTORY_CLIENT
child->bridge()->setActive();
-#endif
newItem->addChildItem(child);
}
}
@@ -702,9 +696,7 @@ static void unit_test()
const char* test1 = new char[0];
WTF::RefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create();
WebCore::HistoryItem* testItem = item.get();
-#ifdef ANDROID_HISTORY_CLIENT
- testItem->setBridge(new WebHistoryItem(NULL));
-#endif
+ testItem->setBridge(new WebHistoryItem(0));
LOG_ASSERT(!read_item_recursive(testItem, &test1, 0), "0 length array should fail!");
delete[] test1;
const char* test2 = new char[2];
@@ -747,9 +739,7 @@ static void unit_test()
ptr = (const char*)test3;
*(int*)(test3 + offset) = 4000;
LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 length target should fail!");
-#ifdef ANDROID_HISTORY_CLIENT
offset += 4; // Scale
-#endif
// Document state
offset += 4;
memset(test3, 0, HISTORY_MIN_SIZE);
@@ -768,12 +758,7 @@ static void unit_test()
ptr = (const char*)test3;
*(int*)(test3 + offset) = 4000;
LOG_ASSERT(!read_item_recursive(testItem, &ptr, HISTORY_MIN_SIZE), "4000 kids should fail!");
-
-#ifdef ANDROID_HISTORY_CLIENT
offset = 36;
-#else
- offset = 28;
-#endif
// Test document state
delete[] test3;
test3 = new char[HISTORY_MIN_SIZE + sizeof(unsigned)];
@@ -811,10 +796,8 @@ static JNINativeMethod gWebHistoryItemMethods[] = {
int register_webhistory(JNIEnv* env)
{
-#ifdef ANDROID_HISTORY_CLIENT
// Get notified of all changes to history items.
WebCore::notifyHistoryItemChanged = historyItemChanged;
-#endif
#ifdef UNIT_TEST
unit_test();
#endif
diff --git a/WebKit/android/jni/WebHistory.h b/WebKit/android/jni/WebHistory.h
index fe70443..12bf00a 100644
--- a/WebKit/android/jni/WebHistory.h
+++ b/WebKit/android/jni/WebHistory.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,14 +26,12 @@
#ifndef ANDROID_WEBKIT_WEBHISTORY_H
#define ANDROID_WEBKIT_WEBHISTORY_H
+#include "AndroidWebHistoryBridge.h"
+
#include <jni.h>
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
-namespace WebCore {
- class HistoryItem;
-}
-
namespace android {
class AutoJObject;
@@ -49,33 +47,20 @@ public:
// there are two scale factors saved with each history item. mScale reflects the
// viewport scale factor, default to 100 means 100%. mScreenWidthScale records
// the scale factor for the screen width used to wrap the text paragraph.
-class WebHistoryItem : public WTF::RefCounted<WebHistoryItem> {
+class WebHistoryItem : public WebCore::AndroidWebHistoryBridge {
public:
WebHistoryItem(WebHistoryItem* parent)
- : mParent(parent)
- , mObject(NULL)
- , mScale(100)
- , mScreenWidthScale(100)
- , mActive(false)
- , mHistoryItem(NULL) {}
+ : WebCore::AndroidWebHistoryBridge(0)
+ , m_parent(parent)
+ , m_object(NULL) { }
WebHistoryItem(JNIEnv*, jobject, WebCore::HistoryItem*);
~WebHistoryItem();
void updateHistoryItem(WebCore::HistoryItem* item);
- void setScale(int s) { mScale = s; }
- void setScreenWidthScale(int s) { mScreenWidthScale = s; }
- void setActive() { mActive = true; }
- void setParent(WebHistoryItem* parent) { mParent = parent; }
- WebHistoryItem* parent() { return mParent.get(); }
- int scale() { return mScale; }
- int screenWidthScale() { return mScreenWidthScale; }
- WebCore::HistoryItem* historyItem() { return mHistoryItem; }
+ void setParent(WebHistoryItem* parent) { m_parent = parent; }
+ WebHistoryItem* parent() const { return m_parent.get(); }
private:
- RefPtr<WebHistoryItem> mParent;
- jobject mObject;
- int mScale;
- int mScreenWidthScale;
- bool mActive;
- WebCore::HistoryItem* mHistoryItem;
+ RefPtr<WebHistoryItem> m_parent;
+ jweak m_object;
};
};
diff --git a/WebKit/android/jni/WebIconDatabase.cpp b/WebKit/android/jni/WebIconDatabase.cpp
index daf0334..20258a4 100644
--- a/WebKit/android/jni/WebIconDatabase.cpp
+++ b/WebKit/android/jni/WebIconDatabase.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -67,10 +67,6 @@ static WebIconDatabase* gIconDatabaseClient = new WebIconDatabase();
// XXX: Called by the IconDatabase thread
void WebIconDatabase::dispatchDidAddIconForPageURL(const WebCore::String& pageURL)
{
- // If there are no clients currently, drop this message.
- if (mClients.size() == 0)
- return;
-
mNotificationsMutex.lock();
mNotifications.append(pageURL);
if (!mDeliveryRequested) {
@@ -83,23 +79,25 @@ void WebIconDatabase::dispatchDidAddIconForPageURL(const WebCore::String& pageUR
// Called in the WebCore thread
void WebIconDatabase::RegisterForIconNotification(WebIconDatabaseClient* client)
{
- gIconDatabaseClient->mClientsMutex.lock();
+ WebIconDatabase* db = gIconDatabaseClient;
+ for (unsigned i = 0; i < db->mClients.size(); ++i) {
+ // Do not add the same client twice.
+ if (db->mClients[i] == client)
+ return;
+ }
gIconDatabaseClient->mClients.append(client);
- gIconDatabaseClient->mClientsMutex.unlock();
}
// Called in the WebCore thread
void WebIconDatabase::UnregisterForIconNotification(WebIconDatabaseClient* client)
{
WebIconDatabase* db = gIconDatabaseClient;
- db->mClientsMutex.lock();
for (unsigned i = 0; i < db->mClients.size(); ++i) {
if (db->mClients[i] == client) {
db->mClients.remove(i);
break;
}
}
- db->mClientsMutex.unlock();
}
// Called in the WebCore thread
@@ -123,9 +121,7 @@ void WebIconDatabase::deliverNotifications()
// Swap the clients queue
Vector<WebIconDatabaseClient*> clients;
- mClientsMutex.lock();
clients.swap(mClients);
- mClientsMutex.unlock();
for (unsigned i = 0; i < queue.size(); ++i) {
for (unsigned j = 0; j < clients.size(); ++j) {
diff --git a/WebKit/android/jni/WebIconDatabase.h b/WebKit/android/jni/WebIconDatabase.h
index c88842c..c91c4ae 100644
--- a/WebKit/android/jni/WebIconDatabase.h
+++ b/WebKit/android/jni/WebIconDatabase.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -59,9 +59,8 @@ namespace android {
// Deliver all the icon notifications
void deliverNotifications();
- // List of clients and a mutex to protect it.
+ // List of clients.
Vector<WebIconDatabaseClient*> mClients;
- android::Mutex mClientsMutex;
// Queue of page urls that have received an icon.
Vector<WebCore::String> mNotifications;
diff --git a/WebKit/android/jni/WebSettings.cpp b/WebKit/android/jni/WebSettings.cpp
index 4240dd5..00fec85 100644
--- a/WebKit/android/jni/WebSettings.cpp
+++ b/WebKit/android/jni/WebSettings.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -38,6 +38,7 @@
#include "Geolocation.h"
#include "GeolocationPermissions.h"
#include "Page.h"
+#include "PageCache.h"
#include "RenderTable.h"
#include "Settings.h"
#include "WebCoreFrameBridge.h"
@@ -110,6 +111,7 @@ struct FieldIds {
mSupportMultipleWindows = env->GetFieldID(clazz, "mSupportMultipleWindows", "Z");
mShrinksStandaloneImagesToFit = env->GetFieldID(clazz, "mShrinksStandaloneImagesToFit", "Z");
mUseDoubleTree = env->GetFieldID(clazz, "mUseDoubleTree", "Z");
+ mPageCacheCapacity = env->GetFieldID(clazz, "mPageCacheCapacity", "I");
LOG_ASSERT(mLayoutAlgorithm, "Could not find field mLayoutAlgorithm");
LOG_ASSERT(mTextSize, "Could not find field mTextSize");
@@ -145,6 +147,7 @@ struct FieldIds {
LOG_ASSERT(mSupportMultipleWindows, "Could not find field mSupportMultipleWindows");
LOG_ASSERT(mShrinksStandaloneImagesToFit, "Could not find field mShrinksStandaloneImagesToFit");
LOG_ASSERT(mUseDoubleTree, "Could not find field mUseDoubleTree");
+ LOG_ASSERT(mPageCacheCapacity, "Could not find field mPageCacheCapacity");
jclass c = env->FindClass("java/lang/Enum");
LOG_ASSERT(c, "Could not find Enum class!");
@@ -189,6 +192,7 @@ struct FieldIds {
jfieldID mSupportMultipleWindows;
jfieldID mShrinksStandaloneImagesToFit;
jfieldID mUseDoubleTree;
+ jfieldID mPageCacheCapacity;
// Ordinal() method and value field for enums
jmethodID mOrdinal;
jfieldID mTextSizeValue;
@@ -342,7 +346,8 @@ public:
flag = env->GetBooleanField(obj, gFieldIds->mDatabaseEnabled);
s->setDatabasesEnabled(flag);
str = (jstring)env->GetObjectField(obj, gFieldIds->mDatabasePath);
- WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(to_string(env, str));
+ if (str && WebCore::DatabaseTracker::tracker().databaseDirectoryPath().isNull())
+ WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(to_string(env, str));
#endif
#if ENABLE(DOM_STORAGE)
flag = env->GetBooleanField(obj, gFieldIds->mDomStorageEnabled);
@@ -363,6 +368,13 @@ public:
GeolocationPermissions::setDatabasePath(to_string(env,str));
WebCore::Geolocation::setDatabasePath(to_string(env,str));
}
+
+ size = env->GetIntField(obj, gFieldIds->mPageCacheCapacity);
+ if (size > 0) {
+ s->setUsesPageCache(true);
+ WebCore::pageCache()->setCapacity(size);
+ } else
+ s->setUsesPageCache(false);
}
};
diff --git a/WebKit/android/jni/WebStorage.cpp b/WebKit/android/jni/WebStorage.cpp
index aa83892..07e4880 100644
--- a/WebKit/android/jni/WebStorage.cpp
+++ b/WebKit/android/jni/WebStorage.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -93,9 +93,9 @@ static unsigned long long GetUsageForOrigin(JNIEnv* env, jobject obj, jstring or
if (manifestOrigin.get() == 0)
continue;
if (manifestOrigin->isSameSchemeHostPort(securityOrigin.get())) {
- int64_t size = 0;
- WebCore::cacheStorage().cacheGroupSize(manifestUrls[i].string(), &size);
- usage += size;
+ int64_t cacheSize = 0;
+ WebCore::cacheStorage().cacheGroupSize(manifestUrls[i].string(), &cacheSize);
+ usage += cacheSize;
}
}
return usage;
@@ -163,4 +163,3 @@ int register_webstorage(JNIEnv* env)
}
#endif //ENABLE(DATABASE)
-
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 0eca9bc..8414068 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -57,6 +57,7 @@
#include "HTMLElement.h"
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
+#include "HTMLLabelElement.h"
#include "HTMLMapElement.h"
#include "HTMLNames.h"
#include "HTMLOptGroupElement.h"
@@ -68,6 +69,7 @@
#include "KeyboardCodes.h"
#include "Navigator.h"
#include "Node.h"
+#include "NodeList.h"
#include "Page.h"
#include "PageGroup.h"
#include "PlatformKeyboardEvent.h"
@@ -88,6 +90,7 @@
#include "Settings.h"
#include "SkANP.h"
#include "SkTemplates.h"
+#include "SkTDArray.h"
#include "SkTypes.h"
#include "SkCanvas.h"
#include "SkPicture.h"
@@ -129,6 +132,11 @@ FILE* gRenderTreeFile = 0;
#include "TimeCounter.h"
#endif
+#if USE(ACCELERATED_COMPOSITING)
+#include "GraphicsLayerAndroid.h"
+#include "RenderLayerCompositor.h"
+#endif
+
/* We pass this flag when recording the actual content, so that we don't spend
time actually regionizing complex path clips, when all we really want to do
is record them.
@@ -141,6 +149,24 @@ namespace android {
bool WebViewCore::s_isPaused = false;
+static SkTDArray<WebViewCore*> gInstanceList;
+
+void WebViewCore::addInstance(WebViewCore* inst) {
+ *gInstanceList.append() = inst;
+}
+
+void WebViewCore::removeInstance(WebViewCore* inst) {
+ int index = gInstanceList.find(inst);
+ LOG_ASSERT(index >= 0, "RemoveInstance inst not found");
+ if (index >= 0) {
+ gInstanceList.removeShuffle(index);
+ }
+}
+
+bool WebViewCore::isInstance(WebViewCore* inst) {
+ return gInstanceList.find(inst) >= 0;
+}
+
// ----------------------------------------------------------------------------
#define GET_NATIVE_VIEW(env, obj) ((WebViewCore*)env->GetIntField(obj, gWebViewCoreFields.m_nativeClass))
@@ -161,12 +187,13 @@ struct WebViewCoreFields {
// ----------------------------------------------------------------------------
struct WebViewCore::JavaGlue {
- jobject m_obj;
+ jweak m_obj;
jmethodID m_spawnScrollTo;
jmethodID m_scrollTo;
jmethodID m_scrollBy;
jmethodID m_contentDraw;
jmethodID m_requestListBox;
+ jmethodID m_openFileChooser;
jmethodID m_requestSingleListBox;
jmethodID m_jsAlert;
jmethodID m_jsConfirm;
@@ -177,6 +204,8 @@ struct WebViewCore::JavaGlue {
jmethodID m_updateViewport;
jmethodID m_sendNotifyProgressFinished;
jmethodID m_sendViewInvalidate;
+ jmethodID m_sendImmediateRepaint;
+ jmethodID m_setRootLayer;
jmethodID m_updateTextfield;
jmethodID m_updateTextSelection;
jmethodID m_clearTextEntry;
@@ -190,10 +219,15 @@ struct WebViewCore::JavaGlue {
jmethodID m_geolocationPermissionsShowPrompt;
jmethodID m_geolocationPermissionsHidePrompt;
jmethodID m_addMessageToConsole;
- jmethodID m_startFullScreenPluginActivity;
- jmethodID m_createSurface;
+ jmethodID m_getPluginClass;
+ jmethodID m_showFullScreenPlugin;
+ jmethodID m_hideFullScreenPlugin;
+ jmethodID m_updateFullScreenPlugin;
+ jmethodID m_addSurface;
+ jmethodID m_updateSurface;
jmethodID m_destroySurface;
- jmethodID m_showRect;
+ jmethodID m_getContext;
+ jmethodID m_sendFindAgain;
AutoJObject object(JNIEnv* env) {
return getRealObject(env, m_obj);
}
@@ -222,7 +256,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_popupReply = 0;
m_moveGeneration = 0;
- m_generation = 0;
m_lastGeneration = 0;
m_touchGeneration = 0;
m_blockTextfieldUpdates = false;
@@ -238,13 +271,14 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
jclass clazz = env->GetObjectClass(javaWebViewCore);
m_javaGlue = new JavaGlue;
- m_javaGlue->m_obj = adoptGlobalRef(env, javaWebViewCore);
+ m_javaGlue->m_obj = env->NewWeakGlobalRef(javaWebViewCore);
m_javaGlue->m_spawnScrollTo = GetJMethod(env, clazz, "contentSpawnScrollTo", "(II)V");
m_javaGlue->m_scrollTo = GetJMethod(env, clazz, "contentScrollTo", "(II)V");
m_javaGlue->m_scrollBy = GetJMethod(env, clazz, "contentScrollBy", "(IIZ)V");
m_javaGlue->m_contentDraw = GetJMethod(env, clazz, "contentDraw", "()V");
- m_javaGlue->m_requestListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[Z[I)V");
- m_javaGlue->m_requestSingleListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[ZI)V");
+ m_javaGlue->m_requestListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[I[I)V");
+ m_javaGlue->m_openFileChooser = GetJMethod(env, clazz, "openFileChooser", "()Ljava/lang/String;");
+ m_javaGlue->m_requestSingleListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[II)V");
m_javaGlue->m_jsAlert = GetJMethod(env, clazz, "jsAlert", "(Ljava/lang/String;Ljava/lang/String;)V");
m_javaGlue->m_jsConfirm = GetJMethod(env, clazz, "jsConfirm", "(Ljava/lang/String;Ljava/lang/String;)Z");
m_javaGlue->m_jsPrompt = GetJMethod(env, clazz, "jsPrompt", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
@@ -254,23 +288,30 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_updateViewport = GetJMethod(env, clazz, "updateViewport", "()V");
m_javaGlue->m_sendNotifyProgressFinished = GetJMethod(env, clazz, "sendNotifyProgressFinished", "()V");
m_javaGlue->m_sendViewInvalidate = GetJMethod(env, clazz, "sendViewInvalidate", "(IIII)V");
+ m_javaGlue->m_sendImmediateRepaint = GetJMethod(env, clazz, "sendImmediateRepaint", "()V");
+ m_javaGlue->m_setRootLayer = GetJMethod(env, clazz, "setRootLayer", "(I)V");
m_javaGlue->m_updateTextfield = GetJMethod(env, clazz, "updateTextfield", "(IZLjava/lang/String;I)V");
m_javaGlue->m_updateTextSelection = GetJMethod(env, clazz, "updateTextSelection", "(IIII)V");
m_javaGlue->m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V");
m_javaGlue->m_restoreScale = GetJMethod(env, clazz, "restoreScale", "(I)V");
m_javaGlue->m_restoreScreenWidthScale = GetJMethod(env, clazz, "restoreScreenWidthScale", "(I)V");
m_javaGlue->m_needTouchEvents = GetJMethod(env, clazz, "needTouchEvents", "(Z)V");
- m_javaGlue->m_requestKeyboard = GetJMethod(env, clazz, "requestKeyboard", "(Z)V");
+ m_javaGlue->m_requestKeyboard = GetJMethod(env, clazz, "requestKeyboard", "(ZZ)V");
m_javaGlue->m_exceededDatabaseQuota = GetJMethod(env, clazz, "exceededDatabaseQuota", "(Ljava/lang/String;Ljava/lang/String;JJ)V");
m_javaGlue->m_reachedMaxAppCacheSize = GetJMethod(env, clazz, "reachedMaxAppCacheSize", "(J)V");
m_javaGlue->m_populateVisitedLinks = GetJMethod(env, clazz, "populateVisitedLinks", "()V");
m_javaGlue->m_geolocationPermissionsShowPrompt = GetJMethod(env, clazz, "geolocationPermissionsShowPrompt", "(Ljava/lang/String;)V");
m_javaGlue->m_geolocationPermissionsHidePrompt = GetJMethod(env, clazz, "geolocationPermissionsHidePrompt", "()V");
m_javaGlue->m_addMessageToConsole = GetJMethod(env, clazz, "addMessageToConsole", "(Ljava/lang/String;ILjava/lang/String;)V");
- m_javaGlue->m_startFullScreenPluginActivity = GetJMethod(env, clazz, "startFullScreenPluginActivity", "(Ljava/lang/String;Ljava/lang/String;I)V");
- m_javaGlue->m_createSurface = GetJMethod(env, clazz, "createSurface", "(Ljava/lang/String;Ljava/lang/String;IIIII)Landroid/webkit/ViewManager$ChildView;");
+ m_javaGlue->m_getPluginClass = GetJMethod(env, clazz, "getPluginClass", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;");
+ m_javaGlue->m_showFullScreenPlugin = GetJMethod(env, clazz, "showFullScreenPlugin", "(Landroid/webkit/ViewManager$ChildView;IIIII)V");
+ m_javaGlue->m_hideFullScreenPlugin = GetJMethod(env, clazz, "hideFullScreenPlugin", "()V");
+ m_javaGlue->m_updateFullScreenPlugin = GetJMethod(env, clazz, "updateFullScreenPlugin", "(IIII)V");
+ m_javaGlue->m_addSurface = GetJMethod(env, clazz, "addSurface", "(Landroid/view/View;IIII)Landroid/webkit/ViewManager$ChildView;");
+ m_javaGlue->m_updateSurface = GetJMethod(env, clazz, "updateSurface", "(Landroid/webkit/ViewManager$ChildView;IIII)V");
m_javaGlue->m_destroySurface = GetJMethod(env, clazz, "destroySurface", "(Landroid/webkit/ViewManager$ChildView;)V");
- m_javaGlue->m_showRect = GetJMethod(env, clazz, "showRect", "(IIIIIIFFFF)V");
+ m_javaGlue->m_getContext = GetJMethod(env, clazz, "getContext", "()Landroid/content/Context;");
+ m_javaGlue->m_sendFindAgain = GetJMethod(env, clazz, "sendFindAgain", "()V");
env->SetIntField(javaWebViewCore, gWebViewCoreFields.m_nativeClass, (jint)this);
@@ -279,16 +320,20 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
PageGroup::setShouldTrackVisitedLinks(true);
reset(true);
+
+ WebViewCore::addInstance(this);
}
WebViewCore::~WebViewCore()
{
+ WebViewCore::removeInstance(this);
+
// Release the focused view
Release(m_popupReply);
if (m_javaGlue->m_obj) {
JNIEnv* env = JSC::Bindings::getJNIEnv();
- env->DeleteGlobalRef(m_javaGlue->m_obj);
+ env->DeleteWeakGlobalRef(m_javaGlue->m_obj);
m_javaGlue->m_obj = 0;
}
delete m_javaGlue;
@@ -326,9 +371,9 @@ void WebViewCore::reset(bool fromConstructor)
m_lastFocused = 0;
m_lastFocusedBounds = WebCore::IntRect(0,0,0,0);
+ m_focusBoundsChanged = false;
m_lastFocusedSelStart = 0;
m_lastFocusedSelEnd = 0;
- m_lastMoveGeneration = 0;
clearContent();
m_updatedFrameCache = true;
m_frameCacheOutOfDate = true;
@@ -573,6 +618,8 @@ void WebViewCore::recordPictureSet(PictureSet* content)
{
return;
}
+ m_focusBoundsChanged |= m_lastFocused == oldFocusNode
+ && m_lastFocusedBounds != oldBounds;
m_lastFocused = oldFocusNode;
m_lastFocusedBounds = oldBounds;
m_lastFocusedSelStart = oldSelStart;
@@ -580,6 +627,14 @@ void WebViewCore::recordPictureSet(PictureSet* content)
m_domtree_version = latestVersion;
DBG_NAV_LOG("call updateFrameCache");
updateFrameCache();
+ if (m_findIsUp) {
+ LOG_ASSERT(m_javaGlue->m_obj,
+ "A Java widget was not associated with this view bridge!");
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_sendFindAgain);
+ checkException(env);
+ }
}
void WebViewCore::updateButtonList(WTF::Vector<Container>* buttons)
@@ -666,6 +721,13 @@ bool WebViewCore::drawContent(SkCanvas* canvas, SkColor color)
return tookTooLong;
}
+bool WebViewCore::focusBoundsChanged()
+{
+ bool result = m_focusBoundsChanged;
+ m_focusBoundsChanged = false;
+ return result;
+}
+
bool WebViewCore::pictureReady()
{
bool done;
@@ -776,12 +838,9 @@ void WebViewCore::scrollTo(int x, int y, bool animate)
// LOGD("WebViewCore::scrollTo(%d %d)\n", x, y);
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), animate ? m_javaGlue->m_spawnScrollTo : m_javaGlue->m_scrollTo, x, y);
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ animate ? m_javaGlue->m_spawnScrollTo : m_javaGlue->m_scrollTo,
+ x, y);
checkException(env);
}
@@ -789,12 +848,7 @@ void WebViewCore::sendNotifyProgressFinished()
{
LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue->m_sendNotifyProgressFinished);
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_sendNotifyProgressFinished);
checkException(env);
}
@@ -802,12 +856,7 @@ void WebViewCore::viewInvalidate(const WebCore::IntRect& rect)
{
LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(),
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
m_javaGlue->m_sendViewInvalidate,
rect.x(), rect.y(), rect.right(), rect.bottom());
checkException(env);
@@ -818,25 +867,37 @@ void WebViewCore::scrollBy(int dx, int dy, bool animate)
if (!(dx | dy))
return;
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue->m_scrollBy,
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_scrollBy,
dx, dy, animate);
checkException(env);
}
+#if USE(ACCELERATED_COMPOSITING)
+
+void WebViewCore::immediateRepaint()
+{
+ LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!");
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_sendImmediateRepaint);
+ checkException(env);
+}
+
+void WebViewCore::setRootLayer(int layer)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_setRootLayer,
+ layer);
+ checkException(env);
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
void WebViewCore::contentDraw()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue->m_contentDraw);
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_contentDraw);
checkException(env);
}
@@ -885,18 +946,14 @@ void WebViewCore::didFirstLayout()
WebCore::FrameLoadType loadType = loader->loadType();
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue->m_didFirstLayout,
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_didFirstLayout,
loadType == WebCore::FrameLoadTypeStandard
// When redirect with locked history, we would like to reset the
// scale factor. This is important for www.yahoo.com as it is
// redirected to www.yahoo.com/?rs=1 on load.
|| loadType == WebCore::FrameLoadTypeRedirectWithLockedBackForwardList);
checkException(env);
+
DBG_NAV_LOG("call updateFrameCache");
m_check_domtree_version = false;
updateFrameCache();
@@ -909,12 +966,7 @@ void WebViewCore::updateViewport()
LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue->m_updateViewport);
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_updateViewport);
checkException(env);
}
@@ -924,12 +976,7 @@ void WebViewCore::restoreScale(int scale)
LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue->m_restoreScale, scale);
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_restoreScale, scale);
checkException(env);
}
@@ -939,12 +986,8 @@ void WebViewCore::restoreScreenWidthScale(int scale)
LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue->m_restoreScreenWidthScale, scale);
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_restoreScreenWidthScale, scale);
checkException(env);
}
@@ -955,28 +998,19 @@ void WebViewCore::needTouchEvents(bool need)
#if ENABLE(TOUCH_EVENTS) // Android
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue->m_needTouchEvents, need);
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_needTouchEvents, need);
checkException(env);
#endif
}
-void WebViewCore::requestKeyboard(bool showKeyboard)
+void WebViewCore::requestKeyboard(bool showKeyboard, bool isTextView)
{
- DEBUG_NAV_UI_LOGD("%s", __FUNCTION__);
+ DBG_NAV_LOGD("showKeyboard=%d", showKeyboard);
LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue->m_requestKeyboard, showKeyboard);
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_requestKeyboard, showKeyboard,
+ isTextView);
checkException(env);
}
@@ -1047,15 +1081,13 @@ void WebViewCore::setGlobalBounds(int x, int y, int h, int v)
void WebViewCore::setSizeScreenWidthAndScale(int width, int height,
int screenWidth, float scale, int realScreenWidth, int screenHeight,
- int anchorX, int anchorY, bool ignoreHeight)
+ bool ignoreHeight)
{
WebCoreViewBridge* window = m_mainFrame->view()->platformWidget();
int ow = window->width();
int oh = window->height();
window->setSize(width, height);
int osw = m_screenWidth;
- int orsw = m_screenWidth * m_screenWidthScale / m_scale;
- int osh = m_screenHeight;
DBG_NAV_LOGD("old:(w=%d,h=%d,sw=%d,scale=%g) new:(w=%d,h=%d,sw=%d,scale=%g)",
ow, oh, osw, m_scale, width, height, screenWidth, scale);
m_screenWidth = screenWidth;
@@ -1074,63 +1106,46 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height,
DBG_NAV_LOGD("renderer=%p view=(w=%d,h=%d)", r,
realScreenWidth, screenHeight);
if (r) {
- WebCore::IntPoint anchorPoint;
- if ((anchorX | anchorY) == 0)
- // get current screen center position
- anchorPoint = WebCore::IntPoint(m_scrollOffsetX
- + (realScreenWidth >> 1), m_scrollOffsetY
- + (screenHeight >> 1));
- else
- anchorPoint = WebCore::IntPoint(anchorX, anchorY);
- WebCore::HitTestResult hitTestResult = m_mainFrame->eventHandler()->
- hitTestResultAtPoint(anchorPoint, false);
- WebCore::Node* node = hitTestResult.innerNode();
+ // get current screen center position
+ WebCore::IntPoint screenCenter = WebCore::IntPoint(
+ m_scrollOffsetX + (realScreenWidth >> 1),
+ m_scrollOffsetY + (screenHeight >> 1));
+ WebCore::Node* node = 0;
WebCore::IntRect bounds;
WebCore::IntPoint offset;
+ // If the screen width changed, it is probably zoom change or
+ // orientation change. Try to keep the node in the center of the
+ // screen staying at the same place.
+ if (osw != screenWidth) {
+ WebCore::HitTestResult hitTestResult =
+ m_mainFrame->eventHandler()-> hitTestResultAtPoint(
+ screenCenter, false);
+ node = hitTestResult.innerNode();
+ }
if (node) {
bounds = node->getRect();
DBG_NAV_LOGD("ob:(x=%d,y=%d,w=%d,h=%d)",
bounds.x(), bounds.y(), bounds.width(), bounds.height());
- if ((anchorX | anchorY) == 0) {
- offset = WebCore::IntPoint(anchorPoint.x() - bounds.x(),
- anchorPoint.y() - bounds.y());
- if (offset.x() < 0 || offset.x() > realScreenWidth ||
- offset.y() < 0 || offset.y() > screenHeight)
- {
- DBG_NAV_LOGD("offset out of bounds:(x=%d,y=%d)",
- offset.x(), offset.y());
- node = 0;
- }
+ offset = WebCore::IntPoint(screenCenter.x() - bounds.x(),
+ screenCenter.y() - bounds.y());
+ if (offset.x() < 0 || offset.x() > realScreenWidth ||
+ offset.y() < 0 || offset.y() > screenHeight)
+ {
+ DBG_NAV_LOGD("offset out of bounds:(x=%d,y=%d)",
+ offset.x(), offset.y());
+ node = 0;
}
}
r->setNeedsLayoutAndPrefWidthsRecalc();
m_mainFrame->view()->forceLayout();
// scroll to restore current screen center
- if (!node)
- return;
- const WebCore::IntRect& newBounds = node->getRect();
- DBG_NAV_LOGD("nb:(x=%d,y=%d,w=%d,"
- "h=%d,ns=%d)", newBounds.x(), newBounds.y(),
- newBounds.width(), newBounds.height());
- if ((anchorX | anchorY) == 0)
- scrollBy(newBounds.x() - bounds.x(),
- newBounds.y() - bounds.y(), false);
- else if ((orsw && osh && bounds.width() && bounds.height())
- && (bounds != newBounds)) {
- WebCore::FrameView* view = m_mainFrame->view();
- // force left align if width is not changed while height changed.
- // the anchorPoint is probably at some white space in the node
- // which is affected by text wrap around the screen width.
- bool leftAlign = (osw != m_screenWidth)
- && (bounds.width() == newBounds.width())
- && (bounds.height() != newBounds.height());
- showRect(newBounds.x(), newBounds.y(), newBounds.width(),
- newBounds.height(), view->contentsWidth(),
- view->contentsHeight(),
- leftAlign ? 0.0 : (float) (anchorX - bounds.x()) / bounds.width(),
- leftAlign ? 0.0 : (float) (anchorX - m_scrollOffsetX) / orsw,
- (float) (anchorY - bounds.y()) / bounds.height(),
- (float) (anchorY - m_scrollOffsetY) / osh);
+ if (node) {
+ const WebCore::IntRect& newBounds = node->getRect();
+ DBG_NAV_LOGD("nb:(x=%d,y=%d,w=%d,"
+ "h=%d,ns=%d)", newBounds.x(), newBounds.y(),
+ newBounds.width(), newBounds.height());
+ scrollBy(newBounds.x() - bounds.x(), newBounds.y() - bounds.y(),
+ false);
}
}
}
@@ -1155,26 +1170,24 @@ void WebViewCore::dumpDomTree(bool useFile)
void WebViewCore::dumpRenderTree(bool useFile)
{
#ifdef ANDROID_DOM_LOGGING
- if (useFile)
- gRenderTreeFile = fopen(RENDER_TREE_LOG_FILE, "w");
- WebCore::CString renderDump = WebCore::externalRepresentation(m_mainFrame->contentRenderer()).utf8();
+ WebCore::CString renderDump = WebCore::externalRepresentation(m_mainFrame).utf8();
const char* data = renderDump.data();
- int length = renderDump.length();
- int last = 0;
- for (int i = 0; i < length; i++) {
- if (data[i] == '\n') {
- if (i != last) {
- char* chunk = new char[i - last + 1];
- strncpy(chunk, (data + last), i - last);
- chunk[i - last] = '\0';
- DUMP_RENDER_LOGD("%s", chunk);
- }
- last = i + 1;
- }
- }
- if (gRenderTreeFile) {
+ if (useFile) {
+ gRenderTreeFile = fopen(RENDER_TREE_LOG_FILE, "w");
+ DUMP_RENDER_LOGD("%s", data);
fclose(gRenderTreeFile);
gRenderTreeFile = 0;
+ } else {
+ // adb log can only output 1024 characters, so write out line by line.
+ // exclude '\n' as adb log adds it for each output.
+ int length = renderDump.length();
+ for (int i = 0, last = 0; i < length; i++) {
+ if (data[i] == '\n') {
+ if (i != last)
+ DUMP_RENDER_LOGD("%.*s", (i - last), &(data[last]));
+ last = i + 1;
+ }
+ }
}
#endif
}
@@ -1186,14 +1199,41 @@ void WebViewCore::dumpNavTree()
#endif
}
-WebCore::String WebViewCore::retrieveHref(WebCore::Frame* frame, WebCore::Node* node)
+WebCore::HTMLAnchorElement* WebViewCore::retrieveAnchorElement(WebCore::Frame* frame, WebCore::Node* node)
{
if (!CacheBuilder::validNode(m_mainFrame, frame, node))
- return WebCore::String();
+ return 0;
if (!node->hasTagName(WebCore::HTMLNames::aTag))
- return WebCore::String();
- WebCore::HTMLAnchorElement* anchor = static_cast<WebCore::HTMLAnchorElement*>(node);
- return anchor->href();
+ return 0;
+ return static_cast<WebCore::HTMLAnchorElement*>(node);
+}
+
+WebCore::String WebViewCore::retrieveHref(WebCore::Frame* frame, WebCore::Node* node)
+{
+ WebCore::HTMLAnchorElement* anchor = retrieveAnchorElement(frame, node);
+ return anchor ? anchor->href() : WebCore::String();
+}
+
+WebCore::String WebViewCore::retrieveAnchorText(WebCore::Frame* frame, WebCore::Node* node)
+{
+ WebCore::HTMLAnchorElement* anchor = retrieveAnchorElement(frame, node);
+ return anchor ? anchor->text() : WebCore::String();
+}
+
+WebCore::String WebViewCore::requestLabel(WebCore::Frame* frame,
+ WebCore::Node* node)
+{
+ if (CacheBuilder::validNode(m_mainFrame, frame, node)) {
+ RefPtr<WebCore::NodeList> list = node->document()->getElementsByTagName("label");
+ unsigned length = list->length();
+ for (unsigned i = 0; i < length; i++) {
+ WebCore::HTMLLabelElement* label = static_cast<WebCore::HTMLLabelElement*>(
+ list->item(i));
+ if (label->correspondingControl() == node)
+ return label->innerHTML();
+ }
+ }
+ return WebCore::String();
}
void WebViewCore::updateCacheOnNodeChange()
@@ -1226,6 +1266,12 @@ void WebViewCore::updateCacheOnNodeChange()
void WebViewCore::updateFrameCache()
{
+#if USE(ACCELERATED_COMPOSITING)
+ ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(
+ mainFrame()->page()->chrome()->client());
+ chromeC->scheduleCompositingLayerSync();
+#endif
+
if (!m_frameCacheOutOfDate) {
DBG_NAV_LOG("!m_frameCacheOutOfDate");
return;
@@ -1300,6 +1346,11 @@ void WebViewCore::removePlugin(PluginWidgetAndroid* w)
}
}
+bool WebViewCore::isPlugin(PluginWidgetAndroid* w) const
+{
+ return m_plugins.find(w) >= 0;
+}
+
void WebViewCore::invalPlugin(PluginWidgetAndroid* w)
{
const double PLUGIN_INVAL_DELAY = 1.0 / 60;
@@ -1398,6 +1449,18 @@ void WebViewCore::sendPluginEvent(const ANPEvent& evt)
}
}
+PluginWidgetAndroid* WebViewCore::getPluginWidget(NPP npp)
+{
+ PluginWidgetAndroid** iter = m_plugins.begin();
+ PluginWidgetAndroid** stop = m_plugins.end();
+ for (; iter < stop; ++iter) {
+ if ((*iter)->pluginView()->instance() == npp) {
+ return (*iter);
+ }
+ }
+ return NULL;
+}
+
static PluginView* nodeIsPlugin(Node* node) {
RenderObject* renderer = node->renderer();
if (renderer && renderer->isWidget()) {
@@ -1421,33 +1484,6 @@ Node* WebViewCore::cursorNodeIsPlugin() {
return 0;
}
-
-void WebViewCore::updatePluginState(Frame* frame, Node* node, PluginState state) {
-
- // check that the node and frame pointers are (still) valid
- if (!frame || !node || !CacheBuilder::validNode(m_mainFrame, frame, node))
- return;
-
- // check that the node is a plugin view
- PluginView* pluginView = nodeIsPlugin(node);
- if (!pluginView)
- return;
-
- // create the event
- ANPEvent event;
- SkANP::InitEvent(&event, kLifecycle_ANPEventType);
-
- if (state == kLoseFocus_PluginState)
- event.data.lifecycle.action = kLoseFocus_ANPLifecycleAction;
- else if (state == kGainFocus_PluginState)
- event.data.lifecycle.action = kGainFocus_ANPLifecycleAction;
- else
- return;
-
- // send the event
- pluginView->platformPluginWidget()->sendEvent(event);
-}
-
///////////////////////////////////////////////////////////////////////////////
void WebViewCore::moveMouseIfLatest(int moveGeneration,
WebCore::Frame* frame, int x, int y)
@@ -1464,7 +1500,26 @@ void WebViewCore::moveMouseIfLatest(int moveGeneration,
moveMouse(frame, x, y);
}
-// Update mouse position and may change focused node.
+void WebViewCore::moveFocus(WebCore::Frame* frame, WebCore::Node* node)
+{
+ DBG_NAV_LOGD("frame=%p node=%p", frame, node);
+ if (!node || !CacheBuilder::validNode(m_mainFrame, frame, node)
+ || !node->isElementNode())
+ return;
+ // Code borrowed from FocusController::advanceFocus
+ WebCore::FocusController* focusController
+ = m_mainFrame->page()->focusController();
+ WebCore::Document* oldDoc
+ = focusController->focusedOrMainFrame()->document();
+ if (oldDoc->focusedNode() == node)
+ return;
+ if (node->document() != oldDoc)
+ oldDoc->setFocusedNode(0);
+ focusController->setFocusedFrame(frame);
+ static_cast<WebCore::Element*>(node)->focus(false);
+}
+
+// Update mouse position
void WebViewCore::moveMouse(WebCore::Frame* frame, int x, int y)
{
DBG_NAV_LOGD("frame=%p x=%d y=%d scrollOffset=(%d,%d)", frame,
@@ -1482,161 +1537,6 @@ void WebViewCore::moveMouse(WebCore::Frame* frame, int x, int y)
updateCacheOnNodeChange();
}
-static int findTextBoxIndex(WebCore::Node* node, const WebCore::IntPoint& pt)
-{
- if (!node->isTextNode()) {
- DBG_NAV_LOGD("node=%p pt=(%d,%d) isText=false", node, pt.x(), pt.y());
- return -2; // error
- }
- WebCore::RenderText* renderText = (WebCore::RenderText*) node->renderer();
- if (!renderText) {
- DBG_NAV_LOGD("node=%p pt=(%d,%d) renderText=0", node, pt.x(), pt.y());
- return -3; // error
- }
- FloatPoint absPt = renderText->localToAbsolute();
- WebCore::InlineTextBox *textBox = renderText->firstTextBox();
- int globalX, globalY;
- CacheBuilder::GetGlobalOffset(node, &globalX, &globalY);
- int x = pt.x() - globalX;
- int y = pt.y() - globalY;
- do {
- int textBoxStart = textBox->start();
- int textBoxEnd = textBoxStart + textBox->len();
- if (textBoxEnd <= textBoxStart)
- continue;
- WebCore::IntRect bounds = textBox->selectionRect(absPt.x(), absPt.y(),
- textBoxStart, textBoxEnd);
- if (!bounds.contains(x, y))
- continue;
- int offset = textBox->offsetForPosition(x - absPt.x());
-#if DEBUG_NAV_UI
- int prior = offset > 0 ? textBox->positionForOffset(offset - 1) : -1;
- int current = textBox->positionForOffset(offset);
- int next = textBox->positionForOffset(offset + 1);
- DBG_NAV_LOGD(
- "offset=%d pt.x=%d globalX=%d renderX=%d x=%d "
- "textBox->x()=%d textBox->start()=%d prior=%d current=%d next=%d",
- offset, pt.x(), globalX, absPt.x(), x,
- textBox->x(), textBox->start(), prior, current, next
- );
-#endif
- return textBox->start() + offset;
- } while ((textBox = textBox->nextTextBox()));
- return -1; // couldn't find point, may have walked off end
-}
-
-static inline bool isPunctuation(UChar c)
-{
- return WTF::Unicode::category(c) & (0
- | WTF::Unicode::Punctuation_Dash
- | WTF::Unicode::Punctuation_Open
- | WTF::Unicode::Punctuation_Close
- | WTF::Unicode::Punctuation_Connector
- | WTF::Unicode::Punctuation_Other
- | WTF::Unicode::Punctuation_InitialQuote
- | WTF::Unicode::Punctuation_FinalQuote
- );
-}
-
-static int centerX(const SkIRect& rect)
-{
- return (rect.fLeft + rect.fRight) >> 1;
-}
-
-static int centerY(const SkIRect& rect)
-{
- return (rect.fTop + rect.fBottom) >> 1;
-}
-
-WebCore::String WebViewCore::getSelection(SkRegion* selRgn)
-{
- SkRegion::Iterator iter(*selRgn);
- // FIXME: switch this to use StringBuilder instead
- WebCore::String result;
- WebCore::Node* lastStartNode = 0;
- int lastStartEnd = -1;
- UChar lastChar = 0xffff;
- for (; !iter.done(); iter.next()) {
- const SkIRect& rect = iter.rect();
- DBG_NAV_LOGD("rect=(%d, %d, %d, %d)", rect.fLeft, rect.fTop,
- rect.fRight, rect.fBottom);
- int cy = centerY(rect);
- WebCore::IntPoint startPt = WebCore::IntPoint(rect.fLeft + 1, cy);
- WebCore::HitTestResult hitTestResult = m_mainFrame->eventHandler()->
- hitTestResultAtPoint(startPt, false);
- WebCore::Node* node = hitTestResult.innerNode();
- if (!node) {
- DBG_NAV_LOG("!node");
- return result;
- }
- WebCore::IntPoint endPt = WebCore::IntPoint(rect.fRight - 1, cy);
- hitTestResult = m_mainFrame->eventHandler()->hitTestResultAtPoint(endPt, false);
- WebCore::Node* endNode = hitTestResult.innerNode();
- if (!endNode) {
- DBG_NAV_LOG("!endNode (right-1)");
- endPt = WebCore::IntPoint(rect.fRight - 2, cy);
- hitTestResult = m_mainFrame->eventHandler()->hitTestResultAtPoint(endPt, false);
- endNode = hitTestResult.innerNode();
- }
- if (!endNode) {
- DBG_NAV_LOG("!endNode (right-2)");
- return result;
- }
- int start = findTextBoxIndex(node, startPt);
- if (start < 0)
- continue;
- int end = findTextBoxIndex(endNode, endPt);
- if (end < -1) // use node if endNode is not valid
- endNode = node;
- if (end <= 0)
- end = static_cast<WebCore::Text*>(endNode)->string()->length();
- DBG_NAV_LOGD("node=%p start=%d endNode=%p end=%d", node, start, endNode, end);
- WebCore::Node* startNode = node;
- do {
- if (!node->isTextNode())
- continue;
- if (node->getRect().isEmpty())
- continue;
- WebCore::Text* textNode = static_cast<WebCore::Text*>(node);
- WebCore::StringImpl* string = textNode->string();
- if (!string->length())
- continue;
- const UChar* chars = string->characters();
- int newLength = node == endNode ? end : string->length();
- if (node == startNode) {
- #if DEBUG_NAV_UI
- if (node == lastStartNode)
- DBG_NAV_LOGD("start=%d last=%d", start, lastStartEnd);
- #endif
- if (node == lastStartNode && start < lastStartEnd)
- break; // skip rect if text overlaps already written text
- lastStartNode = node;
- lastStartEnd = newLength - start;
- }
- if (newLength < start) {
- DBG_NAV_LOGD("newLen=%d < start=%d", newLength, start);
- break;
- }
- if (!isPunctuation(chars[start]))
- result.append(' ');
- result.append(chars + start, newLength - start);
- start = 0;
- } while (node != endNode && (node = node->traverseNextNode()));
- }
- result = result.simplifyWhiteSpace().stripWhiteSpace();
-#if DUMP_NAV_CACHE
- {
- char buffer[256];
- CacheBuilder::Debug debug;
- debug.init(buffer, sizeof(buffer));
- debug.print("copy: ");
- debug.wideString(result);
- DUMP_NAV_LOGD("%s", buffer);
- }
-#endif
- return result;
-}
-
void WebViewCore::setSelection(int start, int end)
{
WebCore::Node* focus = currentFocus();
@@ -1670,7 +1570,16 @@ void WebViewCore::deleteSelection(int start, int end, int textGeneration)
WebCore::Node* focus = currentFocus();
if (!focus)
return;
- WebCore::TypingCommand::deleteSelection(focus->document());
+ // Prevent our editor client from passing a message to change the
+ // selection.
+ EditorClientAndroid* client = static_cast<EditorClientAndroid*>(
+ m_mainFrame->editor()->client());
+ client->setUiGeneratedSelectionChange(true);
+ PlatformKeyboardEvent down(kKeyCodeDel, 0, 0, true, false, false, false);
+ PlatformKeyboardEvent up(kKeyCodeDel, 0, 0, false, false, false, false);
+ key(down);
+ key(up);
+ client->setUiGeneratedSelectionChange(false);
m_textGeneration = textGeneration;
}
@@ -1765,7 +1674,7 @@ void WebViewCore::saveDocumentState(WebCore::Frame* frame)
{
if (!CacheBuilder::validNode(m_mainFrame, frame, 0))
frame = m_mainFrame;
- WebCore::HistoryItem *item = frame->loader()->currentHistoryItem();
+ WebCore::HistoryItem *item = frame->loader()->history()->currentItem();
// item can be null when there is no offical URL for the current page. This happens
// when the content is loaded using with WebCoreFrameBridge::LoadData() and there
@@ -1883,6 +1792,21 @@ static jobjectArray makeLabelArray(JNIEnv* env, const uint16_t** labels, size_t
return array;
}
+void WebViewCore::openFileChooser(PassRefPtr<WebCore::FileChooser> chooser) {
+ if (!chooser)
+ return;
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ jstring jName = (jstring) env->CallObjectMethod(
+ m_javaGlue->object(env).get(), m_javaGlue->m_openFileChooser);
+ checkException(env);
+ const UChar* string = (const UChar*) env->GetStringChars(jName, NULL);
+ if (!string)
+ return;
+ WebCore::String webcoreString = to_string(env, jName);
+ env->ReleaseStringChars(jName, string);
+ chooser->chooseFile(webcoreString);
+}
+
void WebViewCore::listBoxRequest(WebCoreReply* reply, const uint16_t** labels, size_t count, const int enabled[], size_t enabledCount,
bool multiple, const int selected[], size_t selectedCountOrSelection)
{
@@ -1894,22 +1818,17 @@ void WebViewCore::listBoxRequest(WebCoreReply* reply, const uint16_t** labels, s
// Create an array of java Strings for the drop down.
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
jobjectArray labelArray = makeLabelArray(env, labels, count);
// Create an array determining whether each item is enabled.
- jbooleanArray enabledArray = env->NewBooleanArray(enabledCount);
+ jintArray enabledArray = env->NewIntArray(enabledCount);
checkException(env);
- jboolean* ptrArray = env->GetBooleanArrayElements(enabledArray, 0);
+ jint* ptrArray = env->GetIntArrayElements(enabledArray, 0);
checkException(env);
for (size_t i = 0; i < enabledCount; i++) {
ptrArray[i] = enabled[i];
}
- env->ReleaseBooleanArrayElements(enabledArray, ptrArray, 0);
+ env->ReleaseIntArrayElements(enabledArray, ptrArray, 0);
checkException(env);
if (multiple) {
@@ -1923,11 +1842,15 @@ void WebViewCore::listBoxRequest(WebCoreReply* reply, const uint16_t** labels, s
}
env->ReleaseIntArrayElements(selectedArray, selArray, 0);
- env->CallVoidMethod(obj.get(), m_javaGlue->m_requestListBox, labelArray, enabledArray, selectedArray);
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_requestListBox, labelArray, enabledArray,
+ selectedArray);
env->DeleteLocalRef(selectedArray);
} else {
// Pass up the single selection.
- env->CallVoidMethod(obj.get(), m_javaGlue->m_requestSingleListBox, labelArray, enabledArray, selectedCountOrSelection);
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_requestSingleListBox, labelArray, enabledArray,
+ selectedCountOrSelection);
}
env->DeleteLocalRef(labelArray);
@@ -1972,9 +1895,19 @@ void WebViewCore::click(WebCore::Frame* frame, WebCore::Node* node) {
}
}
-bool WebViewCore::handleTouchEvent(int action, int x, int y)
+int WebViewCore::handleTouchEvent(int action, int x, int y)
{
- bool preventDefault = false;
+ int preventDefault = 0;
+
+#if USE(ACCELERATED_COMPOSITING)
+ RenderView* contentRenderer = m_mainFrame->contentRenderer();
+ GraphicsLayerAndroid* rootLayer = 0;
+ if (contentRenderer)
+ rootLayer = static_cast<GraphicsLayerAndroid*>(
+ contentRenderer->compositor()->rootPlatformLayer());
+ if (rootLayer)
+ rootLayer->pauseDisplay(true);
+#endif
#if ENABLE(TOUCH_EVENTS) // Android
WebCore::TouchEventType type = WebCore::TouchEventCancel;
@@ -1991,12 +1924,22 @@ bool WebViewCore::handleTouchEvent(int action, int x, int y)
case 3: // MotionEvent.ACTION_CANCEL
type = WebCore::TouchEventCancel;
break;
+ case 0x100: // WebViewCore.ACTION_LONGPRESS
+ type = WebCore::TouchEventLongPress;
+ break;
+ case 0x200: // WebViewCore.ACTION_DOUBLETAP
+ type = WebCore::TouchEventDoubleTap;
+ break;
}
WebCore::IntPoint pt(x - m_scrollOffsetX, y - m_scrollOffsetY);
WebCore::PlatformTouchEvent te(pt, pt, type);
preventDefault = m_mainFrame->eventHandler()->handleTouchEvent(te);
#endif
+#if USE(ACCELERATED_COMPOSITING)
+ if (rootLayer)
+ rootLayer->pauseDisplay(false);
+#endif
return preventDefault;
}
@@ -2008,35 +1951,16 @@ void WebViewCore::touchUp(int touchGeneration,
" x=%d y=%d", m_touchGeneration, touchGeneration, x, y);
return; // short circuit if a newer touch has been generated
}
+ // This moves m_mousePos to the correct place, and handleMouseClick uses
+ // m_mousePos to determine where the click happens.
moveMouse(frame, x, y);
m_lastGeneration = touchGeneration;
if (frame && CacheBuilder::validNode(m_mainFrame, frame, 0)) {
frame->loader()->resetMultipleFormSubmissionProtection();
}
- // If the click is on an unselected textfield/area we do not want to allow
- // the click to change the selection, because we will set it ourselves
- // elsewhere - beginning for textareas, end for textfields
- bool needToIgnoreChangesToSelectedRange = true;
- WebCore::Node* focusNode = currentFocus();
- if (focusNode) {
- WebCore::RenderObject* renderer = focusNode->renderer();
- if (renderer && (renderer->isTextField() || renderer->isTextArea())) {
- // Now check to see if the click is inside the focused textfield
- if (focusNode->getRect().contains(x, y))
- needToIgnoreChangesToSelectedRange = false;
- }
- }
- EditorClientAndroid* client = 0;
- if (needToIgnoreChangesToSelectedRange) {
- client = static_cast<EditorClientAndroid*>(
- m_mainFrame->editor()->client());
- client->setShouldChangeSelectedRange(false);
- }
DBG_NAV_LOGD("touchGeneration=%d handleMouseClick frame=%p node=%p"
" x=%d y=%d", touchGeneration, frame, node, x, y);
handleMouseClick(frame, node);
- if (needToIgnoreChangesToSelectedRange)
- client->setShouldChangeSelectedRange(true);
}
// Common code for both clicking with the trackball and touchUp
@@ -2060,6 +1984,13 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
WebCore::HTMLSelectElement* select = static_cast<WebCore::HTMLSelectElement*>(nodePtr);
const WTF::Vector<WebCore::Element*>& listItems = select->listItems();
SkTDArray<const uint16_t*> names;
+ // Possible values for enabledArray. Keep in Sync with values in
+ // InvokeListBox.Container in WebView.java
+ enum OptionStatus {
+ OPTGROUP = -1,
+ OPTION_DISABLED = 0,
+ OPTION_ENABLED = 1,
+ };
SkTDArray<int> enabledArray;
SkTDArray<int> selectedArray;
int size = listItems.size();
@@ -2068,13 +1999,13 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
if (listItems[i]->hasTagName(WebCore::HTMLNames::optionTag)) {
WebCore::HTMLOptionElement* option = static_cast<WebCore::HTMLOptionElement*>(listItems[i]);
*names.append() = stringConverter(option->textIndentedToRespectGroupLabel());
- *enabledArray.append() = option->disabled() ? 0 : 1;
+ *enabledArray.append() = option->disabled() ? OPTION_DISABLED : OPTION_ENABLED;
if (multiple && option->selected())
*selectedArray.append() = i;
} else if (listItems[i]->hasTagName(WebCore::HTMLNames::optgroupTag)) {
WebCore::HTMLOptGroupElement* optGroup = static_cast<WebCore::HTMLOptGroupElement*>(listItems[i]);
*names.append() = stringConverter(optGroup->groupLabelText());
- *enabledArray.append() = 0;
+ *enabledArray.append() = OPTGROUP;
}
}
WebCoreReply* reply = new ListBoxReply(select, select->document()->frame(), this);
@@ -2109,8 +2040,12 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
m_mousePos.y(), focusNode, handled ? "true" : "false");
if (focusNode) {
WebCore::RenderObject* renderer = focusNode->renderer();
- if (renderer && (renderer->isTextField() || renderer->isTextArea()))
- setFocusControllerActive(true);
+ if (renderer && (renderer->isTextField() || renderer->isTextArea())) {
+ bool ime = !(static_cast<WebCore::HTMLInputElement*>(focusNode))
+ ->readOnly();
+ setFocusControllerActive(ime);
+ requestKeyboard(ime, true);
+ }
}
return handled;
}
@@ -2135,14 +2070,11 @@ void WebViewCore::popupReply(const int* array, int count)
void WebViewCore::addMessageToConsole(const WebCore::String& message, unsigned int lineNumber, const WebCore::String& sourceID) {
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
jstring jMessageStr = env->NewString((unsigned short *)message.characters(), message.length());
jstring jSourceIDStr = env->NewString((unsigned short *)sourceID.characters(), sourceID.length());
- env->CallVoidMethod(obj.get(), m_javaGlue->m_addMessageToConsole, jMessageStr, lineNumber, jSourceIDStr);
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_addMessageToConsole, jMessageStr, lineNumber,
+ jSourceIDStr);
env->DeleteLocalRef(jMessageStr);
env->DeleteLocalRef(jSourceIDStr);
checkException(env);
@@ -2151,14 +2083,9 @@ void WebViewCore::addMessageToConsole(const WebCore::String& message, unsigned i
void WebViewCore::jsAlert(const WebCore::String& url, const WebCore::String& text)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
jstring jInputStr = env->NewString((unsigned short *)text.characters(), text.length());
jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length());
- env->CallVoidMethod(obj.get(), m_javaGlue->m_jsAlert, jUrlStr, jInputStr);
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsAlert, jUrlStr, jInputStr);
env->DeleteLocalRef(jInputStr);
env->DeleteLocalRef(jUrlStr);
checkException(env);
@@ -2168,14 +2095,11 @@ void WebViewCore::exceededDatabaseQuota(const WebCore::String& url, const WebCor
{
#if ENABLE(DATABASE)
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
jstring jDatabaseIdentifierStr = env->NewString((unsigned short *)databaseIdentifier.characters(), databaseIdentifier.length());
jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length());
- env->CallVoidMethod(obj.get(), m_javaGlue->m_exceededDatabaseQuota, jUrlStr, jDatabaseIdentifierStr, currentQuota, estimatedSize);
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_exceededDatabaseQuota, jUrlStr,
+ jDatabaseIdentifierStr, currentQuota, estimatedSize);
env->DeleteLocalRef(jDatabaseIdentifierStr);
env->DeleteLocalRef(jUrlStr);
checkException(env);
@@ -2186,12 +2110,8 @@ void WebViewCore::reachedMaxAppCacheSize(const unsigned long long spaceNeeded)
{
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue->m_reachedMaxAppCacheSize, spaceNeeded);
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_reachedMaxAppCacheSize, spaceNeeded);
checkException(env);
#endif
}
@@ -2200,25 +2120,15 @@ void WebViewCore::populateVisitedLinks(WebCore::PageGroup* group)
{
m_groupForVisitedLinks = group;
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue->m_populateVisitedLinks);
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_populateVisitedLinks);
checkException(env);
}
void WebViewCore::geolocationPermissionsShowPrompt(const WebCore::String& origin)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
jstring originString = env->NewString((unsigned short *)origin.characters(), origin.length());
- env->CallVoidMethod(obj.get(),
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
m_javaGlue->m_geolocationPermissionsShowPrompt,
originString);
env->DeleteLocalRef(originString);
@@ -2228,12 +2138,7 @@ void WebViewCore::geolocationPermissionsShowPrompt(const WebCore::String& origin
void WebViewCore::geolocationPermissionsHidePrompt()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(),
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
m_javaGlue->m_geolocationPermissionsHidePrompt);
checkException(env);
}
@@ -2241,14 +2146,9 @@ void WebViewCore::geolocationPermissionsHidePrompt()
bool WebViewCore::jsConfirm(const WebCore::String& url, const WebCore::String& text)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return false;
jstring jInputStr = env->NewString((unsigned short *)text.characters(), text.length());
jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length());
- jboolean result = env->CallBooleanMethod(obj.get(), m_javaGlue->m_jsConfirm, jUrlStr, jInputStr);
+ jboolean result = env->CallBooleanMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsConfirm, jUrlStr, jInputStr);
env->DeleteLocalRef(jInputStr);
env->DeleteLocalRef(jUrlStr);
checkException(env);
@@ -2258,16 +2158,10 @@ bool WebViewCore::jsConfirm(const WebCore::String& url, const WebCore::String& t
bool WebViewCore::jsPrompt(const WebCore::String& url, const WebCore::String& text, const WebCore::String& defaultValue, WebCore::String& result)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return false;
-
jstring jInputStr = env->NewString((unsigned short *)text.characters(), text.length());
jstring jDefaultStr = env->NewString((unsigned short *)defaultValue.characters(), defaultValue.length());
jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length());
- jstring returnVal = (jstring) env->CallObjectMethod(obj.get(), m_javaGlue->m_jsPrompt, jUrlStr, jInputStr, jDefaultStr);
+ jstring returnVal = (jstring) env->CallObjectMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsPrompt, jUrlStr, jInputStr, jDefaultStr);
// If returnVal is null, it means that the user cancelled the dialog.
if (!returnVal)
return false;
@@ -2283,14 +2177,9 @@ bool WebViewCore::jsPrompt(const WebCore::String& url, const WebCore::String& te
bool WebViewCore::jsUnload(const WebCore::String& url, const WebCore::String& message)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return false;
jstring jInputStr = env->NewString((unsigned short *)message.characters(), message.length());
jstring jUrlStr = env->NewString((unsigned short *)url.characters(), url.length());
- jboolean result = env->CallBooleanMethod(obj.get(), m_javaGlue->m_jsUnload, jUrlStr, jInputStr);
+ jboolean result = env->CallBooleanMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsUnload, jUrlStr, jInputStr);
env->DeleteLocalRef(jInputStr);
env->DeleteLocalRef(jUrlStr);
checkException(env);
@@ -2300,12 +2189,7 @@ bool WebViewCore::jsUnload(const WebCore::String& url, const WebCore::String& me
bool WebViewCore::jsInterrupt()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return true; // default to interrupt
- jboolean result = env->CallBooleanMethod(obj.get(), m_javaGlue->m_jsInterrupt);
+ jboolean result = env->CallBooleanMethod(m_javaGlue->object(env).get(), m_javaGlue->m_jsInterrupt);
checkException(env);
return result;
}
@@ -2320,12 +2204,7 @@ jobject
WebViewCore::getWebViewJavaObject()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return 0;
- return env->GetObjectField(obj.get(), gWebViewCoreFields.m_webView);
+ return env->GetObjectField(m_javaGlue->object(env).get(), gWebViewCoreFields.m_webView);
}
void WebViewCore::updateTextSelection() {
@@ -2337,12 +2216,7 @@ void WebViewCore::updateTextSelection() {
return;
RenderTextControl* rtc = static_cast<RenderTextControl*>(renderer);
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(),
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
m_javaGlue->m_updateTextSelection, reinterpret_cast<int>(focusNode),
rtc->selectionStart(), rtc->selectionEnd(), m_textGeneration);
checkException(env);
@@ -2354,21 +2228,15 @@ void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword,
if (m_blockTextfieldUpdates)
return;
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
-
if (changeToPassword) {
- env->CallVoidMethod(obj.get(), m_javaGlue->m_updateTextfield,
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_updateTextfield,
(int) ptr, true, 0, m_textGeneration);
checkException(env);
return;
}
int length = text.length();
jstring string = env->NewString((unsigned short *) text.characters(), length);
- env->CallVoidMethod(obj.get(), m_javaGlue->m_updateTextfield,
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_updateTextfield,
(int) ptr, false, string, m_textGeneration);
env->DeleteLocalRef(string);
checkException(env);
@@ -2377,13 +2245,8 @@ void WebViewCore::updateTextfield(WebCore::Node* ptr, bool changeToPassword,
void WebViewCore::clearTextEntry()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
-
- env->CallVoidMethod(obj.get(), m_javaGlue->m_clearTextEntry);
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_clearTextEntry);
}
void WebViewCore::setBackgroundColor(SkColor c)
@@ -2398,73 +2261,106 @@ void WebViewCore::setBackgroundColor(SkColor c)
view->setBaseBackgroundColor(bcolor);
}
-void WebViewCore::startFullScreenPluginActivity(const char* libName,
- const char* className, NPP npp)
+jclass WebViewCore::getPluginClass(const WebCore::String& libName, const char* className)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- jstring libString = env->NewStringUTF(libName);
+ jstring libString = env->NewString(libName.characters(), libName.length());
+ jstring classString = env->NewStringUTF(className);
+ jobject pluginClass = env->CallObjectMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_getPluginClass,
+ libString, classString);
+ checkException(env);
+
+ // cleanup unneeded local JNI references
+ env->DeleteLocalRef(libString);
+ env->DeleteLocalRef(classString);
+
+ if (pluginClass != NULL) {
+ return static_cast<jclass>(pluginClass);
+ } else {
+ return NULL;
+ }
+}
+
+void WebViewCore::showFullScreenPlugin(jobject childView, NPP npp, int x,
+ int y, int width, int height)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- jstring classString = env->NewStringUTF(className);
env->CallVoidMethod(obj.get(),
- m_javaGlue->m_startFullScreenPluginActivity,
- libString, classString, (int) npp);
+ m_javaGlue->m_showFullScreenPlugin,
+ childView, (int)npp, x, y, width, height);
checkException(env);
}
-jobject WebViewCore::createSurface(const char* libName, const char* className,
- NPP npp, int x, int y, int width, int height)
+void WebViewCore::hideFullScreenPlugin()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return 0;
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_hideFullScreenPlugin);
+ checkException(env);
+}
- jstring libString = env->NewStringUTF(libName);
- jstring classString = env->NewStringUTF(className);
- jobject result = env->CallObjectMethod(obj.get(),
- m_javaGlue->m_createSurface, libString,
- classString,(int) npp, x, y, width, height);
+void WebViewCore::updateFullScreenPlugin(int x, int y, int width, int height)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_updateFullScreenPlugin, x, y,
+ width, height);
+ checkException(env);
+}
+
+jobject WebViewCore::addSurface(jobject view, int x, int y, int width, int height)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ jobject result = env->CallObjectMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_addSurface,
+ view, x, y, width, height);
checkException(env);
return result;
+}
+void WebViewCore::updateSurface(jobject childView, int x, int y, int width, int height)
+{
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue->object(env).get(),
+ m_javaGlue->m_updateSurface, childView,
+ x, y, width, height);
+ checkException(env);
}
void WebViewCore::destroySurface(jobject childView)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
-
- env->CallVoidMethod(obj.get(), m_javaGlue->m_destroySurface, childView);
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_destroySurface, childView);
checkException(env);
}
-void WebViewCore::showRect(int left, int top, int width, int height,
- int contentWidth, int contentHeight, float xPercentInDoc,
- float xPercentInView, float yPercentInDoc, float yPercentInView)
+jobject WebViewCore::getContext()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
AutoJObject obj = m_javaGlue->object(env);
- // if it is called during DESTROY is handled, the real object of WebViewCore
- // can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue->m_showRect, left, top, width,
- height, contentWidth, contentHeight, xPercentInDoc, xPercentInView,
- yPercentInDoc, yPercentInView);
+ jobject result = env->CallObjectMethod(obj.get(), m_javaGlue->m_getContext);
checkException(env);
+ return result;
+}
+
+bool WebViewCore::validNodeAndBounds(Frame* frame, Node* node,
+ const IntRect& originalAbsoluteBounds)
+{
+ bool valid = CacheBuilder::validNode(m_mainFrame, frame, node);
+ if (!valid)
+ return false;
+ RenderObject* renderer = node->renderer();
+ if (!renderer)
+ return false;
+ IntRect absBounds = node->hasTagName(HTMLNames::areaTag)
+ ? CacheBuilder::getAreaRect(static_cast<HTMLAreaElement*>(node))
+ : renderer->absoluteBoundingBoxRect();
+ return absBounds == originalAbsoluteBounds;
}
//----------------------------------------------------------------------
@@ -2480,6 +2376,13 @@ static jstring WebCoreStringToJString(JNIEnv *env, WebCore::String string)
return ret;
}
+static jstring RequestLabel(JNIEnv *env, jobject obj, int framePointer,
+ int nodePointer)
+{
+ return WebCoreStringToJString(env, GET_NATIVE_VIEW(env, obj)->requestLabel(
+ (WebCore::Frame*) framePointer, (WebCore::Node*) nodePointer));
+}
+
static void UpdateFrameCacheIfLoading(JNIEnv *env, jobject obj)
{
GET_NATIVE_VIEW(env, obj)->updateFrameCacheIfLoading();
@@ -2487,7 +2390,7 @@ static void UpdateFrameCacheIfLoading(JNIEnv *env, jobject obj)
static void SetSize(JNIEnv *env, jobject obj, jint width, jint height,
jint screenWidth, jfloat scale, jint realScreenWidth, jint screenHeight,
- jint anchorX, jint anchorY, jboolean ignoreHeight)
+ jboolean ignoreHeight)
{
#ifdef ANDROID_INSTRUMENT
TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
@@ -2496,7 +2399,7 @@ static void SetSize(JNIEnv *env, jobject obj, jint width, jint height,
LOGV("webviewcore::nativeSetSize(%u %u)\n viewImpl: %p", (unsigned)width, (unsigned)height, viewImpl);
LOG_ASSERT(viewImpl, "viewImpl not set in nativeSetSize");
viewImpl->setSizeScreenWidthAndScale(width, height, screenWidth, scale,
- realScreenWidth, screenHeight, anchorX, anchorY, ignoreHeight);
+ realScreenWidth, screenHeight, ignoreHeight);
}
static void SetScrollOffset(JNIEnv *env, jobject obj, jint gen, jint x, jint y)
@@ -2711,7 +2614,7 @@ static jstring FindAddress(JNIEnv *env, jobject obj, jstring addr,
return ret;
}
-static jboolean HandleTouchEvent(JNIEnv *env, jobject obj, jint action, jint x, jint y)
+static jint HandleTouchEvent(JNIEnv *env, jobject obj, jint action, jint x, jint y)
{
#ifdef ANDROID_INSTRUMENT
TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
@@ -2748,6 +2651,32 @@ static jstring RetrieveHref(JNIEnv *env, jobject obj, jint frame,
return 0;
}
+static jstring RetrieveAnchorText(JNIEnv *env, jobject obj, jint frame,
+ jint node)
+{
+#ifdef ANDROID_INSTRUMENT
+ TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
+#endif
+ WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
+ LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__);
+ WebCore::String result = viewImpl->retrieveAnchorText((WebCore::Frame*) frame,
+ (WebCore::Node*) node);
+ if (!result.isEmpty())
+ return WebCoreStringToJString(env, result);
+ return 0;
+}
+
+
+static void MoveFocus(JNIEnv *env, jobject obj, jint framePtr, jint nodePtr)
+{
+#ifdef ANDROID_INSTRUMENT
+ TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
+#endif
+ WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
+ LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__);
+ viewImpl->moveFocus((WebCore::Frame*) framePtr, (WebCore::Node*) nodePtr);
+}
+
static void MoveMouse(JNIEnv *env, jobject obj, jint frame,
jint x, jint y)
{
@@ -2836,20 +2765,6 @@ static void SetBackgroundColor(JNIEnv *env, jobject obj, jint color)
viewImpl->setBackgroundColor((SkColor) color);
}
-static jstring GetSelection(JNIEnv *env, jobject obj, jobject selRgn)
-{
-#ifdef ANDROID_INSTRUMENT
- TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
-#endif
- WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
- LOG_ASSERT(viewImpl, "viewImpl not set in %s", __FUNCTION__);
- SkRegion* selectionRegion = GraphicsJNI::getNativeRegion(env, selRgn);
- WebCore::String result = viewImpl->getSelection(selectionRegion);
- if (!result.isEmpty())
- return WebCoreStringToJString(env, result);
- return 0;
-}
-
static void DumpDomTree(JNIEnv *env, jobject obj, jboolean useFile)
{
WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
@@ -2944,20 +2859,14 @@ static bool DrawContent(JNIEnv *env, jobject obj, jobject canv, jint color)
return viewImpl->drawContent(canvas, color);
}
-static bool PictureReady(JNIEnv* env, jobject obj)
+static bool FocusBoundsChanged(JNIEnv* env, jobject obj)
{
- return GET_NATIVE_VIEW(env, obj)->pictureReady();
+ return GET_NATIVE_VIEW(env, obj)->focusBoundsChanged();
}
-static void UpdatePluginState(JNIEnv* env, jobject obj, jint framePtr, jint nodePtr, jint state)
+static bool PictureReady(JNIEnv* env, jobject obj)
{
-#ifdef ANDROID_INSTRUMENT
- TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
-#endif
- WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
- LOG_ASSERT(viewImpl, "viewImpl not set in nativeUpdatePluginState");
- viewImpl->updatePluginState((WebCore::Frame*) framePtr, (WebCore::Node*) nodePtr,
- (PluginState) state);
+ return GET_NATIVE_VIEW(env, obj)->pictureReady();
}
static void Pause(JNIEnv* env, jobject obj)
@@ -3027,7 +2936,30 @@ static void ProvideVisitedHistory(JNIEnv *env, jobject obj, jobject hist)
env->ReleaseStringChars(item, str);
env->DeleteLocalRef(item);
}
- env->DeleteLocalRef(array);
+}
+
+// Notification from the UI thread that the plugin's full-screen surface has been discarded
+static void FullScreenPluginHidden(JNIEnv* env, jobject obj, jint npp)
+{
+ WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
+ PluginWidgetAndroid* plugin = viewImpl->getPluginWidget((NPP)npp);
+ plugin->exitFullScreen(false);
+}
+
+static WebCore::IntRect jrect_to_webrect(JNIEnv* env, jobject obj)
+{
+ int L, T, R, B;
+ GraphicsJNI::get_jrect(env, obj, &L, &T, &R, &B);
+ return WebCore::IntRect(L, T, R - L, B - T);
+}
+
+static bool ValidNodeAndBounds(JNIEnv *env, jobject obj, int frame, int node,
+ jobject rect)
+{
+ IntRect nativeRect = jrect_to_webrect(env, rect);
+ return GET_NATIVE_VIEW(env, obj)->validNodeAndBounds(
+ reinterpret_cast<Frame*>(frame),
+ reinterpret_cast<Node*>(node), nativeRect);
}
// ----------------------------------------------------------------------------
@@ -3042,6 +2974,8 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) CopyContentToPicture },
{ "nativeDrawContent", "(Landroid/graphics/Canvas;I)Z",
(void*) DrawContent } ,
+ { "nativeFocusBoundsChanged", "()Z",
+ (void*) FocusBoundsChanged } ,
{ "nativeKey", "(IIIZZZZ)Z",
(void*) Key },
{ "nativeClick", "(II)V",
@@ -3052,7 +2986,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) SendListBoxChoices },
{ "nativeSendListBoxChoice", "(I)V",
(void*) SendListBoxChoice },
- { "nativeSetSize", "(IIIFIIIIZ)V",
+ { "nativeSetSize", "(IIIFIIZ)V",
(void*) SetSize },
{ "nativeSetScrollOffset", "(III)V",
(void*) SetScrollOffset },
@@ -3064,6 +2998,8 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) DeleteSelection } ,
{ "nativeReplaceTextfieldText", "(IILjava/lang/String;III)V",
(void*) ReplaceTextfieldText } ,
+ { "nativeMoveFocus", "(II)V",
+ (void*) MoveFocus },
{ "nativeMoveMouse", "(III)V",
(void*) MoveMouse },
{ "nativeMoveMouseIfLatest", "(IIII)V",
@@ -3078,12 +3014,14 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) SaveDocumentState },
{ "nativeFindAddress", "(Ljava/lang/String;Z)Ljava/lang/String;",
(void*) FindAddress },
- { "nativeHandleTouchEvent", "(III)Z",
+ { "nativeHandleTouchEvent", "(III)I",
(void*) HandleTouchEvent },
{ "nativeTouchUp", "(IIIII)V",
(void*) TouchUp },
{ "nativeRetrieveHref", "(II)Ljava/lang/String;",
(void*) RetrieveHref },
+ { "nativeRetrieveAnchorText", "(II)Ljava/lang/String;",
+ (void*) RetrieveAnchorText },
{ "nativeUpdateFrameCache", "()V",
(void*) UpdateFrameCache },
{ "nativeGetContentMinPrefWidth", "()I",
@@ -3096,8 +3034,6 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) SplitContent },
{ "nativeSetBackgroundColor", "(I)V",
(void*) SetBackgroundColor },
- { "nativeGetSelection", "(Landroid/graphics/Region;)Ljava/lang/String;",
- (void*) GetSelection },
{ "nativeRegisterURLSchemeAsLocal", "(Ljava/lang/String;)V",
(void*) RegisterURLSchemeAsLocal },
{ "nativeDumpDomTree", "(Z)V",
@@ -3114,11 +3050,16 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
{ "nativeResume", "()V", (void*) Resume },
{ "nativeFreeMemory", "()V", (void*) FreeMemory },
{ "nativeSetJsFlags", "(Ljava/lang/String;)V", (void*) SetJsFlags },
- { "nativeUpdatePluginState", "(III)V", (void*) UpdatePluginState },
+ { "nativeRequestLabel", "(II)Ljava/lang/String;",
+ (void*) RequestLabel },
{ "nativeUpdateFrameCacheIfLoading", "()V",
(void*) UpdateFrameCacheIfLoading },
{ "nativeProvideVisitedHistory", "([Ljava/lang/String;)V",
(void*) ProvideVisitedHistory },
+ { "nativeFullScreenPluginHidden", "(I)V",
+ (void*) FullScreenPluginHidden },
+ { "nativeValidNodeAndBounds", "(IILandroid/graphics/Rect;)Z",
+ (void*) ValidNodeAndBounds },
};
int register_webviewcore(JNIEnv* env)
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index eab22b4..0569b4d 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -27,6 +27,7 @@
#define WEBVIEWCORE_H
#include "android_npapi.h"
+#include "FileChooser.h"
#include "CacheBuilder.h"
#include "CachedHistory.h"
#include "PictureSet.h"
@@ -45,6 +46,7 @@ namespace WebCore {
class AtomicString;
class Color;
class FrameView;
+ class HTMLAnchorElement;
class HTMLSelectElement;
class RenderPart;
class RenderText;
@@ -62,14 +64,8 @@ class SkIRect;
namespace android {
- enum PluginState {
- kGainFocus_PluginState = 0,
- kLoseFocus_PluginState = 1,
- };
-
class CachedRoot;
class ListBoxReply;
- class SurfaceCallback;
class WebCoreReply : public WebCoreRefObject {
public:
@@ -130,6 +126,11 @@ namespace android {
*/
void contentDraw();
+#if USE(ACCELERATED_COMPOSITING)
+ void immediateRepaint();
+ void setRootLayer(int layer);
+#endif
+
/** Invalidate the view/screen, NOT the content/DOM, but expressed in
* content/DOM coordinates (i.e. they need to eventually be scaled,
* by webview into view.java coordinates
@@ -242,9 +243,10 @@ namespace android {
// Followings support calls from Java to native WebCore
//
- WebCore::String retrieveHref(WebCore::Frame* frame, WebCore::Node* node);
- WebCore::String getSelection(SkRegion* );
+ WebCore::String retrieveHref(WebCore::Frame* frame, WebCore::Node* node);
+ WebCore::String retrieveAnchorText(WebCore::Frame* frame, WebCore::Node* node);
+ WebCore::String requestLabel(WebCore::Frame* , WebCore::Node* );
// Create a single picture to represent the drawn DOM (used by navcache)
void recordPicture(SkPicture* picture);
@@ -252,6 +254,7 @@ namespace android {
// Create a set of pictures to represent the drawn DOM, driven by
// the invalidated region and the time required to draw (used to draw)
void recordPictureSet(PictureSet* master);
+ void moveFocus(WebCore::Frame* frame, WebCore::Node* node);
void moveMouse(WebCore::Frame* frame, int x, int y);
void moveMouseIfLatest(int moveGeneration,
WebCore::Frame* frame, int x, int y);
@@ -262,8 +265,8 @@ namespace android {
void setGlobalBounds(int x, int y, int h, int v);
void setSizeScreenWidthAndScale(int width, int height, int screenWidth,
- float scale, int realScreenWidth, int screenHeight, int anchorX,
- int anchorY, bool ignoreHeight);
+ float scale, int realScreenWidth, int screenHeight,
+ bool ignoreHeight);
/**
* Handle key events from Java.
@@ -279,7 +282,7 @@ namespace android {
/**
* Handle touch event
*/
- bool handleTouchEvent(int action, int x, int y);
+ int handleTouchEvent(int action, int x, int y);
/**
* Handle motionUp event from the UI thread (called touchUp in the
@@ -348,6 +351,8 @@ namespace android {
*/
void addPlugin(PluginWidgetAndroid*);
void removePlugin(PluginWidgetAndroid*);
+ // returns true if the pluginwidgit is in our active list
+ bool isPlugin(PluginWidgetAndroid*) const;
void invalPlugin(PluginWidgetAndroid*);
void drawPlugins();
@@ -363,39 +368,48 @@ namespace android {
// send this event to all of the plugins who have the given flag set
void sendPluginEvent(const ANPEvent& evt, ANPEventFlag flag);
+ // lookup the plugin widget struct given an NPP
+ PluginWidgetAndroid* getPluginWidget(NPP npp);
+
// return the cursorNode if it is a plugin
Node* cursorNodeIsPlugin();
- // notify the plugin of an update in state
- void updatePluginState(Frame* frame, Node* node, PluginState state);
-
// Notify the Java side whether it needs to pass down the touch events
void needTouchEvents(bool);
// Notify the Java side that webkit is requesting a keyboard
- void requestKeyboard(bool);
+ void requestKeyboard(bool showKeyboard, bool isTextView);
+
+ // Generates a class loader that contains classes from the plugin's apk
+ jclass getPluginClass(const WebCore::String& libName, const char* className);
- // Creates a full screen surface (i.e. View on an Activity) for a plugin
- void startFullScreenPluginActivity(const char* libName,
- const char* className, NPP npp);
+ // Creates a full screen surface for a plugin
+ void showFullScreenPlugin(jobject webkitPlugin, NPP npp, int x, int y, int width, int height);
- // Creates a Surface (i.e. View) for a plugin
- jobject createSurface(const char* libName, const char* className,
- NPP npp, int x, int y, int width, int height);
+ // Instructs the UI thread to discard the plugin's full-screen surface
+ void hideFullScreenPlugin();
+
+ // Update coordinates and dimensions for a full screen plugin
+ void updateFullScreenPlugin(int x, int y, int width, int height);
+
+ // Adds the plugin's view (aka surface) to the view hierarchy
+ jobject addSurface(jobject view, int x, int y, int width, int height);
+
+ // Updates a Surface coordinates and dimensions for a plugin
+ void updateSurface(jobject childView, int x, int y, int width, int height);
// Destroys a SurfaceView for a plugin
void destroySurface(jobject childView);
- // Make the rect (left, top, width, height) visible. If it can be fully
- // fit, center it on the screen. Otherwise make sure the point specified
- // by (left + xPercentInDoc * width, top + yPercentInDoc * height)
- // pinned at the screen position (xPercentInView, yPercentInView).
- void showRect(int left, int top, int width, int height, int contentWidth,
- int contentHeight, float xPercentInDoc, float xPercentInView,
- float yPercentInDoc, float yPercentInView);
+ // Returns the context (android.content.Context) of the WebView
+ jobject getContext();
+ bool validNodeAndBounds(Frame* , Node* , const IntRect& );
// other public functions
public:
+ // Open a file chooser for selecting a file to upload
+ void openFileChooser(PassRefPtr<WebCore::FileChooser> );
+
// reset the picture set to empty
void clearContent();
@@ -404,6 +418,7 @@ namespace android {
// draw the picture set with the specified background color
bool drawContent(SkCanvas* , SkColor );
+ bool focusBoundsChanged();
bool pictureReady();
// record the inval area, and the picture size
@@ -421,7 +436,6 @@ namespace android {
static Mutex gFrameCacheMutex;
CachedRoot* m_frameCacheKit; // nav data being built by webcore
SkPicture* m_navPictureKit;
- int m_generation; // copy of the number bumped by WebViewNative
int m_moveGeneration; // copy of state in WebViewNative triggered by move
int m_touchGeneration; // copy of state in WebViewNative triggered by touch
int m_lastGeneration; // last action using up to date cache
@@ -466,7 +480,6 @@ namespace android {
WebCore::IntRect m_lastFocusedBounds;
int m_lastFocusedSelStart;
int m_lastFocusedSelEnd;
- int m_lastMoveGeneration;
static Mutex m_contentMutex; // protects ui/core thread pictureset access
PictureSet m_content; // the set of pictures to draw (accessed by UI too)
SkRegion m_addInval; // the accumulated inval region (not yet drawn)
@@ -474,6 +487,7 @@ namespace android {
// Used in passToJS to avoid updating the UI text field until after the
// key event has been processed.
bool m_blockTextfieldUpdates;
+ bool m_focusBoundsChanged;
bool m_skipContentDraw;
// Passed in with key events to know when they were generated. Store it
// with the cache so that we can ignore stale text changes.
@@ -510,9 +524,21 @@ namespace android {
void rebuildPictureSet(PictureSet* );
void sendNotifyProgressFinished();
bool handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr);
+ WebCore::HTMLAnchorElement* retrieveAnchorElement(WebCore::Frame* frame, WebCore::Node* node);
+
#if DEBUG_NAV_UI
uint32_t m_now;
#endif
+
+ private:
+ // called from constructor, to add this to a global list
+ static void addInstance(WebViewCore*);
+ // called from destructor, to remove this from a global list
+ static void removeInstance(WebViewCore*);
+ public:
+ // call only from webkit thread (like add/remove), return true if inst
+ // is still alive
+ static bool isInstance(WebViewCore*);
};
} // namespace android