From 434a6e3561fea806dd3f0b3888d8c2e20b650a6f Mon Sep 17 00:00:00 2001
From: Robo <hop2deep@gmail.com>
Date: Thu, 4 Oct 2018 23:38:56 +0530
Subject: [PATCH] refactor: create request context from network context
 (#14656)

* [ci skip] refactor: create request context from network context

* [ci skip] refactor: subscribe to mojo cookiemanager for cookie changes

* [ci skip] refactor: manage the lifetime of custom URLRequestJobFactory

* refactor: use OOP mojo proxy resolver

* revert: add support for kIgnoreCertificateErrorsSPKIList

* build: provide service manifest overlays for content services

* chore: gn format

* fix: log-net-log switch not working as expected

* spec: verify proxy settings are respected from pac script with session.setProxy

* chore: use chrome constants where possible

* fix: initialize request context for global cert fetcher

* refactor: fix destruction of request context getters

* spec: use custom session for proxy tests

* fix: queue up additional stop callbacks while net log is being stopped

* fix: Add CHECK for cookie manager retrieval

* chore: add helper to retrieve logging state for net log module

* fix: ui::ResourceBundle::GetRawDataResourceForScale => GetRawDataResource

* style: comment unused parameters

* build: move //components/certificate_transparency deps from //brightray

* chore: update gritsettings_resource_ids patch

* chore: update api for chromium 68

* fix: net log instance is now a property of session
---
 BUILD.gn                                      |  42 ++
 atom/browser/api/atom_api_cookies.cc          |  26 +-
 atom/browser/api/atom_api_cookies.h           |   2 +-
 atom/browser/api/atom_api_net_log.cc          | 121 +++--
 atom/browser/api/atom_api_net_log.h           |  34 +-
 atom/browser/api/atom_api_protocol.cc         |  22 +-
 atom/browser/api/atom_api_protocol.h          |  22 +-
 atom/browser/api/atom_api_session.cc          | 158 ++----
 atom/browser/api/atom_api_session.h           |  10 +-
 atom/browser/api/atom_api_web_request.cc      |   6 +-
 atom/browser/atom_browser_client.cc           |  47 +-
 atom/browser/atom_browser_client.h            |   8 +
 atom/browser/atom_browser_context.cc          | 231 +++++++--
 atom/browser/atom_browser_context.h           | 126 ++++-
 atom/browser/atom_browser_main_parts.cc       |  34 +-
 atom/browser/atom_browser_main_parts.h        |  15 +-
 atom/browser/common_web_contents_delegate.cc  |   4 +-
 atom/browser/cookie_change_notifier.cc        |  72 +++
 atom/browser/cookie_change_notifier.h         |  48 ++
 atom/browser/io_thread.cc                     |  80 +++
 {brightray => atom}/browser/io_thread.h       |  24 +-
 atom/browser/net/atom_url_request.cc          |   2 +-
 .../net/atom_url_request_job_factory.cc       |  29 +-
 .../net/atom_url_request_job_factory.h        |   8 +-
 atom/browser/net/cookie_details.h             |  10 +-
 atom/browser/net/resolve_proxy_helper.cc      |  96 ++++
 atom/browser/net/resolve_proxy_helper.h       |  68 +++
 .../browser/net/url_request_context_getter.cc | 417 ++++++++++++++++
 atom/browser/net/url_request_context_getter.h | 117 +++++
 atom/browser/net/url_request_fetch_job.cc     |   4 +
 atom/browser/pref_store_delegate.cc           |  30 ++
 atom/browser/pref_store_delegate.h            |  52 ++
 atom/browser/request_context_delegate.cc      | 166 -------
 atom/browser/request_context_delegate.h       |  59 ---
 atom/common/node_bindings.cc                  |   1 -
 atom/common/options_switches.cc               |   7 +
 atom/common/options_switches.h                |   2 +
 atom/utility/atom_content_utility_client.cc   |  14 +
 atom/utility/atom_content_utility_client.h    |   1 +
 brightray/BUILD.gn                            |  13 -
 brightray/browser/browser_client.cc           |   5 -
 brightray/browser/browser_client.h            |   3 -
 brightray/browser/browser_context.cc          | 207 --------
 brightray/browser/browser_context.h           | 133 -----
 brightray/browser/browser_main_parts.cc       |   6 -
 brightray/browser/browser_main_parts.h        |   5 -
 brightray/browser/inspectable_web_contents.cc |   3 +-
 brightray/browser/inspectable_web_contents.h  |   3 +
 .../browser/inspectable_web_contents_impl.cc  |  16 +-
 .../browser/inspectable_web_contents_impl.h   |   4 +-
 brightray/browser/io_thread.cc                |  52 --
 brightray/browser/net_log.cc                  | 103 ----
 brightray/browser/net_log.h                   |  44 --
 .../browser/url_request_context_getter.cc     | 459 ------------------
 .../browser/url_request_context_getter.h      | 150 ------
 brightray/common/switches.cc                  |  55 ---
 brightray/common/switches.h                   |  25 -
 chromium_src/BUILD.gn                         |  11 +
 docs/api/net-log.md                           |  17 +-
 docs/api/session.md                           |  17 +
 electron_paks.gni                             |   2 +
 electron_resources.grd                        |  15 +
 filenames.gni                                 |  12 +-
 lib/browser/api/net-log.js                    |  36 +-
 ...tron_content_browser_manifest_overlay.json |  12 +
 ...nt_packaged_services_manifest_overlay.json |   5 +
 patches/common/chromium/.patches.yaml         |  16 +-
 .../chromium/content_browser_manifest.patch   |  15 -
 .../chromium/gritsettings_resource_ids.patch  |  15 +
 .../chromium/proxy_config_monitor.patch       |  84 ++++
 spec/api-net-log-spec.js                      |  35 +-
 spec/api-session-spec.js                      |  47 +-
 spec/fixtures/api/net-log/main.js             |  35 +-
 73 files changed, 2031 insertions(+), 1844 deletions(-)
 create mode 100644 atom/browser/cookie_change_notifier.cc
 create mode 100644 atom/browser/cookie_change_notifier.h
 create mode 100644 atom/browser/io_thread.cc
 rename {brightray => atom}/browser/io_thread.h (55%)
 create mode 100644 atom/browser/net/resolve_proxy_helper.cc
 create mode 100644 atom/browser/net/resolve_proxy_helper.h
 create mode 100644 atom/browser/net/url_request_context_getter.cc
 create mode 100644 atom/browser/net/url_request_context_getter.h
 create mode 100644 atom/browser/pref_store_delegate.cc
 create mode 100644 atom/browser/pref_store_delegate.h
 delete mode 100644 atom/browser/request_context_delegate.cc
 delete mode 100644 atom/browser/request_context_delegate.h
 delete mode 100644 brightray/browser/browser_context.cc
 delete mode 100644 brightray/browser/browser_context.h
 delete mode 100644 brightray/browser/io_thread.cc
 delete mode 100644 brightray/browser/net_log.cc
 delete mode 100644 brightray/browser/net_log.h
 delete mode 100644 brightray/browser/url_request_context_getter.cc
 delete mode 100644 brightray/browser/url_request_context_getter.h
 delete mode 100644 brightray/common/switches.cc
 delete mode 100644 brightray/common/switches.h
 create mode 100644 electron_resources.grd
 create mode 100644 manifests/electron_content_browser_manifest_overlay.json
 create mode 100644 manifests/electron_content_packaged_services_manifest_overlay.json
 delete mode 100644 patches/common/chromium/content_browser_manifest.patch
 create mode 100644 patches/common/chromium/gritsettings_resource_ids.patch
 create mode 100644 patches/common/chromium/proxy_config_monitor.patch

diff --git a/BUILD.gn b/BUILD.gn
index 322cc4d989fe..b7b0f69283ad 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -6,8 +6,10 @@ import("filenames.gni")
 import("//build/config/locales.gni")
 import("//build/config/win/manifest.gni")
 import("//pdf/features.gni")
+import("//services/service_manager/public/service_manifest.gni")
 import("//third_party/ffmpeg/ffmpeg_options.gni")
 import("//third_party/widevine/cdm/widevine.gni")
+import("//tools/grit/grit_rule.gni")
 import("//tools/grit/repack.gni")
 import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
 import("//v8/snapshot_toolchain.gni")
@@ -171,6 +173,26 @@ asar("app2asar") {
   root = "default_app"
 }
 
+grit("resources") {
+  source = "electron_resources.grd"
+
+  outputs = [
+    "grit/electron_resources.h",
+    "electron_resources.pak",
+  ]
+
+  grit_flags = [
+    "-E",
+    "target_gen_dir=" + rebase_path(target_gen_dir, root_build_dir),
+  ]
+
+  deps = [
+    ":electron_content_manifest_overlays",
+  ]
+
+  output_dir = "$target_gen_dir"
+}
+
 static_library("electron_lib") {
   configs += [ "//v8:external_startup_data" ]
   configs += [ "//third_party/electron_node:node_internals" ]
@@ -185,12 +207,15 @@ static_library("electron_lib") {
     "native_mate",
     "//base",
     "//base:i18n",
+    "//components/certificate_transparency",
+    "//components/net_log",
     "//components/network_session_configurator/common",
     "//components/prefs",
     "//components/printing/common",
     "//components/viz/service",
     "//content/public/app:both",
     "//content/public/child",
+    "//content/public/common:service_names",
     "//device/geolocation",
     "//gin",
     "//net:net_resources",
@@ -198,6 +223,7 @@ static_library("electron_lib") {
     "//ppapi/proxy",
     "//ppapi/shared_impl",
     "//printing",
+    "//services/proxy_resolver:lib",
     "//skia",
     "//third_party/blink/public:blink",
     "//third_party/boringssl",
@@ -914,3 +940,19 @@ group("electron") {
     ":electron_app",
   ]
 }
+
+group("electron_content_manifest_overlays") {
+  deps = [
+    ":electron_content_browser_manifest_overlay",
+    ":electron_content_packaged_services_manifest_overlay",
+  ]
+}
+
+service_manifest("electron_content_packaged_services_manifest_overlay") {
+  source = "//electron/manifests/electron_content_packaged_services_manifest_overlay.json"
+  packaged_services = [ "//services/proxy_resolver:proxy_resolver_manifest" ]
+}
+
+service_manifest("electron_content_browser_manifest_overlay") {
+  source = "//electron/manifests/electron_content_browser_manifest_overlay.json"
+}
diff --git a/atom/browser/api/atom_api_cookies.cc b/atom/browser/api/atom_api_cookies.cc
index e1013b711f07..882937b1c6be 100644
--- a/atom/browser/api/atom_api_cookies.cc
+++ b/atom/browser/api/atom_api_cookies.cc
@@ -8,7 +8,7 @@
 #include <utility>
 
 #include "atom/browser/atom_browser_context.h"
-#include "atom/browser/request_context_delegate.h"
+#include "atom/browser/cookie_change_notifier.h"
 #include "atom/common/native_mate_converters/callback.h"
 #include "atom/common/native_mate_converters/gurl_converter.h"
 #include "atom/common/native_mate_converters/value_converter.h"
@@ -59,20 +59,21 @@ struct Converter<net::CanonicalCookie> {
 };
 
 template <>
-struct Converter<net::CookieChangeCause> {
-  static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
-                                   const net::CookieChangeCause& val) {
+struct Converter<network::mojom::CookieChangeCause> {
+  static v8::Local<v8::Value> ToV8(
+      v8::Isolate* isolate,
+      const network::mojom::CookieChangeCause& val) {
     switch (val) {
-      case net::CookieChangeCause::INSERTED:
-      case net::CookieChangeCause::EXPLICIT:
+      case network::mojom::CookieChangeCause::INSERTED:
+      case network::mojom::CookieChangeCause::EXPLICIT:
         return mate::StringToV8(isolate, "explicit");
-      case net::CookieChangeCause::OVERWRITE:
+      case network::mojom::CookieChangeCause::OVERWRITE:
         return mate::StringToV8(isolate, "overwrite");
-      case net::CookieChangeCause::EXPIRED:
+      case network::mojom::CookieChangeCause::EXPIRED:
         return mate::StringToV8(isolate, "expired");
-      case net::CookieChangeCause::EVICTED:
+      case network::mojom::CookieChangeCause::EVICTED:
         return mate::StringToV8(isolate, "evicted");
-      case net::CookieChangeCause::EXPIRED_OVERWRITE:
+      case network::mojom::CookieChangeCause::EXPIRED_OVERWRITE:
         return mate::StringToV8(isolate, "expired-overwrite");
       default:
         return mate::StringToV8(isolate, "unknown");
@@ -258,9 +259,8 @@ Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context)
     : browser_context_(browser_context) {
   Init(isolate);
   cookie_change_subscription_ =
-      browser_context->GetRequestContextDelegate()
-          ->RegisterCookieChangeCallback(
-              base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
+      browser_context_->cookie_change_notifier()->RegisterCookieChangeCallback(
+          base::Bind(&Cookies::OnCookieChanged, base::Unretained(this)));
 }
 
 Cookies::~Cookies() {}
diff --git a/atom/browser/api/atom_api_cookies.h b/atom/browser/api/atom_api_cookies.h
index f40eaa30f44d..5e2f7b52a5be 100644
--- a/atom/browser/api/atom_api_cookies.h
+++ b/atom/browser/api/atom_api_cookies.h
@@ -56,7 +56,7 @@ class Cookies : public mate::TrackableObject<Cookies> {
   void Set(const base::DictionaryValue& details, const SetCallback& callback);
   void FlushStore(const base::Closure& callback);
 
-  // AtomBrowserContext::RegisterCookieChangeCallback subscription:
+  // CookieChangeNotifier subscription:
   void OnCookieChanged(const CookieDetails*);
 
  private:
diff --git a/atom/browser/api/atom_api_net_log.cc b/atom/browser/api/atom_api_net_log.cc
index 24bd017f3d96..676dca42ebf4 100644
--- a/atom/browser/api/atom_api_net_log.cc
+++ b/atom/browser/api/atom_api_net_log.cc
@@ -6,13 +6,16 @@
 
 #include <utility>
 
-#include "atom/browser/atom_browser_client.h"
+#include "atom/browser/atom_browser_context.h"
+#include "atom/browser/atom_browser_main_parts.h"
 #include "atom/common/native_mate_converters/callback.h"
 #include "atom/common/native_mate_converters/file_path_converter.h"
-#include "base/callback.h"
-#include "content/public/common/content_switches.h"
+#include "base/command_line.h"
+#include "components/net_log/chrome_net_log.h"
+#include "content/public/browser/storage_partition.h"
 #include "native_mate/dictionary.h"
 #include "native_mate/handle.h"
+#include "net/url_request/url_request_context_getter.h"
 
 #include "atom/common/node_includes.h"
 
@@ -20,17 +23,17 @@ namespace atom {
 
 namespace api {
 
-NetLog::NetLog(v8::Isolate* isolate) {
+NetLog::NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context)
+    : browser_context_(browser_context) {
   Init(isolate);
 
-  net_log_ = atom::AtomBrowserClient::Get()->GetNetLog();
+  net_log_writer_ =
+      atom::AtomBrowserMainParts::Get()->net_log()->net_export_file_writer();
+  net_log_writer_->AddObserver(this);
 }
 
-NetLog::~NetLog() {}
-
-// static
-v8::Local<v8::Value> NetLog::Create(v8::Isolate* isolate) {
-  return mate::CreateHandle(isolate, new NetLog(isolate)).ToV8();
+NetLog::~NetLog() {
+  net_log_writer_->RemoveObserver(this);
 }
 
 void NetLog::StartLogging(mate::Arguments* args) {
@@ -40,22 +43,83 @@ void NetLog::StartLogging(mate::Arguments* args) {
     return;
   }
 
-  net_log_->StartDynamicLogging(log_path);
+  auto* network_context =
+      content::BrowserContext::GetDefaultStoragePartition(browser_context_)
+          ->GetNetworkContext();
+
+  // TODO(deepak1556): Provide more flexibility to this module
+  // by allowing customizations on the capturing options.
+  net_log_writer_->StartNetLog(
+      log_path, net::NetLogCaptureMode::Default(),
+      net_log::NetExportFileWriter::kNoLimit /* file size limit */,
+      base::CommandLine::ForCurrentProcess()->GetCommandLineString(),
+      std::string(), network_context);
 }
 
-bool NetLog::IsCurrentlyLogging() {
-  return net_log_->IsDynamicLogging();
+std::string NetLog::GetLoggingState() const {
+  if (!net_log_state_)
+    return std::string();
+  const base::Value* current_log_state =
+      net_log_state_->FindKeyOfType("state", base::Value::Type::STRING);
+  if (!current_log_state)
+    return std::string();
+  return current_log_state->GetString();
 }
 
-base::FilePath::StringType NetLog::GetCurrentlyLoggingPath() {
-  return net_log_->GetDynamicLoggingPath().value();
+bool NetLog::IsCurrentlyLogging() const {
+  const std::string log_state = GetLoggingState();
+  return (log_state == "STARTING_LOG") || (log_state == "LOGGING");
+}
+
+std::string NetLog::GetCurrentlyLoggingPath() const {
+  // Net log exporter has a default path which will be used
+  // when no log path is provided, but since we don't allow
+  // net log capture without user provided file path, this
+  // check is completely safe.
+  if (IsCurrentlyLogging()) {
+    const base::Value* current_log_path =
+        net_log_state_->FindKeyOfType("file", base::Value::Type::STRING);
+    if (current_log_path)
+      return current_log_path->GetString();
+  }
+
+  return std::string();
 }
 
 void NetLog::StopLogging(mate::Arguments* args) {
-  base::OnceClosure callback;
-  args->GetNext(&callback);
+  net_log::NetExportFileWriter::FilePathCallback callback;
+  if (!args->GetNext(&callback)) {
+    args->ThrowError("Invalid callback function");
+    return;
+  }
 
-  net_log_->StopDynamicLogging(std::move(callback));
+  if (IsCurrentlyLogging()) {
+    stop_callback_queue_.emplace_back(callback);
+    net_log_writer_->StopNetLog(nullptr);
+  } else {
+    callback.Run(base::FilePath());
+  }
+}
+
+void NetLog::OnNewState(const base::DictionaryValue& state) {
+  net_log_state_ = state.CreateDeepCopy();
+
+  if (stop_callback_queue_.empty())
+    return;
+
+  if (GetLoggingState() == "NOT_LOGGING") {
+    for (auto& callback : stop_callback_queue_) {
+      if (!callback.is_null())
+        net_log_writer_->GetFilePathToCompletedLog(callback);
+    }
+    stop_callback_queue_.clear();
+  }
+}
+
+// static
+mate::Handle<NetLog> NetLog::Create(v8::Isolate* isolate,
+                                    AtomBrowserContext* browser_context) {
+  return mate::CreateHandle(isolate, new NetLog(isolate, browser_context));
 }
 
 // static
@@ -66,28 +130,9 @@ void NetLog::BuildPrototype(v8::Isolate* isolate,
       .SetProperty("currentlyLogging", &NetLog::IsCurrentlyLogging)
       .SetProperty("currentlyLoggingPath", &NetLog::GetCurrentlyLoggingPath)
       .SetMethod("startLogging", &NetLog::StartLogging)
-      .SetMethod("_stopLogging", &NetLog::StopLogging);
+      .SetMethod("stopLogging", &NetLog::StopLogging);
 }
 
 }  // namespace api
 
 }  // namespace atom
-
-namespace {
-
-using atom::api::NetLog;
-
-void Initialize(v8::Local<v8::Object> exports,
-                v8::Local<v8::Value> unused,
-                v8::Local<v8::Context> context,
-                void* priv) {
-  v8::Isolate* isolate = context->GetIsolate();
-
-  mate::Dictionary dict(isolate, exports);
-  dict.Set("netLog", NetLog::Create(isolate));
-  dict.Set("NetLog", NetLog::GetConstructor(isolate)->GetFunction());
-}
-
-}  // namespace
-
-NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_net_log, Initialize)
diff --git a/atom/browser/api/atom_api_net_log.h b/atom/browser/api/atom_api_net_log.h
index dd68ac306c96..1afe0b43597f 100644
--- a/atom/browser/api/atom_api_net_log.h
+++ b/atom/browser/api/atom_api_net_log.h
@@ -5,32 +5,50 @@
 #ifndef ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
 #define ATOM_BROWSER_API_ATOM_API_NET_LOG_H_
 
+#include <list>
+#include <memory>
 #include <string>
-#include "brightray/browser/net_log.h"
-#include "native_mate/wrappable.h"
+
+#include "atom/browser/api/trackable_object.h"
+#include "base/callback.h"
+#include "base/values.h"
+#include "components/net_log/net_export_file_writer.h"
+#include "native_mate/handle.h"
 
 namespace atom {
 
+class AtomBrowserContext;
+
 namespace api {
 
-class NetLog : public mate::Wrappable<NetLog> {
+class NetLog : public mate::TrackableObject<NetLog>,
+               public net_log::NetExportFileWriter::StateObserver {
  public:
-  static v8::Local<v8::Value> Create(v8::Isolate* isolate);
+  static mate::Handle<NetLog> Create(v8::Isolate* isolate,
+                                     AtomBrowserContext* browser_context);
 
   static void BuildPrototype(v8::Isolate* isolate,
                              v8::Local<v8::FunctionTemplate> prototype);
 
   void StartLogging(mate::Arguments* args);
-  bool IsCurrentlyLogging();
-  base::FilePath::StringType GetCurrentlyLoggingPath();
+  std::string GetLoggingState() const;
+  bool IsCurrentlyLogging() const;
+  std::string GetCurrentlyLoggingPath() const;
   void StopLogging(mate::Arguments* args);
 
  protected:
-  explicit NetLog(v8::Isolate* isolate);
+  explicit NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context);
   ~NetLog() override;
 
+  // net_log::NetExportFileWriter::StateObserver implementation
+  void OnNewState(const base::DictionaryValue& state) override;
+
  private:
-  brightray::NetLog* net_log_;
+  AtomBrowserContext* browser_context_;
+  net_log::NetExportFileWriter* net_log_writer_;
+  std::list<net_log::NetExportFileWriter::FilePathCallback>
+      stop_callback_queue_;
+  std::unique_ptr<base::DictionaryValue> net_log_state_;
 
   DISALLOW_COPY_AND_ASSIGN(NetLog);
 };
diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc
index 9c171abd54e0..f0ec02a0a588 100644
--- a/atom/browser/api/atom_api_protocol.cc
+++ b/atom/browser/api/atom_api_protocol.cc
@@ -83,7 +83,8 @@ void Protocol::UnregisterProtocol(const std::string& scheme,
                                   mate::Arguments* args) {
   CompletionCallback callback;
   args->GetNext(&callback);
-  auto* getter = browser_context_->GetRequestContext();
+  auto* getter = static_cast<URLRequestContextGetter*>(
+      browser_context_->GetRequestContext());
   content::BrowserThread::PostTaskAndReplyWithResult(
       content::BrowserThread::IO, FROM_HERE,
       base::BindOnce(&Protocol::UnregisterProtocolInIO,
@@ -93,10 +94,9 @@ void Protocol::UnregisterProtocol(const std::string& scheme,
 
 // static
 Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
-    scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
+    scoped_refptr<URLRequestContextGetter> request_context_getter,
     const std::string& scheme) {
-  auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
-      request_context_getter->job_factory());
+  auto* job_factory = request_context_getter->job_factory();
   if (!job_factory->HasProtocolHandler(scheme))
     return PROTOCOL_NOT_REGISTERED;
   job_factory->SetProtocolHandler(scheme, nullptr);
@@ -105,7 +105,8 @@ Protocol::ProtocolError Protocol::UnregisterProtocolInIO(
 
 void Protocol::IsProtocolHandled(const std::string& scheme,
                                  const BooleanCallback& callback) {
-  auto* getter = browser_context_->GetRequestContext();
+  auto* getter = static_cast<URLRequestContextGetter*>(
+      browser_context_->GetRequestContext());
   content::BrowserThread::PostTaskAndReplyWithResult(
       content::BrowserThread::IO, FROM_HERE,
       base::Bind(&Protocol::IsProtocolHandledInIO, base::RetainedRef(getter),
@@ -115,7 +116,7 @@ void Protocol::IsProtocolHandled(const std::string& scheme,
 
 // static
 bool Protocol::IsProtocolHandledInIO(
-    scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
+    scoped_refptr<URLRequestContextGetter> request_context_getter,
     const std::string& scheme) {
   return request_context_getter->job_factory()->IsHandledProtocol(scheme);
 }
@@ -124,7 +125,8 @@ void Protocol::UninterceptProtocol(const std::string& scheme,
                                    mate::Arguments* args) {
   CompletionCallback callback;
   args->GetNext(&callback);
-  auto* getter = browser_context_->GetRequestContext();
+  auto* getter = static_cast<URLRequestContextGetter*>(
+      browser_context_->GetRequestContext());
   content::BrowserThread::PostTaskAndReplyWithResult(
       content::BrowserThread::IO, FROM_HERE,
       base::BindOnce(&Protocol::UninterceptProtocolInIO,
@@ -134,11 +136,9 @@ void Protocol::UninterceptProtocol(const std::string& scheme,
 
 // static
 Protocol::ProtocolError Protocol::UninterceptProtocolInIO(
-    scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
+    scoped_refptr<URLRequestContextGetter> request_context_getter,
     const std::string& scheme) {
-  return static_cast<AtomURLRequestJobFactory*>(
-             request_context_getter->job_factory())
-                 ->UninterceptProtocol(scheme)
+  return request_context_getter->job_factory()->UninterceptProtocol(scheme)
              ? PROTOCOL_OK
              : PROTOCOL_NOT_INTERCEPTED;
 }
diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h
index eb58159d75fe..7bfe4ac90226 100644
--- a/atom/browser/api/atom_api_protocol.h
+++ b/atom/browser/api/atom_api_protocol.h
@@ -102,7 +102,8 @@ class Protocol : public mate::TrackableObject<Protocol> {
                         mate::Arguments* args) {
     CompletionCallback callback;
     args->GetNext(&callback);
-    auto* getter = browser_context_->GetRequestContext();
+    auto* getter = static_cast<URLRequestContextGetter*>(
+        browser_context_->GetRequestContext());
     content::BrowserThread::PostTaskAndReplyWithResult(
         content::BrowserThread::IO, FROM_HERE,
         base::BindOnce(&Protocol::RegisterProtocolInIO<RequestJob>,
@@ -111,12 +112,11 @@ class Protocol : public mate::TrackableObject<Protocol> {
   }
   template <typename RequestJob>
   static ProtocolError RegisterProtocolInIO(
-      scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
+      scoped_refptr<URLRequestContextGetter> request_context_getter,
       v8::Isolate* isolate,
       const std::string& scheme,
       const Handler& handler) {
-    auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
-        request_context_getter->job_factory());
+    auto* job_factory = request_context_getter->job_factory();
     if (job_factory->IsHandledProtocol(scheme))
       return PROTOCOL_REGISTERED;
     auto protocol_handler = std::make_unique<CustomProtocolHandler<RequestJob>>(
@@ -130,14 +130,14 @@ class Protocol : public mate::TrackableObject<Protocol> {
   // Unregister the protocol handler that handles |scheme|.
   void UnregisterProtocol(const std::string& scheme, mate::Arguments* args);
   static ProtocolError UnregisterProtocolInIO(
-      scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
+      scoped_refptr<URLRequestContextGetter> request_context_getter,
       const std::string& scheme);
 
   // Whether the protocol has handler registered.
   void IsProtocolHandled(const std::string& scheme,
                          const BooleanCallback& callback);
   static bool IsProtocolHandledInIO(
-      scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
+      scoped_refptr<URLRequestContextGetter> request_context_getter,
       const std::string& scheme);
 
   // Replace the protocol handler with a new one.
@@ -147,7 +147,8 @@ class Protocol : public mate::TrackableObject<Protocol> {
                          mate::Arguments* args) {
     CompletionCallback callback;
     args->GetNext(&callback);
-    auto* getter = browser_context_->GetRequestContext();
+    auto* getter = static_cast<URLRequestContextGetter*>(
+        browser_context_->GetRequestContext());
     content::BrowserThread::PostTaskAndReplyWithResult(
         content::BrowserThread::IO, FROM_HERE,
         base::BindOnce(&Protocol::InterceptProtocolInIO<RequestJob>,
@@ -156,12 +157,11 @@ class Protocol : public mate::TrackableObject<Protocol> {
   }
   template <typename RequestJob>
   static ProtocolError InterceptProtocolInIO(
-      scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
+      scoped_refptr<URLRequestContextGetter> request_context_getter,
       v8::Isolate* isolate,
       const std::string& scheme,
       const Handler& handler) {
-    auto* job_factory = static_cast<AtomURLRequestJobFactory*>(
-        request_context_getter->job_factory());
+    auto* job_factory = request_context_getter->job_factory();
     if (!job_factory->IsHandledProtocol(scheme))
       return PROTOCOL_NOT_REGISTERED;
     // It is possible a protocol is handled but can not be intercepted.
@@ -177,7 +177,7 @@ class Protocol : public mate::TrackableObject<Protocol> {
   // Restore the |scheme| to its original protocol handler.
   void UninterceptProtocol(const std::string& scheme, mate::Arguments* args);
   static ProtocolError UninterceptProtocolInIO(
-      scoped_refptr<brightray::URLRequestContextGetter> request_context_getter,
+      scoped_refptr<URLRequestContextGetter> request_context_getter,
       const std::string& scheme);
 
   // Convert error code to JS exception and call the callback.
diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc
index ad1e7d6b15b1..57aa15a0c781 100644
--- a/atom/browser/api/atom_api_session.cc
+++ b/atom/browser/api/atom_api_session.cc
@@ -12,6 +12,7 @@
 
 #include "atom/browser/api/atom_api_cookies.h"
 #include "atom/browser/api/atom_api_download_item.h"
+#include "atom/browser/api/atom_api_net_log.h"
 #include "atom/browser/api/atom_api_protocol.h"
 #include "atom/browser/api/atom_api_web_request.h"
 #include "atom/browser/atom_browser_context.h"
@@ -31,12 +32,14 @@
 #include "base/guid.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
-#include "base/threading/thread_task_runner_handle.h"
 #include "brightray/browser/media/media_device_id_salt.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/common/pref_names.h"
 #include "components/download/public/common/download_danger_type.h"
 #include "components/prefs/pref_service.h"
+#include "components/prefs/value_map_pref_store.h"
+#include "components/proxy_config/proxy_config_dictionary.h"
+#include "components/proxy_config/proxy_config_pref_names.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/download_item_utils.h"
 #include "content/public/browser/download_manager_delegate.h"
@@ -48,10 +51,8 @@
 #include "net/dns/host_cache.h"
 #include "net/http/http_auth_handler_factory.h"
 #include "net/http/http_auth_preferences.h"
-#include "net/proxy_resolution/proxy_config_service_fixed.h"
-#include "net/proxy_resolution/proxy_config_with_annotation.h"
-#include "net/proxy_resolution/proxy_resolution_service.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "net/http/http_cache.h"
+#include "net/http/http_transaction_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_getter.h"
@@ -183,37 +184,6 @@ struct Converter<ClearAuthCacheOptions> {
   }
 };
 
-template <>
-struct Converter<net::ProxyConfig> {
-  static bool FromV8(v8::Isolate* isolate,
-                     v8::Local<v8::Value> val,
-                     net::ProxyConfig* out) {
-    std::string proxy_rules, proxy_bypass_rules;
-    GURL pac_url;
-    mate::Dictionary options;
-    // Fallback to previous API when passed String.
-    // https://git.io/vuhjj
-    if (ConvertFromV8(isolate, val, &proxy_rules)) {
-      pac_url = GURL(proxy_rules);  // Assume it is PAC script if it is URL.
-    } else if (ConvertFromV8(isolate, val, &options)) {
-      options.Get("pacScript", &pac_url);
-      options.Get("proxyRules", &proxy_rules);
-      options.Get("proxyBypassRules", &proxy_bypass_rules);
-    } else {
-      return false;
-    }
-
-    // pacScript takes precedence over proxyRules.
-    if (!pac_url.is_empty() && pac_url.is_valid()) {
-      out->set_pac_url(pac_url);
-    } else {
-      out->proxy_rules().ParseFromString(proxy_rules);
-      out->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_rules);
-    }
-    return true;
-  }
-};
-
 template <>
 struct Converter<atom::VerifyRequestParams> {
   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
@@ -240,56 +210,6 @@ const char kPersistPrefix[] = "persist:";
 // Referenced session objects.
 std::map<uint32_t, v8::Global<v8::Object>> g_sessions;
 
-class ResolveProxyHelper {
- public:
-  ResolveProxyHelper(AtomBrowserContext* browser_context,
-                     const GURL& url,
-                     const Session::ResolveProxyCallback& callback)
-      : callback_(callback),
-        original_thread_(base::ThreadTaskRunnerHandle::Get()) {
-    scoped_refptr<net::URLRequestContextGetter> context_getter =
-        browser_context->GetRequestContext();
-    context_getter->GetNetworkTaskRunner()->PostTask(
-        FROM_HERE, base::BindOnce(&ResolveProxyHelper::ResolveProxy,
-                                  base::Unretained(this), context_getter, url));
-  }
-
-  void OnResolveProxyCompleted(int result) {
-    std::string proxy;
-    if (result == net::OK)
-      proxy = proxy_info_.ToPacString();
-    original_thread_->PostTask(FROM_HERE, base::BindOnce(callback_, proxy));
-    delete this;
-  }
-
- private:
-  void ResolveProxy(scoped_refptr<net::URLRequestContextGetter> context_getter,
-                    const GURL& url) {
-    DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
-    net::ProxyResolutionService* proxy_service =
-        context_getter->GetURLRequestContext()->proxy_resolution_service();
-    net::CompletionCallback completion_callback = base::Bind(
-        &ResolveProxyHelper::OnResolveProxyCompleted, base::Unretained(this));
-
-    // Start the request.
-    int result = proxy_service->ResolveProxy(url, "GET", &proxy_info_,
-                                             completion_callback, &pac_req_,
-                                             nullptr, net::NetLogWithSource());
-
-    // Completed synchronously.
-    if (result != net::ERR_IO_PENDING)
-      completion_callback.Run(result);
-  }
-
-  Session::ResolveProxyCallback callback_;
-  net::ProxyInfo proxy_info_;
-  net::ProxyResolutionService::Request* pac_req_;
-  scoped_refptr<base::SingleThreadTaskRunner> original_thread_;
-
-  DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
-};
-
 // Runs the callback in UI thread.
 void RunCallbackInUI(const base::Callback<void()>& callback) {
   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
@@ -347,19 +267,6 @@ void DoCacheActionInIO(
     on_get_backend.Run(net::OK);
 }
 
-void SetProxyInIO(scoped_refptr<net::URLRequestContextGetter> getter,
-                  const net::ProxyConfig& config,
-                  const base::Closure& callback) {
-  auto* proxy_service =
-      getter->GetURLRequestContext()->proxy_resolution_service();
-  proxy_service->ResetConfigService(
-      base::WrapUnique(new net::ProxyConfigServiceFixed(
-          net::ProxyConfigWithAnnotation(config, NO_TRAFFIC_ANNOTATION_YET))));
-  // Refetches and applies the new pac script if provided.
-  proxy_service->ForceReloadProxyConfig();
-  RunCallbackInUI(callback);
-}
-
 void SetCertVerifyProcInIO(
     const scoped_refptr<net::URLRequestContextGetter>& context_getter,
     const AtomCertVerifier::VerifyProc& proc) {
@@ -447,7 +354,7 @@ void DownloadIdCallback(content::DownloadManager* download_manager,
 }
 
 void SetDevToolsNetworkEmulationClientIdInIO(
-    brightray::URLRequestContextGetter* url_request_context_getter,
+    net::URLRequestContextGetter* url_request_context_getter,
     const std::string& client_id) {
   if (!url_request_context_getter)
     return;
@@ -496,6 +403,7 @@ Session::~Session() {
   DestroyGlobalHandle(isolate(), cookies_);
   DestroyGlobalHandle(isolate(), web_request_);
   DestroyGlobalHandle(isolate(), protocol_);
+  DestroyGlobalHandle(isolate(), net_log_);
   g_sessions.erase(weak_map_id());
 }
 
@@ -518,8 +426,10 @@ void Session::OnDownloadCreated(content::DownloadManager* manager,
   }
 }
 
-void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) {
-  new ResolveProxyHelper(browser_context(), url, callback);
+void Session::ResolveProxy(
+    const GURL& url,
+    const ResolveProxyHelper::ResolveProxyCallback& callback) {
+  browser_context_->GetResolveProxyHelper()->ResolveProxy(url, callback);
 }
 
 template <Session::CacheAction action>
@@ -557,13 +467,34 @@ void Session::FlushStorageData() {
   storage_partition->Flush();
 }
 
-void Session::SetProxy(const net::ProxyConfig& config,
+void Session::SetProxy(const mate::Dictionary& options,
                        const base::Closure& callback) {
-  auto* getter = browser_context_->GetRequestContext();
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::BindOnce(&SetProxyInIO, base::RetainedRef(getter), config,
-                     callback));
+  if (!browser_context_->in_memory_pref_store()) {
+    callback.Run();
+    return;
+  }
+
+  std::string proxy_rules, bypass_list, pac_url;
+
+  options.Get("pacScript", &pac_url);
+  options.Get("proxyRules", &proxy_rules);
+  options.Get("proxyBypassRules", &bypass_list);
+
+  // pacScript takes precedence over proxyRules.
+  if (!pac_url.empty()) {
+    browser_context_->in_memory_pref_store()->SetValue(
+        proxy_config::prefs::kProxy,
+        ProxyConfigDictionary::CreatePacScript(pac_url,
+                                               true /* pac_mandatory */),
+        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  } else {
+    browser_context_->in_memory_pref_store()->SetValue(
+        proxy_config::prefs::kProxy,
+        ProxyConfigDictionary::CreateFixedServers(proxy_rules, bypass_list),
+        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  }
+
+  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
 }
 
 void Session::SetDownloadPath(const base::FilePath& path) {
@@ -686,7 +617,7 @@ void Session::SetUserAgent(const std::string& user_agent,
   std::string accept_lang = g_browser_process->GetApplicationLocale();
   args->GetNext(&accept_lang);
 
-  scoped_refptr<brightray::URLRequestContextGetter> getter(
+  scoped_refptr<net::URLRequestContextGetter> getter(
       browser_context_->GetRequestContext());
   getter->GetNetworkTaskRunner()->PostTask(
       FROM_HERE,
@@ -777,6 +708,14 @@ v8::Local<v8::Value> Session::WebRequest(v8::Isolate* isolate) {
   return v8::Local<v8::Value>::New(isolate, web_request_);
 }
 
+v8::Local<v8::Value> Session::NetLog(v8::Isolate* isolate) {
+  if (net_log_.IsEmpty()) {
+    auto handle = atom::api::NetLog::Create(isolate, browser_context());
+    net_log_.Reset(isolate, handle.ToV8());
+  }
+  return v8::Local<v8::Value>::New(isolate, net_log_);
+}
+
 // static
 mate::Handle<Session> Session::CreateFrom(v8::Isolate* isolate,
                                           AtomBrowserContext* browser_context) {
@@ -845,6 +784,7 @@ void Session::BuildPrototype(v8::Isolate* isolate,
       .SetMethod("setPreloads", &Session::SetPreloads)
       .SetMethod("getPreloads", &Session::GetPreloads)
       .SetProperty("cookies", &Session::Cookies)
+      .SetProperty("netLog", &Session::NetLog)
       .SetProperty("protocol", &Session::Protocol)
       .SetProperty("webRequest", &Session::WebRequest);
 }
diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h
index 3b5a0987ec77..09be19595a36 100644
--- a/atom/browser/api/atom_api_session.h
+++ b/atom/browser/api/atom_api_session.h
@@ -10,6 +10,7 @@
 
 #include "atom/browser/api/trackable_object.h"
 #include "atom/browser/atom_blob_reader.h"
+#include "atom/browser/net/resolve_proxy_helper.h"
 #include "base/values.h"
 #include "content/public/browser/download_manager.h"
 #include "native_mate/handle.h"
@@ -39,8 +40,6 @@ namespace api {
 class Session : public mate::TrackableObject<Session>,
                 public content::DownloadManager::Observer {
  public:
-  using ResolveProxyCallback = base::Callback<void(std::string)>;
-
   enum class CacheAction {
     CLEAR,
     STATS,
@@ -63,12 +62,13 @@ class Session : public mate::TrackableObject<Session>,
                              v8::Local<v8::FunctionTemplate> prototype);
 
   // Methods.
-  void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
+  void ResolveProxy(const GURL& url,
+                    const ResolveProxyHelper::ResolveProxyCallback& callback);
   template <CacheAction action>
   void DoCacheAction(const net::CompletionCallback& callback);
   void ClearStorageData(mate::Arguments* args);
   void FlushStorageData();
-  void SetProxy(const net::ProxyConfig& config, const base::Closure& callback);
+  void SetProxy(const mate::Dictionary& options, const base::Closure& callback);
   void SetDownloadPath(const base::FilePath& path);
   void EnableNetworkEmulation(const mate::Dictionary& options);
   void DisableNetworkEmulation();
@@ -90,6 +90,7 @@ class Session : public mate::TrackableObject<Session>,
   v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
   v8::Local<v8::Value> Protocol(v8::Isolate* isolate);
   v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
+  v8::Local<v8::Value> NetLog(v8::Isolate* isolate);
 
  protected:
   Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
@@ -104,6 +105,7 @@ class Session : public mate::TrackableObject<Session>,
   v8::Global<v8::Value> cookies_;
   v8::Global<v8::Value> protocol_;
   v8::Global<v8::Value> web_request_;
+  v8::Global<v8::Value> net_log_;
 
   // The X-DevTools-Emulate-Network-Conditions-Client-Id.
   std::string devtools_network_emulation_client_id_;
diff --git a/atom/browser/api/atom_api_web_request.cc b/atom/browser/api/atom_api_web_request.cc
index 6901955d96fa..2dc48a4c0333 100644
--- a/atom/browser/api/atom_api_web_request.cc
+++ b/atom/browser/api/atom_api_web_request.cc
@@ -43,7 +43,7 @@ namespace {
 
 template <typename Method, typename Event, typename Listener>
 void CallNetworkDelegateMethod(
-    brightray::URLRequestContextGetter* url_request_context_getter,
+    URLRequestContextGetter* url_request_context_getter,
     Method method,
     Event type,
     URLPatterns patterns,
@@ -95,8 +95,8 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
     return;
   }
 
-  brightray::URLRequestContextGetter* url_request_context_getter =
-      browser_context_->GetRequestContext();
+  auto* url_request_context_getter = static_cast<URLRequestContextGetter*>(
+      browser_context_->GetRequestContext());
   if (!url_request_context_getter)
     return;
   BrowserThread::PostTask(
diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc
index b2caa095d378..d5f6e428a3c5 100644
--- a/atom/browser/atom_browser_client.cc
+++ b/atom/browser/atom_browser_client.cc
@@ -21,6 +21,7 @@
 #include "atom/browser/atom_resource_dispatcher_host_delegate.h"
 #include "atom/browser/atom_speech_recognition_manager_delegate.h"
 #include "atom/browser/child_web_contents_tracker.h"
+#include "atom/browser/io_thread.h"
 #include "atom/browser/native_window.h"
 #include "atom/browser/session_preferences.h"
 #include "atom/browser/web_contents_permission_helper.h"
@@ -32,6 +33,7 @@
 #include "base/command_line.h"
 #include "base/environment.h"
 #include "base/files/file_util.h"
+#include "base/json/json_reader.h"
 #include "base/no_destructor.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
@@ -39,6 +41,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/printing/printing_message_filter.h"
 #include "chrome/browser/speech/tts_message_filter.h"
+#include "components/net_log/chrome_net_log.h"
 #include "content/public/browser/browser_ppapi_host.h"
 #include "content/public/browser/client_certificate_delegate.h"
 #include "content/public/browser/render_frame_host.h"
@@ -49,15 +52,19 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_paths.h"
 #include "content/public/common/content_switches.h"
+#include "content/public/common/service_names.mojom.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/web_preferences.h"
 #include "device/geolocation/public/cpp/location_provider.h"
 #include "electron/buildflags/buildflags.h"
+#include "electron/grit/electron_resources.h"
 #include "net/base/escape.h"
 #include "net/ssl/ssl_cert_request_info.h"
 #include "ppapi/host/ppapi_host.h"
 #include "services/network/public/cpp/resource_request_body.h"
+#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
 #include "v8/include/v8.h"
 
 #if defined(USE_NSS_CERTS)
@@ -518,10 +525,44 @@ AtomBrowserClient::OverrideSystemLocationProvider() {
 #endif
 }
 
+network::mojom::NetworkContextPtr AtomBrowserClient::CreateNetworkContext(
+    content::BrowserContext* browser_context,
+    bool /*in_memory*/,
+    const base::FilePath& /*relative_partition_path*/) {
+  if (!browser_context)
+    return nullptr;
+  return static_cast<AtomBrowserContext*>(browser_context)->GetNetworkContext();
+}
+
+void AtomBrowserClient::RegisterOutOfProcessServices(
+    OutOfProcessServiceMap* services) {
+  (*services)[proxy_resolver::mojom::kProxyResolverServiceName] =
+      base::ASCIIToUTF16("V8 Proxy Resolver");
+}
+
+std::unique_ptr<base::Value> AtomBrowserClient::GetServiceManifestOverlay(
+    base::StringPiece name) {
+  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+  int id = -1;
+  if (name == content::mojom::kBrowserServiceName)
+    id = IDR_ELECTRON_CONTENT_BROWSER_MANIFEST_OVERLAY;
+  else if (name == content::mojom::kPackagedServicesServiceName)
+    id = IDR_ELECTRON_CONTENT_PACKAGED_SERVICES_MANIFEST_OVERLAY;
+
+  if (id == -1)
+    return nullptr;
+
+  base::StringPiece manifest_contents = rb.GetRawDataResource(id);
+  return base::JSONReader::Read(manifest_contents);
+}
+
+net::NetLog* AtomBrowserClient::GetNetLog() {
+  return AtomBrowserMainParts::Get()->net_log();
+}
+
 brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
-    const content::MainFunctionParams&) {
-  v8::V8::Initialize();  // Init V8 before creating main parts.
-  return new AtomBrowserMainParts;
+    const content::MainFunctionParams& params) {
+  return new AtomBrowserMainParts(params);
 }
 
 void AtomBrowserClient::WebNotificationAllowed(
diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h
index a41a6885b900..b22cbc7bf932 100644
--- a/atom/browser/atom_browser_client.h
+++ b/atom/browser/atom_browser_client.h
@@ -112,6 +112,14 @@ class AtomBrowserClient : public brightray::BrowserClient,
       content::ResourceContext* resource_context) override;
   std::unique_ptr<device::LocationProvider> OverrideSystemLocationProvider()
       override;
+  network::mojom::NetworkContextPtr CreateNetworkContext(
+      content::BrowserContext* browser_context,
+      bool in_memory,
+      const base::FilePath& relative_partition_path) override;
+  void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override;
+  std::unique_ptr<base::Value> GetServiceManifestOverlay(
+      base::StringPiece name) override;
+  net::NetLog* GetNetLog() override;
 
   // brightray::BrowserClient:
   brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc
index 250862cddf33..8528d2bbf183 100644
--- a/atom/browser/atom_browser_context.cc
+++ b/atom/browser/atom_browser_context.cc
@@ -4,12 +4,16 @@
 
 #include "atom/browser/atom_browser_context.h"
 
+#include <utility>
+
 #include "atom/browser/atom_blob_reader.h"
 #include "atom/browser/atom_browser_main_parts.h"
 #include "atom/browser/atom_download_manager_delegate.h"
 #include "atom/browser/atom_permission_manager.h"
 #include "atom/browser/browser.h"
-#include "atom/browser/request_context_delegate.h"
+#include "atom/browser/cookie_change_notifier.h"
+#include "atom/browser/net/resolve_proxy_helper.h"
+#include "atom/browser/pref_store_delegate.h"
 #include "atom/browser/special_storage_policy.h"
 #include "atom/browser/web_view_manager.h"
 #include "atom/common/atom_version.h"
@@ -18,12 +22,29 @@
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/path_service.h"
+#include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/threading/thread_restrictions.h"
+#include "brightray/browser/brightray_paths.h"
+#include "brightray/browser/inspectable_web_contents_impl.h"
+#include "brightray/browser/zoom_level_delegate.h"
+#include "brightray/common/application_info.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/pref_names.h"
+#include "components/prefs/json_pref_store.h"
 #include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+#include "components/prefs/pref_service_factory.h"
+#include "components/prefs/value_map_pref_store.h"
+#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
+#include "components/proxy_config/proxy_config_pref_names.h"
 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
+#include "content/public/browser/storage_partition.h"
 #include "content/public/common/user_agent.h"
+#include "net/base/escape.h"
+
+using content::BrowserThread;
 
 namespace atom {
 
@@ -37,14 +58,25 @@ std::string RemoveWhitespace(const std::string& str) {
     return str;
 }
 
+// Convert string to lower case and escape it.
+std::string MakePartitionName(const std::string& input) {
+  return net::EscapePath(base::ToLowerASCII(input));
+}
+
 }  // namespace
 
+// static
+AtomBrowserContext::BrowserContextMap AtomBrowserContext::browser_context_map_;
+
 AtomBrowserContext::AtomBrowserContext(const std::string& partition,
                                        bool in_memory,
                                        const base::DictionaryValue& options)
-    : brightray::BrowserContext(partition, in_memory),
-      url_request_context_getter_(nullptr),
-      storage_policy_(new SpecialStoragePolicy) {
+    : base::RefCountedDeleteOnSequence<AtomBrowserContext>(
+          base::SequencedTaskRunnerHandle::Get()),
+      in_memory_pref_store_(nullptr),
+      storage_policy_(new SpecialStoragePolicy),
+      in_memory_(in_memory),
+      weak_factory_(this) {
   // Construct user agent string.
   Browser* browser = Browser::Get();
   std::string name = RemoveWhitespace(browser->GetName());
@@ -61,23 +93,131 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
 
   // Read options.
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  bool use_cache = !command_line->HasSwitch(switches::kDisableHttpCache);
-  options.GetBoolean("cache", &use_cache);
+  use_cache_ = !command_line->HasSwitch(switches::kDisableHttpCache);
+  options.GetBoolean("cache", &use_cache_);
 
-  request_context_delegate_.reset(new RequestContextDelegate(use_cache));
+  base::StringToInt(command_line->GetSwitchValueASCII(switches::kDiskCacheSize),
+                    &max_cache_size_);
 
-  // Initialize Pref Registry in brightray.
+  if (!base::PathService::Get(brightray::DIR_USER_DATA, &path_)) {
+    base::PathService::Get(brightray::DIR_APP_DATA, &path_);
+    path_ = path_.Append(
+        base::FilePath::FromUTF8Unsafe(brightray::GetApplicationName()));
+    base::PathService::Override(brightray::DIR_USER_DATA, path_);
+  }
+
+  if (!in_memory && !partition.empty())
+    path_ = path_.Append(FILE_PATH_LITERAL("Partitions"))
+                .Append(base::FilePath::FromUTF8Unsafe(
+                    MakePartitionName(partition)));
+
+  content::BrowserContext::Initialize(this, path_);
+
+  // Initialize Pref Registry.
   InitPrefs();
+
+  proxy_config_monitor_ = std::make_unique<ProxyConfigMonitor>(prefs_.get());
+  io_handle_ = new URLRequestContextGetter::Handle(weak_factory_.GetWeakPtr());
+  cookie_change_notifier_ = std::make_unique<CookieChangeNotifier>(this);
 }
 
 AtomBrowserContext::~AtomBrowserContext() {
-  url_request_context_getter_->set_delegate(nullptr);
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  NotifyWillBeDestroyed(this);
+  ShutdownStoragePartitions();
+  io_handle_->ShutdownOnUIThread();
+}
+
+void AtomBrowserContext::InitPrefs() {
+  auto prefs_path = GetPath().Append(FILE_PATH_LITERAL("Preferences"));
+  base::ThreadRestrictions::ScopedAllowIO allow_io;
+  PrefServiceFactory prefs_factory;
+  scoped_refptr<JsonPrefStore> pref_store =
+      base::MakeRefCounted<JsonPrefStore>(prefs_path);
+  pref_store->ReadPrefs();  // Synchronous.
+  prefs_factory.set_user_prefs(pref_store);
+
+  auto registry = WrapRefCounted(new PrefRegistrySimple);
+
+  registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory,
+                                 base::FilePath());
+  base::FilePath download_dir;
+  base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &download_dir);
+  registry->RegisterFilePathPref(prefs::kDownloadDefaultDirectory,
+                                 download_dir);
+  registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
+  brightray::InspectableWebContentsImpl::RegisterPrefs(registry.get());
+  brightray::MediaDeviceIDSalt::RegisterPrefs(registry.get());
+  brightray::ZoomLevelDelegate::RegisterPrefs(registry.get());
+  PrefProxyConfigTrackerImpl::RegisterPrefs(registry.get());
+
+  prefs_ = prefs_factory.Create(
+      registry.get(),
+      std::make_unique<PrefStoreDelegate>(weak_factory_.GetWeakPtr()));
+  prefs_->UpdateCommandLinePrefStore(new ValueMapPrefStore);
 }
 
 void AtomBrowserContext::SetUserAgent(const std::string& user_agent) {
   user_agent_ = user_agent;
 }
 
+net::URLRequestContextGetter* AtomBrowserContext::CreateRequestContext(
+    content::ProtocolHandlerMap* protocol_handlers,
+    content::URLRequestInterceptorScopedVector protocol_interceptors) {
+  return io_handle_
+      ->CreateMainRequestContextGetter(protocol_handlers,
+                                       std::move(protocol_interceptors))
+      .get();
+}
+
+net::URLRequestContextGetter* AtomBrowserContext::CreateMediaRequestContext() {
+  return io_handle_->GetMainRequestContextGetter().get();
+}
+
+net::URLRequestContextGetter* AtomBrowserContext::GetRequestContext() {
+  return GetDefaultStoragePartition(this)->GetURLRequestContext();
+}
+
+network::mojom::NetworkContextPtr AtomBrowserContext::GetNetworkContext() {
+  return io_handle_->GetNetworkContext();
+}
+
+base::FilePath AtomBrowserContext::GetPath() const {
+  return path_;
+}
+
+bool AtomBrowserContext::IsOffTheRecord() const {
+  return in_memory_;
+}
+
+bool AtomBrowserContext::CanUseHttpCache() const {
+  return use_cache_;
+}
+
+int AtomBrowserContext::GetMaxCacheSize() const {
+  return max_cache_size_;
+}
+
+content::ResourceContext* AtomBrowserContext::GetResourceContext() {
+  return io_handle_->GetResourceContext();
+}
+
+std::string AtomBrowserContext::GetMediaDeviceIDSalt() {
+  if (!media_device_id_salt_.get())
+    media_device_id_salt_.reset(new brightray::MediaDeviceIDSalt(prefs_.get()));
+  return media_device_id_salt_->GetSalt();
+}
+
+std::unique_ptr<content::ZoomLevelDelegate>
+AtomBrowserContext::CreateZoomLevelDelegate(
+    const base::FilePath& partition_path) {
+  if (!IsOffTheRecord()) {
+    return std::make_unique<brightray::ZoomLevelDelegate>(prefs(),
+                                                          partition_path);
+  }
+  return std::unique_ptr<content::ZoomLevelDelegate>();
+}
+
 content::DownloadManagerDelegate*
 AtomBrowserContext::GetDownloadManagerDelegate() {
   if (!download_manager_delegate_.get()) {
@@ -104,26 +244,10 @@ storage::SpecialStoragePolicy* AtomBrowserContext::GetSpecialStoragePolicy() {
   return storage_policy_.get();
 }
 
-void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
-  pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory,
-                                      base::FilePath());
-  base::FilePath download_dir;
-  base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &download_dir);
-  pref_registry->RegisterFilePathPref(prefs::kDownloadDefaultDirectory,
-                                      download_dir);
-  pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
-}
-
 std::string AtomBrowserContext::GetUserAgent() const {
   return user_agent_;
 }
 
-void AtomBrowserContext::OnMainRequestContextCreated(
-    brightray::URLRequestContextGetter* getter) {
-  getter->set_delegate(request_context_delegate_.get());
-  url_request_context_getter_ = getter;
-}
-
 AtomBlobReader* AtomBrowserContext::GetBlobReader() {
   if (!blob_reader_.get()) {
     content::ChromeBlobStorageContext* blob_context =
@@ -133,16 +257,67 @@ AtomBlobReader* AtomBrowserContext::GetBlobReader() {
   return blob_reader_.get();
 }
 
+content::PushMessagingService* AtomBrowserContext::GetPushMessagingService() {
+  return nullptr;
+}
+
+content::SSLHostStateDelegate* AtomBrowserContext::GetSSLHostStateDelegate() {
+  return nullptr;
+}
+
+content::BackgroundFetchDelegate*
+AtomBrowserContext::GetBackgroundFetchDelegate() {
+  return nullptr;
+}
+
+content::BackgroundSyncController*
+AtomBrowserContext::GetBackgroundSyncController() {
+  return nullptr;
+}
+
+content::BrowsingDataRemoverDelegate*
+AtomBrowserContext::GetBrowsingDataRemoverDelegate() {
+  return nullptr;
+}
+
+net::URLRequestContextGetter*
+AtomBrowserContext::CreateRequestContextForStoragePartition(
+    const base::FilePath& partition_path,
+    bool in_memory,
+    content::ProtocolHandlerMap* protocol_handlers,
+    content::URLRequestInterceptorScopedVector request_interceptors) {
+  NOTREACHED();
+  return nullptr;
+}
+
+net::URLRequestContextGetter*
+AtomBrowserContext::CreateMediaRequestContextForStoragePartition(
+    const base::FilePath& partition_path,
+    bool in_memory) {
+  NOTREACHED();
+  return nullptr;
+}
+
+ResolveProxyHelper* AtomBrowserContext::GetResolveProxyHelper() {
+  if (!resolve_proxy_helper_) {
+    resolve_proxy_helper_ = base::MakeRefCounted<ResolveProxyHelper>(this);
+  }
+  return resolve_proxy_helper_.get();
+}
+
 // static
 scoped_refptr<AtomBrowserContext> AtomBrowserContext::From(
     const std::string& partition,
     bool in_memory,
     const base::DictionaryValue& options) {
-  auto browser_context = brightray::BrowserContext::Get(partition, in_memory);
+  PartitionKey key(partition, in_memory);
+  auto* browser_context = browser_context_map_[key].get();
   if (browser_context)
-    return static_cast<AtomBrowserContext*>(browser_context.get());
+    return scoped_refptr<AtomBrowserContext>(browser_context);
 
-  return new AtomBrowserContext(partition, in_memory, options);
+  auto* new_context = new AtomBrowserContext(partition, in_memory, options);
+  browser_context_map_[key] = new_context->GetWeakPtr();
+  return scoped_refptr<AtomBrowserContext>(new_context);
 }
 
 }  // namespace atom
diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h
index fd9e8830c679..c58377b78fd9 100644
--- a/atom/browser/atom_browser_context.h
+++ b/atom/browser/atom_browser_context.h
@@ -5,12 +5,21 @@
 #ifndef ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_
 #define ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_
 
+#include <map>
 #include <memory>
 #include <string>
 #include <vector>
 
-#include "base/memory/scoped_refptr.h"
-#include "brightray/browser/browser_context.h"
+#include "atom/browser/net/url_request_context_getter.h"
+#include "base/memory/ref_counted_delete_on_sequence.h"
+#include "base/memory/weak_ptr.h"
+#include "brightray/browser/media/media_device_id_salt.h"
+#include "chrome/browser/net/proxy_config_monitor.h"
+#include "content/public/browser/browser_context.h"
+
+class PrefRegistrySimple;
+class PrefService;
+class ValueMapPrefStore;
 
 namespace storage {
 class SpecialStoragePolicy;
@@ -19,13 +28,17 @@ class SpecialStoragePolicy;
 namespace atom {
 
 class AtomBlobReader;
+class AtomBrowserContext;
 class AtomDownloadManagerDelegate;
 class AtomPermissionManager;
-class RequestContextDelegate;
+class CookieChangeNotifier;
+class ResolveProxyHelper;
 class SpecialStoragePolicy;
 class WebViewManager;
 
-class AtomBrowserContext : public brightray::BrowserContext {
+class AtomBrowserContext
+    : public base::RefCountedDeleteOnSequence<AtomBrowserContext>,
+      public content::BrowserContext {
  public:
   // Get or create the BrowserContext according to its |partition| and
   // |in_memory|. The |options| will be passed to constructor when there is no
@@ -36,22 +49,60 @@ class AtomBrowserContext : public brightray::BrowserContext {
       const base::DictionaryValue& options = base::DictionaryValue());
 
   void SetUserAgent(const std::string& user_agent);
+  std::string GetUserAgent() const;
+  bool CanUseHttpCache() const;
+  int GetMaxCacheSize() const;
   AtomBlobReader* GetBlobReader();
+  network::mojom::NetworkContextPtr GetNetworkContext();
+  // Get the request context, if there is none, create it.
+  net::URLRequestContextGetter* GetRequestContext();
+  ResolveProxyHelper* GetResolveProxyHelper();
 
   // content::BrowserContext:
+  base::FilePath GetPath() const override;
+  bool IsOffTheRecord() const override;
+  content::ResourceContext* GetResourceContext() override;
+  std::unique_ptr<content::ZoomLevelDelegate> CreateZoomLevelDelegate(
+      const base::FilePath& partition_path) override;
+  content::PushMessagingService* GetPushMessagingService() override;
+  content::SSLHostStateDelegate* GetSSLHostStateDelegate() override;
+  content::BackgroundFetchDelegate* GetBackgroundFetchDelegate() override;
+  content::BackgroundSyncController* GetBackgroundSyncController() override;
+  content::BrowsingDataRemoverDelegate* GetBrowsingDataRemoverDelegate()
+      override;
+  net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
+      const base::FilePath& partition_path,
+      bool in_memory,
+      content::ProtocolHandlerMap* protocol_handlers,
+      content::URLRequestInterceptorScopedVector request_interceptors) override;
+  net::URLRequestContextGetter* CreateMediaRequestContextForStoragePartition(
+      const base::FilePath& partition_path,
+      bool in_memory) override;
+  std::string GetMediaDeviceIDSalt() override;
   content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
   content::BrowserPluginGuestManager* GetGuestManager() override;
   content::PermissionManager* GetPermissionManager() override;
   storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override;
+  net::URLRequestContextGetter* CreateRequestContext(
+      content::ProtocolHandlerMap* protocol_handlers,
+      content::URLRequestInterceptorScopedVector request_interceptors) override;
+  net::URLRequestContextGetter* CreateMediaRequestContext() override;
 
-  // brightray::BrowserContext:
-  void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
-  std::string GetUserAgent() const override;
-  void OnMainRequestContextCreated(
-      brightray::URLRequestContextGetter* getter) override;
-
-  RequestContextDelegate* GetRequestContextDelegate() const {
-    return request_context_delegate_.get();
+  CookieChangeNotifier* cookie_change_notifier() const {
+    return cookie_change_notifier_.get();
+  }
+  ProxyConfigMonitor* proxy_config_monitor() {
+    return proxy_config_monitor_.get();
+  }
+  PrefService* prefs() const { return prefs_.get(); }
+  void set_in_memory_pref_store(ValueMapPrefStore* pref_store) {
+    in_memory_pref_store_ = pref_store;
+  }
+  ValueMapPrefStore* in_memory_pref_store() const {
+    return in_memory_pref_store_;
+  }
+  base::WeakPtr<AtomBrowserContext> GetWeakPtr() {
+    return weak_factory_.GetWeakPtr();
   }
 
  protected:
@@ -61,15 +112,60 @@ class AtomBrowserContext : public brightray::BrowserContext {
   ~AtomBrowserContext() override;
 
  private:
-  brightray::URLRequestContextGetter* url_request_context_getter_;
+  friend class base::RefCountedDeleteOnSequence<AtomBrowserContext>;
+  friend class base::DeleteHelper<AtomBrowserContext>;
 
+  // Initialize pref registry.
+  void InitPrefs();
+
+  // partition_id => browser_context
+  struct PartitionKey {
+    std::string partition;
+    bool in_memory;
+
+    PartitionKey(const std::string& partition, bool in_memory)
+        : partition(partition), in_memory(in_memory) {}
+
+    bool operator<(const PartitionKey& other) const {
+      if (partition == other.partition)
+        return in_memory < other.in_memory;
+      return partition < other.partition;
+    }
+
+    bool operator==(const PartitionKey& other) const {
+      return (partition == other.partition) && (in_memory == other.in_memory);
+    }
+  };
+  using BrowserContextMap =
+      std::map<PartitionKey, base::WeakPtr<AtomBrowserContext>>;
+  static BrowserContextMap browser_context_map_;
+
+  // Self-destructing class responsible for creating URLRequestContextGetter
+  // on the UI thread and deletes itself on the IO thread.
+  URLRequestContextGetter::Handle* io_handle_;
+  ValueMapPrefStore* in_memory_pref_store_;
+
+  std::unique_ptr<CookieChangeNotifier> cookie_change_notifier_;
+  std::unique_ptr<PrefService> prefs_;
   std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
   std::unique_ptr<WebViewManager> guest_manager_;
   std::unique_ptr<AtomPermissionManager> permission_manager_;
-  scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
   std::unique_ptr<AtomBlobReader> blob_reader_;
-  std::unique_ptr<RequestContextDelegate> request_context_delegate_;
+  std::unique_ptr<brightray::MediaDeviceIDSalt> media_device_id_salt_;
+  scoped_refptr<ResolveProxyHelper> resolve_proxy_helper_;
+  scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
+
+  // Tracks the ProxyConfig to use, and passes any updates to a NetworkContext
+  // ProxyConfigClient.
+  std::unique_ptr<ProxyConfigMonitor> proxy_config_monitor_;
+
   std::string user_agent_;
+  base::FilePath path_;
+  bool in_memory_ = false;
+  bool use_cache_ = true;
+  int max_cache_size_ = 0;
+
+  base::WeakPtrFactory<AtomBrowserContext> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
 };
diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc
index e07ad049cec5..68658dd9839b 100644
--- a/atom/browser/atom_browser_main_parts.cc
+++ b/atom/browser/atom_browser_main_parts.cc
@@ -12,6 +12,7 @@
 #include "atom/browser/atom_browser_context.h"
 #include "atom/browser/bridge_task_runner.h"
 #include "atom/browser/browser.h"
+#include "atom/browser/io_thread.h"
 #include "atom/browser/javascript_environment.h"
 #include "atom/browser/node_debugger.h"
 #include "atom/common/api/atom_bindings.h"
@@ -20,11 +21,15 @@
 #include "base/command_line.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/net/chrome_net_log_helper.h"
+#include "components/net_log/chrome_net_log.h"
+#include "components/net_log/net_export_file_writer.h"
 #include "content/public/browser/child_process_security_policy.h"
 #include "content/public/common/result_codes.h"
 #include "content/public/common/service_manager_connection.h"
 #include "electron/buildflags/buildflags.h"
 #include "services/device/public/mojom/constants.mojom.h"
+#include "services/network/public/cpp/network_switches.h"
 #include "services/service_manager/public/cpp/connector.h"
 #include "ui/base/idle/idle.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -61,12 +66,14 @@ void Erase(T* container, typename T::iterator iter) {
 // static
 AtomBrowserMainParts* AtomBrowserMainParts::self_ = nullptr;
 
-AtomBrowserMainParts::AtomBrowserMainParts()
+AtomBrowserMainParts::AtomBrowserMainParts(
+    const content::MainFunctionParams& params)
     : fake_browser_process_(new BrowserProcess),
       browser_(new Browser),
       node_bindings_(NodeBindings::Create(NodeBindings::BROWSER)),
       atom_bindings_(new AtomBindings(uv_default_loop())),
-      gc_timer_(true, true) {
+      gc_timer_(true, true),
+      main_function_params_(params) {
   DCHECK(!self_) << "Cannot have two AtomBrowserMainParts";
   self_ = this;
   // Register extension scheme as web safe scheme.
@@ -178,9 +185,32 @@ int AtomBrowserMainParts::PreCreateThreads() {
   ui::InitIdleMonitor();
 #endif
 
+  net_log_ = std::make_unique<net_log::ChromeNetLog>();
+  auto& command_line = main_function_params_.command_line;
+  // start net log trace if --log-net-log is passed in the command line.
+  if (command_line.HasSwitch(network::switches::kLogNetLog)) {
+    base::FilePath log_file =
+        command_line.GetSwitchValuePath(network::switches::kLogNetLog);
+    if (!log_file.empty()) {
+      net_log_->StartWritingToFile(
+          log_file, GetNetCaptureModeFromCommandLine(command_line),
+          command_line.GetCommandLineString(), std::string());
+    }
+  }
+  // Initialize net log file exporter.
+  net_log_->net_export_file_writer()->Initialize();
+
+  // Manage global state of net and other IO thread related.
+  io_thread_ = std::make_unique<IOThread>(net_log_.get());
+
   return result;
 }
 
+void AtomBrowserMainParts::PostDestroyThreads() {
+  brightray::BrowserMainParts::PostDestroyThreads();
+  io_thread_.reset();
+}
+
 void AtomBrowserMainParts::ToolkitInitialized() {
   brightray::BrowserMainParts::ToolkitInitialized();
 #if defined(OS_MACOSX)
diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h
index 517afd25d841..0450ab0474b5 100644
--- a/atom/browser/atom_browser_main_parts.h
+++ b/atom/browser/atom_browser_main_parts.h
@@ -13,6 +13,7 @@
 #include "base/timer/timer.h"
 #include "brightray/browser/browser_main_parts.h"
 #include "content/public/browser/browser_context.h"
+#include "content/public/common/main_function_params.h"
 #include "services/device/public/mojom/geolocation_control.mojom.h"
 
 class BrowserProcess;
@@ -23,10 +24,15 @@ class ViewsDelegate;
 }
 #endif
 
+namespace net_log {
+class ChromeNetLog;
+}
+
 namespace atom {
 
 class AtomBindings;
 class Browser;
+class IOThread;
 class JavascriptEnvironment;
 class NodeBindings;
 class NodeDebugger;
@@ -39,7 +45,7 @@ class ViewsDelegateMac;
 
 class AtomBrowserMainParts : public brightray::BrowserMainParts {
  public:
-  AtomBrowserMainParts();
+  explicit AtomBrowserMainParts(const content::MainFunctionParams& params);
   ~AtomBrowserMainParts() override;
 
   static AtomBrowserMainParts* Get();
@@ -60,6 +66,8 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
   device::mojom::GeolocationControl* GetGeolocationControl();
 
   Browser* browser() { return browser_.get(); }
+  IOThread* io_thread() const { return io_thread_.get(); }
+  net_log::ChromeNetLog* net_log() { return net_log_.get(); }
 
  protected:
   // content::BrowserMainParts:
@@ -74,6 +82,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
 #if defined(OS_MACOSX)
   void PreMainMessageLoopStart() override;
 #endif
+  void PostDestroyThreads() override;
 
  private:
 #if defined(OS_POSIX)
@@ -108,6 +117,8 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
   std::unique_ptr<AtomBindings> atom_bindings_;
   std::unique_ptr<NodeEnvironment> node_env_;
   std::unique_ptr<NodeDebugger> node_debugger_;
+  std::unique_ptr<IOThread> io_thread_;
+  std::unique_ptr<net_log::ChromeNetLog> net_log_;
 
   base::Timer gc_timer_;
 
@@ -116,6 +127,8 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
 
   device::mojom::GeolocationControlPtr geolocation_control_;
 
+  const content::MainFunctionParams main_function_params_;
+
   static AtomBrowserMainParts* self_;
 
   DISALLOW_COPY_AND_ASSIGN(AtomBrowserMainParts);
diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc
index 86a8b1fb6583..b4eea58dc4d6 100644
--- a/atom/browser/common_web_contents_delegate.cc
+++ b/atom/browser/common_web_contents_delegate.cc
@@ -177,8 +177,8 @@ void CommonWebContentsDelegate::InitWithWebContents(
       !web_preferences || web_preferences->IsEnabled(options::kOffscreen);
 
   // Create InspectableWebContents.
-  web_contents_.reset(
-      brightray::InspectableWebContents::Create(web_contents, is_guest));
+  web_contents_.reset(brightray::InspectableWebContents::Create(
+      web_contents, browser_context->prefs(), is_guest));
   web_contents_->SetDelegate(this);
 }
 
diff --git a/atom/browser/cookie_change_notifier.cc b/atom/browser/cookie_change_notifier.cc
new file mode 100644
index 000000000000..a0f99d2779d5
--- /dev/null
+++ b/atom/browser/cookie_change_notifier.cc
@@ -0,0 +1,72 @@
+// Copyright (c) 2018 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include "atom/browser/cookie_change_notifier.h"
+
+#include <utility>
+
+#include "atom/browser/atom_browser_context.h"
+#include "atom/browser/net/cookie_details.h"
+#include "base/bind.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/storage_partition.h"
+#include "net/cookies/canonical_cookie.h"
+
+using content::BrowserThread;
+
+namespace atom {
+
+CookieChangeNotifier::CookieChangeNotifier(AtomBrowserContext* browser_context)
+    : browser_context_(browser_context), binding_(this) {
+  StartListening();
+}
+
+CookieChangeNotifier::~CookieChangeNotifier() = default;
+
+std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
+CookieChangeNotifier::RegisterCookieChangeCallback(
+    const base::Callback<void(const CookieDetails*)>& cb) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  return cookie_change_sub_list_.Add(cb);
+}
+
+void CookieChangeNotifier::StartListening() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  DCHECK(!binding_.is_bound());
+
+  network::mojom::CookieManager* cookie_manager =
+      content::BrowserContext::GetDefaultStoragePartition(browser_context_)
+          ->GetCookieManagerForBrowserProcess();
+  // Cookie manager should be created whenever network context is created,
+  // if this fails then there is something wrong with our context creation
+  // cycle.
+  CHECK(cookie_manager);
+
+  network::mojom::CookieChangeListenerPtr listener_ptr;
+  binding_.Bind(mojo::MakeRequest(&listener_ptr));
+  binding_.set_connection_error_handler(base::BindOnce(
+      &CookieChangeNotifier::OnConnectionError, base::Unretained(this)));
+
+  cookie_manager->AddGlobalChangeListener(std::move(listener_ptr));
+}
+
+void CookieChangeNotifier::OnConnectionError() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  binding_.Close();
+  StartListening();
+}
+
+void CookieChangeNotifier::OnCookieChange(
+    const net::CanonicalCookie& cookie,
+    network::mojom::CookieChangeCause cause) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  CookieDetails cookie_details(
+      &cookie, cause != network::mojom::CookieChangeCause::INSERTED, cause);
+  cookie_change_sub_list_.Notify(&cookie_details);
+}
+
+}  // namespace atom
diff --git a/atom/browser/cookie_change_notifier.h b/atom/browser/cookie_change_notifier.h
new file mode 100644
index 000000000000..49a0ea50bf97
--- /dev/null
+++ b/atom/browser/cookie_change_notifier.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2018 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#ifndef ATOM_BROWSER_COOKIE_CHANGE_NOTIFIER_H_
+#define ATOM_BROWSER_COOKIE_CHANGE_NOTIFIER_H_
+
+#include <memory>
+
+#include "base/callback_list.h"
+#include "base/macros.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "services/network/public/mojom/cookie_manager.mojom.h"
+
+namespace atom {
+
+class AtomBrowserContext;
+struct CookieDetails;
+
+// Sends cookie-change notifications on the UI thread.
+class CookieChangeNotifier : public network::mojom::CookieChangeListener {
+ public:
+  explicit CookieChangeNotifier(AtomBrowserContext* browser_context);
+  ~CookieChangeNotifier() override;
+
+  // Register callbacks that needs to notified on any cookie store changes.
+  std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
+  RegisterCookieChangeCallback(
+      const base::Callback<void(const CookieDetails*)>& cb);
+
+ private:
+  void StartListening();
+  void OnConnectionError();
+
+  // network::mojom::CookieChangeListener implementation.
+  void OnCookieChange(const net::CanonicalCookie& cookie,
+                      network::mojom::CookieChangeCause cause) override;
+
+  AtomBrowserContext* browser_context_;
+  base::CallbackList<void(const CookieDetails*)> cookie_change_sub_list_;
+  mojo::Binding<network::mojom::CookieChangeListener> binding_;
+
+  DISALLOW_COPY_AND_ASSIGN(CookieChangeNotifier);
+};
+
+}  // namespace atom
+
+#endif  // ATOM_BROWSER_COOKIE_CHANGE_NOTIFIER_H_
diff --git a/atom/browser/io_thread.cc b/atom/browser/io_thread.cc
new file mode 100644
index 000000000000..15a60e3a2dc3
--- /dev/null
+++ b/atom/browser/io_thread.cc
@@ -0,0 +1,80 @@
+// Copyright (c) 2017 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include "atom/browser/io_thread.h"
+
+#include "components/net_log/chrome_net_log.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_builder.h"
+#include "net/url_request/url_request_context_getter.h"
+
+#if defined(USE_NSS_CERTS)
+#include "net/cert_net/nss_ocsp.h"
+#endif
+
+#if defined(OS_LINUX) || defined(OS_MACOSX)
+#include "net/cert/cert_net_fetcher.h"
+#include "net/cert_net/cert_net_fetcher_impl.h"
+#endif
+
+using content::BrowserThread;
+
+namespace atom {
+
+IOThread::IOThread(net_log::ChromeNetLog* net_log) : net_log_(net_log) {
+  BrowserThread::SetIOThreadDelegate(this);
+}
+
+IOThread::~IOThread() {
+  BrowserThread::SetIOThreadDelegate(nullptr);
+}
+
+void IOThread::Init() {
+  net::URLRequestContextBuilder builder;
+  // TODO(deepak1556): We need to respoect user proxy configurations,
+  // the following initialization has to happen before any request
+  // contexts are utilized by the io thread, so that proper cert validation
+  // take place, solutions:
+  // 1) Use the request context from default partition, but since
+  //    an app can completely run on a custom session without ever creating
+  //    the default session, we will have to force create the default session
+  //    in those scenarios.
+  // 2) Add a new api on app module that sets the proxy configuration
+  //    for the global requests, like the cert fetchers below and
+  //    geolocation requests.
+  // 3) There is also ongoing work in upstream which will eventually allow
+  //    localizing these global fetchers to their own URLRequestContexts.
+  builder.set_proxy_resolution_service(
+      net::ProxyResolutionService::CreateDirect());
+  url_request_context_ = builder.Build();
+  url_request_context_getter_ = new net::TrivialURLRequestContextGetter(
+      url_request_context_.get(), base::ThreadTaskRunnerHandle::Get());
+
+#if defined(USE_NSS_CERTS)
+  net::SetURLRequestContextForNSSHttpIO(url_request_context_.get());
+#endif
+#if defined(OS_LINUX) || defined(OS_MACOSX)
+  net::SetGlobalCertNetFetcher(
+      net::CreateCertNetFetcher(url_request_context_.get()));
+#endif
+}
+
+void IOThread::CleanUp() {
+#if defined(USE_NSS_CERTS)
+  net::SetURLRequestContextForNSSHttpIO(nullptr);
+#endif
+#if defined(OS_LINUX) || defined(OS_MACOSX)
+  net::ShutdownGlobalCertNetFetcher();
+#endif
+  // Explicitly release before the IO thread gets destroyed.
+  url_request_context_.reset();
+  url_request_context_getter_ = nullptr;
+
+  if (net_log_)
+    net_log_->ShutDownBeforeTaskScheduler();
+}
+
+}  // namespace atom
diff --git a/brightray/browser/io_thread.h b/atom/browser/io_thread.h
similarity index 55%
rename from brightray/browser/io_thread.h
rename to atom/browser/io_thread.h
index b7ddae0eb7e8..4e1027e4ca8e 100644
--- a/brightray/browser/io_thread.h
+++ b/atom/browser/io_thread.h
@@ -2,12 +2,13 @@
 // Use of this source code is governed by the MIT license that can be
 // found in the LICENSE file.
 
-#ifndef BRIGHTRAY_BROWSER_IO_THREAD_H_
-#define BRIGHTRAY_BROWSER_IO_THREAD_H_
+#ifndef ATOM_BROWSER_IO_THREAD_H_
+#define ATOM_BROWSER_IO_THREAD_H_
 
 #include <memory>
 
 #include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
 #include "content/public/browser/browser_thread_delegate.h"
 
 namespace net {
@@ -15,15 +16,19 @@ class URLRequestContext;
 class URLRequestContextGetter;
 }  // namespace net
 
-namespace brightray {
+namespace net_log {
+class ChromeNetLog;
+}
+
+namespace atom {
 
 class IOThread : public content::BrowserThreadDelegate {
  public:
-  IOThread();
+  explicit IOThread(net_log::ChromeNetLog* net_log);
   ~IOThread() override;
 
   net::URLRequestContextGetter* GetRequestContext() {
-    return url_request_context_getter_;
+    return url_request_context_getter_.get();
   }
 
  protected:
@@ -32,12 +37,15 @@ class IOThread : public content::BrowserThreadDelegate {
   void CleanUp() override;
 
  private:
+  // The NetLog is owned by the browser process, to allow logging from other
+  // threads during shutdown, but is used most frequently on the IOThread.
+  net_log::ChromeNetLog* net_log_;
   std::unique_ptr<net::URLRequestContext> url_request_context_;
-  net::URLRequestContextGetter* url_request_context_getter_;
+  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
 
   DISALLOW_COPY_AND_ASSIGN(IOThread);
 };
 
-}  // namespace brightray
+}  // namespace atom
 
-#endif  // BRIGHTRAY_BROWSER_IO_THREAD_H_
+#endif  // ATOM_BROWSER_IO_THREAD_H_
diff --git a/atom/browser/net/atom_url_request.cc b/atom/browser/net/atom_url_request.cc
index 3cab12e6d582..6ff799df91b8 100644
--- a/atom/browser/net/atom_url_request.cc
+++ b/atom/browser/net/atom_url_request.cc
@@ -73,7 +73,7 @@ scoped_refptr<AtomURLRequest> AtomURLRequest::Create(
   if (!browser_context || url.empty() || !delegate) {
     return nullptr;
   }
-  scoped_refptr<brightray::URLRequestContextGetter> request_context_getter(
+  scoped_refptr<net::URLRequestContextGetter> request_context_getter(
       browser_context->GetRequestContext());
   DCHECK(request_context_getter);
   scoped_refptr<AtomURLRequest> atom_url_request(new AtomURLRequest(delegate));
diff --git a/atom/browser/net/atom_url_request_job_factory.cc b/atom/browser/net/atom_url_request_job_factory.cc
index 7047f7a6f7f8..fd4f3a8377f0 100644
--- a/atom/browser/net/atom_url_request_job_factory.cc
+++ b/atom/browser/net/atom_url_request_job_factory.cc
@@ -5,6 +5,8 @@
 
 #include "atom/browser/net/atom_url_request_job_factory.h"
 
+#include <utility>
+
 #include "base/memory/ptr_util.h"
 #include "base/stl_util.h"
 #include "content/public/browser/browser_thread.h"
@@ -33,6 +35,11 @@ AtomURLRequestJobFactory::~AtomURLRequestJobFactory() {
   Clear();
 }
 
+void AtomURLRequestJobFactory::Chain(
+    std::unique_ptr<net::URLRequestJobFactory> job_factory) {
+  job_factory_ = std::move(job_factory);
+}
+
 bool AtomURLRequestJobFactory::SetProtocolHandler(
     const std::string& scheme,
     std::unique_ptr<ProtocolHandler> protocol_handler) {
@@ -73,16 +80,6 @@ bool AtomURLRequestJobFactory::UninterceptProtocol(const std::string& scheme) {
   return true;
 }
 
-ProtocolHandler* AtomURLRequestJobFactory::GetProtocolHandler(
-    const std::string& scheme) const {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  auto it = protocol_handler_map_.find(scheme);
-  if (it == protocol_handler_map_.end())
-    return nullptr;
-  return it->second;
-}
-
 bool AtomURLRequestJobFactory::HasProtocolHandler(
     const std::string& scheme) const {
   return base::ContainsKey(protocol_handler_map_, scheme);
@@ -101,11 +98,18 @@ net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
     net::NetworkDelegate* network_delegate) const {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
+  auto* job = job_factory_->MaybeCreateJobWithProtocolHandler(scheme, request,
+                                                              network_delegate);
+  if (job)
+    return job;
+
   auto it = protocol_handler_map_.find(scheme);
   if (it == protocol_handler_map_.end())
     return nullptr;
+
   if (request->GetUserData(DisableProtocolInterceptFlagKey()))
     return nullptr;
+
   return it->second->MaybeCreateJob(request, network_delegate);
 }
 
@@ -113,13 +117,14 @@ net::URLRequestJob* AtomURLRequestJobFactory::MaybeInterceptRedirect(
     net::URLRequest* request,
     net::NetworkDelegate* network_delegate,
     const GURL& location) const {
-  return nullptr;
+  return job_factory_->MaybeInterceptRedirect(request, network_delegate,
+                                              location);
 }
 
 net::URLRequestJob* AtomURLRequestJobFactory::MaybeInterceptResponse(
     net::URLRequest* request,
     net::NetworkDelegate* network_delegate) const {
-  return nullptr;
+  return job_factory_->MaybeInterceptResponse(request, network_delegate);
 }
 
 bool AtomURLRequestJobFactory::IsHandledProtocol(
diff --git a/atom/browser/net/atom_url_request_job_factory.h b/atom/browser/net/atom_url_request_job_factory.h
index c0e26568fdea..fe965e237be0 100644
--- a/atom/browser/net/atom_url_request_job_factory.h
+++ b/atom/browser/net/atom_url_request_job_factory.h
@@ -23,6 +23,9 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
   AtomURLRequestJobFactory();
   ~AtomURLRequestJobFactory() override;
 
+  // Requests are forwarded to the chained job factory first.
+  void Chain(std::unique_ptr<net::URLRequestJobFactory> job_factory);
+
   // Sets the ProtocolHandler for a scheme. Returns true on success, false on
   // failure (a ProtocolHandler already exists for |scheme|). On success,
   // URLRequestJobFactory takes ownership of |protocol_handler|.
@@ -34,9 +37,6 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
                          std::unique_ptr<ProtocolHandler> protocol_handler);
   bool UninterceptProtocol(const std::string& scheme);
 
-  // Returns the protocol handler registered with scheme.
-  ProtocolHandler* GetProtocolHandler(const std::string& scheme) const;
-
   // Whether the protocol handler is registered by the job factory.
   bool HasProtocolHandler(const std::string& scheme) const;
 
@@ -69,6 +69,8 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory {
   // Can only be accessed in IO thread.
   OriginalProtocolsMap original_protocols_;
 
+  std::unique_ptr<net::URLRequestJobFactory> job_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(AtomURLRequestJobFactory);
 };
 
diff --git a/atom/browser/net/cookie_details.h b/atom/browser/net/cookie_details.h
index 9e361f199c6c..82ad8d6f7aa1 100644
--- a/atom/browser/net/cookie_details.h
+++ b/atom/browser/net/cookie_details.h
@@ -6,7 +6,11 @@
 #define ATOM_BROWSER_NET_COOKIE_DETAILS_H_
 
 #include "base/macros.h"
-#include "net/cookies/cookie_change_dispatcher.h"
+#include "services/network/public/mojom/cookie_manager.mojom.h"
+
+namespace net {
+class CanonicalCookie;
+}
 
 namespace atom {
 
@@ -14,12 +18,12 @@ struct CookieDetails {
  public:
   CookieDetails(const net::CanonicalCookie* cookie_copy,
                 bool is_removed,
-                net::CookieChangeCause cause)
+                network::mojom::CookieChangeCause cause)
       : cookie(cookie_copy), removed(is_removed), cause(cause) {}
 
   const net::CanonicalCookie* cookie;
   bool removed;
-  net::CookieChangeCause cause;
+  network::mojom::CookieChangeCause cause;
 };
 
 }  // namespace atom
diff --git a/atom/browser/net/resolve_proxy_helper.cc b/atom/browser/net/resolve_proxy_helper.cc
new file mode 100644
index 000000000000..cf148183de5d
--- /dev/null
+++ b/atom/browser/net/resolve_proxy_helper.cc
@@ -0,0 +1,96 @@
+// Copyright (c) 2018 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include "atom/browser/net/resolve_proxy_helper.h"
+
+#include "atom/browser/atom_browser_context.h"
+#include "base/bind.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
+
+namespace atom {
+
+ResolveProxyHelper::ResolveProxyHelper(AtomBrowserContext* browser_context)
+    : context_getter_(browser_context->GetRequestContext()),
+      original_thread_(base::ThreadTaskRunnerHandle::Get()) {}
+
+ResolveProxyHelper::~ResolveProxyHelper() {
+  // Clear all pending requests if the ProxyService is still alive.
+  pending_requests_.clear();
+}
+
+void ResolveProxyHelper::ResolveProxy(const GURL& url,
+                                      const ResolveProxyCallback& callback) {
+  // Enqueue the pending request.
+  pending_requests_.push_back(PendingRequest(url, callback));
+
+  // If nothing is in progress, start.
+  if (pending_requests_.size() == 1)
+    StartPendingRequest();
+}
+
+void ResolveProxyHelper::StartPendingRequest() {
+  auto& pending_request = pending_requests_.front();
+  context_getter_->GetNetworkTaskRunner()->PostTask(
+      FROM_HERE, base::BindOnce(&ResolveProxyHelper::StartPendingRequestInIO,
+                                base::Unretained(this), pending_request.url));
+}
+
+void ResolveProxyHelper::StartPendingRequestInIO(const GURL& url) {
+  auto* proxy_service =
+      context_getter_->GetURLRequestContext()->proxy_resolution_service();
+  // Start the request.
+  int result = proxy_service->ResolveProxy(
+      url, std::string(), &proxy_info_,
+      base::Bind(&ResolveProxyHelper::OnProxyResolveComplete,
+                 base::RetainedRef(this)),
+      nullptr, nullptr, net::NetLogWithSource());
+  // Completed synchronously.
+  if (result != net::ERR_IO_PENDING)
+    OnProxyResolveComplete(result);
+}
+
+void ResolveProxyHelper::OnProxyResolveComplete(int result) {
+  DCHECK(!pending_requests_.empty());
+
+  std::string proxy;
+  if (result == net::OK)
+    proxy = proxy_info_.ToPacString();
+
+  original_thread_->PostTask(
+      FROM_HERE, base::BindOnce(&ResolveProxyHelper::SendProxyResult,
+                                base::RetainedRef(this), proxy));
+}
+
+void ResolveProxyHelper::SendProxyResult(const std::string& proxy) {
+  DCHECK(!pending_requests_.empty());
+
+  const auto& completed_request = pending_requests_.front();
+  if (!completed_request.callback.is_null())
+    completed_request.callback.Run(proxy);
+
+  // Clear the current (completed) request.
+  pending_requests_.pop_front();
+
+  // Start the next request.
+  if (!pending_requests_.empty())
+    StartPendingRequest();
+}
+
+ResolveProxyHelper::PendingRequest::PendingRequest(
+    const GURL& url,
+    const ResolveProxyCallback& callback)
+    : url(url), callback(callback) {}
+
+ResolveProxyHelper::PendingRequest::PendingRequest(
+    ResolveProxyHelper::PendingRequest&& pending_request) = default;
+
+ResolveProxyHelper::PendingRequest::~PendingRequest() noexcept = default;
+
+ResolveProxyHelper::PendingRequest& ResolveProxyHelper::PendingRequest::
+operator=(ResolveProxyHelper::PendingRequest&& pending_request) noexcept =
+    default;
+
+}  // namespace atom
diff --git a/atom/browser/net/resolve_proxy_helper.h b/atom/browser/net/resolve_proxy_helper.h
new file mode 100644
index 000000000000..864ca674db1e
--- /dev/null
+++ b/atom/browser/net/resolve_proxy_helper.h
@@ -0,0 +1,68 @@
+// Copyright (c) 2018 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#ifndef ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_
+#define ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_
+
+#include <deque>
+#include <string>
+
+#include "base/memory/ref_counted.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
+#include "url/gurl.h"
+
+namespace net {
+class URLRequestContextGetter;
+}
+
+namespace atom {
+
+class AtomBrowserContext;
+
+class ResolveProxyHelper
+    : public base::RefCountedThreadSafe<ResolveProxyHelper> {
+ public:
+  using ResolveProxyCallback = base::Callback<void(std::string)>;
+
+  explicit ResolveProxyHelper(AtomBrowserContext* browser_context);
+
+  void ResolveProxy(const GURL& url, const ResolveProxyCallback& callback);
+
+ private:
+  friend class base::RefCountedThreadSafe<ResolveProxyHelper>;
+  // A PendingRequest is a resolve request that is in progress, or queued.
+  struct PendingRequest {
+   public:
+    PendingRequest(const GURL& url, const ResolveProxyCallback& callback);
+    PendingRequest(PendingRequest&& pending_request) noexcept;
+    ~PendingRequest();
+
+    PendingRequest& operator=(PendingRequest&& pending_request) noexcept;
+
+    GURL url;
+    ResolveProxyCallback callback;
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(PendingRequest);
+  };
+
+  ~ResolveProxyHelper();
+
+  // Starts the first pending request.
+  void StartPendingRequest();
+  void StartPendingRequestInIO(const GURL& url);
+  void OnProxyResolveComplete(int result);
+  void SendProxyResult(const std::string& proxy);
+
+  net::ProxyInfo proxy_info_;
+  std::deque<PendingRequest> pending_requests_;
+  scoped_refptr<net::URLRequestContextGetter> context_getter_;
+  scoped_refptr<base::SingleThreadTaskRunner> original_thread_;
+
+  DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper);
+};
+
+}  // namespace atom
+
+#endif  // ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_
diff --git a/atom/browser/net/url_request_context_getter.cc b/atom/browser/net/url_request_context_getter.cc
new file mode 100644
index 000000000000..328b9625bbd2
--- /dev/null
+++ b/atom/browser/net/url_request_context_getter.cc
@@ -0,0 +1,417 @@
+// Copyright (c) 2018 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include "atom/browser/net/url_request_context_getter.h"
+
+#include <algorithm>
+#include <memory>
+#include <utility>
+
+#include "atom/browser/api/atom_api_protocol.h"
+#include "atom/browser/atom_browser_client.h"
+#include "atom/browser/atom_browser_context.h"
+#include "atom/browser/net/about_protocol_handler.h"
+#include "atom/browser/net/asar/asar_protocol_handler.h"
+#include "atom/browser/net/atom_cert_verifier.h"
+#include "atom/browser/net/atom_network_delegate.h"
+#include "atom/browser/net/atom_url_request_job_factory.h"
+#include "atom/browser/net/http_protocol_handler.h"
+#include "atom/common/options_switches.h"
+#include "base/command_line.h"
+#include "base/strings/string_util.h"
+#include "base/task_scheduler/post_task.h"
+#include "brightray/browser/net/require_ct_delegate.h"
+#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/pref_names.h"
+#include "components/network_session_configurator/common/network_switches.h"
+#include "components/prefs/value_map_pref_store.h"
+#include "components/proxy_config/proxy_config_dictionary.h"
+#include "components/proxy_config/proxy_config_pref_names.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/devtools_network_transaction_factory.h"
+#include "content/public/browser/network_service_instance.h"
+#include "content/public/browser/resource_context.h"
+#include "content/public/common/content_switches.h"
+#include "net/base/host_mapping_rules.h"
+#include "net/cert/multi_log_ct_verifier.h"
+#include "net/cookies/cookie_monster.h"
+#include "net/dns/mapped_host_resolver.h"
+#include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_auth_preferences.h"
+#include "net/http/http_auth_scheme.h"
+#include "net/http/http_transaction_factory.h"
+#include "net/log/net_log.h"
+#include "net/proxy_resolution/proxy_config.h"
+#include "net/proxy_resolution/proxy_config_service.h"
+#include "net/proxy_resolution/proxy_config_with_annotation.h"
+#include "net/proxy_resolution/proxy_resolution_service.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "net/url_request/data_protocol_handler.h"
+#include "net/url_request/static_http_user_agent_settings.h"
+#include "net/url_request/url_request_intercepting_job_factory.h"
+#include "net/url_request/url_request_job_factory_impl.h"
+#include "services/network/ignore_errors_cert_verifier.h"
+#include "services/network/network_service.h"
+#include "services/network/public/cpp/network_switches.h"
+#include "services/network/url_request_context_builder_mojo.h"
+#include "url/url_constants.h"
+
+#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
+#include "net/url_request/ftp_protocol_handler.h"
+#endif
+
+using content::BrowserThread;
+
+namespace atom {
+
+namespace {
+
+network::mojom::NetworkContextParamsPtr CreateDefaultNetworkContextParams(
+    const base::FilePath& base_path,
+    const std::string& user_agent,
+    bool in_memory,
+    bool use_cache,
+    int max_cache_size) {
+  network::mojom::NetworkContextParamsPtr network_context_params =
+      network::mojom::NetworkContextParams::New();
+  network_context_params->enable_brotli = true;
+  network_context_params->user_agent = user_agent;
+  network_context_params->http_cache_enabled = use_cache;
+  network_context_params->accept_language =
+      net::HttpUtil::GenerateAcceptLanguageHeader(
+          brightray::BrowserClient::Get()->GetApplicationLocale());
+  network_context_params->allow_gssapi_library_load = true;
+  network_context_params->enable_data_url_support = false;
+  network_context_params->proxy_resolver_factory =
+      ChromeMojoProxyResolverFactory::CreateWithStrongBinding().PassInterface();
+  if (!in_memory) {
+    network_context_params->http_cache_path =
+        base_path.Append(chrome::kCacheDirname);
+    network_context_params->http_cache_max_size = max_cache_size;
+    network_context_params->http_server_properties_path =
+        base_path.Append(chrome::kNetworkPersistentStateFilename);
+    network_context_params->cookie_path =
+        base_path.Append(chrome::kCookieFilename);
+    network_context_params->channel_id_path =
+        base_path.Append(chrome::kChannelIDFilename);
+    network_context_params->restore_old_session_cookies = false;
+    network_context_params->persist_session_cookies = false;
+  }
+  // TODO(deepak1556): Decide the stand on chrome ct policy and
+  // enable it.
+  // See //net/docs/certificate-transparency.md
+  // network_context_params->enforce_chrome_ct_policy = true;
+  return network_context_params;
+}
+
+void SetupAtomURLRequestJobFactory(
+    content::ProtocolHandlerMap* protocol_handlers,
+    net::URLRequestContext* url_request_context,
+    AtomURLRequestJobFactory* job_factory) {
+  for (auto& protocol_handler : *protocol_handlers) {
+    job_factory->SetProtocolHandler(protocol_handler.first,
+                                    std::move(protocol_handler.second));
+  }
+  protocol_handlers->clear();
+
+  job_factory->SetProtocolHandler(url::kAboutScheme,
+                                  std::make_unique<AboutProtocolHandler>());
+  job_factory->SetProtocolHandler(url::kDataScheme,
+                                  std::make_unique<net::DataProtocolHandler>());
+  job_factory->SetProtocolHandler(
+      url::kFileScheme,
+      std::make_unique<asar::AsarProtocolHandler>(
+          base::CreateTaskRunnerWithTraits(
+              {base::MayBlock(), base::TaskPriority::USER_BLOCKING,
+               base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})));
+  job_factory->SetProtocolHandler(
+      url::kHttpScheme,
+      std::make_unique<HttpProtocolHandler>(url::kHttpScheme));
+  job_factory->SetProtocolHandler(
+      url::kHttpsScheme,
+      std::make_unique<HttpProtocolHandler>(url::kHttpsScheme));
+  job_factory->SetProtocolHandler(
+      url::kWsScheme, std::make_unique<HttpProtocolHandler>(url::kWsScheme));
+  job_factory->SetProtocolHandler(
+      url::kWssScheme, std::make_unique<HttpProtocolHandler>(url::kWssScheme));
+
+#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
+  auto* host_resolver = url_request_context->host_resolver();
+  job_factory->SetProtocolHandler(
+      url::kFtpScheme, net::FtpProtocolHandler::Create(host_resolver));
+#endif
+}
+
+void ApplyProxyModeFromCommandLine(ValueMapPrefStore* pref_store) {
+  if (!pref_store)
+    return;
+
+  auto* command_line = base::CommandLine::ForCurrentProcess();
+
+  if (command_line->HasSwitch(::switches::kNoProxyServer)) {
+    pref_store->SetValue(proxy_config::prefs::kProxy,
+                         ProxyConfigDictionary::CreateDirect(),
+                         WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  } else if (command_line->HasSwitch(::switches::kProxyPacUrl)) {
+    std::string pac_script_url =
+        command_line->GetSwitchValueASCII(::switches::kProxyPacUrl);
+    pref_store->SetValue(proxy_config::prefs::kProxy,
+                         ProxyConfigDictionary::CreatePacScript(
+                             pac_script_url, false /* pac_mandatory */),
+                         WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  } else if (command_line->HasSwitch(::switches::kProxyAutoDetect)) {
+    pref_store->SetValue(proxy_config::prefs::kProxy,
+                         ProxyConfigDictionary::CreateAutoDetect(),
+                         WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  } else if (command_line->HasSwitch(::switches::kProxyServer)) {
+    std::string proxy_server =
+        command_line->GetSwitchValueASCII(::switches::kProxyServer);
+    std::string bypass_list =
+        command_line->GetSwitchValueASCII(::switches::kProxyBypassList);
+    pref_store->SetValue(
+        proxy_config::prefs::kProxy,
+        ProxyConfigDictionary::CreateFixedServers(proxy_server, bypass_list),
+        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  }
+}
+
+}  // namespace
+
+class ResourceContext : public content::ResourceContext {
+ public:
+  ResourceContext() = default;
+  ~ResourceContext() override = default;
+
+  net::HostResolver* GetHostResolver() override {
+    if (request_context_)
+      return request_context_->host_resolver();
+    return nullptr;
+  }
+
+  net::URLRequestContext* GetRequestContext() override {
+    return request_context_;
+  }
+
+ private:
+  friend class URLRequestContextGetter;
+
+  net::URLRequestContext* request_context_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(ResourceContext);
+};
+
+URLRequestContextGetter::Handle::Handle(
+    base::WeakPtr<AtomBrowserContext> browser_context)
+    : resource_context_(new ResourceContext),
+      browser_context_(browser_context),
+      initialized_(false) {}
+
+URLRequestContextGetter::Handle::~Handle() {}
+
+content::ResourceContext*
+URLRequestContextGetter::Handle::GetResourceContext() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  LazyInitialize();
+  return resource_context_.get();
+}
+
+scoped_refptr<URLRequestContextGetter>
+URLRequestContextGetter::Handle::CreateMainRequestContextGetter(
+    content::ProtocolHandlerMap* protocol_handlers,
+    content::URLRequestInterceptorScopedVector protocol_interceptors) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK(!main_request_context_getter_.get());
+  LazyInitialize();
+  main_request_context_getter_ = new URLRequestContextGetter(
+      AtomBrowserClient::Get()->GetNetLog(), this, protocol_handlers,
+      std::move(protocol_interceptors));
+  return main_request_context_getter_;
+}
+
+scoped_refptr<URLRequestContextGetter>
+URLRequestContextGetter::Handle::GetMainRequestContextGetter() {
+  return main_request_context_getter_;
+}
+
+network::mojom::NetworkContextPtr
+URLRequestContextGetter::Handle::GetNetworkContext() {
+  if (!main_network_context_) {
+    main_network_context_request_ = mojo::MakeRequest(&main_network_context_);
+  }
+  return std::move(main_network_context_);
+}
+
+void URLRequestContextGetter::Handle::LazyInitialize() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (initialized_)
+    return;
+
+  initialized_ = true;
+  main_network_context_params_ = CreateDefaultNetworkContextParams(
+      browser_context_->GetPath(), browser_context_->GetUserAgent(),
+      browser_context_->IsOffTheRecord(), browser_context_->CanUseHttpCache(),
+      browser_context_->GetMaxCacheSize());
+
+  browser_context_->proxy_config_monitor()->AddToNetworkContextParams(
+      main_network_context_params_.get());
+
+  ApplyProxyModeFromCommandLine(browser_context_->in_memory_pref_store());
+
+  if (!main_network_context_request_.is_pending()) {
+    main_network_context_request_ = mojo::MakeRequest(&main_network_context_);
+  }
+  content::BrowserContext::EnsureResourceContextInitialized(
+      browser_context_.get());
+}
+
+void URLRequestContextGetter::Handle::ShutdownOnUIThread() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (main_request_context_getter_.get()) {
+    if (BrowserThread::IsThreadInitialized(BrowserThread::IO)) {
+      BrowserThread::PostTask(
+          BrowserThread::IO, FROM_HERE,
+          base::BindOnce(&URLRequestContextGetter::NotifyContextShuttingDown,
+                         base::RetainedRef(main_request_context_getter_),
+                         std::move(resource_context_)));
+    }
+  }
+
+  if (!BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this))
+    delete this;
+}
+
+URLRequestContextGetter::URLRequestContextGetter(
+    net::NetLog* net_log,
+    URLRequestContextGetter::Handle* context_handle,
+    content::ProtocolHandlerMap* protocol_handlers,
+    content::URLRequestInterceptorScopedVector protocol_interceptors)
+    : net_log_(net_log),
+      context_handle_(context_handle),
+      url_request_context_(nullptr),
+      protocol_interceptors_(std::move(protocol_interceptors)),
+      context_shutting_down_(false) {
+  // Must first be created on the UI thread.
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  if (protocol_handlers)
+    std::swap(protocol_handlers_, *protocol_handlers);
+}
+
+URLRequestContextGetter::~URLRequestContextGetter() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  // NotifyContextShuttingDown should have been called.
+  DCHECK(context_shutting_down_);
+}
+
+void URLRequestContextGetter::NotifyContextShuttingDown(
+    std::unique_ptr<ResourceContext> resource_context) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  context_shutting_down_ = true;
+  resource_context.reset();
+  net::URLRequestContextGetter::NotifyContextShuttingDown();
+}
+
+net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  if (context_shutting_down_)
+    return nullptr;
+
+  if (!url_request_context_) {
+    auto& command_line = *base::CommandLine::ForCurrentProcess();
+    std::unique_ptr<network::URLRequestContextBuilderMojo> builder =
+        std::make_unique<network::URLRequestContextBuilderMojo>();
+    builder->set_network_delegate(std::make_unique<AtomNetworkDelegate>());
+
+    ct_delegate_.reset(new brightray::RequireCTDelegate);
+    auto cert_verifier = std::make_unique<AtomCertVerifier>(ct_delegate_.get());
+    builder->SetCertVerifier(std::move(cert_verifier));
+
+    builder->SetCreateHttpTransactionFactoryCallback(
+        base::BindOnce(&content::CreateDevToolsNetworkTransactionFactory));
+
+    std::unique_ptr<net::HostResolver> host_resolver =
+        net::HostResolver::CreateDefaultResolver(net_log_);
+    // --host-resolver-rules
+    if (command_line.HasSwitch(network::switches::kHostResolverRules)) {
+      auto remapped_resolver =
+          std::make_unique<net::MappedHostResolver>(std::move(host_resolver));
+      remapped_resolver->SetRulesFromString(command_line.GetSwitchValueASCII(
+          network::switches::kHostResolverRules));
+      host_resolver = std::move(remapped_resolver);
+    }
+
+    net::HttpAuthPreferences auth_preferences;
+    // --auth-server-whitelist
+    if (command_line.HasSwitch(switches::kAuthServerWhitelist)) {
+      auth_preferences.SetServerWhitelist(
+          command_line.GetSwitchValueASCII(switches::kAuthServerWhitelist));
+    }
+
+    // --auth-negotiate-delegate-whitelist
+    if (command_line.HasSwitch(switches::kAuthNegotiateDelegateWhitelist)) {
+      auth_preferences.SetDelegateWhitelist(command_line.GetSwitchValueASCII(
+          switches::kAuthNegotiateDelegateWhitelist));
+    }
+    auto http_auth_handler_factory =
+        net::HttpAuthHandlerRegistryFactory::CreateDefault(host_resolver.get());
+    http_auth_handler_factory->SetHttpAuthPreferences(net::kNegotiateAuthScheme,
+                                                      &auth_preferences);
+    builder->SetHttpAuthHandlerFactory(std::move(http_auth_handler_factory));
+    builder->set_host_resolver(std::move(host_resolver));
+    builder->set_ct_verifier(std::make_unique<net::MultiLogCTVerifier>());
+
+    network_context_ =
+        content::GetNetworkServiceImpl()->CreateNetworkContextWithBuilder(
+            std::move(context_handle_->main_network_context_request_),
+            std::move(context_handle_->main_network_context_params_),
+            std::move(builder), &url_request_context_);
+
+    net::TransportSecurityState* transport_security_state =
+        url_request_context_->transport_security_state();
+    transport_security_state->SetRequireCTDelegate(ct_delegate_.get());
+
+    // Add custom standard schemes to cookie schemes.
+    auto* cookie_monster =
+        static_cast<net::CookieMonster*>(url_request_context_->cookie_store());
+    std::vector<std::string> cookie_schemes(
+        {url::kHttpScheme, url::kHttpsScheme, url::kWsScheme, url::kWssScheme});
+    const auto& custom_standard_schemes = atom::api::GetStandardSchemes();
+    cookie_schemes.insert(cookie_schemes.end(), custom_standard_schemes.begin(),
+                          custom_standard_schemes.end());
+    cookie_monster->SetCookieableSchemes(cookie_schemes);
+
+    // Setup handlers for custom job factory.
+    top_job_factory_.reset(new AtomURLRequestJobFactory);
+    SetupAtomURLRequestJobFactory(&protocol_handlers_, url_request_context_,
+                                  top_job_factory_.get());
+    std::unique_ptr<net::URLRequestJobFactory> inner_job_factory(
+        new net::URLRequestJobFactoryImpl);
+    if (!protocol_interceptors_.empty()) {
+      // Set up interceptors in the reverse order.
+      for (auto it = protocol_interceptors_.rbegin();
+           it != protocol_interceptors_.rend(); ++it) {
+        inner_job_factory.reset(new net::URLRequestInterceptingJobFactory(
+            std::move(inner_job_factory), std::move(*it)));
+      }
+      protocol_interceptors_.clear();
+    }
+    top_job_factory_->Chain(std::move(inner_job_factory));
+    url_request_context_->set_job_factory(top_job_factory_.get());
+
+    context_handle_->resource_context_->request_context_ = url_request_context_;
+  }
+
+  return url_request_context_;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+URLRequestContextGetter::GetNetworkTaskRunner() const {
+  return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+}
+
+}  // namespace atom
diff --git a/atom/browser/net/url_request_context_getter.h b/atom/browser/net/url_request_context_getter.h
new file mode 100644
index 000000000000..dd8798eeebfa
--- /dev/null
+++ b/atom/browser/net/url_request_context_getter.h
@@ -0,0 +1,117 @@
+// Copyright (c) 2018 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#ifndef ATOM_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_
+#define ATOM_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "content/public/browser/browser_context.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "services/network/public/mojom/network_service.mojom.h"
+
+#if DCHECK_IS_ON()
+#include "base/debug/leak_tracker.h"
+#endif
+
+namespace brightray {
+class RequireCTDelegate;
+}  // namespace brightray
+
+namespace net {
+class NetLog;
+}
+
+namespace atom {
+
+class AtomBrowserContext;
+class AtomURLRequestJobFactory;
+class ResourceContext;
+
+class URLRequestContextGetter : public net::URLRequestContextGetter {
+ public:
+  // net::URLRequestContextGetter:
+  net::URLRequestContext* GetURLRequestContext() override;
+  scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
+      const override;
+
+  // Discard reference to URLRequestContext and inform observers to
+  // shutdown. Must be called only on IO thread.
+  void NotifyContextShuttingDown(std::unique_ptr<ResourceContext>);
+
+  AtomURLRequestJobFactory* job_factory() const {
+    return top_job_factory_.get();
+  }
+
+ private:
+  friend class AtomBrowserContext;
+
+  // Responsible for destroying URLRequestContextGetter
+  // on the IO thread.
+  class Handle {
+   public:
+    explicit Handle(base::WeakPtr<AtomBrowserContext> browser_context);
+    ~Handle();
+
+    scoped_refptr<URLRequestContextGetter> CreateMainRequestContextGetter(
+        content::ProtocolHandlerMap* protocol_handlers,
+        content::URLRequestInterceptorScopedVector protocol_interceptors);
+    content::ResourceContext* GetResourceContext();
+    scoped_refptr<URLRequestContextGetter> GetMainRequestContextGetter();
+    network::mojom::NetworkContextPtr GetNetworkContext();
+
+    void ShutdownOnUIThread();
+
+   private:
+    friend class URLRequestContextGetter;
+    void LazyInitialize();
+
+    scoped_refptr<URLRequestContextGetter> main_request_context_getter_;
+    std::unique_ptr<ResourceContext> resource_context_;
+    base::WeakPtr<AtomBrowserContext> browser_context_;
+    // This is a NetworkContext interface that uses URLRequestContextGetter
+    // NetworkContext, ownership is passed to StoragePartition when
+    // CreateMainNetworkContext is called.
+    network::mojom::NetworkContextPtr main_network_context_;
+    // Request corresponding to |main_network_context_|. Ownership
+    // is passed to network service.
+    network::mojom::NetworkContextRequest main_network_context_request_;
+    network::mojom::NetworkContextParamsPtr main_network_context_params_;
+    bool initialized_;
+
+    DISALLOW_COPY_AND_ASSIGN(Handle);
+  };
+
+  URLRequestContextGetter(
+      net::NetLog* net_log,
+      URLRequestContextGetter::Handle* context_handle,
+      content::ProtocolHandlerMap* protocol_handlers,
+      content::URLRequestInterceptorScopedVector protocol_interceptors);
+  ~URLRequestContextGetter() override;
+
+#if DCHECK_IS_ON()
+  base::debug::LeakTracker<URLRequestContextGetter> leak_tracker_;
+#endif
+
+  std::unique_ptr<brightray::RequireCTDelegate> ct_delegate_;
+  std::unique_ptr<AtomURLRequestJobFactory> top_job_factory_;
+  std::unique_ptr<network::mojom::NetworkContext> network_context_;
+
+  net::NetLog* net_log_;
+  URLRequestContextGetter::Handle* context_handle_;
+  net::URLRequestContext* url_request_context_;
+  content::ProtocolHandlerMap protocol_handlers_;
+  content::URLRequestInterceptorScopedVector protocol_interceptors_;
+  bool context_shutting_down_;
+
+  DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter);
+};
+
+}  // namespace atom
+
+#endif  // ATOM_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_
diff --git a/atom/browser/net/url_request_fetch_job.cc b/atom/browser/net/url_request_fetch_job.cc
index e86c984a574e..cd6a8726e034 100644
--- a/atom/browser/net/url_request_fetch_job.cc
+++ b/atom/browser/net/url_request_fetch_job.cc
@@ -168,6 +168,9 @@ void URLRequestFetchJob::StartAsync(std::unique_ptr<base::Value> options) {
       request()->extra_request_headers().ToString());
 
   fetcher_->Start();
+  // URLFetcher has a refernce to the context, which
+  // will be cleared when the request is destroyed.
+  url_request_context_getter_ = nullptr;
 }
 
 void URLRequestFetchJob::HeadersCompleted() {
@@ -200,6 +203,7 @@ int URLRequestFetchJob::DataAvailable(net::IOBuffer* buffer,
 void URLRequestFetchJob::Kill() {
   JsAsker<URLRequestJob>::Kill();
   fetcher_.reset();
+  custom_browser_context_ = nullptr;
 }
 
 int URLRequestFetchJob::ReadRawData(net::IOBuffer* dest, int dest_size) {
diff --git a/atom/browser/pref_store_delegate.cc b/atom/browser/pref_store_delegate.cc
new file mode 100644
index 000000000000..a577fde0d296
--- /dev/null
+++ b/atom/browser/pref_store_delegate.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2018 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include "atom/browser/pref_store_delegate.h"
+
+#include <utility>
+
+#include "atom/browser/atom_browser_context.h"
+#include "components/prefs/value_map_pref_store.h"
+
+namespace atom {
+
+PrefStoreDelegate::PrefStoreDelegate(
+    base::WeakPtr<AtomBrowserContext> browser_context)
+    : browser_context_(std::move(browser_context)) {}
+
+PrefStoreDelegate::~PrefStoreDelegate() {
+  if (browser_context_)
+    browser_context_->set_in_memory_pref_store(nullptr);
+}
+
+void PrefStoreDelegate::UpdateCommandLinePrefStore(
+    PrefStore* command_line_prefs) {
+  if (browser_context_)
+    browser_context_->set_in_memory_pref_store(
+        static_cast<ValueMapPrefStore*>(command_line_prefs));
+}
+
+}  // namespace atom
diff --git a/atom/browser/pref_store_delegate.h b/atom/browser/pref_store_delegate.h
new file mode 100644
index 000000000000..73696beb6fb0
--- /dev/null
+++ b/atom/browser/pref_store_delegate.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2018 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#ifndef ATOM_BROWSER_PREF_STORE_DELEGATE_H_
+#define ATOM_BROWSER_PREF_STORE_DELEGATE_H_
+
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "components/prefs/persistent_pref_store.h"
+#include "components/prefs/pref_value_store.h"
+
+namespace atom {
+
+class AtomBrowserContext;
+
+// Retrieves handle to the in memory pref store that gets
+// initialized with the pref service.
+class PrefStoreDelegate : public PrefValueStore::Delegate {
+ public:
+  explicit PrefStoreDelegate(base::WeakPtr<AtomBrowserContext> browser_context);
+  ~PrefStoreDelegate() override;
+
+  void Init(PrefStore* managed_prefs,
+            PrefStore* supervised_user_prefs,
+            PrefStore* extension_prefs,
+            PrefStore* command_line_prefs,
+            PrefStore* user_prefs,
+            PrefStore* recommended_prefs,
+            PrefStore* default_prefs,
+            PrefNotifier* pref_notifier) override {}
+
+  void InitIncognitoUserPrefs(
+      scoped_refptr<PersistentPrefStore> incognito_user_prefs_overlay,
+      scoped_refptr<PersistentPrefStore> incognito_user_prefs_underlay,
+      const std::vector<const char*>& overlay_pref_names) override {}
+
+  void InitPrefRegistry(PrefRegistry* pref_registry) override {}
+
+  void UpdateCommandLinePrefStore(PrefStore* command_line_prefs) override;
+
+ private:
+  base::WeakPtr<AtomBrowserContext> browser_context_;
+
+  DISALLOW_COPY_AND_ASSIGN(PrefStoreDelegate);
+};
+
+}  // namespace atom
+
+#endif  // ATOM_BROWSER_PREF_STORE_DELEGATE_H_
diff --git a/atom/browser/request_context_delegate.cc b/atom/browser/request_context_delegate.cc
deleted file mode 100644
index 4056d6fee9cb..000000000000
--- a/atom/browser/request_context_delegate.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright (c) 2018 GitHub, Inc.
-// Use of this source code is governed by the MIT license that can be
-// found in the LICENSE file.
-
-#include "atom/browser/request_context_delegate.h"
-
-#include <memory>
-#include <utility>
-
-#include "atom/browser/api/atom_api_protocol.h"
-#include "atom/browser/net/about_protocol_handler.h"
-#include "atom/browser/net/asar/asar_protocol_handler.h"
-#include "atom/browser/net/atom_cert_verifier.h"
-#include "atom/browser/net/atom_network_delegate.h"
-#include "atom/browser/net/atom_url_request_job_factory.h"
-#include "atom/browser/net/cookie_details.h"
-#include "atom/browser/net/http_protocol_handler.h"
-#include "atom/common/options_switches.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/task_scheduler/post_task.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/common/url_constants.h"
-#include "net/ftp/ftp_network_layer.h"
-#include "net/url_request/data_protocol_handler.h"
-#include "net/url_request/ftp_protocol_handler.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_intercepting_job_factory.h"
-#include "url/url_constants.h"
-
-using content::BrowserThread;
-
-namespace atom {
-
-namespace {
-
-class NoCacheBackend : public net::HttpCache::BackendFactory {
-  int CreateBackend(net::NetLog* net_log,
-                    std::unique_ptr<disk_cache::Backend>* backend,
-                    const net::CompletionCallback& callback) override {
-    return net::ERR_FAILED;
-  }
-};
-
-}  // namespace
-
-RequestContextDelegate::RequestContextDelegate(bool use_cache)
-    : use_cache_(use_cache), weak_factory_(this) {}
-
-RequestContextDelegate::~RequestContextDelegate() {}
-
-std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
-RequestContextDelegate::RegisterCookieChangeCallback(
-    const base::Callback<void(const CookieDetails*)>& cb) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  return cookie_change_sub_list_.Add(cb);
-}
-
-void RequestContextDelegate::NotifyCookieChange(
-    const net::CanonicalCookie& cookie,
-    net::CookieChangeCause cause) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  CookieDetails cookie_details(
-      &cookie, !(cause == net::CookieChangeCause::INSERTED), cause);
-  cookie_change_sub_list_.Notify(&cookie_details);
-}
-
-std::unique_ptr<net::NetworkDelegate>
-RequestContextDelegate::CreateNetworkDelegate() {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  return std::make_unique<AtomNetworkDelegate>();
-}
-
-std::unique_ptr<net::URLRequestJobFactory>
-RequestContextDelegate::CreateURLRequestJobFactory(
-    net::URLRequestContext* url_request_context,
-    content::ProtocolHandlerMap* protocol_handlers) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  std::unique_ptr<AtomURLRequestJobFactory> job_factory(
-      new AtomURLRequestJobFactory);
-
-  for (auto& it : *protocol_handlers) {
-    job_factory->SetProtocolHandler(it.first,
-                                    base::WrapUnique(it.second.release()));
-  }
-  protocol_handlers->clear();
-
-  job_factory->SetProtocolHandler(url::kAboutScheme,
-                                  base::WrapUnique(new AboutProtocolHandler));
-  job_factory->SetProtocolHandler(
-      url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler));
-  job_factory->SetProtocolHandler(
-      url::kFileScheme,
-      base::WrapUnique(
-          new asar::AsarProtocolHandler(base::CreateTaskRunnerWithTraits(
-              {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
-               base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}))));
-  job_factory->SetProtocolHandler(
-      url::kHttpScheme,
-      base::WrapUnique(new HttpProtocolHandler(url::kHttpScheme)));
-  job_factory->SetProtocolHandler(
-      url::kHttpsScheme,
-      base::WrapUnique(new HttpProtocolHandler(url::kHttpsScheme)));
-  job_factory->SetProtocolHandler(
-      url::kWsScheme,
-      base::WrapUnique(new HttpProtocolHandler(url::kWsScheme)));
-  job_factory->SetProtocolHandler(
-      url::kWssScheme,
-      base::WrapUnique(new HttpProtocolHandler(url::kWssScheme)));
-
-  auto* host_resolver = url_request_context->host_resolver();
-  job_factory->SetProtocolHandler(
-      url::kFtpScheme, net::FtpProtocolHandler::Create(host_resolver));
-
-  return std::move(job_factory);
-}
-
-net::HttpCache::BackendFactory*
-RequestContextDelegate::CreateHttpCacheBackendFactory(
-    const base::FilePath& base_path) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  if (!use_cache_) {
-    return new NoCacheBackend;
-  } else {
-    int max_size = 0;
-    base::StringToInt(
-        command_line->GetSwitchValueASCII(switches::kDiskCacheSize), &max_size);
-
-    base::FilePath cache_path = base_path.Append(FILE_PATH_LITERAL("Cache"));
-    return new net::HttpCache::DefaultBackend(
-        net::DISK_CACHE, net::CACHE_BACKEND_DEFAULT, cache_path, max_size);
-  }
-}
-
-std::unique_ptr<net::CertVerifier> RequestContextDelegate::CreateCertVerifier(
-    brightray::RequireCTDelegate* ct_delegate) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  return std::make_unique<AtomCertVerifier>(ct_delegate);
-}
-
-void RequestContextDelegate::GetCookieableSchemes(
-    std::vector<std::string>* cookie_schemes) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  const auto& standard_schemes = atom::api::GetStandardSchemes();
-  cookie_schemes->insert(cookie_schemes->end(), standard_schemes.begin(),
-                         standard_schemes.end());
-}
-
-void RequestContextDelegate::OnCookieChanged(const net::CanonicalCookie& cookie,
-                                             net::CookieChangeCause cause) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::BindRepeating(&RequestContextDelegate::NotifyCookieChange,
-                          weak_factory_.GetWeakPtr(), cookie, cause));
-}
-
-}  // namespace atom
diff --git a/atom/browser/request_context_delegate.h b/atom/browser/request_context_delegate.h
deleted file mode 100644
index 3b97b0fe7ad1..000000000000
--- a/atom/browser/request_context_delegate.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2018 GitHub, Inc.
-// Use of this source code is governed by the MIT license that can be
-// found in the LICENSE file.
-
-#ifndef ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_
-#define ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/callback_list.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "brightray/browser/url_request_context_getter.h"
-
-namespace atom {
-
-struct CookieDetails;
-
-class RequestContextDelegate
-    : public brightray::URLRequestContextGetter::Delegate {
- public:
-  explicit RequestContextDelegate(bool use_cache);
-  ~RequestContextDelegate() override;
-
-  // Register callbacks that needs to notified on any cookie store changes.
-  std::unique_ptr<base::CallbackList<void(const CookieDetails*)>::Subscription>
-  RegisterCookieChangeCallback(
-      const base::Callback<void(const CookieDetails*)>& cb);
-
- protected:
-  std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() override;
-  std::unique_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
-      net::URLRequestContext* url_request_context,
-      content::ProtocolHandlerMap* protocol_handlers) override;
-  net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
-      const base::FilePath& base_path) override;
-  std::unique_ptr<net::CertVerifier> CreateCertVerifier(
-      brightray::RequireCTDelegate* ct_delegate) override;
-  void GetCookieableSchemes(std::vector<std::string>* cookie_schemes) override;
-  void OnCookieChanged(const net::CanonicalCookie& cookie,
-                       net::CookieChangeCause cause) override;
-
- private:
-  void NotifyCookieChange(const net::CanonicalCookie& cookie,
-                          net::CookieChangeCause cause);
-
-  base::CallbackList<void(const CookieDetails*)> cookie_change_sub_list_;
-  bool use_cache_ = true;
-
-  base::WeakPtrFactory<RequestContextDelegate> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(RequestContextDelegate);
-};
-
-}  // namespace atom
-
-#endif  // ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_
diff --git a/atom/common/node_bindings.cc b/atom/common/node_bindings.cc
index 408a07cabd4e..3ecc867ab049 100644
--- a/atom/common/node_bindings.cc
+++ b/atom/common/node_bindings.cc
@@ -40,7 +40,6 @@
   V(atom_browser_in_app_purchase)            \
   V(atom_browser_menu)                       \
   V(atom_browser_net)                        \
-  V(atom_browser_net_log)                    \
   V(atom_browser_power_monitor)              \
   V(atom_browser_power_save_blocker)         \
   V(atom_browser_protocol)                   \
diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc
index 8b1836f80c58..ef9998a84d89 100644
--- a/atom/common/options_switches.cc
+++ b/atom/common/options_switches.cc
@@ -216,6 +216,13 @@ const char kDiskCacheSize[] = "disk-cache-size";
 // Ignore the limit of 6 connections per host.
 const char kIgnoreConnectionsLimit[] = "ignore-connections-limit";
 
+// Whitelist containing servers for which Integrated Authentication is enabled.
+const char kAuthServerWhitelist[] = "auth-server-whitelist";
+
+// Whitelist containing servers for which Kerberos delegation is allowed.
+const char kAuthNegotiateDelegateWhitelist[] =
+    "auth-negotiate-delegate-whitelist";
+
 }  // namespace switches
 
 }  // namespace atom
diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h
index 5f6d7e9d3812..4880d9b0912e 100644
--- a/atom/common/options_switches.h
+++ b/atom/common/options_switches.h
@@ -111,6 +111,8 @@ extern const char kWidevineCdmVersion[];
 
 extern const char kDiskCacheSize[];
 extern const char kIgnoreConnectionsLimit[];
+extern const char kAuthServerWhitelist[];
+extern const char kAuthNegotiateDelegateWhitelist[];
 
 }  // namespace switches
 
diff --git a/atom/utility/atom_content_utility_client.cc b/atom/utility/atom_content_utility_client.cc
index e2a856d53ae2..3a9cfff38d67 100644
--- a/atom/utility/atom_content_utility_client.cc
+++ b/atom/utility/atom_content_utility_client.cc
@@ -4,6 +4,10 @@
 
 #include "atom/utility/atom_content_utility_client.h"
 
+#include "content/public/child/child_thread.h"
+#include "services/proxy_resolver/proxy_resolver_service.h"
+#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
+
 #if defined(OS_WIN)
 #include "chrome/utility/printing_handler_win.h"
 #endif
@@ -29,4 +33,14 @@ bool AtomContentUtilityClient::OnMessageReceived(const IPC::Message& message) {
   return false;
 }
 
+void AtomContentUtilityClient::RegisterServices(StaticServiceMap* services) {
+  service_manager::EmbeddedServiceInfo proxy_resolver_info;
+  proxy_resolver_info.task_runner =
+      content::ChildThread::Get()->GetIOTaskRunner();
+  proxy_resolver_info.factory =
+      base::BindRepeating(&proxy_resolver::ProxyResolverService::CreateService);
+  services->emplace(proxy_resolver::mojom::kProxyResolverServiceName,
+                    proxy_resolver_info);
+}
+
 }  // namespace atom
diff --git a/atom/utility/atom_content_utility_client.h b/atom/utility/atom_content_utility_client.h
index 7694970457b7..cf990a40ddcb 100644
--- a/atom/utility/atom_content_utility_client.h
+++ b/atom/utility/atom_content_utility_client.h
@@ -21,6 +21,7 @@ class AtomContentUtilityClient : public content::ContentUtilityClient {
   ~AtomContentUtilityClient() override;
 
   bool OnMessageReceived(const IPC::Message& message) override;
+  void RegisterServices(StaticServiceMap* services) override;
 
  private:
 #if defined(OS_WIN)
diff --git a/brightray/BUILD.gn b/brightray/BUILD.gn
index 3f0720824f79..6d7ebbffb6dd 100644
--- a/brightray/BUILD.gn
+++ b/brightray/BUILD.gn
@@ -4,9 +4,6 @@ static_library("brightray") {
   deps = [
     "//base",
     "//base:base_static",
-    "//components/certificate_transparency",
-    "//components/network_session_configurator/common",
-    "//components/prefs",
     "//content/public/browser",
     "//content/shell:copy_shell_resources",
     "//net:extras",
@@ -36,8 +33,6 @@ static_library("brightray") {
     "browser/brightray_paths.h",
     "browser/browser_client.cc",
     "browser/browser_client.h",
-    "browser/browser_context.cc",
-    "browser/browser_context.h",
     "browser/browser_main_parts.cc",
     "browser/browser_main_parts.h",
     "browser/browser_main_parts_mac.mm",
@@ -55,8 +50,6 @@ static_library("brightray") {
     "browser/inspectable_web_contents_view_delegate.h",
     "browser/inspectable_web_contents_view_mac.h",
     "browser/inspectable_web_contents_view_mac.mm",
-    "browser/io_thread.cc",
-    "browser/io_thread.h",
     "browser/linux/libnotify_loader.cc",
     "browser/linux/libnotify_loader.h",
     "browser/linux/libnotify_notification.cc",
@@ -81,8 +74,6 @@ static_library("brightray") {
     "browser/media/media_stream_devices_controller.h",
     "browser/net/require_ct_delegate.cc",
     "browser/net/require_ct_delegate.h",
-    "browser/net_log.cc",
-    "browser/net_log.h",
     "browser/notification.cc",
     "browser/notification.h",
     "browser/notification_delegate.h",
@@ -90,8 +81,6 @@ static_library("brightray") {
     "browser/notification_presenter.h",
     "browser/platform_notification_service.cc",
     "browser/platform_notification_service.h",
-    "browser/url_request_context_getter.cc",
-    "browser/url_request_context_getter.h",
     "browser/views/inspectable_web_contents_view_views.cc",
     "browser/views/inspectable_web_contents_view_views.h",
     "browser/views/views_delegate.cc",
@@ -130,8 +119,6 @@ static_library("brightray") {
     "common/main_delegate_mac.mm",
     "common/platform_util.h",
     "common/platform_util_linux.cc",
-    "common/switches.cc",
-    "common/switches.h",
   ]
   set_sources_assignment_filter(sources_assignment_filter)
 
diff --git a/brightray/browser/browser_client.cc b/brightray/browser/browser_client.cc
index ae1a68fa4776..ff9c8c71dc53 100644
--- a/brightray/browser/browser_client.cc
+++ b/brightray/browser/browser_client.cc
@@ -7,7 +7,6 @@
 #include "base/lazy_instance.h"
 #include "base/no_destructor.h"
 #include "base/path_service.h"
-#include "brightray/browser/browser_context.h"
 #include "brightray/browser/browser_main_parts.h"
 #include "brightray/browser/devtools_manager_delegate.h"
 #include "brightray/browser/media/media_capture_devices_dispatcher.h"
@@ -108,10 +107,6 @@ void BrowserClient::GetAdditionalWebUISchemes(
   additional_schemes->push_back(content::kChromeDevToolsScheme);
 }
 
-NetLog* BrowserClient::GetNetLog() {
-  return &net_log_;
-}
-
 base::FilePath BrowserClient::GetDefaultDownloadDirectory() {
   // ~/Downloads
   base::FilePath path;
diff --git a/brightray/browser/browser_client.h b/brightray/browser/browser_client.h
index 052dd9576896..fea45cfac195 100644
--- a/brightray/browser/browser_client.h
+++ b/brightray/browser/browser_client.h
@@ -9,7 +9,6 @@
 #include <string>
 #include <vector>
 
-#include "brightray/browser/net_log.h"
 #include "content/public/browser/content_browser_client.h"
 
 namespace brightray {
@@ -46,7 +45,6 @@ class BrowserClient : public content::ContentBrowserClient {
       std::vector<std::string>* additional_schemes) override;
   void GetAdditionalWebUISchemes(
       std::vector<std::string>* additional_schemes) override;
-  NetLog* GetNetLog() override;
   base::FilePath GetDefaultDownloadDirectory() override;
   content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override;
   std::string GetApplicationLocale() override;
@@ -60,7 +58,6 @@ class BrowserClient : public content::ContentBrowserClient {
 
  private:
   BrowserMainParts* browser_main_parts_;
-  NetLog net_log_;
 
   std::unique_ptr<PlatformNotificationService> notification_service_;
   std::unique_ptr<NotificationPresenter> notification_presenter_;
diff --git a/brightray/browser/browser_context.cc b/brightray/browser/browser_context.cc
deleted file mode 100644
index 850e3ea841fa..000000000000
--- a/brightray/browser/browser_context.cc
+++ /dev/null
@@ -1,207 +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-CHROMIUM file.
-
-#include "brightray/browser/browser_context.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/files/file_path.h"
-#include "base/path_service.h"
-#include "base/strings/string_util.h"
-#include "base/threading/thread_restrictions.h"
-#include "brightray/browser/brightray_paths.h"
-#include "brightray/browser/browser_client.h"
-#include "brightray/browser/inspectable_web_contents_impl.h"
-#include "brightray/browser/zoom_level_delegate.h"
-#include "brightray/common/application_info.h"
-#include "components/prefs/json_pref_store.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/pref_service.h"
-#include "components/prefs/pref_service_factory.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/storage_partition.h"
-#include "net/base/escape.h"
-
-using content::BrowserThread;
-
-namespace brightray {
-
-namespace {
-
-// Convert string to lower case and escape it.
-std::string MakePartitionName(const std::string& input) {
-  return net::EscapePath(base::ToLowerASCII(input));
-}
-
-}  // namespace
-
-// static
-void BrowserContextDeleter::Destruct(const BrowserContext* browser_context) {
-  browser_context->OnDestruct();
-}
-
-// static
-BrowserContext::BrowserContextMap BrowserContext::browser_context_map_;
-
-// static
-scoped_refptr<BrowserContext> BrowserContext::Get(const std::string& partition,
-                                                  bool in_memory) {
-  PartitionKey key(partition, in_memory);
-  if (browser_context_map_[key].get())
-    return WrapRefCounted(browser_context_map_[key].get());
-
-  return nullptr;
-}
-
-BrowserContext::BrowserContext(const std::string& partition, bool in_memory)
-    : in_memory_(in_memory), weak_factory_(this) {
-  if (!base::PathService::Get(DIR_USER_DATA, &path_)) {
-    base::PathService::Get(DIR_APP_DATA, &path_);
-    path_ = path_.Append(base::FilePath::FromUTF8Unsafe(GetApplicationName()));
-    base::PathService::Override(DIR_USER_DATA, path_);
-  }
-
-  if (!in_memory_ && !partition.empty())
-    path_ = path_.Append(FILE_PATH_LITERAL("Partitions"))
-                .Append(base::FilePath::FromUTF8Unsafe(
-                    MakePartitionName(partition)));
-
-  content::BrowserContext::Initialize(this, path_);
-
-  io_handle_ = new URLRequestContextGetter::Handle(GetWeakPtr());
-
-  browser_context_map_[PartitionKey(partition, in_memory)] = GetWeakPtr();
-}
-
-BrowserContext::~BrowserContext() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  NotifyWillBeDestroyed(this);
-  ShutdownStoragePartitions();
-  io_handle_->ShutdownOnUIThread();
-}
-
-void BrowserContext::OnDestruct() const {
-  if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
-    delete this;
-  } else {
-    BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this);
-  }
-}
-
-void BrowserContext::InitPrefs() {
-  auto prefs_path = GetPath().Append(FILE_PATH_LITERAL("Preferences"));
-  base::ThreadRestrictions::ScopedAllowIO allow_io;
-  PrefServiceFactory prefs_factory;
-  scoped_refptr<JsonPrefStore> pref_store =
-      base::MakeRefCounted<JsonPrefStore>(prefs_path);
-  pref_store->ReadPrefs();  // Synchronous.
-  prefs_factory.set_user_prefs(pref_store);
-
-  auto registry = WrapRefCounted(new PrefRegistrySimple);
-  RegisterInternalPrefs(registry.get());
-  RegisterPrefs(registry.get());
-
-  prefs_ = prefs_factory.Create(registry.get());
-}
-
-void BrowserContext::RegisterInternalPrefs(PrefRegistrySimple* registry) {
-  InspectableWebContentsImpl::RegisterPrefs(registry);
-  MediaDeviceIDSalt::RegisterPrefs(registry);
-  ZoomLevelDelegate::RegisterPrefs(registry);
-}
-
-URLRequestContextGetter* BrowserContext::GetRequestContext() {
-  return static_cast<URLRequestContextGetter*>(
-      GetDefaultStoragePartition(this)->GetURLRequestContext());
-}
-
-net::URLRequestContextGetter* BrowserContext::CreateRequestContext(
-    content::ProtocolHandlerMap* protocol_handlers,
-    content::URLRequestInterceptorScopedVector protocol_interceptors) {
-  return io_handle_
-      ->CreateMainRequestContextGetter(protocol_handlers,
-                                       std::move(protocol_interceptors))
-      .get();
-}
-
-std::string BrowserContext::GetMediaDeviceIDSalt() {
-  if (!media_device_id_salt_.get())
-    media_device_id_salt_.reset(new MediaDeviceIDSalt(prefs_.get()));
-  return media_device_id_salt_->GetSalt();
-}
-
-base::FilePath BrowserContext::GetPath() const {
-  return path_;
-}
-
-std::unique_ptr<content::ZoomLevelDelegate>
-BrowserContext::CreateZoomLevelDelegate(const base::FilePath& partition_path) {
-  if (!IsOffTheRecord()) {
-    return std::make_unique<ZoomLevelDelegate>(prefs(), partition_path);
-  }
-  return std::unique_ptr<content::ZoomLevelDelegate>();
-}
-
-bool BrowserContext::IsOffTheRecord() const {
-  return in_memory_;
-}
-
-content::ResourceContext* BrowserContext::GetResourceContext() {
-  return io_handle_->GetResourceContext();
-}
-
-content::DownloadManagerDelegate* BrowserContext::GetDownloadManagerDelegate() {
-  return nullptr;
-}
-
-content::BrowserPluginGuestManager* BrowserContext::GetGuestManager() {
-  return nullptr;
-}
-
-content::PushMessagingService* BrowserContext::GetPushMessagingService() {
-  return nullptr;
-}
-
-content::SSLHostStateDelegate* BrowserContext::GetSSLHostStateDelegate() {
-  return nullptr;
-}
-
-content::BackgroundFetchDelegate* BrowserContext::GetBackgroundFetchDelegate() {
-  return nullptr;
-}
-
-content::BackgroundSyncController*
-BrowserContext::GetBackgroundSyncController() {
-  return nullptr;
-}
-
-content::BrowsingDataRemoverDelegate*
-BrowserContext::GetBrowsingDataRemoverDelegate() {
-  return nullptr;
-}
-
-net::URLRequestContextGetter*
-BrowserContext::CreateRequestContextForStoragePartition(
-    const base::FilePath& partition_path,
-    bool in_memory,
-    content::ProtocolHandlerMap* protocol_handlers,
-    content::URLRequestInterceptorScopedVector request_interceptors) {
-  NOTREACHED();
-  return nullptr;
-}
-
-net::URLRequestContextGetter* BrowserContext::CreateMediaRequestContext() {
-  return io_handle_->GetMainRequestContextGetter().get();
-}
-
-net::URLRequestContextGetter*
-BrowserContext::CreateMediaRequestContextForStoragePartition(
-    const base::FilePath& partition_path,
-    bool in_memory) {
-  NOTREACHED();
-  return nullptr;
-}
-
-}  // namespace brightray
diff --git a/brightray/browser/browser_context.h b/brightray/browser/browser_context.h
deleted file mode 100644
index 78b7b5044919..000000000000
--- a/brightray/browser/browser_context.h
+++ /dev/null
@@ -1,133 +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-CHROMIUM file.
-
-#ifndef BRIGHTRAY_BROWSER_BROWSER_CONTEXT_H_
-#define BRIGHTRAY_BROWSER_BROWSER_CONTEXT_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "brightray/browser/media/media_device_id_salt.h"
-#include "brightray/browser/url_request_context_getter.h"
-#include "content/public/browser/browser_context.h"
-
-class PrefRegistrySimple;
-class PrefService;
-
-namespace brightray {
-
-class BrowserContext;
-
-struct BrowserContextDeleter {
-  static void Destruct(const BrowserContext* browser_context);
-};
-
-class BrowserContext
-    : public base::RefCountedThreadSafe<BrowserContext, BrowserContextDeleter>,
-      public content::BrowserContext {
- public:
-  // Get the BrowserContext according to its |partition| and |in_memory|,
-  // empty pointer when be returned when there is no matching BrowserContext.
-  static scoped_refptr<BrowserContext> Get(const std::string& partition,
-                                           bool in_memory);
-
-  base::WeakPtr<BrowserContext> GetWeakPtr() {
-    return weak_factory_.GetWeakPtr();
-  }
-
-  // Get the request context, if there is no one, create it.
-  URLRequestContextGetter* GetRequestContext();
-
-  // content::BrowserContext:
-  std::unique_ptr<content::ZoomLevelDelegate> CreateZoomLevelDelegate(
-      const base::FilePath& partition_path) override;
-  bool IsOffTheRecord() const override;
-  content::ResourceContext* GetResourceContext() override;
-  content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
-  content::BrowserPluginGuestManager* GetGuestManager() override;
-  content::PushMessagingService* GetPushMessagingService() override;
-  content::SSLHostStateDelegate* GetSSLHostStateDelegate() override;
-  content::BackgroundFetchDelegate* GetBackgroundFetchDelegate() override;
-  content::BackgroundSyncController* GetBackgroundSyncController() override;
-  content::BrowsingDataRemoverDelegate* GetBrowsingDataRemoverDelegate()
-      override;
-  net::URLRequestContextGetter* CreateRequestContext(
-      content::ProtocolHandlerMap* protocol_handlers,
-      content::URLRequestInterceptorScopedVector request_interceptors) override;
-  net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
-      const base::FilePath& partition_path,
-      bool in_memory,
-      content::ProtocolHandlerMap* protocol_handlers,
-      content::URLRequestInterceptorScopedVector request_interceptors) override;
-  net::URLRequestContextGetter* CreateMediaRequestContext() override;
-  net::URLRequestContextGetter* CreateMediaRequestContextForStoragePartition(
-      const base::FilePath& partition_path,
-      bool in_memory) override;
-  std::string GetMediaDeviceIDSalt() override;
-  base::FilePath GetPath() const override;
-
-  void InitPrefs();
-  PrefService* prefs() { return prefs_.get(); }
-
-  virtual std::string GetUserAgent() const = 0;
-  virtual void OnMainRequestContextCreated(URLRequestContextGetter* getter) {}
-
- protected:
-  BrowserContext(const std::string& partition, bool in_memory);
-  ~BrowserContext() override;
-
-  // Subclasses should override this to register custom preferences.
-  virtual void RegisterPrefs(PrefRegistrySimple* pref_registry) {}
-
- private:
-  friend class base::RefCountedThreadSafe<BrowserContext,
-                                          BrowserContextDeleter>;
-  friend class base::DeleteHelper<BrowserContext>;
-  friend struct BrowserContextDeleter;
-
-  void RegisterInternalPrefs(PrefRegistrySimple* pref_registry);
-  void OnDestruct() const;
-
-  // partition_id => browser_context
-  struct PartitionKey {
-    std::string partition;
-    bool in_memory;
-
-    PartitionKey(const std::string& partition, bool in_memory)
-        : partition(partition), in_memory(in_memory) {}
-
-    bool operator<(const PartitionKey& other) const {
-      if (partition == other.partition)
-        return in_memory < other.in_memory;
-      return partition < other.partition;
-    }
-
-    bool operator==(const PartitionKey& other) const {
-      return (partition == other.partition) && (in_memory == other.in_memory);
-    }
-  };
-  using BrowserContextMap =
-      std::map<PartitionKey, base::WeakPtr<brightray::BrowserContext>>;
-  static BrowserContextMap browser_context_map_;
-
-  base::FilePath path_;
-  bool in_memory_;
-
-  std::unique_ptr<PrefService> prefs_;
-  std::unique_ptr<MediaDeviceIDSalt> media_device_id_salt_;
-  // Self-destructing class responsible for creating URLRequestContextGetter
-  // on the UI thread and deletes itself on the IO thread.
-  URLRequestContextGetter::Handle* io_handle_;
-
-  base::WeakPtrFactory<BrowserContext> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(BrowserContext);
-};
-
-}  // namespace brightray
-
-#endif  // BRIGHTRAY_BROWSER_BROWSER_CONTEXT_H_
diff --git a/brightray/browser/browser_main_parts.cc b/brightray/browser/browser_main_parts.cc
index 3b702c0199a1..62ad62362d4e 100644
--- a/brightray/browser/browser_main_parts.cc
+++ b/brightray/browser/browser_main_parts.cc
@@ -23,7 +23,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "brightray/browser/browser_client.h"
-#include "brightray/browser/browser_context.h"
 #include "brightray/browser/devtools_manager_delegate.h"
 #include "brightray/browser/media/media_capture_devices_dispatcher.h"
 #include "brightray/browser/web_ui_controller_factory.h"
@@ -319,9 +318,6 @@ int BrowserMainParts::PreCreateThreads() {
   BrowserClient::SetApplicationLocale(
       l10n_util::GetApplicationLocale(custom_locale_));
 
-  // Manage global state of net and other IO thread related.
-  io_thread_ = std::make_unique<IOThread>();
-
   return 0;
 }
 
@@ -330,8 +326,6 @@ void BrowserMainParts::PostDestroyThreads() {
   device::BluetoothAdapterFactory::Shutdown();
   bluez::DBusBluezManagerWrapperLinux::Shutdown();
 #endif
-
-  io_thread_.reset();
 }
 
 }  // namespace brightray
diff --git a/brightray/browser/browser_main_parts.h b/brightray/browser/browser_main_parts.h
index cf8e0296585b..f4e345540b67 100644
--- a/brightray/browser/browser_main_parts.h
+++ b/brightray/browser/browser_main_parts.h
@@ -12,7 +12,6 @@
 #include "base/macros.h"
 #include "base/path_service.h"
 #include "brightray/browser/brightray_paths.h"
-#include "brightray/browser/io_thread.h"
 #include "content/public/browser/browser_main_parts.h"
 #include "ui/views/layout/layout_provider.h"
 
@@ -29,8 +28,6 @@ class BrowserMainParts : public content::BrowserMainParts {
   BrowserMainParts();
   ~BrowserMainParts() override;
 
-  IOThread* io_thread() const { return io_thread_.get(); }
-
  protected:
   // content::BrowserMainParts:
   bool ShouldContentCreateFeatureList() override;
@@ -51,8 +48,6 @@ class BrowserMainParts : public content::BrowserMainParts {
   void OverrideAppLogsPath();
 #endif
 
-  std::unique_ptr<IOThread> io_thread_;
-
 #if defined(USE_AURA)
   std::unique_ptr<wm::WMState> wm_state_;
 #endif
diff --git a/brightray/browser/inspectable_web_contents.cc b/brightray/browser/inspectable_web_contents.cc
index ab6d87d6c692..e7c350a3e5c3 100644
--- a/brightray/browser/inspectable_web_contents.cc
+++ b/brightray/browser/inspectable_web_contents.cc
@@ -6,8 +6,9 @@ namespace brightray {
 
 InspectableWebContents* InspectableWebContents::Create(
     content::WebContents* web_contents,
+    PrefService* pref_service,
     bool is_guest) {
-  return new InspectableWebContentsImpl(web_contents, is_guest);
+  return new InspectableWebContentsImpl(web_contents, pref_service, is_guest);
 }
 
 }  // namespace brightray
diff --git a/brightray/browser/inspectable_web_contents.h b/brightray/browser/inspectable_web_contents.h
index 4abaa03c5f9c..f659de1b2fa7 100644
--- a/brightray/browser/inspectable_web_contents.h
+++ b/brightray/browser/inspectable_web_contents.h
@@ -13,6 +13,8 @@ namespace content {
 class DevToolsAgentHost;
 }
 
+class PrefService;
+
 namespace brightray {
 
 class InspectableWebContentsDelegate;
@@ -23,6 +25,7 @@ class InspectableWebContents {
   // The returned InspectableWebContents takes ownership of the passed-in
   // WebContents.
   static InspectableWebContents* Create(content::WebContents* web_contents,
+                                        PrefService* pref_service,
                                         bool is_guest);
 
   virtual ~InspectableWebContents() {}
diff --git a/brightray/browser/inspectable_web_contents_impl.cc b/brightray/browser/inspectable_web_contents_impl.cc
index 0557054428ec..9115513605dc 100644
--- a/brightray/browser/inspectable_web_contents_impl.cc
+++ b/brightray/browser/inspectable_web_contents_impl.cc
@@ -19,7 +19,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "brightray/browser/browser_client.h"
-#include "brightray/browser/browser_context.h"
 #include "brightray/browser/browser_main_parts.h"
 #include "brightray/browser/inspectable_web_contents_delegate.h"
 #include "brightray/browser/inspectable_web_contents_view.h"
@@ -27,13 +26,16 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/host_zoom_map.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_view_host.h"
+#include "content/public/browser/storage_partition.h"
 #include "content/public/common/user_agent.h"
 #include "ipc/ipc_channel.h"
+#include "net/base/io_buffer.h"
 #include "net/http/http_response_headers.h"
 #include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_fetcher_response_writer.h"
@@ -204,13 +206,12 @@ void InspectableWebContentsImpl::RegisterPrefs(PrefRegistrySimple* registry) {
 
 InspectableWebContentsImpl::InspectableWebContentsImpl(
     content::WebContents* web_contents,
+    PrefService* pref_service,
     bool is_guest)
     : frontend_loaded_(false),
       can_dock_(true),
       delegate_(nullptr),
-      pref_service_(
-          static_cast<BrowserContext*>(web_contents->GetBrowserContext())
-              ->prefs()),
+      pref_service_(pref_service),
       web_contents_(web_contents),
       is_guest_(is_guest),
       view_(CreateInspectableContentsView(this)),
@@ -484,13 +485,14 @@ void InspectableWebContentsImpl::LoadNetworkResource(
     return;
   }
 
-  auto* browser_context = static_cast<BrowserContext*>(
-      GetDevToolsWebContents()->GetBrowserContext());
+  auto* browser_context = GetDevToolsWebContents()->GetBrowserContext();
 
   net::URLFetcher* fetcher =
       (net::URLFetcher::Create(gurl, net::URLFetcher::GET, this)).release();
   pending_requests_[fetcher] = callback;
-  fetcher->SetRequestContext(browser_context->GetRequestContext());
+  fetcher->SetRequestContext(
+      content::BrowserContext::GetDefaultStoragePartition(browser_context)
+          ->GetURLRequestContext());
   fetcher->SetExtraRequestHeaders(headers);
   fetcher->SaveResponseWithWriter(
       std::unique_ptr<net::URLFetcherResponseWriter>(
diff --git a/brightray/browser/inspectable_web_contents_impl.h b/brightray/browser/inspectable_web_contents_impl.h
index c2b06e74a7a4..5dca5972e63a 100644
--- a/brightray/browser/inspectable_web_contents_impl.h
+++ b/brightray/browser/inspectable_web_contents_impl.h
@@ -40,7 +40,9 @@ class InspectableWebContentsImpl
  public:
   static void RegisterPrefs(PrefRegistrySimple* pref_registry);
 
-  InspectableWebContentsImpl(content::WebContents* web_contents, bool is_guest);
+  InspectableWebContentsImpl(content::WebContents* web_contents,
+                             PrefService* pref_service,
+                             bool is_guest);
   ~InspectableWebContentsImpl() override;
 
   InspectableWebContentsView* GetView() const override;
diff --git a/brightray/browser/io_thread.cc b/brightray/browser/io_thread.cc
deleted file mode 100644
index 10741b783920..000000000000
--- a/brightray/browser/io_thread.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2017 GitHub, Inc.
-// Use of this source code is governed by the MIT license that can be
-// found in the LICENSE file.
-
-#include "brightray/browser/io_thread.h"
-
-#include "content/public/browser/browser_thread.h"
-#include "net/proxy_resolution/proxy_resolution_service.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_builder.h"
-#include "net/url_request/url_request_context_getter.h"
-
-#if defined(USE_NSS_CERTS)
-#include "net/cert_net/nss_ocsp.h"
-#endif
-
-using content::BrowserThread;
-
-namespace brightray {
-
-IOThread::IOThread() {
-  BrowserThread::SetIOThreadDelegate(this);
-}
-
-IOThread::~IOThread() {
-  BrowserThread::SetIOThreadDelegate(nullptr);
-}
-
-void IOThread::Init() {
-  net::URLRequestContextBuilder builder;
-  builder.set_proxy_resolution_service(
-      net::ProxyResolutionService::CreateDirect());
-  url_request_context_ = builder.Build();
-  url_request_context_getter_ = new net::TrivialURLRequestContextGetter(
-      url_request_context_.get(), base::ThreadTaskRunnerHandle::Get());
-  url_request_context_getter_->AddRef();
-
-#if defined(USE_NSS_CERTS)
-  net::SetURLRequestContextForNSSHttpIO(url_request_context_.get());
-#endif
-}
-
-void IOThread::CleanUp() {
-#if defined(USE_NSS_CERTS)
-  net::SetURLRequestContextForNSSHttpIO(nullptr);
-#endif
-  // Explicitly release before the IO thread gets destroyed.
-  url_request_context_getter_->Release();
-  url_request_context_.reset();
-}
-
-}  // namespace brightray
diff --git a/brightray/browser/net_log.cc b/brightray/browser/net_log.cc
deleted file mode 100644
index fb443ea0b72b..000000000000
--- a/brightray/browser/net_log.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2015 GitHub, Inc.
-// Use of this source code is governed by the MIT license that can be
-// found in the LICENSE file.
-
-#include "brightray/browser/net_log.h"
-
-#include <utility>
-
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/values.h"
-#include "net/log/file_net_log_observer.h"
-#include "net/log/net_log_util.h"
-#include "services/network/public/cpp/network_switches.h"
-
-namespace brightray {
-
-namespace {
-
-std::unique_ptr<base::DictionaryValue> GetConstants() {
-  std::unique_ptr<base::DictionaryValue> constants = net::GetNetConstants();
-
-  // Adding client information to constants dictionary.
-  auto client_info = std::make_unique<base::DictionaryValue>();
-  client_info->SetString(
-      "command_line",
-      base::CommandLine::ForCurrentProcess()->GetCommandLineString());
-
-  constants->Set("clientInfo", std::move(client_info));
-  return constants;
-}
-
-}  // namespace
-
-NetLog::NetLog() {}
-
-NetLog::~NetLog() {
-  StopDynamicLogging();
-  StopLogging();
-}
-
-void NetLog::StartLogging() {
-  auto* command_line = base::CommandLine::ForCurrentProcess();
-  if (!command_line->HasSwitch(network::switches::kLogNetLog))
-    return;
-
-  base::FilePath log_path =
-      command_line->GetSwitchValuePath(network::switches::kLogNetLog);
-  if (log_path.empty())
-    return;
-
-  std::unique_ptr<base::Value> constants(GetConstants());  // Net constants
-  net::NetLogCaptureMode capture_mode = net::NetLogCaptureMode::Default();
-
-  file_net_log_observer_ =
-      net::FileNetLogObserver::CreateUnbounded(log_path, std::move(constants));
-  file_net_log_observer_->StartObserving(this, capture_mode);
-}
-
-void NetLog::StopLogging() {
-  if (!file_net_log_observer_)
-    return;
-
-  file_net_log_observer_->StopObserving(nullptr, base::OnceClosure());
-  file_net_log_observer_.reset();
-}
-
-void NetLog::StartDynamicLogging(const base::FilePath& log_path) {
-  if (dynamic_file_net_log_observer_ || log_path.empty())
-    return;
-
-  dynamic_file_net_log_path_ = log_path;
-
-  std::unique_ptr<base::Value> constants(GetConstants());  // Net constants
-  net::NetLogCaptureMode capture_mode = net::NetLogCaptureMode::Default();
-
-  dynamic_file_net_log_observer_ = net::FileNetLogObserver::CreateUnbounded(
-      dynamic_file_net_log_path_, std::move(constants));
-  dynamic_file_net_log_observer_->StartObserving(this, capture_mode);
-}
-
-bool NetLog::IsDynamicLogging() {
-  return !!dynamic_file_net_log_observer_;
-}
-
-base::FilePath NetLog::GetDynamicLoggingPath() {
-  return dynamic_file_net_log_path_;
-}
-
-void NetLog::StopDynamicLogging(base::OnceClosure callback) {
-  if (!dynamic_file_net_log_observer_) {
-    if (callback)
-      std::move(callback).Run();
-    return;
-  }
-
-  dynamic_file_net_log_observer_->StopObserving(nullptr, std::move(callback));
-  dynamic_file_net_log_observer_.reset();
-
-  dynamic_file_net_log_path_ = base::FilePath();
-}
-
-}  // namespace brightray
diff --git a/brightray/browser/net_log.h b/brightray/browser/net_log.h
deleted file mode 100644
index 0b95ed4f2bdd..000000000000
--- a/brightray/browser/net_log.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2015 GitHub, Inc.
-// Use of this source code is governed by the MIT license that can be
-// found in the LICENSE file.
-
-#ifndef BRIGHTRAY_BROWSER_NET_LOG_H_
-#define BRIGHTRAY_BROWSER_NET_LOG_H_
-
-#include <memory>
-
-#include "base/callback.h"
-#include "base/files/file_path.h"
-#include "net/log/net_log.h"
-
-namespace net {
-class FileNetLogObserver;
-}
-
-namespace brightray {
-
-class NetLog : public net::NetLog {
- public:
-  NetLog();
-  ~NetLog() override;
-
-  void StartLogging();
-  void StopLogging();
-
-  void StartDynamicLogging(const base::FilePath& path);
-  bool IsDynamicLogging();
-  base::FilePath GetDynamicLoggingPath();
-  void StopDynamicLogging(base::OnceClosure callback = base::OnceClosure());
-
- private:
-  // This observer handles writing NetLogs.
-  std::unique_ptr<net::FileNetLogObserver> file_net_log_observer_;
-  std::unique_ptr<net::FileNetLogObserver> dynamic_file_net_log_observer_;
-  base::FilePath dynamic_file_net_log_path_;
-
-  DISALLOW_COPY_AND_ASSIGN(NetLog);
-};
-
-}  // namespace brightray
-
-#endif  // BRIGHTRAY_BROWSER_NET_LOG_H_
diff --git a/brightray/browser/url_request_context_getter.cc b/brightray/browser/url_request_context_getter.cc
deleted file mode 100644
index 76167f747d8e..000000000000
--- a/brightray/browser/url_request_context_getter.cc
+++ /dev/null
@@ -1,459 +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-CHROMIUM file.
-
-#include "brightray/browser/url_request_context_getter.h"
-
-#include <algorithm>
-#include <memory>
-#include <utility>
-
-#include "base/command_line.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/task_scheduler/post_task.h"
-#include "brightray/browser/browser_client.h"
-#include "brightray/browser/browser_context.h"
-#include "brightray/browser/net/require_ct_delegate.h"
-#include "brightray/browser/net_log.h"
-#include "brightray/common/switches.h"
-#include "components/certificate_transparency/ct_known_logs.h"
-#include "components/network_session_configurator/common/network_switches.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/cookie_store_factory.h"
-#include "content/public/browser/devtools_network_transaction_factory.h"
-#include "content/public/browser/resource_context.h"
-#include "net/base/host_mapping_rules.h"
-#include "net/cert/cert_verifier.h"
-#include "net/cert/ct_log_verifier.h"
-#include "net/cert/ct_policy_enforcer.h"
-#include "net/cert/multi_log_ct_verifier.h"
-#include "net/cookies/cookie_monster.h"
-#include "net/cookies/cookie_store.h"
-#include "net/dns/mapped_host_resolver.h"
-#include "net/extras/sqlite/sqlite_channel_id_store.h"
-#include "net/http/http_auth_filter.h"
-#include "net/http/http_auth_handler_factory.h"
-#include "net/http/http_auth_preferences.h"
-#include "net/http/http_server_properties_impl.h"
-#include "net/log/net_log.h"
-#include "net/proxy_resolution/dhcp_pac_file_fetcher_factory.h"
-#include "net/proxy_resolution/pac_file_fetcher_impl.h"
-#include "net/proxy_resolution/proxy_config.h"
-#include "net/proxy_resolution/proxy_config_service.h"
-#include "net/proxy_resolution/proxy_config_with_annotation.h"
-#include "net/proxy_resolution/proxy_resolution_service.h"
-#include "net/ssl/channel_id_service.h"
-#include "net/ssl/default_channel_id_store.h"
-#include "net/ssl/ssl_config_service_defaults.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "net/url_request/data_protocol_handler.h"
-#include "net/url_request/file_protocol_handler.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_builder.h"
-#include "net/url_request/url_request_context_storage.h"
-#include "net/url_request/url_request_intercepting_job_factory.h"
-#include "net/url_request/url_request_job_factory_impl.h"
-#include "services/network/public/cpp/network_switches.h"
-#include "storage/browser/quota/special_storage_policy.h"
-#include "url/url_constants.h"
-
-using content::BrowserThread;
-
-namespace {
-
-std::vector<scoped_refptr<const net::CTLogVerifier>>
-CreateLogVerifiersForKnownLogs() {
-  std::vector<scoped_refptr<const net::CTLogVerifier>> verifiers;
-
-  for (const auto& log : certificate_transparency::GetKnownLogs()) {
-    scoped_refptr<const net::CTLogVerifier> log_verifier =
-        net::CTLogVerifier::Create(
-            base::StringPiece(log.log_key, log.log_key_length), log.log_name,
-            log.log_dns_domain);
-    // Make sure no null logs enter verifiers. Parsing of all statically
-    // configured logs should always succeed, unless there has been binary or
-    // memory corruption.
-    CHECK(log_verifier);
-    verifiers.push_back(std::move(log_verifier));
-  }
-
-  return verifiers;
-}
-
-}  // namespace
-
-namespace brightray {
-
-class ResourceContext : public content::ResourceContext {
- public:
-  ResourceContext() = default;
-  ~ResourceContext() override = default;
-
-  net::HostResolver* GetHostResolver() override {
-    if (request_context_)
-      return request_context_->host_resolver();
-    return nullptr;
-  }
-
-  net::URLRequestContext* GetRequestContext() override {
-    return request_context_;
-  }
-
- private:
-  friend class URLRequestContextGetter;
-
-  net::URLRequestContext* request_context_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(ResourceContext);
-};
-
-URLRequestContextGetter::Handle::Handle(
-    base::WeakPtr<BrowserContext> browser_context)
-    : resource_context_(new ResourceContext),
-      browser_context_(browser_context),
-      initialized_(false) {}
-
-URLRequestContextGetter::Handle::~Handle() {}
-
-content::ResourceContext* URLRequestContextGetter::Handle::GetResourceContext()
-    const {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  LazyInitialize();
-  return resource_context_.get();
-}
-
-scoped_refptr<URLRequestContextGetter>
-URLRequestContextGetter::Handle::CreateMainRequestContextGetter(
-    content::ProtocolHandlerMap* protocol_handlers,
-    content::URLRequestInterceptorScopedVector protocol_interceptors) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  DCHECK(!main_request_context_getter_.get());
-  main_request_context_getter_ = new URLRequestContextGetter(
-      BrowserClient::Get()->GetNetLog(), resource_context_.get(),
-      browser_context_->IsOffTheRecord(), browser_context_->GetUserAgent(),
-      browser_context_->GetPath(), protocol_handlers,
-      std::move(protocol_interceptors));
-  browser_context_->OnMainRequestContextCreated(
-      main_request_context_getter_.get());
-  return main_request_context_getter_;
-}
-
-scoped_refptr<URLRequestContextGetter>
-URLRequestContextGetter::Handle::GetMainRequestContextGetter() const {
-  return main_request_context_getter_;
-}
-
-void URLRequestContextGetter::Handle::LazyInitialize() const {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (initialized_)
-    return;
-
-  initialized_ = true;
-  content::BrowserContext::EnsureResourceContextInitialized(
-      browser_context_.get());
-}
-
-void URLRequestContextGetter::Handle::ShutdownOnUIThread() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (main_request_context_getter_.get()) {
-    if (BrowserThread::IsThreadInitialized(BrowserThread::IO)) {
-      BrowserThread::PostTask(
-          BrowserThread::IO, FROM_HERE,
-          base::BindOnce(&URLRequestContextGetter::NotifyContextShuttingDown,
-                         base::RetainedRef(main_request_context_getter_),
-                         std::move(resource_context_)));
-    }
-  }
-
-  if (!BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this))
-    delete this;
-}
-
-URLRequestContextGetter::URLRequestContextGetter(
-    NetLog* net_log,
-    ResourceContext* resource_context,
-    bool in_memory,
-    const std::string& user_agent,
-    const base::FilePath& base_path,
-    content::ProtocolHandlerMap* protocol_handlers,
-    content::URLRequestInterceptorScopedVector protocol_interceptors)
-    : job_factory_(nullptr),
-      delegate_(nullptr),
-      net_log_(net_log),
-      resource_context_(resource_context),
-      protocol_interceptors_(std::move(protocol_interceptors)),
-      base_path_(base_path),
-      in_memory_(in_memory),
-      user_agent_(user_agent),
-      context_shutting_down_(false) {
-  // Must first be created on the UI thread.
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  if (protocol_handlers)
-    std::swap(protocol_handlers_, *protocol_handlers);
-
-  // We must create the proxy config service on the UI loop on Linux because it
-  // must synchronously run on the glib message loop. This will be passed to
-  // the URLRequestContextStorage on the IO thread in GetURLRequestContext().
-  proxy_config_service_ =
-      net::ProxyResolutionService::CreateSystemProxyConfigService(
-          BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
-}
-
-URLRequestContextGetter::~URLRequestContextGetter() {}
-
-void URLRequestContextGetter::NotifyContextShuttingDown(
-    std::unique_ptr<ResourceContext> resource_context) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  context_shutting_down_ = true;
-  cookie_change_sub_.reset();
-  resource_context.reset();
-  net::URLRequestContextGetter::NotifyContextShuttingDown();
-  url_request_context_.reset();
-  storage_.reset();
-  http_network_session_.reset();
-  http_auth_preferences_.reset();
-  host_mapping_rules_.reset();
-  ct_delegate_.reset();
-}
-
-net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  if (context_shutting_down_)
-    return nullptr;
-
-  if (!url_request_context_.get()) {
-    ct_delegate_.reset(new RequireCTDelegate);
-    auto& command_line = *base::CommandLine::ForCurrentProcess();
-    url_request_context_.reset(new net::URLRequestContext);
-
-    // --log-net-log
-    if (net_log_) {
-      net_log_->StartLogging();
-      url_request_context_->set_net_log(net_log_);
-    }
-
-    storage_.reset(
-        new net::URLRequestContextStorage(url_request_context_.get()));
-
-    storage_->set_network_delegate(delegate_->CreateNetworkDelegate());
-
-    std::unique_ptr<net::CookieStore> cookie_store;
-    scoped_refptr<net::SQLiteChannelIDStore> channel_id_db;
-    // Create a single task runner to use with the CookieStore and
-    // ChannelIDStore.
-    scoped_refptr<base::SequencedTaskRunner> cookie_background_task_runner =
-        base::CreateSequencedTaskRunnerWithTraits(
-            {base::MayBlock(), base::TaskPriority::BACKGROUND,
-             base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
-    auto cookie_path = in_memory_
-                           ? base::FilePath()
-                           : base_path_.Append(FILE_PATH_LITERAL("Cookies"));
-    if (!in_memory_) {
-      channel_id_db = new net::SQLiteChannelIDStore(
-          base_path_.Append(FILE_PATH_LITERAL("Origin Bound Certs")),
-          cookie_background_task_runner);
-    }
-    std::unique_ptr<net::ChannelIDService> channel_id_service(
-        new net::ChannelIDService(
-            new net::DefaultChannelIDStore(channel_id_db.get())));
-    content::CookieStoreConfig cookie_config(cookie_path, false, false,
-                                             nullptr);
-    cookie_config.channel_id_service = channel_id_service.get();
-    cookie_config.background_task_runner = cookie_background_task_runner;
-    cookie_store = content::CreateCookieStore(cookie_config);
-    cookie_store->SetChannelIDServiceID(channel_id_service->GetUniqueID());
-
-    // Set custom schemes that can accept cookies.
-    net::CookieMonster* cookie_monster =
-        static_cast<net::CookieMonster*>(cookie_store.get());
-    std::vector<std::string> cookie_schemes({"http", "https", "ws", "wss"});
-    delegate_->GetCookieableSchemes(&cookie_schemes);
-    cookie_monster->SetCookieableSchemes(cookie_schemes);
-    // Cookie store will outlive notifier by order of declaration
-    // in the header.
-    cookie_change_sub_ =
-        cookie_store->GetChangeDispatcher().AddCallbackForAllChanges(
-            base::Bind(&URLRequestContextGetter::OnCookieChanged,
-                       base::RetainedRef(this)));
-    storage_->set_cookie_store(std::move(cookie_store));
-    storage_->set_channel_id_service(std::move(channel_id_service));
-
-    storage_->set_http_user_agent_settings(
-        base::WrapUnique(new net::StaticHttpUserAgentSettings(
-            net::HttpUtil::GenerateAcceptLanguageHeader(
-                BrowserClient::Get()->GetApplicationLocale()),
-            user_agent_)));
-
-    std::unique_ptr<net::HostResolver> host_resolver(
-        net::HostResolver::CreateDefaultResolver(nullptr));
-
-    // --host-resolver-rules
-    if (command_line.HasSwitch(network::switches::kHostResolverRules)) {
-      std::unique_ptr<net::MappedHostResolver> remapped_resolver(
-          new net::MappedHostResolver(std::move(host_resolver)));
-      remapped_resolver->SetRulesFromString(command_line.GetSwitchValueASCII(
-          network::switches::kHostResolverRules));
-      host_resolver = std::move(remapped_resolver);
-    }
-
-    // --proxy-server
-    if (command_line.HasSwitch(switches::kNoProxyServer)) {
-      storage_->set_proxy_resolution_service(
-          net::ProxyResolutionService::CreateDirect());
-    } else if (command_line.HasSwitch(switches::kProxyServer)) {
-      net::ProxyConfig proxy_config;
-      proxy_config.proxy_rules().ParseFromString(
-          command_line.GetSwitchValueASCII(switches::kProxyServer));
-      proxy_config.proxy_rules().bypass_rules.ParseFromString(
-          command_line.GetSwitchValueASCII(switches::kProxyBypassList));
-      storage_->set_proxy_resolution_service(
-          net::ProxyResolutionService::CreateFixed(
-              net::ProxyConfigWithAnnotation(proxy_config,
-                                             NO_TRAFFIC_ANNOTATION_YET)));
-    } else if (command_line.HasSwitch(switches::kProxyPacUrl)) {
-      auto proxy_config = net::ProxyConfig::CreateFromCustomPacURL(
-          GURL(command_line.GetSwitchValueASCII(switches::kProxyPacUrl)));
-      proxy_config.set_pac_mandatory(true);
-      storage_->set_proxy_resolution_service(
-          net::ProxyResolutionService::CreateFixed(
-              net::ProxyConfigWithAnnotation(proxy_config,
-                                             NO_TRAFFIC_ANNOTATION_YET)));
-    } else {
-      storage_->set_proxy_resolution_service(
-          net::ProxyResolutionService::CreateUsingSystemProxyResolver(
-              std::move(proxy_config_service_), net_log_));
-    }
-
-    std::vector<std::string> schemes;
-    schemes.push_back(std::string("basic"));
-    schemes.push_back(std::string("digest"));
-    schemes.push_back(std::string("ntlm"));
-    schemes.push_back(std::string("negotiate"));
-#if defined(OS_POSIX)
-    http_auth_preferences_.reset(
-        new net::HttpAuthPreferences(schemes, std::string()));
-#else
-    http_auth_preferences_.reset(new net::HttpAuthPreferences(schemes));
-#endif
-
-    // --auth-server-whitelist
-    if (command_line.HasSwitch(switches::kAuthServerWhitelist)) {
-      http_auth_preferences_->SetServerWhitelist(
-          command_line.GetSwitchValueASCII(switches::kAuthServerWhitelist));
-    }
-
-    // --auth-negotiate-delegate-whitelist
-    if (command_line.HasSwitch(switches::kAuthNegotiateDelegateWhitelist)) {
-      http_auth_preferences_->SetDelegateWhitelist(
-          command_line.GetSwitchValueASCII(
-              switches::kAuthNegotiateDelegateWhitelist));
-    }
-
-    auto auth_handler_factory = net::HttpAuthHandlerRegistryFactory::Create(
-        http_auth_preferences_.get(), host_resolver.get());
-
-    std::unique_ptr<net::TransportSecurityState> transport_security_state =
-        base::WrapUnique(new net::TransportSecurityState);
-    transport_security_state->SetRequireCTDelegate(ct_delegate_.get());
-    storage_->set_transport_security_state(std::move(transport_security_state));
-    storage_->set_cert_verifier(
-        delegate_->CreateCertVerifier(ct_delegate_.get()));
-    storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults());
-    storage_->set_http_auth_handler_factory(std::move(auth_handler_factory));
-    std::unique_ptr<net::HttpServerProperties> server_properties(
-        new net::HttpServerPropertiesImpl);
-    storage_->set_http_server_properties(std::move(server_properties));
-
-    // FIXME(jeremy): decide what to do about certificate transparency.
-    std::unique_ptr<net::MultiLogCTVerifier> ct_verifier =
-        std::make_unique<net::MultiLogCTVerifier>();
-    ct_verifier->AddLogs(CreateLogVerifiersForKnownLogs());
-    storage_->set_cert_transparency_verifier(std::move(ct_verifier));
-    storage_->set_ct_policy_enforcer(
-        std::make_unique<net::DefaultCTPolicyEnforcer>());
-
-    net::HttpNetworkSession::Params network_session_params;
-    network_session_params.ignore_certificate_errors = false;
-
-    // --disable-http2
-    if (command_line.HasSwitch(switches::kDisableHttp2))
-      network_session_params.enable_http2 = false;
-
-    // --ignore-certificate-errors
-    if (command_line.HasSwitch(::switches::kIgnoreCertificateErrors))
-      network_session_params.ignore_certificate_errors = true;
-
-    // --host-rules
-    if (command_line.HasSwitch(switches::kHostRules)) {
-      host_mapping_rules_.reset(new net::HostMappingRules);
-      host_mapping_rules_->SetRulesFromString(
-          command_line.GetSwitchValueASCII(switches::kHostRules));
-      network_session_params.host_mapping_rules = *host_mapping_rules_.get();
-    }
-
-    // Give |storage_| ownership at the end in case it's |mapped_host_resolver|.
-    storage_->set_host_resolver(std::move(host_resolver));
-
-    net::HttpNetworkSession::Context network_session_context;
-    net::URLRequestContextBuilder::SetHttpNetworkSessionComponents(
-        url_request_context_.get(), &network_session_context);
-    http_network_session_.reset(new net::HttpNetworkSession(
-        network_session_params, network_session_context));
-
-    std::unique_ptr<net::HttpCache::BackendFactory> backend;
-    if (in_memory_) {
-      backend = net::HttpCache::DefaultBackend::InMemory(0);
-    } else {
-      backend.reset(delegate_->CreateHttpCacheBackendFactory(base_path_));
-    }
-
-    storage_->set_http_transaction_factory(std::make_unique<net::HttpCache>(
-        content::CreateDevToolsNetworkTransactionFactory(
-            http_network_session_.get()),
-        std::move(backend), false));
-
-    std::unique_ptr<net::URLRequestJobFactory> job_factory =
-        delegate_->CreateURLRequestJobFactory(url_request_context_.get(),
-                                              &protocol_handlers_);
-    job_factory_ = job_factory.get();
-
-    // Set up interceptors in the reverse order.
-    std::unique_ptr<net::URLRequestJobFactory> top_job_factory =
-        std::move(job_factory);
-    if (!protocol_interceptors_.empty()) {
-      for (auto it = protocol_interceptors_.rbegin();
-           it != protocol_interceptors_.rend(); ++it) {
-        top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
-            std::move(top_job_factory), std::move(*it)));
-      }
-      protocol_interceptors_.clear();
-    }
-
-    storage_->set_job_factory(std::move(top_job_factory));
-  }
-
-  if (resource_context_)
-    resource_context_->request_context_ = url_request_context_.get();
-
-  return url_request_context_.get();
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-URLRequestContextGetter::GetNetworkTaskRunner() const {
-  return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
-}
-
-void URLRequestContextGetter::OnCookieChanged(
-    const net::CanonicalCookie& cookie,
-    net::CookieChangeCause cause) const {
-  if (delegate_)
-    delegate_->OnCookieChanged(cookie, cause);
-}
-
-}  // namespace brightray
diff --git a/brightray/browser/url_request_context_getter.h b/brightray/browser/url_request_context_getter.h
deleted file mode 100644
index ec875a25d853..000000000000
--- a/brightray/browser/url_request_context_getter.h
+++ /dev/null
@@ -1,150 +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-CHROMIUM file.
-
-#ifndef BRIGHTRAY_BROWSER_URL_REQUEST_CONTEXT_GETTER_H_
-#define BRIGHTRAY_BROWSER_URL_REQUEST_CONTEXT_GETTER_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/files/file_path.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/content_browser_client.h"
-#include "net/cookies/cookie_change_dispatcher.h"
-#include "net/http/http_cache.h"
-#include "net/http/transport_security_state.h"
-#include "net/http/url_security_manager.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_getter.h"
-
-#if DCHECK_IS_ON()
-#include "base/debug/leak_tracker.h"
-#endif
-
-namespace net {
-class HostMappingRules;
-class HostResolver;
-class HttpAuthPreferences;
-class NetworkDelegate;
-class ProxyConfigService;
-class URLRequestContextStorage;
-class URLRequestJobFactory;
-}  // namespace net
-
-namespace brightray {
-
-class BrowserContext;
-class ResourceContext;
-class RequireCTDelegate;
-class NetLog;
-
-class URLRequestContextGetter : public net::URLRequestContextGetter {
- public:
-  class Delegate {
-   public:
-    Delegate() {}
-    virtual ~Delegate() {}
-
-    virtual std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() = 0;
-    virtual std::unique_ptr<net::URLRequestJobFactory>
-    CreateURLRequestJobFactory(
-        net::URLRequestContext* url_request_context,
-        content::ProtocolHandlerMap* protocol_handlers) = 0;
-    virtual net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
-        const base::FilePath& base_path) = 0;
-    virtual std::unique_ptr<net::CertVerifier> CreateCertVerifier(
-        RequireCTDelegate* ct_delegate) = 0;
-    virtual void GetCookieableSchemes(
-        std::vector<std::string>* cookie_schemes) {}
-    virtual void OnCookieChanged(const net::CanonicalCookie& cookie,
-                                 net::CookieChangeCause cause) {}
-  };
-
-  URLRequestContextGetter(
-      NetLog* net_log,
-      ResourceContext* resource_context,
-      bool in_memory,
-      const std::string& user_agent,
-      const base::FilePath& base_path,
-      content::ProtocolHandlerMap* protocol_handlers,
-      content::URLRequestInterceptorScopedVector protocol_interceptors);
-
-  // net::URLRequestContextGetter:
-  net::URLRequestContext* GetURLRequestContext() override;
-  scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
-      const override;
-
-  net::URLRequestJobFactory* job_factory() const { return job_factory_; }
-  void set_delegate(Delegate* delegate) { delegate_ = delegate; }
-
-  // Discard reference to URLRequestContext and inform observers to
-  // shutdown. Must be called only on IO thread.
-  void NotifyContextShuttingDown(std::unique_ptr<ResourceContext>);
-
- private:
-  friend class BrowserContext;
-
-  // Responsible for destroying URLRequestContextGetter
-  // on the IO thread.
-  class Handle {
-   public:
-    explicit Handle(base::WeakPtr<BrowserContext> browser_context);
-    ~Handle();
-
-    scoped_refptr<URLRequestContextGetter> CreateMainRequestContextGetter(
-        content::ProtocolHandlerMap* protocol_handlers,
-        content::URLRequestInterceptorScopedVector protocol_interceptors);
-    content::ResourceContext* GetResourceContext() const;
-    scoped_refptr<URLRequestContextGetter> GetMainRequestContextGetter() const;
-
-    void ShutdownOnUIThread();
-
-   private:
-    void LazyInitialize() const;
-
-    scoped_refptr<URLRequestContextGetter> main_request_context_getter_;
-    std::unique_ptr<ResourceContext> resource_context_;
-    base::WeakPtr<BrowserContext> browser_context_;
-    mutable bool initialized_;
-
-    DISALLOW_COPY_AND_ASSIGN(Handle);
-  };
-
-  ~URLRequestContextGetter() override;
-
-  // net::CookieChangeDispatcher::CookieChangedCallback implementation.
-  void OnCookieChanged(const net::CanonicalCookie& cookie,
-                       net::CookieChangeCause cause) const;
-
-#if DCHECK_IS_ON()
-  base::debug::LeakTracker<URLRequestContextGetter> leak_tracker_;
-#endif
-
-  std::unique_ptr<RequireCTDelegate> ct_delegate_;
-  std::unique_ptr<net::ProxyConfigService> proxy_config_service_;
-  std::unique_ptr<net::URLRequestContextStorage> storage_;
-  std::unique_ptr<net::URLRequestContext> url_request_context_;
-  std::unique_ptr<net::HostMappingRules> host_mapping_rules_;
-  std::unique_ptr<net::HttpAuthPreferences> http_auth_preferences_;
-  std::unique_ptr<net::HttpNetworkSession> http_network_session_;
-  std::unique_ptr<net::CookieChangeSubscription> cookie_change_sub_;
-
-  net::URLRequestJobFactory* job_factory_;
-  Delegate* delegate_;
-  NetLog* net_log_;
-  ResourceContext* resource_context_;
-  content::ProtocolHandlerMap protocol_handlers_;
-  content::URLRequestInterceptorScopedVector protocol_interceptors_;
-  base::FilePath base_path_;
-  bool in_memory_;
-  std::string user_agent_;
-  bool context_shutting_down_;
-
-  DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter);
-};
-
-}  // namespace brightray
-
-#endif  // BRIGHTRAY_BROWSER_URL_REQUEST_CONTEXT_GETTER_H_
diff --git a/brightray/common/switches.cc b/brightray/common/switches.cc
deleted file mode 100644
index ef7a138375bd..000000000000
--- a/brightray/common/switches.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2016 GitHub, Inc.
-// Use of this source code is governed by the MIT license that can be
-// found in the LICENSE file.
-
-#include "brightray/common/switches.h"
-
-namespace brightray {
-
-namespace switches {
-
-// Comma-separated list of rules that control how hostnames are mapped.
-//
-// For example:
-//    "MAP * 127.0.0.1" --> Forces all hostnames to be mapped to 127.0.0.1
-//    "MAP *.google.com proxy" --> Forces all google.com subdomains to be
-//                                 resolved to "proxy".
-//    "MAP test.com [::1]:77 --> Forces "test.com" to resolve to IPv6 loopback.
-//                               Will also force the port of the resulting
-//                               socket address to be 77.
-//    "MAP * baz, EXCLUDE www.google.com" --> Remaps everything to "baz",
-//                                            except for "www.google.com".
-//
-// These mappings apply to the endpoint host in a net::URLRequest (the TCP
-// connect and host resolver in a direct connection, and the CONNECT in an http
-// proxy connection, and the endpoint host in a SOCKS proxy connection).
-const char kHostRules[] = "host-rules";
-
-// Don't use a proxy server, always make direct connections. Overrides any
-// other proxy server flags that are passed.
-const char kNoProxyServer[] = "no-proxy-server";
-
-// Uses a specified proxy server, overrides system settings. This switch only
-// affects HTTP and HTTPS requests.
-const char kProxyServer[] = "proxy-server";
-
-// Bypass specified proxy for the given semi-colon-separated list of hosts. This
-// flag has an effect only when --proxy-server is set.
-const char kProxyBypassList[] = "proxy-bypass-list";
-
-// Uses the pac script at the given URL.
-const char kProxyPacUrl[] = "proxy-pac-url";
-
-// Disable HTTP/2 and SPDY/3.1 protocols.
-const char kDisableHttp2[] = "disable-http2";
-
-// Whitelist containing servers for which Integrated Authentication is enabled.
-const char kAuthServerWhitelist[] = "auth-server-whitelist";
-
-// Whitelist containing servers for which Kerberos delegation is allowed.
-const char kAuthNegotiateDelegateWhitelist[] =
-    "auth-negotiate-delegate-whitelist";
-
-}  // namespace switches
-
-}  // namespace brightray
diff --git a/brightray/common/switches.h b/brightray/common/switches.h
deleted file mode 100644
index 3af00813830f..000000000000
--- a/brightray/common/switches.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2016 GitHub, Inc.
-// Use of this source code is governed by the MIT license that can be
-// found in the LICENSE file.
-
-#ifndef BRIGHTRAY_COMMON_SWITCHES_H_
-#define BRIGHTRAY_COMMON_SWITCHES_H_
-
-namespace brightray {
-
-namespace switches {
-
-extern const char kHostRules[];
-extern const char kNoProxyServer[];
-extern const char kProxyServer[];
-extern const char kProxyBypassList[];
-extern const char kProxyPacUrl[];
-extern const char kDisableHttp2[];
-extern const char kAuthServerWhitelist[];
-extern const char kAuthNegotiateDelegateWhitelist[];
-
-}  // namespace switches
-
-}  // namespace brightray
-
-#endif  // BRIGHTRAY_COMMON_SWITCHES_H_
diff --git a/chromium_src/BUILD.gn b/chromium_src/BUILD.gn
index 9edc1f79b947..8601f7a2f06a 100644
--- a/chromium_src/BUILD.gn
+++ b/chromium_src/BUILD.gn
@@ -9,10 +9,20 @@ import("//electron/buildflags/buildflags.gni")
 source_set("chrome") {
   visibility = [ "//electron:electron_lib" ]
   sources = [
+    "//chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc",
+    "//chrome/browser/net/chrome_mojo_proxy_resolver_factory.h",
+    "//chrome/browser/net/chrome_net_log_helper.cc",
+    "//chrome/browser/net/chrome_net_log_helper.h",
+    "//chrome/browser/net/proxy_config_monitor.cc",
+    "//chrome/browser/net/proxy_config_monitor.h",
+    "//chrome/browser/net/proxy_service_factory.cc",
+    "//chrome/browser/net/proxy_service_factory.h",
     "//chrome/browser/ssl/security_state_tab_helper.cc",
     "//chrome/browser/ssl/security_state_tab_helper.h",
     "//chrome/common/chrome_constants.cc",
     "//chrome/common/chrome_constants.h",
+    "//chrome/common/chrome_switches.cc",
+    "//chrome/common/chrome_switches.h",
     "//chrome/common/secure_origin_whitelist.cc",
     "//chrome/common/secure_origin_whitelist.h",
   ]
@@ -21,6 +31,7 @@ source_set("chrome") {
   ]
   deps = [
     "//chrome/common:constants",
+    "//components/proxy_config",
     "//components/security_state/content",
   ]
 
diff --git a/docs/api/net-log.md b/docs/api/net-log.md
index dda984fead92..fb6dd3e0b039 100644
--- a/docs/api/net-log.md
+++ b/docs/api/net-log.md
@@ -1,21 +1,26 @@
 # netLog
 
-> Logging network events.
+> Logging network events for a session.
 
 Process: [Main](../glossary.md#main-process)
 
 ```javascript
 const { netLog } = require('electron')
-console.log('Start recording net-logs')
-netLog.startLogging('/path/to/net-log')
-// After some network events
-netLog.stopLogging(path => {
-  console.log('Net-logs written to', path)
+
+app.on('ready', function () {
+  netLog.startLogging('/path/to/net-log')
+  // After some network events
+  netLog.stopLogging(path => {
+    console.log('Net-logs written to', path)
+  })
 })
 ```
 
 See [`--log-net-log`](chrome-command-line-switches.md#--log-net-logpath) to log network events throughout the app's lifecycle.
 
+**Note:** All methods unless specified can only be used after the `ready` event
+of the `app` module gets emitted.
+
 ## Methods
 
 ### `netLog.startLogging(path)`
diff --git a/docs/api/session.md b/docs/api/session.md
index 1d706e9c46f3..9884daf6b0ca 100644
--- a/docs/api/session.md
+++ b/docs/api/session.md
@@ -454,3 +454,20 @@ app.on('ready', function () {
   })
 })
 ```
+
+#### `ses.netLog`
+
+A [NetLog](net-log.md) object for this session.
+
+```javascript
+const { app, session } = require('electron')
+
+app.on('ready', function () {
+  const netLog = session.fromPartition('some-partition').netLog
+  netLog.startLogging('/path/to/net-log')
+  // After some network events
+  netLog.stopLogging(path => {
+    console.log('Net-logs written to', path)
+  })
+})
+```
diff --git a/electron_paks.gni b/electron_paks.gni
index c540fdc894fb..c1f577330099 100644
--- a/electron_paks.gni
+++ b/electron_paks.gni
@@ -59,11 +59,13 @@ template("electron_extra_paks") {
       "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
       "$root_gen_dir/net/net_resources.pak",
       "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
+      "$target_gen_dir/electron_resources.pak",
     ]
     deps = [
       "//components/resources",
       "//content:resources",
       "//content/browser/tracing:resources",
+      "//electron:resources",
       "//mojo/public/js:resources",
       "//net:net_resources",
       "//third_party/blink/public:resources",
diff --git a/electron_resources.grd b/electron_resources.grd
new file mode 100644
index 000000000000..f28e5502f536
--- /dev/null
+++ b/electron_resources.grd
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grit latest_public_release="0" current_release="1" output_all_resource_defines="false">
+  <outputs>
+    <output filename="grit/electron_resources.h" type="rc_header">
+      <emit emit_type='prepend'></emit>
+    </output>
+    <output filename="electron_resources.pak" type="data_package" />
+  </outputs>
+  <release seq="1">
+    <includes>
+      <include name="IDR_ELECTRON_CONTENT_BROWSER_MANIFEST_OVERLAY" file="${target_gen_dir}\electron_content_browser_manifest_overlay.json" use_base_dir="false" type="BINDATA" />
+      <include name="IDR_ELECTRON_CONTENT_PACKAGED_SERVICES_MANIFEST_OVERLAY" file="${target_gen_dir}\electron_content_packaged_services_manifest_overlay.json" use_base_dir="false" type="BINDATA" />
+    </includes>
+  </release>
+</grit>
diff --git a/filenames.gni b/filenames.gni
index 90974f679403..f5d5dcc36bed 100644
--- a/filenames.gni
+++ b/filenames.gni
@@ -240,6 +240,10 @@ filenames = {
     "atom/browser/common_web_contents_delegate_views.cc",
     "atom/browser/common_web_contents_delegate.cc",
     "atom/browser/common_web_contents_delegate.h",
+    "atom/browser/cookie_change_notifier.cc",
+    "atom/browser/cookie_change_notifier.h",
+    "atom/browser/io_thread.cc",
+    "atom/browser/io_thread.h",
     "atom/browser/javascript_environment.cc",
     "atom/browser/javascript_environment.h",
     "atom/browser/lib/bluetooth_chooser.cc",
@@ -295,6 +299,8 @@ filenames = {
     "atom/browser/net/http_protocol_handler.h",
     "atom/browser/net/js_asker.cc",
     "atom/browser/net/js_asker.h",
+    "atom/browser/net/resolve_proxy_helper.cc",
+    "atom/browser/net/resolve_proxy_helper.h",
     "atom/browser/net/url_request_about_job.cc",
     "atom/browser/net/url_request_about_job.h",
     "atom/browser/net/url_request_async_asar_job.cc",
@@ -303,12 +309,16 @@ filenames = {
     "atom/browser/net/url_request_string_job.h",
     "atom/browser/net/url_request_buffer_job.cc",
     "atom/browser/net/url_request_buffer_job.h",
+    "atom/browser/net/url_request_context_getter.cc",
+    "atom/browser/net/url_request_context_getter.h",
     "atom/browser/net/url_request_fetch_job.cc",
     "atom/browser/net/url_request_fetch_job.h",
     "atom/browser/net/url_request_stream_job.cc",
     "atom/browser/net/url_request_stream_job.h",
     "atom/browser/node_debugger.cc",
     "atom/browser/node_debugger.h",
+    "atom/browser/pref_store_delegate.cc",
+    "atom/browser/pref_store_delegate.h",
     "atom/browser/relauncher_linux.cc",
     "atom/browser/relauncher_mac.cc",
     "atom/browser/relauncher_win.cc",
@@ -316,8 +326,6 @@ filenames = {
     "atom/browser/relauncher.h",
     "atom/browser/render_process_preferences.cc",
     "atom/browser/render_process_preferences.h",
-    "atom/browser/request_context_delegate.cc",
-    "atom/browser/request_context_delegate.h",
     "atom/browser/session_preferences.cc",
     "atom/browser/session_preferences.h",
     "atom/browser/special_storage_policy.cc",
diff --git a/lib/browser/api/net-log.js b/lib/browser/api/net-log.js
index d6b66d24b8a6..1649c6332a26 100644
--- a/lib/browser/api/net-log.js
+++ b/lib/browser/api/net-log.js
@@ -1,16 +1,28 @@
 'use strict'
 
-const { netLog, NetLog } = process.atomBinding('net_log')
+// TODO(deepak1556): Deprecate and remove standalone netLog module,
+// it is now a property of sessio module.
+const { app, session } = require('electron')
 
-NetLog.prototype.stopLogging = function (callback) {
-  if (callback && typeof callback !== 'function') {
-    throw new Error('Invalid callback function')
+// Fallback to default session.
+Object.setPrototypeOf(module.exports, new Proxy({}, {
+  get (target, property) {
+    if (!app.isReady()) return
+
+    const netLog = session.defaultSession.netLog
+    if (!Object.getPrototypeOf(netLog).hasOwnProperty(property)) return
+
+    // Returning a native function directly would throw error.
+    return (...args) => netLog[property](...args)
+  },
+
+  ownKeys () {
+    if (!app.isReady()) return []
+
+    return Object.getOwnPropertyNames(Object.getPrototypeOf(session.defaultSession.netLog))
+  },
+
+  getOwnPropertyDescriptor (target) {
+    return { configurable: true, enumerable: true }
   }
-
-  const path = this.currentlyLoggingPath
-  this._stopLogging(() => {
-    if (callback) callback(path)
-  })
-}
-
-module.exports = netLog
+}))
diff --git a/manifests/electron_content_browser_manifest_overlay.json b/manifests/electron_content_browser_manifest_overlay.json
new file mode 100644
index 000000000000..221565ae6ef3
--- /dev/null
+++ b/manifests/electron_content_browser_manifest_overlay.json
@@ -0,0 +1,12 @@
+{
+  "name": "content_browser",
+  "display_name": "Electron (browser process)",
+  "interface_provider_specs": {
+    "service_manager:connector": {
+      "requires": {
+        "device": [ "device:geolocation_control" ],
+        "proxy_resolver": [ "factory" ]
+      }
+    }
+  }
+}
diff --git a/manifests/electron_content_packaged_services_manifest_overlay.json b/manifests/electron_content_packaged_services_manifest_overlay.json
new file mode 100644
index 000000000000..71488f02e098
--- /dev/null
+++ b/manifests/electron_content_packaged_services_manifest_overlay.json
@@ -0,0 +1,5 @@
+{
+  "name": "content_packaged_services",
+  "display_name": "Electron Packaged Services",
+  "interface_provider_specs": {}
+}
diff --git a/patches/common/chromium/.patches.yaml b/patches/common/chromium/.patches.yaml
index 95f1a67d1ea2..472d4edff979 100644
--- a/patches/common/chromium/.patches.yaml
+++ b/patches/common/chromium/.patches.yaml
@@ -376,12 +376,6 @@ patches:
     Turns `enable_widevine` flag on by default on Mac and Windows.
     Electron needs that flag to be enabled on those paltforms,
     but there's no way to conditionally set it during a `gn gen` call.
--
-  author: deepak1556 <hop2deep@gmail.com>
-  file: content_browser_manifest.patch
-  description: |
-    Allow content_browser service to access GeolocationControl
-    interface from device service.
 -
   author: deepak1556 <hop2deep@gmail.com>
   file: chrome_key_systems.patch
@@ -490,3 +484,13 @@ patches:
     See https://github.com/electron/electron/issues/14327
     (Android specific changes and changes in some test files
     have been removed from the diff.)
+-
+  author: deepak1556 <hop2deep@gmail.com>
+  file: proxy_config_monitor.patch
+  description: |
+    Allow monitoring proxy config changes for a pref service.
+-
+  author: deepak1556 <hop2deep@gmail.com>
+  file: gritsettings_resource_ids.patch
+  description: |
+    Add electron resources file to the list of resource ids generation.
diff --git a/patches/common/chromium/content_browser_manifest.patch b/patches/common/chromium/content_browser_manifest.patch
deleted file mode 100644
index 91f818a1f89f..000000000000
--- a/patches/common/chromium/content_browser_manifest.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json
-index a515b68616a8..dc0431fd17e6 100644
---- a/content/public/app/mojo/content_browser_manifest.json
-+++ b/content/public/app/mojo/content_browser_manifest.json
-@@ -90,6 +90,7 @@
-           "device:battery_monitor",
-           "device:generic_sensor",
-           "device:geolocation",
-+          "device:geolocation_control",
-           "device:hid",
-           "device:input_service",
-           "device:mtp",
--- 
-2.17.0
-
diff --git a/patches/common/chromium/gritsettings_resource_ids.patch b/patches/common/chromium/gritsettings_resource_ids.patch
new file mode 100644
index 000000000000..d7d4803e229b
--- /dev/null
+++ b/patches/common/chromium/gritsettings_resource_ids.patch
@@ -0,0 +1,15 @@
+diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids
+index fc16a42e623e..8faa1363e177 100644
+--- a/tools/gritsettings/resource_ids
++++ b/tools/gritsettings/resource_ids
+@@ -407,6 +407,10 @@
+     "includes": [28900],
+   },
+ 
++  "electron/electron_resources.grd": {
++    "includes": [31750],
++  },
++
+   # END "everything else" section.
+   # Everything but chrome/, components/, content/, and ios/
+ 
diff --git a/patches/common/chromium/proxy_config_monitor.patch b/patches/common/chromium/proxy_config_monitor.patch
new file mode 100644
index 000000000000..134cd47da0c1
--- /dev/null
+++ b/patches/common/chromium/proxy_config_monitor.patch
@@ -0,0 +1,84 @@
+diff --git a/chrome/browser/net/proxy_config_monitor.cc b/chrome/browser/net/proxy_config_monitor.cc
+index 90a8b0895f10..26c1bc0e5859 100644
+--- a/chrome/browser/net/proxy_config_monitor.cc
++++ b/chrome/browser/net/proxy_config_monitor.cc
+@@ -5,9 +5,13 @@
+ #include "chrome/browser/net/proxy_config_monitor.h"
+ 
+ #include "build/build_config.h"
++#if 0
+ #include "chrome/browser/browser_process.h"
++#endif
+ #include "chrome/browser/net/proxy_service_factory.h"
++#if 0
+ #include "chrome/browser/profiles/profile.h"
++#endif
+ #include "components/proxy_config/pref_proxy_config_tracker_impl.h"
+ #include "content/public/browser/browser_thread.h"
+ #include "mojo/public/cpp/bindings/associated_interface_ptr.h"
+@@ -15,7 +19,7 @@
+ #if defined(OS_CHROMEOS)
+ #include "chrome/browser/chromeos/profiles/profile_helper.h"
+ #endif  // defined(OS_CHROMEOS)
+-
++#if 0
+ ProxyConfigMonitor::ProxyConfigMonitor(Profile* profile) {
+   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+   DCHECK(profile);
+@@ -41,14 +45,13 @@ ProxyConfigMonitor::ProxyConfigMonitor(Profile* profile) {
+ 
+   proxy_config_service_->AddObserver(this);
+ }
++#endif
+ 
+-ProxyConfigMonitor::ProxyConfigMonitor() {
++ProxyConfigMonitor::ProxyConfigMonitor(PrefService* local_prefs) {
+   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+-
+   pref_proxy_config_tracker_.reset(
+       ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
+-          g_browser_process->local_state()));
+-
++          local_prefs));
+   proxy_config_service_ = ProxyServiceFactory::CreateProxyConfigService(
+       pref_proxy_config_tracker_.get());
+ 
+diff --git a/chrome/browser/net/proxy_config_monitor.h b/chrome/browser/net/proxy_config_monitor.h
+index b783ab18d2d7..4475b58756db 100644
+--- a/chrome/browser/net/proxy_config_monitor.h
++++ b/chrome/browser/net/proxy_config_monitor.h
+@@ -20,22 +20,24 @@ class ProxyConfigWithAnnotation;
+ 
+ class Profile;
+ class PrefProxyConfigTracker;
++class PrefService;
+ 
+ // Tracks the ProxyConfig to use, and passes any updates to a NetworkContext's
+ // ProxyConfigClient.
+ class ProxyConfigMonitor : public net::ProxyConfigService::Observer,
+                            public network::mojom::ProxyConfigPollerClient {
+  public:
++#if 0
+   // Creates a ProxyConfigMonitor that gets proxy settings from |profile| and
+   // watches for changes. The created ProxyConfigMonitor must be destroyed
+   // before |profile|.
+   explicit ProxyConfigMonitor(Profile* profile);
+-
++#endif
+   // Creates a ProxyConfigMonitor that gets proxy settings from the
+   // BrowserProcess's |local_state_|, for use with NetworkContexts not
+   // assocaited with a profile. Must be destroyed before the BrowserProcess's
+   // |local_state_|.
+-  ProxyConfigMonitor();
++  explicit ProxyConfigMonitor(PrefService* local_prefs);
+ 
+   ~ProxyConfigMonitor() override;
+ 
+@@ -63,7 +65,6 @@ class ProxyConfigMonitor : public net::ProxyConfigService::Observer,
+   std::unique_ptr<net::ProxyConfigService> proxy_config_service_;
+   // Monitors global and Profile prefs related to proxy configuration.
+   std::unique_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_;
+-
+   mojo::BindingSet<network::mojom::ProxyConfigPollerClient> binding_set_;
+ 
+   mojo::InterfacePtrSet<network::mojom::ProxyConfigClient>
diff --git a/spec/api-net-log-spec.js b/spec/api-net-log-spec.js
index 8157893ccb27..2833d554dcf2 100644
--- a/spec/api-net-log-spec.js
+++ b/spec/api-net-log-spec.js
@@ -6,7 +6,7 @@ const os = require('os')
 const path = require('path')
 const ChildProcess = require('child_process')
 const { remote } = require('electron')
-const { netLog } = remote
+const { session } = remote
 const appPath = path.join(__dirname, 'fixtures', 'api', 'net-log')
 const dumpFile = path.join(os.tmpdir(), 'net_log.json')
 const dumpFileDynamic = path.join(os.tmpdir(), 'net_log_dynamic.json')
@@ -14,6 +14,7 @@ const dumpFileDynamic = path.join(os.tmpdir(), 'net_log_dynamic.json')
 const { expect } = chai
 chai.use(dirtyChai)
 const isCI = remote.getGlobal('isCi')
+const netLog = session.fromPartition('net-log').netLog
 
 describe('netLog module', () => {
   let server
@@ -48,8 +49,12 @@ describe('netLog module', () => {
 
   afterEach(() => {
     try {
-      fs.unlinkSync(dumpFile)
-      fs.unlinkSync(dumpFileDynamic)
+      if (fs.existsSync(dumpFile)) {
+        fs.unlinkSync(dumpFile)
+      }
+      if (fs.existsSync(dumpFileDynamic)) {
+        fs.unlinkSync(dumpFileDynamic)
+      }
     } catch (e) {
       // Ignore error
     }
@@ -89,8 +94,6 @@ describe('netLog module', () => {
     })
   })
 
-  // The following tests are skipped on Linux CI
-
   it('should begin and end logging automatically when --log-net-log is passed', done => {
     if (isCI && process.platform === 'linux') {
       done()
@@ -98,13 +101,14 @@ describe('netLog module', () => {
     }
 
     const appProcess = ChildProcess.spawn(remote.process.execPath,
-      [appPath, `--log-net-log=${dumpFile}`], {
+      [appPath], {
         env: {
-          TEST_REQUEST_URL: server.url
+          TEST_REQUEST_URL: server.url,
+          TEST_DUMP_FILE: dumpFile
         }
       })
 
-    appProcess.once('exit', () => {
+    appProcess.once('close', () => {
       expect(fs.existsSync(dumpFile)).to.be.true()
       done()
     })
@@ -117,19 +121,16 @@ describe('netLog module', () => {
     }
 
     const appProcess = ChildProcess.spawn(remote.process.execPath,
-      [appPath, `--log-net-log=${dumpFile}`], {
+      [appPath], {
         env: {
           TEST_REQUEST_URL: server.url,
-          TEST_DUMP_FILE: dumpFileDynamic,
+          TEST_DUMP_FILE: dumpFile,
+          TEST_DUMP_FILE_DYNAMIC: dumpFileDynamic,
           TEST_MANUAL_STOP: true
         }
       })
 
-    appProcess.stdout.on('data', data => {
-      console.log(data.toString())
-    })
-
-    appProcess.once('exit', () => {
+    appProcess.once('close', () => {
       expect(fs.existsSync(dumpFile)).to.be.true()
       expect(fs.existsSync(dumpFileDynamic)).to.be.true()
       done()
@@ -146,11 +147,11 @@ describe('netLog module', () => {
       [appPath], {
         env: {
           TEST_REQUEST_URL: server.url,
-          TEST_DUMP_FILE: dumpFileDynamic
+          TEST_DUMP_FILE_DYNAMIC: dumpFileDynamic
         }
       })
 
-    appProcess.once('exit', () => {
+    appProcess.once('close', () => {
       expect(fs.existsSync(dumpFileDynamic)).to.be.true()
       done()
     })
diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js
index 30913316baa3..2288bea37f65 100644
--- a/spec/api-session-spec.js
+++ b/spec/api-session-spec.js
@@ -476,23 +476,62 @@ describe('session module', () => {
   })
 
   describe('ses.setProxy(options, callback)', () => {
+    let server = null
+    let customSession = null
+
+    beforeEach(() => {
+      customSession = session.fromPartition('proxyconfig')
+    })
+
+    afterEach(() => {
+      if (server) {
+        server.close()
+      }
+      if (customSession) {
+        customSession.destroy()
+      }
+    })
+
     it('allows configuring proxy settings', (done) => {
       const config = { proxyRules: 'http=myproxy:80' }
-      session.defaultSession.setProxy(config, () => {
-        session.defaultSession.resolveProxy('http://localhost', (proxy) => {
+      customSession.setProxy(config, () => {
+        customSession.resolveProxy('http://localhost', (proxy) => {
           assert.strictEqual(proxy, 'PROXY myproxy:80')
           done()
         })
       })
     })
 
+    it('allows configuring proxy settings with pacScript', (done) => {
+      server = http.createServer((req, res) => {
+        const pac = `
+          function FindProxyForURL(url, host) {
+            return "PROXY myproxy:8132";
+          }
+        `
+        res.writeHead(200, {
+          'Content-Type': 'application/x-ns-proxy-autoconfig'
+        })
+        res.end(pac)
+      })
+      server.listen(0, '127.0.0.1', () => {
+        const config = { pacScript: `http://127.0.0.1:${server.address().port}` }
+        customSession.setProxy(config, () => {
+          customSession.resolveProxy('http://localhost', (proxy) => {
+            assert.strictEqual(proxy, 'PROXY myproxy:8132')
+            done()
+          })
+        })
+      })
+    })
+
     it('allows bypassing proxy settings', (done) => {
       const config = {
         proxyRules: 'http=myproxy:80',
         proxyBypassRules: '<local>'
       }
-      session.defaultSession.setProxy(config, () => {
-        session.defaultSession.resolveProxy('http://localhost', (proxy) => {
+      customSession.setProxy(config, () => {
+        customSession.resolveProxy('http://localhost', (proxy) => {
           assert.strictEqual(proxy, 'DIRECT')
           done()
         })
diff --git a/spec/fixtures/api/net-log/main.js b/spec/fixtures/api/net-log/main.js
index 0a203b463668..d14671d939a6 100644
--- a/spec/fixtures/api/net-log/main.js
+++ b/spec/fixtures/api/net-log/main.js
@@ -1,4 +1,8 @@
-const { app, net, netLog } = require('electron')
+const { app, net, session } = require('electron')
+
+if (process.env.TEST_DUMP_FILE) {
+  app.commandLine.appendSwitch('log-net-log', process.env.TEST_DUMP_FILE)
+}
 
 function request () {
   return new Promise((resolve) => {
@@ -10,24 +14,33 @@ function request () {
   })
 }
 
-function stopLogging () {
+function stopLogging (netLog) {
   return new Promise((resolve) => {
-    netLog.stopLogging(() => {
+    netLog.stopLogging((path) => {
       resolve()
     })
   })
 }
 
 app.on('ready', async () => {
-  if (process.env.TEST_DUMP_FILE) {
-    netLog.startLogging(process.env.TEST_DUMP_FILE)
-  }
+  const netLog = session.defaultSession.netLog
 
-  await request()
+  // The net log exporter becomes ready only after
+  // default path is setup, which is posted as task
+  // to a sequenced task runner due to sync IO operations,
+  // the task are blocked for some reason,
+  // revisit task scheduling after 69 upgrade and fix this workaround.
+  setImmediate(async () => {
+    if (process.env.TEST_DUMP_FILE_DYNAMIC) {
+      netLog.startLogging(process.env.TEST_DUMP_FILE_DYNAMIC)
+    }
 
-  if (process.env.TEST_MANUAL_STOP) {
-    await stopLogging()
-  }
+    await request()
 
-  app.quit()
+    if (process.env.TEST_MANUAL_STOP) {
+      await stopLogging(netLog)
+    }
+
+    app.quit()
+  })
 })