Browse Source

build: move libcc patches to electron repo (#14104)

In the GN build, libchromiumcontent is no longer a distinct library, but
merely a container for a set of scripts and patches. Maintaining those
patches in a separate repository is tedious and error-prone, so merge
them into the main repo.

Once this is merged and GN is the default way to build Electron, the
libchromiumcontent repository can be archived.
Jeremy Apthorp 6 years ago
parent
commit
76c5f5cc8a
100 changed files with 6133 additions and 6 deletions
  1. 1 0
      .gitignore
  2. 10 6
      DEPS
  3. 25 0
      build/config/BUILD.gn
  4. 6 0
      patches/common/angle/.patches.yaml
  5. 13 0
      patches/common/angle/dcheck.patch
  6. 12 0
      patches/common/boringssl/.patches.yaml
  7. 741 0
      patches/common/boringssl/0001-Implement-legacy-OCSP-APIs-for-libssl.patch
  8. 32 0
      patches/common/boringssl/implement-SSL_get_tlsext_status_type.patch
  9. 468 0
      patches/common/chromium/.patches.yaml
  10. 103 0
      patches/common/chromium/accelerator.patch
  11. 13 0
      patches/common/chromium/add_atomic_lib_to_dependencies_even_for_sysroot_builds.patch
  12. 70 0
      patches/common/chromium/add_realloc.patch
  13. 13 0
      patches/common/chromium/allow_nested_error_trackers.patch
  14. 13 0
      patches/common/chromium/allow_new_privs.patch
  15. 13 0
      patches/common/chromium/allow_webview_file_url.patch
  16. 13 0
      patches/common/chromium/app_indicator_icon_menu.patch
  17. 23 0
      patches/common/chromium/backport_35dabc0.patch
  18. 64 0
      patches/common/chromium/backport_953144.patch
  19. 12 0
      patches/common/chromium/backport_d65792a.patch
  20. 29 0
      patches/common/chromium/backport_ef091c206.patch
  21. 12 0
      patches/common/chromium/blink-worker-enable-csp-in-file-scheme.patch
  22. 26 0
      patches/common/chromium/blink_file_path.patch
  23. 17 0
      patches/common/chromium/blink_fix_prototype_assert.patch
  24. 18 0
      patches/common/chromium/blink_initialization_order.patch
  25. 26 0
      patches/common/chromium/blink_local_frame.patch
  26. 45 0
      patches/common/chromium/blink_world_context.patch
  27. 18 0
      patches/common/chromium/boringssl_build_gn.patch
  28. 35 0
      patches/common/chromium/browser_compositor_mac.patch
  29. 18 0
      patches/common/chromium/browser_plugin_guest.patch
  30. 25 0
      patches/common/chromium/browser_plugin_wheel.patch
  31. 91 0
      patches/common/chromium/build_gn.patch
  32. 60 0
      patches/common/chromium/build_toolchain_win_patch.patch
  33. 235 0
      patches/common/chromium/can_create_window.patch
  34. 29 0
      patches/common/chromium/chrome_key_systems.patch
  35. 72 0
      patches/common/chromium/compositor_delegate.patch
  36. 12 0
      patches/common/chromium/content_browser_manifest.patch
  37. 48 0
      patches/common/chromium/crashpad-disabled-windows.patch
  38. 272 0
      patches/common/chromium/dcheck.patch
  39. 13 0
      patches/common/chromium/desktop_screen_win.patch
  40. 16 0
      patches/common/chromium/disable-recursive-surface-sync.patch
  41. 60 0
      patches/common/chromium/disable-redraw-lock.patch
  42. 17 0
      patches/common/chromium/disable_detach_webview_frame.patch
  43. 28 0
      patches/common/chromium/disable_hidden.patch
  44. 28 0
      patches/common/chromium/disable_scroll_begin_dcheck.patch
  45. 15 0
      patches/common/chromium/disable_user_gesture_requirement_for_beforeunload_dialogs.patch
  46. 17 0
      patches/common/chromium/dom_storage_map.patch
  47. 21 0
      patches/common/chromium/enable_osr_components.patch
  48. 13 0
      patches/common/chromium/enable_widevine.patch
  49. 13 0
      patches/common/chromium/exclude_next_version_mini_installer_from_deps.patch
  50. 21 0
      patches/common/chromium/export_blink_webdisplayitemlist.patch
  51. 13 0
      patches/common/chromium/fix-arm64-linking-error.patch
  52. 83 0
      patches/common/chromium/frame_host_manager.patch
  53. 66 0
      patches/common/chromium/gin_enable_disable_v8_platform.patch
  54. 13 0
      patches/common/chromium/gtk_visibility.patch
  55. 17 0
      patches/common/chromium/ignore_rc_check.patch
  56. 101 0
      patches/common/chromium/latency_info.patch
  57. 16 0
      patches/common/chromium/leveldb_ssize_t.patch
  58. 125 0
      patches/common/chromium/libgtkui_export.patch
  59. 47 0
      patches/common/chromium/mas-audiodeviceduck.patch
  60. 44 0
      patches/common/chromium/mas-cfisobjc.patch
  61. 34 0
      patches/common/chromium/mas-cgdisplayusesforcetogray.patch
  62. 27 0
      patches/common/chromium/mas-lssetapplicationlaunchservicesserverconnectionstatus.patch
  63. 112 0
      patches/common/chromium/mas_blink_no_private_api.patch
  64. 436 0
      patches/common/chromium/mas_no_private_api.patch
  65. 12 0
      patches/common/chromium/net_url_request_job.patch
  66. 13 0
      patches/common/chromium/no_cache_storage_check.patch
  67. 13 0
      patches/common/chromium/no_stack_dumping.patch
  68. 15 0
      patches/common/chromium/out_of_process_instance.patch
  69. 484 0
      patches/common/chromium/pepper_flash.patch
  70. 16 0
      patches/common/chromium/protobuf_build_gn.patch
  71. 70 0
      patches/common/chromium/render_widget_host_view_base.patch
  72. 102 0
      patches/common/chromium/render_widget_host_view_mac.patch
  73. 24 0
      patches/common/chromium/resource_file_conflict.patch
  74. 57 0
      patches/common/chromium/scoped_clipboard_writer.patch
  75. 13 0
      patches/common/chromium/scroll_bounce_flag.patch
  76. 91 0
      patches/common/chromium/ssl_security_state_tab_helper.patch
  77. 21 0
      patches/common/chromium/statically_build_power_save_blocker.patch
  78. 21 0
      patches/common/chromium/stream_resource_handler.patch
  79. 126 0
      patches/common/chromium/sysroot.patch
  80. 15 0
      patches/common/chromium/thread_capabilities.patch
  81. 48 0
      patches/common/chromium/use_transparent_window.patch
  82. 12 0
      patches/common/chromium/v8_context_snapshot_generator.patch
  83. 115 0
      patches/common/chromium/web_contents.patch
  84. 111 0
      patches/common/chromium/webgl_context_attributes.patch
  85. 138 0
      patches/common/chromium/webui_in_subframes.patch
  86. 24 0
      patches/common/chromium/webview_cross_drag.patch
  87. 16 0
      patches/common/chromium/webview_reattach.patch
  88. 45 0
      patches/common/chromium/windows_cc_wrapper.patch
  89. 74 0
      patches/common/chromium/worker_context_will_destroy.patch
  90. 8 0
      patches/common/crashpad/.patches.yaml
  91. 54 0
      patches/common/crashpad/http_status.patch
  92. 15 0
      patches/common/ffmpeg/.patches.yaml
  93. 15 0
      patches/common/ffmpeg/build_gn.patch
  94. 13 0
      patches/common/ffmpeg/fix_build_on_linux_x86.patch
  95. 10 0
      patches/common/icu/.patches.yaml
  96. 63 0
      patches/common/icu/build_gn.patch
  97. 44 0
      patches/common/icu/no_inline_default_constructor.patch
  98. 6 0
      patches/common/skia/.patches.yaml
  99. 13 0
      patches/common/skia/dcheck.patch
  100. 87 0
      patches/common/v8/.patches.yaml

+ 1 - 0
.gitignore

@@ -41,6 +41,7 @@
 /vendor/python_26/
 /vendor/native_mksnapshot
 /vendor/LICENSES.chromium.html
+/vendor/pyyaml
 node_modules/
 SHASUMS256.txt
 **/yarn.lock

+ 10 - 6
DEPS

@@ -1,17 +1,21 @@
 vars = {
   'chromium_version':
     '67.0.3396.99',
-  'libchromiumcontent_revision':
-    '5db6529f9663a48ee3e6f4265a6abe7806f1dfbf',
   'node_version':
     '9dcbed23f016d3ad081be6ec7fb5122e57862da7',
 
+  'pyyaml_version':
+    '3.12',
+
   'chromium_git':
     'https://chromium.googlesource.com',
 
   'electron_git':
     'https://github.com/electron',
 
+  'yaml_git':
+    'https://github.com/yaml',
+
   'checkout_nacl':
     False,
   'checkout_libaom':
@@ -23,22 +27,22 @@ vars = {
 deps = {
   'src':
     (Var("chromium_git")) + '/chromium/src.git@' + (Var("chromium_version")),
-  'src/libchromiumcontent':
-    (Var("electron_git")) + '/libchromiumcontent.git@' + (Var("libchromiumcontent_revision")),
   'src/third_party/electron_node':
     (Var("electron_git")) + '/node.git@' + (Var("node_version")),
+  'src/electron/vendor/pyyaml':
+    (Var("yaml_git")) + '/pyyaml.git@' + (Var("pyyaml_version")),
 }
 
 hooks = [
   {
     'action': [
       'python',
-      'src/libchromiumcontent/script/apply-patches',
+      'src/electron/script/apply-patches',
       '--project-root=.',
       '--commit'
     ],
     'pattern':
-      'src/libchromiumcontent',
+      'src/electron',
     'name':
       'patch_chromium'
   },

+ 25 - 0
build/config/BUILD.gn

@@ -0,0 +1,25 @@
+config("build_time_executable") {
+  configs = []
+
+  if (is_electron_build && !is_component_build) {
+    # The executables which have this config applied are dependent on ffmpeg,
+    # which is always a shared library in an Electron build. However, in the
+    # non-component build, executables don't have rpath set to search for
+    # libraries in the executable's directory, so ffmpeg cannot be found. So
+    # let's make sure rpath is set here.
+    # See '//build/config/gcc/BUILD.gn' for details on the rpath setting.
+    if (is_linux) {
+      configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
+    }
+
+    if (is_mac) {
+      ldflags = [ "-Wl,-rpath,@loader_path/." ]
+    }
+  }
+}
+# For MAS build, we force defining "MAS_BUILD".
+config("mas_build") {
+  if (is_mas_build) {
+    defines = [ "MAS_BUILD" ]
+  }
+}

+ 6 - 0
patches/common/angle/.patches.yaml

@@ -0,0 +1,6 @@
+repo: src/third_party/angle
+patches:
+-
+  author: Ales Pergl <[email protected]>
+  file: dcheck.patch
+  description: null

+ 13 - 0
patches/common/angle/dcheck.patch

@@ -0,0 +1,13 @@
+diff --git a/src/common/debug.h b/src/common/debug.h
+index 0108ff655..57fbc5ac5 100644
+--- a/src/common/debug.h
++++ b/src/common/debug.h
+@@ -190,7 +190,7 @@ std::ostream &FmtHexInt(std::ostream &os, T value)
+ 
+ #define ANGLE_EMPTY_STATEMENT for (;;) break
+ #if !defined(NDEBUG) || defined(ANGLE_ENABLE_RELEASE_ASSERTS)
+-#define ANGLE_ENABLE_ASSERTS
++// #define ANGLE_ENABLE_ASSERTS
+ #endif
+ 
+ #define WARN() ANGLE_LOG(WARN)

+ 12 - 0
patches/common/boringssl/.patches.yaml

@@ -0,0 +1,12 @@
+repo: src/third_party/boringssl/src
+patches:
+-
+  author: Jeremy Apthorp <[email protected]>
+  file: 0001-Implement-legacy-OCSP-APIs-for-libssl.patch
+  description: see patch header
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: implement-SSL_get_tlsext_status_type.patch
+  description: |
+    BoringSSL doesn't implement `SSL_get_tlsext_status_type()`,
+    but Node.js expects it to be present cause OpenSSL has it.

+ 741 - 0
patches/common/boringssl/0001-Implement-legacy-OCSP-APIs-for-libssl.patch

@@ -0,0 +1,741 @@
+From 81d4909d00c3628453a8712bc331304bd01d8eaf Mon Sep 17 00:00:00 2001
+From: David Benjamin <[email protected]>
+Date: Thu, 10 May 2018 19:55:02 -0400
+Subject: [PATCH] Implement legacy OCSP APIs for libssl.
+
+Previously, we'd omitted OpenSSL's OCSP APIs because they depend on a
+complex OCSP mechanism and encourage the the unreliable server behavior
+that hampers using OCSP stapling to fix revocation today. (OCSP
+responses should not be fetched on-demand on a callback. They should be
+managed like other server credentials and refreshed eagerly, so
+temporary CA outage does not translate to loss of OCSP.)
+
+But most of the APIs are byte-oriented anyway, so they're easy to
+support. Intentionally omit the one that takes a bunch of OCSP_RESPIDs.
+
+The callback is benign on the client (an artifact of OpenSSL reading
+OCSP and verifying certificates in the wrong order). On the server, it
+encourages unreliability, but pyOpenSSL/cryptography.io depends on this.
+Dcument that this is only for compatibility with legacy software.
+
+Also tweak a few things for compatilibility. cryptography.io expects
+SSL_CTX_set_read_ahead to return something, SSL_get_server_tmp_key's
+signature was wrong, and cryptography.io tries to redefine
+SSL_get_server_tmp_key if SSL_CTRL_GET_SERVER_TMP_KEY is missing.
+
+Change-Id: I2f99711783456bfb7324e9ad972510be8a95e845
+Reviewed-on: https://boringssl-review.googlesource.com/28404
+Commit-Queue: David Benjamin <[email protected]>
+CQ-Verified: CQ bot account: [email protected] <[email protected]>
+Reviewed-by: Adam Langley <[email protected]>
+---
+ crypto/err/ssl.errordata  |   1 +
+ include/openssl/ssl.h     |  64 +++++++++++++--
+ include/openssl/tls1.h    |   1 +
+ ssl/handshake.cc          |  16 ++++
+ ssl/handshake_server.cc   |  16 ++++
+ ssl/internal.h            |   5 ++
+ ssl/ssl_lib.cc            |  39 ++++++++-
+ ssl/test/bssl_shim.cc     |  26 ++++++
+ ssl/test/runner/alert.go  | 122 +++++++++++++--------------
+ ssl/test/runner/runner.go | 205 ++++++++++++++++++++++++++++++++++------------
+ ssl/test/test_config.cc   |   4 +
+ ssl/test/test_config.h    |   4 +
+ 12 files changed, 381 insertions(+), 122 deletions(-)
+
+diff --git a/crypto/err/ssl.errordata b/crypto/err/ssl.errordata
+index 7b63bc8..375df9a 100644
+--- a/crypto/err/ssl.errordata
++++ b/crypto/err/ssl.errordata
+@@ -108,6 +108,7 @@ SSL,266,NO_SHARED_GROUP
+ SSL,280,NO_SUPPORTED_VERSIONS_ENABLED
+ SSL,185,NULL_SSL_CTX
+ SSL,186,NULL_SSL_METHOD_PASSED
++SSL,289,OCSP_CB_ERROR
+ SSL,187,OLD_SESSION_CIPHER_NOT_RETURNED
+ SSL,268,OLD_SESSION_PRF_HASH_MISMATCH
+ SSL,188,OLD_SESSION_VERSION_NOT_RETURNED
+diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
+index 35506f7..d46a5af 100644
+--- a/include/openssl/ssl.h
++++ b/include/openssl/ssl.h
+@@ -3715,14 +3715,14 @@ OPENSSL_EXPORT int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa);
+ // SSL_CTX_get_read_ahead returns zero.
+ OPENSSL_EXPORT int SSL_CTX_get_read_ahead(const SSL_CTX *ctx);
+ 
+-// SSL_CTX_set_read_ahead does nothing.
+-OPENSSL_EXPORT void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes);
++// SSL_CTX_set_read_ahead returns one.
++OPENSSL_EXPORT int SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes);
+ 
+ // SSL_get_read_ahead returns zero.
+ OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *ssl);
+ 
+-// SSL_set_read_ahead does nothing.
+-OPENSSL_EXPORT void SSL_set_read_ahead(SSL *ssl, int yes);
++// SSL_set_read_ahead returns one.
++OPENSSL_EXPORT int SSL_set_read_ahead(SSL *ssl, int yes);
+ 
+ // SSL_renegotiate put an error on the error queue and returns zero.
+ OPENSSL_EXPORT int SSL_renegotiate(SSL *ssl);
+@@ -3793,7 +3793,7 @@ OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_compression(SSL *ssl);
+ OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_expansion(SSL *ssl);
+ 
+ // SSL_get_server_tmp_key returns zero.
+-OPENSSL_EXPORT int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key);
++OPENSSL_EXPORT int SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key);
+ 
+ // SSL_CTX_set_tmp_dh returns 1.
+ OPENSSL_EXPORT int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh);
+@@ -4108,6 +4108,58 @@ extern "C++" OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb(
+                                                  int id_len, int *out_copy));
+ #endif
+ 
++// SSL_set_tlsext_status_type configures a client to request OCSP stapling if
++// |type| is |TLSEXT_STATUSTYPE_ocsp| and disables it otherwise. It returns one
++// on success and zero if handshake configuration has already been shed.
++//
++// Use |SSL_enable_ocsp_stapling| instead.
++OPENSSL_EXPORT int SSL_set_tlsext_status_type(SSL *ssl, int type);
++
++// SSL_set_tlsext_status_ocsp_resp sets the OCSP response. It returns one on
++// success and zero on error. On success, |ssl| takes ownership of |resp|, which
++// must have been allocated by |OPENSSL_malloc|.
++//
++// Use |SSL_set_ocsp_response| instead.
++OPENSSL_EXPORT int SSL_set_tlsext_status_ocsp_resp(SSL *ssl, uint8_t *resp,
++                                                   size_t resp_len);
++
++// SSL_get_tlsext_status_ocsp_resp sets |*out| to point to the OCSP response
++// from the server. It returns the length of the response. If there was no
++// response, it sets |*out| to NULL and returns zero.
++//
++// Use |SSL_get0_ocsp_response| instead.
++//
++// WARNING: the returned data is not guaranteed to be well formed.
++OPENSSL_EXPORT size_t SSL_get_tlsext_status_ocsp_resp(const SSL *ssl,
++                                                      const uint8_t **out);
++
++// SSL_CTX_set_tlsext_status_cb configures the legacy OpenSSL OCSP callback and
++// returns one. Though the type signature is the same, this callback has
++// different behavior for client and server connections:
++//
++// For clients, the callback is called after certificate verification. It should
++// return one for success, zero for a bad OCSP response, and a negative number
++// for internal error. Instead, handle this as part of certificate verification.
++// (Historically, OpenSSL verified certificates just before parsing stapled OCSP
++// responses, but BoringSSL fixes this ordering. All server credentials are
++// available during verification.)
++//
++// Do not use this callback as a server. It is provided for compatibility
++// purposes only. For servers, it is called to configure server credentials. It
++// should return |SSL_TLSEXT_ERR_OK| on success, |SSL_TLSEXT_ERR_NOACK| to
++// ignore OCSP requests, or |SSL_TLSEXT_ERR_ALERT_FATAL| on error. It is usually
++// used to fetch OCSP responses on demand, which is not ideal. Instead, treat
++// OCSP responses like other server credentials, such as certificates or SCT
++// lists. Configure, store, and refresh them eagerly. This avoids downtime if
++// the CA's OCSP responder is briefly offline.
++OPENSSL_EXPORT int SSL_CTX_set_tlsext_status_cb(SSL_CTX *ctx,
++                                                int (*callback)(SSL *ssl,
++                                                                void *arg));
++
++// SSL_CTX_set_tlsext_status_arg sets additional data for
++// |SSL_CTX_set_tlsext_status_cb|'s callback and returns one.
++OPENSSL_EXPORT int SSL_CTX_set_tlsext_status_arg(SSL_CTX *ctx, void *arg);
++
+ 
+ // Private structures.
+ //
+@@ -4285,6 +4337,7 @@ struct ssl_session_st {
+ #define SSL_CTRL_GET_NUM_RENEGOTIATIONS doesnt_exist
+ #define SSL_CTRL_GET_READ_AHEAD doesnt_exist
+ #define SSL_CTRL_GET_RI_SUPPORT doesnt_exist
++#define SSL_CTRL_GET_SERVER_TMP_KEY doesnt_exist
+ #define SSL_CTRL_GET_SESSION_REUSED doesnt_exist
+ #define SSL_CTRL_GET_SESS_CACHE_MODE doesnt_exist
+ #define SSL_CTRL_GET_SESS_CACHE_SIZE doesnt_exist
+@@ -4698,6 +4751,7 @@ OPENSSL_EXPORT bool SSL_apply_handback(SSL *ssl, Span<const uint8_t> handback);
+ #define SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI 285
+ #define SSL_R_SERVER_ECHOED_INVALID_SESSION_ID 286
+ #define SSL_R_PRIVATE_KEY_OPERATION_FAILED 287
++#define SSL_R_OCSP_CB_ERROR 289
+ #define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000
+ #define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
+ #define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020
+diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
+index 3424f3d..7a05969 100644
+--- a/include/openssl/tls1.h
++++ b/include/openssl/tls1.h
+@@ -237,6 +237,7 @@ extern "C" {
+ #define TLSEXT_TYPE_dummy_pq_padding 54537
+ 
+ // status request value from RFC 3546
++#define TLSEXT_STATUSTYPE_nothing (-1)
+ #define TLSEXT_STATUSTYPE_ocsp 1
+ 
+ // ECPointFormat values from RFC 4492
+diff --git a/ssl/handshake.cc b/ssl/handshake.cc
+index 6432424..0a90b9f 100644
+--- a/ssl/handshake.cc
++++ b/ssl/handshake.cc
+@@ -356,6 +356,22 @@ enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs) {
+     ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
+   }
+ 
++  // Emulate OpenSSL's client OCSP callback. OpenSSL verifies certificates
++  // before it receives the OCSP, so it needs a second callback for OCSP.
++  if (ret == ssl_verify_ok && !ssl->server &&
++      hs->new_session->ocsp_response != nullptr &&
++      ssl->ctx->legacy_ocsp_callback != nullptr) {
++    int cb_ret =
++        ssl->ctx->legacy_ocsp_callback(ssl, ssl->ctx->legacy_ocsp_callback_arg);
++    if (cb_ret <= 0) {
++      OPENSSL_PUT_ERROR(SSL, SSL_R_OCSP_CB_ERROR);
++      ssl_send_alert(ssl, SSL3_AL_FATAL,
++                     cb_ret == 0 ? SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE
++                                 : SSL_AD_INTERNAL_ERROR);
++      ret = ssl_verify_invalid;
++    }
++  }
++
+   return ret;
+ }
+ 
+diff --git a/ssl/handshake_server.cc b/ssl/handshake_server.cc
+index fa8a241..7a96767 100644
+--- a/ssl/handshake_server.cc
++++ b/ssl/handshake_server.cc
+@@ -534,6 +534,22 @@ static enum ssl_hs_wait_t do_select_certificate(SSL_HANDSHAKE *hs) {
+     return ssl_hs_error;
+   }
+ 
++  if (hs->ocsp_stapling_requested &&
++      ssl->ctx->legacy_ocsp_callback != nullptr) {
++    switch (ssl->ctx->legacy_ocsp_callback(
++        ssl, ssl->ctx->legacy_ocsp_callback_arg)) {
++      case SSL_TLSEXT_ERR_OK:
++        break;
++      case SSL_TLSEXT_ERR_NOACK:
++        hs->ocsp_stapling_requested = false;
++        break;
++      default:
++        OPENSSL_PUT_ERROR(SSL, SSL_R_OCSP_CB_ERROR);
++        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
++        return ssl_hs_error;
++    }
++  }
++
+   if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
+     // Jump to the TLS 1.3 state machine.
+     hs->state = state_tls13;
+diff --git a/ssl/internal.h b/ssl/internal.h
+index d13d5f2..1cdfb8e 100644
+--- a/ssl/internal.h
++++ b/ssl/internal.h
+@@ -2140,6 +2140,11 @@ struct SSLContext {
+   // session tickets.
+   const SSL_TICKET_AEAD_METHOD *ticket_aead_method;
+ 
++  // legacy_ocsp_callback implements an OCSP-related callback for OpenSSL
++  // compatibility.
++  int (*legacy_ocsp_callback)(SSL *ssl, void *arg);
++  void *legacy_ocsp_callback_arg;
++
+   // verify_sigalgs, if not empty, is the set of signature algorithms
+   // accepted from the peer in decreasing order of preference.
+   uint16_t *verify_sigalgs;
+diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
+index 9f56d54..50608e9 100644
+--- a/ssl/ssl_lib.cc
++++ b/ssl/ssl_lib.cc
+@@ -1591,9 +1591,9 @@ int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; }
+ 
+ int SSL_get_read_ahead(const SSL *ssl) { return 0; }
+ 
+-void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { }
++int SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { return 1; }
+ 
+-void SSL_set_read_ahead(SSL *ssl, int yes) { }
++int SSL_set_read_ahead(SSL *ssl, int yes) { return 1; }
+ 
+ int SSL_pending(const SSL *ssl) {
+   return static_cast<int>(ssl->s3->pending_app_data.size());
+@@ -2205,7 +2205,7 @@ const COMP_METHOD *SSL_get_current_compression(SSL *ssl) { return NULL; }
+ 
+ const COMP_METHOD *SSL_get_current_expansion(SSL *ssl) { return NULL; }
+ 
+-int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key) { return 0; }
++int SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key) { return 0; }
+ 
+ void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) {
+   ctx->quiet_shutdown = (mode != 0);
+@@ -2717,3 +2717,33 @@ void SSL_CTX_set_ticket_aead_method(SSL_CTX *ctx,
+                                     const SSL_TICKET_AEAD_METHOD *aead_method) {
+   ctx->ticket_aead_method = aead_method;
+ }
++
++int SSL_set_tlsext_status_type(SSL *ssl, int type) {
++  ssl->ocsp_stapling_enabled = type == TLSEXT_STATUSTYPE_ocsp;
++  return 1;
++}
++
++int SSL_set_tlsext_status_ocsp_resp(SSL *ssl, uint8_t *resp, size_t resp_len) {
++  if (SSL_set_ocsp_response(ssl, resp, resp_len)) {
++    OPENSSL_free(resp);
++    return 1;
++  }
++  return 0;
++}
++
++size_t SSL_get_tlsext_status_ocsp_resp(const SSL *ssl, const uint8_t **out) {
++  size_t ret;
++  SSL_get0_ocsp_response(ssl, out, &ret);
++  return ret;
++}
++
++int SSL_CTX_set_tlsext_status_cb(SSL_CTX *ctx,
++                                 int (*callback)(SSL *ssl, void *arg)) {
++  ctx->legacy_ocsp_callback = callback;
++  return 1;
++}
++
++int SSL_CTX_set_tlsext_status_arg(SSL_CTX *ctx, void *arg) {
++  ctx->legacy_ocsp_callback_arg = arg;
++  return 1;
++}
+diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
+index ae26ded..3a33d60 100644
+--- a/ssl/test/bssl_shim.cc
++++ b/ssl/test/bssl_shim.cc
+@@ -495,6 +495,7 @@ static bool GetCertificate(SSL *ssl, bssl::UniquePtr<X509> *out_x509,
+     return false;
+   }
+   if (!config->ocsp_response.empty() &&
++      !config->set_ocsp_in_callback &&
+       !SSL_set_ocsp_response(ssl, (const uint8_t *)config->ocsp_response.data(),
+                              config->ocsp_response.size())) {
+     return false;
+@@ -1100,6 +1101,27 @@ static void MessageCallback(int is_write, int version, int content_type,
+   }
+ }
+ 
++static int LegacyOCSPCallback(SSL *ssl, void *arg) {
++  const TestConfig *config = GetTestConfig(ssl);
++  if (!SSL_is_server(ssl)) {
++    return !config->fail_ocsp_callback;
++  }
++
++  if (!config->ocsp_response.empty() &&
++      config->set_ocsp_in_callback &&
++      !SSL_set_ocsp_response(ssl, (const uint8_t *)config->ocsp_response.data(),
++                             config->ocsp_response.size())) {
++    return SSL_TLSEXT_ERR_ALERT_FATAL;
++  }
++  if (config->fail_ocsp_callback) {
++    return SSL_TLSEXT_ERR_ALERT_FATAL;
++  }
++  if (config->decline_ocsp_callback) {
++    return SSL_TLSEXT_ERR_NOACK;
++  }
++  return SSL_TLSEXT_ERR_OK;
++}
++
+ // Connect returns a new socket connected to localhost on |port| or -1 on
+ // error.
+ static int Connect(uint16_t port) {
+@@ -1334,6 +1356,10 @@ static bssl::UniquePtr<SSL_CTX> SetupCtx(SSL_CTX *old_ctx,
+     SSL_CTX_set_false_start_allowed_without_alpn(ssl_ctx.get(), 1);
+   }
+ 
++  if (config->use_ocsp_callback) {
++    SSL_CTX_set_tlsext_status_cb(ssl_ctx.get(), LegacyOCSPCallback);
++  }
++
+   if (old_ctx) {
+     uint8_t keys[48];
+     if (!SSL_CTX_get_tlsext_ticket_keys(old_ctx, &keys, sizeof(keys)) ||
+diff --git a/ssl/test/runner/alert.go b/ssl/test/runner/alert.go
+index 652e9ee..c79725e 100644
+--- a/ssl/test/runner/alert.go
++++ b/ssl/test/runner/alert.go
+@@ -15,69 +15,71 @@ const (
+ )
+ 
+ const (
+-	alertCloseNotify            alert = 0
+-	alertEndOfEarlyData         alert = 1
+-	alertUnexpectedMessage      alert = 10
+-	alertBadRecordMAC           alert = 20
+-	alertDecryptionFailed       alert = 21
+-	alertRecordOverflow         alert = 22
+-	alertDecompressionFailure   alert = 30
+-	alertHandshakeFailure       alert = 40
+-	alertNoCertificate          alert = 41
+-	alertBadCertificate         alert = 42
+-	alertUnsupportedCertificate alert = 43
+-	alertCertificateRevoked     alert = 44
+-	alertCertificateExpired     alert = 45
+-	alertCertificateUnknown     alert = 46
+-	alertIllegalParameter       alert = 47
+-	alertUnknownCA              alert = 48
+-	alertAccessDenied           alert = 49
+-	alertDecodeError            alert = 50
+-	alertDecryptError           alert = 51
+-	alertProtocolVersion        alert = 70
+-	alertInsufficientSecurity   alert = 71
+-	alertInternalError          alert = 80
+-	alertInappropriateFallback  alert = 86
+-	alertUserCanceled           alert = 90
+-	alertNoRenegotiation        alert = 100
+-	alertMissingExtension       alert = 109
+-	alertUnsupportedExtension   alert = 110
+-	alertUnrecognizedName       alert = 112
+-	alertUnknownPSKIdentity     alert = 115
+-	alertCertificateRequired    alert = 116
++	alertCloseNotify                  alert = 0
++	alertEndOfEarlyData               alert = 1
++	alertUnexpectedMessage            alert = 10
++	alertBadRecordMAC                 alert = 20
++	alertDecryptionFailed             alert = 21
++	alertRecordOverflow               alert = 22
++	alertDecompressionFailure         alert = 30
++	alertHandshakeFailure             alert = 40
++	alertNoCertificate                alert = 41
++	alertBadCertificate               alert = 42
++	alertUnsupportedCertificate       alert = 43
++	alertCertificateRevoked           alert = 44
++	alertCertificateExpired           alert = 45
++	alertCertificateUnknown           alert = 46
++	alertIllegalParameter             alert = 47
++	alertUnknownCA                    alert = 48
++	alertAccessDenied                 alert = 49
++	alertDecodeError                  alert = 50
++	alertDecryptError                 alert = 51
++	alertProtocolVersion              alert = 70
++	alertInsufficientSecurity         alert = 71
++	alertInternalError                alert = 80
++	alertInappropriateFallback        alert = 86
++	alertUserCanceled                 alert = 90
++	alertNoRenegotiation              alert = 100
++	alertMissingExtension             alert = 109
++	alertUnsupportedExtension         alert = 110
++	alertUnrecognizedName             alert = 112
++	alertBadCertificateStatusResponse alert = 113
++	alertUnknownPSKIdentity           alert = 115
++	alertCertificateRequired          alert = 116
+ )
+ 
+ var alertText = map[alert]string{
+-	alertCloseNotify:            "close notify",
+-	alertEndOfEarlyData:         "end of early data",
+-	alertUnexpectedMessage:      "unexpected message",
+-	alertBadRecordMAC:           "bad record MAC",
+-	alertDecryptionFailed:       "decryption failed",
+-	alertRecordOverflow:         "record overflow",
+-	alertDecompressionFailure:   "decompression failure",
+-	alertHandshakeFailure:       "handshake failure",
+-	alertNoCertificate:          "no certificate",
+-	alertBadCertificate:         "bad certificate",
+-	alertUnsupportedCertificate: "unsupported certificate",
+-	alertCertificateRevoked:     "revoked certificate",
+-	alertCertificateExpired:     "expired certificate",
+-	alertCertificateUnknown:     "unknown certificate",
+-	alertIllegalParameter:       "illegal parameter",
+-	alertUnknownCA:              "unknown certificate authority",
+-	alertAccessDenied:           "access denied",
+-	alertDecodeError:            "error decoding message",
+-	alertDecryptError:           "error decrypting message",
+-	alertProtocolVersion:        "protocol version not supported",
+-	alertInsufficientSecurity:   "insufficient security level",
+-	alertInternalError:          "internal error",
+-	alertInappropriateFallback:  "inappropriate fallback",
+-	alertUserCanceled:           "user canceled",
+-	alertNoRenegotiation:        "no renegotiation",
+-	alertMissingExtension:       "missing extension",
+-	alertUnsupportedExtension:   "unsupported extension",
+-	alertUnrecognizedName:       "unrecognized name",
+-	alertUnknownPSKIdentity:     "unknown PSK identity",
+-	alertCertificateRequired:    "certificate required",
++	alertCloseNotify:                  "close notify",
++	alertEndOfEarlyData:               "end of early data",
++	alertUnexpectedMessage:            "unexpected message",
++	alertBadRecordMAC:                 "bad record MAC",
++	alertDecryptionFailed:             "decryption failed",
++	alertRecordOverflow:               "record overflow",
++	alertDecompressionFailure:         "decompression failure",
++	alertHandshakeFailure:             "handshake failure",
++	alertNoCertificate:                "no certificate",
++	alertBadCertificate:               "bad certificate",
++	alertUnsupportedCertificate:       "unsupported certificate",
++	alertCertificateRevoked:           "revoked certificate",
++	alertCertificateExpired:           "expired certificate",
++	alertCertificateUnknown:           "unknown certificate",
++	alertIllegalParameter:             "illegal parameter",
++	alertUnknownCA:                    "unknown certificate authority",
++	alertAccessDenied:                 "access denied",
++	alertDecodeError:                  "error decoding message",
++	alertDecryptError:                 "error decrypting message",
++	alertProtocolVersion:              "protocol version not supported",
++	alertInsufficientSecurity:         "insufficient security level",
++	alertInternalError:                "internal error",
++	alertInappropriateFallback:        "inappropriate fallback",
++	alertUserCanceled:                 "user canceled",
++	alertNoRenegotiation:              "no renegotiation",
++	alertMissingExtension:             "missing extension",
++	alertUnsupportedExtension:         "unsupported extension",
++	alertBadCertificateStatusResponse: "bad certificate status response",
++	alertUnrecognizedName:             "unrecognized name",
++	alertUnknownPSKIdentity:           "unknown PSK identity",
++	alertCertificateRequired:          "certificate required",
+ }
+ 
+ func (e alert) String() string {
+diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
+index 510a48b..1a6d0f9 100644
+--- a/ssl/test/runner/runner.go
++++ b/ssl/test/runner/runner.go
+@@ -4744,60 +4744,157 @@ func addStateMachineCoverageTests(config stateMachineTestConfig) {
+ 	})
+ 
+ 	// OCSP stapling tests.
+-	tests = append(tests, testCase{
+-		testType: clientTest,
+-		name:     "OCSPStapling-Client",
+-		config: Config{
+-			MaxVersion: VersionTLS12,
+-		},
+-		flags: []string{
+-			"-enable-ocsp-stapling",
+-			"-expect-ocsp-response",
+-			base64.StdEncoding.EncodeToString(testOCSPResponse),
+-			"-verify-peer",
+-		},
+-		resumeSession: true,
+-	})
+-	tests = append(tests, testCase{
+-		testType: serverTest,
+-		name:     "OCSPStapling-Server",
+-		config: Config{
+-			MaxVersion: VersionTLS12,
+-		},
+-		expectedOCSPResponse: testOCSPResponse,
+-		flags: []string{
+-			"-ocsp-response",
+-			base64.StdEncoding.EncodeToString(testOCSPResponse),
+-		},
+-		resumeSession: true,
+-	})
+-	tests = append(tests, testCase{
+-		testType: clientTest,
+-		name:     "OCSPStapling-Client-TLS13",
+-		config: Config{
+-			MaxVersion: VersionTLS13,
+-		},
+-		flags: []string{
+-			"-enable-ocsp-stapling",
+-			"-expect-ocsp-response",
+-			base64.StdEncoding.EncodeToString(testOCSPResponse),
+-			"-verify-peer",
+-		},
+-		resumeSession: true,
+-	})
+-	tests = append(tests, testCase{
+-		testType: serverTest,
+-		name:     "OCSPStapling-Server-TLS13",
+-		config: Config{
+-			MaxVersion: VersionTLS13,
+-		},
+-		expectedOCSPResponse: testOCSPResponse,
+-		flags: []string{
+-			"-ocsp-response",
+-			base64.StdEncoding.EncodeToString(testOCSPResponse),
+-		},
+-		resumeSession: true,
+-	})
++	for _, vers := range tlsVersions {
++		if config.protocol == dtls && !vers.hasDTLS {
++			continue
++		}
++		if vers.version == VersionSSL30 {
++			continue
++		}
++		tests = append(tests, testCase{
++			testType: clientTest,
++			name:     "OCSPStapling-Client-" + vers.name,
++			config: Config{
++				MaxVersion: vers.version,
++			},
++			tls13Variant: vers.tls13Variant,
++			flags: []string{
++				"-enable-ocsp-stapling",
++				"-expect-ocsp-response",
++				base64.StdEncoding.EncodeToString(testOCSPResponse),
++				"-verify-peer",
++			},
++			resumeSession: true,
++		})
++		tests = append(tests, testCase{
++			testType: serverTest,
++			name:     "OCSPStapling-Server-" + vers.name,
++			config: Config{
++				MaxVersion: vers.version,
++			},
++			tls13Variant:         vers.tls13Variant,
++			expectedOCSPResponse: testOCSPResponse,
++			flags: []string{
++				"-ocsp-response",
++				base64.StdEncoding.EncodeToString(testOCSPResponse),
++			},
++			resumeSession: true,
++		})
++
++		// The client OCSP callback is an alternate certificate
++		// verification callback.
++		tests = append(tests, testCase{
++			testType: clientTest,
++			name:     "ClientOCSPCallback-Pass-" + vers.name,
++			config: Config{
++				MaxVersion:   vers.version,
++				Certificates: []Certificate{rsaCertificate},
++			},
++			tls13Variant: vers.tls13Variant,
++			flags: []string{
++				"-enable-ocsp-stapling",
++				"-use-ocsp-callback",
++			},
++		})
++		var expectedLocalError string
++		if !config.async {
++			// TODO(davidben): Asynchronous fatal alerts are never
++			// sent. https://crbug.com/boringssl/130.
++			expectedLocalError = "remote error: bad certificate status response"
++		}
++		tests = append(tests, testCase{
++			testType: clientTest,
++			name:     "ClientOCSPCallback-Fail-" + vers.name,
++			config: Config{
++				MaxVersion:   vers.version,
++				Certificates: []Certificate{rsaCertificate},
++			},
++			tls13Variant: vers.tls13Variant,
++			flags: []string{
++				"-enable-ocsp-stapling",
++				"-use-ocsp-callback",
++				"-fail-ocsp-callback",
++			},
++			shouldFail:         true,
++			expectedLocalError: expectedLocalError,
++			expectedError:      ":OCSP_CB_ERROR:",
++		})
++		// The callback does not run if the server does not send an
++		// OCSP response.
++		certNoStaple := rsaCertificate
++		certNoStaple.OCSPStaple = nil
++		tests = append(tests, testCase{
++			testType: clientTest,
++			name:     "ClientOCSPCallback-FailNoStaple-" + vers.name,
++			config: Config{
++				MaxVersion:   vers.version,
++				Certificates: []Certificate{certNoStaple},
++			},
++			tls13Variant: vers.tls13Variant,
++			flags: []string{
++				"-enable-ocsp-stapling",
++				"-use-ocsp-callback",
++				"-fail-ocsp-callback",
++			},
++		})
++
++		// The server OCSP callback is a legacy mechanism for
++		// configuring OCSP, used by unreliable server software.
++		tests = append(tests, testCase{
++			testType: serverTest,
++			name:     "ServerOCSPCallback-SetInCallback-" + vers.name,
++			config: Config{
++				MaxVersion: vers.version,
++			},
++			tls13Variant:         vers.tls13Variant,
++			expectedOCSPResponse: testOCSPResponse,
++			flags: []string{
++				"-use-ocsp-callback",
++				"-set-ocsp-in-callback",
++				"-ocsp-response",
++				base64.StdEncoding.EncodeToString(testOCSPResponse),
++			},
++			resumeSession: true,
++		})
++
++		// The callback may decline OCSP, in which case  we act as if
++		// the client did not support it, even if a response was
++		// configured.
++		tests = append(tests, testCase{
++			testType: serverTest,
++			name:     "ServerOCSPCallback-Decline-" + vers.name,
++			config: Config{
++				MaxVersion: vers.version,
++			},
++			tls13Variant:         vers.tls13Variant,
++			expectedOCSPResponse: []byte{},
++			flags: []string{
++				"-use-ocsp-callback",
++				"-decline-ocsp-callback",
++				"-ocsp-response",
++				base64.StdEncoding.EncodeToString(testOCSPResponse),
++			},
++			resumeSession: true,
++		})
++
++		// The callback may also signal an internal error.
++		tests = append(tests, testCase{
++			testType: serverTest,
++			name:     "ServerOCSPCallback-Fail-" + vers.name,
++			config: Config{
++				MaxVersion: vers.version,
++			},
++			tls13Variant: vers.tls13Variant,
++			flags: []string{
++				"-use-ocsp-callback",
++				"-fail-ocsp-callback",
++				"-ocsp-response",
++				base64.StdEncoding.EncodeToString(testOCSPResponse),
++			},
++			shouldFail:    true,
++			expectedError: ":OCSP_CB_ERROR:",
++		})
++	}
+ 
+ 	// Certificate verification tests.
+ 	for _, vers := range tlsVersions {
+diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
+index f50251d..3afb01b 100644
+--- a/ssl/test/test_config.cc
++++ b/ssl/test/test_config.cc
+@@ -133,6 +133,10 @@ const Flag<bool> kBoolFlags[] = {
+   { "-expect-draft-downgrade", &TestConfig::expect_draft_downgrade },
+   { "-handoff", &TestConfig::handoff },
+   { "-expect-dummy-pq-padding", &TestConfig::expect_dummy_pq_padding },
++  { "-use-ocsp-callback", &TestConfig::use_ocsp_callback },
++  { "-set-ocsp-in-callback", &TestConfig::set_ocsp_in_callback },
++  { "-decline-ocsp-callback", &TestConfig::decline_ocsp_callback },
++  { "-fail-ocsp-callback", &TestConfig::fail_ocsp_callback },
+ };
+ 
+ const Flag<std::string> kStringFlags[] = {
+diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
+index fb479d1..a9eec62 100644
+--- a/ssl/test/test_config.h
++++ b/ssl/test/test_config.h
+@@ -154,6 +154,10 @@ struct TestConfig {
+   int dummy_pq_padding_len = 0;
+   bool handoff = false;
+   bool expect_dummy_pq_padding = false;
++  bool use_ocsp_callback = false;
++  bool set_ocsp_in_callback = false;
++  bool decline_ocsp_callback = false;
++  bool fail_ocsp_callback = false;
+ };
+ 
+ bool ParseConfig(int argc, char **argv, TestConfig *out_initial,
+-- 
+2.7.4
+

+ 32 - 0
patches/common/boringssl/implement-SSL_get_tlsext_status_type.patch

@@ -0,0 +1,32 @@
+diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
+index d04390df..0b8677ce 100644
+--- a/include/openssl/ssl.h
++++ b/include/openssl/ssl.h
+@@ -4120,6 +4120,8 @@ extern "C++" OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb(
+ // Use |SSL_enable_ocsp_stapling| instead.
+ OPENSSL_EXPORT int SSL_set_tlsext_status_type(SSL *ssl, int type);
+ 
++OPENSSL_EXPORT int SSL_get_tlsext_status_type(SSL *ssl);
++
+ // SSL_set_tlsext_status_ocsp_resp sets the OCSP response. It returns one on
+ // success and zero on error. On success, |ssl| takes ownership of |resp|, which
+ // must have been allocated by |OPENSSL_malloc|.
+diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
+index 0c004fd4..6c849b5b 100644
+--- a/ssl/ssl_lib.cc
++++ b/ssl/ssl_lib.cc
+@@ -2723,6 +2723,14 @@ int SSL_set_tlsext_status_type(SSL *ssl, int type) {
+   return 1;
+ }
+ 
++int SSL_get_tlsext_status_type(SSL *ssl) {
++  if (ssl->ocsp_stapling_enabled) {
++    return TLSEXT_STATUSTYPE_ocsp;
++  }
++
++  return TLSEXT_STATUSTYPE_nothing;
++}
++
+ int SSL_set_tlsext_status_ocsp_resp(SSL *ssl, uint8_t *resp, size_t resp_len) {
+   if (SSL_set_ocsp_response(ssl, resp, resp_len)) {
+     OPENSSL_free(resp);

+ 468 - 0
patches/common/chromium/.patches.yaml

@@ -0,0 +1,468 @@
+repo: src
+patches:
+-
+  author: Shelley Vohr <[email protected]>
+  file: add_realloc.patch
+  description: |
+    Blink overrides ArrayBuffer's allocator with its own one, while Node simply
+    uses malloc and free, so we need to use v8's allocator in Node. As part of the
+    10.6.0 upgrade, we needed to make SerializerDelegate accept an allocator
+    argument in its constructor, and override ReallocateBufferMemory and
+    FreeBufferMemory to use the allocator. We cannot simply allocate and then memcpy
+    when we override ReallocateBufferMemory, so we therefore need to implement
+    Realloc on the v8 side and correspondingly in gin.
+-
+  author: Ales Pergl <[email protected]>
+  file: build_gn.patch
+  description: null
+-
+  author: deepak1556 <[email protected]>
+  file: dcheck.patch
+  description: |
+    This disables some debug checks which currently fail when running the Electron
+    test suite. In general there should be sustained effort to have all debug checks
+    enabled. If you want to help, choose one of the diffs below and remove it. Then
+    build Electron (debug configuration) and make sure all tests pass on the CI
+    systems. Unfortunately the tests don't always cover the check failures, so it's
+    good to also run some non-trivial Electron app to verify.
+
+    Apart from getting rid of a whole diff, you may also be able to replace one diff
+    with another which enables at least some of the previously disabled checks. For
+    example, the checks might be disabled for a whole build target, but actually
+    only one or two specific checks fail. Then it's better to simply comment out the
+    failing checks and allow the rest of the target to have them enabled.
+
+    Please keep the following lists updated.
+
+    The ELECTRON_NO_DCHECK build flag disables debug checks universally.
+    This patch applies the flag to the following GN targets:
+
+      third_party/blink/renderer/core/loader:loader
+      url:url
+
+    These files have debug checks explicitly commented out:
+
+      base/memory/weak_ptr.cc
+      base/process/kill_win.cc
+      components/viz/service/display/program_binding.h
+      components/viz/service/display_embedder/server_shared_bitmap_manager.cc
+      content/browser/frame_host/navigation_controller_impl.cc
+      content/browser/frame_host/render_frame_host_impl.cc
+      content/browser/renderer_host/render_widget_host_view_mac.mm
+      ppapi/host/ppapi_host.cc
+      third_party/blink/renderer/core/dom/node.cc
+      third_party/blink/renderer/platform/wtf/text/string_impl.cc
+      ui/base/clipboard/clipboard_win.cc
+-
+  author: Cheng Zhao <[email protected]>
+  file: accelerator.patch
+  description: null
+-
+  author: Ales Pergl <[email protected]>
+  file: allow_new_privs.patch
+  description: null
+-
+  author: null
+  file: app_indicator_icon_menu.patch
+  description: null
+-
+  author: Cheng Zhao <[email protected]>
+  file: blink_file_path.patch
+  description: null
+-
+  author: Cheng Zhao <[email protected]>
+  file: blink_local_frame.patch
+  description: |
+    According to electron/electron#3699, it is unreliable to use |unload|
+    event for process.exit('exit'), so we have to do that in
+    willReleaseScriptContext.
+
+    However Chromium then disallowed scripting in willReleaseScriptContext
+    in https://codereview.chromium.org/1657583002, and crash will happen
+    when there is code doing that.
+
+    This patch reverts the change to fix the crash in Electron.
+-
+  author: null
+  file: blink_world_context.patch
+  description: null
+-
+  author: Cheng Zhao <[email protected]>
+  file: browser_compositor_mac.patch
+  description: null
+-
+  author: null
+  file: browser_plugin_wheel.patch
+  description: null
+-
+  author: null
+  file: build_toolchain_win_patch.patch
+  description: |
+    Patch the Windows build toolchain to generate unique PDB names
+
+    When the PDB files generated by the `static_library` build are
+    packaged for distribution they are all copied to a single folder,
+    some of the PDB files have identical names so they end up
+    overwriting each other. The missing PDB files cause linker warnings
+    when building Electron in Release mode, and make it more difficult
+    to debug release builds.
+
+    This patch modifies the PDB naming convention for the
+    `static_library` build configuration to ensure PDB names are unique.
+    For example, instead of generating `obj/ui/base/base_cc.pdb` the
+    build will now generate `obj/ui/base/obj_ui_base_base_cc.pdb`.
+-
+  author: Cheng Zhao <[email protected]>
+  file: can_create_window.patch
+  description: null
+-
+  author: null
+  file: compositor_delegate.patch
+  description: null
+-
+  author: null
+  file: desktop_screen_win.patch
+  description: null
+-
+  author: Cheng Zhao <[email protected]>
+  file: disable_hidden.patch
+  description: null
+-
+  author: Cheng Zhao <[email protected]>
+  file: dom_storage_map.patch
+  description: null
+-
+  author: deepak1556 <[email protected]>
+  file: frame_host_manager.patch
+  description: null
+-
+  author: Tony Ganch <[email protected]>
+  file: latency_info.patch
+  description: null
+-
+  author: Cheng Zhao <[email protected]>
+  file: net_url_request_job.patch
+  description: null
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: no_stack_dumping.patch
+  description: null
+-
+  author: deepak1556 <[email protected]>
+  file: out_of_process_instance.patch
+  description: null
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: protobuf_build_gn.patch
+  description: null
+-
+  author: null
+  file: render_widget_host_view_base.patch
+  description: null
+-
+  author: Cheng Zhao <[email protected]>
+  file: render_widget_host_view_mac.patch
+  description: null
+-
+  author: null
+  file: scoped_clipboard_writer.patch
+  description: null
+-
+  author: deepak1556 <[email protected]>
+  file: stream_resource_handler.patch
+  description: null
+-
+  author: null
+  file: thread_capabilities.patch
+  description: |
+    Chromium automatically drops all capabilities of renderer threads in
+    Linux, which may cause issues in a context like Electron, where the main
+    and renderer threads are supposed to keep inherited permissions over the
+    system.
+
+    See https://github.com/atom/electron/issues/3666
+-
+  author: Cheng Zhao <[email protected]>
+  file: use_transparent_window.patch
+  description: null
+-
+  author: null
+  file: web_contents.patch
+  description: null
+-
+  author: Milan Burda <[email protected]>
+  file: webgl_context_attributes.patch
+  description: null
+-
+  author: null
+  file: webview_cross_drag.patch
+  description: null
+-
+  author: Cheng Zhao <[email protected]>
+  file: worker_context_will_destroy.patch
+  description: null
+-
+  author: null
+  file: webui_in_subframes.patch
+  description: null
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: export_blink_webdisplayitemlist.patch
+  description: null
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: statically_build_power_save_blocker.patch
+  description: null
+-
+  author: Tomas Rycl <[email protected]>
+  file: browser_plugin_guest.patch
+  description: null
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: disable_user_gesture_requirement_for_beforeunload_dialogs.patch
+  description: See https://github.com/electron/electron/issues/10754
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: add_atomic_lib_to_dependencies_even_for_sysroot_builds.patch
+  description: null
+-
+  author: Cheng Zhao <[email protected]>
+  file: gin_enable_disable_v8_platform.patch
+  description: null
+-
+  author: deepak1556 <[email protected]>
+  file: disable-recursive-surface-sync.patch
+  description: null
+-
+  author: deepak1556 <[email protected]>
+  file: blink-worker-enable-csp-in-file-scheme.patch
+  description: null
+-
+  author: Cheng Zhao <[email protected]>
+  file: fix-arm64-linking-error.patch
+  description: Do not use system freetype for arm64
+-
+  author: Heilig Benedek <[email protected]>
+  file: disable-redraw-lock.patch
+  description:  |
+    Chromium uses a custom window titlebar implementation on Windows when DWM
+    is disabled (Windows 7 and earlier, non Aero theme). The native titlebar
+    sometimes painted over this custom titlebar, so a workaround was put in
+    place to lock redraws in reaction to certain events if DWM is disabled,
+    since the code assumes that in that case, the custom titlebar is painted.
+    Electron forces the use of the native titlebar, which the workaround doesn't
+    take into account, and still locks redraws, causing weird repainting issues
+    in electron (and other applications). This patch provides a way to disable
+    the redraw locking mechanism, which fixes these issues. The electron issue
+    can be found at https://github.com/electron/electron/issues/1821
+-
+  author: Nitish Sakhawalkar <[email protected]>
+  file: v8_context_snapshot_generator.patch
+  description: |
+      v8_context_snapshot_generator is a build time executable.
+      The patch adds the config.
+# -
+  # author: Tomas Rycl <[email protected]>
+  # file: crashpad-disabled-windows.patch
+  # description: |
+      # On Windows Electron does not link Crashpad. This causes linking
+      # errors with Chromium where it is enabled by default.
+      # This patch will disable Crashpad in Chromium using fallback
+      # mechanism which uses Breakpad.
+-
+  author: Jeremy Apthorp <[email protected]>
+  file: boringssl_build_gn.patch
+  description: |
+    Build BoringSSL with some extra functions that nodejs needs. Only affects
+    the GN build; with the GYP build, nodejs is still built with OpenSSL.
+-
+  author: deepak1556 <[email protected]>
+  file: pepper_flash.patch
+  description: |
+    Allows building chrome pepper flash integration for Electron.
+-
+  author: Cheng Zhao <[email protected]>
+  file: no_cache_storage_check.patch
+  description: |
+    Do not check for unique origin in CacheStorage, in Electron we may have
+    scripts running without an origin.
+-
+  author: Cheng Zhao <[email protected]>
+  file: blink_fix_prototype_assert.patch
+  description: |
+    A recent Chromium change has accidentally added assertion for the case when
+    a new window object may not have a prototype attached. In Electron it may
+    happen when preventDefault for a native new-window event.
+    https://chromium.googlesource.com/chromium/src/+/f47b361887a31cccf42a6e21a82bccf28372bdaa%5E%21
+    In the long term we should investigate why it happened, and take a more
+    formal fix. But for now I'm just make this assertion silently pass away.
+-
+  author: Cheng Zhao <[email protected]>
+  file: disable_scroll_begin_dcheck.patch
+  description: |
+    When testing https://github.com/electron/electron/issues/13137 I have met
+    these assertions. I grouped them together since they are all related to the
+    ScrollBegin event.
+-
+  author: Jeremy Apthorp <[email protected]>
+  file: libgtkui_export.patch
+  description: |
+    Export libgtkui symbols for the GN component build.
+-
+  author: Jeremy Apthorp <[email protected]>
+  file: gtk_visibility.patch
+  description: |
+    Allow electron and brightray to depend on GTK in the GN build.
+-
+  author: Jeremy Apthorp <[email protected]>
+  file: sysroot.patch
+  description: |
+    Make chrome's install-sysroot scripts point to our custom sysroot builds,
+    which include extra deps that Electron needs (e.g. libnotify)
+-
+  author: Cheng Zhao <[email protected]>
+  file: mas_blink_no_private_api.patch
+  description: |
+    Guard usages in chromium code of private Mac APIs by MAS_BUILD, so they can
+    be excluded for people who want to submit their apps to the Mac App store.
+-
+  author: Cheng Zhao <[email protected]>
+  file: mas_no_private_api.patch
+  description: |
+    Guard usages in blink of private Mac APIs by MAS_BUILD, so they can be
+    excluded for people who want to submit their apps to the Mac App store.
+-
+  author: Jeremy Apthorp <[email protected]>
+  file: resource_file_conflict.patch
+  description: |
+    Resolve conflict between //chrome's .pak files and //electron's. The paths
+    that chrome code hardcodes require that we generate resources at these
+    paths, but GN throws errors if there are multiple targets that generate the
+    same files.
+-
+  author: Cheng Zhao <[email protected]>
+  file: scroll_bounce_flag.patch
+  description: |
+    Patch to make scrollBounce option work.
+-
+  author: Birunthan Mohanathas <[email protected]>
+  file: backport_d65792a.patch
+  description: |
+    https://chromium-review.googlesource.com/c/chromium/src/+/1105698
+    Fixes https://github.com/electron/electron/issues/13256
+-
+  author: Cheng Zhao <[email protected]>
+  file: webview_reattach.patch
+  description: |
+    Backports https://chromium-review.googlesource.com/c/chromium/src/+/1161391
+    Fixes webview not working after renderer process restarted.
+-
+  author: Jeremy Apthorp <[email protected]>
+  file: mas-cfisobjc.patch
+  description: |
+    Removes usage of the _CFIsObjC private API.
+-
+  author: Jeremy Apthorp <[email protected]>
+  file: mas-cgdisplayusesforcetogray.patch
+  description: |
+    Removes usage of the CGDisplayUsesForceToGray private API.
+-
+  author: Jeremy Apthorp <[email protected]>
+  file: mas-audiodeviceduck.patch
+  description: |
+    Removes usage of the AudioDeviceDuck private API.
+-
+  author: Jeremy Apthorp <[email protected]>
+  file: mas-lssetapplicationlaunchservicesserverconnectionstatus.patch
+  description: |
+    Removes usage of the _LSSetApplicationLaunchServicesServerConnectionStatus
+    private API.
+-
+  author: Cheng Zhao <[email protected]>
+  file: allow_webview_file_url.patch
+  description: |
+    Allow webview to load non-web URLs.
+-
+  author: John Kleinschmidt <[email protected]>
+  file: windows_cc_wrapper.patch
+  description: |
+    Allow use of cc_wrapper (eg sccache).
+-
+  author: Shelley Vohr <[email protected]>
+  file: enable_osr_components.patch
+  description: |
+    Add MouseWheelPhaseHandler for OSR.
+-
+  author: Zac Walker <[email protected]>
+  file: ignore_rc_check.patch
+  description: |
+    Dont compare RC.exe and RC.py output.
+    FIXME: It has to be reverted once the script is fixed.
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: enable_widevine.patch
+  description: |
+    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 <[email protected]>
+  file: content_browser_manifest.patch
+  description: |
+    Allow content_browser service to access GeolocationControl
+    interface from device service.
+-
+  author: deepak1556 <[email protected]>
+  file: chrome_key_systems.patch
+  description: |
+    Disable persiste licence support check for widevine cdm,
+    as its not supported in the current version of chrome.
+-
+  author: Charles Kerr <[email protected]>
+  file: allow_nested_error_trackers.patch
+  description: |
+    Only one X11ErrorTracker should exist at a time, but upstream has a bug
+    where two can exist if running in headless mode -- 
+      ui::(anonymous namespace)::SupportsEWMH() [inner tracker is created]
+      ui::WmSupportsHint()
+      ui::IsX11WindowFullScreen()
+      ui::ScreensaverWindowFinder::IsScreensaverWindow()
+      ui::ScreensaverWindowFinder::ShouldStopIterating()
+      ui::EnumerateTopLevelWindows()
+      ui::ScreensaverWindowFinder::ScreensaverWindowExists() [outer tracker created]
+      ui::CheckIdleStateIsLocked()
+      ui::CalculateIdleState()
+    Removal of either tracker could have side-effects in some code paths,
+    so this is probably better handled upstream. This patch tries to do the
+    least harm in the interim by removing the check that prevents more than
+    one tracker from existing at a time.
+-
+  author: Samuel Attard <[email protected]>
+  file: blink_initialization_order.patch
+  description: |
+    Backport of https://chromium-review.googlesource.com/c/chromium/src/+/1030530
+    to fix the order of V8 and Blink initialization.  Also fixes order
+    of DidCreateScriptContext notification with initialization of window globals
+    to fix electron/electron#13787.  The backport landed in Chromium 67 but the
+    DidCreateScriptContext re-ordering needs to be upstreamed or kept indefinitely
+-
+  author: zcbenz <[email protected]>
+  file: disable_detach_webview_frame.patch
+  description: |
+    Don't detach the frame for webview, we will manage the WebContents
+    manually.
+    This is part of the fixes for https://github.com/electron/electron/issues/14211.
+    We should revisit this bug after upgrading to newer versions of Chrome,
+    this patch was introduced in Chrome 66.
+-
+  author: deepak1556 <[email protected]>
+  file: ssl_security_state_tab_helper.patch
+  description: |
+    Allows populating security tab info for devtools in Electron.
+-
+  author: Jeremy Apthorp <[email protected]>
+  file: leveldb_ssize_t.patch
+  description: |
+    Fix conflict between leveldb & node's definition of ssize_t on
+    Windows by preventing leveldb from re-defining the type if it's
+    already defined.

+ 103 - 0
patches/common/chromium/accelerator.patch

@@ -0,0 +1,103 @@
+diff --git a/ui/base/accelerators/accelerator.cc b/ui/base/accelerators/accelerator.cc
+index a6756c2..5352958 100644
+--- a/ui/base/accelerators/accelerator.cc
++++ b/ui/base/accelerators/accelerator.cc
+@@ -11,6 +11,7 @@
+ #include "base/logging.h"
+ #include "base/strings/strcat.h"
+ #include "base/strings/string_util.h"
++#include "base/strings/stringprintf.h"
+ #include "base/strings/utf_string_conversions.h"
+ #include "build/build_config.h"
+ #include "ui/base/l10n/l10n_util.h"
+@@ -21,9 +22,7 @@
+ #include <windows.h>
+ #endif
+ 
+-#if !defined(OS_WIN) && (defined(USE_AURA) || defined(OS_MACOSX))
+ #include "ui/events/keycodes/keyboard_code_conversion.h"
+-#endif
+ 
+ namespace ui {
+ 
+@@ -145,7 +144,17 @@ base::string16 Accelerator::GetShortcutText() const {
+   shortcut = KeyCodeToName(key_code_);
+ #endif
+ 
++  unsigned int flags = 0;
+   if (shortcut.empty()) {
++    if (IsShiftDown())
++      flags = ui::EF_SHIFT_DOWN;
++    const uint16_t c = DomCodeToUsLayoutCharacter(
++        UsLayoutKeyboardCodeToDomCode(key_code_), flags);
++    if (c != 0) {
++      shortcut =
++          static_cast<base::string16::value_type>(
++              base::ToUpperASCII(static_cast<base::char16>(c)));
++    }
+ #if defined(OS_WIN)
+     // Our fallback is to try translate the key code to a regular character
+     // unless it is one of digits (VK_0 to VK_9). Some keyboard
+@@ -154,17 +163,20 @@ base::string16 Accelerator::GetShortcutText() const {
+     // accent' for '0'). For display in the menu (e.g. Ctrl-0 for the
+     // default zoom level), we leave VK_[0-9] alone without translation.
+     wchar_t key;
+-    if (base::IsAsciiDigit(key_code_))
++    if (base::IsAsciiDigit(key_code_)) {
+       key = static_cast<wchar_t>(key_code_);
+-    else
+-      key = LOWORD(::MapVirtualKeyW(key_code_, MAPVK_VK_TO_CHAR));
+-    shortcut += key;
+-#elif defined(USE_AURA) || defined(OS_MACOSX)
+-    const uint16_t c = DomCodeToUsLayoutCharacter(
+-        UsLayoutKeyboardCodeToDomCode(key_code_), false);
+-    if (c != 0)
+-      shortcut +=
+-          static_cast<base::string16::value_type>(base::ToUpperASCII(c));
++      shortcut = key;
++    }
++#endif
++    if (key_code_ > VKEY_F1 && key_code_ <= VKEY_F24)
++      shortcut = base::UTF8ToUTF16(
++          base::StringPrintf("F%d", key_code_ - VKEY_F1 + 1));
++  } else if (IsShiftDown()) {
++#if defined(OS_MACOSX)
++    const base::char16 kShiftSymbol[] = {0x21e7, 0};
++    shortcut = kShiftSymbol;
++#else
++    shortcut = l10n_util::GetStringFUTF16(IDS_APP_SHIFT_MODIFIER, shortcut);
+ #endif
+   }
+ 
+@@ -221,15 +233,12 @@ base::string16 Accelerator::GetShortcutText() const {
+ 
+ base::string16 Accelerator::ApplyLongFormModifiers(
+     base::string16 shortcut) const {
+-  if (IsShiftDown())
+-    shortcut = l10n_util::GetStringFUTF16(IDS_APP_SHIFT_MODIFIER, shortcut);
+-
+   // Note that we use 'else-if' in order to avoid using Ctrl+Alt as a shortcut.
+   // See http://blogs.msdn.com/oldnewthing/archive/2004/03/29/101121.aspx for
+   // more information.
+   if (IsCtrlDown())
+     shortcut = l10n_util::GetStringFUTF16(IDS_APP_CONTROL_MODIFIER, shortcut);
+-  else if (IsAltDown())
++  if (IsAltDown())
+     shortcut = l10n_util::GetStringFUTF16(IDS_APP_ALT_MODIFIER, shortcut);
+ 
+   if (IsCmdDown()) {
+@@ -249,14 +258,12 @@ base::string16 Accelerator::ApplyShortFormModifiers(
+     base::string16 shortcut) const {
+   const base::char16 kCommandSymbol[] = {0x2318, 0};
+   const base::char16 kCtrlSymbol[] = {0x2303, 0};
+-  const base::char16 kShiftSymbol[] = {0x21e7, 0};
+   const base::char16 kOptionSymbol[] = {0x2325, 0};
+   const base::char16 kNoSymbol[] = {0};
+ 
+   std::vector<base::string16> parts;
+   parts.push_back(base::string16(IsCtrlDown() ? kCtrlSymbol : kNoSymbol));
+   parts.push_back(base::string16(IsAltDown() ? kOptionSymbol : kNoSymbol));
+-  parts.push_back(base::string16(IsShiftDown() ? kShiftSymbol : kNoSymbol));
+   parts.push_back(base::string16(IsCmdDown() ? kCommandSymbol : kNoSymbol));
+   parts.push_back(shortcut);
+   return base::StrCat(parts);

+ 13 - 0
patches/common/chromium/add_atomic_lib_to_dependencies_even_for_sysroot_builds.patch

@@ -0,0 +1,13 @@
+diff --git a/base/BUILD.gn b/base/BUILD.gn
+index b674e703617d..5a7a11d816cf 100644
+--- a/base/BUILD.gn
++++ b/base/BUILD.gn
+@@ -1131,7 +1131,7 @@ component("base") {
+   # Needed for <atomic> if using newer C++ library than sysroot, except if
+   # building inside the cros_sdk environment - use host_toolchain as a
+   # more robust check for this.
+-  if (!use_sysroot && (is_android || (is_linux && !is_chromecast)) &&
++  if ((is_android || (is_linux && !is_chromecast)) &&
+       host_toolchain != "//build/toolchain/cros:host") {
+     libs = [ "atomic" ]
+   }

+ 70 - 0
patches/common/chromium/add_realloc.patch

@@ -0,0 +1,70 @@
+diff --git a/gin/array_buffer.cc b/gin/array_buffer.cc
+index f84934bfd712..63bce16a9d06 100644
+--- a/gin/array_buffer.cc
++++ b/gin/array_buffer.cc
+@@ -43,6 +43,10 @@ void* ArrayBufferAllocator::AllocateUninitialized(size_t length) {
+   return malloc(length);
+ }
+
++void* ArrayBufferAllocator::Realloc(void* data, size_t length) {
++  return realloc(data, length);
++}
++
+ void ArrayBufferAllocator::Free(void* data, size_t length) {
+   free(data);
+ }
+diff --git a/gin/array_buffer.h b/gin/array_buffer.h
+index 2aef366ac819..c037808a9bb3 100644
+--- a/gin/array_buffer.h
++++ b/gin/array_buffer.h
+@@ -21,6 +21,7 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
+  public:
+   void* Allocate(size_t length) override;
+   void* AllocateUninitialized(size_t length) override;
++  void* Realloc(void* data, size_t length) override;
+   void Free(void* data, size_t length) override;
+
+   GIN_EXPORT static ArrayBufferAllocator* SharedInstance();
+diff --git a/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.cc b/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.cc
+index 053babce1051..e33d6d4ceb5a 100644
+--- a/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.cc
++++ b/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.cc
+@@ -121,6 +121,11 @@ void* ArrayBufferContents::AllocateMemoryOrNull(size_t size,
+   return AllocateMemoryWithFlags(size, policy, base::PartitionAllocReturnNull);
+ }
+ 
++void* ArrayBufferContents::Realloc(void* data, size_t size) {
++  return Partitions::ArrayBufferPartition()->Realloc(data, size,
++      WTF_HEAP_PROFILER_TYPE_NAME(ArrayBufferContents));
++}
++
+ void ArrayBufferContents::FreeMemory(void* data) {
+   Partitions::ArrayBufferPartition()->Free(data);
+ }
+diff --git a/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h b/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h
+index 809229caa872..6248ad32d6b0 100644
+--- a/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h
++++ b/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h
+@@ -178,6 +178,7 @@ class WTF_EXPORT ArrayBufferContents {
+   void CopyTo(ArrayBufferContents& other);
+ 
+   static void* AllocateMemoryOrNull(size_t, InitializationPolicy);
++  static void* Realloc(void* data, size_t);
+   static void FreeMemory(void*);
+   static DataHandle CreateDataHandle(size_t, InitializationPolicy);
+   static void Initialize(
+diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
+index cf2762ede559..f065b5ebafb8 100644
+--- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
++++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
+@@ -555,6 +555,10 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
+         size, WTF::ArrayBufferContents::kDontInitialize);
+   }
+ 
++  void* Realloc(void* data, size_t size) override {
++    return WTF::ArrayBufferContents::Realloc(data, size);
++  }
++
+   void Free(void* data, size_t size) override {
+     WTF::ArrayBufferContents::FreeMemory(data);
+   }

+ 13 - 0
patches/common/chromium/allow_nested_error_trackers.patch

@@ -0,0 +1,13 @@
+diff --git a/ui/gfx/x/x11_error_tracker.cc b/ui/gfx/x/x11_error_tracker.cc
+index af031de356c5..2a5c18dc473a 100644
+--- a/ui/gfx/x/x11_error_tracker.cc
++++ b/ui/gfx/x/x11_error_tracker.cc
+@@ -24,7 +24,7 @@ namespace gfx {
+ X11ErrorTracker::X11ErrorTracker() {
+   // This is a non-exhaustive check for incorrect usage. It disallows nested
+   // X11ErrorTracker instances on the same thread.
+-  DCHECK(g_handler == NULL);
++  // DCHECK(g_handler == NULL);
+   g_handler = this;
+   XSync(GetXDisplay(), False);
+   old_handler_ = XSetErrorHandler(X11ErrorHandler);

+ 13 - 0
patches/common/chromium/allow_new_privs.patch

@@ -0,0 +1,13 @@
+diff --git a/base/process/launch.h b/base/process/launch.h
+index 20b76fc..9db73bf 100644
+--- a/base/process/launch.h
++++ b/base/process/launch.h
+@@ -147,7 +147,7 @@ struct BASE_EXPORT LaunchOptions {
+ 
+   // By default, child processes will have the PR_SET_NO_NEW_PRIVS bit set. If
+   // true, then this bit will not be set in the new child process.
+-  bool allow_new_privs = false;
++  bool allow_new_privs = true;
+ 
+   // Sets parent process death signal to SIGKILL.
+   bool kill_on_parent_death = false;

+ 13 - 0
patches/common/chromium/allow_webview_file_url.patch

@@ -0,0 +1,13 @@
+diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
+index 0c57d20..0916ed0 100644
+--- a/content/browser/loader/resource_dispatcher_host_impl.cc
++++ b/content/browser/loader/resource_dispatcher_host_impl.cc
+@@ -1870,6 +1870,8 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
+       !policy->IsWebSafeScheme(info.common_params.url.scheme()) &&
+       !is_external_protocol;
+ 
++  non_web_url_in_guest = false;
++
+   if (is_shutdown_ || non_web_url_in_guest ||
+       (delegate_ && !delegate_->ShouldBeginRequest(
+           info.common_params.method,

+ 13 - 0
patches/common/chromium/app_indicator_icon_menu.patch

@@ -0,0 +1,13 @@
+diff --git a/chrome/browser/ui/libgtkui/app_indicator_icon_menu.cc b/chrome/browser/ui/libgtkui/app_indicator_icon_menu.cc
+index 91674b9..8a4c391 100644
+--- a/chrome/browser/ui/libgtkui/app_indicator_icon_menu.cc
++++ b/chrome/browser/ui/libgtkui/app_indicator_icon_menu.cc
+@@ -116,7 +116,7 @@ void AppIndicatorIconMenu::OnMenuItemActivated(GtkWidget* menu_item) {
+     return;
+ 
+   // The menu item can still be activated by hotkeys even if it is disabled.
+-  if (menu_model_->IsEnabledAt(id))
++  if (model->IsEnabledAt(id))
+     ExecuteCommand(model, id);
+ }
+ 

+ 23 - 0
patches/common/chromium/backport_35dabc0.patch

@@ -0,0 +1,23 @@
+diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
+index 2417abcfdae2..13a06d02e012 100644
+--- a/content/browser/service_worker/service_worker_version.cc
++++ b/content/browser/service_worker/service_worker_version.cc
+@@ -53,9 +53,6 @@
+ #include "third_party/WebKit/public/web/WebConsoleMessage.h"
+ 
+ namespace content {
+-
+-using StatusCallback = ServiceWorkerVersion::StatusCallback;
+-
+ namespace {
+ 
+ // Timeout for an installed worker to start.
+@@ -103,7 +100,7 @@ void RunCallbacks(ServiceWorkerVersion* version,
+ 
+ // An adapter to run a |callback| after StartWorker.
+ void RunCallbackAfterStartWorker(base::WeakPtr<ServiceWorkerVersion> version,
+-                                 StatusCallback callback,
++                                 ServiceWorkerVersion::StatusCallback callback,
+                                  ServiceWorkerStatusCode status) {
+   if (status == SERVICE_WORKER_OK &&
+       version->running_status() != EmbeddedWorkerStatus::RUNNING) {

+ 64 - 0
patches/common/chromium/backport_953144.patch

@@ -0,0 +1,64 @@
+diff --git a/content/shell/browser/shell_devtools_frontend.cc b/content/shell/browser/shell_devtools_frontend.cc
+index 3b3221a..6447347 100644
+--- a/content/shell/browser/shell_devtools_frontend.cc
++++ b/content/shell/browser/shell_devtools_frontend.cc
+@@ -19,8 +19,8 @@
+ namespace {
+ static GURL GetFrontendURL() {
+   int port = ShellDevToolsManagerDelegate::GetHttpHandlerPort();
+-  return GURL(
+-      base::StringPrintf("http://127.0.0.1:%d/devtools/inspector.html", port));
++  return GURL(base::StringPrintf(
++      "http://127.0.0.1:%d/devtools/devtools_app.html", port));
+ }
+ }  // namespace
+ 
+diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn
+index 952b922..9e7b4bf 100644
+--- a/third_party/WebKit/Source/devtools/BUILD.gn
++++ b/third_party/WebKit/Source/devtools/BUILD.gn
+@@ -1048,7 +1048,6 @@
+   "$resources_out_dir/cm_modes/cm_modes_module.js",
+   "$resources_out_dir/emulated_devices/emulated_devices_module.js",
+   "$resources_out_dir/product_registry_impl/product_registry_impl_module.js",
+-  "$resources_out_dir/screencast/screencast_module.js",
+ ]
+ 
+ devtools_applications = [
+diff --git a/third_party/WebKit/Source/devtools/front_end/inspector.json b/third_party/WebKit/Source/devtools/front_end/inspector.json
+index 36c222f..dc2149a 100644
+--- a/third_party/WebKit/Source/devtools/front_end/inspector.json
++++ b/third_party/WebKit/Source/devtools/front_end/inspector.json
+@@ -1,6 +1,6 @@
+ {
+   "modules" : [
+-    { "name": "screencast", "type": "remote" }
++    { "name": "screencast", "type": "autostart" }
+   ],
+   "extends": "devtools_app",
+   "has_html": true
+diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js
+index 4c9d9aa..e6d73b1 100644
+--- a/third_party/WebKit/Source/devtools/front_end/main/Main.js
++++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
+@@ -212,19 +212,8 @@
+     this._registerForwardedShortcuts();
+     this._registerMessageSinkListener();
+ 
+-    // Pick first app we could instantiate (for test harness).
+-    for (const extension of self.runtime.extensions(Common.AppProvider)) {
+-      try {
+-        const instance = await extension.instance();
+-        if (instance) {
+-          this._showAppUI(instance);
+-          break;
+-        }
+-      } catch (e) {
+-        console.error(e);
+-      }
+-    }
+     Main.Main.timeEnd('Main._createAppUI');
++    this._showAppUI(await self.runtime.extension(Common.AppProvider).instance());
+   }
+ 
+   /**

+ 12 - 0
patches/common/chromium/backport_d65792a.patch

@@ -0,0 +1,12 @@
+diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
+index bf4b1d0..a3b72c4 100644
+@@ -995,7 +996,8 @@
+
+ void Widget::OnSizeConstraintsChanged() {
+   native_widget_->OnSizeConstraintsChanged();
+-  non_client_view_->SizeConstraintsChanged();
++  if (non_client_view_)
++    non_client_view_->SizeConstraintsChanged();
+ }
+
+ void Widget::OnOwnerClosing() {}

+ 29 - 0
patches/common/chromium/backport_ef091c206.patch

@@ -0,0 +1,29 @@
+ef091c206803ebe507755cb65a1942b097fbeb32
+diff --git a/gpu/command_buffer/service/sync_point_manager.cc b/gpu/command_buffer/service/sync_point_manager.cc
+index 7fdf99e7e134..ac0811194c24 100644
+--- a/gpu/command_buffer/service/sync_point_manager.cc
++++ b/gpu/command_buffer/service/sync_point_manager.cc
+@@ -133,7 +133,6 @@ void SyncPointOrderData::FinishProcessingOrderNumber(uint32_t order_num) {
+   }
+ 
+   for (OrderFence& order_fence : ensure_releases) {
+-    DLOG(ERROR) << "Client did not release sync token as expected";
+     order_fence.client_state->EnsureWaitReleased(order_fence.fence_release,
+                                                  order_fence.release_callback);
+   }
+@@ -156,7 +155,6 @@ bool SyncPointOrderData::ValidateReleaseOrderNumber(
+   // We should have an unprocessed order number lower than the wait order
+   // number for the wait to be valid. It's not possible for wait order number to
+   // equal next unprocessed order number, but we handle that defensively.
+-  DCHECK_NE(wait_order_num, unprocessed_order_nums_.front());
+   if (wait_order_num <= unprocessed_order_nums_.front())
+     return false;
+ 
+@@ -309,6 +307,7 @@ void SyncPointClientState::EnsureWaitReleased(uint64_t release,
+ 
+   if (call_callback) {
+     // This effectively releases the wait without releasing the fence.
++    DLOG(ERROR) << "Client did not release sync token as expected";
+     callback.Run();
+   }
+ }

+ 12 - 0
patches/common/chromium/blink-worker-enable-csp-in-file-scheme.patch

@@ -0,0 +1,12 @@
+diff --git a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
+index bdd886eff5e3..42a3f0ef6e55 100644
+--- a/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
++++ b/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc
+@@ -255,7 +255,6 @@ void WorkerScriptLoader::ProcessContentSecurityPolicy(
+   // document (which is implemented in WorkerMessagingProxy, and
+   // m_contentSecurityPolicy should be left as nullptr to inherit the policy).
+   if (!response.Url().ProtocolIs("blob") &&
+-      !response.Url().ProtocolIs("file") &&
+       !response.Url().ProtocolIs("filesystem")) {
+     content_security_policy_ = ContentSecurityPolicy::Create();
+     content_security_policy_->SetOverrideURLForSelf(response.Url());

+ 26 - 0
patches/common/chromium/blink_file_path.patch

@@ -0,0 +1,26 @@
+diff --git a/third_party/blink/renderer/core/fileapi/file.h b/third_party/blink/renderer/core/fileapi/file.h
+index 0bfe29512050..81439f7ab8f7 100644
+--- a/third_party/blink/renderer/core/fileapi/file.h
++++ b/third_party/blink/renderer/core/fileapi/file.h
+@@ -170,6 +170,9 @@ class CORE_EXPORT File final : public Blob {
+   }
+   const String& name() const { return name_; }
+ 
++  // Getter for the path IDL attribute.
++  const String& path() const { return GetPath(); }
++
+   // Getter for the lastModified IDL attribute,
+   // http://dev.w3.org/2006/webapi/FileAPI/#file-attrs
+   long long lastModified() const;
+diff --git a/third_party/blink/renderer/core/fileapi/file.idl b/third_party/blink/renderer/core/fileapi/file.idl
+index df954bc8f818..4683b2853bb4 100644
+--- a/third_party/blink/renderer/core/fileapi/file.idl
++++ b/third_party/blink/renderer/core/fileapi/file.idl
+@@ -32,6 +32,7 @@
+     Exposed=(Window,Worker)
+ ] interface File : Blob {
+     readonly attribute DOMString name;
++    readonly attribute DOMString path;
+     readonly attribute long long lastModified;
+ 
+     // Non-standard APIs

+ 17 - 0
patches/common/chromium/blink_fix_prototype_assert.patch

@@ -0,0 +1,17 @@
+cdiff --git a/third_party/blink/renderer/platform/bindings/v8_object_constructor.cc b/third_party/blink/renderer/platform/bindings/v8_object_constructor.cc
+index aedc832..8c26681 100644
+--- a/third_party/blink/renderer/platform/bindings/v8_object_constructor.cc
++++ b/third_party/blink/renderer/platform/bindings/v8_object_constructor.cc
+@@ -94,8 +94,10 @@ v8::Local<v8::Function> V8ObjectConstructor::CreateInterfaceObject(
+     bool get_prototype_value =
+         interface_object->Get(context, V8AtomicString(isolate, "prototype"))
+             .ToLocal(&prototype_value);
+-    CHECK(get_prototype_value);
+-    CHECK(prototype_value->IsObject());
++    // CHECK(get_prototype_value);
++    // CHECK(prototype_value->IsObject());
++    if (!get_prototype_value || !prototype_value->IsObject())
++      return v8::Local<v8::Function>();
+ 
+     prototype_object = prototype_value.As<v8::Object>();
+     if (prototype_object->InternalFieldCount() ==

+ 18 - 0
patches/common/chromium/blink_initialization_order.patch

@@ -0,0 +1,18 @@
+diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
+index 33d958fb31ae..47efe62650aa 100644
+--- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
++++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
+@@ -170,11 +170,11 @@ void LocalWindowProxy::Initialize() {
+                  GetFrame()->IsMainFrame());
+     MainThreadDebugger::Instance()->ContextCreated(script_state_.get(),
+                                                    GetFrame(), origin);
++
++    InstallConditionalFeatures();
+     GetFrame()->Client()->DidCreateScriptContext(context, world_->GetWorldId());
+   }
+ 
+-  InstallConditionalFeatures();
+-
+   if (World().IsMainWorld()) {
+     GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
+   }

+ 26 - 0
patches/common/chromium/blink_local_frame.patch

@@ -0,0 +1,26 @@
+diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
+index 97a5393d40b4..04f88dd2ea15 100644
+--- a/third_party/blink/renderer/core/frame/local_frame.cc
++++ b/third_party/blink/renderer/core/frame/local_frame.cc
+@@ -303,10 +303,6 @@ void LocalFrame::Detach(FrameDetachType type) {
+   }
+   CHECK(!view_ || !view_->IsAttached());
+ 
+-  // This is the earliest that scripting can be disabled:
+-  // - FrameLoader::Detach() can fire XHR abort events
+-  // - Document::Shutdown() can dispose plugins which can run script.
+-  ScriptForbiddenScope forbid_script;
+   if (!Client())
+     return;
+ 
+@@ -316,6 +312,10 @@ void LocalFrame::Detach(FrameDetachType type) {
+   // Notify ScriptController that the frame is closing, since its cleanup ends
+   // up calling back to LocalFrameClient via WindowProxy.
+   GetScriptController().ClearForClose();
++  // This is the earliest that scripting can be disabled:
++  // - FrameLoader::Detach() can fire XHR abort events
++  // - Document::Shutdown() can dispose plugins which can run script.
++  ScriptForbiddenScope forbid_script;
+ 
+   // TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes.
+   CHECK(!view_->IsAttached());

+ 45 - 0
patches/common/chromium/blink_world_context.patch

@@ -0,0 +1,45 @@
+diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+index a93834fbe86e..937b7f335693 100644
+--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
++++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+@@ -843,6 +843,13 @@ v8::Local<v8::Object> WebLocalFrameImpl::GlobalProxy() const {
+   return MainWorldScriptContext()->Global();
+ }
+ 
++v8::Local<v8::Context> WebLocalFrameImpl::WorldScriptContext(
++    v8::Isolate* isolate, int world_id) const {
++  scoped_refptr<DOMWrapperWorld> world = DOMWrapperWorld::EnsureIsolatedWorld(
++      isolate, world_id);
++  return ToScriptState(GetFrame(), *world)->GetContext();
++}
++
+ bool WebFrame::ScriptCanAccess(WebFrame* target) {
+   return BindingSecurity::ShouldAllowAccessToFrame(
+       CurrentDOMWindow(V8PerIsolateData::MainThreadIsolate()),
+diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
+index d66499296ff8..bfea68983fda 100644
+--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h
++++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
+@@ -142,6 +142,8 @@ class CORE_EXPORT WebLocalFrameImpl final
+       int argc,
+       v8::Local<v8::Value> argv[]) override;
+   v8::Local<v8::Context> MainWorldScriptContext() const override;
++  v8::Local<v8::Context> WorldScriptContext(
++      v8::Isolate* isolate, int world_id) const override;
+   v8::Local<v8::Object> GlobalProxy() const override;
+   void Reload(WebFrameLoadType) override;
+   void ReloadWithOverrideURL(const WebURL& override_url,
+diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h
+index ad0fa84f9511..69f96587b1f1 100644
+--- a/third_party/blink/public/web/web_local_frame.h
++++ b/third_party/blink/public/web/web_local_frame.h
+@@ -404,6 +404,9 @@ class WebLocalFrame : public WebFrame {
+   // be calling this API.
+   virtual v8::Local<v8::Context> MainWorldScriptContext() const = 0;
+ 
++  virtual v8::Local<v8::Context> WorldScriptContext(
++      v8::Isolate* isolate, int world_id) const = 0;
++
+   // Executes script in the context of the current page and returns the value
+   // that the script evaluated to with callback. Script execution can be
+   // suspend.

+ 18 - 0
patches/common/chromium/boringssl_build_gn.patch

@@ -0,0 +1,18 @@
+diff --git a/third_party/boringssl/BUILD.gn b/third_party/boringssl/BUILD.gn
+index c75fb7c2bb7e..423f4b2ddb10 100644
+--- a/third_party/boringssl/BUILD.gn
++++ b/third_party/boringssl/BUILD.gn
+@@ -44,6 +44,13 @@ config("no_asm_config") {
+ }
+ 
+ all_sources = crypto_sources + ssl_sources
++if (is_electron_build) {
++  # Needed to build a nodejs-compatible boringssl.
++  all_sources += [
++    "src/decrepit/evp/evp_do_all.c",
++    "src/decrepit/xts/xts.c",
++  ]
++}
+ 
+ # Windows' assembly is built with Yasm. The other platforms use the platform
+ # assembler.

+ 35 - 0
patches/common/chromium/browser_compositor_mac.patch

@@ -0,0 +1,35 @@
+diff --git a/content/browser/renderer_host/browser_compositor_view_mac.h b/content/browser/renderer_host/browser_compositor_view_mac.h
+index 7426062f7381..bd5cd2fcd230 100644
+--- a/content/browser/renderer_host/browser_compositor_view_mac.h
++++ b/content/browser/renderer_host/browser_compositor_view_mac.h
+@@ -54,10 +54,13 @@ class CONTENT_EXPORT BrowserCompositorMac : public DelegatedFrameHostClient {
+   // These will not return nullptr until Destroy is called.
+   DelegatedFrameHost* GetDelegatedFrameHost();
+ 
++  ui::Layer* GetRootLayer() { return root_layer_.get(); }
++
+   // Ensure that the currect compositor frame be cleared (even if it is
+   // potentially visible).
+   void ClearCompositorFrame();
+ 
++  ui::Compositor* GetCompositor();
+   gfx::AcceleratedWidget GetAcceleratedWidget();
+   void DidCreateNewRendererCompositorFrameSink(
+       viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink);
+diff --git a/content/browser/renderer_host/browser_compositor_view_mac.mm b/content/browser/renderer_host/browser_compositor_view_mac.mm
+index 7fcc24c15c37..7c31977b20f9 100644
+--- a/content/browser/renderer_host/browser_compositor_view_mac.mm
++++ b/content/browser/renderer_host/browser_compositor_view_mac.mm
+@@ -208,6 +208,12 @@ BrowserCompositorMac::~BrowserCompositorMac() {
+     g_spare_recyclable_compositors.Get().clear();
+ }
+ 
++ui::Compositor* BrowserCompositorMac::GetCompositor() {
++  if (recyclable_compositor_)
++    return recyclable_compositor_->compositor();
++  return nullptr;
++}
++
+ gfx::AcceleratedWidget BrowserCompositorMac::GetAcceleratedWidget() {
+   if (recyclable_compositor_) {
+     return recyclable_compositor_->accelerated_widget_mac()

+ 18 - 0
patches/common/chromium/browser_plugin_guest.patch

@@ -0,0 +1,18 @@
+diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
+index 964c9a093a3b..f3b3d66ff267 100644
+--- a/content/browser/browser_plugin/browser_plugin_guest.cc
++++ b/content/browser/browser_plugin/browser_plugin_guest.cc
+@@ -214,8 +214,11 @@ void BrowserPluginGuest::Init() {
+ 
+   WebContentsImpl* owner_web_contents = static_cast<WebContentsImpl*>(
+       delegate_->GetOwnerWebContents());
+-  owner_web_contents->CreateBrowserPluginEmbedderIfNecessary();
+-  InitInternal(BrowserPluginHostMsg_Attach_Params(), owner_web_contents);
++  if (nullptr != owner_web_contents)
++  {
++      owner_web_contents->CreateBrowserPluginEmbedderIfNecessary();
++      InitInternal(BrowserPluginHostMsg_Attach_Params(), owner_web_contents);
++  }
+ }
+ 
+ base::WeakPtr<BrowserPluginGuest> BrowserPluginGuest::AsWeakPtr() {

+ 25 - 0
patches/common/chromium/browser_plugin_wheel.patch

@@ -0,0 +1,25 @@
+diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc
+index 06762fb..e89b1f0 100644
+--- a/content/renderer/browser_plugin/browser_plugin.cc
++++ b/content/renderer/browser_plugin/browser_plugin.cc
+@@ -448,15 +448,11 @@ blink::WebInputEventResult BrowserPlugin::handleInputEvent(
+ 
+   DCHECK(!blink::WebInputEvent::IsTouchEventType(event.GetType()));
+ 
+-  // With direct event routing turned on, BrowserPlugin should almost never
+-  // see wheel events any more. The two exceptions are (1) scroll bubbling, and
+-  // (2) synthetic mouse wheels generated by touchpad GesturePinch events on
+-  // Mac, which always go to the mainframe and thus may hit BrowserPlugin if
+-  // it's in a top-level embedder. In both cases we should indicate the event
+-  // as not handled (for GesturePinch on Mac, indicating the event has been
+-  // handled leads to touchpad pinch not working).
+-  if (event.GetType() == blink::WebInputEvent::kMouseWheel)
+-    return blink::WebInputEventResult::kNotHandled;
++  if (event.GetType() == blink::WebInputEvent::kMouseWheel) {
++    auto wheel_event = static_cast<const blink::WebMouseWheelEvent&>(event);
++    if (wheel_event.resending_plugin_id == browser_plugin_instance_id_)
++      return blink::WebInputEventResult::kNotHandled;
++  }
+ 
+   if (blink::WebInputEvent::IsGestureEventType(event.GetType())) {
+     auto gesture_event = static_cast<const blink::WebGestureEvent&>(event);

+ 91 - 0
patches/common/chromium/build_gn.patch

@@ -0,0 +1,91 @@
+diff --git a/.gn b/.gn
+index 50a8a2fe9f1e..66ced79f1627 100644
+--- a/.gn
++++ b/.gn
+@@ -259,4 +259,8 @@ exec_script_whitelist =
+       # Not gypi-to-gn.
+       "//google_apis/BUILD.gn",
+       "//printing/BUILD.gn",
++      # While electron transitions to GN, we use gypi_to_gn to synchronize
++      # file lists
++      "//electron/BUILD.gn",
++      "//electron/brightray/BUILD.gn",
+     ]
+diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
+index 7d60dd920904..d2f2cbc99915 100644
+--- a/build/config/BUILDCONFIG.gn
++++ b/build/config/BUILDCONFIG.gn
+@@ -123,6 +123,10 @@ if (current_os == "") {
+ #   even if the value is overridden, which is wasteful. See first bullet.
+ 
+ declare_args() {
++  is_electron_build = false
++  is_electron_gn_build = false
++  is_mas_build = false
++
+   # Set to enable the official build level of optimization. This has nothing
+   # to do with branding, but enables an additional level of optimization above
+   # release (!is_debug). This might be better expressed as a tri-state
+@@ -539,6 +539,7 @@ default_compiler_configs = [
+   "//build/config/compiler:thin_archive",
+   "//build/config/coverage:default_coverage",
+   "//build/config/sanitizers:default_sanitizer_flags",
++  "//electron/build/config:mas_build",
+ ]
+ 
+ if (is_win) {
+@@ -642,6 +645,7 @@ template("component") {
+     _component_mode = "shared_library"
+   } else if (defined(invoker.static_component_type)) {
+     assert(invoker.static_component_type == "static_library" ||
++           (is_electron_build && invoker.static_component_type == "shared_library") ||
+            invoker.static_component_type == "source_set")
+     _component_mode = invoker.static_component_type
+   } else if (is_android || !defined(invoker.sources)) {
+diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
+index 9a10137aa405..bb33e5450eaa 100644
+--- a/build/config/compiler/BUILD.gn
++++ b/build/config/compiler/BUILD.gn
+@@ -579,10 +579,13 @@ config("compiler") {
+       ldflags += [ "-Wl,--lto-O0" ]
+     }
+ 
+-    cflags += [ "-fwhole-program-vtables" ]
+-    if (!is_win) {
+-      ldflags += [ "-fwhole-program-vtables" ]
+-    }
++    # -fwhole-program-vtables doesn't work well in Electron right now, as it's
++    # not a single binary and the optimizations break interfaces used across
++    # binary boundaries.
++    # cflags += [ "-fwhole-program-vtables" ]
++    # if (!is_win) {
++    #  ldflags += [ "-fwhole-program-vtables" ]
++    #}
+ 
+     # Work-around for http://openradar.appspot.com/20356002
+     if (is_mac) {
+diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn
+index 1f6bc13e087f..4630045ff554 100644
+--- a/build/config/win/BUILD.gn
++++ b/build/config/win/BUILD.gn
+@@ -314,7 +314,7 @@ config("cfi_linker") {
+ # See https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx for a reference of
+ # what each value does.
+ config("default_crt") {
+-  if (is_component_build) {
++  if (is_component_build || (is_electron_build && !is_electron_gn_build)) {
+     # Component mode: dynamic CRT. Since the library is shared, it requires
+     # exceptions or will give errors about things not matching, so keep
+     # exceptions on.
+diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
+index bc9fe2cc2000..9173f6f0324c 100644
+--- a/third_party/blink/renderer/platform/BUILD.gn
++++ b/third_party/blink/renderer/platform/BUILD.gn
+@@ -134,6 +134,7 @@ action("instrumentation_probes") {
+ }
+ 
+ executable("character_data_generator") {
++  configs += [ "//electron/build/config:build_time_executable" ]
+   sources = [
+     "text/character_property_data_generator.cc",
+     "text/character_property_data_generator.h",

+ 60 - 0
patches/common/chromium/build_toolchain_win_patch.patch

@@ -0,0 +1,60 @@
+diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn
+index 53f767a0bddb..661466b779e8 100644
+--- a/build/toolchain/win/BUILD.gn
++++ b/build/toolchain/win/BUILD.gn
+@@ -176,6 +176,12 @@ template("msvc_toolchain") {
+       ]
+ 
+       command = "$env_wrapper$cl /nologo /showIncludes ${clflags} $sys_include_flags{{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
++
++      if (is_electron_build && !is_component_build) {
++        pdbdir = "{{target_out_dir}}"
++        pdbname = "{{label_name}}_c.pdb"
++        command = "$python_path $tool_wrapper_path cl-wrapper $env_wrapper$cl /nologo /showIncludes ${clflags} $sys_include_flags{{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} /c {{source}} /Fo{{output}} $pdbdir \"$pdbname\""
++      }
+     }
+ 
+     tool("cxx") {
+@@ -192,6 +198,12 @@ template("msvc_toolchain") {
+       ]
+ 
+       command = "$env_wrapper$cl /nologo /showIncludes ${clflags} $sys_include_flags{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
++
++      if (is_electron_build && !is_component_build) {
++        pdbdir = "{{target_out_dir}}"
++        pdbname = "{{label_name}}_cc.pdb"
++        command = "$python_path $tool_wrapper_path cl-wrapper $env_wrapper$cl /nologo /showIncludes ${clflags} $sys_include_flags{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} /c {{source}} /Fo{{output}} $pdbdir \"$pdbname\""
++      }
+     }
+ 
+     tool("rc") {
+diff --git a/build/toolchain/win/tool_wrapper.py b/build/toolchain/win/tool_wrapper.py
+index 3a81368f3469..7c5ef1ea5db4 100644
+--- a/build/toolchain/win/tool_wrapper.py
++++ b/build/toolchain/win/tool_wrapper.py
+@@ -315,6 +315,25 @@ class WinTool(object):
+     dirname = dirname[0] if dirname else None
+     return subprocess.call(args, shell=True, env=env, cwd=dirname)
+ 
++  def ExecClWrapper(self, *args):
++    """Invokes cl.exe to compile a C/C++ source file."""
++    args = list(args)
++    # Incorporate the PDB output dir into the PDB name to ensure the PDB name
++    # is unique (see https://github.com/electron/libchromiumcontent/issues/287)
++    pdb_name = args.pop()
++    pdb_dir = args.pop()
++    pdb_filename = '%s/%s_%s' % (pdb_dir, pdb_dir.replace('/', '_'), pdb_name)
++    # On Windows when args is a sequence instead of a single string
++    # subprocess.call() will use subprocess.list2cmdline() to convert the
++    # sequence to a string. Unfortunately the double-quote escaping done by
++    # subprocess.list2cmdline() mangles the /Fd"path/to/some.pdb" arg to
++    # /Fd\"path/to/some.pdb\", and cl.exe then fails to parse the PDB filename
++    # correctly. To work around this we use subprocess.list2cmdline()
++    # (even though it's not part of the public API) to construct most of the
++    # command line, and then append the /Fd flag.
++    pdb_flag = '/Fd"%s"' % pdb_filename
++    cmdline = '%s %s' % (subprocess.list2cmdline(args), pdb_flag)
++    return subprocess.call(cmdline, shell=False)
+ 
+ if __name__ == '__main__':
+   sys.exit(main(sys.argv[1:]))

+ 235 - 0
patches/common/chromium/can_create_window.patch

@@ -0,0 +1,235 @@
+diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
+index 25841d376bcd..df41213f4c49 100644
+--- a/content/browser/frame_host/render_frame_host_impl.cc
++++ b/content/browser/frame_host/render_frame_host_impl.cc
+@@ -2874,6 +2874,38 @@ void RenderFrameHostImpl::CreateNewWindow(
+                "frame_tree_node", frame_tree_node_->frame_tree_node_id(), "url",
+                params->target_url.possibly_invalid_spec());
+ 
++  scoped_refptr<network::ResourceRequestBody> body;
++  if (params->body->has_object) {
++    body = new network::ResourceRequestBody;
++    std::vector<network::DataElement> elements;
++    for (const auto& iter : params->body->elements) {
++      network::DataElement element;
++      switch (iter->type) {
++        case network::DataElement::TYPE_BYTES: {
++          element.SetToBytes(iter->bytes.data(), iter->bytes.length());
++          break;
++        }
++        case network::DataElement::TYPE_FILE: {
++          element.SetToFilePathRange(iter->path, iter->offset, iter->length,
++                                     iter->expected_modification_time);
++          break;
++        }
++        case network::DataElement::TYPE_BLOB: {
++          element.SetToBlobRange(iter->blob_uuid, iter->offset, iter->length);
++          break;
++        }
++        case network::DataElement::TYPE_DATA_PIPE:
++        default:
++          NOTREACHED();
++          break;
++      }
++      elements.push_back(std::move(element));
++    }
++    body->swap_elements(&elements);
++    body->set_identifier(params->body->identifier);
++    body->set_contains_sensitive_info(params->body->contains_sensitive_info);
++  }
++
+   bool no_javascript_access = false;
+ 
+   // Filter out URLs to which navigation is disallowed from this context.
+@@ -2896,8 +2928,9 @@ void RenderFrameHostImpl::CreateNewWindow(
+           frame_tree_node_->frame_tree()->GetMainFrame()->GetLastCommittedURL(),
+           last_committed_origin_.GetURL(), params->window_container_type,
+           params->target_url, params->referrer, params->frame_name,
+-          params->disposition, *params->features, params->user_gesture,
+-          params->opener_suppressed, &no_javascript_access);
++          params->disposition, *params->features, params->additional_features,
++          body, params->user_gesture, params->opener_suppressed,
++          &no_javascript_access);
+ 
+   if (!can_create_window) {
+     std::move(callback).Run(mojom::CreateNewWindowStatus::kIgnore, nullptr);
+diff --git a/content/common/frame.mojom b/content/common/frame.mojom
+index 99ec7e8d7995..26a4040fba97 100644
+--- a/content/common/frame.mojom
++++ b/content/common/frame.mojom
+@@ -11,6 +11,8 @@ import "content/public/common/resource_type.mojom";
+ import "content/public/common/resource_load_info.mojom";
+ import "content/public/common/transferrable_url_loader.mojom";
+ import "content/public/common/window_container_type.mojom";
++import "mojo/public/mojom/base/file_path.mojom";
++import "mojo/public/mojom/base/time.mojom";
+ import "mojo/public/mojom/base/string16.mojom";
+ import "mojo/public/mojom/base/unguessable_token.mojom";
+ import "services/network/public/mojom/url_loader.mojom";
+@@ -146,6 +148,24 @@ interface FrameFactory {
+   CreateFrame(int32 frame_routing_id, Frame& frame);
+ };
+ 
++struct DataElement {
++  int32 type;
++  int64 length;
++  string bytes;
++  mojo_base.mojom.FilePath path;
++  int64 offset;
++  mojo_base.mojom.Time expected_modification_time;
++  url.mojom.Url filesystem_url;
++  string blob_uuid;
++};
++
++struct ResourceRequestBody {
++  bool has_object;
++  int64 identifier;
++  bool contains_sensitive_info;
++  array<DataElement> elements;
++};
++
+ struct CreateNewWindowParams {
+   // True if this open request came in the context of a user gesture.
+   bool user_gesture;
+@@ -182,6 +202,10 @@ struct CreateNewWindowParams {
+ 
+   // The window features to use for the new window.
+   blink.mojom.WindowFeatures features;
++
++  // Extra fields added by Electron.
++  array<string> additional_features;
++  ResourceRequestBody body;
+ };
+ 
+ // Operation result when the renderer asks the browser to create a new window.
+diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
+index 37e2d88e28e9..6c366435ddd8 100644
+--- a/content/public/browser/content_browser_client.cc
++++ b/content/public/browser/content_browser_client.cc
+@@ -382,6 +382,8 @@ bool ContentBrowserClient::CanCreateWindow(
+     const std::string& frame_name,
+     WindowOpenDisposition disposition,
+     const blink::mojom::WindowFeatures& features,
++    const std::vector<std::string>& additional_features,
++    const scoped_refptr<network::ResourceRequestBody>& body,
+     bool user_gesture,
+     bool opener_suppressed,
+     bool* no_javascript_access) {
+diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
+index 63cb3851db0a..4a96c8851df0 100644
+--- a/content/public/browser/content_browser_client.h
++++ b/content/public/browser/content_browser_client.h
+@@ -151,6 +151,7 @@ class RenderFrameHost;
+ class RenderProcessHost;
+ class RenderViewHost;
+ class ResourceContext;
++class ResourceRequestBody;
+ class SiteInstance;
+ class SpeechRecognitionManagerDelegate;
+ class StoragePartition;
+@@ -625,6 +626,8 @@ class CONTENT_EXPORT ContentBrowserClient {
+       const std::string& frame_name,
+       WindowOpenDisposition disposition,
+       const blink::mojom::WindowFeatures& features,
++      const std::vector<std::string>& additional_features,
++      const scoped_refptr<network::ResourceRequestBody>& body,
+       bool user_gesture,
+       bool opener_suppressed,
+       bool* no_javascript_access);
+diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
+index 7a866ded50f1..f019ce3b24bb 100644
+--- a/content/renderer/render_view_impl.cc
++++ b/content/renderer/render_view_impl.cc
+@@ -79,6 +79,7 @@
+ #include "content/renderer/input/input_handler_manager.h"
+ #include "content/renderer/internal_document_state_data.h"
+ #include "content/renderer/loader/request_extra_data.h"
++#include "content/renderer/loader/web_url_request_util.h"
+ #include "content/renderer/media/audio_device_factory.h"
+ #include "content/renderer/media/stream/media_stream_device_observer.h"
+ #include "content/renderer/media/video_capture_impl_manager.h"
+@@ -1258,6 +1259,46 @@ WebView* RenderViewImpl::CreateView(WebLocalFrame* creator,
+   }
+   params->features = ConvertWebWindowFeaturesToMojoWindowFeatures(features);
+ 
++  params->body = mojom::ResourceRequestBody::New();
++  auto body = GetRequestBodyForWebURLRequest(request);
++  if (body) {
++    params->body->has_object = true;
++    params->body->identifier = body->identifier();
++    params->body->contains_sensitive_info = body->contains_sensitive_info();
++    for (const auto& element : *body->elements()) {
++      content::mojom::DataElementPtr ptr = content::mojom::DataElement::New();
++      ptr->type = element.type();
++      switch (element.type()) {
++        case network::DataElement::TYPE_BYTES: {
++          ptr->bytes = std::string(element.bytes(), element.length());
++          break;
++        }
++        case network::DataElement::TYPE_FILE: {
++          ptr->path = element.path();
++          ptr->offset = element.offset();
++          ptr->length = element.length();
++          ptr->expected_modification_time = element.expected_modification_time();
++          break;
++        }
++        case network::DataElement::TYPE_BLOB: {
++          ptr->blob_uuid = element.blob_uuid();
++          ptr->offset = element.offset();
++          ptr->length = element.length();
++          break;
++        }
++        case network::DataElement::TYPE_CHUNKED_DATA_PIPE:
++        case network::DataElement::TYPE_RAW_FILE:
++        case network::DataElement::TYPE_DATA_PIPE:
++        case network::DataElement::TYPE_UNKNOWN:
++          NOTREACHED();
++          break;
++      }
++      params->body->elements.push_back(std::move(ptr));
++    }
++  } else {
++    params->body->has_object = false;
++  }
++
+   // We preserve this information before sending the message since |params| is
+   // moved on send.
+   bool is_background_tab =
+diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc
+index 0a1f363a673a..adcef6fca779 100644
+--- a/content/browser/security_exploit_browsertest.cc
++++ b/content/browser/security_exploit_browsertest.cc
+@@ -293,6 +293,7 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
+ 
+   mojom::CreateNewWindowParamsPtr params = mojom::CreateNewWindowParams::New();
+   params->target_url = GURL("about:blank");
++  params->body = mojom::ResourceRequestBody::New();
+   pending_rfh->CreateNewWindow(
+       std::move(params), base::BindOnce([](mojom::CreateNewWindowStatus,
+                                            mojom::CreateNewWindowReplyPtr) {}));
+diff --git a/content/shell/browser/layout_test/layout_test_content_browser_client.cc b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
+index 2eaee37ec780..9994df95a798 100644
+--- a/content/shell/browser/layout_test/layout_test_content_browser_client.cc
++++ b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
+@@ -182,6 +182,8 @@ bool LayoutTestContentBrowserClient::CanCreateWindow(
+     const std::string& frame_name,
+     WindowOpenDisposition disposition,
+     const blink::mojom::WindowFeatures& features,
++    const std::vector<std::string>& additional_features,
++    const scoped_refptr<network::ResourceRequestBody>& body,
+     bool user_gesture,
+     bool opener_suppressed,
+     bool* no_javascript_access) {
+diff --git a/content/shell/browser/layout_test/layout_test_content_browser_client.h b/content/shell/browser/layout_test/layout_test_content_browser_client.h
+index 62b637bc80ce..1a9a06ce4bf6 100644
+--- a/content/shell/browser/layout_test/layout_test_content_browser_client.h
++++ b/content/shell/browser/layout_test/layout_test_content_browser_client.h
+@@ -58,6 +58,8 @@ class LayoutTestContentBrowserClient : public ShellContentBrowserClient {
+                        const std::string& frame_name,
+                        WindowOpenDisposition disposition,
+                        const blink::mojom::WindowFeatures& features,
++                       const std::vector<std::string>& additional_features,
++                       const scoped_refptr<network::ResourceRequestBody>& body,
+                        bool user_gesture,
+                        bool opener_suppressed,
+                        bool* no_javascript_access) override;

+ 29 - 0
patches/common/chromium/chrome_key_systems.patch

@@ -0,0 +1,29 @@
+diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc
+index f3033337199b..856bc8f0b143 100644
+--- a/chrome/renderer/media/chrome_key_systems.cc
++++ b/chrome/renderer/media/chrome_key_systems.cc
+@@ -14,7 +14,9 @@
+ #include "base/strings/string_split.h"
+ #include "base/strings/utf_string_conversions.h"
+ #include "build/build_config.h"
++#if 0
+ #include "chrome/renderer/chrome_render_thread_observer.h"
++#endif
+ #include "components/cdm/renderer/external_clear_key_key_system_properties.h"
+ #include "components/cdm/renderer/widevine_key_system_properties.h"
+ #include "content/public/renderer/render_thread.h"
+@@ -140,12 +142,14 @@ static void AddExternalClearKey(
+ #if defined(WIDEVINE_CDM_AVAILABLE)
+ // Returns persistent-license session support.
+ EmeSessionTypeSupport GetPersistentLicenseSupport(bool supported_by_the_cdm) {
++#if 0
+   // Do not support persistent-license if the process cannot persist data.
+   // TODO(crbug.com/457487): Have a better plan on this. See bug for details.
+   if (ChromeRenderThreadObserver::is_incognito_process()) {
+     DVLOG(2) << __func__ << ": Not supported in incognito process.";
+     return EmeSessionTypeSupport::NOT_SUPPORTED;
+   }
++#endif
+ 
+   if (!supported_by_the_cdm) {
+     DVLOG(2) << __func__ << ": Not supported by the CDM.";

+ 72 - 0
patches/common/chromium/compositor_delegate.patch

@@ -0,0 +1,72 @@
+diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
+index 7b9fc4114c52..bdbbf93f6f0d 100644
+--- a/content/browser/compositor/gpu_process_transport_factory.cc
++++ b/content/browser/compositor/gpu_process_transport_factory.cc
+@@ -495,9 +495,19 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
+         // surfaces as they are not following the correct mode.
+         DisableGpuCompositing(compositor.get());
+       }
++
++      std::unique_ptr<viz::SoftwareOutputDevice> output_device;
++      if (compositor->delegate()) {
++        output_device = compositor->delegate()->CreateSoftwareOutputDevice(
++            compositor.get());
++      }
++      if (!output_device) {
++        output_device = CreateSoftwareOutputDevice(compositor->widget());
++      }
++
+       display_output_surface =
+           std::make_unique<SoftwareBrowserCompositorOutputSurface>(
+-              CreateSoftwareOutputDevice(compositor->widget()),
++              std::move(output_device),
+               std::move(vsync_callback), compositor->task_runner());
+     } else {
+       DCHECK(context_provider);
+diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
+index d842aa55175b..2c2131774b71 100644
+--- a/ui/compositor/compositor.h
++++ b/ui/compositor/compositor.h
+@@ -24,6 +24,7 @@
+ #include "components/viz/common/surfaces/frame_sink_id.h"
+ #include "components/viz/common/surfaces/local_surface_id.h"
+ #include "components/viz/host/host_frame_sink_client.h"
++#include "components/viz/service/display/software_output_device.h"
+ #include "third_party/skia/include/core/SkColor.h"
+ #include "third_party/skia/include/core/SkMatrix44.h"
+ #include "ui/compositor/compositor_animation_observer.h"
+@@ -182,6 +183,15 @@ class COMPOSITOR_EXPORT ContextFactory {
+   virtual void RemoveObserver(ContextFactoryObserver* observer) = 0;
+ };
+ 
++class COMPOSITOR_EXPORT CompositorDelegate {
++ public:
++  virtual std::unique_ptr<viz::SoftwareOutputDevice> CreateSoftwareOutputDevice(
++      ui::Compositor* compositor) = 0;
++
++ protected:
++  virtual ~CompositorDelegate() {}
++};
++
+ // Compositor object to take care of GPU painting.
+ // A Browser compositor object is responsible for generating the final
+ // displayable form of pixels comprising a single widget's contents. It draws an
+@@ -221,6 +231,9 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
+   // Schedules a redraw of the layer tree associated with this compositor.
+   void ScheduleDraw();
+ 
++  CompositorDelegate* delegate() const { return delegate_; }
++  void SetDelegate(CompositorDelegate* delegate) { delegate_ = delegate; }
++
+   // Sets the root of the layer tree drawn by this Compositor. The root layer
+   // must have no parent. The compositor's root layer is reset if the root layer
+   // is destroyed. NULL can be passed to reset the root layer, in which case the
+@@ -426,6 +439,8 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
+   ui::ContextFactory* context_factory_;
+   ui::ContextFactoryPrivate* context_factory_private_;
+ 
++  CompositorDelegate* delegate_ = nullptr;
++
+   // The root of the Layer tree drawn by this compositor.
+   Layer* root_layer_ = nullptr;
+ 

+ 12 - 0
patches/common/chromium/content_browser_manifest.patch

@@ -0,0 +1,12 @@
+diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json
+index 5a217fa9b741..8fd1b39ea6ca 100644
+--- a/content/public/app/mojo/content_browser_manifest.json
++++ b/content/public/app/mojo/content_browser_manifest.json
+@@ -82,6 +82,7 @@
+           "device:battery_monitor",
+           "device:generic_sensor",
+           "device:geolocation",
++          "device:geolocation_control",
+           "device:hid",
+           "device:input_service",
+           "device:nfc",

+ 48 - 0
patches/common/chromium/crashpad-disabled-windows.patch

@@ -0,0 +1,48 @@
+diff --git a/components/crash/core/common/BUILD.gn b/components/crash/core/common/BUILD.gn
+index 4f67529f5c9a..a41bdf709d99 100644
+--- a/components/crash/core/common/BUILD.gn
++++ b/components/crash/core/common/BUILD.gn
+@@ -13,7 +13,7 @@ group("common") {
+   }
+ }
+ 
+-use_crashpad = is_mac || is_win
++use_crashpad = is_mac
+ use_stubs = is_fuchsia
+ 
+ # Crashpad's annotation system can store data on a per-module basis (i.e.,
+@@ -128,7 +128,7 @@ source_set("unit_tests") {
+     sources += [ "objc_zombie_unittest.mm" ]
+   }
+ 
+-  if (!is_mac && !is_win && !is_fuchsia) {
++  if (!is_mac && !is_fuchsia) {
+     include_dirs = [ "//third_party/breakpad/breakpad/src/" ]
+     sources += [ "crash_key_breakpad_unittest.cc" ]
+   }
+diff --git a/components/crash/core/common/crash_key.h b/components/crash/core/common/crash_key.h
+index 951c7e941962..bdf6bb40e1fb 100644
+--- a/components/crash/core/common/crash_key.h
++++ b/components/crash/core/common/crash_key.h
+@@ -19,7 +19,7 @@
+ // Annotation interface. Because not all platforms use Crashpad yet, a
+ // source-compatible interface is provided on top of the older Breakpad
+ // storage mechanism.
+-#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
++#if (defined(OS_MACOSX) && !defined(OS_IOS))
+ #define USE_CRASHPAD_ANNOTATION 1
+ #endif
+ 
+diff --git a/components/crash/core/common/crash_key_breakpad.cc b/components/crash/core/common/crash_key_breakpad.cc
+index 0351e01fa18f..1c355bd89844 100644
+--- a/components/crash/core/common/crash_key_breakpad.cc
++++ b/components/crash/core/common/crash_key_breakpad.cc
+@@ -15,7 +15,7 @@
+ #include "components/crash/core/common/crash_key_base_support.h"
+ #include "components/crash/core/common/crash_key_internal.h"
+ 
+-#if defined(OS_MACOSX) || defined(OS_IOS) || defined(OS_WIN)
++#if defined(OS_MACOSX) || defined(OS_IOS)
+ #error "This file should not be used when Crashpad is available, nor on iOS."
+ #endif
+ 

+ 272 - 0
patches/common/chromium/dcheck.patch

@@ -0,0 +1,272 @@
+diff --git a/base/logging.h b/base/logging.h
+index 582fb89868cd..24d3e82232b6 100644
+--- a/base/logging.h
++++ b/base/logging.h
+@@ -850,7 +850,7 @@ const LogSeverity LOG_DCHECK = LOG_INFO;
+ 
+ #else  // !(defined(_PREFAST_) && defined(OS_WIN))
+ 
+-#if DCHECK_IS_ON()
++#if DCHECK_IS_ON() && !defined(ELECTRON_NO_DCHECK)
+ 
+ #define DCHECK(condition)                                           \
+   LAZY_STREAM(LOG_STREAM(DCHECK), !ANALYZER_ASSUME_TRUE(condition)) \
+diff --git a/base/memory/weak_ptr.cc b/base/memory/weak_ptr.cc
+index 8879651e6da7..33fe8948a063 100644
+--- a/base/memory/weak_ptr.cc
++++ b/base/memory/weak_ptr.cc
+@@ -23,8 +23,8 @@ void WeakReference::Flag::Invalidate() {
+ }
+ 
+ bool WeakReference::Flag::IsValid() const {
+-  DCHECK(sequence_checker_.CalledOnValidSequence())
+-      << "WeakPtrs must be checked on the same sequenced thread.";
++  // DCHECK(sequence_checker_.CalledOnValidSequence())
++  //    << "WeakPtrs must be checked on the same sequenced thread.";
+   return is_valid_;
+ }
+ 
+diff --git a/base/process/kill_win.cc b/base/process/kill_win.cc
+index 6a0038e2c00d..dd00dfb3e5d0 100644
+--- a/base/process/kill_win.cc
++++ b/base/process/kill_win.cc
+@@ -45,7 +45,7 @@ TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) {
+   DWORD tmp_exit_code = 0;
+ 
+   if (!::GetExitCodeProcess(handle, &tmp_exit_code)) {
+-    DPLOG(FATAL) << "GetExitCodeProcess() failed";
++    // DPLOG(FATAL) << "GetExitCodeProcess() failed";
+ 
+     // This really is a random number.  We haven't received any
+     // information about the exit code, presumably because this
+diff --git a/components/viz/service/display/program_binding.h b/components/viz/service/display/program_binding.h
+index 70f1ff97b1ac..d1abd804e988 100644
+--- a/components/viz/service/display/program_binding.h
++++ b/components/viz/service/display/program_binding.h
+@@ -416,7 +416,7 @@ class VIZ_SERVICE_EXPORT Program : public ProgramBindingBase {
+     if (!ProgramBindingBase::Init(context_provider->ContextGL(),
+                                   vertex_shader_.GetShaderString(),
+                                   fragment_shader_.GetShaderString())) {
+-      DCHECK(IsContextLost(context_provider->ContextGL()));
++      // DCHECK(IsContextLost(context_provider->ContextGL()));
+       return;
+     }
+ 
+@@ -428,7 +428,7 @@ class VIZ_SERVICE_EXPORT Program : public ProgramBindingBase {
+
+     // Link after binding uniforms
+     if (!Link(context_provider->ContextGL())) {
+-      DCHECK(IsContextLost(context_provider->ContextGL()));
++      // DCHECK(IsContextLost(context_provider->ContextGL()));
+       return;
+     }
+ 
+diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
+index ff1d3fcb6eba..ad6578f645d4 100644
+--- a/content/browser/frame_host/navigation_controller_impl.cc
++++ b/content/browser/frame_host/navigation_controller_impl.cc
+@@ -1079,8 +1079,10 @@ NavigationType NavigationControllerImpl::ClassifyNavigation(
+     return NAVIGATION_TYPE_NEW_SUBFRAME;
+   }
+ 
+-  // We only clear the session history when navigating to a new page.
+-  DCHECK(!params.history_list_was_cleared);
++  // Electron does its own book keeping of navigation entries and we
++  // expect content to not track any, by clearing history list for
++  // all navigations.
++  // DCHECK(!params.history_list_was_cleared);
+ 
+   if (rfh->GetParent()) {
+     // All manual subframes would be did_create_new_entry and handled above, so
+@@ -1301,7 +1303,10 @@ void NavigationControllerImpl::RendererDidNavigateToNewPage(
+     new_entry->GetFavicon() = GetLastCommittedEntry()->GetFavicon();
+   }
+ 
+-  DCHECK(!params.history_list_was_cleared || !replace_entry);
++  // Electron does its own book keeping of navigation entries and we
++  // expect content to not track any, by clearing history list for
++  // all navigations.
++  // DCHECK(!params.history_list_was_cleared || !replace_entry);
+   // The browser requested to clear the session history when it initiated the
+   // navigation. Now we know that the renderer has updated its state accordingly
+   // and it is safe to also clear the browser side history.
+diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
+index 346765edaef9..a30e87bfcda6 100644
+--- a/content/browser/frame_host/render_frame_host_impl.cc
++++ b/content/browser/frame_host/render_frame_host_impl.cc
+@@ -2072,8 +2073,10 @@ void RenderFrameHostImpl::AllowBindings(int bindings_flags) {
+   }
+ 
+   enabled_bindings_ |= bindings_flags;
+-  if (GetParent())
+-    DCHECK_EQ(GetParent()->GetEnabledBindings(), GetEnabledBindings());
++  // WebUI in sub frames require binding policy while the parent does not,
++  // Fix this when we use OOPIF in Electron.
++  // if (GetParent())
++  //  DCHECK_EQ(GetParent()->GetEnabledBindings(), GetEnabledBindings());
+ 
+   if (render_frame_created_) {
+     if (!frame_bindings_control_)
+diff --git a/content/browser/renderer_host/render_widget_host_view_cocoa.mm b/content/browser/renderer_host/render_widget_host_view_cocoa.mm
+index 8ee84cdafbde..c7ad6fa8c75f 100644
+--- a/content/browser/renderer_host/render_widget_host_view_cocoa.mm
++++ b/content/browser/renderer_host/render_widget_host_view_cocoa.mm
+@@ -618,8 +618,8 @@ void ExtractUnderlines(NSAttributedString* string,
+   if (EventIsReservedBySystem(theEvent))
+     return;
+ 
+-  DCHECK(eventType != NSKeyDown ||
+-         !equiv == !(modifierFlags & NSCommandKeyMask));
++  // DCHECK(eventType != NSKeyDown ||
++  //       !equiv == !(modifierFlags & NSCommandKeyMask));
+ 
+   if (eventType == NSFlagsChanged) {
+     // Ignore NSFlagsChanged events from the NumLock and Fn keys as
+diff --git a/ppapi/host/ppapi_host.cc b/ppapi/host/ppapi_host.cc
+index f3c68fab3de6..b8609daf3ef9 100644
+--- a/ppapi/host/ppapi_host.cc
++++ b/ppapi/host/ppapi_host.cc
+@@ -240,7 +240,7 @@ void PpapiHost::OnHostMsgResourceCreated(
+       CreateResourceHost(params.pp_resource(), instance, nested_msg);
+ 
+   if (!resource_host.get()) {
+-    NOTREACHED();
++    // NOTREACHED();
+     return;
+   }
+ 
+diff --git a/third_party/blink/renderer/core/loader/BUILD.gn b/third_party/blink/renderer/core/loader/BUILD.gn
+index 82f6e8bc9d33..ccad95d61a4a 100644
+--- a/third_party/blink/renderer/core/loader/BUILD.gn
++++ b/third_party/blink/renderer/core/loader/BUILD.gn
+@@ -129,4 +129,11 @@ blink_core_sources("loader") {
+   public_deps = [
+     "//third_party/blink/renderer/platform",
+   ]
++
++  if (is_electron_build) {
++    if (!defined(defines)) {
++      defines = []
++    }
++    defines += [ "ELECTRON_NO_DCHECK" ]
++  }
+ }
+diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc
+index 922a2561bcef..e31fa34f98ea 100644
+--- a/third_party/blink/renderer/core/dom/node.cc
++++ b/third_party/blink/renderer/core/dom/node.cc
+@@ -2435,7 +2435,7 @@ StaticNodeList* Node::getDestinationInsertionPoints() {
+ 
+ HTMLSlotElement* Node::AssignedSlot() const {
+   // assignedSlot doesn't need to call updateDistribution().
+-  DCHECK(!IsPseudoElement());
++  // DCHECK(!IsPseudoElement());
+   if (ShadowRoot* root = V1ShadowRootOfParent())
+     return root->AssignedSlotFor(*this);
+   return nullptr;
+diff --git a/third_party/blink/renderer/platform/wtf/text/string_impl.h b/third_party/blink/renderer/platform/wtf/text/string_impl.h
+index 158d81ca9ba2..1b6aafecadef 100644
+--- a/third_party/blink/renderer/platform/wtf/text/string_impl.h
++++ b/third_party/blink/renderer/platform/wtf/text/string_impl.h
+@@ -258,21 +258,21 @@ class WTF_EXPORT StringImpl {
+   }
+ 
+   ALWAYS_INLINE bool HasOneRef() const {
+-#if DCHECK_IS_ON()
++#if 0
+     DCHECK(IsStatic() || verifier_.IsSafeToUse()) << AsciiForDebugging();
+ #endif
+     return ref_count_ == 1;
+   }
+ 
+   ALWAYS_INLINE void AddRef() const {
+-#if DCHECK_IS_ON()
++#if 0
+     DCHECK(IsStatic() || verifier_.OnRef(ref_count_)) << AsciiForDebugging();
+ #endif
+     ++ref_count_;
+   }
+ 
+   ALWAYS_INLINE void Release() const {
+-#if DCHECK_IS_ON()
++#if 0
+     DCHECK(IsStatic() || verifier_.OnDeref(ref_count_))
+         << AsciiForDebugging() << " " << CurrentThread();
+ #endif
+diff --git a/url/BUILD.gn b/url/BUILD.gn
+index 82eb115ae666..b4806804cdbf 100644
+--- a/url/BUILD.gn
++++ b/url/BUILD.gn
+@@ -96,6 +96,10 @@ component("url") {
+     ]
+     deps += [ "//third_party/icu" ]
+   }
++
++  if (is_electron_build) {
++    defines += [ "ELECTRON_NO_DCHECK" ]
++  }
+ }
+ 
+ if (is_android) {
+diff --git a/ui/base/clipboard/clipboard_win.cc b/ui/base/clipboard/clipboard_win.cc
+index 674b0e9a909c..a1bff6e40f56 100644
+--- a/ui/base/clipboard/clipboard_win.cc
++++ b/ui/base/clipboard/clipboard_win.cc
+@@ -886,9 +886,9 @@ void ClipboardWin::WriteBitmapFromHandle(HBITMAP source_hbitmap,
+ }
+ 
+ void ClipboardWin::WriteToClipboard(unsigned int format, HANDLE handle) {
+-  DCHECK(clipboard_owner_->hwnd() != NULL);
++  // DCHECK(clipboard_owner_->hwnd() != NULL);
+   if (handle && !::SetClipboardData(format, handle)) {
+-    DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError());
++    // DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError());
+     FreeData(format, handle);
+   }
+ }
+ diff --git a/third_party/WebKit/Source/core/animation/ElementAnimations.cpp b/third_party/WebKit/Source/core/animation/ElementAnimations.cpp
+ index 60b8123cd818..dc719dd31dbf 100644
+ --- a/third_party/WebKit/Source/core/animation/ElementAnimations.cpp
+ +++ b/third_party/WebKit/Source/core/animation/ElementAnimations.cpp
+ @@ -108,7 +108,7 @@ void ElementAnimations::UpdateBaseComputedStyle(
+      base_computed_style_ = nullptr;
+      return;
+    }
+ -#if DCHECK_IS_ON()
+ +#if 0
+    if (base_computed_style_ && computed_style)
+      DCHECK(*base_computed_style_ == *computed_style);
+  #endif
+diff --git a/base/process/process_metrics_win.cc b/base/process/process_metrics_win.cc
+index faabdbf63a2a..ba56e4cd994c 100644
+--- a/base/process/process_metrics_win.cc
++++ b/base/process/process_metrics_win.cc
+@@ -179,10 +179,9 @@ bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
+ ProcessMetrics::ProcessMetrics(ProcessHandle process) : last_system_time_(0) {
+   if (process) {
+     HANDLE duplicate_handle = INVALID_HANDLE_VALUE;
+-    BOOL result = ::DuplicateHandle(::GetCurrentProcess(), process,
+-                                    ::GetCurrentProcess(), &duplicate_handle,
+-                                    PROCESS_QUERY_INFORMATION, FALSE, 0);
+-    DPCHECK(result);
++    ::DuplicateHandle(::GetCurrentProcess(), process,
++                      ::GetCurrentProcess(), &duplicate_handle,
++                      PROCESS_QUERY_INFORMATION, FALSE, 0);
+     process_.Set(duplicate_handle);
+   }
+ }
+diff --git a/components/viz/service/display_embedder/server_shared_bitmap_manager.cc b/components/viz/service/display_embedder/server_shared_bitmap_manager.cc
+index 9477a5aa45f9..895425c8c6cc 100644
+--- a/components/viz/service/display_embedder/server_shared_bitmap_manager.cc
++++ b/components/viz/service/display_embedder/server_shared_bitmap_manager.cc
+@@ -69,7 +69,9 @@ base::LazyInstance<ServerSharedBitmapManager>::DestructorAtExit
+ ServerSharedBitmapManager::ServerSharedBitmapManager() = default;
+ 
+ ServerSharedBitmapManager::~ServerSharedBitmapManager() {
+-  DCHECK(handle_map_.empty());
++  // FIXME(alexeykuzmin): Gets constantly triggered on Windows CI.
++  // Backporting https://chromium-review.googlesource.com/802574 should help.
++  // DCHECK(handle_map_.empty());
+ }
+ 
+ ServerSharedBitmapManager* ServerSharedBitmapManager::current() {

+ 13 - 0
patches/common/chromium/desktop_screen_win.patch

@@ -0,0 +1,13 @@
+diff --git a/ui/views/widget/desktop_aura/desktop_screen_win.cc b/ui/views/widget/desktop_aura/desktop_screen_win.cc
+index f772f64..7d13f9f 100644
+--- a/ui/views/widget/desktop_aura/desktop_screen_win.cc
++++ b/ui/views/widget/desktop_aura/desktop_screen_win.cc
+@@ -32,6 +32,8 @@ display::Display DesktopScreenWin::GetDisplayMatching(
+ }
+ 
+ HWND DesktopScreenWin::GetHWNDFromNativeView(gfx::NativeView window) const {
++  if (!window)
++    return NULL;
+   aura::WindowTreeHost* host = window->GetHost();
+   return host ? host->GetAcceleratedWidget() : NULL;
+ }

+ 16 - 0
patches/common/chromium/disable-recursive-surface-sync.patch

@@ -0,0 +1,16 @@
+diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
+index a9b9d180b0eb..5ad8b93114a7 100644
+--- a/content/browser/renderer_host/render_widget_host_impl.cc
++++ b/content/browser/renderer_host/render_widget_host_impl.cc
+@@ -972,6 +975,11 @@ void RenderWidgetHostImpl::PauseForPendingResizeOrRepaints() {
+   if (is_hidden())
+     return;
+ 
++  // Do not pause if there is already a pending operation with the
++  // backing store.
++  if (in_get_backing_store_)
++    return;
++
+   // Do not pause if there is not a paint or resize already coming.
+   if (!repaint_ack_pending_ && !resize_ack_pending_)
+     return;

+ 60 - 0
patches/common/chromium/disable-redraw-lock.patch

@@ -0,0 +1,60 @@
+diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
+index c8fb7eecb9c8..3d995aa331b1 100644
+--- a/ui/views/win/hwnd_message_handler.cc
++++ b/ui/views/win/hwnd_message_handler.cc
+@@ -251,6 +251,10 @@ const int kSynthesizedMouseMessagesTimeDifference = 500;
+
+ }  // namespace
+
++bool HWNDMessageHandlerDelegate::HasNativeFrame() const {
++  return false;
++}
++
+ // A scoping class that prevents a window from being able to redraw in response
+ // to invalidations that may occur within it for the lifetime of the object.
+ //
+@@ -302,6 +306,7 @@ class HWNDMessageHandler::ScopedRedrawLock {
+         cancel_unlock_(false),
+         should_lock_(owner_->IsVisible() && !owner->HasChildRenderingWindow() &&
+                      ::IsWindow(hwnd_) &&
++                     !owner_->HasNativeFrame() &&
+                      (!(GetWindowLong(hwnd_, GWL_STYLE) & WS_CAPTION) ||
+                       !ui::win::IsAeroGlassEnabled())) {
+     if (should_lock_)
+@@ -903,6 +908,10 @@ bool HWNDMessageHandler::HasChildRenderingWindow() {
+       hwnd());
+ }
+
++bool HWNDMessageHandler::HasNativeFrame() {
++  return delegate_->HasNativeFrame();
++}
++
+ ////////////////////////////////////////////////////////////////////////////////
+ // HWNDMessageHandler, gfx::WindowImpl overrides:
+
+diff --git a/ui/views/win/hwnd_message_handler.h b/ui/views/win/hwnd_message_handler.h
+index 5d5765c1928e..d77991cfa737 100644
+--- a/ui/views/win/hwnd_message_handler.h
++++ b/ui/views/win/hwnd_message_handler.h
+@@ -227,6 +227,8 @@ class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl,
+   typedef std::set<DWORD> TouchIDs;
+   enum class DwmFrameState { OFF, ON };
+
++  bool HasNativeFrame();
++
+   // Overridden from WindowImpl:
+   HICON GetDefaultWindowIcon() const override;
+   HICON GetSmallWindowIcon() const override;
+diff --git a/ui/views/win/hwnd_message_handler_delegate.h b/ui/views/win/hwnd_message_handler_delegate.h
+index d13f807e4a75..877189d63616 100644
+--- a/ui/views/win/hwnd_message_handler_delegate.h
++++ b/ui/views/win/hwnd_message_handler_delegate.h
+@@ -46,6 +46,8 @@ class VIEWS_EXPORT HWNDMessageHandlerDelegate {
+   // True if the widget associated with this window has a non-client view.
+   virtual bool HasNonClientView() const = 0;
+
++  virtual bool HasNativeFrame() const;
++
+   // Returns who we want to be drawing the frame. Either the system (Windows)
+   // will handle it or Chrome will custom draw it.
+   virtual FrameMode GetFrameMode() const = 0;

+ 17 - 0
patches/common/chromium/disable_detach_webview_frame.patch

@@ -0,0 +1,17 @@
+diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc
+index b44b0fd..a74d827 100644
+--- a/content/browser/frame_host/render_frame_proxy_host.cc
++++ b/content/browser/frame_host/render_frame_proxy_host.cc
+@@ -253,6 +253,12 @@ void RenderFrameProxyHost::SetDestructionCallback(
+ 
+ void RenderFrameProxyHost::OnDetach() {
+   if (frame_tree_node_->render_manager()->ForInnerDelegate()) {
++    // Don't detach the frame for webview, we will manage the WebContents
++    // manually.
++    // We should revisit this bug after upgrading to newer versions of Chrome,
++    // this patch was introduced in Chrome 66.
++    return;
++
+     // Only main frame proxy can detach for inner WebContents.
+     DCHECK(frame_tree_node_->IsMainFrame());
+     frame_tree_node_->render_manager()->RemoveOuterDelegateFrame();

+ 28 - 0
patches/common/chromium/disable_hidden.patch

@@ -0,0 +1,28 @@
+diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
+index 77c870b8a075..f1c4076788c5 100644
+--- a/content/browser/renderer_host/render_widget_host_impl.cc
++++ b/content/browser/renderer_host/render_widget_host_impl.cc
+@@ -664,6 +664,9 @@ void RenderWidgetHostImpl::WasHidden() {
+   if (is_hidden_)
+     return;
+ 
++  if (disable_hidden_)
++    return;
++
+   RejectMouseLockOrUnlockIfNecessary();
+ 
+   TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::WasHidden");
+diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
+index b6aa99e..ef4fa35 100644
+--- a/content/browser/renderer_host/render_widget_host_impl.h
++++ b/content/browser/renderer_host/render_widget_host_impl.h
+@@ -124,6 +124,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl : public RenderWidgetHost,
+   // RenderWidgetHostImpl.
+   static RenderWidgetHostImpl* From(RenderWidgetHost* rwh);
+ 
++  // Electron: Prevents the widget from getting hidden.
++  bool disable_hidden_ = false;
++
+   void set_hung_renderer_delay(const base::TimeDelta& delay) {
+     hung_renderer_delay_ = delay;
+   }

+ 28 - 0
patches/common/chromium/disable_scroll_begin_dcheck.patch

@@ -0,0 +1,28 @@
+diff --git a/content/browser/renderer_host/input/mouse_wheel_event_queue.cc b/content/browser/renderer_host/input/mouse_wheel_event_queue.cc
+index 5d5bead..f2ac4d8 100644
+--- a/content/browser/renderer_host/input/mouse_wheel_event_queue.cc
++++ b/content/browser/renderer_host/input/mouse_wheel_event_queue.cc
+@@ -339,7 +339,7 @@ void MouseWheelEventQueue::SendScrollBegin(
+          (synthetic && !needs_scroll_begin_when_scroll_latching_disabled_) ||
+          needs_scroll_begin_when_scroll_latching_disabled_);
+ 
+-  DCHECK(!scroll_in_progress_);
++  // DCHECK(!scroll_in_progress_);
+   scroll_in_progress_ = true;
+ 
+   WebGestureEvent scroll_begin(gesture_update);
+diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
+index 97ca37d843be..fdc4a3f90c64 100644
+--- a/content/browser/renderer_host/render_widget_host_impl.cc
++++ b/content/browser/renderer_host/render_widget_host_impl.cc
+@@ -1230,8 +1238,8 @@ void RenderWidgetHostImpl::ForwardGestureEventWithLatencyInfo(
+     // GSB and GSU events instead of sending them to the renderer and continues
+     // to progress the fling. So, the renderer doesn't receive two GSB events
+     // without any GSE in between.
+-    DCHECK(!is_in_gesture_scroll_[gesture_event.SourceDevice()] ||
+-           FlingCancellationIsDeferred());
++    // DCHECK(!is_in_gesture_scroll_[gesture_event.SourceDevice()] ||
++    //        FlingCancellationIsDeferred());
+     is_in_gesture_scroll_[gesture_event.SourceDevice()] = true;
+   } else if (gesture_event.GetType() ==
+              blink::WebInputEvent::kGestureScrollEnd) {

+ 15 - 0
patches/common/chromium/disable_user_gesture_requirement_for_beforeunload_dialogs.patch

@@ -0,0 +1,15 @@
+diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
+index a39067db8c52..4a0d69dc3fb5 100644
+--- a/third_party/blink/renderer/core/dom/document.cc
++++ b/third_party/blink/renderer/core/dom/document.cc
+@@ -3239,7 +3239,9 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient& chrome_client,
+         "Blocked attempt to show a 'beforeunload' confirmation panel for a "
+         "frame that never had a user gesture since its load. "
+         "https://www.chromestatus.com/feature/5082396709879808"));
+-    return true;
++    // TODO(alexeykuzmin): Uncomment `return true` when Electron tests are fixed.
++    // See https://github.com/electron/electron/issues/10754
++    // return true;
+   }
+ 
+   if (did_allow_navigation) {

+ 17 - 0
patches/common/chromium/dom_storage_map.patch

@@ -0,0 +1,17 @@
+diff --git a/content/common/dom_storage/dom_storage_map.cc b/content/common/dom_storage/dom_storage_map.cc
+index 0a6b0176a982..35a1c3c11a58 100644
+--- a/content/common/dom_storage/dom_storage_map.cc
++++ b/content/common/dom_storage/dom_storage_map.cc
+@@ -182,10 +182,12 @@ bool DOMStorageMap::SetItemInternal(MapType* map_type,
+   size_t new_item_size = size_in_storage(key, value);
+   size_t new_storage_used = storage_used_ - old_item_size + new_item_size;
+ 
++#if 0  // Disable localStorage size limit for Electron.
+   // Only check quota if the size is increasing, this allows
+   // shrinking changes to pre-existing files that are over budget.
+   if (new_item_size > old_item_size && new_storage_used > quota_)
+     return false;
++#endif
+ 
+   (*map_type)[key] = value;
+   ResetKeyIterator();

+ 21 - 0
patches/common/chromium/enable_osr_components.patch

@@ -0,0 +1,21 @@
+diff --git a/content/browser/renderer_host/input/mouse_wheel_phase_handler.h b/content/browser/renderer_host/input/mouse_wheel_phase_handler.h
+index 4f7c03d62930..25b74d9b5236 100644
+--- a/content/browser/renderer_host/input/mouse_wheel_phase_handler.h
++++ b/content/browser/renderer_host/input/mouse_wheel_phase_handler.h
+@@ -7,6 +7,7 @@
+ 
+ #include "base/timer/timer.h"
+ #include "content/browser/renderer_host/render_widget_host_delegate.h"
++#include "content/common/content_export.h"
+ #include "content/public/common/input_event_ack_state.h"
+ #include "third_party/blink/public/platform/web_mouse_wheel_event.h"
+ 
+@@ -55,7 +56,7 @@ enum class FirstScrollUpdateAckState {
+ // The MouseWheelPhaseHandler is responsible for adding the proper phase to
+ // wheel events. Phase information is necessary for wheel scrolling since it
+ // shows the start and end of a scrolling sequence.
+-class MouseWheelPhaseHandler {
++class CONTENT_EXPORT MouseWheelPhaseHandler {
+  public:
+   MouseWheelPhaseHandler(RenderWidgetHostViewBase* const host_view);
+   ~MouseWheelPhaseHandler() {}

+ 13 - 0
patches/common/chromium/enable_widevine.patch

@@ -0,0 +1,13 @@
+diff --git a/third_party/widevine/cdm/widevine.gni b/third_party/widevine/cdm/widevine.gni
+index 82a93622585a..cbd10bed9f3b 100644
+--- a/third_party/widevine/cdm/widevine.gni
++++ b/third_party/widevine/cdm/widevine.gni
+@@ -7,7 +7,7 @@ import("//media/media_options.gni")
+ 
+ declare_args() {
+   # Allow Widevine key system support in Chromium.
+-  enable_widevine = false
++  enable_widevine = is_mac || is_win
+ }
+ 
+ enable_widevine_cdm_host_verification =

+ 13 - 0
patches/common/chromium/exclude_next_version_mini_installer_from_deps.patch

@@ -0,0 +1,13 @@
+diff --git a/chrome/installer/mini_installer/BUILD.gn b/chrome/installer/mini_installer/BUILD.gn
+index c44f8a110599..2d48cf1ade70 100644
+--- a/chrome/installer/mini_installer/BUILD.gn
++++ b/chrome/installer/mini_installer/BUILD.gn
+@@ -331,7 +331,7 @@ if (is_win) {
+     testonly = true
+     data_deps = [
+       ":mini_installer",
+-      ":next_version_mini_installer",
++      # ":next_version_mini_installer",
+     ]
+   }
+ }

+ 21 - 0
patches/common/chromium/export_blink_webdisplayitemlist.patch

@@ -0,0 +1,21 @@
+diff --git a/third_party/blink/public/platform/web_display_item_list.h b/third_party/blink/public/platform/web_display_item_list.h
+index 31a3f6d8d5f4..0b2a13230fbd 100644
+--- a/third_party/blink/public/platform/web_display_item_list.h
++++ b/third_party/blink/public/platform/web_display_item_list.h
+@@ -6,6 +6,7 @@
+ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_DISPLAY_ITEM_LIST_H_
+ 
+ #include "third_party/blink/public/platform/web_blend_mode.h"
++#include "third_party/blink/public/platform/web_common.h"
+ #include "third_party/blink/public/platform/web_float_point.h"
+ #include "third_party/blink/public/platform/web_float_rect.h"
+ #include "third_party/blink/public/platform/web_rect.h"
+@@ -33,7 +34,7 @@ namespace blink {
+ // 'drawing' items) and operations to be performed when rendering this content
+ // (stored in 'clip', 'transform', 'filter', etc...). For more details see:
+ // http://dev.chromium.org/blink/slimming-paint.
+-class WebDisplayItemList {
++class BLINK_EXPORT WebDisplayItemList {
+  public:
+   virtual ~WebDisplayItemList() = default;
+ 

+ 13 - 0
patches/common/chromium/fix-arm64-linking-error.patch

@@ -0,0 +1,13 @@
+diff --git a/skia/BUILD.gn b/skia/BUILD.gn
+index c0477a6fe82d..3a020f2e2006 100644
+--- a/skia/BUILD.gn
++++ b/skia/BUILD.gn
+@@ -125,7 +125,7 @@ config("skia_library_config") {
+ 
+   defines = []
+ 
+-  if (!is_ios && !use_system_freetype) {
++  if (!is_ios && (is_win || is_mac)) {
+     defines += [ "SK_FREETYPE_MINIMUM_RUNTIME_VERSION=(((FREETYPE_MAJOR) * 0x01000000) | ((FREETYPE_MINOR) * 0x00010000) | ((FREETYPE_PATCH) * 0x00000100))" ]
+   }
+ 

+ 83 - 0
patches/common/chromium/frame_host_manager.patch

@@ -0,0 +1,83 @@
+diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
+index e6f6b3012b02..965b58e237ec 100644
+--- a/content/browser/frame_host/render_frame_host_manager.cc
++++ b/content/browser/frame_host/render_frame_host_manager.cc
+@@ -1834,6 +1834,18 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
+   bool was_server_redirect = request.navigation_handle() &&
+                              request.navigation_handle()->WasServerRedirect();
+ 
++  BrowserContext* browser_context =
++      delegate_->GetControllerForRenderManager().GetBrowserContext();
++  // If the navigation can swap SiteInstances, compute the SiteInstance it
++  // should use.
++  // TODO(clamy): We should also consider as a candidate SiteInstance the
++  // speculative SiteInstance that was computed on redirects.
++  scoped_refptr<SiteInstance> candidate_site_instance =
++      speculative_render_frame_host_
++          ? speculative_render_frame_host_->GetSiteInstance()
++          : content::SiteInstance::CreateForURL(browser_context,
++                                                request.common_params().url);
++
+   if (frame_tree_node_->IsMainFrame()) {
+     // Renderer-initiated main frame navigations that may require a
+     // SiteInstance swap are sent to the browser via the OpenURL IPC and are
+@@ -1850,6 +1862,19 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
+ 
+     no_renderer_swap_allowed |=
+         request.from_begin_navigation() && !can_renderer_initiate_transfer;
++
++    bool has_response_started =
++        (request.state() == NavigationRequest::RESPONSE_STARTED ||
++         request.state() == NavigationRequest::FAILED) &&
++        !speculative_render_frame_host_;
++    // Gives user a chance to choose a custom site instance.
++    SiteInstance* client_custom_instance = nullptr;
++    GetContentClient()->browser()->OverrideSiteInstanceForNavigation(
++        render_frame_host_.get(), browser_context, request.common_params().url,
++        has_response_started, candidate_site_instance.get(),
++        &client_custom_instance);
++    if (client_custom_instance)
++      return scoped_refptr<SiteInstance>(client_custom_instance);
+   } else {
+     // Subframe navigations will use the current renderer, unless specifically
+     // allowed to swap processes.
+@@ -1861,18 +1886,9 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
+   if (no_renderer_swap_allowed)
+     return scoped_refptr<SiteInstance>(current_site_instance);
+ 
+-  // If the navigation can swap SiteInstances, compute the SiteInstance it
+-  // should use.
+-  // TODO(clamy): We should also consider as a candidate SiteInstance the
+-  // speculative SiteInstance that was computed on redirects.
+-  SiteInstance* candidate_site_instance =
+-      speculative_render_frame_host_
+-          ? speculative_render_frame_host_->GetSiteInstance()
+-          : nullptr;
+-
+   scoped_refptr<SiteInstance> dest_site_instance = GetSiteInstanceForNavigation(
+       request.common_params().url, request.source_site_instance(),
+-      request.dest_site_instance(), candidate_site_instance,
++      request.dest_site_instance(), candidate_site_instance.get(),
+       request.common_params().transition,
+       request.restore_type() != RestoreType::NONE, request.is_view_source(),
+       was_server_redirect);
+diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
+index 746760e8596c..99d9e0770f32 100644
+--- a/content/public/browser/content_browser_client.h
++++ b/content/public/browser/content_browser_client.h
+@@ -181,6 +181,15 @@ class CONTENT_EXPORT ContentBrowserClient {
+  public:
+   virtual ~ContentBrowserClient() {}
+ 
++  // Electron: Allows overriding the SiteInstance when navigating.
++  virtual void OverrideSiteInstanceForNavigation(
++      RenderFrameHost* render_frame_host,
++      BrowserContext* browser_context,
++      const GURL& dest_url,
++      bool has_response_started,
++      SiteInstance* candidate_site_instance,
++      SiteInstance** new_instance) {}
++
+   // Allows the embedder to set any number of custom BrowserMainParts
+   // implementations for the browser startup code. See comments in
+   // browser_main_parts.h.

+ 66 - 0
patches/common/chromium/gin_enable_disable_v8_platform.patch

@@ -0,0 +1,66 @@
+diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc
+index 56402d477ca3..8ab11bd18783 100644
+--- a/gin/isolate_holder.cc
++++ b/gin/isolate_holder.cc
+@@ -116,9 +116,10 @@ IsolateHolder::~IsolateHolder() {
+ void IsolateHolder::Initialize(ScriptMode mode,
+                                V8ExtrasMode v8_extras_mode,
+                                v8::ArrayBuffer::Allocator* allocator,
+-                               const intptr_t* reference_table) {
++                               const intptr_t* reference_table,
++                               bool create_v8_platform) {
+   CHECK(allocator);
+-  V8Initializer::Initialize(mode, v8_extras_mode);
++  V8Initializer::Initialize(mode, v8_extras_mode, create_v8_platform);
+   g_array_buffer_allocator = allocator;
+   g_reference_table = reference_table;
+ }
+diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h
+index 2509aca609f9..94003c6031cf 100644
+--- a/gin/public/isolate_holder.h
++++ b/gin/public/isolate_holder.h
+@@ -84,7 +84,8 @@ class GIN_EXPORT IsolateHolder {
+   static void Initialize(ScriptMode mode,
+                          V8ExtrasMode v8_extras_mode,
+                          v8::ArrayBuffer::Allocator* allocator,
+-                         const intptr_t* reference_table = nullptr);
++                         const intptr_t* reference_table = nullptr,
++                         bool create_v8_platform = true);
+ 
+   v8::Isolate* isolate() { return isolate_; }
+ 
+diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
+index 02d4b1cd6521..ec6d51d7e5d8 100644
+--- a/gin/v8_initializer.cc
++++ b/gin/v8_initializer.cc
+@@ -236,12 +236,14 @@ LoadV8FileResult MapOpenedFile(const OpenedFileMap::mapped_type& file_region,
+ 
+ // static
+ void V8Initializer::Initialize(IsolateHolder::ScriptMode mode,
+-                               IsolateHolder::V8ExtrasMode v8_extras_mode) {
++                               IsolateHolder::V8ExtrasMode v8_extras_mode,
++                               bool create_v8_platform) {
+   static bool v8_is_initialized = false;
+   if (v8_is_initialized)
+     return;
+ 
+-  v8::V8::InitializePlatform(V8Platform::Get());
++  if (create_v8_platform)
++    v8::V8::InitializePlatform(V8Platform::Get());
+ 
+   if (base::FeatureList::IsEnabled(features::kV8OptimizeJavascript)) {
+     static const char optimize[] = "--opt";
+diff --git a/gin/v8_initializer.h b/gin/v8_initializer.h
+index f0a7c5e0fb68..df4ab4f3e4b9 100644
+--- a/gin/v8_initializer.h
++++ b/gin/v8_initializer.h
+@@ -21,7 +21,8 @@ class GIN_EXPORT V8Initializer {
+  public:
+   // This should be called by IsolateHolder::Initialize().
+   static void Initialize(IsolateHolder::ScriptMode mode,
+-                         IsolateHolder::V8ExtrasMode v8_extras_mode);
++                         IsolateHolder::V8ExtrasMode v8_extras_mode,
++                         bool create_v8_platform = true);
+ 
+   // Get address and size information for currently loaded snapshot.
+   // If no snapshot is loaded, the return values are null for addresses

+ 13 - 0
patches/common/chromium/gtk_visibility.patch

@@ -0,0 +1,13 @@
+diff --git a/build/config/linux/gtk/BUILD.gn b/build/config/linux/gtk/BUILD.gn
+index eb75461..2116f93 100644
+--- a/build/config/linux/gtk/BUILD.gn
++++ b/build/config/linux/gtk/BUILD.gn
+@@ -17,6 +17,8 @@ assert(is_linux, "This file should only be referenced on Linux")
+ group("gtk") {
+   visibility = [
+     "//chrome/test:interactive_ui_tests",
++    "//electron:*",
++    "//electron/brightray:*",
+     "//examples:peerconnection_client",
+     "//gpu/gles2_conform_support:gles2_conform_test_windowless",
+     "//remoting/host",

+ 17 - 0
patches/common/chromium/ignore_rc_check.patch

@@ -0,0 +1,17 @@
+diff --git a/build/toolchain/win/tool_wrapper.py b/build/toolchain/win/tool_wrapper.py
+index a76e926a8681..c43839a01211 100644
+--- a/build/toolchain/win/tool_wrapper.py
++++ b/build/toolchain/win/tool_wrapper.py
+@@ -258,7 +258,11 @@ class WinTool(object):
+       if rc_exe_exit_code == 0:
+         import filecmp
+         # Strip "/fo" prefix.
+-        assert filecmp.cmp(rc_res_output[3:], rcpy_res_output[3:])
++        # ------
++        # Temporarily ignore compares
++        # Nightly builds use very large version numbers that fail this check
++        # FIXME(zacwalk): Enable the assert.
++        # assert filecmp.cmp(rc_res_output[3:], rcpy_res_output[3:])
+     return rc_exe_exit_code
+ 
+   def ExecActionWrapper(self, arch, rspfile, *dirname):

+ 101 - 0
patches/common/chromium/latency_info.patch

@@ -0,0 +1,101 @@
+diff --git a/ui/latency/BUILD.gn b/ui/latency/BUILD.gn
+index 2aeebd991ae3..27cacb8748c4 100644
+--- a/ui/latency/BUILD.gn
++++ b/ui/latency/BUILD.gn
+@@ -5,7 +5,7 @@
+ import("//build/config/jumbo.gni")
+ import("//testing/test.gni")
+ 
+-jumbo_source_set("latency") {
++component("latency") {
+   sources = [
+     "fixed_point.cc",
+     "fixed_point.h",
+@@ -18,6 +18,7 @@ jumbo_source_set("latency") {
+     "latency_tracker.h",
+     "stream_analyzer.cc",
+     "stream_analyzer.h",
++    "ui_latency_export.h",
+     "windowed_analyzer.cc",
+     "windowed_analyzer.h",
+   ]
+@@ -22,6 +23,8 @@ jumbo_source_set("latency") {
+   public_deps = [
+     "//services/metrics/public/cpp:metrics_cpp",
+   ]
++
++  defines = [ "UI_LATENCY_IMPLEMENTATION" ]
+ }
+ 
+ jumbo_source_set("test_support") {
+diff --git a/ui/latency/latency_info.h b/ui/latency/latency_info.h
+index d9d390861562..7b1aa99e8a9c 100644
+--- a/ui/latency/latency_info.h
++++ b/ui/latency/latency_info.h
+@@ -16,6 +16,7 @@
+ #include "base/time/time.h"
+ #include "services/metrics/public/cpp/ukm_source_id.h"
+ #include "ui/gfx/geometry/point_f.h"
++#include "ui/latency/ui_latency_export.h"
+ 
+ #if !defined(OS_IOS)
+ #include "ipc/ipc_param_traits.h"  // nogncheck
+@@ -114,7 +115,7 @@ enum SourceEventType {
+   SOURCE_EVENT_TYPE_LAST = OTHER,
+ };
+ 
+-class LatencyInfo {
++class UI_LATENCY_EXPORT LatencyInfo {
+  public:
+   struct LatencyComponent {
+     // Nondecreasing number that can be used to determine what events happened
+diff --git a/ui/latency/latency_tracker.h b/ui/latency/latency_tracker.h
+index 24397fc4ba6d..ad943fa7ccf7 100644
+--- a/ui/latency/latency_tracker.h
++++ b/ui/latency/latency_tracker.h
+@@ -8,12 +8,13 @@
+ #include "base/macros.h"
+ #include "services/metrics/public/cpp/ukm_source_id.h"
+ #include "ui/latency/latency_info.h"
++#include "ui/latency/ui_latency_export.h"
+ 
+ namespace ui {
+ 
+ // Utility class for tracking the latency of events. Relies on LatencyInfo
+ // components logged by content::RenderWidgetHostLatencyTracker.
+-class LatencyTracker {
++class UI_LATENCY_EXPORT LatencyTracker {
+  public:
+   explicit LatencyTracker(bool metric_sampling,
+                           ukm::SourceId ukm_source_id = ukm::kInvalidSourceId);
+diff --git a/ui/latency/ui_latency_export.h b/ui/latency/ui_latency_export.h
+new file mode 100644
+index 0000000..f24ee91
+--- /dev/null
++++ b/ui/latency/ui_latency_export.h
+@@ -0,0 +1,25 @@
++#ifndef UI_LATENCY_UI_LATENCY_EXPORT_H_
++#define UI_LATENCY_UI_LATENCY_EXPORT_H_
++
++#if defined(COMPONENT_BUILD)
++#if defined(WIN32)
++
++#if defined(UI_LATENCY_IMPLEMENTATION)
++#define UI_LATENCY_EXPORT __declspec(dllexport)
++#else
++#define UI_LATENCY_EXPORT __declspec(dllimport)
++#endif  // defined(UI_LATENCY_IMPLEMENTATION)
++
++#else  // defined(WIN32)
++#if defined(UI_LATENCY_IMPLEMENTATION)
++#define UI_LATENCY_EXPORT __attribute__((visibility("default")))
++#else
++#define UI_LATENCY_EXPORT
++#endif
++#endif
++
++#else  // defined(COMPONENT_BUILD)
++#define UI_LATENCY_EXPORT
++#endif
++
++#endif  // UI_LATENCY_UI_LATENCY_EXPORT_H_

+ 16 - 0
patches/common/chromium/leveldb_ssize_t.patch

@@ -0,0 +1,16 @@
+diff --git a/third_party/leveldatabase/port/port_chromium.h b/third_party/leveldatabase/port/port_chromium.h
+index a7c449eba19c..acbce7efd582 100644
+--- a/third_party/leveldatabase/port/port_chromium.h
++++ b/third_party/leveldatabase/port/port_chromium.h
+@@ -26,7 +26,11 @@
+ #endif
+ 
+ #if defined(OS_WIN)
++#  if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED)
+ typedef SSIZE_T ssize_t;
++#  define _SSIZE_T_
++#  define _SSIZE_T_DEFINED
++#  endif
+ #endif
+ 
+ namespace leveldb {

+ 125 - 0
patches/common/chromium/libgtkui_export.patch

@@ -0,0 +1,125 @@
+diff --git a/chrome/browser/ui/libgtkui/app_indicator_icon.h b/chrome/browser/ui/libgtkui/app_indicator_icon.h
+index 7815fbb..f17a5c5 100644
+--- a/chrome/browser/ui/libgtkui/app_indicator_icon.h
++++ b/chrome/browser/ui/libgtkui/app_indicator_icon.h
+@@ -12,6 +12,7 @@
+ #include "base/memory/weak_ptr.h"
+ #include "base/nix/xdg_util.h"
+ #include "chrome/browser/ui/libgtkui/gtk_signal.h"
++#include "chrome/browser/ui/libgtkui/libgtkui_export.h"
+ #include "ui/views/linux_ui/status_icon_linux.h"
+ 
+ typedef struct _AppIndicator AppIndicator;
+@@ -31,7 +32,7 @@ namespace libgtkui {
+ class AppIndicatorIconMenu;
+ 
+ // Status icon implementation which uses libappindicator.
+-class AppIndicatorIcon : public views::StatusIconLinux {
++class LIBGTKUI_EXPORT AppIndicatorIcon : public views::StatusIconLinux {
+  public:
+   // The id uniquely identifies the new status icon from other chrome status
+   // icons.
+diff --git a/chrome/browser/ui/libgtkui/gtk_status_icon.h b/chrome/browser/ui/libgtkui/gtk_status_icon.h
+index e4e0da4..af02871 100644
+--- a/chrome/browser/ui/libgtkui/gtk_status_icon.h
++++ b/chrome/browser/ui/libgtkui/gtk_status_icon.h
+@@ -10,6 +10,7 @@
+ #include "base/macros.h"
+ #include "base/strings/string16.h"
+ #include "chrome/browser/ui/libgtkui/gtk_signal.h"
++#include "chrome/browser/ui/libgtkui/libgtkui_export.h"
+ #include "ui/base/glib/glib_integers.h"
+ #include "ui/base/glib/glib_signal.h"
+ #include "ui/views/linux_ui/status_icon_linux.h"
+@@ -29,7 +30,7 @@ class AppIndicatorIconMenu;
+ 
+ // Status icon implementation which uses the system tray X11 spec (via
+ // GtkStatusIcon).
+-class Gtk2StatusIcon : public views::StatusIconLinux {
++class LIBGTKUI_EXPORT Gtk2StatusIcon : public views::StatusIconLinux {
+  public:
+   Gtk2StatusIcon(const gfx::ImageSkia& image, const base::string16& tool_tip);
+   ~Gtk2StatusIcon() override;
+diff --git a/chrome/browser/ui/libgtkui/gtk_util.h b/chrome/browser/ui/libgtkui/gtk_util.h
+index 665ec57..4ccb088 100644
+--- a/chrome/browser/ui/libgtkui/gtk_util.h
++++ b/chrome/browser/ui/libgtkui/gtk_util.h
+@@ -11,6 +11,7 @@
+ #include "ui/base/glib/scoped_gobject.h"
+ #include "ui/native_theme/native_theme.h"
+ #include "ui/views/window/frame_buttons.h"
++#include "chrome/browser/ui/libgtkui/libgtkui_export.h"
+ 
+ namespace aura {
+ class Window;
+@@ -51,10 +52,10 @@ SkColor NormalURLColor(SkColor foreground);
+ // saturation than to look exactly like the foreground color.
+ SkColor SelectedURLColor(SkColor foreground, SkColor background);
+ 
+-void GtkInitFromCommandLine(const base::CommandLine& command_line);
++LIBGTKUI_EXPORT void GtkInitFromCommandLine(const base::CommandLine& command_line);
+ 
+ // Returns the name of the ".desktop" file associated with our running process.
+-std::string GetDesktopName(base::Environment* env);
++LIBGTKUI_EXPORT std::string GetDesktopName(base::Environment* env);
+ 
+ guint GetGdkKeyCodeForAccelerator(const ui::Accelerator& accelerator);
+ 
+@@ -69,7 +70,7 @@ void TurnButtonBlue(GtkWidget* button);
+ 
+ // Sets |dialog| as transient for |parent|, which will keep it on top and center
+ // it above |parent|. Do nothing if |parent| is nullptr.
+-void SetGtkTransientForAura(GtkWidget* dialog, aura::Window* parent);
++LIBGTKUI_EXPORT void SetGtkTransientForAura(GtkWidget* dialog, aura::Window* parent);
+ 
+ // Gets the transient parent aura window for |dialog|.
+ aura::Window* GetAuraTransientParent(GtkWidget* dialog);
+diff --git a/chrome/browser/ui/libgtkui/skia_utils_gtk.h b/chrome/browser/ui/libgtkui/skia_utils_gtk.h
+index e05fbe9..3afca9a 100644
+--- a/chrome/browser/ui/libgtkui/skia_utils_gtk.h
++++ b/chrome/browser/ui/libgtkui/skia_utils_gtk.h
+@@ -7,6 +7,7 @@
+ 
+ #include <stdint.h>
+ 
++#include "chrome/browser/ui/libgtkui/libgtkui_export.h"
+ #include "third_party/skia/include/core/SkColor.h"
+ 
+ typedef struct _GdkColor GdkColor;
+@@ -41,7 +42,7 @@ const SkBitmap GdkPixbufToImageSkia(GdkPixbuf* pixbuf);
+ // Convert and copy a SkBitmap to a GdkPixbuf. NOTE: this uses BGRAToRGBA, so
+ // it is an expensive operation.  The returned GdkPixbuf will have a refcount of
+ // 1, and the caller is responsible for unrefing it when done.
+-GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap);
++LIBGTKUI_EXPORT GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap);
+ 
+ }  // namespace libgtkui
+ 
+diff --git a/chrome/browser/ui/libgtkui/unity_service.h b/chrome/browser/ui/libgtkui/unity_service.h
+index 8d67e14..95fbb27 100644
+--- a/chrome/browser/ui/libgtkui/unity_service.h
++++ b/chrome/browser/ui/libgtkui/unity_service.h
+@@ -5,18 +5,20 @@
+ #ifndef CHROME_BROWSER_UI_LIBGTKUI_UNITY_SERVICE_H_
+ #define CHROME_BROWSER_UI_LIBGTKUI_UNITY_SERVICE_H_
+ 
++#include "chrome/browser/ui/libgtkui/libgtkui_export.h"
++
+ namespace unity {
+ 
+ // Returns whether unity is currently running.
+-bool IsRunning();
++LIBGTKUI_EXPORT bool IsRunning();
+ 
+ // If unity is running, sets the download counter in the dock icon. Any value
+ // other than 0 displays the badge.
+-void SetDownloadCount(int count);
++LIBGTKUI_EXPORT void SetDownloadCount(int count);
+ 
+ // If unity is running, sets the download progress bar in the dock icon. Any
+ // value between 0.0 and 1.0 (exclusive) shows the progress bar.
+-void SetProgressFraction(float percentage);
++LIBGTKUI_EXPORT void SetProgressFraction(float percentage);
+ 
+ }  // namespace unity
+ 

+ 47 - 0
patches/common/chromium/mas-audiodeviceduck.patch

@@ -0,0 +1,47 @@
+From d322e351554a4fa1fbaf529769416041031f07e9 Mon Sep 17 00:00:00 2001
+From: Jeremy Apthorp <[email protected]>
+Date: Mon, 6 Aug 2018 13:02:53 -0700
+Subject: fix: [mas] don't call private api AudioDeviceDuck
+
+---
+ media/audio/mac/audio_low_latency_input_mac.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/media/audio/mac/audio_low_latency_input_mac.cc b/media/audio/mac/audio_low_latency_input_mac.cc
+index 173167b54dfb..1c0fda354d03 100644
+--- a/media/audio/mac/audio_low_latency_input_mac.cc
++++ b/media/audio/mac/audio_low_latency_input_mac.cc
+@@ -28,12 +28,14 @@
+ 
+ namespace {
+ extern "C" {
++#ifndef MAS_BUILD
+ // See:
+ // https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/PAL/pal/spi/cf/CoreAudioSPI.h?rev=228264
+ OSStatus AudioDeviceDuck(AudioDeviceID inDevice,
+                          Float32 inDuckedLevel,
+                          const AudioTimeStamp* __nullable inStartTime,
+                          Float32 inRampDuration) __attribute__((weak_import));
++#endif
+ }
+ 
+ }  // namespace
+@@ -604,6 +606,7 @@ bool AUAudioInputStream::OpenVoiceProcessingAU() {
+     return false;
+   }
+ 
++#ifndef MAS_BUILD
+   if (AudioDeviceDuck != nullptr) {
+     // Undo the ducking.
+     // Obtain the AudioDeviceID of the default output AudioDevice.
+@@ -619,6 +622,7 @@ bool AUAudioInputStream::OpenVoiceProcessingAU() {
+       AudioDeviceDuck(output_device, 1.0, nullptr, 0.5);
+     }
+   }
++#endif
+ 
+   return true;
+ }
+-- 
+2.17.0
+

+ 44 - 0
patches/common/chromium/mas-cfisobjc.patch

@@ -0,0 +1,44 @@
+From 9fb1ac04b1a3e7ec53e27cf1f413469d04360d1e Mon Sep 17 00:00:00 2001
+From: Jeremy Apthorp <[email protected]>
+Date: Mon, 6 Aug 2018 17:11:14 -0700
+Subject: fix: [mas] remove usage of _CFIsObjC
+
+---
+ base/mac/foundation_util.mm | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/base/mac/foundation_util.mm b/base/mac/foundation_util.mm
+index aec8c0f6398c..6a6dfc272d45 100644
+--- a/base/mac/foundation_util.mm
++++ b/base/mac/foundation_util.mm
+@@ -25,7 +25,6 @@
+ extern "C" {
+ CFTypeID SecACLGetTypeID();
+ CFTypeID SecTrustedApplicationGetTypeID();
+-Boolean _CFIsObjC(CFTypeID typeID, CFTypeRef obj);
+ }  // extern "C"
+ #endif
+ 
+@@ -323,8 +322,7 @@ NSFont* CFToNSCast(CTFontRef cf_val) {
+       const_cast<NSFont*>(reinterpret_cast<const NSFont*>(cf_val));
+   DCHECK(!cf_val ||
+          CTFontGetTypeID() == CFGetTypeID(cf_val) ||
+-         (_CFIsObjC(CTFontGetTypeID(), cf_val) &&
+-          [ns_val isKindOfClass:[NSFont class]]));
++         ([ns_val isKindOfClass:[NSFont class]]));
+   return ns_val;
+ }
+ 
+@@ -392,9 +390,6 @@ CFCast<CTFontRef>(const CFTypeRef& cf_val) {
+     return (CTFontRef)(cf_val);
+   }
+ 
+-  if (!_CFIsObjC(CTFontGetTypeID(), cf_val))
+-    return NULL;
+-
+   id<NSObject> ns_val = reinterpret_cast<id>(const_cast<void*>(cf_val));
+   if ([ns_val isKindOfClass:[NSFont class]]) {
+     return (CTFontRef)(cf_val);
+-- 
+2.17.0
+

+ 34 - 0
patches/common/chromium/mas-cgdisplayusesforcetogray.patch

@@ -0,0 +1,34 @@
+From 82d0ef64e22c69c0435608276149977d2811a3f7 Mon Sep 17 00:00:00 2001
+From: Jeremy Apthorp <[email protected]>
+Date: Mon, 6 Aug 2018 10:58:46 -0700
+Subject: fix: [mas] remove usage of CGDisplayUsesForceToGray
+
+---
+ ui/display/mac/screen_mac.mm | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/ui/display/mac/screen_mac.mm b/ui/display/mac/screen_mac.mm
+index 4850c795480e..ec34b25a6fe8 100644
+--- a/ui/display/mac/screen_mac.mm
++++ b/ui/display/mac/screen_mac.mm
+@@ -106,7 +106,17 @@ Display BuildDisplayForScreen(NSScreen* screen) {
+ 
+   display.set_color_depth(NSBitsPerPixelFromDepth([screen depth]));
+   display.set_depth_per_component(NSBitsPerSampleFromDepth([screen depth]));
++#ifdef MAS_BUILD
++  // This is equivalent to the CGDisplayUsesForceToGray() API as at 2018-08-06,
++  // but avoids usage of the private API.
++  CFStringRef app = CFSTR("com.apple.CoreGraphics");
++  CFStringRef key = CFSTR("DisplayUseForcedGray");
++  Boolean key_valid = false;
++  display.set_is_monochrome(
++      CFPreferencesGetAppBooleanValue(key, app, &key_valid));
++#else
+   display.set_is_monochrome(CGDisplayUsesForceToGray());
++#endif
+ 
+   // CGDisplayRotation returns a double. Display::SetRotationAsDegree will
+   // handle the unexpected situations were the angle is not a multiple of 90.
+-- 
+2.17.0
+

+ 27 - 0
patches/common/chromium/mas-lssetapplicationlaunchservicesserverconnectionstatus.patch

@@ -0,0 +1,27 @@
+From 3fcbe57ff316894349907bf1c85f71d7487f0932 Mon Sep 17 00:00:00 2001
+From: Jeremy Apthorp <[email protected]>
+Date: Mon, 6 Aug 2018 13:40:24 -0700
+Subject: fix: [mas] don't call LaunchServices private api
+
+---
+ content/gpu/gpu_main.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
+index 115f871094bc..aa47a1c1a51e 100644
+--- a/content/gpu/gpu_main.cc
++++ b/content/gpu/gpu_main.cc
+@@ -276,8 +276,10 @@ int GpuMain(const MainFunctionParams& parameters) {
+     std::unique_ptr<base::MessagePump> pump(new base::MessagePumpNSRunLoop());
+     main_message_loop.reset(new base::MessageLoop(std::move(pump)));
+ 
++#ifndef MAS_BUILD
+     // Tell LaunchServices to continue without a connection to the daemon.
+     _LSSetApplicationLaunchServicesServerConnectionStatus(0, nullptr);
++#endif
+ #else
+     main_message_loop.reset(
+         new base::MessageLoop(base::MessageLoop::TYPE_DEFAULT));
+-- 
+2.17.0
+

+ 112 - 0
patches/common/chromium/mas_blink_no_private_api.patch

@@ -0,0 +1,112 @@
+diff --git a/third_party/blink/renderer/core/paint/theme_painter_mac.mm b/third_party/blink/renderer/core/paint/theme_painter_mac.mm
+index 65e6437c22a6..3b726d196427 100644
+--- a/third_party/blink/renderer/core/paint/theme_painter_mac.mm
++++ b/third_party/blink/renderer/core/paint/theme_painter_mac.mm
+@@ -43,6 +43,7 @@
+ 
+ // The methods in this file are specific to the Mac OS X platform.
+ 
++#ifndef MAS_BUILD
+ // Forward declare Mac SPIs.
+ extern "C" {
+ void _NSDrawCarbonThemeBezel(NSRect frame, BOOL enabled, BOOL flipped);
+@@ -52,6 +53,7 @@ void _NSDrawCarbonThemeListBox(NSRect frame,
+                                BOOL flipped,
+                                BOOL always_yes);
+ }
++#endif
+ 
+ namespace blink {
+ 
+@@ -74,10 +76,12 @@ bool ThemePainterMac::PaintTextField(const Node* node,
+   // behavior change while remaining a fragile solution.
+   // https://bugs.chromium.org/p/chromium/issues/detail?id=658085#c3
+   if (!use_ns_text_field_cell) {
++#ifndef MAS_BUILD
+     _NSDrawCarbonThemeBezel(
+         CGRect(r),
+         LayoutTheme::IsEnabled(node) && !LayoutTheme::IsReadOnlyControl(node),
+         YES);
++#endif
+     return false;
+   }
+ 
+@@ -163,10 +167,12 @@ bool ThemePainterMac::PaintTextArea(const Node* node,
+                                     const PaintInfo& paint_info,
+                                     const IntRect& r) {
+   LocalCurrentGraphicsContext local_context(paint_info.context, r);
++#ifndef MAS_BUILD
+   _NSDrawCarbonThemeListBox(
+       CGRect(r),
+       LayoutTheme::IsEnabled(node) && !LayoutTheme::IsReadOnlyControl(node),
+       YES, YES);
++#endif
+   return false;
+ }
+ 
+diff --git a/third_party/blink/renderer/platform/mac/kill_ring_mac.mm b/third_party/blink/renderer/platform/mac/kill_ring_mac.mm
+index acf60f09fdb9..6376120a954f 100644
+--- a/third_party/blink/renderer/platform/mac/kill_ring_mac.mm
++++ b/third_party/blink/renderer/platform/mac/kill_ring_mac.mm
+@@ -27,6 +27,7 @@
+ 
+ namespace blink {
+ 
++#ifndef MAS_BUILD
+ extern "C" {
+ 
+ // Kill ring calls. Would be better to use NSKillRing.h, but that's not
+@@ -39,38 +40,53 @@ NSString* _NSYankFromKillRing();
+ void _NSNewKillRingSequence();
+ void _NSSetKillRingToYankedState();
+ }
++#endif
+ 
+ static void InitializeKillRingIfNeeded() {
+   static bool initialized_kill_ring = false;
+   if (!initialized_kill_ring) {
+     initialized_kill_ring = true;
++#ifndef MAS_BUILD
+     _NSInitializeKillRing();
++#endif
+   }
+ }
+ 
+ void KillRing::Append(const String& string) {
+   InitializeKillRingIfNeeded();
++#ifndef MAS_BUILD
+   _NSAppendToKillRing(string);
++#endif
+ }
+ 
+ void KillRing::Prepend(const String& string) {
+   InitializeKillRingIfNeeded();
++#ifndef MAS_BUILD
+   _NSPrependToKillRing(string);
++#endif
+ }
+ 
+ String KillRing::Yank() {
+   InitializeKillRingIfNeeded();
++#ifndef MAS_BUILD
+   return _NSYankFromKillRing();
++#else
++  return "";
++#endif
+ }
+ 
+ void KillRing::StartNewSequence() {
+   InitializeKillRingIfNeeded();
++#ifndef MAS_BUILD
+   _NSNewKillRingSequence();
++#endif
+ }
+ 
+ void KillRing::SetToYankedState() {
+   InitializeKillRingIfNeeded();
++#ifndef MAS_BUILD
+   _NSSetKillRingToYankedState();
++#endif
+ }
+ 
+ }  // namespace blink

+ 436 - 0
patches/common/chromium/mas_no_private_api.patch

@@ -0,0 +1,436 @@
+diff --git a/content/browser/accessibility/browser_accessibility_cocoa.h b/content/browser/accessibility/browser_accessibility_cocoa.h
+index a03585269db6..e7b028760bba 100644
+--- a/content/browser/accessibility/browser_accessibility_cocoa.h
++++ b/content/browser/accessibility/browser_accessibility_cocoa.h
+@@ -111,7 +111,9 @@ struct AXTextEdit {
+ @property(nonatomic, readonly) NSNumber* enabled;
+ // Returns a text marker that points to the last character in the document that
+ // can be selected with Voiceover.
++#ifndef MAS_BUILD
+ @property(nonatomic, readonly) id endTextMarker;
++#endif
+ @property(nonatomic, readonly) NSNumber* expanded;
+ @property(nonatomic, readonly) NSNumber* focused;
+ @property(nonatomic, readonly) NSNumber* grabbed;
+@@ -147,12 +149,16 @@ struct AXTextEdit {
+ @property(nonatomic, readonly) NSArray* selectedChildren;
+ @property(nonatomic, readonly) NSString* selectedText;
+ @property(nonatomic, readonly) NSValue* selectedTextRange;
++#ifndef MAS_BUILD
+ @property(nonatomic, readonly) id selectedTextMarkerRange;
++#endif
+ @property(nonatomic, readonly) NSValue* size;
+ @property(nonatomic, readonly) NSString* sortDirection;
+ // Returns a text marker that points to the first character in the document that
+ // can be selected with Voiceover.
++#ifndef MAS_BUILD
+ @property(nonatomic, readonly) id startTextMarker;
++#endif
+ // A string indicating the subrole of this object as far as accessibility
+ // is concerned.
+ @property(nonatomic, readonly) NSString* subrole;
+diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
+index 4cff922f28a3..e9c57f7a0879 100644
+--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
++++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
+@@ -119,6 +119,7 @@ NSDictionary* attributeToMethodNameMap = nil;
+ // VoiceOver uses -1 to mean "no limit" for AXResultsLimit.
+ const int kAXResultsLimitNoLimit = -1;
+ 
++#ifndef MAS_BUILD
+ extern "C" {
+ 
+ // The following are private accessibility APIs required for cursor navigation
+@@ -325,6 +326,7 @@ NSAttributedString* GetAttributedTextForTextMarkerRange(
+   AddMisspelledTextAttributes(text_only_objects, attributed_text);
+   return [attributed_text attributedSubstringFromRange:range];
+ }
++#endif
+ 
+ // Returns an autoreleased copy of the AXNodeData's attribute.
+ NSString* NSStringForStringAttribute(
+@@ -578,7 +580,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+       {NSAccessibilityDOMIdentifierAttribute, @"domIdentifier"},
+       {NSAccessibilityEditableAncestorAttribute, @"editableAncestor"},
+       {NSAccessibilityEnabledAttribute, @"enabled"},
++#ifndef MAS_BUILD
+       {NSAccessibilityEndTextMarkerAttribute, @"endTextMarker"},
++#endif
+       {NSAccessibilityExpandedAttribute, @"expanded"},
+       {NSAccessibilityFocusedAttribute, @"focused"},
+       {NSAccessibilityGrabbedAttribute, @"grabbed"},
+@@ -609,13 +613,17 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+       {NSAccessibilityRowsAttribute, @"rows"},
+       // TODO(aboxhall): expose
+       // NSAccessibilityServesAsTitleForUIElementsAttribute
++#ifndef MAS_BUILD
+       {NSAccessibilityStartTextMarkerAttribute, @"startTextMarker"},
++#endif
+       {NSAccessibilitySelectedAttribute, @"selected"},
+       {NSAccessibilitySelectedChildrenAttribute, @"selectedChildren"},
+       {NSAccessibilitySelectedTextAttribute, @"selectedText"},
+       {NSAccessibilitySelectedTextRangeAttribute, @"selectedTextRange"},
++#ifndef MAS_BUILD
+       {NSAccessibilitySelectedTextMarkerRangeAttribute,
+        @"selectedTextMarkerRange"},
++#endif
+       {NSAccessibilitySizeAttribute, @"size"},
+       {NSAccessibilitySortDirectionAttribute, @"sortDirection"},
+       {NSAccessibilitySubroleAttribute, @"subrole"},
+@@ -1069,6 +1077,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+                      ax::mojom::Restriction::kDisabled];
+ }
+ 
++#ifndef MAS_BUILD
+ // Returns a text marker that points to the last character in the document that
+ // can be selected with VoiceOver.
+ - (id)endTextMarker {
+@@ -1080,6 +1089,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+   BrowserAccessibilityPositionInstance position = root->CreatePositionAt(0);
+   return CreateTextMarker(position->CreatePositionAtEndOfAnchor());
+ }
++#endif
+ 
+ - (NSNumber*)expanded {
+   if (![self instanceActive])
+@@ -1892,6 +1902,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+   return [NSValue valueWithRange:NSMakeRange(selStart, selLength)];
+ }
+ 
++#ifndef MAS_BUILD
+ - (id)selectedTextMarkerRange {
+   if (![self instanceActive])
+     return nil;
+@@ -1924,6 +1935,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+                                                anchorAffinity, *focusObject,
+                                                focusOffset, focusAffinity));
+ }
++#endif
+ 
+ - (NSValue*)size {
+   if (![self instanceActive])
+@@ -1956,6 +1968,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+   return nil;
+ }
+ 
++#ifndef MAS_BUILD
+ // Returns a text marker that points to the first character in the document that
+ // can be selected with VoiceOver.
+ - (id)startTextMarker {
+@@ -1967,6 +1980,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+   BrowserAccessibilityPositionInstance position = root->CreatePositionAt(0);
+   return CreateTextMarker(position->CreatePositionAtStartOfAnchor());
+ }
++#endif
+ 
+ // Returns a subrole based upon the role.
+ - (NSString*) subrole {
+@@ -2247,12 +2261,14 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+   NSMutableAttributedString* attributedValue =
+       [[[NSMutableAttributedString alloc] initWithString:value] autorelease];
+ 
++#ifndef MAS_BUILD
+   if (!browserAccessibility_->IsTextOnlyObject()) {
+     std::vector<const BrowserAccessibility*> textOnlyObjects =
+         BrowserAccessibilityManager::FindTextOnlyObjectsInRange(
+             *browserAccessibility_, *browserAccessibility_);
+     AddMisspelledTextAttributes(textOnlyObjects, attributedValue);
+   }
++#endif
+ 
+   return [attributedValue attributedSubstringFromRange:range];
+ }
+@@ -2372,6 +2388,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+     return nil;
+   }
+ 
++#ifndef MAS_BUILD
+   if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) {
+     BrowserAccessibilityPositionInstance position =
+         CreatePositionFromTextMarker(parameter);
+@@ -2549,6 +2566,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+     NSString* text = GetTextForTextMarkerRange(parameter);
+     return [NSNumber numberWithInt:[text length]];
+   }
++#endif
+ 
+   if ([attribute isEqualToString:
+       NSAccessibilityBoundsForRangeParameterizedAttribute]) {
+@@ -2586,6 +2604,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+     return nil;
+   }
+ 
++#ifndef MAS_BUILD
+   if ([attribute isEqualToString:
+            NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute]) {
+     BrowserAccessibilityPositionInstance position =
+@@ -2665,6 +2684,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
+ 
+     return @(child->GetIndexInParent());
+   }
++#endif
+ 
+   return nil;
+ }
+diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm
+index 134f855de654..d588ed98839d 100644
+--- a/content/browser/accessibility/browser_accessibility_manager_mac.mm
++++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
+@@ -441,6 +441,7 @@ NSDictionary* BrowserAccessibilityManagerMac::
+       [user_info setObject:native_focus_object
+                     forKey:NSAccessibilityTextChangeElement];
+ 
++#ifndef MAS_BUILD
+       id selected_text = [native_focus_object selectedTextMarkerRange];
+       if (selected_text) {
+         NSString* const NSAccessibilitySelectedTextMarkerRangeAttribute =
+@@ -448,6 +449,7 @@ NSDictionary* BrowserAccessibilityManagerMac::
+         [user_info setObject:selected_text
+                       forKey:NSAccessibilitySelectedTextMarkerRangeAttribute];
+       }
++#endif
+     }
+   }
+ 
+diff --git a/content/renderer/renderer_main_platform_delegate_mac.mm b/content/renderer/renderer_main_platform_delegate_mac.mm
+index 6b955bdb3724..1775f3b3c1d4 100644
+--- a/content/renderer/renderer_main_platform_delegate_mac.mm
++++ b/content/renderer/renderer_main_platform_delegate_mac.mm
+@@ -22,6 +22,7 @@
+ #include "sandbox/mac/seatbelt.h"
+ #include "services/service_manager/sandbox/mac/sandbox_mac.h"
+ 
++#ifndef MAS_BUILD
+ extern "C" {
+ void CGSSetDenyWindowServerConnections(bool);
+ void CGSShutdownServerConnections();
+@@ -30,6 +31,7 @@ void _LSSetApplicationLaunchServicesServerConnectionStatus(
+     uint64_t flags,
+     bool (^connection_allowed)(CFDictionaryRef));
+ };
++#endif
+ 
+ namespace content {
+ 
+@@ -38,6 +40,7 @@ namespace {
+ // This disconnects from the window server, and then indicates that Chrome
+ // should continue execution without access to launchservicesd.
+ void DisconnectWindowServer() {
++#ifndef MAS_BUILD
+   // Now disconnect from WindowServer, after all objects have been warmed up.
+   // Shutting down the connection requires connecting to WindowServer,
+   // so do this before actually engaging the sandbox. This may cause two log
+@@ -51,6 +54,7 @@ void DisconnectWindowServer() {
+   SetApplicationIsDaemon(true);
+   // Tell LaunchServices to continue without a connection to the daemon.
+   _LSSetApplicationLaunchServicesServerConnectionStatus(0, nullptr);
++#endif
+ }
+ 
+ // You are about to read a pretty disgusting hack. In a static initializer,
+diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm
+index 09123af7c2f0..69d6b926576f 100644
+--- a/device/bluetooth/bluetooth_adapter_mac.mm
++++ b/device/bluetooth/bluetooth_adapter_mac.mm
+@@ -32,6 +32,7 @@
+ #include "device/bluetooth/bluetooth_low_energy_central_manager_delegate.h"
+ #include "device/bluetooth/bluetooth_socket_mac.h"
+ 
++#ifndef MAS_BUILD
+ extern "C" {
+ // Undocumented IOBluetooth Preference API [1]. Used by `blueutil` [2] and
+ // `Karabiner` [3] to programmatically control the Bluetooth state. Calling the
+@@ -45,6 +46,7 @@ extern "C" {
+ // [4] https://support.apple.com/kb/PH25091
+ void IOBluetoothPreferenceSetControllerPowerState(int state);
+ }
++#endif
+ 
+ namespace {
+ 
+@@ -118,8 +120,10 @@ BluetoothAdapterMac::BluetoothAdapterMac()
+       controller_state_function_(
+           base::BindRepeating(&BluetoothAdapterMac::GetHostControllerState,
+                               base::Unretained(this))),
++#ifndef MAS_BUILD
+       power_state_function_(
+           base::BindRepeating(IOBluetoothPreferenceSetControllerPowerState)),
++#endif
+       should_update_name_(true),
+       classic_discovery_manager_(
+           BluetoothDiscoveryManagerMac::CreateClassic(this)),
+@@ -302,8 +306,12 @@ bool BluetoothAdapterMac::IsLowEnergyAvailable() {
+ }
+ 
+ bool BluetoothAdapterMac::SetPoweredImpl(bool powered) {
++#ifndef MAS_BUILD
+   power_state_function_.Run(base::strict_cast<int>(powered));
+   return true;
++#else
++  return false;
++#endif
+ }
+ 
+ void BluetoothAdapterMac::RemovePairingDelegateInternal(
+diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn
+index 10d786fded92..10e6c6772351 100644
+--- a/media/audio/BUILD.gn
++++ b/media/audio/BUILD.gn
+@@ -189,6 +189,12 @@ source_set("audio") {
+       "mac/scoped_audio_unit.cc",
+       "mac/scoped_audio_unit.h",
+     ]
++    if (is_mas_build) {
++      sources -= [
++        "mac/coreaudio_dispatch_override.cc",
++        "mac/coreaudio_dispatch_override.h",
++      ]
++    }
+     libs += [
+       "AudioToolbox.framework",
+       "AudioUnit.framework",
+diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc
+index 1a74579e310b..0a15778d6825 100644
+--- a/media/audio/mac/audio_manager_mac.cc
++++ b/media/audio/mac/audio_manager_mac.cc
+@@ -993,7 +993,7 @@ AudioParameters AudioManagerMac::GetPreferredOutputStreamParameters(
+ 
+ void AudioManagerMac::InitializeOnAudioThread() {
+   DCHECK(GetTaskRunner()->BelongsToCurrentThread());
+-  InitializeCoreAudioDispatchOverride();
++  // InitializeCoreAudioDispatchOverride();
+   power_observer_.reset(new AudioPowerObserver());
+ }
+ 
+diff --git a/net/dns/dns_config_service_posix.cc b/net/dns/dns_config_service_posix.cc
+index 706ba6e8e882..3fbe80c91cd9 100644
+--- a/net/dns/dns_config_service_posix.cc
++++ b/net/dns/dns_config_service_posix.cc
+@@ -244,6 +244,7 @@ class DnsConfigServicePosix::Watcher {
+ 
+   bool Watch() {
+     bool success = true;
++#ifndef MAS_BUILD
+     if (!config_watcher_.Watch(base::Bind(&Watcher::OnConfigChanged,
+                                           base::Unretained(this)))) {
+       LOG(ERROR) << "DNS config watch failed to start.";
+@@ -265,6 +266,7 @@ class DnsConfigServicePosix::Watcher {
+                                 DNS_CONFIG_WATCH_MAX);
+     }
+ #endif  // !defined(OS_ANDROID) && !defined(OS_IOS)
++#endif
+     return success;
+   }
+ 
+diff --git a/sandbox/mac/sandbox_compiler.cc b/sandbox/mac/sandbox_compiler.cc
+index e524aa7b8510..718d3f963da5 100644
+--- a/sandbox/mac/sandbox_compiler.cc
++++ b/sandbox/mac/sandbox_compiler.cc
+@@ -28,6 +28,7 @@ bool SandboxCompiler::InsertStringParam(const std::string& key,
+ }
+ 
+ bool SandboxCompiler::CompileAndApplyProfile(std::string* error) {
++#ifndef MAS_BUILD
+   char* error_internal = nullptr;
+   std::vector<const char*> params;
+ 
+@@ -44,6 +45,7 @@ bool SandboxCompiler::CompileAndApplyProfile(std::string* error) {
+     sandbox::Seatbelt::FreeError(error_internal);
+     return false;
+   }
++#endif
+   return true;
+ }
+ 
+diff --git a/sandbox/mac/seatbelt.cc b/sandbox/mac/seatbelt.cc
+index dfba0bded9e3..876f96999f53 100644
+--- a/sandbox/mac/seatbelt.cc
++++ b/sandbox/mac/seatbelt.cc
+@@ -64,7 +64,11 @@ void Seatbelt::FreeError(char* errorbuf) {
+ 
+ // static
+ bool Seatbelt::IsSandboxed() {
++#ifndef MAS_BUILD
+   return ::sandbox_check(getpid(), NULL, 0);
++#else
++  return true;
++#endif
+ }
+ 
+ }  // namespace sandbox
+diff --git a/sandbox/mac/seatbelt_extension.cc b/sandbox/mac/seatbelt_extension.cc
+index 9073364142e8..2356add74dfa 100644
+--- a/sandbox/mac/seatbelt_extension.cc
++++ b/sandbox/mac/seatbelt_extension.cc
+@@ -8,6 +8,7 @@
+ #include "base/memory/ptr_util.h"
+ #include "sandbox/mac/seatbelt_extension_token.h"
+ 
++#ifndef MAS_BUILD
+ // libsandbox private API.
+ extern "C" {
+ extern const char* APP_SANDBOX_READ;
+@@ -18,6 +19,7 @@ char* sandbox_extension_issue_file(const char* type,
+                                    const char* path,
+                                    uint32_t flags);
+ }
++#endif
+ 
+ namespace sandbox {
+ 
+@@ -46,7 +48,11 @@ std::unique_ptr<SeatbeltExtension> SeatbeltExtension::FromToken(
+ 
+ bool SeatbeltExtension::Consume() {
+   DCHECK(!token_.empty());
++#ifndef MAS_BUILD
+   handle_ = sandbox_extension_consume(token_.c_str());
++#else
++  handle_ = -1;
++#endif
+   return handle_ > 0;
+ }
+ 
+@@ -58,7 +64,11 @@ bool SeatbeltExtension::ConsumePermanently() {
+ }
+ 
+ bool SeatbeltExtension::Revoke() {
++#ifndef MAS_BUILD
+   int rv = sandbox_extension_release(handle_);
++#else
++  int rv = -1;
++#endif
+   handle_ = 0;
+   token_.clear();
+   return rv == 0;
+@@ -76,9 +86,11 @@ SeatbeltExtension::SeatbeltExtension(const std::string& token)
+ char* SeatbeltExtension::IssueToken(SeatbeltExtension::Type type,
+                                     const std::string& resource) {
+   switch (type) {
++#ifndef MAS_BUILD
+     case FILE_READ:
+       return sandbox_extension_issue_file(APP_SANDBOX_READ, resource.c_str(),
+                                           0);
++#endif
+     default:
+       NOTREACHED();
+       return nullptr;
+diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm
+index 3c6e9903d7df..ddc9061c64d1 100644
+--- a/ui/views/cocoa/bridged_native_widget.mm
++++ b/ui/views/cocoa/bridged_native_widget.mm
+@@ -43,6 +43,7 @@
+ #include "ui/views/widget/widget_delegate.h"
+ #include "ui/views/window/dialog_delegate.h"
+ 
++#ifndef MAS_BUILD
+ extern "C" {
+ 
+ typedef int32_t CGSConnection;
+@@ -52,6 +53,7 @@ CGError CGSSetWindowBackgroundBlurRadius(CGSConnection connection,
+                                          int radius);
+ 
+ }
++#endif
+ 
+ // The NSView that hosts the composited CALayer drawing the UI. It fills the
+ // window but is not hittable so that accessibility hit tests always go to the

+ 12 - 0
patches/common/chromium/net_url_request_job.patch

@@ -0,0 +1,12 @@
+diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h
+index 2341999..3011bf7 100644
+--- a/net/url_request/url_request_job.h
++++ b/net/url_request/url_request_job.h
+@@ -269,6 +269,7 @@ class NET_EXPORT URLRequestJob : public base::PowerObserver {
+   void OnCallToDelegate();
+   void OnCallToDelegateComplete();
+ 
++ public:
+   // Called to read raw (pre-filtered) data from this Job. Reads at most
+   // |buf_size| bytes into |buf|.
+   // Possible return values:

+ 13 - 0
patches/common/chromium/no_cache_storage_check.patch

@@ -0,0 +1,13 @@
+diff --git a/content/browser/cache_storage/cache_storage.cc b/content/browser/cache_storage/cache_storage.cc
+index ce6a21b..10a3b18 100644
+--- a/content/browser/cache_storage/cache_storage.cc
++++ b/content/browser/cache_storage/cache_storage.cc
+@@ -129,7 +129,7 @@ class CacheStorage::CacheLoader {
+         blob_context_(blob_context),
+         cache_storage_(cache_storage),
+         origin_(origin) {
+-    DCHECK(!origin_.unique());
++    // DCHECK(!origin_.unique());
+   }
+ 
+   virtual ~CacheLoader() {}

+ 13 - 0
patches/common/chromium/no_stack_dumping.patch

@@ -0,0 +1,13 @@
+diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc
+index c283922..397ba80 100644
+--- a/content/app/content_main_runner.cc
++++ b/content/app/content_main_runner.cc
+@@ -657,7 +657,7 @@ class ContentMainRunnerImpl : public ContentMainRunner {
+ 
+     InitializeV8IfNeeded(command_line, process_type);
+ 
+-#if !defined(OFFICIAL_BUILD)
++#if 0
+ #if defined(OS_WIN)
+     bool should_enable_stack_dump = !process_type.empty();
+ #else

+ 15 - 0
patches/common/chromium/out_of_process_instance.patch

@@ -0,0 +1,15 @@
+diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc
+index 8b9c9f19a3dd..c4d801135053 100644
+--- a/pdf/out_of_process_instance.cc
++++ b/pdf/out_of_process_instance.cc
+@@ -333,7 +333,9 @@ bool OutOfProcessInstance::Init(uint32_t argc,
+   std::string document_url = document_url_var.AsString();
+   base::StringPiece document_url_piece(document_url);
+   is_print_preview_ = IsPrintPreviewUrl(document_url_piece);
+-  if (!document_url_piece.starts_with(kChromeExtension) && !is_print_preview_)
++  if (!document_url_piece.starts_with(kChromeExtension) &&
++      !document_url_piece.starts_with("chrome://pdf-viewer") &&
++      !is_print_preview_)
+     return false;
+ 
+   // Check if the plugin is full frame. This is passed in from JS.

+ 484 - 0
patches/common/chromium/pepper_flash.patch

@@ -0,0 +1,484 @@
+diff --git a/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h b/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h
+index 735da93c3cab..533f53fbc423 100644
+--- a/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h
++++ b/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h
+@@ -5,6 +5,7 @@
+ #ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_CHROME_BROWSER_PEPPER_HOST_FACTORY_H_
+ #define CHROME_BROWSER_RENDERER_HOST_PEPPER_CHROME_BROWSER_PEPPER_HOST_FACTORY_H_
+ 
++#include "base/component_export.h"
+ #include "base/macros.h"
+ #include "ppapi/host/host_factory.h"
+ 
+@@ -12,7 +13,8 @@ namespace content {
+ class BrowserPpapiHost;
+ }  // namespace content
+ 
+-class ChromeBrowserPepperHostFactory : public ppapi::host::HostFactory {
++class COMPONENT_EXPORT(PEPPER_FLASH) ChromeBrowserPepperHostFactory
++    : public ppapi::host::HostFactory {
+  public:
+   // Non-owning pointer to the filter must outlive this class.
+   explicit ChromeBrowserPepperHostFactory(content::BrowserPpapiHost* host);
+diff --git a/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc b/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc
+index f4f1741a8ecf..103238cdd53f 100644
+--- a/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc
++++ b/chrome/browser/renderer_host/pepper/pepper_broker_message_filter.cc
+@@ -6,10 +6,12 @@
+ 
+ #include <string>
+ 
++#if 0
+ #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+ #include "chrome/browser/profiles/profile.h"
+ #include "components/content_settings/core/browser/host_content_settings_map.h"
+ #include "components/content_settings/core/common/content_settings.h"
++#endif
+ #include "content/public/browser/browser_ppapi_host.h"
+ #include "content/public/browser/browser_thread.h"
+ #include "content/public/browser/render_process_host.h"
+@@ -57,6 +59,7 @@ int32_t PepperBrokerMessageFilter::OnIsAllowed(
+      RenderProcessHost::FromID(render_process_id_);
+   if (!render_process_host)
+     return PP_ERROR_FAILED;
++#if 0
+   Profile* profile =
+       Profile::FromBrowserContext(render_process_host->GetBrowserContext());
+   HostContentSettingsMap* content_settings =
+@@ -68,5 +71,6 @@ int32_t PepperBrokerMessageFilter::OnIsAllowed(
+                                           std::string());
+   if (setting == CONTENT_SETTING_ALLOW)
+     return PP_OK;
+-  return PP_ERROR_FAILED;
++#endif
++  return PP_OK;
+ }
+diff --git a/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc b/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc
+index 1c1844a9eb71..2c9834b11d34 100644
+--- a/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc
++++ b/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.cc
+@@ -6,9 +6,11 @@
+ 
+ #include "base/time/time.h"
+ #include "build/build_config.h"
++#if 0
+ #include "chrome/browser/content_settings/cookie_settings_factory.h"
+ #include "chrome/browser/profiles/profile.h"
+ #include "components/content_settings/core/browser/cookie_settings.h"
++#endif
+ #include "content/public/browser/browser_context.h"
+ #include "content/public/browser/browser_ppapi_host.h"
+ #include "content/public/browser/browser_thread.h"
+@@ -40,6 +42,7 @@ using content::ServiceManagerConnection;
+ 
+ namespace {
+ 
++#if 0
+ // Get the CookieSettings on the UI thread for the given render process ID.
+ scoped_refptr<content_settings::CookieSettings> GetCookieSettings(
+     int render_process_id) {
+@@ -53,6 +56,7 @@ scoped_refptr<content_settings::CookieSettings> GetCookieSettings(
+   }
+   return NULL;
+ }
++#endif
+ 
+ void PepperBindConnectorRequest(
+     service_manager::mojom::ConnectorRequest connector_request) {
+@@ -70,7 +74,9 @@ PepperFlashBrowserHost::PepperFlashBrowserHost(BrowserPpapiHost* host,
+                                                PP_Instance instance,
+                                                PP_Resource resource)
+     : ResourceHost(host->GetPpapiHost(), instance, resource),
++#if 0
+       host_(host),
++#endif
+       delay_timer_(FROM_HERE, base::TimeDelta::FromSeconds(45), this,
+                    &PepperFlashBrowserHost::OnDelayTimerFired),
+       weak_factory_(this) {
+@@ -122,6 +128,7 @@ int32_t PepperFlashBrowserHost::OnGetLocalTimeZoneOffset(
+ 
+ int32_t PepperFlashBrowserHost::OnGetLocalDataRestrictions(
+     ppapi::host::HostMessageContext* context) {
++#if 0
+   // Getting the Flash LSO settings requires using the CookieSettings which
+   // belong to the profile which lives on the UI thread. We lazily initialize
+   // |cookie_settings_| by grabbing the reference from the UI thread and then
+@@ -144,9 +151,11 @@ int32_t PepperFlashBrowserHost::OnGetLocalDataRestrictions(
+                    document_url,
+                    plugin_url));
+   }
+-  return PP_OK_COMPLETIONPENDING;
++#endif
++  return PP_FLASHLSORESTRICTIONS_IN_MEMORY;
+ }
+ 
++#if 0
+ void PepperFlashBrowserHost::GetLocalDataRestrictions(
+     ppapi::host::ReplyMessageContext reply_context,
+     const GURL& document_url,
+@@ -175,6 +184,7 @@ void PepperFlashBrowserHost::GetLocalDataRestrictions(
+             PpapiPluginMsg_Flash_GetLocalDataRestrictionsReply(
+                 static_cast<int32_t>(restrictions)));
+ }
++#endif
+ 
+ device::mojom::WakeLock* PepperFlashBrowserHost::GetWakeLock() {
+   // Here is a lazy binding, and will not reconnect after connection error.
+diff --git a/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h b/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h
+index ff0b687a51b6..ab6d96cbe9f8 100644
+--- a/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h
++++ b/chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h
+@@ -23,9 +23,11 @@ namespace content {
+ class BrowserPpapiHost;
+ }
+ 
++#if 0
+ namespace content_settings {
+ class CookieSettings;
+ }
++#endif
+ 
+ class GURL;
+ 
+@@ -51,15 +53,19 @@ class PepperFlashBrowserHost : public ppapi::host::ResourceHost {
+       const base::Time& t);
+   int32_t OnGetLocalDataRestrictions(ppapi::host::HostMessageContext* context);
+ 
++#if 0
+   void GetLocalDataRestrictions(
+       ppapi::host::ReplyMessageContext reply_context,
+       const GURL& document_url,
+       const GURL& plugin_url,
+       scoped_refptr<content_settings::CookieSettings> cookie_settings);
++#endif
+ 
+   device::mojom::WakeLock* GetWakeLock();
+ 
++#if 0
+   content::BrowserPpapiHost* host_;
++#endif
+   int render_process_id_;
+ 
+   // Requests a wake lock to prevent going to sleep, and a timer to cancel it
+@@ -67,8 +73,10 @@ class PepperFlashBrowserHost : public ppapi::host::ResourceHost {
+   device::mojom::WakeLockPtr wake_lock_;
+   base::DelayTimer delay_timer_;
+ 
++#if 0
+   // For fetching the Flash LSO settings.
+   scoped_refptr<content_settings::CookieSettings> cookie_settings_;
++#endif
+   base::WeakPtrFactory<PepperFlashBrowserHost> weak_factory_;
+ 
+   DISALLOW_COPY_AND_ASSIGN(PepperFlashBrowserHost);
+diff --git a/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc b/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc
+index e267746783bd..bc84b44ceb27 100644
+--- a/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc
++++ b/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.cc
+@@ -18,6 +18,7 @@
+ #include "content/public/browser/child_process_security_policy.h"
+ #include "content/public/browser/render_frame_host.h"
+ #include "content/public/common/pepper_plugin_info.h"
++#include "net/base/network_interfaces.h"
+ #include "ppapi/c/pp_errors.h"
+ #include "ppapi/host/dispatch_host_message.h"
+ #include "ppapi/host/host_message_context.h"
+@@ -127,7 +128,9 @@ PepperFlashDRMHost::PepperFlashDRMHost(BrowserPpapiHost* host,
+   content::ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(
+       render_process_id, voucher_file);
+ 
++#if 0
+   fetcher_ = new DeviceIDFetcher(render_process_id);
++#endif
+   monitor_finder_ = new MonitorFinder(render_process_id, render_frame_id);
+   monitor_finder_->GetMonitor();
+ }
+@@ -150,12 +153,18 @@ int32_t PepperFlashDRMHost::OnResourceMessageReceived(
+ 
+ int32_t PepperFlashDRMHost::OnHostMsgGetDeviceID(
+     ppapi::host::HostMessageContext* context) {
++#if 0
+   if (!fetcher_->Start(base::Bind(&PepperFlashDRMHost::GotDeviceID,
+                                   weak_factory_.GetWeakPtr(),
+                                   context->MakeReplyMessageContext()))) {
+     return PP_ERROR_INPROGRESS;
+   }
+-  return PP_OK_COMPLETIONPENDING;
++#endif
++  static std::string id;
++  if (id.empty())
++    id = net::GetHostName();
++  context->reply_msg = PpapiPluginMsg_FlashDRM_GetDeviceIDReply(id);
++  return PP_OK;
+ }
+ 
+ int32_t PepperFlashDRMHost::OnHostMsgGetHmonitor(
+@@ -184,6 +193,7 @@ int32_t PepperFlashDRMHost::OnHostMsgMonitorIsExternal(
+   return PP_OK;
+ }
+ 
++#if 0
+ void PepperFlashDRMHost::GotDeviceID(
+     ppapi::host::ReplyMessageContext reply_context,
+     const std::string& id,
+@@ -196,3 +206,4 @@ void PepperFlashDRMHost::GotDeviceID(
+   host()->SendReply(reply_context,
+                     PpapiPluginMsg_FlashDRM_GetDeviceIDReply(id));
+ }
++#endif
+diff --git a/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h b/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h
+index faa83c9d32e5..bbae9c21b59a 100644
+--- a/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h
++++ b/chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h
+@@ -11,7 +11,9 @@
+ 
+ #include "base/macros.h"
+ #include "base/memory/weak_ptr.h"
++#if 0
+ #include "chrome/browser/renderer_host/pepper/device_id_fetcher.h"
++#endif
+ #include "ppapi/host/host_message_context.h"
+ #include "ppapi/host/resource_host.h"
+ 
+@@ -50,7 +52,9 @@ class PepperFlashDRMHost : public ppapi::host::ResourceHost {
+                    const std::string& id,
+                    int32_t result);
+ 
++#if 0
+   scoped_refptr<DeviceIDFetcher> fetcher_;
++#endif
+   scoped_refptr<MonitorFinder> monitor_finder_;
+ 
+   base::WeakPtrFactory<PepperFlashDRMHost> weak_factory_;
+diff --git a/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc b/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc
+index 5599a2d3d62f..532c7290cc36 100644
+--- a/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc
++++ b/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc
+@@ -7,16 +7,20 @@
+ #include <stddef.h>
+ 
+ #include "base/macros.h"
++#if 0
+ #include "chrome/browser/browser_process.h"
+ #include "chrome/browser/profiles/profile.h"
+ #include "chrome/browser/profiles/profile_manager.h"
+ #include "chrome/common/chrome_switches.h"
+ #include "chrome/common/pepper_permission_util.h"
++#endif
+ #include "content/public/browser/browser_ppapi_host.h"
+ #include "content/public/browser/browser_thread.h"
+ #include "content/public/browser/child_process_security_policy.h"
+ #include "content/public/browser/render_view_host.h"
++#if 0
+ #include "extensions/buildflags/buildflags.h"
++#endif
+ #include "ppapi/c/pp_errors.h"
+ #include "ppapi/host/dispatch_host_message.h"
+ #include "ppapi/host/host_message_context.h"
+@@ -25,12 +29,11 @@
+ #include "ppapi/shared_impl/file_system_util.h"
+ #include "storage/browser/fileapi/isolated_context.h"
+ 
+-#if BUILDFLAG(ENABLE_EXTENSIONS)
++#if 0
+ #include "extensions/browser/extension_registry.h"
+ #include "extensions/common/constants.h"
+ #include "extensions/common/extension.h"
+ #include "extensions/common/extension_set.h"
+-#endif
+ 
+ namespace {
+ 
+@@ -40,6 +43,7 @@ const char* kPredefinedAllowedCrxFsOrigins[] = {
+ };
+ 
+ }  // namespace
++#endif
+ 
+ // static
+ PepperIsolatedFileSystemMessageFilter*
+@@ -67,8 +71,10 @@ PepperIsolatedFileSystemMessageFilter::PepperIsolatedFileSystemMessageFilter(
+       profile_directory_(profile_directory),
+       document_url_(document_url),
+       ppapi_host_(ppapi_host) {
++#if 0
+   for (size_t i = 0; i < arraysize(kPredefinedAllowedCrxFsOrigins); ++i)
+     allowed_crxfs_origins_.insert(kPredefinedAllowedCrxFsOrigins[i]);
++#endif
+ }
+ 
+ PepperIsolatedFileSystemMessageFilter::
+@@ -94,6 +100,7 @@ int32_t PepperIsolatedFileSystemMessageFilter::OnResourceMessageReceived(
+   return PP_ERROR_FAILED;
+ }
+ 
++#if 0
+ Profile* PepperIsolatedFileSystemMessageFilter::GetProfile() {
+   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+   ProfileManager* profile_manager = g_browser_process->profile_manager();
+@@ -120,6 +127,7 @@ std::string PepperIsolatedFileSystemMessageFilter::CreateCrxFileSystem(
+   return std::string();
+ #endif
+ }
++#endif
+ 
+ int32_t PepperIsolatedFileSystemMessageFilter::OnOpenFileSystem(
+     ppapi::host::HostMessageContext* context,
+@@ -128,7 +136,7 @@ int32_t PepperIsolatedFileSystemMessageFilter::OnOpenFileSystem(
+     case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_INVALID:
+       break;
+     case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX:
+-       return OpenCrxFileSystem(context);
++       return PP_ERROR_NOTSUPPORTED;
+     case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE:
+       return OpenPluginPrivateFileSystem(context);
+   }
+@@ -138,6 +146,7 @@ int32_t PepperIsolatedFileSystemMessageFilter::OnOpenFileSystem(
+   return PP_ERROR_FAILED;
+ }
+ 
++#if 0
+ int32_t PepperIsolatedFileSystemMessageFilter::OpenCrxFileSystem(
+     ppapi::host::HostMessageContext* context) {
+ #if BUILDFLAG(ENABLE_EXTENSIONS)
+@@ -176,6 +185,7 @@ int32_t PepperIsolatedFileSystemMessageFilter::OpenCrxFileSystem(
+   return PP_ERROR_NOTSUPPORTED;
+ #endif
+ }
++#endif
+ 
+ int32_t PepperIsolatedFileSystemMessageFilter::OpenPluginPrivateFileSystem(
+     ppapi::host::HostMessageContext* context) {
+diff --git a/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h b/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h
+index ca7f87b973e6..f73b596ce78e 100644
+--- a/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h
++++ b/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.h
+@@ -19,7 +19,9 @@
+ #include "ppapi/host/resource_message_filter.h"
+ #include "url/gurl.h"
+ 
++#if 0
+ class Profile;
++#endif
+ 
+ namespace content {
+ class BrowserPpapiHost;
+@@ -53,16 +55,20 @@ class PepperIsolatedFileSystemMessageFilter
+ 
+   ~PepperIsolatedFileSystemMessageFilter() override;
+ 
++#if 0
+   Profile* GetProfile();
+ 
+   // Returns filesystem id of isolated filesystem if valid, or empty string
+   // otherwise.  This must run on the UI thread because ProfileManager only
+   // allows access on that thread.
+   std::string CreateCrxFileSystem(Profile* profile);
++#endif
+ 
+   int32_t OnOpenFileSystem(ppapi::host::HostMessageContext* context,
+                            PP_IsolatedFileSystemType_Private type);
++#if 0
+   int32_t OpenCrxFileSystem(ppapi::host::HostMessageContext* context);
++#endif
+   int32_t OpenPluginPrivateFileSystem(ppapi::host::HostMessageContext* context);
+ 
+   const int render_process_id_;
+@@ -73,8 +79,10 @@ class PepperIsolatedFileSystemMessageFilter
+   // Not owned by this object.
+   ppapi::host::PpapiHost* ppapi_host_;
+ 
++#if 0
+   // Set of origins that can use CrxFs private APIs from NaCl.
+   std::set<std::string> allowed_crxfs_origins_;
++#endif
+ 
+   DISALLOW_COPY_AND_ASSIGN(PepperIsolatedFileSystemMessageFilter);
+ };
+diff --git a/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc b/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc
+index d63e90b6c507..c98a7bd07ddd 100644
+--- a/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc
++++ b/chrome/renderer/pepper/chrome_renderer_pepper_host_factory.cc
+@@ -10,8 +10,10 @@
+ #include "chrome/renderer/pepper/pepper_flash_fullscreen_host.h"
+ #include "chrome/renderer/pepper/pepper_flash_menu_host.h"
+ #include "chrome/renderer/pepper/pepper_flash_renderer_host.h"
++#if 0
+ #include "chrome/renderer/pepper/pepper_uma_host.h"
+ #include "components/pdf/renderer/pepper_pdf_host.h"
++#endif
+ #include "content/public/renderer/renderer_ppapi_host.h"
+ #include "ppapi/host/ppapi_host.h"
+ #include "ppapi/host/resource_host.h"
+@@ -86,6 +88,7 @@ ChromeRendererPepperHostFactory::CreateResourceHost(
+     }
+   }
+ 
++#if 0
+   if (host_->GetPpapiHost()->permissions().HasPermission(
+           ppapi::PERMISSION_PDF)) {
+     switch (message.type()) {
+@@ -104,6 +107,7 @@ ChromeRendererPepperHostFactory::CreateResourceHost(
+       return std::make_unique<PepperUMAHost>(host_, instance, resource);
+     }
+   }
++#endif
+ 
+   return nullptr;
+ }
+diff --git a/chrome/renderer/pepper/pepper_flash_renderer_host.cc b/chrome/renderer/pepper/pepper_flash_renderer_host.cc
+index 66a532e2cb41..e776d0e96c4a 100644
+--- a/chrome/renderer/pepper/pepper_flash_renderer_host.cc
++++ b/chrome/renderer/pepper/pepper_flash_renderer_host.cc
+@@ -13,7 +13,9 @@
+ #include "base/macros.h"
+ #include "base/metrics/histogram_macros.h"
+ #include "base/strings/string_util.h"
++#if 0
+ #include "components/pdf/renderer/pepper_pdf_host.h"
++#endif
+ #include "content/public/renderer/pepper_plugin_instance.h"
+ #include "content/public/renderer/render_thread.h"
+ #include "content/public/renderer/renderer_ppapi_host.h"
+@@ -130,9 +132,11 @@ bool IsSimpleHeader(const std::string& lower_case_header_name,
+ }
+ 
+ void RecordFlashNavigateUsage(FlashNavigateUsage usage) {
++#if 0
+   DCHECK_NE(FLASH_NAVIGATE_USAGE_ENUM_COUNT, usage);
+   UMA_HISTOGRAM_ENUMERATION(
+       "Plugin.FlashNavigateUsage", usage, FLASH_NAVIGATE_USAGE_ENUM_COUNT);
++#endif
+ }
+ 
+ }  // namespace
+@@ -374,6 +378,8 @@ int32_t PepperFlashRendererHost::OnIsRectTopmost(
+ 
+ int32_t PepperFlashRendererHost::OnInvokePrinting(
+     ppapi::host::HostMessageContext* host_context) {
++#if 0
+   pdf::PepperPDFHost::InvokePrintingForInstance(pp_instance());
+-  return PP_OK;
++#endif
++  return PP_ERROR_FAILED;
+ }
+diff --git a/chrome/renderer/pepper/pepper_helper.h b/chrome/renderer/pepper/pepper_helper.h
+index e021c964da3d..e035f0fb9e2b 100644
+--- a/chrome/renderer/pepper/pepper_helper.h
++++ b/chrome/renderer/pepper/pepper_helper.h
+@@ -6,12 +6,14 @@
+ #define CHROME_RENDERER_PEPPER_PEPPER_HELPER_H_
+ 
+ #include "base/compiler_specific.h"
++#include "base/component_export.h"
+ #include "base/macros.h"
+ #include "content/public/renderer/render_frame_observer.h"
+ 
+ // This class listens for Pepper creation events from the RenderFrame and
+ // attaches the parts required for Chrome-specific plugin support.
+-class PepperHelper : public content::RenderFrameObserver {
++class COMPONENT_EXPORT(PEPPER_FLASH) PepperHelper
++    : public content::RenderFrameObserver {
+  public:
+   explicit PepperHelper(content::RenderFrame* render_frame);
+   ~PepperHelper() override;

+ 16 - 0
patches/common/chromium/protobuf_build_gn.patch

@@ -0,0 +1,16 @@
+diff --git a/BUILD.gn b/BUILD.gn
+index 067416ed38f4..9fa07961c5b8 100644
+--- a/third_party/protobuf/BUILD.gn
++++ b/third_party/protobuf/BUILD.gn
+@@ -599,6 +599,11 @@ if (current_toolchain == host_toolchain) {
+ 
+     configs -= [ "//build/config/compiler:chromium_code" ]
+     configs += [ "//build/config/compiler:no_chromium_code" ]
++    if (is_win) {
++      # https://crbug.com/703251
++      configs -= [ "//build/config/win:default_incremental_linking" ]
++      configs += [ "//build/config/win:no_incremental_linking" ]
++    }
+ 
+     cflags = protobuf_lite_cflags
+ 

+ 70 - 0
patches/common/chromium/render_widget_host_view_base.patch

@@ -0,0 +1,70 @@
+diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
+index 09a37c1a2c70..ff8c2db3fdae 100644
+--- a/content/browser/renderer_host/render_widget_host_view_base.cc
++++ b/content/browser/renderer_host/render_widget_host_view_base.cc
+@@ -399,6 +399,15 @@ viz::FrameSinkId RenderWidgetHostViewBase::FrameSinkIdAtPoint(
+   return frame_sink_id.is_valid() ? frame_sink_id : GetFrameSinkId();
+ }
+ 
++RenderWidgetHostViewBase* RenderWidgetHostViewBase::CreateViewForWidget(
++    RenderWidgetHost* render_widget_host,
++    RenderWidgetHost* embedder_render_widget_host,
++    WebContentsView* web_contents_view) {
++  return web_contents_view->CreateViewForWidget(
++    render_widget_host,
++    !!embedder_render_widget_host);
++}
++
+ void RenderWidgetHostViewBase::ProcessMouseEvent(
+     const blink::WebMouseEvent& event,
+     const ui::LatencyInfo& latency) {
+diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
+index 8e391207a8a7..d3637c82aba9 100644
+--- a/content/browser/renderer_host/render_widget_host_view_base.h
++++ b/content/browser/renderer_host/render_widget_host_view_base.h
+@@ -21,8 +21,10 @@
+ #include "components/viz/common/surfaces/scoped_surface_id_allocator.h"
+ #include "components/viz/common/surfaces/surface_id.h"
+ #include "content/browser/renderer_host/event_with_latency_info.h"
++#include "content/browser/web_contents/web_contents_view.h"
+ #include "content/common/content_export.h"
+ #include "content/public/browser/render_frame_metadata_provider.h"
++#include "content/public/browser/render_widget_host.h"
+ #include "content/public/browser/render_widget_host_view.h"
+ #include "content/public/common/input_event_ack_state.h"
+ #include "content/public/common/screen_info.h"
+@@ -79,10 +81,12 @@ class BrowserAccessibilityManager;
+ class CursorManager;
+ class RenderWidgetHostImpl;
+ class RenderWidgetHostViewBaseObserver;
++class RenderWidgetHostViewGuest;
+ class SyntheticGestureTarget;
+ class TextInputManager;
+ class TouchSelectionControllerClientManager;
+ class WebContentsAccessibility;
++class WebContentsView;
+ class WebCursor;
+ struct TextInputState;
+ 
+@@ -124,6 +128,9 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
+   float GetDeviceScaleFactor() const final;
+   TouchSelectionControllerClientManager*
+   GetTouchSelectionControllerClientManager() override;
++
++  virtual void InitAsGuest(RenderWidgetHostView* parent_host_view,
++                           RenderWidgetHostViewGuest* guest_view) {}
+ 
+   // This only needs to be overridden by RenderWidgetHostViewBase subclasses
+   // that handle content embedded within other RenderWidgetHostViews.
+@@ -318,6 +325,11 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView,
+   virtual void ProcessGestureEvent(const blink::WebGestureEvent& event,
+                                    const ui::LatencyInfo& latency);
+ 
++  virtual RenderWidgetHostViewBase* CreateViewForWidget(
++      RenderWidgetHost* render_widget_host,
++      RenderWidgetHost* embedder_render_widget_host,
++      WebContentsView* web_contents_view);
++
+   // Transform a point that is in the coordinate space of a Surface that is
+   // embedded within the RenderWidgetHostViewBase's Surface to the
+   // coordinate space of an embedding, or embedded, Surface. Typically this

+ 102 - 0
patches/common/chromium/render_widget_host_view_mac.patch

@@ -0,0 +1,102 @@
+diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
+index 6a161f0f36c6..349bc78976ad 100644
+--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
++++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
+@@ -48,6 +48,7 @@
+ #include "ui/gfx/geometry/dip_util.h"
+ #include "ui/gfx/mac/coordinate_conversion.h"
+ #include "ui/gl/gl_switches.h"
++#include "ui/gl/gpu_switching_manager.h"
+ 
+ using blink::WebInputEvent;
+ using blink::WebMouseEvent;
+@@ -1112,6 +1113,12 @@ void RenderWidgetHostViewMac::SetBackgroundColor(SkColor color) {
+   DCHECK(SkColorGetA(color) == SK_AlphaOPAQUE ||
+          SkColorGetA(color) == SK_AlphaTRANSPARENT);
+   bool opaque = SkColorGetA(color) == SK_AlphaOPAQUE;
++  if (opaque) {
++    bool wantsTransparent = ui::GpuSwitchingManager::UseTransparent() ||
++                            ([cocoa_view() window] && ![[cocoa_view() window] isOpaque]);
++    if (wantsTransparent)
++      opaque = NO;
++  }
+   if (background_is_opaque_ != opaque) {
+     background_is_opaque_ = opaque;
+     if (host())
+diff --git a/content/browser/renderer_host/render_widget_host_view_cocoa.mm b/content/browser/renderer_host/render_widget_host_view_cocoa.mm
+index c7ad6fa8c75f..bdfabc1061bb 100644
+--- a/content/browser/renderer_host/render_widget_host_view_cocoa.mm
++++ b/content/browser/renderer_host/render_widget_host_view_cocoa.mm
+@@ -178,6 +178,11 @@ void ExtractUnderlines(NSAttributedString* string,
+ 
+ }  // namespace
+ 
++@interface NSWindow (AtomCustomMethods)
++- (BOOL)acceptsFirstMouse;
++- (BOOL)disableAutoHideCursor;
++@end
++
+ // These are not documented, so use only after checking -respondsToSelector:.
+ @interface NSApplication (UndocumentedSpeechMethods)
+ - (void)speakString:(NSString*)string;
+@@ -355,6 +360,9 @@ void ExtractUnderlines(NSAttributedString* string,
+ }
+ 
+ - (BOOL)acceptsFirstMouse:(NSEvent*)theEvent {
++  if ([self.window respondsToSelector:@selector(acceptsFirstMouse)] &&
++      [self.window acceptsFirstMouse])
++    return YES;
+   return [self acceptsMouseEventsWhenInactive];
+ }
+ 
+@@ -555,6 +563,7 @@ void ExtractUnderlines(NSAttributedString* string,
+   if (EventIsReservedBySystem(theEvent))
+     return NO;
+ 
++#if 0
+   // If we return |NO| from this function, cocoa will send the key event to
+   // the menu and only if the menu does not process the event to |keyDown:|. We
+   // want to send the event to a renderer _before_ sending it to the menu, so
+@@ -568,6 +577,7 @@ void ExtractUnderlines(NSAttributedString* string,
+     DCHECK(![[NSApp mainMenu] performKeyEquivalent:theEvent]);
+     return NO;
+   }
++#endif
+ 
+   // Command key combinations are sent via performKeyEquivalent rather than
+   // keyDown:. We just forward this on and if WebCore doesn't want to handle
+@@ -664,6 +674,10 @@ void ExtractUnderlines(NSAttributedString* string,
+                               eventType == NSKeyDown &&
+                               !(modifierFlags & NSCommandKeyMask);
+ 
++  if ([theEvent.window respondsToSelector:@selector(disableAutoHideCursor)] &&
++      [theEvent.window disableAutoHideCursor])
++    shouldAutohideCursor = NO;
++
+   // We only handle key down events and just simply forward other events.
+   if (eventType != NSKeyDown) {
+     client_->OnNSViewForwardKeyboardEvent(event, latency_info);
+@@ -1425,9 +1439,11 @@ void ExtractUnderlines(NSAttributedString* string,
+ // Since this implementation doesn't have to wait any IPC calls, this doesn't
+ // make any key-typing jank. --hbono 7/23/09
+ //
++#ifndef MAS_BUILD
+ extern "C" {
+ extern NSString* NSTextInputReplacementRangeAttributeName;
+ }
++#endif
+ 
+ - (NSArray*)validAttributesForMarkedText {
+   // This code is just copied from WebKit except renaming variables.
+@@ -1436,7 +1452,10 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
+         initWithObjects:NSUnderlineStyleAttributeName,
+                         NSUnderlineColorAttributeName,
+                         NSMarkedClauseSegmentAttributeName,
+-                        NSTextInputReplacementRangeAttributeName, nil]);
++#ifndef MAS_BUILD
++                        NSTextInputReplacementRangeAttributeName,
++#endif
++                        nil]);
+   }
+   return validAttributesForMarkedText_.get();
+ }

+ 24 - 0
patches/common/chromium/resource_file_conflict.patch

@@ -0,0 +1,24 @@
+diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
+index fbcf20c..d2173e2 100644
+--- a/chrome/BUILD.gn
++++ b/chrome/BUILD.gn
+@@ -1656,6 +1656,11 @@ if (is_chrome_branded && !is_android) {
+   }
+ }
+ 
++if (is_electron_gn_build) {
++  group("packed_resources") {
++    public_deps = [ "//electron:packed_resources" ]
++  }
++} else {
+ chrome_paks("packed_resources") {
+   if (is_mac) {
+     output_dir = "$root_gen_dir/repack"
+@@ -1677,6 +1682,7 @@ chrome_paks("packed_resources") {
+     ]
+   }
+ }
++}
+ 
+ repack("browser_tests_pak") {
+   sources = [

+ 57 - 0
patches/common/chromium/scoped_clipboard_writer.patch

@@ -0,0 +1,57 @@
+diff --git a/ui/base/clipboard/scoped_clipboard_writer.cc b/ui/base/clipboard/scoped_clipboard_writer.cc
+index 6850cd460b1d..6d652cca59b4 100644
+--- a/ui/base/clipboard/scoped_clipboard_writer.cc
++++ b/ui/base/clipboard/scoped_clipboard_writer.cc
+@@ -102,17 +102,16 @@ void ScopedClipboardWriter::WriteImage(const SkBitmap& bitmap) {
+   objects_[Clipboard::CBF_SMBITMAP] = parameters;
+ }
+ 
+-void ScopedClipboardWriter::WritePickledData(
+-    const base::Pickle& pickle,
+-    const Clipboard::FormatType& format) {
++void ScopedClipboardWriter::WriteData(const char* data,
++                                      int size,
++                                      const Clipboard::FormatType& format) {
+   std::string format_string = format.Serialize();
+   Clipboard::ObjectMapParam format_parameter(format_string.begin(),
+                                              format_string.end());
+   Clipboard::ObjectMapParam data_parameter;
+ 
+-  data_parameter.resize(pickle.size());
+-  memcpy(const_cast<char*>(&data_parameter.front()),
+-         pickle.data(), pickle.size());
++  data_parameter.resize(size);
++  memcpy(const_cast<char*>(&data_parameter.front()), data, size);
+ 
+   Clipboard::ObjectMapParams parameters;
+   parameters.push_back(format_parameter);
+@@ -121,6 +121,13 @@ void ScopedClipboardWriter::WritePickledData(
+   objects_[Clipboard::CBF_DATA] = parameters;
+ }
+ 
++void ScopedClipboardWriter::WritePickledData(
++    const base::Pickle& pickle,
++    const Clipboard::FormatType& format) {
++  WriteData(reinterpret_cast<const char*>(pickle.data()), pickle.size(),
++            format);
++}
++
+ void ScopedClipboardWriter::Reset() {
+   objects_.clear();
+   bitmap_.reset();
+diff --git a/ui/base/clipboard/scoped_clipboard_writer.h b/ui/base/clipboard/scoped_clipboard_writer.h
+index a7e064561ca9..d5a1b76bc6a7 100644
+--- a/ui/base/clipboard/scoped_clipboard_writer.h
++++ b/ui/base/clipboard/scoped_clipboard_writer.h
+@@ -61,6 +61,11 @@ class UI_BASE_EXPORT ScopedClipboardWriter {
+   // Used by WebKit to determine whether WebKit wrote the clipboard last
+   void WriteWebSmartPaste();
+ 
++  // Adds arbitrary data to clipboard.
++  void WriteData(const char* data,
++                 int size,
++                 const Clipboard::FormatType& format);
++
+   // Adds arbitrary pickled data to clipboard.
+   void WritePickledData(const base::Pickle& pickle,
+                         const Clipboard::FormatType& format);

+ 13 - 0
patches/common/chromium/scroll_bounce_flag.patch

@@ -0,0 +1,13 @@
+diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
+index 81d3f80..a8c4a57 100644
+--- a/content/renderer/render_thread_impl.cc
++++ b/content/renderer/render_thread_impl.cc
+@@ -1737,7 +1737,7 @@ bool RenderThreadImpl::IsGpuMemoryBufferCompositorResourcesEnabled() {
+ }
+ 
+ bool RenderThreadImpl::IsElasticOverscrollEnabled() {
+-  return is_elastic_overscroll_enabled_;
++  return base::CommandLine::ForCurrentProcess()->HasSwitch("scroll-bounce");
+ }
+ 
+ scoped_refptr<base::SingleThreadTaskRunner>

+ 91 - 0
patches/common/chromium/ssl_security_state_tab_helper.patch

@@ -0,0 +1,91 @@
+diff --git a/chrome/browser/ssl/security_state_tab_helper.cc b/chrome/browser/ssl/security_state_tab_helper.cc
+index a73442a5476c..6cd7ae78b814 100644
+--- a/chrome/browser/ssl/security_state_tab_helper.cc
++++ b/chrome/browser/ssl/security_state_tab_helper.cc
+@@ -10,15 +10,21 @@
+ #include "base/metrics/histogram_macros.h"
+ #include "base/time/time.h"
+ #include "build/build_config.h"
++#if 0
+ #include "chrome/browser/browser_process.h"
+ #include "chrome/browser/profiles/profile.h"
+ #include "chrome/browser/safe_browsing/safe_browsing_service.h"
+ #include "chrome/browser/safe_browsing/ui_manager.h"
++#endif
+ #include "components/prefs/pref_service.h"
++#if 0
+ #include "components/safe_browsing/features.h"
++#endif
+ #include "components/security_state/content/content_utils.h"
+ #include "components/ssl_config/ssl_config_prefs.h"
++#if 0
+ #include "components/toolbar/toolbar_field_trial.h"
++#endif
+ #include "content/public/browser/browser_context.h"
+ #include "content/public/browser/navigation_entry.h"
+ #include "content/public/browser/navigation_handle.h"
+@@ -37,7 +43,7 @@
+ #include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
+ #endif  // defined(OS_CHROMEOS)
+ 
+-#if defined(SAFE_BROWSING_DB_LOCAL)
++#if 0
+ #include "chrome/browser/safe_browsing/chrome_password_protection_service.h"
+ #endif
+ 
+@@ -59,7 +65,9 @@ void RecordSecurityLevel(const security_state::SecurityInfo& security_info) {
+ 
+ DEFINE_WEB_CONTENTS_USER_DATA_KEY(SecurityStateTabHelper);
+ 
++#if 0
+ using safe_browsing::SafeBrowsingUIManager;
++#endif
+ 
+ SecurityStateTabHelper::SecurityStateTabHelper(
+     content::WebContents* web_contents)
+@@ -67,8 +75,11 @@ SecurityStateTabHelper::SecurityStateTabHelper(
+       logged_http_warning_on_current_navigation_(false),
+       is_incognito_(false) {
+   content::BrowserContext* context = web_contents->GetBrowserContext();
+-  if (context->IsOffTheRecord() &&
+-      !Profile::FromBrowserContext(context)->IsGuestSession()) {
++  if (context->IsOffTheRecord()
++#if 0
++      && !Profile::FromBrowserContext(context)->IsGuestSession()
++#endif
++  ) {
+     is_incognito_ = true;
+   }
+ }
+@@ -150,6 +161,7 @@ void SecurityStateTabHelper::DidFinishNavigation(
+     UMA_HISTOGRAM_BOOLEAN("interstitial.ssl.visited_site_after_warning", true);
+   }
+ 
++#if 0
+   // Security indicator UI study (https://crbug.com/803501): Show a message in
+   // the console to reduce developer confusion about the experimental UI
+   // treatments for HTTPS pages with EV certificates.
+@@ -177,6 +189,7 @@ void SecurityStateTabHelper::DidFinishNavigation(
+           "Validation is still valid.");
+     }
+   }
++#endif
+ }
+ 
+ void SecurityStateTabHelper::DidChangeVisibleSecurityState() {
+@@ -250,6 +263,7 @@ SecurityStateTabHelper::GetMaliciousContentStatus() const {
+       web_contents()->GetController().GetVisibleEntry();
+   if (!entry)
+     return security_state::MALICIOUS_CONTENT_STATUS_NONE;
++#if 0
+   safe_browsing::SafeBrowsingService* sb_service =
+       g_browser_process->safe_browsing_service();
+   if (!sb_service)
+@@ -301,6 +315,7 @@ SecurityStateTabHelper::GetMaliciousContentStatus() const {
+         break;
+     }
+   }
++#endif
+   return security_state::MALICIOUS_CONTENT_STATUS_NONE;
+ }
+ 

+ 21 - 0
patches/common/chromium/statically_build_power_save_blocker.patch

@@ -0,0 +1,21 @@
+diff --git a/services/device/wake_lock/power_save_blocker/BUILD.gn b/services/device/wake_lock/power_save_blocker/BUILD.gn
+index e04629ca1a93..299e6efd75f9 100644
+--- a/services/device/wake_lock/power_save_blocker/BUILD.gn
++++ b/services/device/wake_lock/power_save_blocker/BUILD.gn
+@@ -9,7 +9,7 @@ if (is_android) {
+   import("//build/config/android/rules.gni")
+ }
+ 
+-source_set("power_save_blocker") {
++static_library("power_save_blocker") {
+   visibility = [
+     # //remoting runs in a separate process which is outside of the context of
+     # the ServiceManager-based world. Instead of embedding a Service Manager
+@@ -18,6 +18,7 @@ source_set("power_save_blocker") {
+     "//remoting/host:*",
+     "//remoting/host/win:*",
+     "//services/device/wake_lock:*",
++    "//electron:*",
+   ]
+ 
+   sources = [

+ 21 - 0
patches/common/chromium/stream_resource_handler.patch

@@ -0,0 +1,21 @@
+diff --git a/content/browser/loader/stream_resource_handler.h b/content/browser/loader/stream_resource_handler.h
+index 9f69994..ae8d1630 100644
+--- a/content/browser/loader/stream_resource_handler.h
++++ b/content/browser/loader/stream_resource_handler.h
+@@ -11,6 +11,7 @@
+ #include "base/memory/ref_counted.h"
+ #include "content/browser/loader/resource_handler.h"
+ #include "content/browser/loader/stream_writer.h"
++#include "content/common/content_export.h"
+ 
+ namespace net {
+ class URLRequest;
+@@ -22,7 +23,7 @@ class ResourceController;
+ class StreamRegistry;
+ 
+ // Redirect this resource to a stream.
+-class StreamResourceHandler : public ResourceHandler {
++class CONTENT_EXPORT StreamResourceHandler : public ResourceHandler {
+  public:
+   // |origin| will be used to construct the URL for the Stream. See
+   // WebCore::BlobURL and and WebCore::SecurityOrigin in Blink to understand

+ 126 - 0
patches/common/chromium/sysroot.patch

@@ -0,0 +1,126 @@
+diff --git a/build/config/sysroot.gni b/build/config/sysroot.gni
+index d5daf2df2e41..46999e2e2198 100644
+--- a/build/config/sysroot.gni
++++ b/build/config/sysroot.gni
+@@ -32,17 +32,17 @@ if (current_os == target_os && current_cpu == target_cpu &&
+   # By default build against a sysroot image downloaded from Cloud Storage
+   # during gclient runhooks.
+   if (current_cpu == "x64") {
+-    sysroot = "$target_sysroot_dir/debian_sid_amd64-sysroot"
++    sysroot = "$target_sysroot_dir/debian_stretch_amd64-sysroot"
+   } else if (current_cpu == "x86") {
+-    sysroot = "$target_sysroot_dir/debian_sid_i386-sysroot"
++    sysroot = "$target_sysroot_dir/debian_stretch_i386-sysroot"
+   } else if (current_cpu == "mipsel") {
+-    sysroot = "$target_sysroot_dir/debian_sid_mips-sysroot"
++    sysroot = "$target_sysroot_dir/debian_stretch_mips-sysroot"
+   } else if (current_cpu == "mips64el") {
+-    sysroot = "$target_sysroot_dir/debian_sid_mips64el-sysroot"
++    sysroot = "$target_sysroot_dir/debian_stretch_mips64el-sysroot"
+   } else if (current_cpu == "arm") {
+-    sysroot = "$target_sysroot_dir/debian_sid_arm-sysroot"
++    sysroot = "$target_sysroot_dir/debian_stretch_arm-sysroot"
+   } else if (current_cpu == "arm64") {
+-    sysroot = "$target_sysroot_dir/debian_sid_arm64-sysroot"
++    sysroot = "$target_sysroot_dir/debian_stretch_arm64-sysroot"
+   } else {
+     assert(false, "No linux sysroot for cpu: $target_cpu")
+   }
+diff --git a/build/linux/sysroot_scripts/install-sysroot.py b/build/linux/sysroot_scripts/install-sysroot.py
+index 58f09950d844..53500a0853a6 100755
+--- a/build/linux/sysroot_scripts/install-sysroot.py
++++ b/build/linux/sysroot_scripts/install-sysroot.py
+@@ -31,8 +31,8 @@ import urllib2
+ 
+ SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
+ 
+-URL_PREFIX = 'https://commondatastorage.googleapis.com'
+-URL_PATH = 'chrome-linux-sysroot/toolchain'
++URL_PREFIX = 'http://s3.amazonaws.com'
++URL_PATH = 'gh-contractor-zcbenz/toolchain'
+ 
+ VALID_ARCHS = ('arm', 'arm64', 'i386', 'amd64', 'mips', 'mips64el')
+ 
+@@ -43,7 +43,7 @@ ARCH_TRANSLATIONS = {
+     'mips64': 'mips64el',
+ }
+ 
+-DEFAULT_TARGET_PLATFORM = 'sid'
++DEFAULT_TARGET_PLATFORM = 'stretch'
+ 
+ class Error(Exception):
+   pass
+diff --git a/build/linux/sysroot_scripts/sysroots.json b/build/linux/sysroot_scripts/sysroots.json
+index 48a1d36f0609..91ef1417a1bf 100644
+--- a/build/linux/sysroot_scripts/sysroots.json
++++ b/build/linux/sysroot_scripts/sysroots.json
+@@ -1,38 +1,38 @@
+ {
+-    "sid_amd64": {
+-        "Revision": "15b7efb900d75f7316c6e713e80f87b9904791b1",
+-        "Sha1Sum": "85ac8d5e0f6cff99fc323fd3d29cb73e2aa970e2",
+-        "SysrootDir": "debian_sid_amd64-sysroot",
+-        "Tarball": "debian_sid_amd64_sysroot.tar.xz"
++    "stretch_amd64": {
++        "Revision": "02772eaba5440a79c6bd2d9cb7e42fa836950366",
++        "Sha1Sum": "69457fddca3500e2dde124f77f8382b0a18d765e",
++        "SysrootDir": "debian_stretch_amd64-sysroot",
++        "Tarball": "debian_stretch_amd64_sysroot.tgz"
+     },
+-    "sid_arm": {
+-        "Revision": "15b7efb900d75f7316c6e713e80f87b9904791b1",
+-        "Sha1Sum": "ed31924757f11885a21793dc4b928d07ab25740c",
+-        "SysrootDir": "debian_sid_arm-sysroot",
+-        "Tarball": "debian_sid_arm_sysroot.tar.xz"
++    "stretch_arm": {
++        "Revision": "02772eaba5440a79c6bd2d9cb7e42fa836950366",
++        "Sha1Sum": "3e880f69177992ce02b05deeac619f7591b30287",
++        "SysrootDir": "debian_stretch_arm-sysroot",
++        "Tarball": "debian_stretch_arm_sysroot.tgz"
+     },
+-    "sid_arm64": {
+-        "Revision": "15b7efb900d75f7316c6e713e80f87b9904791b1",
+-        "Sha1Sum": "b9447285e58c5260bd9fa2737d1f0d1f82156738",
+-        "SysrootDir": "debian_sid_arm64-sysroot",
+-        "Tarball": "debian_sid_arm64_sysroot.tar.xz"
++    "stretch_arm64": {
++        "Revision": "02772eaba5440a79c6bd2d9cb7e42fa836950366",
++        "Sha1Sum": "8fd58c7d4b38fa3c6785573c6310cf6ca6c88312",
++        "SysrootDir": "debian_stretch_arm64-sysroot",
++        "Tarball": "debian_stretch_arm64_sysroot.tgz"
+     },
+-    "sid_i386": {
+-        "Revision": "15b7efb900d75f7316c6e713e80f87b9904791b1",
+-        "Sha1Sum": "f09856d93f39e8df84ffd9c04881f44e6cbc0508",
+-        "SysrootDir": "debian_sid_i386-sysroot",
+-        "Tarball": "debian_sid_i386_sysroot.tar.xz"
++    "stretch_i386": {
++        "Revision": "02772eaba5440a79c6bd2d9cb7e42fa836950366",
++        "Sha1Sum": "1bd14db5eb0466064659126d398b38220013fb38",
++        "SysrootDir": "debian_stretch_i386-sysroot",
++        "Tarball": "debian_stretch_i386_sysroot.tgz"
+     },
+-    "sid_mips": {
+-        "Revision": "15b7efb900d75f7316c6e713e80f87b9904791b1",
+-        "Sha1Sum": "90586b566b567b2bcf49e7fd112f0c8189bbd07b",
+-        "SysrootDir": "debian_sid_mips-sysroot",
+-        "Tarball": "debian_sid_mips_sysroot.tar.xz"
++    "stretch_mips": {
++        "Revision": "02772eaba5440a79c6bd2d9cb7e42fa836950366",
++        "Sha1Sum": "285751660ffab14e6d052c8ddb5c90752a51704d",
++        "SysrootDir": "debian_stretch_mips-sysroot",
++        "Tarball": "debian_stretch_mips_sysroot.tgz"
+     },
+-    "sid_mips64el": {
+-        "Revision": "15b7efb900d75f7316c6e713e80f87b9904791b1",
+-        "Sha1Sum": "f90c3b81485ffebb283afddb1a72bc61e14c593d",
+-        "SysrootDir": "debian_sid_mips64el-sysroot",
+-        "Tarball": "debian_sid_mips64el_sysroot.tar.xz"
+-    }
++    "stretch_mips64el": {
++        "Revision": "02772eaba5440a79c6bd2d9cb7e42fa836950366",
++        "Sha1Sum": "23f51f29bc35a550092dde41dc823780fdb50f9e",
++        "SysrootDir": "debian_stretch_mips64el-sysroot",
++        "Tarball": "debian_stretch_mips64el_sysroot.tgz"
++     }
+ }

+ 15 - 0
patches/common/chromium/thread_capabilities.patch

@@ -0,0 +1,15 @@
+diff --git a/sandbox/linux/services/credentials.cc b/sandbox/linux/services/credentials.cc
+index 50a109e..3ee9159 100644
+--- a/sandbox/linux/services/credentials.cc
++++ b/sandbox/linux/services/credentials.cc
+@@ -358,8 +358,10 @@ pid_t Credentials::ForkAndDropCapabilitiesInChild() {
+     return pid;
+   }
+ 
++#if 0
+   // Since we just forked, we are single threaded.
+   PCHECK(DropAllCapabilitiesOnCurrentThread());
++#endif
+   return 0;
+ }
+ 

+ 48 - 0
patches/common/chromium/use_transparent_window.patch

@@ -0,0 +1,48 @@
+diff --git a/ui/gl/gpu_switching_manager.cc b/ui/gl/gpu_switching_manager.cc
+index be7156465809..cee3b1af3dc5 100644
+--- a/ui/gl/gpu_switching_manager.cc
++++ b/ui/gl/gpu_switching_manager.cc
+@@ -4,6 +4,12 @@
+ 
+ #include "ui/gl/gpu_switching_manager.h"
+ 
++namespace {
++
++bool g_use_transparent = false;
++
++}  // namespace
++
+ namespace ui {
+ 
+ // static
+@@ -11,6 +17,16 @@ GpuSwitchingManager* GpuSwitchingManager::GetInstance() {
+   return base::Singleton<GpuSwitchingManager>::get();
+ }
+ 
++// static
++void GpuSwitchingManager::SetTransparent(bool transparent) {
++  g_use_transparent = transparent;
++}
++
++// static
++bool GpuSwitchingManager::UseTransparent() {
++  return g_use_transparent;
++}
++
+ GpuSwitchingManager::GpuSwitchingManager() {}
+ 
+ GpuSwitchingManager::~GpuSwitchingManager() {}
+diff --git a/ui/gl/gpu_switching_manager.h b/ui/gl/gpu_switching_manager.h
+index 4308bbed9398..a7cafcfccdff 100644
+--- a/ui/gl/gpu_switching_manager.h
++++ b/ui/gl/gpu_switching_manager.h
+@@ -18,6 +18,9 @@ class GL_EXPORT GpuSwitchingManager {
+   // Getter for the singleton. This will return NULL on failure.
+   static GpuSwitchingManager* GetInstance();
+ 
++  static void SetTransparent(bool transparent);
++  static bool UseTransparent();
++
+   void AddObserver(GpuSwitchingObserver* observer);
+   void RemoveObserver(GpuSwitchingObserver* observer);
+ 

+ 12 - 0
patches/common/chromium/v8_context_snapshot_generator.patch

@@ -0,0 +1,12 @@
+diff --git a/tools/v8_context_snapshot/BUILD.gn b/tools/v8_context_snapshot/BUILD.gn
+index d6691a527f25..000105b86f53 100644
+--- a/tools/v8_context_snapshot/BUILD.gn
++++ b/tools/v8_context_snapshot/BUILD.gn
+@@ -105,6 +105,7 @@ if (use_v8_context_snapshot) {
+     configs += [
+       "//v8:external_startup_data",
+       ":disable_icf",
++      "//electron/build/config:build_time_executable"
+     ]
+   }
+ }

+ 115 - 0
patches/common/chromium/web_contents.patch

@@ -0,0 +1,115 @@
+diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
+index 018534073da1..48f3d0e7343b 100644
+--- a/content/browser/web_contents/web_contents_impl.cc
++++ b/content/browser/web_contents/web_contents_impl.cc
+@@ -1759,6 +1759,12 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
+   std::string unique_name;
+   frame_tree_.root()->SetFrameName(params.main_frame_name, unique_name);
+ 
++  if (params.view && params.delegate_view) {
++    view_.reset(params.view);
++    render_view_host_delegate_view_ = params.delegate_view;
++  }
++
++  if (!view_) {
+   WebContentsViewDelegate* delegate =
+       GetContentClient()->browser()->GetWebContentsViewDelegate(this);
+ 
+@@ -1774,6 +1780,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
+           &render_view_host_delegate_view_);
+     }
+   }
++  }  //  !view_
+   CHECK(render_view_host_delegate_view_);
+   CHECK(view_.get());
+ 
+diff --git a/content/browser/web_contents/web_contents_view_guest.cc b/content/browser/web_contents/web_contents_view_guest.cc
+index 699570cc1390..454830098cb9 100644
+--- a/content/browser/web_contents/web_contents_view_guest.cc
++++ b/content/browser/web_contents/web_contents_view_guest.cc
+@@ -67,21 +67,27 @@ gfx::NativeWindow WebContentsViewGuest::GetTopLevelNativeWindow() const {
+ 
+ void WebContentsViewGuest::OnGuestAttached(WebContentsView* parent_view) {
+ #if defined(USE_AURA)
++  if (!platform_view_->GetNativeView())
++    return;
+   // In aura, ScreenPositionClient doesn't work properly if we do
+   // not have the native view associated with this WebContentsViewGuest in the
+   // view hierarchy. We add this view as embedder's child here.
+   // This would go in WebContentsViewGuest::CreateView, but that is too early to
+   // access embedder_web_contents(). Therefore, we do it here.
+   if (!base::FeatureList::IsEnabled(features::kMash))
+-    parent_view->GetNativeView()->AddChild(platform_view_->GetNativeView());
++    if (parent_view->GetNativeView() != platform_view_->GetNativeView())
++      parent_view->GetNativeView()->AddChild(platform_view_->GetNativeView());
+ #endif  // defined(USE_AURA)
+ }
+ 
+ void WebContentsViewGuest::OnGuestDetached(WebContentsView* old_parent_view) {
+ #if defined(USE_AURA)
++  if (!platform_view_->GetNativeView())
++    return;
+   if (!base::FeatureList::IsEnabled(features::kMash)) {
+-    old_parent_view->GetNativeView()->RemoveChild(
+-        platform_view_->GetNativeView());
++    if (old_parent_view->GetNativeView() != platform_view_->GetNativeView())
++      old_parent_view->GetNativeView()->RemoveChild(
++          platform_view_->GetNativeView());
+   }
+ #endif  // defined(USE_AURA)
+ }
+@@ -146,11 +152,22 @@ RenderWidgetHostViewBase* WebContentsViewGuest::CreateViewForWidget(
+         render_widget_host->GetView());
+   }
+ 
++  RenderWidgetHost* embedder_render_widget_host =
++    guest_->embedder_web_contents()->GetRenderViewHost()->GetWidget();
++  RenderWidgetHostViewBase* embedder_render_widget_host_view =
++      static_cast<RenderWidgetHostViewBase*>(
++        embedder_render_widget_host->GetView());
+   RenderWidgetHostViewBase* platform_widget =
+-      platform_view_->CreateViewForWidget(render_widget_host, true);
+-
+-  return RenderWidgetHostViewGuest::Create(render_widget_host, guest_,
+-                                           platform_widget->GetWeakPtr());
++      embedder_render_widget_host_view->CreateViewForWidget(
++        render_widget_host,
++        embedder_render_widget_host,
++        platform_view_.get());
++  RenderWidgetHostViewGuest* guest_view = RenderWidgetHostViewGuest::Create(
++    render_widget_host, guest_, platform_widget->GetWeakPtr());
++  platform_widget->InitAsGuest(embedder_render_widget_host->GetView(),
++                               guest_view);
++
++  return guest_view;
+ }
+ 
+ RenderWidgetHostViewBase* WebContentsViewGuest::CreateViewForPopupWidget(
+diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
+index a13db5f4dd61..621124decfdc 100644
+--- a/content/public/browser/web_contents.h
++++ b/content/public/browser/web_contents.h
+@@ -69,9 +69,12 @@ class BrowserPluginGuestDelegate;
+ class InterstitialPage;
+ class RenderFrameHost;
+ class RenderViewHost;
++class RenderViewHostDelegateView;
+ class RenderWidgetHost;
+ class RenderWidgetHostView;
++class RenderWidgetHostViewBase;
+ class WebContentsDelegate;
++class WebContentsView;
+ struct CustomContextMenuContext;
+ struct DropData;
+ struct Manifest;
+@@ -172,6 +175,10 @@ class WebContents : public PageNavigator,
+     // navigation requires a dedicated or privileged process, such as a WebUI.
+     bool initialize_renderer;
+ 
++    // Optionally specify the view and delegate view.
++    content::WebContentsView* view = nullptr;
++    content::RenderViewHostDelegateView* delegate_view = nullptr;
++
+     // Sandboxing flags set on the new WebContents.
+     blink::WebSandboxFlags starting_sandbox_flags;
+   };

+ 111 - 0
patches/common/chromium/webgl_context_attributes.patch

@@ -0,0 +1,111 @@
+diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
+index 0affacaa0294..0c321d51364d 100644
+--- a/content/renderer/renderer_blink_platform_impl.cc
++++ b/content/renderer/renderer_blink_platform_impl.cc
+@@ -1136,8 +1136,10 @@ RendererBlinkPlatformImpl::CreateOffscreenGraphicsContext3DProvider(
+   attributes.sample_buffers = 0;
+   attributes.bind_generates_resource = false;
+   attributes.enable_raster_interface = web_attributes.enable_raster_interface;
+-  // Prefer discrete GPU for WebGL.
+-  attributes.gpu_preference = gl::PreferDiscreteGpu;
++
++  attributes.gpu_preference = web_attributes.prefer_integrated_gpu
++      ? gl::PreferIntegratedGpu
++      : gl::PreferDiscreteGpu;
+ 
+   attributes.fail_if_major_perf_caveat =
+       web_attributes.fail_if_major_performance_caveat;
+diff --git a/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h b/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h
+index ca4543a10e69..a1f5e5c9f906 100644
+--- a/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h
++++ b/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h
+@@ -30,6 +30,7 @@ class CORE_EXPORT CanvasContextCreationAttributesCore {
+   String pixel_format = "8-8-8-8";
+   bool premultiplied_alpha = true;
+   bool preserve_drawing_buffer = false;
++  String power_preference = "default";
+   bool stencil = false;
+ 
+   // This attribute is of type XRDevice, defined in modules/xr/XRDevice.h
+diff --git a/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl b/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl
+index 7419bb20d316..5b04af00fab4 100644
+--- a/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl
++++ b/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl
+@@ -28,6 +28,12 @@ enum CanvasPixelFormat {
+     "float16",
+ };
+ 
++enum CanvasPowerPreference {
++    "default",
++    "low-power",
++    "high-performance",
++};
++
+ [PermissiveDictionaryConversion]
+ dictionary CanvasContextCreationAttributesModule {
+     // This is an experimental feature, but it is not hidden behind a flag in
+@@ -47,6 +47,7 @@ dictionary CanvasContextCreationAttributesModule {
+     boolean antialias = true;
+     boolean premultipliedAlpha = true;
+     boolean preserveDrawingBuffer = false;
++    CanvasPowerPreference powerPreference = "default";
+     boolean failIfMajorPerformanceCaveat = false;
+     [OriginTrialEnabled=WebXR] XRDevice compatibleXRDevice = null;
+ };
+diff --git a/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.cc b/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.cc
+index 332fa9fb0547..e8fae4b01c39 100644
+--- a/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.cc
++++ b/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.cc
+@@ -18,6 +18,7 @@ WebGLContextAttributes ToWebGLContextAttributes(
+   result.setAntialias(attrs.antialias);
+   result.setPremultipliedAlpha(attrs.premultiplied_alpha);
+   result.setPreserveDrawingBuffer(attrs.preserve_drawing_buffer);
++  result.setPowerPreference(attrs.power_preference);
+   result.setFailIfMajorPerformanceCaveat(
+       attrs.fail_if_major_performance_caveat);
+   result.setCompatibleXRDevice(
+@@ -30,6 +30,7 @@ Platform::ContextAttributes ToPlatformContextAttributes(
+     unsigned web_gl_version,
+     bool support_own_offscreen_surface) {
+   Platform::ContextAttributes result;
++  result.prefer_integrated_gpu = attrs.power_preference == "low-power";
+   result.fail_if_major_performance_caveat =
+       attrs.fail_if_major_performance_caveat;
+   result.context_type = web_gl_version == 2 ? Platform::kWebGL2ContextType
+diff --git a/third_party/blink/renderer/modules/webgl/webgl_context_attributes.idl b/third_party/blink/renderer/modules/webgl/webgl_context_attributes.idl
+index 180673be9bd0..0af29cbc9402 100644
+--- a/third_party/blink/renderer/modules/webgl/webgl_context_attributes.idl
++++ b/third_party/blink/renderer/modules/webgl/webgl_context_attributes.idl
+@@ -26,6 +26,12 @@
+ 
+ // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.2
+ 
++enum WebGLPowerPreference {
++    "default",
++    "low-power",
++    "high-performance",
++};
++
+ dictionary WebGLContextAttributes {
+     boolean alpha = true;
+     boolean depth = true;
+@@ -33,6 +33,7 @@ dictionary WebGLContextAttributes {
+     boolean antialias = true;
+     boolean premultipliedAlpha = true;
+     boolean preserveDrawingBuffer = false;
++    WebGLPowerPreference powerPreference = "default";
+     boolean failIfMajorPerformanceCaveat = false;
+     [OriginTrialEnabled=WebXR] XRDevice compatibleXRDevice = null;
+ };
+diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
+index d4948345246e..bc277ba6aa5f 100644
+--- a/third_party/blink/public/platform/platform.h
++++ b/third_party/blink/public/platform/platform.h
+@@ -522,6 +522,7 @@ class BLINK_PLATFORM_EXPORT Platform {
+     kGLES3ContextType,   // GLES 3.0 context
+   };
+   struct ContextAttributes {
++    bool prefer_integrated_gpu = false;
+     bool fail_if_major_performance_caveat = false;
+     ContextType context_type = kGLES2ContextType;
+     // Offscreen contexts usually share a surface for the default frame buffer

+ 138 - 0
patches/common/chromium/webui_in_subframes.patch

@@ -0,0 +1,138 @@
+diff --git a/content/browser/frame_host/render_frame_host_delegate.cc b/content/browser/frame_host/render_frame_host_delegate.cc
+index 4d0a8ea553c5..0fac0b22ff2f 100644
+--- a/content/browser/frame_host/render_frame_host_delegate.cc
++++ b/content/browser/frame_host/render_frame_host_delegate.cc
+@@ -89,8 +89,10 @@ bool RenderFrameHostDelegate::ShouldRouteMessageEvent(
+ }
+ 
+ std::unique_ptr<WebUIImpl>
+-RenderFrameHostDelegate::CreateWebUIForRenderFrameHost(const GURL& url) {
+-  return nullptr;
++RenderFrameHostDelegate::CreateWebUIForRenderFrameHost(
++    const GURL& url,
++    const std::string& frame_name) {
++  return nullptr;
+ }
+ 
+ bool RenderFrameHostDelegate::ShouldAllowRunningInsecureContent(
+diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h
+index 197b64b49fd6..2e94b03c4f44 100644
+--- a/content/browser/frame_host/render_frame_host_delegate.h
++++ b/content/browser/frame_host/render_frame_host_delegate.h
+@@ -234,7 +234,8 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
+   // Creates a WebUI object for a frame navigating to |url|. If no WebUI
+   // applies, returns null.
+   virtual std::unique_ptr<WebUIImpl> CreateWebUIForRenderFrameHost(
+-      const GURL& url);
++      const GURL& url,
++      const std::string& frame_name);
+ 
+   // Called by |frame| to notify that it has received an update on focused
+   // element. |bounds_in_root_view| is the rectangle containing the element that
+diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
+index 1f566ef1f437..bb2f59d62315 100644
+--- a/content/browser/frame_host/render_frame_host_impl.cc
++++ b/content/browser/frame_host/render_frame_host_impl.cc
+@@ -20,6 +20,7 @@
+ #include "base/process/kill.h"
+ #include "base/task_scheduler/post_task.h"
+ #include "base/time/time.h"
++#include "base/unguessable_token.h"
+ #include "build/build_config.h"
+ #include "cc/base/switches.h"
+ #include "content/browser/accessibility/browser_accessibility_manager.h"
+@@ -3468,8 +3514,23 @@ bool RenderFrameHostImpl::UpdatePendingWebUI(const GURL& dest_url,
+       DCHECK(web_ui_);
+       should_reuse_web_ui_ = true;
+     } else {
++      // Give the frame a name if it does not already have one.
++      // The reason is web ui code base the frame look up on the frame name.
++      std::string frame_name = GetFrameName();
++      if (frame_name.empty() && !frame_tree_node_->IsMainFrame()) {
++        frame_name = base::StringPrintf("frame_%i", frame_tree_node_->frame_tree_node_id());
++        frame_tree_node_->SetFrameName(
++            frame_name, frame_name + base::UnguessableToken::Create().ToString());
++      }
++
++      // If the web ui is in subframes, the parent frame bindings does not have the web ui binding,
++      // so we reset the bindings for the subframes.
++      if (!frame_tree_node_->IsMainFrame() && new_web_ui_type != WebUI::kNoWebUI) {
++        entry_bindings = NavigationEntryImpl::kInvalidBindings;
++      }
++
+       // Otherwise create a new pending WebUI.
+-      pending_web_ui_ = delegate_->CreateWebUIForRenderFrameHost(dest_url);
++      pending_web_ui_ = delegate_->CreateWebUIForRenderFrameHost(dest_url, frame_name);
+       DCHECK(pending_web_ui_);
+       pending_web_ui_type_ = new_web_ui_type;
+ 
+diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
+index f985ea2bceab..779cfd79312d 100644
+--- a/content/browser/web_contents/web_contents_impl.cc
++++ b/content/browser/web_contents/web_contents_impl.cc
+@@ -768,6 +768,25 @@ RenderFrameHostManager* WebContentsImpl::GetRenderManagerForTesting() {
+   return GetRenderManager();
+ }
+
++void SendMessageToFrameTreeWebUIs(RenderFrameHostImpl* parent_frame_host,
++                                  const IPC::Message& message,
++                                  int& dispatch_count) {
++  // Get the web ui or the pending one if it's not yet commited.
++  WebUIImpl* web_ui = parent_frame_host->web_ui()
++      ? parent_frame_host->web_ui()
++      : parent_frame_host->pending_web_ui();
++  if (web_ui && web_ui->OnMessageReceived(message, parent_frame_host)) {
++    ++dispatch_count;
++  }
++
++  size_t child_count = parent_frame_host->frame_tree_node()->child_count();
++  for (size_t i = 0; i < child_count; ++i) {
++    RenderFrameHostImpl* sub_frame_host =
++        parent_frame_host->frame_tree_node()->child_at(i)->current_frame_host();
++    SendMessageToFrameTreeWebUIs(sub_frame_host, message, dispatch_count);
++  }
++}
++
+ bool WebContentsImpl::OnMessageReceived(RenderViewHostImpl* render_view_host,
+                                         const IPC::Message& message) {
+   for (auto& observer : observers_) {
+@@ -809,9 +828,10 @@ bool WebContentsImpl::OnMessageReceived(RenderViewHostImpl* render_view_host,
+
+ bool WebContentsImpl::OnMessageReceived(RenderFrameHostImpl* render_frame_host,
+                                         const IPC::Message& message) {
+-  {
+-    WebUIImpl* web_ui = render_frame_host->web_ui();
+-    if (web_ui && web_ui->OnMessageReceived(message, render_frame_host))
++  int dispatch_count = 0;
++  if (render_frame_host) {
++    SendMessageToFrameTreeWebUIs(render_frame_host, message, dispatch_count);
++    if (dispatch_count > 0)
+       return true;
+   }
+
+@@ -5021,8 +5043,9 @@ NavigationControllerImpl& WebContentsImpl::GetControllerForRenderManager() {
+ }
+ 
+ std::unique_ptr<WebUIImpl> WebContentsImpl::CreateWebUIForRenderFrameHost(
+-    const GURL& url) {
+-  return CreateWebUI(url);
++    const GURL& url,
++    const std::string& frame_name) {
++  return CreateWebUI(url/*, frame_name*/);
+ }
+ 
+ NavigationEntry*
+diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
+index 84a01a83c72a..49d0a4b547c2 100644
+--- a/content/browser/web_contents/web_contents_impl.h
++++ b/content/browser/web_contents/web_contents_impl.h
+@@ -534,7 +534,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
+       SiteInstance* source_site_instance) const override;
+   void EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) override;
+   std::unique_ptr<WebUIImpl> CreateWebUIForRenderFrameHost(
+-      const GURL& url) override;
++      const GURL& url,
++      const std::string& frame_name) override;
+   void SetFocusedFrame(FrameTreeNode* node, SiteInstance* source) override;
+   void DidCallFocus() override;
+   RenderFrameHost* GetFocusedFrameIncludingInnerWebContents() override;

+ 24 - 0
patches/common/chromium/webview_cross_drag.patch

@@ -0,0 +1,24 @@
+diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
+index 1bfef2c..0ba2260 100644
+--- a/content/browser/web_contents/web_contents_view_aura.cc
++++ b/content/browser/web_contents/web_contents_view_aura.cc
+@@ -675,6 +675,7 @@ gfx::NativeView WebContentsViewAura::GetRenderWidgetHostViewParent() const {
+ 
+ bool WebContentsViewAura::IsValidDragTarget(
+     RenderWidgetHostImpl* target_rwh) const {
++  return true;
+   return target_rwh->GetProcess()->GetID() == drag_start_process_id_ ||
+       GetRenderViewHostID(web_contents_->GetRenderViewHost()) !=
+       drag_start_view_id_;
+diff --git a/content/browser/web_contents/web_drag_dest_mac.mm b/content/browser/web_contents/web_drag_dest_mac.mm
+index 37ed265..814a37d 100644
+--- a/content/browser/web_contents/web_drag_dest_mac.mm
++++ b/content/browser/web_contents/web_drag_dest_mac.mm
+@@ -348,6 +348,7 @@ - (void)setDragStartTrackersForProcess:(int)processID {
+ }
+ 
+ - (bool)isValidDragTarget:(content::RenderWidgetHostImpl*)targetRWH {
++  return YES;
+   return targetRWH->GetProcess()->GetID() == dragStartProcessID_ ||
+          GetRenderViewHostID(webContents_->GetRenderViewHost()) !=
+              dragStartViewID_;

+ 16 - 0
patches/common/chromium/webview_reattach.patch

@@ -0,0 +1,16 @@
+diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
+index b2d1e63..bc2cf9a 100644
+--- a/content/browser/web_contents/web_contents_impl.cc
++++ b/content/browser/web_contents/web_contents_impl.cc
+@@ -4562,6 +4562,11 @@ void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host,
+   for (auto& observer : observers_)
+     observer.RenderViewHostChanged(old_host, new_host);
+ 
++  // If this is an inner WebContents that has swapped views, we need to reattach
++  // it to its outer WebContents.
++  if (node_.outer_web_contents())
++    ReattachToOuterWebContentsFrame();
++
+   // Ensure that the associated embedder gets cleared after a RenderViewHost
+   // gets swapped, so we don't reuse the same embedder next time a
+   // RenderViewHost is attached to this WebContents.

+ 45 - 0
patches/common/chromium/windows_cc_wrapper.patch

@@ -0,0 +1,45 @@
+diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn
+index a526d47e7786..946df3cd513c 100644
+--- a/build/toolchain/win/BUILD.gn
++++ b/build/toolchain/win/BUILD.gn
+@@ -6,6 +6,7 @@ import("//build/config/clang/clang.gni")
+ import("//build/config/compiler/compiler.gni")
+ import("//build/config/sanitizers/sanitizers.gni")
+ import("//build/config/win/visual_studio_version.gni")
++import("//build/toolchain/cc_wrapper.gni")
+ import("//build/toolchain/clang_static_analyzer.gni")
+ import("//build/toolchain/goma.gni")
+ import("//build/toolchain/toolchain.gni")
+@@ -28,8 +29,14 @@ if (use_goma) {
+   } else {
+     goma_prefix = "$goma_dir/gomacc "
+   }
++  clang_prefix = goma_prefix
+ } else {
+   goma_prefix = ""
++  if (cc_wrapper != "") {
++    clang_prefix = cc_wrapper + " "
++  } else {
++    clang_prefix = ""
++  }
+ }
+ 
+ if (disable_goma) {
+@@ -389,7 +396,7 @@ if (target_os == "win" &&
+   msvc_toolchain("win_clang_" + target_cpu) {
+     environment = "environment." + target_cpu
+     prefix = rebase_path("$clang_base_path/bin", root_build_dir)
+-    cl = "${goma_prefix}$prefix/${clang_cl}"
++    cl = "${clang_prefix}$prefix/${clang_cl}"
+     sys_include_flags = "${target_cpu_toolchain_data.include_flags_imsvc}"
+ 
+     toolchain_args = {
+@@ -431,7 +438,7 @@ template("win_x64_toolchains") {
+   msvc_toolchain("win_clang_" + target_name) {
+     environment = "environment.x64"
+     prefix = rebase_path("$clang_base_path/bin", root_build_dir)
+-    cl = "${goma_prefix}$prefix/${clang_cl}"
++    cl = "${clang_prefix}$prefix/${clang_cl}"
+     sys_include_flags = "${x64_toolchain_data.include_flags_imsvc}"
+ 
+     toolchain_args = {

+ 74 - 0
patches/common/chromium/worker_context_will_destroy.patch

@@ -0,0 +1,74 @@
+diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
+index 0e554ba8467a..8e56489a5152 100644
+--- a/content/public/renderer/content_renderer_client.h
++++ b/content/public/renderer/content_renderer_client.h
+@@ -351,6 +351,11 @@ class CONTENT_EXPORT ContentRendererClient {
+   virtual void DidInitializeWorkerContextOnWorkerThread(
+       v8::Local<v8::Context> context) {}
+ 
++  // Notifies that a worker context will be destroyed. This function is called
++  // from the worker thread.
++  virtual void WillDestroyWorkerContextOnWorkerThread(
++      v8::Local<v8::Context> context) {}
++
+   // Overwrites the given URL to use an HTML5 embed if possible.
+   // An empty URL is returned if the URL is not overriden.
+   virtual GURL OverrideFlashEmbedWithHTML(const GURL& url);
+diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
+index 0affacaa0294..eca456faa640 100644
+--- a/content/renderer/renderer_blink_platform_impl.cc
++++ b/content/renderer/renderer_blink_platform_impl.cc
+@@ -1402,6 +1404,12 @@ void RendererBlinkPlatformImpl::WillStopWorkerThread() {
+   WorkerThreadRegistry::Instance()->WillStopCurrentWorkerThread();
+ }
+ 
++void RendererBlinkPlatformImpl::WorkerContextWillDestroy(
++    const v8::Local<v8::Context>& worker) {
++  GetContentClient()->renderer()->WillDestroyWorkerContextOnWorkerThread(
++      worker);
++}
++
+ void RendererBlinkPlatformImpl::WorkerContextCreated(
+     const v8::Local<v8::Context>& worker) {
+   GetContentClient()->renderer()->DidInitializeWorkerContextOnWorkerThread(
+diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
+index e8a4578009d1..e9ba4e7f391f 100644
+--- a/content/renderer/renderer_blink_platform_impl.h
++++ b/content/renderer/renderer_blink_platform_impl.h
+@@ -219,6 +219,7 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
+   void DidStartWorkerThread() override;
+   void WillStopWorkerThread() override;
+   void WorkerContextCreated(const v8::Local<v8::Context>& worker) override;
++  void WorkerContextWillDestroy(const v8::Local<v8::Context>& worker) override;
+ 
+   // Set the PlatformEventObserverBase in |platform_event_observers_| associated
+   // with |type| to |observer|. If there was already an observer associated to
+diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc
+index a522ba4dbdf7..6991078b36f5 100644
+--- a/third_party/blink/renderer/core/workers/worker_thread.cc
++++ b/third_party/blink/renderer/core/workers/worker_thread.cc
+@@ -481,6 +481,12 @@ void WorkerThread::PrepareForShutdownOnWorkerThread() {
+       SetExitCode(ExitCode::kGracefullyTerminated);
+   }
+ 
++  {
++    v8::HandleScope handle_scope(GetIsolate());
++    Platform::Current()->WorkerContextWillDestroy(
++        GlobalScope()->ScriptController()->GetContext());
++  }
++
+   inspector_task_runner_->Dispose();
+   GetWorkerReportingProxy().WillDestroyWorkerGlobalScope();
+   probe::AllAsyncTasksCanceled(GlobalScope());
+diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
+index 98ecb84..0779d4a 100644
+--- a/third_party/blink/public/platform/platform.h
++++ b/third_party/blink/public/platform/platform.h
+@@ -596,6 +596,7 @@ class BLINK_PLATFORM_EXPORT Platform {
+   virtual void DidStartWorkerThread() {}
+   virtual void WillStopWorkerThread() {}
+   virtual void WorkerContextCreated(const v8::Local<v8::Context>& worker) {}
++  virtual void WorkerContextWillDestroy(const v8::Local<v8::Context>& worker) {}
+   virtual bool AllowScriptExtensionForServiceWorker(const WebURL& script_url) {
+     return false;
+   }

+ 8 - 0
patches/common/crashpad/.patches.yaml

@@ -0,0 +1,8 @@
+repo: src
+patches:
+-
+  author: Jeremy Apthorp <[email protected]>
+  file: http_status.patch
+  description: |
+    Accept all HTTP codes in [200, 300) as successful, instead of just 200.
+    For example HockeyApp responds with 202.

+ 54 - 0
patches/common/crashpad/http_status.patch

@@ -0,0 +1,54 @@
+From 800aa10d300af0f3fe162ae586b6b1ebe0566ab4 Mon Sep 17 00:00:00 2001
+From: Catalin Fratila <[email protected]>
+Date: Fri, 19 May 2017 09:28:53 +0200
+Subject: [PATCH] Handle everything not in [200, 300) as error. For example
+ HockeyApp responds with 202.
+
+(cherry picked from commit f7c320766756a8aaa45ccbcff2945053d9f7e109)
+(cherry picked from commit 1875fddc7e671b14d8b54068301d9648d12e9dc2)
+(cherry picked from commit 670fb453b0c3d6ae0a0d5923f68df02464337617)
+---
+ third_party/crashpad/crashpad/util/net/http_transport_libcurl.cc | 2 +-
+ third_party/crashpad/crashpad/util/net/http_transport_mac.mm     | 2 +-
+ third_party/crashpad/crashpad/util/net/http_transport_win.cc     | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/third_party/crashpad/crashpad/util/net/http_transport_libcurl.cc b/third_party/crashpad/crashpad/util/net/http_transport_libcurl.cc
+index c16a593..0e262b0 100644
+--- a/third_party/crashpad/crashpad/util/net/http_transport_libcurl.cc
++++ b/third_party/crashpad/crashpad/util/net/http_transport_libcurl.cc
+@@ -338,7 +338,7 @@ bool HTTPTransportLibcurl::ExecuteSynchronously(std::string* response_body) {
+     return false;
+   }
+ 
+-  if (status != 200) {
++  if (status < 200 || status >= 300) {
+     LOG(ERROR) << base::StringPrintf("HTTP status %ld", status);
+     return false;
+   }
+diff --git a/third_party/crashpad/crashpad/util/net/http_transport_mac.mm b/third_party/crashpad/crashpad/util/net/http_transport_mac.mm
+index 8d5f78c..a6434c2 100644
+--- a/third_party/crashpad/crashpad/util/net/http_transport_mac.mm
++++ b/third_party/crashpad/crashpad/util/net/http_transport_mac.mm
+@@ -293,7 +293,7 @@ static void Unschedule(CFReadStreamRef stream,
+       return false;
+     }
+     NSInteger http_status = [http_response statusCode];
+-    if (http_status != 200) {
++    if (http_status < 200 || http_status >= 300) {
+       LOG(ERROR) << base::StringPrintf("HTTP status %ld",
+                                        implicit_cast<long>(http_status));
+       return false;
+diff --git a/third_party/crashpad/crashpad/util/net/http_transport_win.cc b/third_party/crashpad/crashpad/util/net/http_transport_win.cc
+index 18d343c..40c3061 100644
+--- a/third_party/crashpad/crashpad/util/net/http_transport_win.cc
++++ b/third_party/crashpad/crashpad/util/net/http_transport_win.cc
+@@ -375,7 +375,7 @@ bool HTTPTransportWin::ExecuteSynchronously(std::string* response_body) {
+     return false;
+   }
+ 
+-  if (status_code != 200) {
++  if (status_code < 200 || status_code >= 300) {
+     LOG(ERROR) << base::StringPrintf("HTTP status %lu", status_code);
+     return false;
+   }

+ 15 - 0
patches/common/ffmpeg/.patches.yaml

@@ -0,0 +1,15 @@
+repo: src/third_party/ffmpeg
+patches:
+-
+  author: Ales Pergl <[email protected]>
+  file: build_gn.patch
+  description: |
+    Chromium's Mac toolchain sets the "install_name" linker parameter only
+    when "is_component_build" is true, but we want to set even if it's false,
+    because we are making a dylib which will be distributed inside a bundle.
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: fix_build_on_linux_x86.patch
+  description: |
+    Builds on Linux x86 fail with a clang error. See https://crbug.com/796379.
+    Once it's fixed the patch can be removed.

+ 15 - 0
patches/common/ffmpeg/build_gn.patch

@@ -0,0 +1,15 @@
+diff --git a/BUILD.gn b/BUILD.gn
+index 5439b39693..6783292c3b 100755
+--- a/BUILD.gn
++++ b/BUILD.gn
+@@ -393,6 +393,10 @@ if (is_component_ffmpeg) {
+     # So we can append below and assume they're defined.
+     ldflags = []
+ 
++    if (!is_component_build && is_mac) {
++      ldflags += [ "-Wl,-install_name,@rpath/libffmpeg.dylib" ]
++    }
++
+     if (is_fuchsia || (is_posix && !is_mac)) {
+       # Fixes warnings PIC relocation when building as component.
+       ldflags += [

+ 13 - 0
patches/common/ffmpeg/fix_build_on_linux_x86.patch

@@ -0,0 +1,13 @@
+diff --git a/BUILD.gn b/BUILD.gn
+index ff09111634..fa7712a3a3 100755
+--- a/BUILD.gn
++++ b/BUILD.gn
+@@ -247,7 +247,7 @@ target(link_target_type, "ffmpeg_internal") {
+     # On POSIX x86, sanitizers will fail to compiler the H264 CABAC code due to
+     # insufficient registers unless we disable EBP usage. crbug.com/786760
+     if (target_cpu == "x86") {
+-      if (using_sanitizer) {
++      if (using_sanitizer || is_electron_build) {
+         defines += [ "HAVE_EBP_AVAILABLE=0" ]
+       } else {
+         defines += [ "HAVE_EBP_AVAILABLE=1" ]

+ 10 - 0
patches/common/icu/.patches.yaml

@@ -0,0 +1,10 @@
+repo: src/third_party/icu
+patches:
+-
+  author: Ales Pergl <[email protected]>
+  file: build_gn.patch
+  description: null
+-
+  author: Cheng Zhao <[email protected]>
+  file: no_inline_default_constructor.patch
+  description: null

+ 63 - 0
patches/common/icu/build_gn.patch

@@ -0,0 +1,63 @@
+diff --git a/BUILD.gn b/BUILD.gn
+index 76914cd7..a44d7896 100644
+--- a/BUILD.gn
++++ b/BUILD.gn
+@@ -34,7 +34,7 @@ config("icu_config") {
+     "U_ENABLE_DYLOAD=0",
+   ]
+ 
+-  if (!is_component_build) {
++  if (!is_component_build && !(is_electron_build && !is_electron_gn_build)) {
+     defines += [ "U_STATIC_IMPLEMENTATION" ]
+   }
+ 
+@@ -537,6 +537,24 @@ component("icui18n") {
+     ":icuuc",
+   ]
+ 
++  # In Electron all of ICU is in one binary, hence we must build with
++  # U_COMBINED_IMPLEMENTATION defined.
++  # Also, for the "static_library" configuration, keep icui18n as
++  # a shared library so that other Chromium targets build cleanly.
++  if (is_electron_build && !is_electron_gn_build) {
++    defines += [ "U_COMBINED_IMPLEMENTATION" ]
++
++    if (!is_component_build) {
++      static_component_type = "shared_library"
++
++      # Because GN already applied the wrong defaults (see the
++      # set_defaults("component") statement in BUILDCONFIG.gn) we must reset
++      # the configs and assign those for shared libraries.
++      configs = []
++      configs = default_shared_library_configs
++    }
++  }
++
+   # ICU uses RTTI, replace the default "no rtti" config.
+   configs -= [
+     "//build/config/compiler:no_rtti",  # ICU uses RTTI.
+@@ -945,6 +963,24 @@ component("icuuc") {
+     ":icudata",
+   ]
+ 
++  # In Electron all of ICU is in one binary, hence we must build with
++  # U_COMBINED_IMPLEMENTATION defined.
++  # Also, for the "static_library" configuration, keep icuuc as
++  # a shared library so that other Chromium targets build cleanly.
++  if (is_electron_build && !is_electron_gn_build) {
++    defines += [ "U_COMBINED_IMPLEMENTATION" ]
++
++    if (!is_component_build) {
++      static_component_type = "shared_library"
++
++      # Because GN already applied the wrong defaults (see the
++      # set_defaults("component") statement in BUILDCONFIG.gn) we must reset
++      # the configs and assign those for shared libraries.
++      configs = []
++      configs = default_shared_library_configs
++    }
++  }
++
+   configs -= [
+     "//build/config/compiler:no_rtti",  # ICU uses RTTI.
+     "//build/config/compiler:chromium_code",

+ 44 - 0
patches/common/icu/no_inline_default_constructor.patch

@@ -0,0 +1,44 @@
+diff --git a/source/common/unicode/unistr.h b/source/common/unicode/unistr.h
+index e0ab0b9e..fe4c673b 100644
+--- a/source/common/unicode/unistr.h
++++ b/source/common/unicode/unistr.h
+@@ -2957,7 +2957,7 @@ public:
+   /** Construct an empty UnicodeString.
+    * @stable ICU 2.0
+    */
+-  inline UnicodeString();
++  UnicodeString();
+ 
+   /**
+    * Construct a UnicodeString with capacity to hold <TT>capacity</TT> char16_ts
+@@ -3915,15 +3915,6 @@ UnicodeString::getArrayStart() const {
+     fUnion.fStackFields.fBuffer : fUnion.fFields.fArray;
+ }
+ 
+-//========================================
+-// Default constructor
+-//========================================
+-
+-inline
+-UnicodeString::UnicodeString() {
+-  fUnion.fStackFields.fLengthAndFlags=kShortString;
+-}
+-
+ inline UnicodeString::UnicodeString(const std::nullptr_t /*text*/) {
+   fUnion.fStackFields.fLengthAndFlags=kShortString;
+ }
+diff --git a/source/common/unistr.cpp b/source/common/unistr.cpp
+index 1bfb71aa..5495ee91 100644
+--- a/source/common/unistr.cpp
++++ b/source/common/unistr.cpp
+@@ -146,7 +146,9 @@ UnicodeString::releaseArray() {
+ // Constructors
+ //========================================
+ 
+-// The default constructor is inline in unistr.h.
++UnicodeString::UnicodeString() {
++  fUnion.fStackFields.fLengthAndFlags=kShortString;
++}
+ 
+ UnicodeString::UnicodeString(int32_t capacity, UChar32 c, int32_t count) {
+   fUnion.fFields.fLengthAndFlags = 0;

+ 6 - 0
patches/common/skia/.patches.yaml

@@ -0,0 +1,6 @@
+repo: src/third_party/skia
+patches:
+-
+  author: Ales Pergl <[email protected]>
+  file: dcheck.patch
+  description: null

+ 13 - 0
patches/common/skia/dcheck.patch

@@ -0,0 +1,13 @@
+diff --git a/include/core/SkPostConfig.h b/include/core/SkPostConfig.h
+index c34397cde6..5a55535eeb 100644
+--- a/include/core/SkPostConfig.h
++++ b/include/core/SkPostConfig.h
+@@ -18,7 +18,7 @@
+     #ifdef NDEBUG
+         #define SK_RELEASE
+     #else
+-        #define SK_DEBUG
++        #define SK_RELEASE
+     #endif
+ #endif
+ 

+ 87 - 0
patches/common/v8/.patches.yaml

@@ -0,0 +1,87 @@
+repo: src/v8
+patches:
+-
+  author: Shelley Vohr <[email protected]>
+  file: add_realloc.patch
+  description: |
+    Blink overrides ArrayBuffer's allocator with its own one, while Node simply
+    uses malloc and free, so we need to use v8's allocator in Node. As part of the
+    10.6.0 upgrade, we needed to make SerializerDelegate accept an allocator
+    argument in its constructor, and override ReallocateBufferMemory and
+    FreeBufferMemory to use the allocator. We cannot simply allocate and then memcpy
+    when we override ReallocateBufferMemory, so we therefore need to implement
+    Realloc on the v8 side.
+-
+  author: Ales Pergl <[email protected]>
+  file: build_gn.patch
+  description: null
+-
+  author: Cheng Zhao <[email protected]>
+  file: array_buffer.patch
+  description: null
+-
+  author: Cheng Zhao <[email protected]>
+  file: ostreams.patch
+  description: null
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: export_platform.patch
+  description: |
+    v8::Platform::SystemClockTimeMillis must be exported so that node::NodePlatform can call it
+-
+  author: Ales Pergl <[email protected]>
+  file: dcheck.patch
+  description: null
+-
+  author: Nitish Sakhawalkar <[email protected]>
+  file: disable-warning-win.patch
+  description:
+    Disable unit test windows build warning
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: backport_39d546a.patch
+  description: Node 10.0.0 needs it.
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: backport_ff0a97933.patch
+  description: Node 10.2.0 needs it.
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: backport_9fb02b526.patch
+  description: Node 10.2.0 needs it.
+-
+  author: Aleksei Kuzmin <[email protected]>
+  file: backport_23652c5f.patch
+  description: Node 10.2.0 needs it.
+-
+  author: Shelley Vohr <[email protected]>
+  file: backport_91ddb65d.patch
+  description: Node 10.6.0 needs it.
+-
+  author: Shelley Vohr <[email protected]>
+  file: cherry-pick_6989b3f6d7.patch
+  description: Node 10.6.0 needs it.
+-
+  author: Shelley Vohr <[email protected]>
+  file: cherry-pick_a440efb27f.patch
+  description: Node 10.6.0 needs it.
+-
+  author: Shelley Vohr <[email protected]>
+  file: cherry-pick_5dd3395.patch
+  description: Node 10.6.0 needs it.
+-
+  author: Shelley Vohr <[email protected]>
+  file: backport_aa6ce3e.patch
+  description: Node 10.6.0 needs it.
+-
+  author: Shelley Vohr <[email protected]>
+  file: cherry-pick_b20faff.patch
+  description: Node 10.6.0 needs it.
+-
+  author: Shelley Vohr <[email protected]>
+  file: cherry-pick_acc336c.patch
+  description: Node 10.6.0 needs it.
+-
+  author: Shelley Vohr <[email protected]>
+  file: cherry-pick_70c4340.patch
+  description: Node 10.6.0 needs it.

Some files were not shown because too many files changed in this diff