OSDN Git Service

Add support for file uploads in WebKit
authorKristian Monsen <kristianm@google.com>
Mon, 1 Nov 2010 14:28:16 +0000 (14:28 +0000)
committerKristian Monsen <kristianm@google.com>
Thu, 4 Nov 2010 12:05:17 +0000 (12:05 +0000)
This also moves some of the android file handling to Java so it is not
duplicated in both places.

This CL needs https://android-git.corp.google.com/g/#change,77400
in frameworks/base

Change-Id: I90c1726e6c323a9de3fd64f2e6feef4b64171053

WebKit/android/WebCoreSupport/WebRequest.cpp
WebKit/android/WebCoreSupport/WebRequest.h
WebKit/android/WebCoreSupport/WebResourceRequest.cpp
WebKit/android/WebCoreSupport/WebResourceRequest.h
WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
WebKit/android/jni/WebCoreFrameBridge.cpp
WebKit/android/jni/WebCoreFrameBridge.h

index ef09ff7..f21c1a2 100644 (file)
@@ -130,10 +130,18 @@ void WebRequest::finish(bool success)
     m_urlLoader = 0;
 }
 
-void WebRequest::AppendBytesToUpload(WTF::Vector<char>* data)
+void WebRequest::appendFileToUpload(std::string filename)
+{
+    // AppendFileToUpload is only valid before calling start
+    ASSERT(m_loadState == Created, "appendFileToUpload called on a WebRequest not in CREATED state: (%s)", m_url.c_str());
+    FilePath filePath(filename);
+    m_request->AppendFileToUpload(filePath);
+}
+
+void WebRequest::appendBytesToUpload(WTF::Vector<char>* data)
 {
     // AppendBytesToUpload is only valid before calling start
-    ASSERT(m_loadState == Created, "Start called on a WebRequest not in CREATED state: (%s)", m_url.c_str());
+    ASSERT(m_loadState == Created, "appendBytesToUpload called on a WebRequest not in CREATED state: (%s)", m_url.c_str());
     m_request->AppendBytesToUpload(data->data(), data->size());
     delete data;
 }
index 1f73d2a..c82096e 100644 (file)
@@ -60,7 +60,8 @@ public:
     WebRequest(WebUrlLoaderClient*, const WebResourceRequest&, int inputStream);
 
     // Optional, but if used has to be called before start
-    void AppendBytesToUpload(Vector<char>* data);
+    void appendBytesToUpload(Vector<char>* data);
+    void appendFileToUpload(std::string filename);
 
     void start(bool isPrivateBrowsing);
     void cancel();
index 8954887..e8fb520 100644 (file)
 
 #include <wtf/text/CString.h>
 
-namespace {
-const std::string android_asset("file:///android_asset/");
-const std::string android_res("file:///android_res/");
-const std::string android_content("content:");
-
-// Matched in BrowserFrame.java
-const int RESOURCE = 1;
-const int ASSET = 2;
-const int CONTENT = 3;
-}
-
 namespace android {
 
 WebResourceRequest::WebResourceRequest(const WebCore::ResourceRequest& resourceRequest)
@@ -77,28 +66,6 @@ WebResourceRequest::WebResourceRequest(const WebCore::ResourceRequest& resourceR
     m_userAgent = resourceRequest.httpUserAgent().utf8().data();
 
     m_url = resourceRequest.url().string().utf8().data();
-
-    // Android has special file urls, resolve these
-    m_specialAndroidFileType = 0;
-    std::string::size_type loc = m_url.find(android_asset);
-    if (loc != std::string::npos && loc == 0) {
-        m_url = m_url.erase(0, android_asset.length());
-        m_specialAndroidFileType = ASSET;
-        return;
-    }
-
-    loc = m_url.find(android_res);
-    if (loc != std::string::npos && loc == 0) {
-        m_url = m_url.erase(0, android_res.length());
-        m_specialAndroidFileType = RESOURCE;
-        return;
-    }
-
-    loc = m_url.find(android_content);
-    if (loc != std::string::npos && loc == 0) {
-        m_specialAndroidFileType = CONTENT;
-        return;
-    }
 }
 
 } // namespace android
index 6274624..d0c7f90 100644 (file)
@@ -66,22 +66,11 @@ public:
         return m_url;
     }
 
-    bool isAndroidUrl() const
-    {
-        return m_specialAndroidFileType != 0;
-    }
-
-    int androidFileType() const
-    {
-        return m_specialAndroidFileType;
-    }
-
 private:
     std::string m_method;
     std::string m_referrer;
     std::string m_userAgent;
     net::HttpRequestHeaders m_requestHeaders;
-    int m_specialAndroidFileType;
     std::string m_url;
 };
 
index 8925fbc..6d8e192 100644 (file)
 #include "WebRequest.h"
 #include "WebResourceRequest.h"
 
+#include <wtf/text/CString.h>
+
+namespace {
+const char* androidAsset = "file:///android_asset/";
+const char* androidResource = "file:///android_res/";
+const char* androidContent = "content:";
+const int androidAssetLen = strlen(androidAsset);
+const int androidResourceLen = strlen(androidResource);
+const int androidContentLen = strlen(androidContent);
+
+bool isAndroidUrl(const std::string& url)
+{
+    if (!url.compare(0, androidAssetLen, androidAsset))
+        return true;
+
+    if (!url.compare(0, androidResourceLen, androidResource))
+        return true;
+
+    if (!url.compare(0, androidContentLen, androidContent))
+        return true;
+
+    return false;
+}
+}
+
 namespace android {
 
 base::Thread* WebUrlLoaderClient::ioThread()
@@ -93,8 +118,8 @@ WebUrlLoaderClient::WebUrlLoaderClient(WebFrame* webFrame, WebCore::ResourceHand
     , m_finished(false)
 {
     WebResourceRequest webResourceRequest(resourceRequest);
-    if (webResourceRequest.isAndroidUrl()) {
-        int inputStream = webFrame->inputStreamForAndroidResource(webResourceRequest.url().c_str(), webResourceRequest.androidFileType());
+    if (isAndroidUrl(webResourceRequest.url())) {
+        int inputStream = webFrame->inputStreamForAndroidResource(webResourceRequest.url().c_str());
         m_request = new WebRequest(this, webResourceRequest, inputStream);
         return;
     }
@@ -107,6 +132,7 @@ WebUrlLoaderClient::WebUrlLoaderClient(WebFrame* webFrame, WebCore::ResourceHand
         Vector<FormDataElement> elements = resourceRequest.httpBody()->elements();
         for (iter = elements.begin(); iter != elements.end(); iter++) {
             FormDataElement element = *iter;
+
             switch (element.m_type) {
             case FormDataElement::data:
                 if (!element.m_data.isEmpty()) {
@@ -115,22 +141,29 @@ WebUrlLoaderClient::WebUrlLoaderClient(WebFrame* webFrame, WebCore::ResourceHand
                     base::Thread* thread = ioThread();
                     if (thread) {
                         Vector<char>* data = new Vector<char>(element.m_data);
-                        thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::AppendBytesToUpload, data));
+                        thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::appendBytesToUpload, data));
                     }
                 }
                 break;
-#if ENABLE(BLOB)
             case FormDataElement::encodedFile:
-                if (element.m_fileLength == -1)
-                    continue; // TODO: Not supporting directories yet
-                else {
-                    // TODO: Add fileuploads after Google log-in is fixed.
-                    // Chrome code is here: webkit/glue/weburlloader_impl.cc:391
+                {
+                    // Chromium check if it is a directory by checking
+                    // element.m_fileLength, that doesn't work in Android
+                    std::string filename = element.m_filename.utf8().data();
+                    if (filename.size() > 0) {
+                        base::Thread* thread = ioThread();
+                        if (thread)
+                            thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::appendFileToUpload, filename));
+                    }
                 }
                 break;
-#endif
+#if ENABLE(BLOB)
+            case FormDataElement::encodedBlob:
+                LOG_ASSERT(false, "Unexpected use of FormDataElement::encodedBlob");
+                break;
+#endif // ENABLE(BLOB)
             default:
-                // TODO: Add a warning/DCHECK/assert here, should never happen
+                LOG_ASSERT(false, "Unexpected default case in WebUrlLoaderClient.cpp");
                 break;
             }
         }
index 9cd5c79..c4d07a4 100644 (file)
@@ -234,7 +234,7 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page*
     mJavaFrame = new JavaBrowserFrame;
     mJavaFrame->mObj = env->NewWeakGlobalRef(obj);
     mJavaFrame->mHistoryList = env->NewWeakGlobalRef(historyList);
-    mJavaFrame->mInputStreamForAndroidResource = env->GetMethodID(clazz, "inputStreamForAndroidResource", "(Ljava/lang/String;I)Ljava/io/InputStream;");
+    mJavaFrame->mInputStreamForAndroidResource = env->GetMethodID(clazz, "inputStreamForAndroidResource", "(Ljava/lang/String;)Ljava/io/InputStream;");
     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->mLoadStarted = env->GetMethodID(clazz, "loadStarted",
@@ -382,13 +382,13 @@ private:
     int m_size;
 };
 
-int WebFrame::inputStreamForAndroidResource(const char* url, int type)
+int WebFrame::inputStreamForAndroidResource(const char* url)
 {
     JNIEnv* env = getJNIEnv();
     AutoJObject obj = mJavaFrame->frame(env);
     jstring jUrlStr = env->NewStringUTF(url);
 
-    jobject jInputStream = env->CallObjectMethod(obj.get(), mJavaFrame->mInputStreamForAndroidResource, jUrlStr, type);
+    jobject jInputStream = env->CallObjectMethod(obj.get(), mJavaFrame->mInputStreamForAndroidResource, jUrlStr);
     env->DeleteLocalRef(jUrlStr);
 
     return (int)jInputStream;
index 9e3b5db..2d2b571 100644 (file)
@@ -60,7 +60,7 @@ class WebFrame : public WebCoreRefObject {
     // helper function
     static WebFrame* getWebFrame(const WebCore::Frame* frame);
 
-    int inputStreamForAndroidResource(const char* url, int type);
+    int inputStreamForAndroidResource(const char* url);
 
     virtual PassRefPtr<WebCore::ResourceLoaderAndroid> startLoadingResource(WebCore::ResourceHandle*,
             const WebCore::ResourceRequest& request, bool mainResource,