android/WebCoreSupport/GeolocationPermissions.cpp \
android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp \
android/WebCoreSupport/PlatformBridge.cpp \
+ android/WebCoreSupport/ResourceLoaderAndroid.cpp \
android/WebCoreSupport/UrlInterceptResponse.cpp \
android/WebCoreSupport/V8Counters.cpp
android/WebCoreSupport/WebResourceRequest.cpp \
android/WebCoreSupport/WebResponse.cpp \
android/WebCoreSupport/WebViewClientError.cpp
-else
-LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
- android/WebCoreSupport/ResourceLoaderAndroid.cpp
endif # HTTP_STACK == chrome
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
String PlatformBridge::computeDefaultLanguage()
{
#if USE(CHROME_NETWORK_STACK)
- std::string acceptLanguages = WebRequestContext::get(false)->GetAcceptLanguage();
+ String acceptLanguages = WebRequestContext::acceptLanguage();
size_t length = acceptLanguages.find(',');
if (length == std::string::npos)
length = acceptLanguages.length();
- return String::fromUTF8(acceptLanguages.c_str(), length);
+ return acceptLanguages.substring(0, length);
#else
return "en";
#endif
*/
#include <config.h>
-
#include <ResourceLoaderAndroid.h>
#include "FrameLoaderClientAndroid.h"
#include "WebCoreFrameBridge.h"
#include "WebCoreResourceLoader.h"
+#include "WebUrlLoader.h"
using namespace android;
namespace WebCore {
PassRefPtr<ResourceLoaderAndroid> ResourceLoaderAndroid::start(
- ResourceHandle* handle, const ResourceRequest& request, FrameLoaderClient* client, bool isMainResource, bool isSync, bool /*isPrivateBrowsing*/)
+ ResourceHandle* handle, const ResourceRequest& request, FrameLoaderClient* client, bool isMainResource, bool isSync, bool isPrivateBrowsing)
{
+ // Called on main thread
+#if USE(CHROME_NETWORK_STACK)
+ // TODO: Implement sync requests
+ return WebUrlLoader::start(client, handle, request, isSync, isPrivateBrowsing);
+#else
FrameLoaderClientAndroid* clientAndroid = static_cast<FrameLoaderClientAndroid*> (client);
return clientAndroid->webFrame()->startLoadingResource(handle, request, isMainResource, isSync);
+#endif
}
bool ResourceLoaderAndroid::willLoadFromCache(const WebCore::KURL& url, int64_t identifier)
{
+#if USE(CHROME_NETWORK_STACK)
+ // This method is used to determine if a POST request can be repeated from
+ // cache, but you cannot really know until you actually try to read from the
+ // cache. Even if we checked now, something else could come along and wipe
+ // out the cache entry by the time we fetch it.
+ //
+ // So, we always say yes here, to prevent the FrameLoader from initiating a
+ // reload. Then in FrameLoaderClientImpl::dispatchWillSendRequest, we
+ // fix-up the cache policy of the request to force a load from the cache.
+ return true;
+#else
return WebCoreResourceLoader::willLoadFromCache(url, identifier);
+#endif
}
}
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "config.h"
#include "WebCache.h"
+
+#include "JNIUtility.h"
+#include "WebCoreJni.h"
#include "WebRequestContext.h"
#include "WebUrlLoaderClient.h"
+using namespace WTF;
using namespace net;
namespace android {
-WebCache* WebCache::s_instance = 0;
+static const std::string& rootDirectory()
+{
+ // This method may be called on any thread, as the Java method is
+ // synchronized.
+ static WTF::Mutex mutex;
+ MutexLocker lock(mutex);
+ static std::string cacheDirectory;
+ if (cacheDirectory.empty()) {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ jclass bridgeClass = env->FindClass("android/webkit/JniUtil");
+ jmethodID method = env->GetStaticMethodID(bridgeClass, "getCacheDirectory", "()Ljava/lang/String;");
+ cacheDirectory = jstringToStdString(env, static_cast<jstring>(env->CallStaticObjectMethod(bridgeClass, method)));
+ env->DeleteLocalRef(bridgeClass);
+ }
+ return cacheDirectory;
+}
-void WebCache::clear()
+WebCache* WebCache::get(bool isPrivateBrowsing)
{
- base::Thread* thread = WebUrlLoaderClient::ioThread();
- if (thread)
- thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(getInstance(), &WebCache::doClear));
+ static const char* const kDirectory = "/webviewCacheChromium";
+ static const char* const kDirectoryPrivate = "/webviewCacheChromiumPrivate";
+
+ static WebCache* regularCache = 0;
+ static WebCache* privateCache = 0;
+
+ if (isPrivateBrowsing) {
+ if (!privateCache) {
+ std::string storageDirectory = rootDirectory();
+ storageDirectory.append(kDirectoryPrivate);
+ privateCache = new WebCache(storageDirectory);
+ }
+ return privateCache;
+ }
+
+ if (!regularCache) {
+ std::string storageDirectory = rootDirectory();
+ storageDirectory.append(kDirectory);
+ regularCache = new WebCache(storageDirectory);
+ }
+ return regularCache;
}
-WebCache::WebCache()
- : m_doomAllEntriesCallback(this, &WebCache::doomAllEntries)
- , m_doneCallback(this, &WebCache::done)
+WebCache::WebCache(const std::string& storageDirectory)
+ : m_storageDirectory(storageDirectory)
+ , m_doomAllEntriesCallback(this, &WebCache::doomAllEntries)
+ , m_doneCallback(this, &WebCache::onClearDone)
, m_isClearInProgress(false)
{
+ base::Thread* ioThread = WebUrlLoaderClient::ioThread();
+ scoped_refptr<base::MessageLoopProxy> cacheMessageLoopProxy = ioThread->message_loop_proxy();
+
+ static const int kMaximumCacheSizeBytes = 20 * 1024 * 1024;
+ FilePath directoryPath(m_storageDirectory.c_str());
+ net::HttpCache::DefaultBackend* backendFactory = new net::HttpCache::DefaultBackend(net::DISK_CACHE, directoryPath, kMaximumCacheSizeBytes, cacheMessageLoopProxy);
+
+ m_hostResolver = net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism, 0, 0);
+ m_cache = new net::HttpCache(m_hostResolver.get(),
+ 0, // dnsrr_resolver
+ net::ProxyService::CreateDirect(),
+ net::SSLConfigService::CreateSystemSSLConfigService(),
+ net::HttpAuthHandlerFactory::CreateDefault(m_hostResolver.get()),
+ 0, // network_delegate
+ 0, // net_log
+ backendFactory);
}
-WebCache* WebCache::getInstance()
+void WebCache::clear()
{
- if (!s_instance) {
- s_instance = new WebCache();
- s_instance->AddRef();
- }
- return s_instance;
+ base::Thread* thread = WebUrlLoaderClient::ioThread();
+ if (thread)
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &WebCache::doClear));
+}
+
+void WebCache::cleanupFiles()
+{
+ WebRequestContext::removeFileOrDirectory(m_storageDirectory.c_str());
}
void WebCache::doClear()
if (m_isClearInProgress)
return;
m_isClearInProgress = true;
- URLRequestContext* context = WebRequestContext::get(false /* isPrivateBrowsing */);
- HttpTransactionFactory* factory = context->http_transaction_factory();
- int code = factory->GetCache()->GetBackend(&m_cacheBackend, &m_doomAllEntriesCallback);
+
+ int code = m_cache->GetBackend(&m_cacheBackend, &m_doomAllEntriesCallback);
// Code ERR_IO_PENDING indicates that the operation is still in progress and
// the supplied callback will be invoked when it completes.
if (code == ERR_IO_PENDING)
m_isClearInProgress = false;
return;
}
- done(0 /*unused*/);
+ onClearDone(0 /*unused*/);
}
-void WebCache::done(int)
+void WebCache::onClearDone(int)
{
m_isClearInProgress = false;
}
#include "ChromiumIncludes.h"
+#include <OwnPtr.h>
+#include <wtf/ThreadingPrimitives.h>
+
namespace android {
+// This class is not generally threadsafe. get() is not threadsafe - instances
+// are created on the WebCore thread only.
class WebCache : public base::RefCountedThreadSafe<WebCache> {
public:
- static void clear();
+ static WebCache* get(bool isPrivateBrowsing);
+
+ void clear();
+ void cleanupFiles();
+ net::HostResolver* hostResolver() { return m_hostResolver.get(); }
+ net::HttpCache* cache() { return m_cache.get(); }
private:
- WebCache();
- static WebCache* getInstance();
+ WebCache(const std::string& storageDirectory);
+ // For clear()
void doClear();
void doomAllEntries(int);
- void done(int);
+ void onClearDone(int);
+
+ std::string m_storageDirectory;
+ OwnPtr<net::HostResolver> m_hostResolver;
+ OwnPtr<net::HttpCache> m_cache;
- static WebCache* s_instance;
+ // For clear()
net::CompletionCallbackImpl<WebCache> m_doomAllEntriesCallback;
net::CompletionCallbackImpl<WebCache> m_doneCallback;
disk_cache::Backend* m_cacheBackend;
static WebCookieJar* regularCookieManager = 0;
static WebCookieJar* privateCookieManager = 0;
+ WTF::Mutex instanceMutex;
+ MutexLocker lock(instanceMutex);
+
if (isPrivateBrowsing) {
if (!privateCookieManager) {
std::string databaseFilePath = databaseDirectory();
namespace android {
+// This class is threadsafe. It is used from the IO, WebCore and Chromium IO
+// threads.
class WebCookieJar : public net::CookiePolicy {
public:
static WebCookieJar* get(bool isPrivateBrowsing);
#include "ChromiumIncludes.h"
#include "ChromiumLogging.h"
-#include "JNIUtility.h"
+#include "WebCache.h"
#include "WebCookieJar.h"
-#include "WebCoreJni.h"
-#include "WebUrlLoaderClient.h"
-#include "jni.h"
#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
#include <wtf/text/CString.h>
namespace {
// TODO: The userAgent should not be a static, as it can be set per WebView.
// http://b/3113804
std::string userAgent("");
-std::string acceptLanguage("");
-
Lock userAgentLock;
-Lock acceptLanguageLock;
-WTF::Mutex cacheDirectoryMutex;
+std::string acceptLanguageStdString("");
+WTF::String acceptLanguageWtfString("");
+WTF::Mutex acceptLanguageMutex;
}
using namespace WTF;
namespace android {
-static const char* const kCacheDirectory = "/webviewCacheChromium";
-static const char* const kCacheDirectoryPrivate = "/webviewCacheChromiumPrivate";
-
static scoped_refptr<WebRequestContext> privateBrowsingContext(0);
static WTF::Mutex privateBrowsingContextMutex;
return userAgent;
}
-void WebRequestContext::setAcceptLanguage(String string)
+void WebRequestContext::setAcceptLanguage(const String& string)
{
- // The accept language is set on the WebCore thread and read on the network
- // stack's IO thread.
- AutoLock aLock(acceptLanguageLock);
- acceptLanguage = string.utf8().data();
+ MutexLocker lock(acceptLanguageMutex);
+ acceptLanguageStdString = string.utf8().data();
+ acceptLanguageWtfString = string;
}
const std::string& WebRequestContext::GetAcceptLanguage() const
{
- // The accept language is set on the WebCore thread and read on the network
- // stack's IO thread.
- AutoLock aLock(acceptLanguageLock);
- return acceptLanguage;
+ MutexLocker lock(acceptLanguageMutex);
+ return acceptLanguageStdString;
}
-static const std::string& cacheRootDirectory()
+const String& WebRequestContext::acceptLanguage()
{
- // This method may be called on any thread, as the Java method is
- // synchronized.
- MutexLocker lock(cacheDirectoryMutex);
- static std::string cacheDirectory;
- if (cacheDirectory.empty()) {
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- jclass bridgeClass = env->FindClass("android/webkit/JniUtil");
- jmethodID method = env->GetStaticMethodID(bridgeClass, "getCacheDirectory", "()Ljava/lang/String;");
- cacheDirectory = jstringToStdString(env, static_cast<jstring>(env->CallStaticObjectMethod(bridgeClass, method)));
- env->DeleteLocalRef(bridgeClass);
- }
- return cacheDirectory;
+ MutexLocker lock(acceptLanguageMutex);
+ return acceptLanguageWtfString;
}
WebRequestContext* WebRequestContext::getImpl(bool isPrivateBrowsing)
{
- static std::string path = cacheRootDirectory();
- path.append(isPrivateBrowsing ? kCacheDirectoryPrivate : kCacheDirectory);
- FilePath cachePath(path.c_str());
-
WebRequestContext* context = new WebRequestContext();
- context->host_resolver_ = net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism, 0, 0);
- base::Thread* ioThread = WebUrlLoaderClient::ioThread();
- scoped_refptr<base::MessageLoopProxy> cacheMessageLoopProxy = ioThread->message_loop_proxy();
- // 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);
- context->http_transaction_factory_ = new net::HttpCache(context->host_resolver(), context->dnsrr_resolver(), net::ProxyService::CreateDirect(), net::SSLConfigService::CreateSystemSSLConfigService(), net::HttpAuthHandlerFactory::CreateDefault(context->host_resolver_), 0, 0, defaultBackend);
+ WebCache* cache = WebCache::get(isPrivateBrowsing);
+ context->host_resolver_ = cache->hostResolver();
+ context->http_transaction_factory_ = cache->cache();
WebCookieJar* cookieJar = WebCookieJar::get(isPrivateBrowsing);
context->cookie_store_ = cookieJar->cookieStore();
WebRequestContext* WebRequestContext::getRegularContext()
{
- static WTF::Mutex regularContextMutex;
static scoped_refptr<WebRequestContext> regularContext(0);
-
- MutexLocker lock(regularContextMutex);
if (!regularContext)
regularContext = getImpl(false);
return regularContext;
privateBrowsingContext = 0;
WebCookieJar::get(true)->cleanupFiles();
-
- std::string cachePath = cacheRootDirectory();
- cachePath.append(kCacheDirectoryPrivate);
- removeFileOrDirectory(cachePath.c_str());
+ WebCache::get(true)->cleanupFiles();
return true;
}
return false;
namespace android {
+// This class is generally not threadsafe. .get() is not threadsafe - instances
+// are created on the WebCore thread only.
class WebRequestContext : public URLRequestContext {
public:
// URLRequestContext overrides.
virtual const std::string& GetAcceptLanguage() const;
// Lazily create the relevant context. This class holds a reference.
- // This may be called on any thread. The context returned, however, is not
- // threadsafe, and should only be used on a single thread (the network stack
- // IO thread), with the exception of the methods below.
static WebRequestContext* get(bool isPrivateBrowsing);
// These methods are threadsafe.
static bool cleanupPrivateBrowsingFiles();
static void setUserAgent(WTF::String);
- static void setAcceptLanguage(WTF::String);
+ static void setAcceptLanguage(const WTF::String&);
+ static const WTF::String& acceptLanguage();
// A helper function used by the cache and cookie managers. Should probably
// find a better home, but wait for the refactoring in b/3113804 to be
}
} // namespace android
-
-
-namespace WebCore {
-// on main thread
-// static
-// TODO: Implement sync requests
-PassRefPtr<ResourceLoaderAndroid> ResourceLoaderAndroid::start(WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest,
- FrameLoaderClient* client, bool /*isMainResource*/, bool isSync, bool isPrivateBrowsing)
-{
- return android::WebUrlLoader::start(client, resourceHandle, resourceRequest, isSync, isPrivateBrowsing);
-}
-
-// static
-bool ResourceLoaderAndroid::willLoadFromCache(const WebCore::KURL&, int64_t identifier)
-{
- // This method is used to determine if a POST request can be repeated from
- // cache, but you cannot really know until you actually try to read from the
- // cache. Even if we checked now, something else could come along and wipe
- // out the cache entry by the time we fetch it.
- //
- // So, we always say yes here, to prevent the FrameLoader from initiating a
- // reload. Then in FrameLoaderClientImpl::dispatchWillSendRequest, we
- // fix-up the cache policy of the request to force a load from the cache.
- //
- return true;
-}
-
-} // namespace WebCore
// JNI for android.webkit.CookieManager
static const char* javaCookieManagerClass = "android/webkit/CookieManager";
-// Though WebRequestContext::get() is threadsafe, the context itself, in
-// general, is not. The context is generally used on the HTTP stack IO
-// thread, but calls to the methods of this class are made on the UI thread.
-// We ensure thread safety as follows ...
-// - The cookie_store() getter just returns a pointer which is only set when the
-// context is first constructed. The CookieMonster itself is threadsafe, so
-// using it from the UI thread is safe.
-// - Calls to the other WebRequestContext methods used here are explicitly
-// threadsafe.
-
+// WebCookieJar is threadsafe, as is CookieMonster.
static bool useChromiumHttpStack(JNIEnv*, jobject)
{
#if USE(CHROME_NETWORK_STACK)
static void ClearWebViewCache()
{
#if USE(CHROME_NETWORK_STACK)
- WebCache::clear();
+ WebCache::get(false /*privateBrowsing*/)->clear();
#else
// The Android network stack provides a WebView cache in CacheManager.java.
// Clearing this is handled entirely Java-side.
view->selectBestAt(rect);
}
+static jobject nativeLayerBounds(JNIEnv* env, jobject obj, jint jlayer)
+{
+ SkRect r;
+#if USE(ACCELERATED_COMPOSITING)
+ LayerAndroid* layer = (LayerAndroid*) jlayer;
+ r = layer->bounds();
+#else
+ r.setEmpty();
+#endif
+ SkIRect irect;
+ r.round(&irect);
+ jclass rectClass = env->FindClass("android/graphics/Rect");
+ jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V");
+ jobject rect = env->NewObject(rectClass, init, irect.fLeft, irect.fTop,
+ irect.fRight, irect.fBottom);
+ env->DeleteLocalRef(rectClass);
+ return rect;
+}
+
static jobject nativeSubtractLayers(JNIEnv* env, jobject obj, jobject jrect)
{
SkIRect irect = jrect_to_webrect(env, jrect);
(void*) nativeImageURI },
{ "nativeInstrumentReport", "()V",
(void*) nativeInstrumentReport },
+ { "nativeLayerBounds", "(I)Landroid/graphics/Rect;",
+ (void*) nativeLayerBounds },
{ "nativeMotionUp", "(III)Z",
(void*) nativeMotionUp },
{ "nativeMoveCursor", "(IIZ)Z",