summaryrefslogtreecommitdiffstats
path: root/WebKit/android
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/android')
-rw-r--r--WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp3
-rw-r--r--WebKit/android/WebCoreSupport/ResourceLoaderAndroid.cpp2
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.cpp29
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.h2
-rw-r--r--WebKit/android/WebCoreSupport/WebRequestContext.cpp80
-rw-r--r--WebKit/android/WebCoreSupport/WebRequestContext.h14
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoader.cpp8
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoader.h2
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp76
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.h30
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.cpp15
-rw-r--r--WebKit/android/jni/WebSettings.cpp9
-rw-r--r--WebKit/android/jni/WebViewCore.cpp56
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp23
-rw-r--r--WebKit/android/nav/CacheBuilder.h1
-rw-r--r--WebKit/android/nav/CachedLayer.cpp25
-rw-r--r--WebKit/android/nav/CachedLayer.h6
-rw-r--r--WebKit/android/nav/CachedRoot.h5
-rw-r--r--WebKit/android/nav/WebView.cpp13
19 files changed, 295 insertions, 104 deletions
diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
index f5b8a20..95673d7 100644
--- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
@@ -775,7 +775,8 @@ bool FrameLoaderClientAndroid::canShowMIMEType(const String& mimeType) const {
&& m_frame->settings()->arePluginsEnabled()
&& PluginDatabase::installedPlugins()->isMIMETypeRegistered(
mimeType)) ||
- DOMImplementation::isTextMIMEType(mimeType) ||
+ (DOMImplementation::isTextMIMEType(mimeType) &&
+ !mimeType.startsWith("text/vnd")) ||
DOMImplementation::isXMLMIMEType(mimeType))
return true;
return false;
diff --git a/WebKit/android/WebCoreSupport/ResourceLoaderAndroid.cpp b/WebKit/android/WebCoreSupport/ResourceLoaderAndroid.cpp
index 2b2ad95..8872a52 100644
--- a/WebKit/android/WebCoreSupport/ResourceLoaderAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/ResourceLoaderAndroid.cpp
@@ -36,7 +36,7 @@ using namespace android;
namespace WebCore {
PassRefPtr<ResourceLoaderAndroid> ResourceLoaderAndroid::start(
- ResourceHandle* handle, const ResourceRequest& request, FrameLoaderClient* client, bool isMainResource, bool isSync)
+ ResourceHandle* handle, const ResourceRequest& request, FrameLoaderClient* client, bool isMainResource, bool isSync, bool /*isPrivateBrowsing*/)
{
FrameLoaderClientAndroid* clientAndroid = static_cast<FrameLoaderClientAndroid*> (client);
return clientAndroid->webFrame()->startLoadingResource(handle, request, isMainResource, isSync);
diff --git a/WebKit/android/WebCoreSupport/WebRequest.cpp b/WebKit/android/WebCoreSupport/WebRequest.cpp
index 4030160..9118baf 100644
--- a/WebKit/android/WebCoreSupport/WebRequest.cpp
+++ b/WebKit/android/WebCoreSupport/WebRequest.cpp
@@ -49,7 +49,9 @@ namespace {
const int kInitialReadBufSize = 32768;
}
-WebRequest::WebRequest(WebUrlLoaderClient* loader, WebResourceRequest webResourceRequest) : m_urlLoader(loader), m_request(0)
+WebRequest::WebRequest(WebUrlLoaderClient* loader, WebResourceRequest webResourceRequest)
+ : m_urlLoader(loader)
+ , m_request(0)
{
GURL gurl(webResourceRequest.url());
m_request = new URLRequest(gurl, this);
@@ -67,11 +69,11 @@ void WebRequest::finish(bool success)
{
if (success) {
LoaderData* loaderData = new LoaderData(m_urlLoader);
- callOnMainThread(WebUrlLoaderClient::didFinishLoading, loaderData);
+ m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didFinishLoading, loaderData);
} else {
WebResponse webResponse(m_request.get());
LoaderData* loaderData = new LoaderData(m_urlLoader, webResponse);
- callOnMainThread(WebUrlLoaderClient::didFail, loaderData);
+ m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didFail, loaderData);
}
m_networkBuffer = 0;
m_request = 0;
@@ -82,13 +84,17 @@ void WebRequest::AppendBytesToUpload(const char* bytes, int bytesLen)
m_request->AppendBytesToUpload(bytes, bytesLen);
}
-void WebRequest::start()
+void WebRequest::start(bool isPrivateBrowsing)
{
// Handle data urls before we send it off to the http stack
if (m_request->url().SchemeIs("data"))
return handleDataURL(m_request->url());
- m_request->set_context(WebRequestContext::GetAndroidContext());
+ if (!isPrivateBrowsing)
+ m_request->set_context(WebRequestContext::GetAndroidContext());
+ else
+ m_request->set_context(WebRequestContext::GetAndroidPrivateBrowsingContext());
+
m_request->Start();
}
@@ -110,11 +116,11 @@ void WebRequest::handleDataURL(GURL url)
// weburlloader_impl.cc
WebResponse webResponse(url.spec(), mimeType, data->size(), charset, 200);
LoaderData* loaderResponse = new LoaderData(m_urlLoader, webResponse);
- callOnMainThread(WebUrlLoaderClient::didReceiveResponse, loaderResponse);
+ m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveResponse, loaderResponse);
if (!data->empty()) {
LoaderData* loaderData = new LoaderData(m_urlLoader, data.leakPtr());
- callOnMainThread(WebUrlLoaderClient::didReceiveDataUrl, loaderData);
+ m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveDataUrl, loaderData);
}
} else {
// handle the failed case
@@ -123,7 +129,6 @@ void WebRequest::handleDataURL(GURL url)
finish(true);
}
-
// Called upon a server-initiated redirect. The delegate may call the
// request's Cancel method to prevent the redirect from being followed.
// Since there may be multiple chained redirects, there may also be more
@@ -146,7 +151,7 @@ void WebRequest::OnReceivedRedirect(URLRequest* newRequest, const GURL& newUrl,
WebResponse webResponse(newRequest);
webResponse.setUrl(newUrl.spec());
LoaderData* ld = new LoaderData(m_urlLoader, webResponse);
- callOnMainThread(WebUrlLoaderClient::willSendRequest, ld);
+ m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::willSendRequest, ld);
} else {
// why would this happen? And what to do?
}
@@ -180,7 +185,7 @@ void WebRequest::OnResponseStarted(URLRequest* request)
if (request && request->status().is_success()) {
WebResponse webResponse(request);
LoaderData* loaderData = new LoaderData(m_urlLoader, webResponse);
- callOnMainThread(WebUrlLoaderClient::didReceiveResponse, loaderData);
+ m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveResponse, loaderData);
// Start reading the response
startReading();
@@ -205,7 +210,7 @@ void WebRequest::startReading()
// Read ok, forward buffer to webcore
m_networkBuffer->AddRef();
LoaderData* loaderData = new LoaderData(m_urlLoader, m_networkBuffer.get(), bytesRead);
- callOnMainThread(WebUrlLoaderClient::didReceiveData, loaderData);
+ m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveData, loaderData);
// m_networkBuffer->Release() on main thread
m_networkBuffer = 0;
} else if (m_request && m_request->status().is_io_pending()) {
@@ -241,7 +246,7 @@ void WebRequest::OnReadCompleted(URLRequest* request, int bytesRead)
m_networkBuffer->AddRef();
LoaderData* loaderData = new LoaderData(m_urlLoader, m_networkBuffer.get(), bytesRead);
// m_networkBuffer->Release() on main thread
- callOnMainThread(WebUrlLoaderClient::didReceiveData, loaderData);
+ m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveData, loaderData);
m_networkBuffer = 0;
// Get the rest of the data
diff --git a/WebKit/android/WebCoreSupport/WebRequest.h b/WebKit/android/WebCoreSupport/WebRequest.h
index 2bd86d8..9c9c830 100644
--- a/WebKit/android/WebCoreSupport/WebRequest.h
+++ b/WebKit/android/WebCoreSupport/WebRequest.h
@@ -45,7 +45,7 @@ public:
// Optional, but if used has to be called before start
void AppendBytesToUpload(const char* bytes, int bytesLen);
- void start();
+ void start(bool isPrivateBrowsing);
void cancel();
// From URLRequest::Delegate
diff --git a/WebKit/android/WebCoreSupport/WebRequestContext.cpp b/WebKit/android/WebCoreSupport/WebRequestContext.cpp
index e9ef24c..6b2fe1b 100644
--- a/WebKit/android/WebCoreSupport/WebRequestContext.cpp
+++ b/WebKit/android/WebCoreSupport/WebRequestContext.cpp
@@ -36,10 +36,14 @@
#include <net/http/http_cache.h>
#include <net/http/http_network_layer.h>
#include <net/proxy/proxy_service.h>
+#include <wtf/text/CString.h>
namespace {
- // TODO: Get uastring from webcore
- std::string userAgent("Mozilla/5.0 (Linux; U; Android 2.1; en-gb; Nexus One Build/ERE21) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17");
+std::string userAgent("Mozilla/5.0 (Linux; U; Android 2.1; en-gb; Nexus One Build/ERE21) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17");
+std::string acceptLanguage("");
+
+Lock userAgentLock;
+Lock acceptLanguageLock;
}
namespace android {
@@ -48,17 +52,39 @@ std::string* WebRequestContext::s_dataDirectory(0);
WebRequestContext::WebRequestContext()
{
+ // Also hardcoded in FrameLoader.java
+ accept_charset_ = "utf-8, iso-8859-1, utf-16, *;q=0.7";
}
WebRequestContext::~WebRequestContext()
{
}
+void WebRequestContext::SetUserAgent(WTF::String string)
+{
+ AutoLock aLock(userAgentLock);
+ userAgent = string.utf8().data();
+ userAgent.append(" alternate http");
+}
+
const std::string& WebRequestContext::GetUserAgent(const GURL& url) const
{
+ AutoLock aLock(userAgentLock);
return userAgent;
}
+void WebRequestContext::SetAcceptLanguage(WTF::String string)
+{
+ AutoLock aLock(acceptLanguageLock);
+ acceptLanguage = string.utf8().data();
+}
+
+const std::string& WebRequestContext::GetAcceptLanguage() const
+{
+ AutoLock aLock(acceptLanguageLock);
+ return acceptLanguage;
+}
+
const std::string* WebRequestContext::GetDataDirectory()
{
if (!s_dataDirectory) {
@@ -77,28 +103,44 @@ const std::string* WebRequestContext::GetDataDirectory()
return s_dataDirectory;
}
+WebRequestContext* WebRequestContext::GetAndroidContextForPath(const char* cookieFilename, const char* cacheFilename)
+{
+ std::string cookieString(*GetDataDirectory());
+ cookieString.append(cookieFilename);
+ FilePath cookiePath(cookieString.c_str());
+ std::string cacheString(*GetDataDirectory());
+ cacheString.append(cacheFilename);
+ FilePath cachePath(cacheString.c_str());
+
+ scoped_refptr<WebRequestContext> androidContext = new WebRequestContext();
+ androidContext->host_resolver_ = net::CreateSystemHostResolver(0);
+ scoped_refptr<base::MessageLoopProxy> cacheMessageLoopProxy = base::MessageLoopProxy::CreateForCurrentThread();
+ // Todo: check if the context takes ownership of the cache
+ net::HttpCache::DefaultBackend* defaultBackend = new net::HttpCache::DefaultBackend(net::DISK_CACHE, cachePath, 20 * 1024 * 1024, cacheMessageLoopProxy);
+ androidContext->http_transaction_factory_ = new net::HttpCache(androidContext->host_resolver(), net::ProxyService::CreateNull(), net::SSLConfigService::CreateSystemSSLConfigService(), 0, 0, 0, defaultBackend);
+
+ scoped_refptr<SQLitePersistentCookieStore> cookieDb = new SQLitePersistentCookieStore(cookiePath);
+ androidContext->cookie_store_ = new net::CookieMonster(cookieDb.get(), 0);
+
+ return androidContext.release();
+}
+
WebRequestContext* WebRequestContext::GetAndroidContext()
{
static scoped_refptr<WebRequestContext> androidContext(0);
+ if (!androidContext)
+ androidContext = GetAndroidContextForPath("/chromecookies.db", "/chromecache");
+ return androidContext;
+}
+
+WebRequestContext* WebRequestContext::GetAndroidPrivateBrowsingContext()
+{
+ static scoped_refptr<WebRequestContext> androidContext(0);
if (!androidContext) {
- std::string cookieString(*GetDataDirectory());
- cookieString.append("/chromecookies.db");
- FilePath cookiePath(cookieString.c_str());
- std::string cacheString(*GetDataDirectory());
- cacheString.append("/chromecache");
- FilePath cachePath(cacheString.c_str());
-
- androidContext = new WebRequestContext();
- androidContext->host_resolver_ = net::CreateSystemHostResolver(0);
- scoped_refptr<base::MessageLoopProxy> cacheMessageLoopProxy = base::MessageLoopProxy::CreateForCurrentThread();
- // Todo: check if the context takes ownership of the cache
- net::HttpCache::DefaultBackend* defaultBackend = new net::HttpCache::DefaultBackend(net::DISK_CACHE, cachePath, 20 * 1024 * 1024, cacheMessageLoopProxy);
- androidContext->http_transaction_factory_ = new net::HttpCache(androidContext->host_resolver(), net::ProxyService::CreateNull(), net::SSLConfigService::CreateSystemSSLConfigService(), 0, 0, 0, defaultBackend);
-
- scoped_refptr<SQLitePersistentCookieStore> cookieDb = new SQLitePersistentCookieStore(cookiePath);
- androidContext->cookie_store_ = new net::CookieMonster(cookieDb.get(), 0);
+ // TODO: Where is the right place to put the temporary db? Should it be
+ // kept in memory?
+ androidContext = GetAndroidContextForPath("/chromecookies_private.db", "/chromecache_private");
}
-
return androidContext;
}
diff --git a/WebKit/android/WebCoreSupport/WebRequestContext.h b/WebKit/android/WebCoreSupport/WebRequestContext.h
index 0ff081c..a1f7973 100644
--- a/WebKit/android/WebCoreSupport/WebRequestContext.h
+++ b/WebKit/android/WebCoreSupport/WebRequestContext.h
@@ -31,22 +31,32 @@
// a subclass of a chrome class.
#if USE(CHROME_NETWORK_STACK)
-#include "net/http/http_cache.h"
-#include "net/url_request/url_request_context.h"
+#include "PlatformString.h"
+
+#include <net/http/http_cache.h>
+#include <net/url_request/url_request_context.h>
namespace android {
class WebRequestContext : public URLRequestContext {
public:
virtual const std::string& GetUserAgent(const GURL& url) const;
+ virtual const std::string& GetAcceptLanguage() const;
static WebRequestContext* GetAndroidContext();
+ static WebRequestContext* GetAndroidPrivateBrowsingContext();
+
+ static void SetUserAgent(WTF::String);
+ static void SetAcceptLanguage(WTF::String);
+
private:
static const std::string* GetDataDirectory();
+ static WebRequestContext* GetAndroidContextForPath(const char* cookiePath, const char* cachePath);
WebRequestContext();
~WebRequestContext();
// Caching this query from java
static std::string* s_dataDirectory;
+ static std::string* s_userAgent;
};
} // namespace android
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoader.cpp b/WebKit/android/WebCoreSupport/WebUrlLoader.cpp
index 9df58e4..4b815c6 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoader.cpp
+++ b/WebKit/android/WebCoreSupport/WebUrlLoader.cpp
@@ -42,10 +42,10 @@ WebUrlLoader::~WebUrlLoader()
{
}
-PassRefPtr<WebUrlLoader> WebUrlLoader::start(WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest, bool isSync)
+PassRefPtr<WebUrlLoader> WebUrlLoader::start(WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest, bool isSync, bool isPrivateBrowsing)
{
RefPtr<WebUrlLoader> loader = WebUrlLoader::create(resourceHandle, resourceRequest);
- loader->m_loaderClient->start(isSync);
+ loader->m_loaderClient->start(isSync, isPrivateBrowsing);
return loader.release();
}
@@ -69,9 +69,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)
+ FrameLoaderClient* /*client*/, bool /*isMainResource*/, bool isSync, bool isPrivateBrowsing)
{
- return android::WebUrlLoader::start(resourceHandle, resourceRequest, isSync);
+ return android::WebUrlLoader::start(resourceHandle, resourceRequest, isSync, isPrivateBrowsing);
}
// static
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoader.h b/WebKit/android/WebCoreSupport/WebUrlLoader.h
index 167bdc0..c465b66 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoader.h
+++ b/WebKit/android/WebCoreSupport/WebUrlLoader.h
@@ -36,7 +36,7 @@ class WebUrlLoaderClient;
class WebUrlLoader : public ResourceLoaderAndroid {
public:
virtual ~WebUrlLoader();
- static PassRefPtr<WebUrlLoader> start(WebCore::ResourceHandle*, const WebCore::ResourceRequest&, bool sync);
+ static PassRefPtr<WebUrlLoader> start(WebCore::ResourceHandle*, const WebCore::ResourceRequest&, bool sync, bool isPrivateBrowsing);
virtual void cancel();
virtual void downloadFile() {} // Not implemented yet
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
index bfb8eb7..e3ee14c 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
+++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
@@ -33,6 +33,8 @@
#include "WebRequest.h"
#include "WebResourceRequest.h"
+#include <base/condition_variable.h>
+#include <base/lock.h>
#include <base/thread.h>
#include <net/base/io_buffer.h>
@@ -66,12 +68,21 @@ base::Thread* WebUrlLoaderClient::ioThread()
return networkThread;
}
+Lock* WebUrlLoaderClient::syncLock() {
+ static Lock s_syncLock;
+ return &s_syncLock;
+}
+
+ConditionVariable* WebUrlLoaderClient::syncCondition() {
+ static ConditionVariable s_syncCondition(syncLock());
+ return &s_syncCondition;
+}
+
WebUrlLoaderClient::~WebUrlLoaderClient()
{
base::Thread* thread = ioThread();
if (thread)
thread->message_loop()->ReleaseSoon(FROM_HERE, m_request);
-
}
bool WebUrlLoaderClient::isActive() const
@@ -85,7 +96,10 @@ bool WebUrlLoaderClient::isActive() const
}
WebUrlLoaderClient::WebUrlLoaderClient(WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest)
- : m_resourceHandle(resourceHandle), m_cancelling(false)
+ : m_resourceHandle(resourceHandle)
+ , m_cancelling(false)
+ , m_sync(false)
+ , m_finished(false)
{
WebResourceRequest webResourceRequest(resourceRequest);
@@ -129,15 +143,40 @@ WebUrlLoaderClient::WebUrlLoaderClient(WebCore::ResourceHandle* resourceHandle,
}
}
-bool WebUrlLoaderClient::start(bool /*sync*/)
+bool WebUrlLoaderClient::start(bool sync, bool isPrivateBrowsing)
{
base::Thread* thread = ioThread();
- if (thread) {
- thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::start));
- return true;
+ if (!thread) {
+ return false;
}
- return false;
+ m_sync = sync;
+ if (m_sync) {
+ AutoLock autoLock(*syncLock());
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::start, isPrivateBrowsing));
+
+ // Run callbacks until the queue is exhausted and m_finished is true.
+ while(!m_finished) {
+ while (!m_queue.empty()) {
+ Callback& callback = m_queue.front();
+ CallbackFunction* function = callback.a;
+ void* context = callback.b;
+ (*function)(context);
+ m_queue.pop_front();
+ }
+ if (m_queue.empty() && !m_finished) {
+ syncCondition()->Wait();
+ }
+ }
+
+ // This may be the last reference to us, so we may be deleted now.
+ // Don't access any more member variables after releasing this reference.
+ m_resourceHandle = 0;
+ } else {
+ // Asynchronous start.
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::start, isPrivateBrowsing));
+ }
+ return true;
}
void WebUrlLoaderClient::cancel()
@@ -151,9 +190,26 @@ void WebUrlLoaderClient::cancel()
void WebUrlLoaderClient::finish()
{
- // This will probably cause this to be deleted as we are the only one holding a reference to
- // m_resourceHandle, and it is holding the only reference to this.
- m_resourceHandle = 0;
+ m_finished = true;
+ if (!m_sync) {
+ // This is the last reference to us, so we will be deleted now.
+ // We only release the reference here if start() was called asynchronously!
+ m_resourceHandle = 0;
+ }
+}
+
+// This is called from the IO thread, and dispatches the callback to the main thread.
+void WebUrlLoaderClient::maybeCallOnMainThread(CallbackFunction* function, void* context) {
+ if (m_sync) {
+ AutoLock autoLock(*syncLock());
+ if (m_queue.empty()) {
+ syncCondition()->Broadcast();
+ }
+ m_queue.push_back(Callback(function, context));
+ } else {
+ // Let WebKit handle it.
+ callOnMainThread(function, context);
+ }
}
// Response methods
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
index 399df08..a761f15 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
+++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
@@ -31,7 +31,12 @@
#include "WebUrlLoader.h"
#include <base/ref_counted.h>
+#include <base/tuple.h>
#include <string>
+#include <deque>
+
+class Lock;
+class ConditionVariable;
namespace base {
class Thread;
@@ -58,12 +63,18 @@ public:
~WebUrlLoaderClient();
// Called from WebCore, will be forwarded to the IO thread
- bool start(bool sync);
+ bool start(bool sync, bool isPrivateBrowsing);
void cancel();
void downloadFile();
void pauseLoad(bool pause) {} // Android method, does nothing for now
- // Called by WebRequest, should be forwarded to WebCore
+ typedef void CallbackFunction(void*);
+
+ // This is called from the IO thread, and dispatches the callback to the main thread.
+ // (For asynchronous calls, we just delegate to WebKit's callOnMainThread.)
+ void maybeCallOnMainThread(CallbackFunction*, void* context);
+
+ // Called by WebRequest (using maybeCallOnMainThread), should be forwarded to WebCore.
static void didReceiveResponse(void*);
static void didReceiveData(void*);
static void didReceiveDataUrl(void*);
@@ -75,6 +86,8 @@ private:
void finish();
RefPtr<WebCore::ResourceHandle> m_resourceHandle;
bool m_cancelling;
+ bool m_sync;
+ volatile bool m_finished;
// Not an OwnPtr since it should be deleted on another thread
WebRequest* m_request;
@@ -84,9 +97,20 @@ private:
// Check if a request is active
bool isActive() const;
+
+ // Mutex and condition variable used for synchronous requests.
+ // Note that these are static. This works because there's only one main thread.
+ static Lock* syncLock();
+ static ConditionVariable* syncCondition();
+
+ typedef Tuple2<CallbackFunction*, void*> Callback;
+ typedef std::deque<Callback> CallbackQueue;
+
+ // Queue of callbacks to be executed by the main thread. Must only be accessed inside mutex.
+ CallbackQueue m_queue;
};
-// A struct to send more than one thing in a void*, needed for callOnMainThread
+// A struct to send more than one thing in a void*, needed for maybeCallOnMainThread
struct LoaderData {
net::IOBuffer* buffer;
WebUrlLoaderClient* loader;
diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp
index 10c8439..868233a 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -532,7 +532,12 @@ WebFrame::loadStarted(WebCore::Frame* frame)
#ifdef ANDROID_INSTRUMENT
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
- const WebCore::KURL& url = frame->loader()->activeDocumentLoader()->url();
+ // activeDocumentLoader() can return null.
+ DocumentLoader* documentLoader = frame->loader()->activeDocumentLoader();
+ if (documentLoader == NULL)
+ return;
+
+ const WebCore::KURL& url = documentLoader->url();
if (url.isEmpty())
return;
LOGV("::WebCore:: loadStarted %s", url.string().ascii().data());
@@ -598,8 +603,14 @@ WebFrame::didFinishLoad(WebCore::Frame* frame)
TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter);
#endif
JNIEnv* env = getJNIEnv();
+
+ // activeDocumentLoader() can return null.
WebCore::FrameLoader* loader = frame->loader();
- const WebCore::KURL& url = loader->activeDocumentLoader()->url();
+ DocumentLoader* documentLoader = loader->activeDocumentLoader();
+ if (documentLoader == NULL)
+ return;
+
+ const WebCore::KURL& url = documentLoader->url();
if (url.isEmpty())
return;
LOGV("::WebCore:: didFinishLoad %s", url.string().ascii().data());
diff --git a/WebKit/android/jni/WebSettings.cpp b/WebKit/android/jni/WebSettings.cpp
index f389a39..9b84409 100644
--- a/WebKit/android/jni/WebSettings.cpp
+++ b/WebKit/android/jni/WebSettings.cpp
@@ -48,6 +48,7 @@
#if USE(V8)
#include "WorkerContextExecutionProxy.h"
#endif
+#include "WebRequestContext.h"
#include <JNIHelp.h>
#include <utils/misc.h>
@@ -76,6 +77,7 @@ struct FieldIds {
"Ljava/lang/String;");
mUserAgent = env->GetFieldID(clazz, "mUserAgent",
"Ljava/lang/String;");
+ mAcceptLanguage = env->GetFieldID(clazz, "mAcceptLanguage", "Ljava/lang/String;");
mMinimumFontSize = env->GetFieldID(clazz, "mMinimumFontSize", "I");
mMinimumLogicalFontSize = env->GetFieldID(clazz, "mMinimumLogicalFontSize", "I");
mDefaultFontSize = env->GetFieldID(clazz, "mDefaultFontSize", "I");
@@ -130,6 +132,7 @@ struct FieldIds {
LOG_ASSERT(mFantasyFontFamily, "Could not find field mFantasyFontFamily");
LOG_ASSERT(mDefaultTextEncoding, "Could not find field mDefaultTextEncoding");
LOG_ASSERT(mUserAgent, "Could not find field mUserAgent");
+ LOG_ASSERT(mAcceptLanguage, "Could not find field mAcceptLanguage");
LOG_ASSERT(mMinimumFontSize, "Could not find field mMinimumFontSize");
LOG_ASSERT(mMinimumLogicalFontSize, "Could not find field mMinimumLogicalFontSize");
LOG_ASSERT(mDefaultFontSize, "Could not find field mDefaultFontSize");
@@ -177,6 +180,7 @@ struct FieldIds {
jfieldID mFantasyFontFamily;
jfieldID mDefaultTextEncoding;
jfieldID mUserAgent;
+ jfieldID mAcceptLanguage;
jfieldID mMinimumFontSize;
jfieldID mMinimumLogicalFontSize;
jfieldID mDefaultFontSize;
@@ -295,6 +299,11 @@ public:
str = (jstring)env->GetObjectField(obj, gFieldIds->mUserAgent);
WebFrame::getWebFrame(pFrame)->setUserAgent(to_string(env, str));
+#if USE(CHROME_NETWORK_STACK)
+ WebRequestContext::SetUserAgent(to_string(env, str));
+ str = (jstring)env->GetObjectField(obj, gFieldIds->mAcceptLanguage);
+ WebRequestContext::SetAcceptLanguage(to_string(env, str));
+#endif
jint size = env->GetIntField(obj, gFieldIds->mMinimumFontSize);
s->setMinimumFontSize(size);
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 1ed885a..6cd1280 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -2360,7 +2360,8 @@ void WebViewCore::touchUp(int touchGeneration,
// Return the RenderLayer for the given RenderObject only if the layer is
// composited and it contains a scrollable content layer.
-static WebCore::RenderLayer* getLayerFromRenderer(WebCore::RenderObject* renderer)
+static WebCore::RenderLayer* getLayerFromRenderer(
+ WebCore::RenderObject* renderer, LayerAndroid** aLayer)
{
if (!renderer)
return 0;
@@ -2371,9 +2372,10 @@ static WebCore::RenderLayer* getLayerFromRenderer(WebCore::RenderObject* rendere
static_cast<GraphicsLayerAndroid*>(layer->backing()->graphicsLayer());
if (!graphicsLayer)
return 0;
- LayerAndroid* aLayer = graphicsLayer->contentLayer();
- if (!aLayer || !aLayer->contentIsScrollable())
+ LayerAndroid* layerAndroid = graphicsLayer->contentLayer();
+ if (!layerAndroid || !layerAndroid->contentIsScrollable())
return 0;
+ *aLayer = layerAndroid;
return layer;
}
@@ -2381,34 +2383,27 @@ static WebCore::RenderLayer* getLayerFromRenderer(WebCore::RenderObject* rendere
// done so that the node is visible when it is clicked.
static void scrollLayer(WebCore::RenderObject* renderer, WebCore::IntPoint* pos)
{
- WebCore::RenderLayer* layer = getLayerFromRenderer(renderer);
+ LayerAndroid* aLayer;
+ WebCore::RenderLayer* layer = getLayerFromRenderer(renderer, &aLayer);
if (!layer)
return;
WebCore::IntRect absBounds = renderer->absoluteBoundingBoxRect();
- WebCore::IntRect layerBounds = layer->absoluteBoundingBox();
+ // Do not include the outline when moving the node's bounds.
+ WebCore::IntRect layerBounds = layer->renderer()->absoluteBoundingBoxRect();
// Move the node's bounds into the layer's coordinates.
absBounds.move(-layerBounds.x(), -layerBounds.y());
+ int diffX = layer->scrollXOffset();
+ int diffY = layer->scrollYOffset();
// Scroll the layer to the node's position. The false parameters tell the
// layer not to invalidate.
- layer->scrollToOffset(absBounds.x(), absBounds.y(), false, false);
+ layer->scrollToOffset(absBounds.x(), absBounds.y(), false, true);
+ diffX = layer->scrollXOffset() - diffX;
+ diffY = layer->scrollYOffset() - diffY;
// Update the mouse position to the layer offset.
- pos->move(-layer->scrollXOffset(), -layer->scrollYOffset());
-}
-
-static void restoreScrolledLayer(WebCore::RenderObject* renderer,
- WebCore::IntPoint* pos)
-{
- WebCore::RenderLayer* layer = getLayerFromRenderer(renderer);
- if (!layer)
- return;
- // Move the mouse position back to it's original position.
- pos->move(layer->scrollXOffset(), layer->scrollYOffset());
-
- // Scroll the layer back to 0,0.
- layer->scrollToOffset(0, 0, false, false);
+ pos->move(-diffX, -diffY);
}
// Common code for both clicking with the trackball and touchUp
@@ -2503,13 +2498,24 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
} else {
requestKeyboard(false);
}
- } else if (focusNode->isContentEditable()) {
- setFocusControllerActive(framePtr, true);
- requestKeyboard(true);
+ } else {
+ // If the focusNode is contentEditable, show the keyboard and enable
+ // the focus controller so the user can type. Otherwise hide the
+ // keyboard and disable the focus controller because no text input
+ // is needed.
+ bool keyboard = focusNode->isContentEditable();
+ setFocusControllerActive(framePtr, keyboard);
+ if (keyboard) {
+ requestKeyboard(true);
+ } else {
+ clearTextEntry();
+ }
}
+ } else {
+ // There is no focusNode, so the keyboard is not needed.
+ setFocusControllerActive(framePtr, false);
+ clearTextEntry();
}
- if (nodePtr && valid)
- restoreScrolledLayer(nodePtr->renderer(), &m_mousePos);
return handled;
}
diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp
index e76c729..c05395c 100644
--- a/WebKit/android/nav/CacheBuilder.cpp
+++ b/WebKit/android/nav/CacheBuilder.cpp
@@ -915,7 +915,7 @@ static bool checkForPluginViewThatWantsFocus(RenderObject* renderer) {
#if USE(ACCELERATED_COMPOSITING)
static void AddLayer(CachedFrame* frame, size_t index, const IntPoint& location,
- int id)
+ const IntPoint& scroll, int id)
{
DBG_NAV_LOGD("frame=%p index=%d loc=(%d,%d) id=%d", frame, index,
location.x(), location.y(), id);
@@ -923,6 +923,7 @@ static void AddLayer(CachedFrame* frame, size_t index, const IntPoint& location,
cachedLayer.reset();
cachedLayer.setCachedNodeIndex(index);
cachedLayer.setOffset(location);
+ cachedLayer.setScrollOffset(scroll);
cachedLayer.setUniqueId(id);
frame->add(cachedLayer);
}
@@ -1063,12 +1064,16 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
TrackLayer(layerTracker, nodeRenderer, lastChild,
globalOffsetX, globalOffsetY);
size_t size = tracker.size();
- const LayerAndroid* layer = layerTracker.last().mLayer;
+ LayerAndroid* layer = layerTracker.last().mLayer;
if (layer) {
int id = layer->uniqueId();
- IntPoint loc = nodeRenderer->
- absoluteBoundingBoxRect().location();
+ const RenderLayer* renderLayer =
+ layerTracker.last().mRenderLayer;
+ IntPoint loc(SkScalarRound(layer->getPosition().fX),
+ SkScalarRound(layer->getPosition().fY));
loc.move(globalOffsetX, globalOffsetY);
+ IntPoint scroll(renderLayer->scrollXOffset(),
+ renderLayer->scrollYOffset());
// if this is a child of a CachedNode, add a layer
size_t limit = cachedFrame->layerCount() == 0 ? 0 :
cachedFrame->lastLayer()->cachedNodeIndex();
@@ -1084,7 +1089,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
CachedNode* trackedNode = cachedFrame->getIndex(index);
trackedNode->setIsInLayer(true);
trackedNode->setIsUnclipped(true);
- AddLayer(cachedFrame, index, loc, id);
+ AddLayer(cachedFrame, index, loc, scroll, id);
}
}
}
@@ -1327,6 +1332,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
LayerAndroid* layer = layerTracker.last().mLayer;
if (layer) {
const IntRect& layerClip = layerTracker.last().mBounds;
+ const RenderLayer* renderLayer = layerTracker.last().mRenderLayer;
if (!layer->contentIsScrollable() && !layerClip.isEmpty() &&
!cachedNode.clip(layerClip)) {
DBG_NAV_LOGD("skipped on layer clip %d", cacheIndex);
@@ -1334,8 +1340,10 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
}
isInLayer = true;
isUnclipped = true; // assume that layers do not have occluded nodes
+ IntPoint scroll(renderLayer->scrollXOffset(),
+ renderLayer->scrollYOffset());
AddLayer(cachedFrame, cachedFrame->size(), layerClip.location(),
- layer->uniqueId());
+ scroll, layer->uniqueId());
}
#endif
cachedNode.setNavableRects();
@@ -2838,7 +2846,8 @@ void CacheBuilder::TrackLayer(WTF::Vector<LayerTracker>& layerTracker,
layerTracker.grow(layerTracker.size() + 1);
LayerTracker& indexTracker = layerTracker.last();
indexTracker.mLayer = aLayer;
- indexTracker.mBounds = nodeRenderer->absoluteBoundingBoxRect();
+ indexTracker.mRenderLayer = layer;
+ indexTracker.mBounds = IntRect(FloatRect(aLayer->bounds()));
indexTracker.mBounds.move(offsetX, offsetY);
indexTracker.mLastChild = lastChild ? OneAfter(lastChild) : 0;
DBG_NAV_LOGD("layer=%p [%d] bounds=(%d,%d,w=%d,h=%d)", aLayer,
diff --git a/WebKit/android/nav/CacheBuilder.h b/WebKit/android/nav/CacheBuilder.h
index 5324187..d19e0c9 100644
--- a/WebKit/android/nav/CacheBuilder.h
+++ b/WebKit/android/nav/CacheBuilder.h
@@ -198,6 +198,7 @@ private:
};
struct LayerTracker : Tracker {
LayerAndroid* mLayer;
+ RenderLayer* mRenderLayer;
IntRect mBounds;
};
struct TabIndexTracker : Tracker {
diff --git a/WebKit/android/nav/CachedLayer.cpp b/WebKit/android/nav/CachedLayer.cpp
index 9c7d59b..c4293a5 100644
--- a/WebKit/android/nav/CachedLayer.cpp
+++ b/WebKit/android/nav/CachedLayer.cpp
@@ -49,6 +49,10 @@ IntRect CachedLayer::adjustBounds(const LayerAndroid* root,
// First, remove the original offset from the bounds.
temp.move(-mOffset.x(), -mOffset.y());
+ // Now, add in the original scroll position. This moves the node to the
+ // original location within the layer.
+ temp.move(mScrollOffset.x(), mScrollOffset.y());
+
// Next, add in the new position of the layer (could be different due to a
// fixed position layer).
const FloatPoint& position = aLayer->getPosition();
@@ -72,12 +76,17 @@ IntRect CachedLayer::adjustBounds(const LayerAndroid* root,
DBG_NAV_LOGD("root=%p aLayer=%p [%d]"
" bounds=(%d,%d,w=%d,h=%d) trans=(%g,%g)"
+ " pos=(%f,%f)"
" offset=(%d,%d) clip=(%d,%d,w=%d,h=%d)"
+ " scroll=(%d,%d) origScroll=(%d,%d)"
" result=(%d,%d,w=%d,h=%d)",
root, aLayer, aLayer->uniqueId(),
bounds.x(), bounds.y(), bounds.width(), bounds.height(),
- translation.x(), translation.y(), mOffset.x(), mOffset.y(),
+ translation.x(), translation.y(), position.x(), position.y(),
+ mOffset.x(), mOffset.y(),
clip.x(), clip.y(), clip.width(), clip.height(),
+ SkScalarRound(scroll.fX), SkScalarRound(scroll.fY),
+ mScrollOffset.x(), mScrollOffset.y(),
result.x(), result.y(), result.width(), result.height());
return result;
}
@@ -104,6 +113,9 @@ IntRect CachedLayer::unadjustBounds(const LayerAndroid* root,
// Move it back to the original offset.
temp.move(mOffset.x(), mOffset.y());
+
+ // Move the bounds by the original scroll.
+ temp.move(-mScrollOffset.x(), -mScrollOffset.y());
return temp;
}
@@ -122,6 +134,10 @@ IntRect CachedLayer::localBounds(const LayerAndroid* root,
// Remove the original offset from the bounds.
temp.move(-mOffset.x(), -mOffset.y());
+ // We add in the original scroll position in order to position the node
+ // relative to the current internal scroll position.
+ temp.move(mScrollOffset.x(), mScrollOffset.y());
+
const LayerAndroid* aLayer = layer(root);
if (aLayer) {
// Move the bounds by the scroll position of the layer.
@@ -134,7 +150,12 @@ IntRect CachedLayer::localBounds(const LayerAndroid* root,
temp.intersect(IntRect(aLayer->foregroundClip()));
}
- return enclosingIntRect(temp);
+ DBG_NAV_LOGD("bounds=(%d,%d,w=%d,h=%d) offset=(%d,%d)"
+ " result=(%d,%d,w=%d,h=%d)", bounds.x(), bounds.y(),
+ bounds.width(), bounds.height(), mOffset.x(), mOffset.y(),
+ temp.x(), temp.y(), temp.width(), temp.height());
+
+ return temp;
}
SkPicture* CachedLayer::picture(const LayerAndroid* root) const
diff --git a/WebKit/android/nav/CachedLayer.h b/WebKit/android/nav/CachedLayer.h
index 8bfe922..0a56ea1 100644
--- a/WebKit/android/nav/CachedLayer.h
+++ b/WebKit/android/nav/CachedLayer.h
@@ -58,12 +58,18 @@ public:
void reset() { mLayer = 0; }
void setCachedNodeIndex(int index) { mCachedNodeIndex = index; }
void setOffset(const IntPoint& offset) { mOffset = offset; }
+ void setScrollOffset(const IntPoint& scrollOffset) {
+ mScrollOffset = scrollOffset;
+ }
void setUniqueId(int uniqueId) { mUniqueId = uniqueId; }
int uniqueId() const { return mUniqueId; }
private:
int mCachedNodeIndex;
mutable const LayerAndroid* mLayer;
+ // mOffset and mScrollOffset are the position and scroll offset of the
+ // layer when recorded by the nav cache.
IntPoint mOffset;
+ IntPoint mScrollOffset;
int mUniqueId;
#if DUMP_NAV_CACHE
diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h
index 2853241..a6420f9 100644
--- a/WebKit/android/nav/CachedRoot.h
+++ b/WebKit/android/nav/CachedRoot.h
@@ -96,7 +96,10 @@ public:
void setTextGeneration(int textGeneration) { mTextGeneration = textGeneration; }
void setMaxScroll(int x, int y) { mMaxXScroll = x; mMaxYScroll = y; }
void setPicture(SkPicture* picture) { mPicture = picture; }
- void setRootLayer(WebCore::LayerAndroid* layer) { mRootLayer = layer; }
+ void setRootLayer(WebCore::LayerAndroid* layer) {
+ mRootLayer = layer;
+ resetLayers();
+ }
void setScrollOnly(bool state) { mScrollOnly = state; }
void setSelection(int start, int end) { mSelectionStart = start; mSelectionEnd = end; }
void setupScrolledBounds() const { mScrolledBounds = mViewBounds; }
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index efaa509..2132957 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -105,7 +105,6 @@ enum DrawExtras { // keep this in sync with WebView.java
struct JavaGlue {
jweak m_obj;
jmethodID m_calcOurContentVisibleRectF;
- jmethodID m_clearTextEntry;
jmethodID m_overrideLoading;
jmethodID m_scrollBy;
jmethodID m_sendMoveFocus;
@@ -141,7 +140,6 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) :
m_javaGlue.m_obj = env->NewWeakGlobalRef(javaWebView);
m_javaGlue.m_scrollBy = GetJMethod(env, clazz, "setContentScrollBy", "(IIZ)Z");
m_javaGlue.m_calcOurContentVisibleRectF = GetJMethod(env, clazz, "calcOurContentVisibleRectF", "(Landroid/graphics/RectF;)V");
- m_javaGlue.m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "(Z)V");
m_javaGlue.m_overrideLoading = GetJMethod(env, clazz, "overrideLoading", "(Ljava/lang/String;)V");
m_javaGlue.m_sendMoveFocus = GetJMethod(env, clazz, "sendMoveFocus", "(II)V");
m_javaGlue.m_sendMoveMouse = GetJMethod(env, clazz, "sendMoveMouse", "(IIII)V");
@@ -222,15 +220,6 @@ void hideCursor()
viewInvalidate();
}
-void clearTextEntry()
-{
- DEBUG_NAV_UI_LOGD("%s", __FUNCTION__);
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- env->CallVoidMethod(m_javaGlue.object(env).get(),
- m_javaGlue.m_clearTextEntry, true);
- checkException(env);
-}
-
#if DUMP_NAV_CACHE
void debugDump()
{
@@ -893,7 +882,6 @@ bool motionUp(int x, int y, int slop)
sendMotionUp(frame ? (WebCore::Frame*) frame->framePointer() : 0,
0, x, y);
viewInvalidate();
- clearTextEntry();
return pageScrolled;
}
DBG_NAV_LOGD("CachedNode:%p (%d) x=%d y=%d rx=%d ry=%d", result,
@@ -914,7 +902,6 @@ bool motionUp(int x, int y, int slop)
}
viewInvalidate();
if (!result->isTextInput()) {
- clearTextEntry();
if (!result->isSelect() && !result->isContentEditable())
setFollowedLink(true);
if (syntheticLink)