summaryrefslogtreecommitdiffstats
path: root/WebKit/android/jni/WebCoreFrameBridge.cpp
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-11-18 18:18:30 +0000
committerIain Merrick <husky@google.com>2010-11-22 16:56:54 +0000
commit20b3d204269f6c234d3f154a074f351565aa67b3 (patch)
tree1e4434d3c0796b4e58204788af9d98c448089666 /WebKit/android/jni/WebCoreFrameBridge.cpp
parentd8fcffded6ee266e903e4e191ed95a07007fac74 (diff)
downloadexternal_webkit-20b3d204269f6c234d3f154a074f351565aa67b3.zip
external_webkit-20b3d204269f6c234d3f154a074f351565aa67b3.tar.gz
external_webkit-20b3d204269f6c234d3f154a074f351565aa67b3.tar.bz2
Add maybeSavePassword() method to WebFrame.
This calls through to the new entrypoint on the Java size (see change I3f3f84a1). I've done some modest refactoring to minimize code duplication. The way we obtain a pointer to the frame is still a bit messy, but I couldn't find a really clean solution to that. Change-Id: Ia5c12f615b8c41f1c846bbf6fd6dcfe56f3e2a51
Diffstat (limited to 'WebKit/android/jni/WebCoreFrameBridge.cpp')
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.cpp218
1 files changed, 130 insertions, 88 deletions
diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp
index 181e256..4212aa2 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -193,6 +193,7 @@ struct WebFrame::JavaBrowserFrame
jweak mObj;
jweak mHistoryList; // WebBackForwardList object
jmethodID mStartLoadingResource;
+ jmethodID mMaybeSavePassword;
jmethodID mShouldInterceptRequest;
jmethodID mLoadStarted;
jmethodID mTransitionToCommitted;
@@ -238,6 +239,8 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
mJavaFrame->mHistoryList = env->NewWeakGlobalRef(historyList);
mJavaFrame->mStartLoadingResource = env->GetMethodID(clazz, "startLoadingResource",
"(ILjava/lang/String;Ljava/lang/String;Ljava/util/HashMap;[BJIZZZLjava/lang/String;Ljava/lang/String;)Landroid/webkit/LoadListener;");
+ mJavaFrame->mMaybeSavePassword = env->GetMethodID(clazz, "maybeSavePassword",
+ "([BLjava/lang/String;Ljava/lang/String;)V");
mJavaFrame->mShouldInterceptRequest =
env->GetMethodID(clazz, "shouldInterceptRequest",
"(Ljava/lang/String;)Landroid/webkit/WebResourceResponse;");
@@ -283,6 +286,7 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
env->DeleteLocalRef(clazz);
LOG_ASSERT(mJavaFrame->mStartLoadingResource, "Could not find method startLoadingResource");
+ LOG_ASSERT(mJavaFrame->mMaybeSavePassword, "Could not find method maybeSavePassword");
LOG_ASSERT(mJavaFrame->mShouldInterceptRequest, "Could not find method shouldInterceptRequest");
LOG_ASSERT(mJavaFrame->mLoadStarted, "Could not find method loadStarted");
LOG_ASSERT(mJavaFrame->mTransitionToCommitted, "Could not find method transitionToCommitted");
@@ -420,67 +424,8 @@ WebFrame::startLoadingResource(WebCore::ResourceHandle* loader,
jstring jMethodStr = NULL;
if (!method.isEmpty())
jMethodStr = WtfStringToJstring(env, method);
- 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
- // then another to copy it out of the vector and into the java byte
- // array. Instead, we copy the form data ourselves below saving a
- // memcpy.
- const WTF::Vector<WebCore::FormDataElement>& elements =
- formdata->elements();
-
- // 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;
- }
- }
-
- // Only create the byte array if there is POST data to pass up.
- // The Java code is expecting null if there is no data.
- if (size > 0) {
- // Copy the actual form data.
- jPostDataStr = env->NewByteArray(size);
- if (jPostDataStr) {
- // Write the form data to the java array.
- jbyte* bytes = env->GetByteArrayElements(jPostDataStr, NULL);
- int offset = 0;
- for (size_t i = 0; i < n; ++i) {
- const WebCore::FormDataElement& e = elements[i];
- if (e.m_type == WebCore::FormDataElement::data) {
- 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;
- }
-
+ jbyteArray jPostDataStr = getPostData(request);
jobject jHeaderMap = createJavaMapFromHTTPHeaders(env, headers);
// Convert the WebCore Cache Policy to a WebView Cache Policy.
@@ -510,7 +455,7 @@ WebFrame::startLoadingResource(WebCore::ResourceHandle* loader,
bool isUserGesture = UserGestureIndicator::processingUserGesture();
jobject jLoadListener =
- env->CallObjectMethod(obj.get(), mJavaFrame->mStartLoadingResource,
+ env->CallObjectMethod(mJavaFrame->frame(env).get(), mJavaFrame->mStartLoadingResource,
(int)loader, jUrlStr, jMethodStr, jHeaderMap,
jPostDataStr, formdata ? formdata->identifier(): 0,
cacheMode, mainResource, isUserGesture,
@@ -946,8 +891,129 @@ WebFrame::downloadStart(const std::string& url, const std::string& userAgent, co
checkException(env);
}
+void WebFrame::maybeSavePassword(WebCore::Frame* frame, const WebCore::ResourceRequest& request)
+{
+ if (request.httpMethod() != "POST")
+ return;
+
+ WTF::String username;
+ WTF::String password;
+ if (!getUsernamePasswordFromDom(frame, username, password))
+ return;
+
+ JNIEnv* env = getJNIEnv();
+ jstring jUsername = WtfStringToJstring(env, username);
+ jstring jPassword = WtfStringToJstring(env, password);
+ jbyteArray jPostData = getPostData(request);
+ if (jPostData) {
+ env->CallVoidMethod(mJavaFrame->frame(env).get(),
+ mJavaFrame->mMaybeSavePassword, jPostData, jUsername, jPassword);
+ }
+
+ env->DeleteLocalRef(jPostData);
+ env->DeleteLocalRef(jUsername);
+ env->DeleteLocalRef(jPassword);
+ checkException(env);
+}
+
+bool WebFrame::getUsernamePasswordFromDom(WebCore::Frame* frame, WTF::String& username, WTF::String& password)
+{
+ bool found = false;
+ WTF::PassRefPtr<WebCore::HTMLCollection> form = frame->document()->forms();
+ WebCore::Node* node = form->firstItem();
+ while (node && !found && !node->namespaceURI().isNull() &&
+ !node->namespaceURI().isEmpty()) {
+ const WTF::Vector<WebCore::HTMLFormControlElement*>& elements =
+ ((WebCore::HTMLFormElement*)node)->associatedElements();
+ size_t size = elements.size();
+ for (size_t i = 0; i< size && !found; i++) {
+ WebCore::HTMLFormControlElement* e = elements[i];
+ if (e->hasLocalName(WebCore::HTMLNames::inputTag)) {
+ WebCore::HTMLInputElement* input = (WebCore::HTMLInputElement*)e;
+ if (input->autoComplete() == false)
+ continue;
+ if (input->isPasswordField())
+ password = input->value();
+ else if (input->isTextField() || input->isEmailField())
+ username = input->value();
+ if (!username.isNull() && !password.isNull())
+ found = true;
+ }
+ }
+ node = form->nextItem();
+ }
+ return found;
+}
+
+jbyteArray WebFrame::getPostData(const WebCore::ResourceRequest& request)
+{
+ jbyteArray jPostDataStr = NULL;
+ WebCore::FormData* formdata = request.httpBody();
+ if (formdata) {
+ JNIEnv* env = getJNIEnv();
+ AutoJObject obj = mJavaFrame->frame(env);
+
+ // We can use the formdata->flatten() but it will result in two
+ // memcpys, first through loading up the vector with the form data
+ // then another to copy it out of the vector and into the java byte
+ // array. Instead, we copy the form data ourselves below saving a
+ // memcpy.
+ const WTF::Vector<WebCore::FormDataElement>& elements =
+ formdata->elements();
+
+ // 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;
+ }
+ }
+
+ // Only create the byte array if there is POST data to pass up.
+ // The Java code is expecting null if there is no data.
+ if (size > 0) {
+ // Copy the actual form data.
+ jPostDataStr = env->NewByteArray(size);
+ if (jPostDataStr) {
+ // Write the form data to the java array.
+ jbyte* bytes = env->GetByteArrayElements(jPostDataStr, NULL);
+ int offset = 0;
+ for (size_t i = 0; i < n; ++i) {
+ const WebCore::FormDataElement& e = elements[i];
+ if (e.m_type == WebCore::FormDataElement::data) {
+ 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;
+ }
+ return jPostDataStr;
+}
// ----------------------------------------------------------------------------
+
static void CallPolicyFunction(JNIEnv* env, jobject obj, jint func, jint decision)
{
#ifdef ANDROID_INSTRUMENT
@@ -1680,33 +1746,9 @@ static jobjectArray GetUsernamePassword(JNIEnv *env, jobject obj)
WebCore::Frame* pFrame = GET_NATIVE_FRAME(env, obj);
LOG_ASSERT(pFrame, "GetUsernamePassword must take a valid frame pointer!");
jobjectArray strArray = NULL;
-
- WTF::String username, password;
- bool found = false;
- WTF::PassRefPtr<WebCore::HTMLCollection> form = pFrame->document()->forms();
- WebCore::Node* node = form->firstItem();
- while (node && !found && !node->namespaceURI().isNull() &&
- !node->namespaceURI().isEmpty()) {
- const WTF::Vector<WebCore::HTMLFormControlElement*>& elements =
- ((WebCore::HTMLFormElement*)node)->associatedElements();
- size_t size = elements.size();
- for (size_t i = 0; i< size && !found; i++) {
- WebCore::HTMLFormControlElement* e = elements[i];
- if (e->hasLocalName(WebCore::HTMLNames::inputTag)) {
- WebCore::HTMLInputElement* input = (WebCore::HTMLInputElement*)e;
- if (input->autoComplete() == false)
- continue;
- if (input->isPasswordField())
- password = input->value();
- else if (input->isTextField() || input->isEmailField())
- username = input->value();
- if (!username.isNull() && !password.isNull())
- found = true;
- }
- }
- node = form->nextItem();
- }
- if (found) {
+ WTF::String username;
+ WTF::String password;
+ if (WebFrame::getWebFrame(pFrame)->getUsernamePasswordFromDom(pFrame, username, password)) {
jclass stringClass = env->FindClass("java/lang/String");
strArray = env->NewObjectArray(2, stringClass, NULL);
env->DeleteLocalRef(stringClass);