diff options
| author | Iain Merrick <husky@google.com> | 2010-10-18 18:03:00 +0100 |
|---|---|---|
| committer | Iain Merrick <husky@google.com> | 2010-10-20 15:40:37 +0100 |
| commit | 583f3b2e7b569ec9f88e9c481db1eb86a8c0224b (patch) | |
| tree | 671e646c2b9d028152f7ca51c4b85bd7a6f5d30a | |
| parent | db17cf1782eab2488aab0933add6c79b21639c08 (diff) | |
| download | external_webkit-583f3b2e7b569ec9f88e9c481db1eb86a8c0224b.zip external_webkit-583f3b2e7b569ec9f88e9c481db1eb86a8c0224b.tar.gz external_webkit-583f3b2e7b569ec9f88e9c481db1eb86a8c0224b.tar.bz2 | |
Implement file downloads for Chrome HTTP stack (C++ side)
Due to the way the WebView API works, downloads are handled by the Java
client code via the DownloadListener interface, so we need to toss them
over the JNI wall.
I had to refactor WebResourceRequest slightly to save the user-agent
header before it gets stripped out. I have also made it const-correct.
Test: manually checked that we can download a file, with both stacks.
See matching change in frameworks/base (I87e71deb)
Change-Id: I8130040099d02c399d42b223444b333398628235
| -rw-r--r-- | WebKit/android/WebCoreSupport/WebRequest.cpp | 24 | ||||
| -rw-r--r-- | WebKit/android/WebCoreSupport/WebRequest.h | 7 | ||||
| -rw-r--r-- | WebKit/android/WebCoreSupport/WebResourceRequest.cpp | 1 | ||||
| -rw-r--r-- | WebKit/android/WebCoreSupport/WebResourceRequest.h | 14 | ||||
| -rw-r--r-- | WebKit/android/WebCoreSupport/WebUrlLoader.cpp | 5 | ||||
| -rw-r--r-- | WebKit/android/WebCoreSupport/WebUrlLoader.h | 2 | ||||
| -rw-r--r-- | WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp | 5 | ||||
| -rw-r--r-- | WebKit/android/jni/WebCoreFrameBridge.cpp | 27 | ||||
| -rw-r--r-- | WebKit/android/jni/WebCoreFrameBridge.h | 2 |
9 files changed, 75 insertions, 12 deletions
diff --git a/WebKit/android/WebCoreSupport/WebRequest.cpp b/WebKit/android/WebCoreSupport/WebRequest.cpp index e080bcd..0e3149d 100644 --- a/WebKit/android/WebCoreSupport/WebRequest.cpp +++ b/WebKit/android/WebCoreSupport/WebRequest.cpp @@ -28,6 +28,7 @@ #include "JNIUtility.h" #include "MainThread.h" +#include "WebCoreFrameBridge.h" #include "WebRequestContext.h" #include "WebResourceRequest.h" #include "jni.h" @@ -58,14 +59,15 @@ namespace { const int kInitialReadBufSize = 32768; } -WebRequest::WebRequest(WebUrlLoaderClient* loader, WebResourceRequest webResourceRequest) +WebRequest::WebRequest(WebUrlLoaderClient* loader, const WebResourceRequest& webResourceRequest) : m_urlLoader(loader) , m_inputStream(0) , m_androidUrl(false) , m_loadState(Created) + , m_url(webResourceRequest.url()) + , m_userAgent(webResourceRequest.userAgent()) { - m_url = webResourceRequest.url(); - GURL gurl(webResourceRequest.url()); + GURL gurl(m_url); m_request = new URLRequest(gurl, this); @@ -76,14 +78,15 @@ WebRequest::WebRequest(WebUrlLoaderClient* loader, WebResourceRequest webResourc // This is a special URL for Android. Query the Java InputStream // for data and send to WebCore -WebRequest::WebRequest(WebUrlLoaderClient* loader, WebResourceRequest webResourceRequest, int inputStream) +WebRequest::WebRequest(WebUrlLoaderClient* loader, const WebResourceRequest& webResourceRequest, int inputStream) : m_urlLoader(loader) , m_androidUrl(true) , m_loadState(Created) + , m_url(webResourceRequest.url()) + , m_userAgent(webResourceRequest.userAgent()) { JNIEnv* env = JSC::Bindings::getJNIEnv(); m_inputStream = (int)env->NewGlobalRef((_jobject*)inputStream); - m_url = webResourceRequest.url(); } WebRequest::~WebRequest() @@ -340,6 +343,17 @@ void WebRequest::cancelAuth() m_request->CancelAuth(); } +void WebRequest::downloadFile(WebFrame* frame) +{ + std::string contentDisposition; + std::string mimeType; + + m_request->GetResponseHeaderByName("content-disposition", &contentDisposition); + m_request->GetMimeType(&mimeType); + + frame->downloadStart(m_request->url().spec(), m_userAgent, contentDisposition, mimeType, m_request->GetExpectedContentSize()); +} + void WebRequest::startReading() { ASSERT(m_loadState == Response || m_loadState == GotData, "StartReading in state other than RESPONSE and GOTDATA"); diff --git a/WebKit/android/WebCoreSupport/WebRequest.h b/WebKit/android/WebCoreSupport/WebRequest.h index f39be2a..e52425a 100644 --- a/WebKit/android/WebCoreSupport/WebRequest.h +++ b/WebKit/android/WebCoreSupport/WebRequest.h @@ -45,18 +45,19 @@ enum LoadState { }; class WebResourceRequest; +class WebFrame; // All methods in this class must be called on the io thread class WebRequest : public URLRequest::Delegate, public base::RefCountedThreadSafe<WebRequest> { public: - WebRequest(WebUrlLoaderClient*, WebResourceRequest); + WebRequest(WebUrlLoaderClient*, const WebResourceRequest&); // If this is an android specific url we load it with a java input stream // Used for: // - file:///android_asset // - file:///android_res // - content:// - WebRequest(WebUrlLoaderClient*, WebResourceRequest, int inputStream); + WebRequest(WebUrlLoaderClient*, const WebResourceRequest&, int inputStream); // Optional, but if used has to be called before start void AppendBytesToUpload(Vector<char>* data); @@ -73,6 +74,7 @@ public: // Methods called during a request by the UI code (via WebUrlLoaderClient). void setAuth(const string16& username, const string16& password); void cancelAuth(); + void downloadFile(WebFrame*); private: void startReading(); @@ -93,6 +95,7 @@ private: int m_inputStream; bool m_androidUrl; std::string m_url; + std::string m_userAgent; LoadState m_loadState; }; diff --git a/WebKit/android/WebCoreSupport/WebResourceRequest.cpp b/WebKit/android/WebCoreSupport/WebResourceRequest.cpp index edecf9c..8954887 100644 --- a/WebKit/android/WebCoreSupport/WebResourceRequest.cpp +++ b/WebKit/android/WebCoreSupport/WebResourceRequest.cpp @@ -74,6 +74,7 @@ WebResourceRequest::WebResourceRequest(const WebCore::ResourceRequest& resourceR m_method = resourceRequest.httpMethod().utf8().data(); m_referrer = resourceRequest.httpReferrer().utf8().data(); + m_userAgent = resourceRequest.httpUserAgent().utf8().data(); m_url = resourceRequest.url().string().utf8().data(); diff --git a/WebKit/android/WebCoreSupport/WebResourceRequest.h b/WebKit/android/WebCoreSupport/WebResourceRequest.h index 79aad39..6274624 100644 --- a/WebKit/android/WebCoreSupport/WebResourceRequest.h +++ b/WebKit/android/WebCoreSupport/WebResourceRequest.h @@ -41,22 +41,27 @@ class WebResourceRequest { public: WebResourceRequest(const WebCore::ResourceRequest&); - const std::string& method() + const std::string& method() const { return m_method; } - const std::string& referrer() + const std::string& referrer() const { return m_referrer; } - const net::HttpRequestHeaders& requestHeaders() + const std::string& userAgent() const + { + return m_userAgent; + } + + const net::HttpRequestHeaders& requestHeaders() const { return m_requestHeaders; } - const std::string& url() + const std::string& url() const { return m_url; } @@ -74,6 +79,7 @@ public: private: std::string m_method; std::string m_referrer; + std::string m_userAgent; net::HttpRequestHeaders m_requestHeaders; int m_specialAndroidFileType; std::string m_url; diff --git a/WebKit/android/WebCoreSupport/WebUrlLoader.cpp b/WebKit/android/WebCoreSupport/WebUrlLoader.cpp index 391f988..7ada817 100644 --- a/WebKit/android/WebCoreSupport/WebUrlLoader.cpp +++ b/WebKit/android/WebCoreSupport/WebUrlLoader.cpp @@ -70,6 +70,11 @@ void WebUrlLoader::cancel() m_loaderClient->cancel(); } +void WebUrlLoader::downloadFile() +{ + m_loaderClient->downloadFile(); +} + } // namespace android diff --git a/WebKit/android/WebCoreSupport/WebUrlLoader.h b/WebKit/android/WebCoreSupport/WebUrlLoader.h index a8184c8..7106ede 100644 --- a/WebKit/android/WebCoreSupport/WebUrlLoader.h +++ b/WebKit/android/WebCoreSupport/WebUrlLoader.h @@ -40,7 +40,7 @@ public: static PassRefPtr<WebUrlLoader> start(FrameLoaderClient* client, WebCore::ResourceHandle*, const WebCore::ResourceRequest&, bool sync, bool isPrivateBrowsing); virtual void cancel(); - virtual void downloadFile() {} // Not implemented yet + virtual void downloadFile(); virtual void pauseLoad(bool pause) {} // Android method, does nothing for now private: diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp index 9c91941..87a76a4 100644 --- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp +++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp @@ -182,6 +182,11 @@ bool WebUrlLoaderClient::start(bool sync, bool isPrivateBrowsing) return true; } +void WebUrlLoaderClient::downloadFile() +{ + m_request->downloadFile(m_webFrame); +} + void WebUrlLoaderClient::cancel() { m_cancelling = true; diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp index 9f5f44d..010c6df 100644 --- a/WebKit/android/jni/WebCoreFrameBridge.cpp +++ b/WebKit/android/jni/WebCoreFrameBridge.cpp @@ -212,6 +212,7 @@ struct WebFrame::JavaBrowserFrame jmethodID mGetFileSize; jmethodID mGetFile; jmethodID mDidReceiveAuthenticationChallenge; + jmethodID mDownloadStart; AutoJObject frame(JNIEnv* env) { return getRealObject(env, mObj); } @@ -273,6 +274,8 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page* mJavaFrame->mGetFile = env->GetMethodID(clazz, "getFile", "(Ljava/lang/String;[BII)I"); mJavaFrame->mDidReceiveAuthenticationChallenge = env->GetMethodID(clazz, "didReceiveAuthenticationChallenge", "(ILjava/lang/String;Ljava/lang/String;Z)V"); + mJavaFrame->mDownloadStart = env->GetMethodID(clazz, "downloadStart", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;J)V"); LOG_ASSERT(mJavaFrame->mInputStreamForAndroidResource, "Could not find method inputStreamForAndroidResource"); LOG_ASSERT(mJavaFrame->mStartLoadingResource, "Could not find method startLoadingResource"); @@ -296,6 +299,7 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page* LOG_ASSERT(mJavaFrame->mGetFileSize, "Could not find method getFileSize"); LOG_ASSERT(mJavaFrame->mGetFile, "Could not find method getFile"); LOG_ASSERT(mJavaFrame->mDidReceiveAuthenticationChallenge, "Could not find method didReceiveAuthenticationChallenge"); + LOG_ASSERT(mJavaFrame->mDownloadStart, "Could not find method downloadStart"); mUserAgent = WTF::String(); mUserInitiatedAction = false; @@ -912,6 +916,29 @@ WebFrame::didReceiveAuthenticationChallenge(WebUrlLoaderClient* client, const st checkException(env); } +void +WebFrame::downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, long long contentLength) +{ +#ifdef ANDROID_INSTRUMENT + TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); +#endif + JNIEnv* env = getJNIEnv(); + jstring jUrl = env->NewStringUTF(url.c_str()); + jstring jUserAgent = env->NewStringUTF(userAgent.c_str()); + jstring jContentDisposition = env->NewStringUTF(contentDisposition.c_str()); + jstring jMimetype = env->NewStringUTF(mimetype.c_str()); + + env->CallVoidMethod(mJavaFrame->frame(env).get(), + mJavaFrame->mDownloadStart, jUrl, jUserAgent, jContentDisposition, jMimetype, contentLength); + + env->DeleteLocalRef(jUrl); + env->DeleteLocalRef(jUserAgent); + env->DeleteLocalRef(jContentDisposition); + env->DeleteLocalRef(jMimetype); + checkException(env); +} + + // ---------------------------------------------------------------------------- static void CallPolicyFunction(JNIEnv* env, jobject obj, jint func, jint decision) { diff --git a/WebKit/android/jni/WebCoreFrameBridge.h b/WebKit/android/jni/WebCoreFrameBridge.h index cbf55c4..9e3b5db 100644 --- a/WebKit/android/jni/WebCoreFrameBridge.h +++ b/WebKit/android/jni/WebCoreFrameBridge.h @@ -113,6 +113,8 @@ class WebFrame : public WebCoreRefObject { void didReceiveAuthenticationChallenge(WebUrlLoaderClient*, const std::string& host, const std::string& realm, bool useCachedCredentials); + void downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, long long contentLength); + /** * When the user initiates an action (via trackball, key-press, or touch), * we set mUserInitiatedAction to true. If a load happens due to this click, |
