diff options
-rw-r--r-- | WebKit/android/WebCoreSupport/WebRequest.cpp | 68 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebRequest.h | 11 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebResourceRequest.cpp | 34 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebResourceRequest.h | 11 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebResponse.cpp | 1 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebUrlLoader.cpp | 19 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebUrlLoader.h | 7 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp | 30 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebUrlLoaderClient.h | 9 | ||||
-rw-r--r-- | WebKit/android/jni/WebCoreFrameBridge.cpp | 15 | ||||
-rw-r--r-- | WebKit/android/jni/WebCoreFrameBridge.h | 2 |
11 files changed, 187 insertions, 20 deletions
diff --git a/WebKit/android/WebCoreSupport/WebRequest.cpp b/WebKit/android/WebCoreSupport/WebRequest.cpp index 8c718d8..5e760ae 100644 --- a/WebKit/android/WebCoreSupport/WebRequest.cpp +++ b/WebKit/android/WebCoreSupport/WebRequest.cpp @@ -26,9 +26,11 @@ #include "config.h" #include "WebRequest.h" +#include "JNIUtility.h" #include "MainThread.h" #include "WebRequestContext.h" #include "WebResourceRequest.h" +#include "jni.h" #include <net/base/data_url.h> #include <net/base/io_buffer.h> @@ -40,10 +42,7 @@ extern android::AssetManager* globalAssetManager(); // TODO: -// - Get gmail log in to work // - Finish the file upload. Testcase is mobile buzz -// - Handle fails better -// - Check the string conversion work for more than the general case // - Add network throttle needed by Android plugins namespace android { @@ -54,8 +53,12 @@ namespace { WebRequest::WebRequest(WebUrlLoaderClient* loader, WebResourceRequest webResourceRequest) : m_urlLoader(loader) + , m_inputStream(0) + , m_androidUrl(false) { + m_url = webResourceRequest.url(); GURL gurl(webResourceRequest.url()); + m_request = new URLRequest(gurl, this); m_request->SetExtraRequestHeaders(webResourceRequest.requestHeaders()); @@ -63,8 +66,23 @@ WebRequest::WebRequest(WebUrlLoaderClient* loader, WebResourceRequest webResourc m_request->set_method(webResourceRequest.method()); } +// 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) + : m_urlLoader(loader) + , m_request(0) + , m_androidUrl(true) +{ + JNIEnv* env = JSC::Bindings::getJNIEnv(); + m_inputStream = (int)env->NewGlobalRef((_jobject*)inputStream); + m_url = webResourceRequest.url(); +} + WebRequest::~WebRequest() { + JNIEnv* env = JSC::Bindings::getJNIEnv(); + if (m_inputStream) + env->DeleteGlobalRef((_jobject*)m_inputStream); } void WebRequest::finish(bool success) @@ -89,6 +107,9 @@ void WebRequest::AppendBytesToUpload(const char* bytes, int bytesLen) void WebRequest::start(bool isPrivateBrowsing) { + if (m_androidUrl) + return handleAndroidURL(); + // Handle data urls before we send it off to the http stack if (m_request->url().SchemeIs("data")) return handleDataURL(m_request->url()); @@ -116,6 +137,47 @@ void WebRequest::cancel() finish(true); } +void WebRequest::handleAndroidURL() +{ + JNIEnv* env = JSC::Bindings::getJNIEnv(); + if (m_inputStream == 0) { + WebResponse webResponse(m_url, "", 0, "", 0); + LoaderData* loaderData = new LoaderData(m_urlLoader, webResponse); + m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didFail, loaderData); + return; + } + + WebResponse webResponse(m_url, "", 0, "", 200); + LoaderData* loaderResponse = new LoaderData(m_urlLoader, webResponse); + m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveResponse, loaderResponse); + + int size = 0; + jclass bridgeClass = env->FindClass("android/webkit/BrowserFrame"); + jmethodID method = env->GetStaticMethodID(bridgeClass, "readFromStream", "(Ljava/io/InputStream;[B)I"); + + jbyteArray jb = env->NewByteArray(kInitialReadBufSize); + do { + size = (int)env->CallStaticIntMethod(bridgeClass, method, m_inputStream, jb); + if (size < 0) // -1 is EOF + break; + + // data is deleted in WebUrlLoaderClient::didReceiveAndroidFileData + // data is sent to the webcore thread + std::vector<char>* data = new std::vector<char>(); + data->reserve(size); + env->GetByteArrayRegion(jb, 0, size, (jbyte*)&data->front()); + + // Passes ownership of data + LoaderData* loaderData = new LoaderData(m_urlLoader, data, size); + m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveAndroidFileData, loaderData); + } while (true); + + env->DeleteLocalRef(jb); + env->DeleteLocalRef(bridgeClass); + + finish(true); +} + void WebRequest::handleDataURL(GURL url) { OwnPtr<std::string*> data(new std::string); diff --git a/WebKit/android/WebCoreSupport/WebRequest.h b/WebKit/android/WebCoreSupport/WebRequest.h index dc53ca6..b6b3ae2 100644 --- a/WebKit/android/WebCoreSupport/WebRequest.h +++ b/WebKit/android/WebCoreSupport/WebRequest.h @@ -42,6 +42,13 @@ class WebRequest : public URLRequest::Delegate, public base::RefCountedThreadSaf public: WebRequest(WebUrlLoaderClient*, 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); + // Optional, but if used has to be called before start void AppendBytesToUpload(const char* bytes, int bytesLen); @@ -62,6 +69,7 @@ private: virtual ~WebRequest(); void handleDataURL(GURL); void handleBrowserURL(GURL); + void handleAndroidURL(); void finish(bool success); // Not owned @@ -69,6 +77,9 @@ private: OwnPtr<URLRequest> m_request; scoped_refptr<net::IOBuffer> m_networkBuffer; + int m_inputStream; + bool m_androidUrl; + std::string m_url; }; } // namespace android diff --git a/WebKit/android/WebCoreSupport/WebResourceRequest.cpp b/WebKit/android/WebCoreSupport/WebResourceRequest.cpp index 5c7410c..f357119 100644 --- a/WebKit/android/WebCoreSupport/WebResourceRequest.cpp +++ b/WebKit/android/WebCoreSupport/WebResourceRequest.cpp @@ -31,6 +31,17 @@ #include <base/string_util.h> #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) @@ -64,7 +75,30 @@ WebResourceRequest::WebResourceRequest(const WebCore::ResourceRequest& resourceR m_method = resourceRequest.httpMethod().utf8().data(); m_referrer = resourceRequest.httpReferrer().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 diff --git a/WebKit/android/WebCoreSupport/WebResourceRequest.h b/WebKit/android/WebCoreSupport/WebResourceRequest.h index 7064176..6880340 100644 --- a/WebKit/android/WebCoreSupport/WebResourceRequest.h +++ b/WebKit/android/WebCoreSupport/WebResourceRequest.h @@ -60,10 +60,21 @@ public: return m_url; } + const bool isAndroidUrl() + { + return m_specialAndroidFileType != 0; + } + + const int androidFileType() + { + return m_specialAndroidFileType; + } + private: std::string m_method; std::string m_referrer; net::HttpRequestHeaders m_requestHeaders; + int m_specialAndroidFileType; std::string m_url; }; diff --git a/WebKit/android/WebCoreSupport/WebResponse.cpp b/WebKit/android/WebCoreSupport/WebResponse.cpp index fcd2127..cb10cba 100644 --- a/WebKit/android/WebCoreSupport/WebResponse.cpp +++ b/WebKit/android/WebCoreSupport/WebResponse.cpp @@ -57,6 +57,7 @@ WebResponse::WebResponse(URLRequest* request) WebResponse::WebResponse(const std::string &url, const std::string &mimeType, const long long length, const std::string &encoding, const int httpStatusCode) : m_encoding(encoding) , m_httpStatusCode(httpStatusCode) + , m_httpStatusText("") , m_length(length) , m_mime(mimeType) , m_url(url) diff --git a/WebKit/android/WebCoreSupport/WebUrlLoader.cpp b/WebKit/android/WebCoreSupport/WebUrlLoader.cpp index 4b815c6..cda02dd 100644 --- a/WebKit/android/WebCoreSupport/WebUrlLoader.cpp +++ b/WebKit/android/WebCoreSupport/WebUrlLoader.cpp @@ -27,14 +27,15 @@ #include "WebUrlLoader.h" +#include "FrameLoaderClientAndroid.h" #include "WebUrlLoaderClient.h" namespace android { // on main thread -WebUrlLoader::WebUrlLoader(WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest) +WebUrlLoader::WebUrlLoader(WebFrame* webFrame, WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest) { - m_loaderClient = new WebUrlLoaderClient(resourceHandle, resourceRequest); + m_loaderClient = new WebUrlLoaderClient(webFrame, resourceHandle, resourceRequest); } // on main thread @@ -42,17 +43,19 @@ WebUrlLoader::~WebUrlLoader() { } -PassRefPtr<WebUrlLoader> WebUrlLoader::start(WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest, bool isSync, bool isPrivateBrowsing) +PassRefPtr<WebUrlLoader> WebUrlLoader::start(FrameLoaderClient* client, WebCore::ResourceHandle* resourceHandle, + const WebCore::ResourceRequest& resourceRequest, bool isSync, bool isPrivateBrowsing) { - RefPtr<WebUrlLoader> loader = WebUrlLoader::create(resourceHandle, resourceRequest); + FrameLoaderClientAndroid* clientAndroid = static_cast<FrameLoaderClientAndroid*> (client); + RefPtr<WebUrlLoader> loader = WebUrlLoader::create(clientAndroid->webFrame(), resourceHandle, resourceRequest); loader->m_loaderClient->start(isSync, isPrivateBrowsing); return loader.release(); } -PassRefPtr<WebUrlLoader> WebUrlLoader::create(WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest) +PassRefPtr<WebUrlLoader> WebUrlLoader::create(WebFrame* webFrame, WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest) { - return adoptRef(new WebUrlLoader(resourceHandle, resourceRequest)); + return adoptRef(new WebUrlLoader(webFrame, resourceHandle, resourceRequest)); } // on main thread @@ -69,9 +72,9 @@ namespace WebCore { // static // TODO: Implement sync requests PassRefPtr<ResourceLoaderAndroid> ResourceLoaderAndroid::start(WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest, - FrameLoaderClient* /*client*/, bool /*isMainResource*/, bool isSync, bool isPrivateBrowsing) + FrameLoaderClient* client, bool /*isMainResource*/, bool isSync, bool isPrivateBrowsing) { - return android::WebUrlLoader::start(resourceHandle, resourceRequest, isSync, isPrivateBrowsing); + return android::WebUrlLoader::start(client, resourceHandle, resourceRequest, isSync, isPrivateBrowsing); } // static diff --git a/WebKit/android/WebCoreSupport/WebUrlLoader.h b/WebKit/android/WebCoreSupport/WebUrlLoader.h index c465b66..a8184c8 100644 --- a/WebKit/android/WebCoreSupport/WebUrlLoader.h +++ b/WebKit/android/WebCoreSupport/WebUrlLoader.h @@ -32,19 +32,20 @@ using namespace WebCore; namespace android { class WebUrlLoaderClient; +class WebFrame; class WebUrlLoader : public ResourceLoaderAndroid { public: virtual ~WebUrlLoader(); - static PassRefPtr<WebUrlLoader> start(WebCore::ResourceHandle*, const WebCore::ResourceRequest&, bool sync, bool isPrivateBrowsing); + 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 pauseLoad(bool pause) {} // Android method, does nothing for now private: - WebUrlLoader(WebCore::ResourceHandle*, const WebCore::ResourceRequest&); - static PassRefPtr<WebUrlLoader> create(WebCore::ResourceHandle*, const WebCore::ResourceRequest&); + WebUrlLoader(WebFrame*, WebCore::ResourceHandle*, const WebCore::ResourceRequest&); + static PassRefPtr<WebUrlLoader> create(WebFrame*, WebCore::ResourceHandle*, const WebCore::ResourceRequest&); OwnPtr<WebUrlLoaderClient> m_loaderClient; }; diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp index e3ee14c..80b1dbd 100644 --- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp +++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp @@ -30,6 +30,7 @@ #include "ResourceHandle.h" #include "ResourceHandleClient.h" #include "ResourceResponse.h" +#include "WebCoreFrameBridge.h" #include "WebRequest.h" #include "WebResourceRequest.h" @@ -95,17 +96,22 @@ bool WebUrlLoaderClient::isActive() const return true; } -WebUrlLoaderClient::WebUrlLoaderClient(WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest) +WebUrlLoaderClient::WebUrlLoaderClient(WebFrame* webFrame, WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest) : m_resourceHandle(resourceHandle) , m_cancelling(false) , m_sync(false) , m_finished(false) { WebResourceRequest webResourceRequest(resourceRequest); + if (webResourceRequest.isAndroidUrl()) { + int inputStream = webFrame->inputStreamForAndroidResource(webResourceRequest.url().c_str(), webResourceRequest.androidFileType()); + m_request = new WebRequest(this, webResourceRequest, inputStream); + m_request->AddRef(); // Matched by ReleaseSoon in destructor + return; + } m_request = new WebRequest(this, webResourceRequest); m_request->AddRef(); // Matched by ReleaseSoon in destructor - base::Thread* thread = ioThread(); // Set uploads before start is called on the request if (resourceRequest.httpBody() && !(webResourceRequest.method() == "GET" || webResourceRequest.method() == "HEAD")) { @@ -245,18 +251,32 @@ void WebUrlLoaderClient::didReceiveData(void* data) // For data url's void WebUrlLoaderClient::didReceiveDataUrl(void* data) { - OwnPtr<LoaderData> ld(static_cast<LoaderData*>(data)); - const WebUrlLoaderClient* loader = ld->loader; + OwnPtr<LoaderData> loaderData(static_cast<LoaderData*>(data)); + const WebUrlLoaderClient* loader = loaderData->loader; if (!loader->isActive()) return; - std::string* str = ld->string.get(); + std::string* str = loaderData->string.get(); // didReceiveData will take a copy of the data loader->m_resourceHandle->client()->didReceiveData(loader->m_resourceHandle.get(), str->data(), str->size(), str->size()); } // static - on main thread +// For special android files +void WebUrlLoaderClient::didReceiveAndroidFileData(void* data) +{ + OwnPtr<LoaderData> loaderData(static_cast<LoaderData*>(data)); + const WebUrlLoaderClient* loader = loaderData->loader; + + if (!loader->isActive()) + return; + + // didReceiveData will take a copy of the data + loader->m_resourceHandle->client()->didReceiveData(loader->m_resourceHandle.get(), &(loaderData->vector->front()), loaderData->size, loaderData->size); +} + +// static - on main thread void WebUrlLoaderClient::didFail(void* data) { OwnPtr<LoaderData> loaderData(static_cast<LoaderData*>(data)); diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h index a761f15..1506e5e 100644 --- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h +++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h @@ -48,6 +48,7 @@ class IOBuffer; namespace android { +class WebFrame; class WebRequest; // This class handles communication between the IO thread where loading happens @@ -59,7 +60,7 @@ class WebRequest; // - Implement pauseLoad class WebUrlLoaderClient { public: - WebUrlLoaderClient(WebCore::ResourceHandle*, const WebCore::ResourceRequest&); + WebUrlLoaderClient(WebFrame*, WebCore::ResourceHandle*, const WebCore::ResourceRequest&); ~WebUrlLoaderClient(); // Called from WebCore, will be forwarded to the IO thread @@ -78,6 +79,7 @@ public: static void didReceiveResponse(void*); static void didReceiveData(void*); static void didReceiveDataUrl(void*); + static void didReceiveAndroidFileData(void*); static void didFinishLoading(void*); static void didFail(void*); static void willSendRequest(void*); @@ -117,6 +119,7 @@ struct LoaderData { WebResponse webResponse; const int size; OwnPtr<std::string*> string; + OwnPtr<std::vector<char> > vector; LoaderData(WebUrlLoaderClient* l) : buffer(0), loader(l), size(0) { @@ -134,6 +137,10 @@ struct LoaderData { { } + LoaderData(WebUrlLoaderClient* l, std::vector<char>* data, const int s) : buffer(0), loader(l), size(s), vector(data) + { + } + ~LoaderData(); }; diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp index 52f1551..0e8a7a2 100644 --- a/WebKit/android/jni/WebCoreFrameBridge.cpp +++ b/WebKit/android/jni/WebCoreFrameBridge.cpp @@ -184,6 +184,7 @@ struct WebFrame::JavaBrowserFrame { jweak mObj; jweak mHistoryList; // WebBackForwardList object + jmethodID mInputStreamForAndroidResource; jmethodID mStartLoadingResource; jmethodID mLoadStarted; jmethodID mTransitionToCommitted; @@ -225,6 +226,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->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", @@ -263,6 +265,7 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page* mJavaFrame->mGetFileSize = env->GetMethodID(clazz, "getFileSize", "(Ljava/lang/String;)I"); mJavaFrame->mGetFile = env->GetMethodID(clazz, "getFile", "(Ljava/lang/String;[BII)I"); + LOG_ASSERT(mJavaFrame->mInputStreamForAndroidResource, "Could not find method inputStreamForAndroidResource"); LOG_ASSERT(mJavaFrame->mStartLoadingResource, "Could not find method startLoadingResource"); LOG_ASSERT(mJavaFrame->mLoadStarted, "Could not find method loadStarted"); LOG_ASSERT(mJavaFrame->mTransitionToCommitted, "Could not find method transitionToCommitted"); @@ -363,6 +366,18 @@ private: int m_size; }; +int WebFrame::inputStreamForAndroidResource(const char* url, int type) +{ + JNIEnv* env = getJNIEnv(); + AutoJObject obj = mJavaFrame->frame(env); + jstring jUrlStr = env->NewStringUTF(url); + + jobject jInputStream = env->CallObjectMethod(obj.get(), mJavaFrame->mInputStreamForAndroidResource, jUrlStr, type); + env->DeleteLocalRef(jUrlStr); + + return (int)jInputStream; +} + PassRefPtr<WebCore::ResourceLoaderAndroid> WebFrame::startLoadingResource(WebCore::ResourceHandle* loader, const WebCore::ResourceRequest& request, diff --git a/WebKit/android/jni/WebCoreFrameBridge.h b/WebKit/android/jni/WebCoreFrameBridge.h index 5fd4da9..07bdc41 100644 --- a/WebKit/android/jni/WebCoreFrameBridge.h +++ b/WebKit/android/jni/WebCoreFrameBridge.h @@ -58,6 +58,8 @@ class WebFrame : public WebCoreRefObject { // helper function static WebFrame* getWebFrame(const WebCore::Frame* frame); + int inputStreamForAndroidResource(const char* url, int type); + virtual PassRefPtr<WebCore::ResourceLoaderAndroid> startLoadingResource(WebCore::ResourceHandle*, const WebCore::ResourceRequest& request, bool mainResource, bool synchronous); |