summaryrefslogtreecommitdiffstats
path: root/WebKit
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-10-18 18:03:00 +0100
committerIain Merrick <husky@google.com>2010-10-20 15:40:37 +0100
commit583f3b2e7b569ec9f88e9c481db1eb86a8c0224b (patch)
tree671e646c2b9d028152f7ca51c4b85bd7a6f5d30a /WebKit
parentdb17cf1782eab2488aab0933add6c79b21639c08 (diff)
downloadexternal_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
Diffstat (limited to 'WebKit')
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.cpp24
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.h7
-rw-r--r--WebKit/android/WebCoreSupport/WebResourceRequest.cpp1
-rw-r--r--WebKit/android/WebCoreSupport/WebResourceRequest.h14
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoader.cpp5
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoader.h2
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp5
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.cpp27
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.h2
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,