summaryrefslogtreecommitdiffstats
path: root/WebKit/android/jni/WebCoreFrameBridge.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/android/jni/WebCoreFrameBridge.cpp')
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.cpp495
1 files changed, 299 insertions, 196 deletions
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)