#if PLATFORM(ANDROID)
virtual MainResourceLoader* mainResourceLoader() const = 0;
- virtual bool isPrivateBrowsingEnabled() const = 0;
virtual FrameLoaderClient* frameLoaderClient() const = 0;
#endif
MainResourceLoader* mainLoader = context->mainResourceLoader();
bool isMainResource =
static_cast<void*>(mainLoader) == static_cast<void*>(client());
- bool isPrivateBrowsing = context->isPrivateBrowsingEnabled();
- PassRefPtr<ResourceLoaderAndroid> loader = ResourceLoaderAndroid::start(this, d->m_firstRequest, context->frameLoaderClient(), isMainResource, false, isPrivateBrowsing);
+ PassRefPtr<ResourceLoaderAndroid> loader = ResourceLoaderAndroid::start(this, d->m_firstRequest, context->frameLoaderClient(), isMainResource, false);
if (loader) {
d->m_loader = loader;
{
SyncLoader s(error, response, data);
RefPtr<ResourceHandle> h = adoptRef(new ResourceHandle(request, &s, false, false));
- bool isPrivateBrowsing = context->isPrivateBrowsingEnabled();
// This blocks until the load is finished.
// Use the request owned by the ResourceHandle. This has had the username
// and password (if present) stripped from the URL in
// ResourceHandleInternal::ResourceHandleInternal(). This matches the
// behaviour in the asynchronous case.
- ResourceLoaderAndroid::start(h.get(), request, context->frameLoaderClient(), false, true, isPrivateBrowsing);
+ ResourceLoaderAndroid::start(h.get(), request, context->frameLoaderClient(), false, true);
}
} // namespace WebCore
class ResourceLoaderAndroid : public RefCounted<ResourceLoaderAndroid> {
public:
- static PassRefPtr<ResourceLoaderAndroid> start(ResourceHandle*, const ResourceRequest&, FrameLoaderClient*, bool isMainResource, bool isSync, bool isPrivateBrowsing);
+ static PassRefPtr<ResourceLoaderAndroid> start(ResourceHandle*, const ResourceRequest&, FrameLoaderClient*, bool isMainResource, bool isSync);
virtual ~ResourceLoaderAndroid() { }
virtual void cancel() = 0;
virtual PassRefPtr<DocumentLoader> createDocumentLoader(const ResourceRequest&, const SubstituteData&);
virtual void setTitle(const String& title, const KURL&);
+ // This provides the userAgent to WebCore. It is used by WebCore to
+ // populate navigator.userAgent and to set the HTTP header in
+ // ResourceRequest objects. We also set a userAgent on WebRequestContext
+ // for the Chromium HTTP stack, which overrides the value on the
+ // ResourceRequest.
virtual String userAgent(const KURL&);
-
+
virtual void savePlatformDataToCachedFrame(WebCore::CachedFrame*);
virtual void transitionToCommittedFromCachedFrame(WebCore::CachedFrame*);
virtual void transitionToCommittedForNewPage();
return frame()->loader()->activeDocumentLoader()->mainResourceLoader();
}
-bool FrameNetworkingContextAndroid::isPrivateBrowsingEnabled() const
-{
- return frame()->settings() && frame()->settings()->privateBrowsingEnabled();
-}
-
FrameLoaderClient* FrameNetworkingContextAndroid::frameLoaderClient() const
{
return frame()->loader()->client();
FrameNetworkingContextAndroid(WebCore::Frame*);
virtual WebCore::MainResourceLoader* mainResourceLoader() const;
- virtual bool isPrivateBrowsingEnabled() const;
virtual WebCore::FrameLoaderClient* frameLoaderClient() const;
};
#include <config.h>
#include <ResourceLoaderAndroid.h>
+#include "Frame.h"
#include "FrameLoaderClientAndroid.h"
#include "WebCoreFrameBridge.h"
#include "WebCoreResourceLoader.h"
#include "WebUrlLoader.h"
+#include "WebViewCore.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)
{
// Called on main thread
+ FrameLoaderClientAndroid* clientAndroid = static_cast<FrameLoaderClientAndroid*>(client);
#if USE(CHROME_NETWORK_STACK)
- return WebUrlLoader::start(client, handle, request, isSync, isPrivateBrowsing);
+ WebViewCore* webViewCore = WebViewCore::getWebViewCore(clientAndroid->getFrame()->view());
+ return WebUrlLoader::start(client, handle, request, isSync, webViewCore->webRequestContext());
#else
- FrameLoaderClientAndroid* clientAndroid = static_cast<FrameLoaderClientAndroid*> (client);
return clientAndroid->webFrame()->startLoadingResource(handle, request, isMainResource, isSync);
#endif
}
static std::string storageDirectory(bool isPrivateBrowsing)
{
+ // TODO: Where is the right place to put the db for private browsing? Should
+ // it be kept in memory?
static const char* const kDirectory = "/webviewCacheChromium";
static const char* const kDirectoryPrivate = "/webviewCacheChromiumPrivate";
delete data;
}
-void WebRequest::start(bool isPrivateBrowsing)
+void WebRequest::start(WebRequestContext* context)
{
ASSERT(m_loadState == Created, "Start called on a WebRequest not in CREATED state: (%s)", m_url.c_str());
if (m_request->url().SchemeIs("browser"))
return handleBrowserURL(m_request->url());
- URLRequestContext* context = WebRequestContext::get(isPrivateBrowsing);
m_request->set_context(context);
m_request->Start();
#define WebRequest_h
#include "ChromiumIncludes.h"
-#include "wtf/Vector.h"
+#include <wtf/Vector.h>
class MessageLoop;
};
class UrlInterceptResponse;
-class WebResourceRequest;
class WebFrame;
+class WebRequestContext;
+class WebResourceRequest;
class WebUrlLoaderClient;
// All methods in this class must be called on the io thread
void appendBytesToUpload(Vector<char>* data);
void appendFileToUpload(const std::string& filename);
- void start(bool isPrivateBrowsing);
+ void start(WebRequestContext*);
void cancel();
// From URLRequest::Delegate
#include <dirent.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("");
-Lock userAgentLock;
-
-std::string acceptLanguageStdString("");
-WTF::String acceptLanguageWtfString("");
-WTF::Mutex acceptLanguageMutex;
-}
+static std::string acceptLanguageStdString("");
+static WTF::String acceptLanguageWtfString("");
+static WTF::Mutex acceptLanguageMutex;
+
+static int numPrivateBrowsingInstances;
+static WTF::Mutex numPrivateBrowsingInstancesMutex;
using namespace WTF;
namespace android {
-static scoped_refptr<WebRequestContext> privateBrowsingContext(0);
-static WTF::Mutex privateBrowsingContextMutex;
-
-WebRequestContext::WebRequestContext()
+WebRequestContext::WebRequestContext(bool isPrivateBrowsing)
+ : m_isPrivateBrowsing(isPrivateBrowsing)
{
+ // Initialize chromium logging, needs to be done before any chromium code is called.
+ initChromiumLogging();
+
+ WebCache* cache = WebCache::get(m_isPrivateBrowsing);
+ host_resolver_ = cache->hostResolver();
+ http_transaction_factory_ = cache->cache();
+
+ WebCookieJar* cookieJar = WebCookieJar::get(m_isPrivateBrowsing);
+ cookie_store_ = cookieJar->cookieStore();
+ cookie_policy_ = cookieJar;
+
// Also hardcoded in FrameLoader.java
accept_charset_ = "utf-8, iso-8859-1, utf-16, *;q=0.7";
+
+ if (m_isPrivateBrowsing) {
+ MutexLocker lock(numPrivateBrowsingInstancesMutex);
+ numPrivateBrowsingInstances++;
+ }
}
WebRequestContext::~WebRequestContext()
{
+ if (m_isPrivateBrowsing) {
+ MutexLocker lock(numPrivateBrowsingInstancesMutex);
+ numPrivateBrowsingInstances--;
+ }
}
-void WebRequestContext::setUserAgent(String string)
+void WebRequestContext::setUserAgent(const String& string)
{
- // The useragent is set on the WebCore thread and read on the network
- // stack's IO thread.
- AutoLock aLock(userAgentLock);
- userAgent = string.utf8().data();
+ MutexLocker lock(m_userAgentMutex);
+ m_userAgent = string.utf8().data();
}
const std::string& WebRequestContext::GetUserAgent(const GURL& url) const
{
- // The useragent is set on the WebCore thread and read on the network
- // stack's IO thread.
- AutoLock aLock(userAgentLock);
- ASSERT(userAgent != "");
- return userAgent;
+ MutexLocker lock(m_userAgentMutex);
+ return m_userAgent;
}
void WebRequestContext::setAcceptLanguage(const String& string)
return acceptLanguageWtfString;
}
-WebRequestContext* WebRequestContext::getImpl(bool isPrivateBrowsing)
-{
- WebRequestContext* context = new WebRequestContext();
-
- 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();
- context->cookie_policy_ = cookieJar;
-
- return context;
-}
-
-WebRequestContext* WebRequestContext::getRegularContext()
-{
- static scoped_refptr<WebRequestContext> regularContext(0);
- if (!regularContext)
- regularContext = getImpl(false);
- return regularContext;
-}
-
-WebRequestContext* WebRequestContext::getPrivateBrowsingContext()
-{
- MutexLocker lock(privateBrowsingContextMutex);
-
- // TODO: Where is the right place to put the temporary db? Should it be
- // kept in memory?
- if (!privateBrowsingContext)
- privateBrowsingContext = getImpl(true);
- return privateBrowsingContext;
-}
-
-WebRequestContext* WebRequestContext::get(bool isPrivateBrowsing)
-{
- // Initialize chromium logging, needs to be done before any chromium code is called
- initChromiumLogging();
-
- return isPrivateBrowsing ? getPrivateBrowsingContext() : getRegularContext();
-}
-
void WebRequestContext::removeFileOrDirectory(const char* filename)
{
struct stat filetype;
// This is called on the UI thread.
// TODO: This should be done on a different thread. Moving to the WebKit
// thread should be straightforward and safe. See b/3243891.
- MutexLocker lock(privateBrowsingContextMutex);
+ MutexLocker lock(numPrivateBrowsingInstancesMutex);
- if (!privateBrowsingContext || privateBrowsingContext->HasOneRef()) {
- privateBrowsingContext = 0;
+ // If there are private browsing contexts in use, do nothing.
+ if (numPrivateBrowsingInstances)
+ return false;
- WebCookieJar::cleanup(true);
- WebCache::cleanup(true);
- return true;
- }
- return false;
+ WebCookieJar::cleanup(true);
+ WebCache::cleanup(true);
+ return true;
}
} // namespace android
namespace android {
-// This class is generally not threadsafe. .get() is not threadsafe - instances
-// are created on the WebCore thread only.
+// This class is generally not threadsafe.
class WebRequestContext : public URLRequestContext {
public:
// URLRequestContext overrides.
virtual const std::string& GetUserAgent(const GURL&) const;
virtual const std::string& GetAcceptLanguage() const;
- // Lazily create the relevant context. This class holds a reference.
- static WebRequestContext* get(bool isPrivateBrowsing);
+ WebRequestContext(bool isPrivateBrowsing);
// These methods are threadsafe.
static bool cleanupPrivateBrowsingFiles();
- static void setUserAgent(WTF::String);
+ void setUserAgent(const WTF::String&);
static void setAcceptLanguage(const WTF::String&);
static const WTF::String& acceptLanguage();
WebRequestContext();
~WebRequestContext();
- static WebRequestContext* getImpl(bool isPrivateBrowsing);
- static WebRequestContext* getRegularContext();
- static WebRequestContext* getPrivateBrowsingContext();
-
+ std::string m_userAgent;
+ mutable WTF::Mutex m_userAgentMutex;
+ bool m_isPrivateBrowsing;
};
} // namespace android
{
}
-PassRefPtr<WebUrlLoader> WebUrlLoader::start(FrameLoaderClient* client, 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, WebRequestContext* context)
{
FrameLoaderClientAndroid* androidClient = static_cast<FrameLoaderClientAndroid*>(client);
WebFrame* webFrame = androidClient->webFrame();
webFrame->maybeSavePassword(androidClient->getFrame(), resourceRequest);
RefPtr<WebUrlLoader> loader = WebUrlLoader::create(webFrame, resourceHandle, resourceRequest);
- loader->m_loaderClient->start(isSync, isPrivateBrowsing);
+ loader->m_loaderClient->start(isSync, context);
return loader.release();
}
namespace android {
class WebUrlLoaderClient;
class WebFrame;
+class WebRequestContext;
class WebUrlLoader : public ResourceLoaderAndroid {
public:
virtual ~WebUrlLoader();
- static PassRefPtr<WebUrlLoader> start(FrameLoaderClient* client, WebCore::ResourceHandle*, const WebCore::ResourceRequest&, bool sync, bool isPrivateBrowsing);
+ static PassRefPtr<WebUrlLoader> start(FrameLoaderClient* client, WebCore::ResourceHandle*, const WebCore::ResourceRequest&, bool sync, WebRequestContext*);
virtual void cancel();
virtual void downloadFile();
}
}
-bool WebUrlLoaderClient::start(bool sync, bool isPrivateBrowsing)
+bool WebUrlLoaderClient::start(bool sync, WebRequestContext* context)
{
base::Thread* thread = ioThread();
if (!thread) {
m_sync = sync;
if (m_sync) {
AutoLock autoLock(*syncLock());
- thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::start, isPrivateBrowsing));
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::start, context));
// Run callbacks until the queue is exhausted and m_finished is true.
while(!m_finished) {
m_resourceHandle = 0;
} else {
// Asynchronous start.
- thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::start, isPrivateBrowsing));
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::start, context));
}
return true;
}
class WebFrame;
class WebRequest;
+class WebRequestContext;
// This class handles communication between the IO thread where loading happens
// and the webkit main thread.
WebUrlLoaderClient(WebFrame*, WebCore::ResourceHandle*, const WebCore::ResourceRequest&);
// Called from WebCore, will be forwarded to the IO thread
- bool start(bool sync, bool isPrivateBrowsing);
+ bool start(bool sync, WebRequestContext*);
void cancel();
void downloadFile();
void pauseLoad(bool pause) {} // Android method, does nothing for now
return;
mFormManager = new FormManager();
- AndroidURLRequestContextGetter::Get()->SetURLRequestContext(WebRequestContext::get(false /* isPrivateBrowsing */));
+ // We use the WebView's WebRequestContext, which may be a private browsing context.
+ ASSERT(mWebViewCore);
+ AndroidURLRequestContextGetter::Get()->SetURLRequestContext(mWebViewCore->webRequestContext());
AndroidURLRequestContextGetter::Get()->SetIOThread(WebUrlLoaderClient::ioThread());
mTabContents = new TabContents();
mAutoFillManager = new AutoFillManager(mTabContents.get());
#include "WorkerContextExecutionProxy.h"
#endif
#include "WebRequestContext.h"
+#include "WebViewCore.h"
#include <JNIHelp.h>
#include <utils/misc.h>
str = (jstring)env->GetObjectField(obj, gFieldIds->mUserAgent);
WebFrame::getWebFrame(pFrame)->setUserAgent(jstringToWtfString(env, str));
#if USE(CHROME_NETWORK_STACK)
- WebRequestContext::setUserAgent(jstringToWtfString(env, str));
+ WebViewCore::getWebViewCore(pFrame->view())->setWebRequestContextUserAgent();
+
str = (jstring)env->GetObjectField(obj, gFieldIds->mAcceptLanguage);
WebRequestContext::setAcceptLanguage(jstringToWtfString(env, str));
#endif
gWebViewCoreFields.m_drawIsPaused);
}
+#if USE(CHROME_NETWORK_STACK)
+void WebViewCore::setWebRequestContextUserAgent()
+{
+ if (m_webRequestContext)
+ m_webRequestContext->setUserAgent(WebFrame::getWebFrame(m_mainFrame)->userAgentForURL(0)); // URL not used
+}
+
+WebRequestContext* WebViewCore::webRequestContext()
+{
+ if (!m_webRequestContext) {
+ Settings* settings = mainFrame()->settings();
+ m_webRequestContext = new WebRequestContext(settings && settings->privateBrowsingEnabled());
+ setWebRequestContextUserAgent();
+ }
+ return m_webRequestContext.get();
+}
+#endif
+
//----------------------------------------------------------------------
// Native JNI methods
//----------------------------------------------------------------------
#ifndef WEBVIEWCORE_H
#define WEBVIEWCORE_H
-#include "android_npapi.h"
-#include "FileChooser.h"
#include "CacheBuilder.h"
#include "CachedHistory.h"
#include "DeviceMotionAndOrientationManager.h"
#include "DOMSelection.h"
+#include "FileChooser.h"
#include "PictureSet.h"
#include "PlatformGraphicsContext.h"
#include "SkColor.h"
#include "Timer.h"
#include "WebCoreRefObject.h"
#include "WebCoreJni.h"
+#include "WebRequestContext.h"
+#include "android_npapi.h"
+
#include <jni.h>
#include <ui/KeycodeLabels.h>
#include <ui/PixelFormat.h>
bool isPaused() const { return m_isPaused; }
void setIsPaused(bool isPaused) { m_isPaused = isPaused; }
bool drawIsPaused() const;
+ void setWebRequestContextUserAgent();
+ WebRequestContext* webRequestContext();
// end of shared members
// internal functions
bool setSelection(DOMSelection* selection, Text* textNode, int direction);
bool setSelection(DOMSelection* selection, Node* startNode, Node* endNode, int startOffset, int endOffset);
Node* m_currentNodeDomNavigationAxis;
-
#if ENABLE(TOUCH_EVENTS)
bool m_forwardingTouchEvents;
#endif
-
#if DEBUG_NAV_UI
uint32_t m_now;
#endif
-
DeviceMotionAndOrientationManager m_deviceMotionAndOrientationManager;
+#if USE(CHROME_NETWORK_STACK)
+ scoped_refptr<WebRequestContext> m_webRequestContext;
+#endif
private:
// called from constructor, to add this to a global list