Add StoragePartition's ProtocolHandlers at URLRequestContext construction time. 
Previously they were added later which doesn't mesh with pending 
URLRequestJobFactory API changes. 

BUG=146602,161529

Review URL: https://chromiumcodereview.appspot.com/11308362

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@181519 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc
index d7f9789..8043adc 100644
--- a/android_webview/browser/aw_browser_context.cc
+++ b/android_webview/browser/aw_browser_context.cc
@@ -6,10 +6,40 @@
 
 #include "android_webview/browser/net/aw_url_request_context_getter.h"
 #include "components/visitedlink/browser/visitedlink_master.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/resource_context.h"
+#include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
+#include "net/url_request/url_request_context.h"
 
 namespace android_webview {
 
+namespace {
+
+class AwResourceContext : public content::ResourceContext {
+ public:
+  explicit AwResourceContext(net::URLRequestContextGetter* getter)
+      : getter_(getter) {}
+  virtual ~AwResourceContext() {}
+
+  // content::ResourceContext implementation.
+  virtual net::HostResolver* GetHostResolver() OVERRIDE {
+    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+    return getter_->GetURLRequestContext()->host_resolver();
+  }
+  virtual net::URLRequestContext* GetRequestContext() OVERRIDE {
+    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+    return getter_->GetURLRequestContext();
+  }
+
+ private:
+  net::URLRequestContextGetter* getter_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwResourceContext);
+};
+
+}  // namespace
+
 AwBrowserContext::AwBrowserContext(
     const FilePath path,
     GeolocationPermissionFactoryFn* geolocation_permission_factory)
@@ -43,6 +73,43 @@
   visitedlink_master_->AddURLs(urls);
 }
 
+net::URLRequestContextGetter* AwBrowserContext::CreateRequestContext(
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  CHECK(url_request_context_getter_);
+  url_request_context_getter_->SetProtocolHandlers(
+      blob_protocol_handler.Pass(), file_system_protocol_handler.Pass(),
+      developer_protocol_handler.Pass(), chrome_protocol_handler.Pass(),
+      chrome_devtools_protocol_handler.Pass());
+  return url_request_context_getter_.get();
+}
+
+net::URLRequestContextGetter*
+AwBrowserContext::CreateRequestContextForStoragePartition(
+    const FilePath& partition_path,
+    bool in_memory,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  CHECK(url_request_context_getter_);
+  return url_request_context_getter_.get();
+}
+
 FilePath AwBrowserContext::GetPath() {
   return context_storage_path_;
 }
@@ -53,8 +120,7 @@
 }
 
 net::URLRequestContextGetter* AwBrowserContext::GetRequestContext() {
-  DCHECK(url_request_context_getter_);
-  return url_request_context_getter_;
+  return GetDefaultStoragePartition(this)->GetURLRequestContext();
 }
 
 net::URLRequestContextGetter*
@@ -63,13 +129,6 @@
   return GetRequestContext();
 }
 
-net::URLRequestContextGetter*
-AwBrowserContext::GetRequestContextForStoragePartition(
-    const FilePath& partition_path,
-    bool in_memory) {
-  return GetRequestContext();
-}
-
 net::URLRequestContextGetter* AwBrowserContext::GetMediaRequestContext() {
   return GetRequestContext();
 }
@@ -88,7 +147,12 @@
 }
 
 content::ResourceContext* AwBrowserContext::GetResourceContext() {
-  return url_request_context_getter_->GetResourceContext();
+  if (!resource_context_) {
+    CHECK(url_request_context_getter_);
+    resource_context_.reset(new AwResourceContext(
+        url_request_context_getter_.get()));
+  }
+  return resource_context_.get();
 }
 
 content::DownloadManagerDelegate*
diff --git a/android_webview/browser/aw_browser_context.h b/android_webview/browser/aw_browser_context.h
index 198c9709..b7f1b37 100644
--- a/android_webview/browser/aw_browser_context.h
+++ b/android_webview/browser/aw_browser_context.h
@@ -8,11 +8,15 @@
 #include <vector>
 
 #include "android_webview/browser/aw_download_manager_delegate.h"
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
 #include "base/file_path.h"
 #include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
 #include "components/visitedlink/browser/visitedlink_delegate.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/geolocation_permission_context.h"
+#include "net/url_request/url_request_job_factory.h"
 
 class GURL;
 
@@ -21,6 +25,7 @@
 }  // namespace components
 
 namespace content {
+class ResourceContext;
 class WebContents;
 }  // namespace content
 
@@ -53,14 +58,37 @@
   // These methods map to Add methods in components::VisitedLinkMaster.
   void AddVisitedURLs(const std::vector<GURL>& urls);
 
+  net::URLRequestContextGetter* CreateRequestContext(
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler);
+  net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
+      const FilePath& partition_path,
+      bool in_memory,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler);
+
   // content::BrowserContext implementation.
   virtual FilePath GetPath() OVERRIDE;
   virtual bool IsOffTheRecord() const OVERRIDE;
   virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE;
   virtual net::URLRequestContextGetter* GetRequestContextForRenderProcess(
       int renderer_child_id) OVERRIDE;
-  virtual net::URLRequestContextGetter* GetRequestContextForStoragePartition(
-      const FilePath& partition_path, bool in_memory) OVERRIDE;
   virtual net::URLRequestContextGetter* GetMediaRequestContext() OVERRIDE;
   virtual net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess(
       int renderer_child_id) OVERRIDE;
@@ -81,7 +109,6 @@
       const scoped_refptr<URLEnumerator>& enumerator) OVERRIDE;
 
  private:
-
   // The file path where data for this context is persisted.
   FilePath context_storage_path_;
 
@@ -93,6 +120,7 @@
   AwDownloadManagerDelegate download_manager_delegate_;
 
   scoped_ptr<components::VisitedLinkMaster> visitedlink_master_;
+  scoped_ptr<content::ResourceContext> resource_context_;
 
   DISALLOW_COPY_AND_ASSIGN(AwBrowserContext);
 };
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index 03f631d..8bd40a4 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -101,6 +101,49 @@
       host->GetID(), chrome::kFileScheme);
 }
 
+net::URLRequestContextGetter*
+AwContentBrowserClient::CreateRequestContext(
+    content::BrowserContext* browser_context,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  DCHECK(browser_context_.get() == browser_context);
+  return browser_context_->CreateRequestContext(
+      blob_protocol_handler.Pass(), file_system_protocol_handler.Pass(),
+      developer_protocol_handler.Pass(), chrome_protocol_handler.Pass(),
+      chrome_devtools_protocol_handler.Pass());
+}
+
+net::URLRequestContextGetter*
+AwContentBrowserClient::CreateRequestContextForStoragePartition(
+    content::BrowserContext* browser_context,
+    const FilePath& partition_path,
+    bool in_memory,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  DCHECK(browser_context_.get() == browser_context);
+  return browser_context_->CreateRequestContextForStoragePartition(
+      partition_path, in_memory, blob_protocol_handler.Pass(),
+      file_system_protocol_handler.Pass(),
+      developer_protocol_handler.Pass(), chrome_protocol_handler.Pass(),
+      chrome_devtools_protocol_handler.Pass());
+}
+
 std::string AwContentBrowserClient::GetCanonicalEncodingNameByAliasName(
     const std::string& alias_name) {
   return alias_name;
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index 2f5dee04f..59a1c9e 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -5,10 +5,12 @@
 #ifndef ANDROID_WEBVIEW_LIB_AW_CONTENT_BROWSER_CLIENT_H_
 #define ANDROID_WEBVIEW_LIB_AW_CONTENT_BROWSER_CLIENT_H_
 
-#include "content/public/browser/content_browser_client.h"
-
 #include "android_webview/browser/aw_browser_context.h"
+#include "base/basictypes.h"
 #include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/content_browser_client.h"
+#include "net/url_request/url_request_job_factory.h"
 
 namespace android_webview {
 
@@ -37,6 +39,32 @@
       content::WebContents* web_contents) OVERRIDE;
   virtual void RenderProcessHostCreated(
       content::RenderProcessHost* host) OVERRIDE;
+  virtual net::URLRequestContextGetter* CreateRequestContext(
+      content::BrowserContext* browser_context,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) OVERRIDE;
+  virtual net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
+      content::BrowserContext* browser_context,
+      const FilePath& partition_path,
+      bool in_memory,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) OVERRIDE;
   virtual std::string GetCanonicalEncodingNameByAliasName(
       const std::string& alias_name) OVERRIDE;
   virtual void AppendExtraCommandLineSwitches(CommandLine* command_line,
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc
index f80f0c24..6ec1aad7 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.cc
+++ b/android_webview/browser/net/aw_url_request_context_getter.cc
@@ -11,7 +11,6 @@
 #include "android_webview/browser/net/init_native_callback.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/resource_context.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/url_constants.h"
 #include "net/http/http_cache.h"
@@ -26,40 +25,6 @@
 
 namespace android_webview {
 
-namespace {
-
-class AwResourceContext : public content::ResourceContext {
- public:
-  AwResourceContext(net::URLRequestContext* getter);
-  virtual ~AwResourceContext();
-  virtual net::HostResolver* GetHostResolver() OVERRIDE;
-  virtual net::URLRequestContext* GetRequestContext() OVERRIDE;
-
- private:
-  net::URLRequestContext* context_;  // weak
-
-  DISALLOW_COPY_AND_ASSIGN(AwResourceContext);
-};
-
-AwResourceContext::AwResourceContext(net::URLRequestContext* context)
-    : context_(context) {
-}
-
-AwResourceContext::~AwResourceContext() {
-}
-
-net::HostResolver* AwResourceContext::GetHostResolver() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  return context_->host_resolver();
-}
-
-net::URLRequestContext* AwResourceContext::GetRequestContext() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  return context_;
-}
-
-}  // namespace
-
 AwURLRequestContextGetter::AwURLRequestContextGetter(
     AwBrowserContext* browser_context)
     : browser_context_(browser_context),
@@ -95,14 +60,6 @@
 
   url_request_context_.reset(builder.Build());
 
-  scoped_ptr<AwURLRequestJobFactory> job_factory(new AwURLRequestJobFactory);
-  bool set_protocol = job_factory->SetProtocolHandler(
-      chrome::kFileScheme, new net::FileProtocolHandler());
-  DCHECK(set_protocol);
-  set_protocol = job_factory->SetProtocolHandler(
-      chrome::kDataScheme, new net::DataProtocolHandler());
-  DCHECK(set_protocol);
-
   // TODO(mnaganov): Fix URLRequestContextBuilder to use proper threads.
   net::HttpNetworkSession::Params network_session_params;
   PopulateNetworkSessionParams(&network_session_params);
@@ -115,14 +72,6 @@
           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)));
   main_http_factory_.reset(main_cache);
   url_request_context_->set_http_transaction_factory(main_cache);
-
-  job_factory_ = CreateAndroidJobFactoryAndCookieMonster(
-      url_request_context_.get(), job_factory.Pass());
-  job_factory_.reset(new net::ProtocolInterceptJobFactory(
-      job_factory_.Pass(),
-      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(
-          new AwRequestInterceptor())));
-  url_request_context_->set_job_factory(job_factory_.get());
 }
 
 void AwURLRequestContextGetter::PopulateNetworkSessionParams(
@@ -140,15 +89,46 @@
   params->net_log = context->net_log();
 }
 
-content::ResourceContext* AwURLRequestContextGetter::GetResourceContext() {
-  DCHECK(url_request_context_);
-  if (!resource_context_)
-    resource_context_.reset(new AwResourceContext(url_request_context_.get()));
-  return resource_context_.get();
-}
-
 net::URLRequestContext* AwURLRequestContextGetter::GetURLRequestContext() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  if (!job_factory_) {
+    scoped_ptr<AwURLRequestJobFactory> job_factory(new AwURLRequestJobFactory);
+    bool set_protocol = job_factory->SetProtocolHandler(
+        chrome::kFileScheme, new net::FileProtocolHandler());
+    DCHECK(set_protocol);
+    set_protocol = job_factory->SetProtocolHandler(
+        chrome::kDataScheme, new net::DataProtocolHandler());
+    DCHECK(set_protocol);
+    DCHECK(blob_protocol_handler_);
+    set_protocol = job_factory->SetProtocolHandler(
+        chrome::kBlobScheme, blob_protocol_handler_.release());
+    DCHECK(set_protocol);
+    DCHECK(file_system_protocol_handler_);
+    set_protocol = job_factory->SetProtocolHandler(
+        chrome::kFileSystemScheme, file_system_protocol_handler_.release());
+    DCHECK(set_protocol);
+    DCHECK(chrome_protocol_handler_);
+    set_protocol = job_factory->SetProtocolHandler(
+        chrome::kChromeUIScheme, chrome_protocol_handler_.release());
+    DCHECK(set_protocol);
+    DCHECK(chrome_devtools_protocol_handler_);
+    set_protocol = job_factory->SetProtocolHandler(
+        chrome::kChromeDevToolsScheme,
+        chrome_devtools_protocol_handler_.release());
+    DCHECK(set_protocol);
+    // Create a chain of URLRequestJobFactories.  Keep |job_factory_| pointed
+    // at the beginning of the chain.
+    job_factory_ = CreateAndroidJobFactoryAndCookieMonster(
+        url_request_context_.get(), job_factory.Pass());
+    job_factory_.reset(new net::ProtocolInterceptJobFactory(
+        job_factory_.Pass(),
+        scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(
+            new AwRequestInterceptor())));
+    job_factory_.reset(new net::ProtocolInterceptJobFactory(
+        job_factory_.Pass(),
+        developer_protocol_handler_.Pass()));
+    url_request_context_->set_job_factory(job_factory_.get());
+  }
   return url_request_context_.get();
 }
 
@@ -157,4 +137,22 @@
   return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
 }
 
+void AwURLRequestContextGetter::SetProtocolHandlers(
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  blob_protocol_handler_ = blob_protocol_handler.Pass();
+  file_system_protocol_handler_ = file_system_protocol_handler.Pass();
+  developer_protocol_handler_ = developer_protocol_handler.Pass();
+  chrome_protocol_handler_ = chrome_protocol_handler.Pass();
+  chrome_devtools_protocol_handler_ = chrome_devtools_protocol_handler.Pass();
+}
+
 }  // namespace android_webview
diff --git a/android_webview/browser/net/aw_url_request_context_getter.h b/android_webview/browser/net/aw_url_request_context_getter.h
index c5b9ecf4..cc2d81fa 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.h
+++ b/android_webview/browser/net/aw_url_request_context_getter.h
@@ -5,15 +5,13 @@
 #ifndef ANDROID_WEBVIEW_BROWSER_NET_AW_URL_REQUEST_CONTEXT_GETTER_H_
 #define ANDROID_WEBVIEW_BROWSER_NET_AW_URL_REQUEST_CONTEXT_GETTER_H_
 
-#include "content/public/browser/browser_thread_delegate.h"
-
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
+#include "content/public/browser/browser_thread_delegate.h"
 #include "net/http/http_network_session.h"
 #include "net/url_request/url_request_context_getter.h"
-
-namespace content {
-class ResourceContext;
-}
+#include "net/url_request/url_request_job_factory.h"
 
 namespace net {
 class HttpTransactionFactory;
@@ -30,12 +28,10 @@
 class AwURLRequestContextGetter : public net::URLRequestContextGetter,
                                   public content::BrowserThreadDelegate {
  public:
-  AwURLRequestContextGetter(AwBrowserContext* browser_context);
+  explicit AwURLRequestContextGetter(AwBrowserContext* browser_context);
 
   void InitializeOnNetworkThread();
 
-  content::ResourceContext* GetResourceContext();
-
   // content::BrowserThreadDelegate implementation.
   virtual void Init() OVERRIDE;
   virtual void CleanUp() OVERRIDE {}
@@ -46,17 +42,48 @@
       GetNetworkTaskRunner() const OVERRIDE;
 
  private:
+  friend class AwBrowserContext;
+
   virtual ~AwURLRequestContextGetter();
 
+  // Prior to GetURLRequestContext() being called, SetProtocolHandlers() is
+  // called to hand over the ProtocolHandlers that GetURLRequestContext() will
+  // later install into |job_factory_|.  This ordering is enforced by having
+  // AwBrowserContext::CreateRequestContext() call SetProtocolHandlers().
+  // SetProtocolHandlers() is necessary because the ProtocolHandlers are created
+  // on the UI thread while |job_factory_| must be created on the IO thread.
+  void SetProtocolHandlers(
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler);
+
   void PopulateNetworkSessionParams(net::HttpNetworkSession::Params* params);
 
   AwBrowserContext* browser_context_;  // weak
   scoped_ptr<net::URLRequestContext> url_request_context_;
   scoped_ptr<net::ProxyConfigService> proxy_config_service_;
-  scoped_ptr<content::ResourceContext> resource_context_;
   scoped_ptr<net::URLRequestJobFactory> job_factory_;
   scoped_ptr<net::HttpTransactionFactory> main_http_factory_;
 
+  // ProtocolHandlers are stored here between SetProtocolHandlers() and the
+  // first GetURLRequestContext() call.
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> blob_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      file_system_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      developer_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      chrome_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      chrome_devtools_protocol_handler_;
+
   DISALLOW_COPY_AND_ASSIGN(AwURLRequestContextGetter);
 };
 
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 78e9939..ed551048 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -798,6 +798,53 @@
   return true;
 }
 
+net::URLRequestContextGetter*
+ChromeContentBrowserClient::CreateRequestContext(
+    content::BrowserContext* browser_context,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  Profile* profile = Profile::FromBrowserContext(browser_context);
+  return profile->CreateRequestContext(blob_protocol_handler.Pass(),
+                                       file_system_protocol_handler.Pass(),
+                                       developer_protocol_handler.Pass(),
+                                       chrome_protocol_handler.Pass(),
+                                       chrome_devtools_protocol_handler.Pass());
+}
+
+net::URLRequestContextGetter*
+ChromeContentBrowserClient::CreateRequestContextForStoragePartition(
+    content::BrowserContext* browser_context,
+    const FilePath& partition_path,
+    bool in_memory,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  Profile* profile = Profile::FromBrowserContext(browser_context);
+  return profile->CreateRequestContextForStoragePartition(
+      partition_path,
+      in_memory,
+      blob_protocol_handler.Pass(),
+      file_system_protocol_handler.Pass(),
+      developer_protocol_handler.Pass(),
+      chrome_protocol_handler.Pass(),
+      chrome_devtools_protocol_handler.Pass());
+}
+
 bool ChromeContentBrowserClient::IsHandledURL(const GURL& url) {
   return ProfileIOData::IsHandledURL(url);
 }
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 9f2ecc61..b92f5109 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -68,6 +68,32 @@
                                        const GURL& effective_url) OVERRIDE;
   virtual GURL GetEffectiveURL(content::BrowserContext* browser_context,
                                const GURL& url) OVERRIDE;
+  virtual net::URLRequestContextGetter* CreateRequestContext(
+      content::BrowserContext* browser_context,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) OVERRIDE;
+  virtual net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
+      content::BrowserContext* browser_context,
+      const FilePath& partition_path,
+      bool in_memory,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) OVERRIDE;
   virtual bool IsHandledURL(const GURL& url) OVERRIDE;
   virtual bool IsSuitableHost(content::RenderProcessHost* process_host,
                               const GURL& url) OVERRIDE;
diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc
index c57ad45..21d3753 100644
--- a/chrome/browser/net/chrome_url_request_context.cc
+++ b/chrome/browser/net/chrome_url_request_context.cc
@@ -40,15 +40,46 @@
 // Factory that creates the main ChromeURLRequestContext.
 class FactoryForMain : public ChromeURLRequestContextFactory {
  public:
-  explicit FactoryForMain(const ProfileIOData* profile_io_data)
-      : profile_io_data_(profile_io_data) {}
+  FactoryForMain(
+      const ProfileIOData* profile_io_data,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler)
+      : profile_io_data_(profile_io_data),
+        blob_protocol_handler_(blob_protocol_handler.Pass()),
+        file_system_protocol_handler_(file_system_protocol_handler.Pass()),
+        developer_protocol_handler_(developer_protocol_handler.Pass()),
+        chrome_protocol_handler_(chrome_protocol_handler.Pass()),
+        chrome_devtools_protocol_handler_(
+            chrome_devtools_protocol_handler.Pass()) {}
 
   virtual ChromeURLRequestContext* Create() OVERRIDE {
+    profile_io_data_->Init(blob_protocol_handler_.Pass(),
+                           file_system_protocol_handler_.Pass(),
+                           developer_protocol_handler_.Pass(),
+                           chrome_protocol_handler_.Pass(),
+                           chrome_devtools_protocol_handler_.Pass());
     return profile_io_data_->GetMainRequestContext();
   }
 
  private:
   const ProfileIOData* const profile_io_data_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> blob_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      file_system_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      developer_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      chrome_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      chrome_devtools_protocol_handler_;
 };
 
 // Factory that creates the ChromeURLRequestContext for extensions.
@@ -73,11 +104,27 @@
       const StoragePartitionDescriptor& partition_descriptor,
       ChromeURLRequestContextGetter* main_context,
       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-          protocol_handler_interceptor)
+          protocol_handler_interceptor,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler)
       : profile_io_data_(profile_io_data),
         partition_descriptor_(partition_descriptor),
         main_request_context_getter_(main_context),
-        protocol_handler_interceptor_(protocol_handler_interceptor.Pass()) {}
+        protocol_handler_interceptor_(protocol_handler_interceptor.Pass()),
+        blob_protocol_handler_(blob_protocol_handler.Pass()),
+        file_system_protocol_handler_(file_system_protocol_handler.Pass()),
+        developer_protocol_handler_(developer_protocol_handler.Pass()),
+        chrome_protocol_handler_(chrome_protocol_handler.Pass()),
+        chrome_devtools_protocol_handler_(
+            chrome_devtools_protocol_handler.Pass()) {}
 
   virtual ChromeURLRequestContext* Create() OVERRIDE {
     // We will copy most of the state from the main request context.
@@ -87,7 +134,11 @@
     // state onwards.
     return profile_io_data_->GetIsolatedAppRequestContext(
         main_request_context_getter_->GetIOContext(), partition_descriptor_,
-        protocol_handler_interceptor_.Pass());
+        protocol_handler_interceptor_.Pass(), blob_protocol_handler_.Pass(),
+        file_system_protocol_handler_.Pass(),
+        developer_protocol_handler_.Pass(),
+        chrome_protocol_handler_.Pass(),
+        chrome_devtools_protocol_handler_.Pass());
   }
 
  private:
@@ -97,6 +148,16 @@
       main_request_context_getter_;
   scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
       protocol_handler_interceptor_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      blob_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      file_system_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      developer_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      chrome_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      chrome_devtools_protocol_handler_;
 };
 
 // Factory that creates the media ChromeURLRequestContext for a given isolated
@@ -182,10 +243,25 @@
 // static
 ChromeURLRequestContextGetter* ChromeURLRequestContextGetter::CreateOriginal(
     Profile* profile,
-    const ProfileIOData* profile_io_data) {
+    const ProfileIOData* profile_io_data,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
   DCHECK(!profile->IsOffTheRecord());
   return new ChromeURLRequestContextGetter(
-      new FactoryForMain(profile_io_data));
+      new FactoryForMain(profile_io_data,
+                         blob_protocol_handler.Pass(),
+                         file_system_protocol_handler.Pass(),
+                         developer_protocol_handler.Pass(),
+                         chrome_protocol_handler.Pass(),
+                         chrome_devtools_protocol_handler.Pass()));
 }
 
 // static
@@ -213,13 +289,26 @@
     const ProfileIOData* profile_io_data,
     const StoragePartitionDescriptor& partition_descriptor,
     scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-        protocol_handler_interceptor) {
+        protocol_handler_interceptor,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
   DCHECK(!profile->IsOffTheRecord());
   ChromeURLRequestContextGetter* main_context =
       static_cast<ChromeURLRequestContextGetter*>(profile->GetRequestContext());
   return new ChromeURLRequestContextGetter(
       new FactoryForIsolatedApp(profile_io_data, partition_descriptor,
-           main_context, protocol_handler_interceptor.Pass()));
+           main_context, protocol_handler_interceptor.Pass(),
+           blob_protocol_handler.Pass(), file_system_protocol_handler.Pass(),
+           developer_protocol_handler.Pass(), chrome_protocol_handler.Pass(),
+           chrome_devtools_protocol_handler.Pass()));
 }
 
 // static
@@ -238,10 +327,26 @@
 // static
 ChromeURLRequestContextGetter*
 ChromeURLRequestContextGetter::CreateOffTheRecord(
-    Profile* profile, const ProfileIOData* profile_io_data) {
+    Profile* profile,
+    const ProfileIOData* profile_io_data,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
   DCHECK(profile->IsOffTheRecord());
   return new ChromeURLRequestContextGetter(
-      new FactoryForMain(profile_io_data));
+      new FactoryForMain(profile_io_data,
+                         blob_protocol_handler.Pass(),
+                         file_system_protocol_handler.Pass(),
+                         developer_protocol_handler.Pass(),
+                         chrome_protocol_handler.Pass(),
+                         chrome_devtools_protocol_handler.Pass()));
 }
 
 // static
@@ -260,13 +365,26 @@
     const ProfileIOData* profile_io_data,
     const StoragePartitionDescriptor& partition_descriptor,
     scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-        protocol_handler_interceptor) {
+        protocol_handler_interceptor,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
   DCHECK(profile->IsOffTheRecord());
   ChromeURLRequestContextGetter* main_context =
       static_cast<ChromeURLRequestContextGetter*>(profile->GetRequestContext());
   return new ChromeURLRequestContextGetter(
       new FactoryForIsolatedApp(profile_io_data, partition_descriptor,
-          main_context, protocol_handler_interceptor.Pass()));
+          main_context, protocol_handler_interceptor.Pass(),
+          blob_protocol_handler.Pass(), file_system_protocol_handler.Pass(),
+          developer_protocol_handler.Pass(), chrome_protocol_handler.Pass(),
+          chrome_devtools_protocol_handler.Pass()));
 }
 
 // ----------------------------------------------------------------------------
diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h
index 3d54bba8..8958fa8 100644
--- a/chrome/browser/net/chrome_url_request_context.h
+++ b/chrome/browser/net/chrome_url_request_context.h
@@ -96,7 +96,18 @@
   // Create an instance for use with an 'original' (non-OTR) profile. This is
   // expected to get called on the UI thread.
   static ChromeURLRequestContextGetter* CreateOriginal(
-      Profile* profile, const ProfileIOData* profile_io_data);
+      Profile* profile,
+      const ProfileIOData* profile_io_data,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler);
 
   // Create an instance for an original profile for media. This is expected to
   // get called on UI thread. This method takes a profile and reuses the
@@ -116,7 +127,17 @@
       const ProfileIOData* profile_io_data,
       const StoragePartitionDescriptor& partition_descriptor,
       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-          protocol_handler_interceptor);
+          protocol_handler_interceptor,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler);
 
   // Create an instance for an original profile for media with isolated
   // storage. This is expected to get called on UI thread.
@@ -129,7 +150,18 @@
   // Create an instance for use with an OTR profile. This is expected to get
   // called on the UI thread.
   static ChromeURLRequestContextGetter* CreateOffTheRecord(
-      Profile* profile, const ProfileIOData* profile_io_data);
+      Profile* profile,
+      const ProfileIOData* profile_io_data,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler);
 
   // Create an instance for an OTR profile for extensions. This is expected
   // to get called on UI thread.
@@ -143,7 +175,17 @@
       const ProfileIOData* profile_io_data,
       const StoragePartitionDescriptor& partition_descriptor,
       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-          protocol_handler_interceptor);
+          protocol_handler_interceptor,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler);
 
  private:
   virtual ~ChromeURLRequestContextGetter();
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc
index 87f30a2..f883d554 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -254,7 +254,23 @@
 }
 
 net::URLRequestContextGetter* OffTheRecordProfileImpl::GetRequestContext() {
-  return io_data_.GetMainRequestContextGetter();
+  return GetDefaultStoragePartition(this)->GetURLRequestContext();
+}
+
+net::URLRequestContextGetter* OffTheRecordProfileImpl::CreateRequestContext(
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  return io_data_.CreateMainRequestContextGetter(blob_protocol_handler.Pass(),
+      file_system_protocol_handler.Pass(), developer_protocol_handler.Pass(),
+      chrome_protocol_handler.Pass(), chrome_devtools_protocol_handler.Pass());
 }
 
 net::URLRequestContextGetter*
@@ -282,7 +298,7 @@
 OffTheRecordProfileImpl::GetMediaRequestContextForStoragePartition(
     const FilePath& partition_path,
     bool in_memory) {
-  return GetRequestContextForStoragePartition(partition_path, in_memory);
+  return io_data_.GetIsolatedAppRequestContextGetter(partition_path, in_memory);
 }
 
 net::URLRequestContextGetter*
@@ -291,10 +307,23 @@
 }
 
 net::URLRequestContextGetter*
-    OffTheRecordProfileImpl::GetRequestContextForStoragePartition(
+    OffTheRecordProfileImpl::CreateRequestContextForStoragePartition(
         const FilePath& partition_path,
-        bool in_memory) {
-  return io_data_.GetIsolatedAppRequestContextGetter(partition_path, in_memory);
+        bool in_memory,
+        scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+            blob_protocol_handler,
+        scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+            file_system_protocol_handler,
+        scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+            developer_protocol_handler,
+        scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+            chrome_protocol_handler,
+        scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+            chrome_devtools_protocol_handler) {
+  return io_data_.CreateIsolatedAppRequestContextGetter(
+      partition_path, in_memory, blob_protocol_handler.Pass(),
+      file_system_protocol_handler.Pass(), developer_protocol_handler.Pass(),
+      chrome_protocol_handler.Pass(), chrome_devtools_protocol_handler.Pass());
 }
 
 content::ResourceContext* OffTheRecordProfileImpl::GetResourceContext() {
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.h b/chrome/browser/profiles/off_the_record_profile_impl.h
index 8b659bd..78d85fe 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.h
+++ b/chrome/browser/profiles/off_the_record_profile_impl.h
@@ -47,9 +47,30 @@
   virtual PrefServiceSyncable* GetOffTheRecordPrefs() OVERRIDE;
   virtual net::URLRequestContextGetter*
       GetRequestContextForExtensions() OVERRIDE;
-  virtual net::URLRequestContextGetter* GetRequestContextForStoragePartition(
+  virtual net::URLRequestContextGetter* CreateRequestContext(
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) OVERRIDE;
+  virtual net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
       const FilePath& partition_path,
-      bool in_memory) OVERRIDE;
+      bool in_memory,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) OVERRIDE;
   virtual net::SSLConfigService* GetSSLConfigService() OVERRIDE;
   virtual HostContentSettingsMap* GetHostContentSettingsMap() OVERRIDE;
   virtual ProtocolHandlerRegistry* GetProtocolHandlerRegistry() OVERRIDE;
diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc
index 3878470b..6e2e8571 100644
--- a/chrome/browser/profiles/off_the_record_profile_io_data.cc
+++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc
@@ -33,6 +33,7 @@
 #include "net/http/http_cache.h"
 #include "net/http/http_network_session.h"
 #include "net/http/http_server_properties_impl.h"
+#include "net/url_request/protocol_intercept_job_factory.h"
 #include "net/url_request/url_request_job_factory_impl.h"
 #include "webkit/database/database_tracker.h"
 
@@ -68,17 +69,30 @@
 }
 
 scoped_refptr<ChromeURLRequestContextGetter>
-OffTheRecordProfileIOData::Handle::GetMainRequestContextGetter() const {
+OffTheRecordProfileIOData::Handle::CreateMainRequestContextGetter(
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) const {
   // TODO(oshima): Re-enable when ChromeOS only accesses the profile on the UI
   // thread.
 #if !defined(OS_CHROMEOS)
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 #endif  // defined(OS_CHROMEOS)
   LazyInitialize();
-  if (!main_request_context_getter_) {
-    main_request_context_getter_ =
-        ChromeURLRequestContextGetter::CreateOffTheRecord(profile_, io_data_);
-  }
+  DCHECK(!main_request_context_getter_);
+  main_request_context_getter_ =
+      ChromeURLRequestContextGetter::CreateOffTheRecord(
+          profile_, io_data_, blob_protocol_handler.Pass(),
+          file_system_protocol_handler.Pass(),
+          developer_protocol_handler.Pass(), chrome_protocol_handler.Pass(),
+          chrome_devtools_protocol_handler.Pass());
   return main_request_context_getter_;
 }
 
@@ -106,8 +120,31 @@
   StoragePartitionDescriptor descriptor(partition_path, in_memory);
   ChromeURLRequestContextGetterMap::iterator iter =
       app_request_context_getter_map_.find(descriptor);
-  if (iter != app_request_context_getter_map_.end())
-    return iter->second;
+  CHECK(iter != app_request_context_getter_map_.end());
+  return iter->second;
+}
+
+scoped_refptr<ChromeURLRequestContextGetter>
+OffTheRecordProfileIOData::Handle::CreateIsolatedAppRequestContextGetter(
+    const FilePath& partition_path,
+    bool in_memory,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) const {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK(!partition_path.empty());
+  LazyInitialize();
+
+  // Keep a map of request context getters, one per requested app ID.
+  StoragePartitionDescriptor descriptor(partition_path, in_memory);
+  DCHECK_EQ(app_request_context_getter_map_.count(descriptor), 0u);
 
   scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
       protocol_handler_interceptor(
@@ -115,8 +152,10 @@
               CreateJobInterceptorFactory());
   ChromeURLRequestContextGetter* context =
       ChromeURLRequestContextGetter::CreateOffTheRecordForIsolatedApp(
-          profile_, io_data_, descriptor,
-          protocol_handler_interceptor.Pass());
+          profile_, io_data_, descriptor, protocol_handler_interceptor.Pass(),
+          blob_protocol_handler.Pass(), file_system_protocol_handler.Pass(),
+          developer_protocol_handler.Pass(), chrome_protocol_handler.Pass(),
+          chrome_devtools_protocol_handler.Pass());
   app_request_context_getter_map_[descriptor] = context;
 
   return context;
@@ -144,8 +183,18 @@
   DestroyResourceContext();
 }
 
-void OffTheRecordProfileIOData::LazyInitializeInternal(
-    ProfileParams* profile_params) const {
+void OffTheRecordProfileIOData::InitializeInternal(
+    ProfileParams* profile_params,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) const {
   ChromeURLRequestContext* main_context = main_request_context();
 
   IOThread* const io_thread = profile_params->io_thread;
@@ -205,12 +254,27 @@
   scoped_ptr<net::URLRequestJobFactoryImpl> main_job_factory(
       new net::URLRequestJobFactoryImpl());
 
+  bool set_protocol = main_job_factory->SetProtocolHandler(
+      chrome::kBlobScheme, blob_protocol_handler.release());
+  DCHECK(set_protocol);
+  set_protocol = main_job_factory->SetProtocolHandler(
+      chrome::kFileSystemScheme, file_system_protocol_handler.release());
+  DCHECK(set_protocol);
+  set_protocol = main_job_factory->SetProtocolHandler(
+      chrome::kChromeUIScheme, chrome_protocol_handler.release());
+  DCHECK(set_protocol);
+  set_protocol = main_job_factory->SetProtocolHandler(
+      chrome::kChromeDevToolsScheme,
+      chrome_devtools_protocol_handler.release());
+  DCHECK(set_protocol);
   main_job_factory_ = SetUpJobFactoryDefaults(
       main_job_factory.Pass(),
       profile_params->protocol_handler_interceptor.Pass(),
       network_delegate(),
       main_context->ftp_transaction_factory(),
       main_context->ftp_auth_cache());
+  main_job_factory_.reset(new net::ProtocolInterceptJobFactory(
+      main_job_factory_.Pass(), developer_protocol_handler.Pass()));
   main_context->set_job_factory(main_job_factory_.get());
 
 #if defined(ENABLE_EXTENSIONS)
@@ -271,7 +335,17 @@
     ChromeURLRequestContext* main_context,
     const StoragePartitionDescriptor& partition_descriptor,
     scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-        protocol_handler_interceptor) const {
+        protocol_handler_interceptor,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) const {
   AppRequestContext* context = new AppRequestContext(load_time_stats());
 
   // Copy most state from the main context.
@@ -294,12 +368,27 @@
 
   scoped_ptr<net::URLRequestJobFactoryImpl> job_factory(
       new net::URLRequestJobFactoryImpl());
+  bool set_protocol = job_factory->SetProtocolHandler(
+      chrome::kBlobScheme, blob_protocol_handler.release());
+  DCHECK(set_protocol);
+  set_protocol = job_factory->SetProtocolHandler(
+      chrome::kFileSystemScheme, file_system_protocol_handler.release());
+  DCHECK(set_protocol);
+  set_protocol = job_factory->SetProtocolHandler(
+      chrome::kChromeUIScheme, chrome_protocol_handler.release());
+  DCHECK(set_protocol);
+  set_protocol = job_factory->SetProtocolHandler(
+      chrome::kChromeDevToolsScheme,
+      chrome_devtools_protocol_handler.release());
+  DCHECK(set_protocol);
   scoped_ptr<net::URLRequestJobFactory> top_job_factory;
   top_job_factory = SetUpJobFactoryDefaults(job_factory.Pass(),
                                             protocol_handler_interceptor.Pass(),
                                             network_delegate(),
                                             context->ftp_transaction_factory(),
                                             context->ftp_auth_cache());
+  top_job_factory.reset(new net::ProtocolInterceptJobFactory(
+      top_job_factory.Pass(), developer_protocol_handler.Pass()));
   context->SetJobFactory(top_job_factory.Pass());
   return context;
 }
@@ -323,11 +412,26 @@
     ChromeURLRequestContext* main_context,
     const StoragePartitionDescriptor& partition_descriptor,
     scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-        protocol_handler_interceptor) const {
+        protocol_handler_interceptor,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) const {
   // We create per-app contexts on demand, unlike the others above.
   ChromeURLRequestContext* app_request_context =
       InitializeAppRequestContext(main_context, partition_descriptor,
-                                  protocol_handler_interceptor.Pass());
+                                  protocol_handler_interceptor.Pass(),
+                                  blob_protocol_handler.Pass(),
+                                  file_system_protocol_handler.Pass(),
+                                  developer_protocol_handler.Pass(),
+                                  chrome_protocol_handler.Pass(),
+                                  chrome_devtools_protocol_handler.Pass());
   DCHECK(app_request_context);
   return app_request_context;
 }
diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.h b/chrome/browser/profiles/off_the_record_profile_io_data.h
index 877efe94..bc282c0 100644
--- a/chrome/browser/profiles/off_the_record_profile_io_data.h
+++ b/chrome/browser/profiles/off_the_record_profile_io_data.h
@@ -43,13 +43,37 @@
     // safely be used during initialization.
     content::ResourceContext* GetResourceContextNoInit() const;
     scoped_refptr<ChromeURLRequestContextGetter>
-        GetMainRequestContextGetter() const;
+        CreateMainRequestContextGetter(
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                blob_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                file_system_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                developer_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                chrome_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                chrome_devtools_protocol_handler) const;
     scoped_refptr<ChromeURLRequestContextGetter>
         GetExtensionsRequestContextGetter() const;
     scoped_refptr<ChromeURLRequestContextGetter>
         GetIsolatedAppRequestContextGetter(
             const FilePath& partition_path,
             bool in_memory) const;
+    scoped_refptr<ChromeURLRequestContextGetter>
+        CreateIsolatedAppRequestContextGetter(
+            const FilePath& partition_path,
+            bool in_memory,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                blob_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                file_system_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                developer_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                chrome_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                chrome_devtools_protocol_handler) const;
 
    private:
     typedef std::map<StoragePartitionDescriptor,
@@ -94,15 +118,35 @@
   OffTheRecordProfileIOData();
   virtual ~OffTheRecordProfileIOData();
 
-  virtual void LazyInitializeInternal(
-      ProfileParams* profile_params) const OVERRIDE;
+  virtual void InitializeInternal(
+      ProfileParams* profile_params,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) const OVERRIDE;
   virtual void InitializeExtensionsRequestContext(
       ProfileParams* profile_params) const OVERRIDE;
   virtual ChromeURLRequestContext* InitializeAppRequestContext(
       ChromeURLRequestContext* main_context,
       const StoragePartitionDescriptor& partition_descriptor,
       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-          protocol_handler_interceptor) const OVERRIDE;
+          protocol_handler_interceptor,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) const OVERRIDE;
   virtual ChromeURLRequestContext* InitializeMediaRequestContext(
       ChromeURLRequestContext* original_context,
       const StoragePartitionDescriptor& partition_descriptor) const OVERRIDE;
@@ -113,7 +157,17 @@
           ChromeURLRequestContext* main_context,
           const StoragePartitionDescriptor& partition_descriptor,
           scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-              protocol_handler_interceptor) const OVERRIDE;
+              protocol_handler_interceptor,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              blob_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              file_system_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              developer_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              chrome_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              chrome_devtools_protocol_handler) const OVERRIDE;
   virtual ChromeURLRequestContext*
       AcquireIsolatedMediaRequestContext(
           ChromeURLRequestContext* app_context,
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h
index 40ca85de..22b0242 100644
--- a/chrome/browser/profiles/profile.h
+++ b/chrome/browser/profiles/profile.h
@@ -14,6 +14,7 @@
 #include "base/logging.h"
 #include "chrome/browser/net/pref_proxy_config_tracker.h"
 #include "content/public/browser/browser_context.h"
+#include "net/url_request/url_request_job_factory.h"
 
 class ChromeAppCacheService;
 class ExtensionService;
@@ -225,11 +226,6 @@
   // is only used for a separate cookie store currently.
   virtual net::URLRequestContextGetter* GetRequestContextForExtensions() = 0;
 
-  // Returns the request context used within |partition_id|.
-  virtual net::URLRequestContextGetter* GetRequestContextForStoragePartition(
-      const base::FilePath& partition_path,
-      bool in_memory) = 0;
-
   // Returns the SSLConfigService for this profile.
   virtual net::SSLConfigService* GetSSLConfigService() = 0;
 
@@ -252,6 +248,45 @@
   // the user started chrome.
   virtual base::Time GetStartTime() const = 0;
 
+  // Creates the main net::URLRequestContextGetter that will be returned by
+  // GetRequestContext(). Should only be called once per ContentBrowserClient
+  // object. This function is exposed because of the circular dependency where
+  // GetStoragePartition() is used to retrieve the request context, but creation
+  // still has to happen in the Profile so the StoragePartition calls
+  // ContextBrowserClient to call this function.
+  // TODO(ajwong): Remove once http://crbug.com/159193 is resolved.
+  virtual net::URLRequestContextGetter* CreateRequestContext(
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) = 0;
+
+  // Creates the net::URLRequestContextGetter for a StoragePartition. Should
+  // only be called once per partition_path per ContentBrowserClient object.
+  // This function is exposed because the request context is retrieved from the
+  // StoragePartition, but creation still has to happen in the Profile so the
+  // StoragePartition calls ContextBrowserClient to call this function.
+  // TODO(ajwong): Remove once http://crbug.com/159193 is resolved.
+  virtual net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
+      const base::FilePath& partition_path,
+      bool in_memory,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) = 0;
+
   // Returns the last directory that was chosen for uploading or opening a file.
   virtual base::FilePath last_selected_directory() = 0;
   virtual void set_last_selected_directory(const base::FilePath& path) = 0;
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 06716b8..4c658cd 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -515,8 +515,6 @@
                 cache_max_size, media_cache_path, media_cache_max_size,
                 extensions_cookie_path, GetPath(), infinite_cache_path,
                 predictor_,
-                g_browser_process->local_state(),
-                g_browser_process->io_thread(),
                 restore_old_session_cookies,
                 GetSpecialStoragePolicy());
 
@@ -803,8 +801,29 @@
   return pref_file_path;
 }
 
+net::URLRequestContextGetter* ProfileImpl::CreateRequestContext(
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  return io_data_.CreateMainRequestContextGetter(
+      blob_protocol_handler.Pass(),
+      file_system_protocol_handler.Pass(),
+      developer_protocol_handler.Pass(),
+      chrome_protocol_handler.Pass(),
+      chrome_devtools_protocol_handler.Pass(),
+      g_browser_process->local_state(),
+      g_browser_process->io_thread());
+}
+
 net::URLRequestContextGetter* ProfileImpl::GetRequestContext() {
-  return io_data_.GetMainRequestContextGetter();
+  return GetDefaultStoragePartition(this)->GetURLRequestContext();
 }
 
 net::URLRequestContextGetter* ProfileImpl::GetRequestContextForRenderProcess(
@@ -846,10 +865,24 @@
   return io_data_.GetExtensionsRequestContextGetter();
 }
 
-net::URLRequestContextGetter* ProfileImpl::GetRequestContextForStoragePartition(
+net::URLRequestContextGetter*
+ProfileImpl::CreateRequestContextForStoragePartition(
     const FilePath& partition_path,
-    bool in_memory) {
-  return io_data_.GetIsolatedAppRequestContextGetter(partition_path, in_memory);
+    bool in_memory,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  return io_data_.CreateIsolatedAppRequestContextGetter(
+      partition_path, in_memory, blob_protocol_handler.Pass(),
+      file_system_protocol_handler.Pass(), developer_protocol_handler.Pass(),
+      chrome_protocol_handler.Pass(), chrome_devtools_protocol_handler.Pass());
 }
 
 net::SSLConfigService* ProfileImpl::GetSSLConfigService() {
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h
index 2c81c8c..849117bd 100644
--- a/chrome/browser/profiles/profile_impl.h
+++ b/chrome/browser/profiles/profile_impl.h
@@ -68,9 +68,6 @@
   virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE;
   virtual net::URLRequestContextGetter* GetRequestContextForRenderProcess(
       int renderer_child_id) OVERRIDE;
-  virtual net::URLRequestContextGetter* GetRequestContextForStoragePartition(
-      const FilePath& partition_path,
-      bool in_memory) OVERRIDE;
   virtual net::URLRequestContextGetter* GetMediaRequestContext() OVERRIDE;
   virtual net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess(
       int renderer_child_id) OVERRIDE;
@@ -110,6 +107,30 @@
   virtual ProtocolHandlerRegistry* GetProtocolHandlerRegistry() OVERRIDE;
   virtual bool IsSameProfile(Profile* profile) OVERRIDE;
   virtual base::Time GetStartTime() const OVERRIDE;
+  virtual net::URLRequestContextGetter* CreateRequestContext(
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) OVERRIDE;
+  virtual net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
+      const FilePath& partition_path,
+      bool in_memory,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) OVERRIDE;
   virtual FilePath last_selected_directory() OVERRIDE;
   virtual void set_last_selected_directory(const FilePath& path) OVERRIDE;
   virtual chrome_browser_net::Predictor* GetNetworkPredictor() OVERRIDE;
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index 8b24c9e..50172b0 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -37,6 +37,7 @@
 #include "net/base/server_bound_cert_service.h"
 #include "net/ftp/ftp_network_layer.h"
 #include "net/http/http_cache.h"
+#include "net/url_request/protocol_intercept_job_factory.h"
 #include "net/url_request/url_request_job_factory_impl.h"
 #include "webkit/quota/special_storage_policy.h"
 
@@ -75,8 +76,6 @@
       const FilePath& profile_path,
       const FilePath& infinite_cache_path,
       chrome_browser_net::Predictor* predictor,
-      PrefService* local_state,
-      IOThread* io_thread,
       bool restore_old_session_cookies,
       quota::SpecialStoragePolicy* special_storage_policy) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -106,16 +105,6 @@
 
   io_data_->predictor_.reset(predictor);
 
-  if (!main_request_context_getter_) {
-    main_request_context_getter_ =
-        ChromeURLRequestContextGetter::CreateOriginal(
-            profile_, io_data_);
-  }
-  io_data_->predictor_->InitNetworkPredictor(profile_->GetPrefs(),
-                                             local_state,
-                                             io_thread,
-                                             main_request_context_getter_);
-
   io_data_->InitializeMetricsEnabledStateOnUIThread();
 }
 
@@ -136,19 +125,36 @@
 }
 
 scoped_refptr<ChromeURLRequestContextGetter>
-ProfileImplIOData::Handle::GetMainRequestContextGetter() const {
+ProfileImplIOData::Handle::CreateMainRequestContextGetter(
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler,
+    PrefService* local_state,
+    IOThread* io_thread) const {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   LazyInitialize();
-  if (!main_request_context_getter_) {
-    main_request_context_getter_ =
-        ChromeURLRequestContextGetter::CreateOriginal(
-            profile_, io_data_);
+  DCHECK(!main_request_context_getter_);
+  main_request_context_getter_ = ChromeURLRequestContextGetter::CreateOriginal(
+      profile_, io_data_, blob_protocol_handler.Pass(),
+      file_system_protocol_handler.Pass(), developer_protocol_handler.Pass(),
+      chrome_protocol_handler.Pass(), chrome_devtools_protocol_handler.Pass());
 
-    content::NotificationService::current()->Notify(
-        chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED,
-        content::Source<Profile>(profile_),
-        content::NotificationService::NoDetails());
-  }
+  io_data_->predictor_->InitNetworkPredictor(profile_->GetPrefs(),
+                                             local_state,
+                                             io_thread,
+                                             main_request_context_getter_);
+
+  content::NotificationService::current()->Notify(
+      chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED,
+      content::Source<Profile>(profile_),
+      content::NotificationService::NoDetails());
   return main_request_context_getter_;
 }
 
@@ -177,9 +183,19 @@
 }
 
 scoped_refptr<ChromeURLRequestContextGetter>
-ProfileImplIOData::Handle::GetIsolatedAppRequestContextGetter(
+ProfileImplIOData::Handle::CreateIsolatedAppRequestContextGetter(
     const FilePath& partition_path,
-    bool in_memory) const {
+    bool in_memory,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) const {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   // Check that the partition_path is not the same as the base profile path. We
   // expect isolated partition, which will never go to the default profile path.
@@ -200,7 +216,10 @@
   ChromeURLRequestContextGetter* context =
       ChromeURLRequestContextGetter::CreateOriginalForIsolatedApp(
           profile_, io_data_, descriptor,
-          protocol_handler_interceptor.Pass());
+          protocol_handler_interceptor.Pass(), blob_protocol_handler.Pass(),
+          file_system_protocol_handler.Pass(),
+          developer_protocol_handler.Pass(), chrome_protocol_handler.Pass(),
+          chrome_devtools_protocol_handler.Pass());
   app_request_context_getter_map_[descriptor] = context;
 
   return context;
@@ -225,8 +244,10 @@
 
   // Get the app context as the starting point for the media context, so that
   // it uses the app's cookie store.
-  ChromeURLRequestContextGetter* app_context =
-      GetIsolatedAppRequestContextGetter(partition_path, in_memory);
+  ChromeURLRequestContextGetterMap::const_iterator app_iter =
+      app_request_context_getter_map_.find(descriptor);
+  DCHECK(app_iter != app_request_context_getter_map_.end());
+  ChromeURLRequestContextGetter* app_context = app_iter->second;
   ChromeURLRequestContextGetter* context =
       ChromeURLRequestContextGetter::CreateOriginalForIsolatedMedia(
           profile_, app_context, io_data_, descriptor);
@@ -292,8 +313,18 @@
     media_request_context_->AssertNoURLRequests();
 }
 
-void ProfileImplIOData::LazyInitializeInternal(
-    ProfileParams* profile_params) const {
+void ProfileImplIOData::InitializeInternal(
+    ProfileParams* profile_params,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) const {
   ChromeURLRequestContext* main_context = main_request_context();
 
   IOThread* const io_thread = profile_params->io_thread;
@@ -411,12 +442,27 @@
 
   scoped_ptr<net::URLRequestJobFactoryImpl> main_job_factory(
       new net::URLRequestJobFactoryImpl());
+  bool set_protocol = main_job_factory->SetProtocolHandler(
+      chrome::kBlobScheme, blob_protocol_handler.release());
+  DCHECK(set_protocol);
+  set_protocol = main_job_factory->SetProtocolHandler(
+      chrome::kFileSystemScheme, file_system_protocol_handler.release());
+  DCHECK(set_protocol);
+  set_protocol = main_job_factory->SetProtocolHandler(
+      chrome::kChromeUIScheme, chrome_protocol_handler.release());
+  DCHECK(set_protocol);
+  set_protocol = main_job_factory->SetProtocolHandler(
+      chrome::kChromeDevToolsScheme,
+      chrome_devtools_protocol_handler.release());
+  DCHECK(set_protocol);
   main_job_factory_ = SetUpJobFactoryDefaults(
       main_job_factory.Pass(),
       profile_params->protocol_handler_interceptor.Pass(),
       network_delegate(),
       main_context->ftp_transaction_factory(),
       main_context->ftp_auth_cache());
+  main_job_factory_.reset(new net::ProtocolInterceptJobFactory(
+      main_job_factory_.Pass(), developer_protocol_handler.Pass()));
   main_context->set_job_factory(main_job_factory_.get());
 
 #if defined(ENABLE_EXTENSIONS)
@@ -484,7 +530,17 @@
     ChromeURLRequestContext* main_context,
     const StoragePartitionDescriptor& partition_descriptor,
     scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-        protocol_handler_interceptor) const {
+        protocol_handler_interceptor,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) const {
   // Copy most state from the main context.
   AppRequestContext* context = new AppRequestContext(load_time_stats());
   context->CopyFrom(main_context);
@@ -549,6 +605,19 @@
 
   scoped_ptr<net::URLRequestJobFactoryImpl> job_factory(
       new net::URLRequestJobFactoryImpl());
+  bool set_protocol = job_factory->SetProtocolHandler(
+      chrome::kBlobScheme, blob_protocol_handler.release());
+  DCHECK(set_protocol);
+  set_protocol = job_factory->SetProtocolHandler(
+      chrome::kFileSystemScheme, file_system_protocol_handler.release());
+  DCHECK(set_protocol);
+  set_protocol = job_factory->SetProtocolHandler(
+      chrome::kChromeUIScheme, chrome_protocol_handler.release());
+  DCHECK(set_protocol);
+  set_protocol = job_factory->SetProtocolHandler(
+      chrome::kChromeDevToolsScheme,
+      chrome_devtools_protocol_handler.release());
+  DCHECK(set_protocol);
   scoped_ptr<net::URLRequestJobFactory> top_job_factory;
   // Overwrite the job factory that we inherit from the main context so
   // that we can later provide our own handlers for storage related protocols.
@@ -563,6 +632,8 @@
   } else {
     top_job_factory = job_factory.PassAs<net::URLRequestJobFactory>();
   }
+  top_job_factory.reset(new net::ProtocolInterceptJobFactory(
+      top_job_factory.Pass(), developer_protocol_handler.Pass()));
   context->SetJobFactory(top_job_factory.Pass());
 
   return context;
@@ -627,11 +698,26 @@
     ChromeURLRequestContext* main_context,
     const StoragePartitionDescriptor& partition_descriptor,
     scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-        protocol_handler_interceptor) const {
+        protocol_handler_interceptor,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) const {
   // We create per-app contexts on demand, unlike the others above.
   ChromeURLRequestContext* app_request_context =
       InitializeAppRequestContext(main_context, partition_descriptor,
-                                  protocol_handler_interceptor.Pass());
+                                  protocol_handler_interceptor.Pass(),
+                                  blob_protocol_handler.Pass(),
+                                  file_system_protocol_handler.Pass(),
+                                  developer_protocol_handler.Pass(),
+                                  chrome_protocol_handler.Pass(),
+                                  chrome_devtools_protocol_handler.Pass());
   DCHECK(app_request_context);
   return app_request_context;
 }
@@ -656,7 +742,7 @@
     base::Time time,
     const base::Closure& completion) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  LazyInitialize();
+  DCHECK(initialized());
 
   DCHECK(transport_security_state());
   transport_security_state()->DeleteSince(time);  // Completes synchronously.
diff --git a/chrome/browser/profiles/profile_impl_io_data.h b/chrome/browser/profiles/profile_impl_io_data.h
index b0d8d2ad..94acde8 100644
--- a/chrome/browser/profiles/profile_impl_io_data.h
+++ b/chrome/browser/profiles/profile_impl_io_data.h
@@ -33,11 +33,7 @@
     explicit Handle(Profile* profile);
     ~Handle();
 
-    bool HasMainRequestContext() const {
-      return main_request_context_getter_ != NULL;
-    }
-
-    // Init() must be called before ~Handle(). It records all the necessary
+    // Init() must be called before ~Handle(). It records most of the
     // parameters needed to construct a ChromeURLRequestContextGetter.
     void Init(const FilePath& cookie_path,
               const FilePath& server_bound_cert_path,
@@ -49,26 +45,51 @@
               const FilePath& profile_path,
               const FilePath& infinite_cache_path,
               chrome_browser_net::Predictor* predictor,
-              PrefService* local_state,
-              IOThread* io_thread,
               bool restore_old_session_cookies,
               quota::SpecialStoragePolicy* special_storage_policy);
 
+    // These Create*ContextGetter() functions are only exposed because the
+    // circular relationship between Profile, ProfileIOData::Handle, and the
+    // ChromeURLRequestContextGetter factories requires Profile be able to call
+    // these functions.
+    scoped_refptr<ChromeURLRequestContextGetter>
+        CreateMainRequestContextGetter(
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                blob_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                file_system_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                developer_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                chrome_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                chrome_devtools_protocol_handler,
+            PrefService* local_state,
+            IOThread* io_thread) const;
+    scoped_refptr<ChromeURLRequestContextGetter>
+        CreateIsolatedAppRequestContextGetter(
+            const FilePath& partition_path,
+            bool in_memory,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                blob_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                file_system_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                developer_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                chrome_protocol_handler,
+            scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+                chrome_devtools_protocol_handler) const;
+
     content::ResourceContext* GetResourceContext() const;
     // GetResourceContextNoInit() does not call LazyInitialize() so it can be
     // safely be used during initialization.
     content::ResourceContext* GetResourceContextNoInit() const;
     scoped_refptr<ChromeURLRequestContextGetter>
-        GetMainRequestContextGetter() const;
-    scoped_refptr<ChromeURLRequestContextGetter>
         GetMediaRequestContextGetter() const;
     scoped_refptr<ChromeURLRequestContextGetter>
         GetExtensionsRequestContextGetter() const;
     scoped_refptr<ChromeURLRequestContextGetter>
-        GetIsolatedAppRequestContextGetter(
-            const FilePath& partition_path,
-            bool in_memory) const;
-    scoped_refptr<ChromeURLRequestContextGetter>
         GetIsolatedMediaRequestContextGetter(
             const FilePath& partition_path,
             bool in_memory) const;
@@ -143,15 +164,35 @@
   ProfileImplIOData();
   virtual ~ProfileImplIOData();
 
-  virtual void LazyInitializeInternal(
-      ProfileParams* profile_params) const OVERRIDE;
+  virtual void InitializeInternal(
+      ProfileParams* profile_params,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) const OVERRIDE;
   virtual void InitializeExtensionsRequestContext(
       ProfileParams* profile_params) const OVERRIDE;
   virtual ChromeURLRequestContext* InitializeAppRequestContext(
       ChromeURLRequestContext* main_context,
       const StoragePartitionDescriptor& partition_descriptor,
       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-          protocol_handler_interceptor) const OVERRIDE;
+          protocol_handler_interceptor,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) const OVERRIDE;
   virtual ChromeURLRequestContext* InitializeMediaRequestContext(
       ChromeURLRequestContext* original_context,
       const StoragePartitionDescriptor& partition_descriptor) const OVERRIDE;
@@ -162,7 +203,17 @@
           ChromeURLRequestContext* main_context,
           const StoragePartitionDescriptor& partition_descriptor,
           scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-              protocol_handler_interceptor) const OVERRIDE;
+              protocol_handler_interceptor,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              blob_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              file_system_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              developer_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              chrome_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              chrome_devtools_protocol_handler) const OVERRIDE;
   virtual ChromeURLRequestContext*
       AcquireIsolatedMediaRequestContext(
           ChromeURLRequestContext* app_context,
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 37b24d5..bcbc31c 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -262,7 +262,7 @@
 
   // The profile instance is only available here in the InitializeOnUIThread
   // method, so we create the url job factory here, then save it for
-  // later delivery to the job factory in LazyInitialize.
+  // later delivery to the job factory in Init().
   params->protocol_handler_interceptor =
       protocol_handler_registry->CreateJobInterceptorFactory();
 
@@ -459,52 +459,58 @@
   return resource_context_.get();
 }
 
-ChromeURLRequestContext*
-ProfileIOData::GetMainRequestContext() const {
-  LazyInitialize();
+ChromeURLRequestContext* ProfileIOData::GetMainRequestContext() const {
+  DCHECK(initialized_);
   return main_request_context_.get();
 }
 
-ChromeURLRequestContext*
-ProfileIOData::GetMediaRequestContext() const {
-  LazyInitialize();
-  ChromeURLRequestContext* context =
-      AcquireMediaRequestContext();
+ChromeURLRequestContext* ProfileIOData::GetMediaRequestContext() const {
+  DCHECK(initialized_);
+  ChromeURLRequestContext* context = AcquireMediaRequestContext();
   DCHECK(context);
   return context;
 }
 
-ChromeURLRequestContext*
-ProfileIOData::GetExtensionsRequestContext() const {
-  LazyInitialize();
+ChromeURLRequestContext* ProfileIOData::GetExtensionsRequestContext() const {
+  DCHECK(initialized_);
   return extensions_request_context_.get();
 }
 
-ChromeURLRequestContext*
-ProfileIOData::GetIsolatedAppRequestContext(
+ChromeURLRequestContext* ProfileIOData::GetIsolatedAppRequestContext(
     ChromeURLRequestContext* main_context,
     const StoragePartitionDescriptor& partition_descriptor,
     scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-        protocol_handler_interceptor) const {
-  LazyInitialize();
+        protocol_handler_interceptor,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) const {
+  DCHECK(initialized_);
   ChromeURLRequestContext* context = NULL;
   if (ContainsKey(app_request_context_map_, partition_descriptor)) {
     context = app_request_context_map_[partition_descriptor];
   } else {
     context = AcquireIsolatedAppRequestContext(
-        main_context, partition_descriptor,
-        protocol_handler_interceptor.Pass());
+        main_context, partition_descriptor, protocol_handler_interceptor.Pass(),
+        blob_protocol_handler.Pass(), file_system_protocol_handler.Pass(),
+        developer_protocol_handler.Pass(), chrome_protocol_handler.Pass(),
+        chrome_devtools_protocol_handler.Pass());
     app_request_context_map_[partition_descriptor] = context;
   }
   DCHECK(context);
   return context;
 }
 
-ChromeURLRequestContext*
-ProfileIOData::GetIsolatedMediaRequestContext(
+ChromeURLRequestContext* ProfileIOData::GetIsolatedMediaRequestContext(
     ChromeURLRequestContext* app_context,
     const StoragePartitionDescriptor& partition_descriptor) const {
-  LazyInitialize();
+  DCHECK(initialized_);
   ChromeURLRequestContext* context = NULL;
   if (ContainsKey(isolated_media_request_context_map_, partition_descriptor)) {
     context = isolated_media_request_context_map_[partition_descriptor];
@@ -518,16 +524,19 @@
 }
 
 ExtensionInfoMap* ProfileIOData::GetExtensionInfoMap() const {
-  DCHECK(extension_info_map_) << "ExtensionSystem not initialized";
+  DCHECK(initialized_) << "ExtensionSystem not initialized";
   return extension_info_map_;
 }
 
 CookieSettings* ProfileIOData::GetCookieSettings() const {
+  // Allow either Init() or SetCookieSettingsForTesting() to initialize.
+  DCHECK(initialized_ || cookie_settings_);
   return cookie_settings_;
 }
 
 #if defined(ENABLE_NOTIFICATIONS)
 DesktopNotificationService* ProfileIOData::GetNotificationService() const {
+  DCHECK(initialized_);
   return notification_service_;
 }
 #endif
@@ -578,19 +587,15 @@
 
 ProfileIOData::ResourceContext::~ResourceContext() {}
 
-void ProfileIOData::ResourceContext::EnsureInitialized() {
-  io_data_->LazyInitialize();
-}
-
 net::HostResolver* ProfileIOData::ResourceContext::GetHostResolver()  {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  EnsureInitialized();
+  DCHECK(io_data_->initialized_);
   return host_resolver_;
 }
 
 net::URLRequestContext* ProfileIOData::ResourceContext::GetRequestContext()  {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  EnsureInitialized();
+  DCHECK(io_data_->initialized_);
   return request_context_;
 }
 
@@ -605,10 +610,22 @@
   return StringPrintf("profile/%u", ssl_session_cache_instance++);
 }
 
-void ProfileIOData::LazyInitialize() const {
+void ProfileIOData::Init(
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) const {
+  // The basic logic is implemented here. The specific initialization
+  // is done in InitializeInternal(), implemented by subtypes. Static helper
+  // functions have been provided to assist in common operations.
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  if (initialized_)
-    return;
+  DCHECK(!initialized_);
 
   startup_metric_utils::ScopedSlowStartupUMA
       scoped_timer("Startup.SlowStartupProfileIODataInit");
@@ -685,7 +702,12 @@
   managed_mode_url_filter_ = profile_params_->managed_mode_url_filter;
 #endif
 
-  LazyInitializeInternal(profile_params_.get());
+  InitializeInternal(profile_params_.get(),
+                     blob_protocol_handler.Pass(),
+                     file_system_protocol_handler.Pass(),
+                     developer_protocol_handler.Pass(),
+                     chrome_protocol_handler.Pass(),
+                     chrome_devtools_protocol_handler.Pass());
 
   profile_params_.reset();
   initialized_ = true;
@@ -711,9 +733,10 @@
       chrome::kFileScheme, new net::FileProtocolHandler());
   DCHECK(set_protocol);
 
+  DCHECK(extension_info_map_);
   set_protocol = job_factory->SetProtocolHandler(
       extensions::kExtensionScheme,
-      CreateExtensionProtocolHandler(is_incognito(), GetExtensionInfoMap()));
+      CreateExtensionProtocolHandler(is_incognito(), extension_info_map_));
   DCHECK(set_protocol);
   set_protocol = job_factory->SetProtocolHandler(
       chrome::kExtensionResourceScheme,
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h
index 03faa86..9c672ed 100644
--- a/chrome/browser/profiles/profile_io_data.h
+++ b/chrome/browser/profiles/profile_io_data.h
@@ -80,9 +80,21 @@
   // Called by Profile.
   content::ResourceContext* GetResourceContext() const;
 
-  // These should only be called at most once each. Ownership is reversed when
-  // they get called, from ProfileIOData owning ChromeURLRequestContext to vice
-  // versa.
+  // Initializes the ProfileIOData object and primes the RequestContext
+  // generation. Must be called prior to any of the Get*() methods other than
+  // GetResouceContext or GetMetricsEnabledStateOnIOThread.
+  void Init(
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) const;
+
   ChromeURLRequestContext* GetMainRequestContext() const;
   ChromeURLRequestContext* GetMediaRequestContext() const;
   ChromeURLRequestContext* GetExtensionsRequestContext() const;
@@ -90,7 +102,17 @@
       ChromeURLRequestContext* main_context,
       const StoragePartitionDescriptor& partition_descriptor,
       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-          protocol_handler_interceptor) const;
+          protocol_handler_interceptor,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) const;
   ChromeURLRequestContext* GetIsolatedMediaRequestContext(
       ChromeURLRequestContext* app_context,
       const StoragePartitionDescriptor& partition_descriptor) const;
@@ -274,12 +296,6 @@
       net::FtpTransactionFactory* ftp_transaction_factory,
       net::FtpAuthCache* ftp_auth_cache) const;
 
-  // Lazy initializes the ProfileIOData object the first time a request context
-  // is requested. The lazy logic is implemented here. The actual initialization
-  // is done in LazyInitializeInternal(), implemented by subtypes. Static helper
-  // functions have been provided to assist in common operations.
-  void LazyInitialize() const;
-
   // Called when the profile is destroyed.
   void ShutdownOnUIThread();
 
@@ -315,6 +331,10 @@
     return load_time_stats_;
   }
 
+  bool initialized() const {
+    return initialized_;
+  }
+
   // Destroys the ResourceContext first, to cancel any URLRequests that are
   // using it still, before we destroy the member variables that those
   // URLRequests may be accessing.
@@ -343,8 +363,6 @@
    private:
     friend class ProfileIOData;
 
-    void EnsureInitialized();
-
     ProfileIOData* const io_data_;
 
     net::HostResolver* host_resolver_;
@@ -362,7 +380,18 @@
 
   // Does the actual initialization of the ProfileIOData subtype. Subtypes
   // should use the static helper functions above to implement this.
-  virtual void LazyInitializeInternal(ProfileParams* profile_params) const = 0;
+  virtual void InitializeInternal(
+      ProfileParams* profile_params,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) const = 0;
 
   // Initializes the RequestContext for extensions.
   virtual void InitializeExtensionsRequestContext(
@@ -373,7 +402,17 @@
       ChromeURLRequestContext* main_context,
       const StoragePartitionDescriptor& details,
       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-          protocol_handler_interceptor) const = 0;
+          protocol_handler_interceptor,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) const = 0;
 
   // Does an on-demand initialization of a media RequestContext for the given
   // isolated app.
@@ -390,7 +429,17 @@
           ChromeURLRequestContext* main_context,
           const StoragePartitionDescriptor& partition_descriptor,
           scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-              protocol_handler_interceptor) const = 0;
+              protocol_handler_interceptor,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              blob_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              file_system_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              developer_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              chrome_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              chrome_devtools_protocol_handler) const = 0;
   virtual ChromeURLRequestContext*
       AcquireIsolatedMediaRequestContext(
           ChromeURLRequestContext* app_context,
diff --git a/chrome/browser/ui/sync/one_click_signin_helper_unittest.cc b/chrome/browser/ui/sync/one_click_signin_helper_unittest.cc
index c9f7d67..398ba581 100644
--- a/chrome/browser/ui/sync/one_click_signin_helper_unittest.cc
+++ b/chrome/browser/ui/sync/one_click_signin_helper_unittest.cc
@@ -87,8 +87,18 @@
   }
 
   // ProfileIOData overrides:
-  virtual void LazyInitializeInternal(
-      ProfileParams* profile_params) const OVERRIDE {
+  virtual void InitializeInternal(
+      ProfileParams* profile_params,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) const OVERRIDE {
     NOTREACHED();
   }
   virtual void InitializeExtensionsRequestContext(
@@ -99,7 +109,17 @@
       ChromeURLRequestContext* main_context,
       const StoragePartitionDescriptor& details,
       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-          protocol_handler_interceptor) const OVERRIDE {
+          protocol_handler_interceptor,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) const OVERRIDE {
     NOTREACHED();
     return NULL;
   }
@@ -119,7 +139,17 @@
           ChromeURLRequestContext* main_context,
           const StoragePartitionDescriptor& partition_descriptor,
           scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
-              protocol_handler_interceptor) const OVERRIDE {
+              protocol_handler_interceptor,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              blob_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              file_system_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              developer_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              chrome_protocol_handler,
+          scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+              chrome_devtools_protocol_handler) const OVERRIDE {
     NOTREACHED();
     return NULL;
   }
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index fa809eb..f7094ae 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -586,6 +586,20 @@
   return request_context_.get();
 }
 
+net::URLRequestContextGetter* TestingProfile::CreateRequestContext(
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  return request_context_.get();
+}
+
 net::URLRequestContextGetter* TestingProfile::GetRequestContextForRenderProcess(
     int renderer_child_id) {
   content::RenderProcessHost* rph = content::RenderProcessHost::FromID(
@@ -638,9 +652,19 @@
 }
 
 net::URLRequestContextGetter*
-TestingProfile::GetRequestContextForStoragePartition(
+TestingProfile::CreateRequestContextForStoragePartition(
     const FilePath& partition_path,
-    bool in_memory) {
+    bool in_memory,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
   // We don't test storage partitions here yet, so returning the same dummy
   // context is sufficient for now.
   return GetRequestContext();
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h
index 3161bfff..23302ac 100644
--- a/chrome/test/base/testing_profile.h
+++ b/chrome/test/base/testing_profile.h
@@ -190,6 +190,17 @@
   // getter is currently only capable of returning a Context that helps test
   // the CookieMonster. See implementation comments for more details.
   virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE;
+  virtual net::URLRequestContextGetter* CreateRequestContext(
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) OVERRIDE;
   virtual net::URLRequestContextGetter* GetRequestContextForRenderProcess(
       int renderer_child_id) OVERRIDE;
   virtual content::ResourceContext* GetResourceContext() OVERRIDE;
@@ -244,9 +255,19 @@
       GetMediaRequestContextForStoragePartition(
           const FilePath& partition_path,
           bool in_memory) OVERRIDE;
-  virtual net::URLRequestContextGetter* GetRequestContextForStoragePartition(
+  virtual net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
       const FilePath& partition_path,
-      bool in_memory) OVERRIDE;
+      bool in_memory,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) OVERRIDE;
   virtual net::SSLConfigService* GetSSLConfigService() OVERRIDE;
   virtual HostContentSettingsMap* GetHostContentSettingsMap() OVERRIDE;
   virtual std::wstring GetName();
diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc
index 41912e41..a923f87 100644
--- a/content/browser/download/download_manager_impl_unittest.cc
+++ b/content/browser/download/download_manager_impl_unittest.cc
@@ -393,9 +393,6 @@
   MOCK_METHOD0(GetRequestContext, net::URLRequestContextGetter*());
   MOCK_METHOD1(GetRequestContextForRenderProcess,
                net::URLRequestContextGetter*(int renderer_child_id));
-  MOCK_METHOD2(GetRequestContextForStoragePartition,
-               net::URLRequestContextGetter*(
-                   const base::FilePath& partition_path, bool in_memory));
   MOCK_METHOD0(GetMediaRequestContext,
                net::URLRequestContextGetter*());
   MOCK_METHOD1(GetMediaRequestContextForRenderProcess,
diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc
index 79c6a77..75c4898d 100644
--- a/content/browser/storage_partition_impl_map.cc
+++ b/content/browser/storage_partition_impl_map.cc
@@ -46,28 +46,64 @@
 
 namespace {
 
-class BlobProtocolHandler : public webkit_blob::BlobProtocolHandler {
+class BlobProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
  public:
-  BlobProtocolHandler(
-      webkit_blob::BlobStorageController* blob_storage_controller,
-      fileapi::FileSystemContext* file_system_context,
-      base::MessageLoopProxy* loop_proxy)
-      : webkit_blob::BlobProtocolHandler(blob_storage_controller,
-                                         file_system_context,
-                                         loop_proxy) {}
+  BlobProtocolHandler(ChromeBlobStorageContext* blob_storage_context,
+                      fileapi::FileSystemContext* file_system_context)
+      : blob_storage_context_(blob_storage_context),
+        file_system_context_(file_system_context) {}
 
   virtual ~BlobProtocolHandler() {}
 
- private:
-  virtual scoped_refptr<webkit_blob::BlobData>
-      LookupBlobData(net::URLRequest* request) const {
-    const ResourceRequestInfoImpl* info =
-        ResourceRequestInfoImpl::ForRequest(request);
-    if (!info)
-      return NULL;
-    return info->requested_blob_data();
+  virtual net::URLRequestJob* MaybeCreateJob(
+      net::URLRequest* request,
+      net::NetworkDelegate* network_delegate) const OVERRIDE {
+    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+    if (!webkit_blob_protocol_handler_impl_) {
+      webkit_blob_protocol_handler_impl_.reset(
+          new WebKitBlobProtocolHandlerImpl(blob_storage_context_->controller(),
+                                            file_system_context_));
+    }
+    return webkit_blob_protocol_handler_impl_->MaybeCreateJob(request,
+                                                              network_delegate);
   }
 
+ private:
+  // An implementation of webkit_blob::BlobProtocolHandler that gets
+  // the BlobData from ResourceRequestInfoImpl.
+  class WebKitBlobProtocolHandlerImpl
+      : public webkit_blob::BlobProtocolHandler {
+   public:
+    WebKitBlobProtocolHandlerImpl(
+        webkit_blob::BlobStorageController* blob_storage_controller,
+        fileapi::FileSystemContext* file_system_context)
+        : webkit_blob::BlobProtocolHandler(
+              blob_storage_controller, file_system_context,
+              BrowserThread::GetMessageLoopProxyForThread(
+                  BrowserThread::FILE)) {}
+
+    virtual ~WebKitBlobProtocolHandlerImpl() {}
+
+   private:
+    // webkit_blob::BlobProtocolHandler implementation.
+    virtual scoped_refptr<webkit_blob::BlobData>
+        LookupBlobData(net::URLRequest* request) const OVERRIDE {
+      const ResourceRequestInfoImpl* info =
+          ResourceRequestInfoImpl::ForRequest(request);
+      if (!info)
+        return NULL;
+      return info->requested_blob_data();
+    }
+
+    DISALLOW_COPY_AND_ASSIGN(WebKitBlobProtocolHandlerImpl);
+  };
+
+  const scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
+  const scoped_refptr<fileapi::FileSystemContext> file_system_context_;
+
+  mutable scoped_ptr<WebKitBlobProtocolHandlerImpl>
+  webkit_blob_protocol_handler_impl_;
+
   DISALLOW_COPY_AND_ASSIGN(BlobProtocolHandler);
 };
 
@@ -75,16 +111,16 @@
 // handler because we want to reuse the chrome://scheme (everyone is familiar
 // with it, and no need to expose the content/chrome separation through our UI).
 class DeveloperProtocolHandler
-    : public net::URLRequestJobFactory::Interceptor {
+    : public net::URLRequestJobFactory::ProtocolHandler {
  public:
   DeveloperProtocolHandler(
       AppCacheService* appcache_service,
-      BlobStorageController* blob_storage_controller)
+      ChromeBlobStorageContext* blob_storage_context)
       : appcache_service_(appcache_service),
-        blob_storage_controller_(blob_storage_controller) {}
+        blob_storage_context_(blob_storage_context) {}
   virtual ~DeveloperProtocolHandler() {}
 
-  virtual net::URLRequestJob* MaybeIntercept(
+  virtual net::URLRequestJob* MaybeCreateJob(
       net::URLRequest* request,
       net::NetworkDelegate* network_delegate) const OVERRIDE {
     // Check for chrome://view-http-cache/*, which uses its own job type.
@@ -102,7 +138,7 @@
     // Next check for chrome://blob-internals/, which uses its own job type.
     if (ViewBlobInternalsJobFactory::IsSupportedURL(request->url())) {
       return ViewBlobInternalsJobFactory::CreateJobForRequest(
-          request, network_delegate, blob_storage_controller_);
+          request, network_delegate, blob_storage_context_->controller());
     }
 
 #if defined(USE_TCMALLOC)
@@ -122,90 +158,11 @@
     return NULL;
   }
 
-  virtual net::URLRequestJob* MaybeInterceptRedirect(
-        const GURL& location,
-        net::URLRequest* request,
-        net::NetworkDelegate* network_delegate) const OVERRIDE {
-    return NULL;
-  }
-
-  virtual net::URLRequestJob* MaybeInterceptResponse(
-      net::URLRequest* request,
-      net::NetworkDelegate* network_delegate) const OVERRIDE {
-    return NULL;
-  }
-
-  virtual bool WillHandleProtocol(const std::string& protocol) const {
-    return protocol == chrome::kChromeUIScheme;
-  }
-
  private:
   AppCacheService* appcache_service_;
-  BlobStorageController* blob_storage_controller_;
+  ChromeBlobStorageContext* blob_storage_context_;
 };
 
-void InitializeURLRequestContext(
-    net::URLRequestContextGetter* context_getter,
-    AppCacheService* appcache_service,
-    FileSystemContext* file_system_context,
-    ChromeBlobStorageContext* blob_storage_context,
-    ResourceContext* resource_context,
-    bool off_the_record) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  if (!context_getter)
-    return;  // tests.
-
-  // This code only modifies the URLRequestJobFactory on the context
-  // to handle blob: URLs, filesystem: URLs, and to let AppCache intercept
-  // the appropriate requests.  This is in addition to the slew of other
-  // initializtion that is done in during creation of the URLRequestContext.
-  // We cannot yet centralize this code because URLRequestContext needs
-  // to be created before the StoragePartition context.
-  //
-  // TODO(ajwong): Fix the ordering so all the initialization is in one spot.
-  net::URLRequestContext* context = context_getter->GetURLRequestContext();
-  net::URLRequestJobFactory* job_factory =
-      const_cast<net::URLRequestJobFactory*>(context->job_factory());
-
-  // Note: if this is called twice with 2 request contexts that share one job
-  // factory (as is the case with a media request context and its related
-  // normal request context) then this will early exit.
-  if (job_factory->IsHandledProtocol(chrome::kBlobScheme))
-    return;  // Already initialized this JobFactory.
-
-  bool set_protocol = job_factory->SetProtocolHandler(
-      chrome::kBlobScheme,
-      new BlobProtocolHandler(
-          blob_storage_context->controller(),
-          file_system_context,
-          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)));
-  DCHECK(set_protocol);
-  set_protocol = job_factory->SetProtocolHandler(
-      chrome::kFileSystemScheme,
-      CreateFileSystemProtocolHandler(file_system_context));
-  DCHECK(set_protocol);
-
-  job_factory->AddInterceptor(
-      new DeveloperProtocolHandler(appcache_service,
-                                   blob_storage_context->controller()));
-
-  set_protocol = job_factory->SetProtocolHandler(
-      chrome::kChromeUIScheme,
-      URLDataManagerBackend::CreateProtocolHandler(
-          GetURLDataManagerForResourceContext(resource_context),
-          off_the_record));
-  DCHECK(set_protocol);
-
-  set_protocol = job_factory->SetProtocolHandler(
-      chrome::kChromeDevToolsScheme,
-      CreateDevToolsProtocolHandler(
-          GetURLDataManagerForResourceContext(resource_context),
-          off_the_record));
-  DCHECK(set_protocol);
-
-  // TODO(jam): Add the ProtocolHandlerRegistryIntercepter here!
-}
-
 // These constants are used to create the directory structure under the profile
 // where renderers with a non-default storage partition keep their persistent
 // state. This will contain a set of directories that partially mirror the
@@ -488,12 +445,43 @@
                                    partition_path);
   partitions_[partition_config] = partition;
 
+  ChromeBlobStorageContext* blob_storage_context =
+      ChromeBlobStorageContext::GetFor(browser_context_);
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> blob_protocol_handler(
+      new BlobProtocolHandler(blob_storage_context,
+                              partition->GetFileSystemContext()));
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      file_system_protocol_handler(
+            CreateFileSystemProtocolHandler(partition->GetFileSystemContext()));
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      developer_protocol_handler(
+          new DeveloperProtocolHandler(partition->GetAppCacheService(),
+                                       blob_storage_context));
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      chrome_protocol_handler(
+          URLDataManagerBackend::CreateProtocolHandler(
+              browser_context_->GetResourceContext(),
+              browser_context_->IsOffTheRecord()));
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      chrome_devtools_protocol_handler(
+          CreateDevToolsProtocolHandler(browser_context_->GetResourceContext(),
+                                        browser_context_->IsOffTheRecord()));
+
   // These calls must happen after StoragePartitionImpl::Create().
-  partition->SetURLRequestContext(
-      partition_domain.empty() ?
-      browser_context_->GetRequestContext() :
-      browser_context_->GetRequestContextForStoragePartition(
-          partition->GetPath(), in_memory));
+  if (partition_domain.empty()) {
+    partition->SetURLRequestContext(
+        GetContentClient()->browser()->CreateRequestContext(browser_context_,
+            blob_protocol_handler.Pass(), file_system_protocol_handler.Pass(),
+            developer_protocol_handler.Pass(), chrome_protocol_handler.Pass(),
+            chrome_devtools_protocol_handler.Pass()));
+  } else {
+    partition->SetURLRequestContext(
+        GetContentClient()->browser()->CreateRequestContextForStoragePartition(
+            browser_context_, partition->GetPath(), in_memory,
+            blob_protocol_handler.Pass(), file_system_protocol_handler.Pass(),
+            developer_protocol_handler.Pass(), chrome_protocol_handler.Pass(),
+            chrome_devtools_protocol_handler.Pass()));
+  }
   partition->SetMediaURLRequestContext(
       partition_domain.empty() ?
       browser_context_->GetMediaRequestContext() :
@@ -612,19 +600,6 @@
                    make_scoped_refptr(
                        browser_context_->GetSpecialStoragePolicy())));
 
-    // Add content's URLRequestContext's hooks.
-    BrowserThread::PostTask(
-        BrowserThread::IO, FROM_HERE,
-        base::Bind(
-            &InitializeURLRequestContext,
-            make_scoped_refptr(partition->GetURLRequestContext()),
-            make_scoped_refptr(partition->GetAppCacheService()),
-            make_scoped_refptr(partition->GetFileSystemContext()),
-            make_scoped_refptr(
-                ChromeBlobStorageContext::GetFor(browser_context_)),
-            browser_context_->GetResourceContext(),
-            browser_context_->IsOffTheRecord()));
-
     // We do not call InitializeURLRequestContext() for media contexts because,
     // other than the HTTP cache, the media contexts share the same backing
     // objects as their associated "normal" request context.  Thus, the previous
diff --git a/content/browser/webui/url_data_manager_backend.cc b/content/browser/webui/url_data_manager_backend.cc
index f5fdd6b..3ffc195 100644
--- a/content/browser/webui/url_data_manager_backend.cc
+++ b/content/browser/webui/url_data_manager_backend.cc
@@ -18,6 +18,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop.h"
 #include "base/string_util.h"
+#include "content/browser/resource_context_impl.h"
 #include "content/browser/webui/shared_resources_data_source.h"
 #include "content/browser/webui/url_data_source_impl.h"
 #include "content/public/browser/browser_thread.h"
@@ -333,7 +334,7 @@
     : public net::URLRequestJobFactory::ProtocolHandler {
  public:
   // |is_incognito| should be set for incognito profiles.
-  explicit ChromeProtocolHandler(URLDataManagerBackend* backend,
+  explicit ChromeProtocolHandler(content::ResourceContext* resource_context,
                                  bool is_incognito);
   ~ChromeProtocolHandler();
 
@@ -343,7 +344,7 @@
 
  private:
   // These members are owned by ProfileIOData, which owns this ProtocolHandler.
-  URLDataManagerBackend* const backend_;
+  content::ResourceContext* const resource_context_;
 
   // True when generated from an incognito profile.
   const bool is_incognito_;
@@ -352,8 +353,8 @@
 };
 
 ChromeProtocolHandler::ChromeProtocolHandler(
-    URLDataManagerBackend* backend, bool is_incognito)
-    : backend_(backend), is_incognito_(is_incognito) {}
+    content::ResourceContext* resource_context, bool is_incognito)
+    : resource_context_(resource_context), is_incognito_(is_incognito) {}
 
 ChromeProtocolHandler::~ChromeProtocolHandler() {}
 
@@ -362,8 +363,9 @@
   DCHECK(request);
 
   // Fall back to using a custom handler
-  return new URLRequestChromeJob(request, network_delegate, backend_,
-                                 is_incognito_);
+  return new URLRequestChromeJob(
+      request, network_delegate,
+      GetURLDataManagerForResourceContext(resource_context_), is_incognito_);
 }
 
 }  // namespace
@@ -387,9 +389,9 @@
 // static
 net::URLRequestJobFactory::ProtocolHandler*
 URLDataManagerBackend::CreateProtocolHandler(
-    URLDataManagerBackend* backend, bool is_incognito) {
-  DCHECK(backend);
-  return new ChromeProtocolHandler(backend, is_incognito);
+    content::ResourceContext* resource_context, bool is_incognito) {
+  DCHECK(resource_context);
+  return new ChromeProtocolHandler(resource_context, is_incognito);
 }
 
 void URLDataManagerBackend::AddDataSource(
@@ -521,7 +523,7 @@
     : public net::URLRequestJobFactory::ProtocolHandler {
  public:
   // |is_incognito| should be set for incognito profiles.
-  DevToolsJobFactory(URLDataManagerBackend* backend,
+  DevToolsJobFactory(content::ResourceContext* resource_context,
                      bool is_incognito);
   virtual ~DevToolsJobFactory();
 
@@ -530,9 +532,9 @@
       net::NetworkDelegate* network_delegate) const OVERRIDE;
 
  private:
-  // |backend_| and |network_delegate_| are owned by ProfileIOData, which owns
-  // this ProtocolHandler.
-  URLDataManagerBackend* const backend_;
+  // |resource_context_| and |network_delegate_| are owned by ProfileIOData,
+  // which owns this ProtocolHandler.
+  content::ResourceContext* const resource_context_;
 
   // True when generated from an incognito profile.
   const bool is_incognito_;
@@ -540,11 +542,12 @@
   DISALLOW_COPY_AND_ASSIGN(DevToolsJobFactory);
 };
 
-DevToolsJobFactory::DevToolsJobFactory(URLDataManagerBackend* backend,
-                                       bool is_incognito)
-    : backend_(backend),
+DevToolsJobFactory::DevToolsJobFactory(
+    content::ResourceContext* resource_context,
+    bool is_incognito)
+    : resource_context_(resource_context),
       is_incognito_(is_incognito) {
-  DCHECK(backend_);
+  DCHECK(resource_context_);
 }
 
 DevToolsJobFactory::~DevToolsJobFactory() {}
@@ -552,16 +555,17 @@
 net::URLRequestJob*
 DevToolsJobFactory::MaybeCreateJob(
     net::URLRequest* request, net::NetworkDelegate* network_delegate) const {
-  return new URLRequestChromeJob(request, network_delegate, backend_,
-                                 is_incognito_);
+  return new URLRequestChromeJob(
+      request, network_delegate,
+      GetURLDataManagerForResourceContext(resource_context_), is_incognito_);
 }
 
 }  // namespace
 
 net::URLRequestJobFactory::ProtocolHandler*
-CreateDevToolsProtocolHandler(URLDataManagerBackend* backend,
+CreateDevToolsProtocolHandler(content::ResourceContext* resource_context,
                               bool is_incognito) {
-  return new DevToolsJobFactory(backend, is_incognito);
+  return new DevToolsJobFactory(resource_context, is_incognito);
 }
 
 }  // namespace content
diff --git a/content/browser/webui/url_data_manager_backend.h b/content/browser/webui/url_data_manager_backend.h
index a6c6fa2..58daa4e 100644
--- a/content/browser/webui/url_data_manager_backend.h
+++ b/content/browser/webui/url_data_manager_backend.h
@@ -22,6 +22,7 @@
 }
 
 namespace content {
+class ResourceContext;
 class URLDataManagerBackend;
 class URLDataSourceImpl;
 class URLRequestChromeJob;
@@ -37,9 +38,9 @@
   virtual ~URLDataManagerBackend();
 
   // Invoked to create the protocol handler for chrome://. |is_incognito| should
-  // be set for incognito profiles.
+  // be set for incognito profiles. Called on the UI thread.
   static net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler(
-      URLDataManagerBackend* backend,
+      content::ResourceContext* resource_context,
       bool is_incognito);
 
   // Adds a DataSource to the collection of data sources.
@@ -95,7 +96,7 @@
 // Creates protocol handler for chrome-devtools://. |is_incognito| should be
 // set for incognito profiles.
 net::URLRequestJobFactory::ProtocolHandler*
-CreateDevToolsProtocolHandler(URLDataManagerBackend* backend,
+CreateDevToolsProtocolHandler(content::ResourceContext* resource_context,
                               bool is_incognito);
 
 }  // namespace content
diff --git a/content/content_shell.gypi b/content/content_shell.gypi
index 6c8d3e3..582174a 100644
--- a/content/content_shell.gypi
+++ b/content/content_shell.gypi
@@ -111,8 +111,6 @@
         'shell/shell_network_delegate.h',
         'shell/shell_render_process_observer.cc',
         'shell/shell_render_process_observer.h',
-        'shell/shell_resource_context.cc',
-        'shell/shell_resource_context.h',
         'shell/shell_resource_dispatcher_host_delegate.cc',
         'shell/shell_resource_dispatcher_host_delegate.h',
         'shell/shell_switches.cc',
diff --git a/content/public/browser/browser_context.h b/content/public/browser/browser_context.h
index d82326a..a1b5d7b 100644
--- a/content/public/browser/browser_context.h
+++ b/content/public/browser/browser_context.h
@@ -116,10 +116,6 @@
   virtual net::URLRequestContextGetter* GetRequestContextForRenderProcess(
       int renderer_child_id) = 0;
 
-  virtual net::URLRequestContextGetter* GetRequestContextForStoragePartition(
-      const base::FilePath& partition_path,
-      bool in_memory) = 0;
-
   // Returns the default request context for media resources associated with
   // this context.
   // TODO(creis): Remove this version in favor of the one below.
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 6ad2694..2b16e49 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -36,6 +36,39 @@
   return false;
 }
 
+net::URLRequestContextGetter* ContentBrowserClient::CreateRequestContext(
+    BrowserContext* browser_context,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  return NULL;
+}
+
+net::URLRequestContextGetter*
+ContentBrowserClient::CreateRequestContextForStoragePartition(
+    BrowserContext* browser_context,
+    const FilePath& partition_path,
+    bool in_memory,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  return NULL;
+}
+
 bool ContentBrowserClient::IsHandledURL(const GURL& url) {
   return false;
 }
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index b332073..0e1ed14 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -10,12 +10,14 @@
 #include <vector>
 
 #include "base/callback_forward.h"
+#include "base/memory/scoped_ptr.h"
 #include "content/public/browser/file_descriptor_info.h"
 #include "content/public/common/socket_permission_request.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/window_container_type.h"
 #include "net/base/mime_util.h"
 #include "net/cookies/canonical_cookie.h"
+#include "net/url_request/url_request_job_factory.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNotificationPresenter.h"
 
 #if defined(OS_POSIX) && !defined(OS_MACOSX)
@@ -49,6 +51,7 @@
 class SSLInfo;
 class URLRequest;
 class URLRequestContext;
+class URLRequestContextGetter;
 class X509Certificate;
 }
 
@@ -135,6 +138,40 @@
   virtual bool ShouldUseProcessPerSite(BrowserContext* browser_context,
                                        const GURL& effective_url);
 
+  // Creates the main net::URLRequestContextGetter. Should only be called once
+  // per ContentBrowserClient object.
+  // TODO(ajwong): Remove once http://crbug.com/159193 is resolved.
+  virtual net::URLRequestContextGetter* CreateRequestContext(
+      BrowserContext* browser_context,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler);
+
+  // Creates the net::URLRequestContextGetter for a StoragePartition. Should
+  // only be called once per partition_path per ContentBrowserClient object.
+  // TODO(ajwong): Remove once http://crbug.com/159193 is resolved.
+  virtual net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
+      BrowserContext* browser_context,
+      const FilePath& partition_path,
+      bool in_memory,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler);
+
   // Returns whether a specified URL is handled by the embedder's internal
   // protocol handlers.
   virtual bool IsHandledURL(const GURL& url);
diff --git a/content/public/test/test_browser_context.cc b/content/public/test/test_browser_context.cc
index ec47813..b954c70 100644
--- a/content/public/test/test_browser_context.cc
+++ b/content/public/test/test_browser_context.cc
@@ -82,14 +82,6 @@
   return NULL;
 }
 
-
-net::URLRequestContextGetter*
-TestBrowserContext::GetRequestContextForStoragePartition(
-    const FilePath& partition_path,
-    bool in_memory) {
-  return NULL;
-}
-
 net::URLRequestContextGetter* TestBrowserContext::GetMediaRequestContext() {
   return NULL;
 }
diff --git a/content/public/test/test_browser_context.h b/content/public/test/test_browser_context.h
index 5a93376..41ddfdd 100644
--- a/content/public/test/test_browser_context.h
+++ b/content/public/test/test_browser_context.h
@@ -33,9 +33,6 @@
   virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE;
   virtual net::URLRequestContextGetter* GetRequestContextForRenderProcess(
       int renderer_child_id) OVERRIDE;
-  virtual net::URLRequestContextGetter* GetRequestContextForStoragePartition(
-      const FilePath& partition_path,
-      bool in_memory) OVERRIDE;
   virtual net::URLRequestContextGetter* GetMediaRequestContext() OVERRIDE;
   virtual net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess(
       int renderer_child_id) OVERRIDE;
diff --git a/content/shell/shell_browser_context.cc b/content/shell/shell_browser_context.cc
index b464477..1acfa79 100644
--- a/content/shell/shell_browser_context.cc
+++ b/content/shell/shell_browser_context.cc
@@ -12,11 +12,12 @@
 #include "base/path_service.h"
 #include "base/threading/thread.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/resource_context.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/common/content_switches.h"
 #include "content/shell/shell_download_manager_delegate.h"
-#include "content/shell/shell_resource_context.h"
 #include "content/shell/shell_switches.h"
 #include "content/shell/shell_url_request_context_getter.h"
-#include "content/public/common/content_switches.h"
 
 #if defined(OS_WIN)
 #include "base/base_paths_win.h"
@@ -28,9 +29,35 @@
 
 namespace content {
 
+class ShellBrowserContext::ShellResourceContext : public ResourceContext {
+ public:
+  ShellResourceContext() : getter_(NULL) {}
+  virtual ~ShellResourceContext() {}
+
+  // ResourceContext implementation:
+  virtual net::HostResolver* GetHostResolver() OVERRIDE {
+    CHECK(getter_);
+    return getter_->host_resolver();
+  }
+  virtual net::URLRequestContext* GetRequestContext() OVERRIDE {
+    CHECK(getter_);
+    return getter_->GetURLRequestContext();
+  }
+
+  void set_url_request_context_getter(ShellURLRequestContextGetter* getter) {
+    getter_ = getter;
+  }
+
+ private:
+  ShellURLRequestContextGetter* getter_;
+
+  DISALLOW_COPY_AND_ASSIGN(ShellResourceContext);
+};
+
 ShellBrowserContext::ShellBrowserContext(bool off_the_record)
     : off_the_record_(off_the_record),
-      ignore_certificate_errors_(false) {
+      ignore_certificate_errors_(false),
+      resource_context_(new ShellResourceContext) {
   InitWhileIOAllowed();
 }
 
@@ -100,14 +127,33 @@
 }
 
 net::URLRequestContextGetter* ShellBrowserContext::GetRequestContext()  {
-  if (!url_request_getter_) {
-    url_request_getter_ = new ShellURLRequestContextGetter(
-        ignore_certificate_errors_,
-        GetPath(),
-        BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
-        BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE));
-  }
-  return url_request_getter_;
+  return GetDefaultStoragePartition(this)->GetURLRequestContext();
+}
+
+net::URLRequestContextGetter* ShellBrowserContext::CreateRequestContext(
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  DCHECK(!url_request_getter_);
+  url_request_getter_ = new ShellURLRequestContextGetter(
+      ignore_certificate_errors_,
+      GetPath(),
+      BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
+      BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
+      blob_protocol_handler.Pass(),
+      file_system_protocol_handler.Pass(),
+      developer_protocol_handler.Pass(),
+      chrome_protocol_handler.Pass(),
+      chrome_devtools_protocol_handler.Pass());
+  resource_context_->set_url_request_context_getter(url_request_getter_.get());
+  return url_request_getter_.get();
 }
 
 net::URLRequestContextGetter*
@@ -135,17 +181,23 @@
 }
 
 net::URLRequestContextGetter*
-    ShellBrowserContext::GetRequestContextForStoragePartition(
+    ShellBrowserContext::CreateRequestContextForStoragePartition(
         const base::FilePath& partition_path,
-        bool in_memory) {
+        bool in_memory,
+        scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+            blob_protocol_handler,
+        scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+            file_system_protocol_handler,
+        scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+            developer_protocol_handler,
+        scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+            chrome_protocol_handler,
+        scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+            chrome_devtools_protocol_handler) {
   return NULL;
 }
 
 ResourceContext* ShellBrowserContext::GetResourceContext()  {
-  if (!resource_context_.get()) {
-    resource_context_.reset(new ShellResourceContext(
-        static_cast<ShellURLRequestContextGetter*>(GetRequestContext())));
-  }
   return resource_context_.get();
 }
 
diff --git a/content/shell/shell_browser_context.h b/content/shell/shell_browser_context.h
index 8b82b8a..938c3b8b3 100644
--- a/content/shell/shell_browser_context.h
+++ b/content/shell/shell_browser_context.h
@@ -10,12 +10,14 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "content/public/browser/browser_context.h"
+#include "net/url_request/url_request_job_factory.h"
 
 namespace content {
 
 class DownloadManagerDelegate;
 class ResourceContext;
 class ShellDownloadManagerDelegate;
+class ShellURLRequestContextGetter;
 
 class ShellBrowserContext : public BrowserContext {
  public:
@@ -36,9 +38,6 @@
       GetMediaRequestContextForStoragePartition(
           const base::FilePath& partition_path,
           bool in_memory) OVERRIDE;
-  virtual net::URLRequestContextGetter* GetRequestContextForStoragePartition(
-      const base::FilePath& partition_path,
-      bool in_memory) OVERRIDE;
   virtual ResourceContext* GetResourceContext() OVERRIDE;
   virtual GeolocationPermissionContext*
       GetGeolocationPermissionContext() OVERRIDE;
@@ -46,7 +45,34 @@
       GetSpeechRecognitionPreferences() OVERRIDE;
   virtual quota::SpecialStoragePolicy* GetSpecialStoragePolicy() OVERRIDE;
 
+  net::URLRequestContextGetter* CreateRequestContext(
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler);
+  net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
+      const FilePath& partition_path,
+      bool in_memory,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler);
+
  private:
+  class ShellResourceContext;
+
   // Performs initialization of the ShellBrowserContext while IO is still
   // allowed on the current thread.
   void InitWhileIOAllowed();
@@ -54,9 +80,9 @@
   bool off_the_record_;
   bool ignore_certificate_errors_;
   base::FilePath path_;
-  scoped_ptr<ResourceContext> resource_context_;
+  scoped_ptr<ShellResourceContext> resource_context_;
   scoped_refptr<ShellDownloadManagerDelegate> download_manager_delegate_;
-  scoped_refptr<net::URLRequestContextGetter> url_request_getter_;
+  scoped_refptr<ShellURLRequestContextGetter> url_request_getter_;
 
   DISALLOW_COPY_AND_ASSIGN(ShellBrowserContext);
 };
diff --git a/content/shell/shell_content_browser_client.cc b/content/shell/shell_content_browser_client.cc
index abc24d1..b2b93aa 100644
--- a/content/shell/shell_content_browser_client.cc
+++ b/content/shell/shell_content_browser_client.cc
@@ -81,6 +81,50 @@
   host->Send(new ShellViewMsg_SetWebKitSourceDir(webkit_source_dir_));
 }
 
+net::URLRequestContextGetter* ShellContentBrowserClient::CreateRequestContext(
+    BrowserContext* content_browser_context,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  ShellBrowserContext* shell_browser_context =
+      ShellBrowserContextForBrowserContext(content_browser_context);
+  return shell_browser_context->CreateRequestContext(
+      blob_protocol_handler.Pass(), file_system_protocol_handler.Pass(),
+      developer_protocol_handler.Pass(), chrome_protocol_handler.Pass(),
+      chrome_devtools_protocol_handler.Pass());
+}
+
+net::URLRequestContextGetter*
+ShellContentBrowserClient::CreateRequestContextForStoragePartition(
+    BrowserContext* content_browser_context,
+    const FilePath& partition_path,
+    bool in_memory,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler) {
+  ShellBrowserContext* shell_browser_context =
+      ShellBrowserContextForBrowserContext(content_browser_context);
+  return shell_browser_context->CreateRequestContextForStoragePartition(
+      partition_path, in_memory, blob_protocol_handler.Pass(),
+      file_system_protocol_handler.Pass(),
+      developer_protocol_handler.Pass(), chrome_protocol_handler.Pass(),
+      chrome_devtools_protocol_handler.Pass());
+}
+
 void ShellContentBrowserClient::AppendExtraCommandLineSwitches(
     CommandLine* command_line, int child_process_id) {
   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
@@ -166,4 +210,13 @@
   return new ShellAccessTokenStore(browser_context()->GetRequestContext());
 }
 
+ShellBrowserContext*
+ShellContentBrowserClient::ShellBrowserContextForBrowserContext(
+    BrowserContext* content_browser_context) {
+  if (content_browser_context == browser_context())
+    return browser_context();
+  DCHECK_EQ(content_browser_context, off_the_record_browser_context());
+  return off_the_record_browser_context();
+}
+
 }  // namespace content
diff --git a/content/shell/shell_content_browser_client.h b/content/shell/shell_content_browser_client.h
index 91d821e..10933a92 100644
--- a/content/shell/shell_content_browser_client.h
+++ b/content/shell/shell_content_browser_client.h
@@ -27,6 +27,32 @@
   virtual BrowserMainParts* CreateBrowserMainParts(
       const MainFunctionParams& parameters) OVERRIDE;
   virtual void RenderProcessHostCreated(RenderProcessHost* host) OVERRIDE;
+  virtual net::URLRequestContextGetter* CreateRequestContext(
+      BrowserContext* browser_context,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) OVERRIDE;
+  virtual net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
+      BrowserContext* browser_context,
+      const FilePath& partition_path,
+      bool in_memory,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler) OVERRIDE;
   virtual void AppendExtraCommandLineSwitches(CommandLine* command_line,
                                               int child_process_id) OVERRIDE;
   virtual void OverrideWebkitPrefs(RenderViewHost* render_view_host,
@@ -62,6 +88,9 @@
   }
 
  private:
+  ShellBrowserContext* ShellBrowserContextForBrowserContext(
+      BrowserContext* content_browser_context);
+
   scoped_ptr<ShellResourceDispatcherHostDelegate>
       resource_dispatcher_host_delegate_;
 
diff --git a/content/shell/shell_resource_context.cc b/content/shell/shell_resource_context.cc
deleted file mode 100644
index 4d247e4..0000000
--- a/content/shell/shell_resource_context.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/shell/shell_resource_context.h"
-#include "content/shell/shell_url_request_context_getter.h"
-
-namespace content {
-
-ShellResourceContext::ShellResourceContext(
-    ShellURLRequestContextGetter* getter)
-    : getter_(getter) {
-}
-
-ShellResourceContext::~ShellResourceContext() {
-}
-
-net::HostResolver* ShellResourceContext::GetHostResolver() {
-  return getter_->host_resolver();
-}
-
-net::URLRequestContext* ShellResourceContext::GetRequestContext() {
-  return getter_->GetURLRequestContext();
-}
-
-}  // namespace content
diff --git a/content/shell/shell_resource_context.h b/content/shell/shell_resource_context.h
deleted file mode 100644
index 046b89a0..0000000
--- a/content/shell/shell_resource_context.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_SHELL_SHELL_RESOURCE_CONTEXT_H_
-#define CONTENT_SHELL_SHELL_RESOURCE_CONTEXT_H_
-
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "content/public/browser/resource_context.h"
-
-namespace content {
-
-class ShellURLRequestContextGetter;
-
-class ShellResourceContext : public ResourceContext {
- public:
-  explicit ShellResourceContext(ShellURLRequestContextGetter* getter);
-  virtual ~ShellResourceContext();
-
- private:
-  // ResourceContext implementation:
-  virtual net::HostResolver* GetHostResolver() OVERRIDE;
-  virtual net::URLRequestContext* GetRequestContext() OVERRIDE;
-
-  scoped_refptr<ShellURLRequestContextGetter> getter_;
-
-  DISALLOW_COPY_AND_ASSIGN(ShellResourceContext);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_SHELL_SHELL_RESOURCE_CONTEXT_H_
diff --git a/content/shell/shell_url_request_context_getter.cc b/content/shell/shell_url_request_context_getter.cc
index b085b9e..251bf00 100644
--- a/content/shell/shell_url_request_context_getter.cc
+++ b/content/shell/shell_url_request_context_getter.cc
@@ -12,6 +12,7 @@
 #include "base/threading/worker_pool.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/content_switches.h"
+#include "content/public/common/url_constants.h"
 #include "content/shell/shell_network_delegate.h"
 #include "content/shell/shell_switches.h"
 #include "net/base/cert_verifier.h"
@@ -26,6 +27,7 @@
 #include "net/http/http_network_session.h"
 #include "net/http/http_server_properties_impl.h"
 #include "net/proxy/proxy_service.h"
+#include "net/url_request/protocol_intercept_job_factory.h"
 #include "net/url_request/static_http_user_agent_settings.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_storage.h"
@@ -37,11 +39,27 @@
     bool ignore_certificate_errors,
     const base::FilePath& base_path,
     MessageLoop* io_loop,
-    MessageLoop* file_loop)
+    MessageLoop* file_loop,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        blob_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        file_system_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        developer_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_protocol_handler,
+    scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+        chrome_devtools_protocol_handler)
     : ignore_certificate_errors_(ignore_certificate_errors),
       base_path_(base_path),
       io_loop_(io_loop),
-      file_loop_(file_loop) {
+      file_loop_(file_loop),
+      blob_protocol_handler_(blob_protocol_handler.Pass()),
+      file_system_protocol_handler_(file_system_protocol_handler.Pass()),
+      developer_protocol_handler_(developer_protocol_handler.Pass()),
+      chrome_protocol_handler_(chrome_protocol_handler.Pass()),
+      chrome_devtools_protocol_handler_(
+          chrome_devtools_protocol_handler.Pass()) {
   // Must first be created on the UI thread.
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
@@ -151,7 +169,24 @@
         network_session_params, main_backend);
     storage_->set_http_transaction_factory(main_cache);
 
-    storage_->set_job_factory(new net::URLRequestJobFactoryImpl);
+    scoped_ptr<net::URLRequestJobFactoryImpl> job_factory(
+        new net::URLRequestJobFactoryImpl());
+    bool set_protocol = job_factory->SetProtocolHandler(
+        chrome::kBlobScheme, blob_protocol_handler_.release());
+    DCHECK(set_protocol);
+    set_protocol = job_factory->SetProtocolHandler(
+        chrome::kFileSystemScheme, file_system_protocol_handler_.release());
+    DCHECK(set_protocol);
+    set_protocol = job_factory->SetProtocolHandler(
+            chrome::kChromeUIScheme, chrome_protocol_handler_.release());
+    DCHECK(set_protocol);
+    set_protocol = job_factory->SetProtocolHandler(
+        chrome::kChromeDevToolsScheme,
+        chrome_devtools_protocol_handler_.release());
+    DCHECK(set_protocol);
+    storage_->set_job_factory(new net::ProtocolInterceptJobFactory(
+        job_factory.PassAs<net::URLRequestJobFactory>(),
+        developer_protocol_handler_.Pass()));
   }
 
   return url_request_context_.get();
diff --git a/content/shell/shell_url_request_context_getter.h b/content/shell/shell_url_request_context_getter.h
index 764a9e6..e631a18f 100644
--- a/content/shell/shell_url_request_context_getter.h
+++ b/content/shell/shell_url_request_context_getter.h
@@ -10,6 +10,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "net/url_request/url_request_context_getter.h"
+#include "net/url_request/url_request_job_factory.h"
 
 class MessageLoop;
 
@@ -29,7 +30,17 @@
       bool ignore_certificate_errors,
       const base::FilePath& base_path,
       MessageLoop* io_loop,
-      MessageLoop* file_loop);
+      MessageLoop* file_loop,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          blob_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          file_system_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          developer_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_protocol_handler,
+      scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+          chrome_devtools_protocol_handler);
 
   // net::URLRequestContextGetter implementation.
   virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
@@ -51,6 +62,16 @@
   scoped_ptr<net::NetworkDelegate> network_delegate_;
   scoped_ptr<net::URLRequestContextStorage> storage_;
   scoped_ptr<net::URLRequestContext> url_request_context_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      blob_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      file_system_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      developer_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      chrome_protocol_handler_;
+  scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
+      chrome_devtools_protocol_handler_;
 
   DISALLOW_COPY_AND_ASSIGN(ShellURLRequestContextGetter);
 };