diff --git a/.gitignore b/.gitignore
index 8a02255..c1b82c6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
 *.bak
-*.gypcmd
 *.mk
 *.ncb
 *.opensdf
@@ -192,8 +191,11 @@
 /gpu/gles2_conform_test
 /infra/.recipe_deps
 /ios/third_party/earl_grey/src
+/ios/third_party/earl_grey2/src
+/ios/third_party/edo/src
 /ios/third_party/fishhook/src
 /ios/third_party/gcdwebserver/src
+/ios/third_party/gtx/src
 /ios/third_party/material_components_ios/src
 /ios/third_party/material_font_disk_loader_ios/src
 /ios/third_party/material_internationalization_ios/src
@@ -260,7 +262,6 @@
 /tools/gn/bin/linux
 /tools/gn/bin/mac
 /tools/gn/bin/win
-/tools/gyp
 /tools/histograms
 /tools/json_schema_compiler/test/json_schema_compiler_tests.xml
 /tools/metrics/actions/actions.old.xml
diff --git a/.gn b/.gn
index eaf210e..3a439c9b 100644
--- a/.gn
+++ b/.gn
@@ -74,90 +74,185 @@
 # their includes checked for proper dependencies when you run either
 # "gn check" or "gn gen --check".
 check_targets = [
-  #"//apps/*",  # Medium-hard.
+  "//apps/*",
   "//ash/*",
   "//base/*",
   "//blink/*",
   "//build/*",
   "//cc/*",
 
-  #"//chrome/*",  # Epic number of errors.
+  #"//chrome/android/*",  # 13 errors
   "//chrome/app/*",
   "//chrome/app_shim/*",
 
-  #"//chrome/browser/android/*",  # Only vr has errors. https://crbug.com/871623
-  "//chrome/browser/android/accessibility/*",
-  "//chrome/browser/android/autofill_assistant/*",
-  "//chrome/browser/android/bookmarks/*",
-  "//chrome/browser/android/bottombar/*",
-  "//chrome/browser/android/browserservices/*",
-  "//chrome/browser/android/browsing_data/*",
-  "//chrome/browser/android/component_updater/*",
-  "//chrome/browser/android/compositor/*",
-  "//chrome/browser/android/compositor/layer/*",
-  "//chrome/browser/android/compositor/resources/*",
-  "//chrome/browser/android/compositor/scene_layer/*",
-  "//chrome/browser/android/consent_auditor/*",
-  "//chrome/browser/android/content/*",
-  "//chrome/browser/android/contextualsearch/*",
-  "//chrome/browser/android/contextual_suggestions/*",
-  "//chrome/browser/android/cookies/*",
-  "//chrome/browser/android/crash/*",
-  "//chrome/browser/android/customtabs/*",
-  "//chrome/browser/android/digital_asset_links/*",
-  "//chrome/browser/android/document/*",
-  "//chrome/browser/android/dom_distiller/*",
-  "//chrome/browser/android/download/*",
-  "//chrome/browser/android/download/items/*",
-  "//chrome/browser/android/download/service/*",
-  "//chrome/browser/android/explore_sites/*",
-  "//chrome/browser/android/feature_engagement/*",
-  "//chrome/browser/android/feed/*",
-  "//chrome/browser/android/feedback/*",
-  "//chrome/browser/android/find_in_page/*",
-  "//chrome/browser/android/history/*",
-  "//chrome/browser/android/history_report/*",
-  "//chrome/browser/android/instantapps/*",
-  "//chrome/browser/android/locale/*",
-  "//chrome/browser/android/metrics/*",
-  "//chrome/browser/android/mojo/*",
-  "//chrome/browser/android/net/*",
-  "//chrome/browser/android/ntp/*",
-  "//chrome/browser/android/omnibox/*",
-  "//chrome/browser/android/oom_intervention/*",
-  "//chrome/browser/android/password_manager/*",
-  "//chrome/browser/android/payments/*",
-  "//chrome/browser/android/policy/*",
-  "//chrome/browser/android/preferences/*",
-  "//chrome/browser/android/preferences/autofill/*",
-  "//chrome/browser/android/profiles/*",
-  "//chrome/browser/android/proto/*",
-  "//chrome/browser/android/provider/*",
-  "//chrome/browser/android/rappor/*",
-  "//chrome/browser/android/rlz/*",
-  "//chrome/browser/android/search_permissions/*",
-  "//chrome/browser/android/sessions/*",
-  "//chrome/browser/android/signin/*",
-  "//chrome/browser/android/subresource_filter/*",
-  "//chrome/browser/android/tasks/*",
-  "//chrome/browser/android/thumbnail/*",
-  "//chrome/browser/android/usb/*",
-  "//chrome/browser/android/vr/arcore_device/*",
-  "//chrome/browser/android/webapk/*",
-  "//chrome/browser/android/webapps/*",
-  "//chrome/browser/android/widget/*",
-
+  #"//chrome/browser/*",  # ~1300 errors
+  #"//chrome/browser:*",  # ~600 errors
+  "//chrome/browser/accessibility/*",
+  "//chrome/browser/android/*",
+  "//chrome/browser/app_mode/*",
+  "//chrome/browser/apps/*",
+  "//chrome/browser/assist_ranker/*",
+  "//chrome/browser/autocomplete/*",
+  "//chrome/browser/autofill/*",
+  "//chrome/browser/background/*",
+  "//chrome/browser/background_fetch/*",
+  "//chrome/browser/background_sync/*",
+  "//chrome/browser/banners/*",
+  "//chrome/browser/bitmap_fetcher/*",
+  "//chrome/browser/bookmarks/*",
+  "//chrome/browser/browsing_data/*",
+  "//chrome/browser/budget_service/*",
+  "//chrome/browser/captive_portal/*",
+  "//chrome/browser/chooser_controller/*",
   "//chrome/browser/chromeos/*",
+  "//chrome/browser/client_hints/*",
+  "//chrome/browser/clipboard/*",
+  "//chrome/browser/component_updater/*",
+  "//chrome/browser/conflicts/*",
+  "//chrome/browser/consent_auditor/*",
+  "//chrome/browser/content_settings/*",
+  "//chrome/browser/crash_upload_list/*",
+  "//chrome/browser/custom_handlers/*",
+  "//chrome/browser/data_saver/*",
+  "//chrome/browser/data_use_measurement/*",
+  "//chrome/browser/dbus/*",
+
+  #"//chrome/browser/devtools/*",  # 93 errors
+  "//chrome/browser/diagnostics/*",
+  "//chrome/browser/domain_reliability/*",
+  "//chrome/browser/dom_distiller/*",
+  "//chrome/browser/downgrade/*",
+  "//chrome/browser/download/*",
+  "//chrome/browser/drive/*",
+  "//chrome/browser/engagement/*",
   "//chrome/browser/extensions/*",
+  "//chrome/browser/external_protocol/*",
+  "//chrome/browser/favicon/*",
+  "//chrome/browser/feature_engagement/*",
+  "//chrome/browser/feedback/*",
+  "//chrome/browser/first_run/*",
+  "//chrome/browser/gcm/*",
+  "//chrome/browser/generic_sensor/*",
+  "//chrome/browser/geolocation/*",
+  "//chrome/browser/google/*",
+  "//chrome/browser/gpu/*",
+  "//chrome/browser/guest_view/*",
+  "//chrome/browser/hang_monitor/*",
+  "//chrome/browser/history/*",
+  "//chrome/browser/importer/*",
+  "//chrome/browser/infobars/*",
+  "//chrome/browser/installable/*",
+  "//chrome/browser/install_verification/*",
+  "//chrome/browser/internal/*",
+  "//chrome/browser/interstitials/*",
+  "//chrome/browser/invalidation/*",
+  "//chrome/browser/language/*",
+  "//chrome/browser/lifetime/*",
+
+  #"//chrome/browser/loader/*",  # 2 errors
+  "//chrome/browser/local_discovery/*",
+  "//chrome/browser/mac/*",
+
+  #"//chrome/browser/media/*",  # 74 errors
+  "//chrome/browser/media_galleries/*",
+  "//chrome/browser/memory/*",
+  "//chrome/browser/metrics/*",
+  "//chrome/browser/nacl_host/*",
+  "//chrome/browser/navigation_predictor/*",
+  "//chrome/browser/net/*",
+  "//chrome/browser/notifications/*",
+  "//chrome/browser/ntp_snippets/*",
+  "//chrome/browser/ntp_tiles/*",
+  "//chrome/browser/obsolete_system/*",
+  "//chrome/browser/offline_items_collection/*",
+  "//chrome/browser/offline_pages/*",
+  "//chrome/browser/page_load_metrics/*",
+  "//chrome/browser/password_manager/*",
+  "//chrome/browser/payments/*",
+  "//chrome/browser/pdf/*",
+  "//chrome/browser/performance_monitor/*",
+  "//chrome/browser/permissions/*",
+  "//chrome/browser/picture_in_picture/*",
+  "//chrome/browser/plugins/*",
+
+  # "//chrome/browser/policy/*",  # 1 error on Windows
+  "//chrome/browser/predictors/*",
+  "//chrome/browser/prefetch/*",
+  "//chrome/browser/prefs/*",
+  "//chrome/browser/prerender/*",
+  "//chrome/browser/previews/*",
+  "//chrome/browser/printing/*",
+  "//chrome/browser/profile_resetter/*",
+  "//chrome/browser/profiles/*",
+
+  #"//chrome/browser/profiling_host/*",  # 16 errors
+  "//chrome/browser/push_messaging/*",
+  "//chrome/browser/recovery/*",
+  "//chrome/browser/renderer_context_menu/*",
+  "//chrome/browser/renderer_host/*",
   "//chrome/browser/resource_coordinator/*",
+
+  #"//chrome/browser/resources/*",  # 18 errors on ChromeOS
+  "//chrome/browser/rlz/*",
+
+  #"//chrome/browser/safe_browsing/*",  # 239 errors
+  "//chrome/browser/search/*",
+  "//chrome/browser/search_engines/*",
+  "//chrome/browser/search_provider_logos/*",
+  "//chrome/browser/service_process/*",
+  "//chrome/browser/sessions/*",
+  "//chrome/browser/signin/*",
+  "//chrome/browser/speech/*",
+  "//chrome/browser/spellchecker/*",
+  "//chrome/browser/ssl/*",
+  "//chrome/browser/status_icons/*",
+  "//chrome/browser/storage/*",
+  "//chrome/browser/subresource_filter/*",
+  "//chrome/browser/supervised_user/*",
+  "//chrome/browser/sync/*",
+  "//chrome/browser/sync_file_system/*",
+  "//chrome/browser/tab_contents/*",
+  "//chrome/browser/task_manager/*",
+  "//chrome/browser/themes/*",
+  "//chrome/browser/thumbnails/*",
+  "//chrome/browser/tracing/*",
+  "//chrome/browser/translate/*",
   "//chrome/browser/ui/*",
+  "//chrome/browser/undo/*",
+  "//chrome/browser/unified_consent/*",
+  "//chrome/browser/update_client/*",
+  "//chrome/browser/upgrade_detector/*",
+  "//chrome/browser/usb/*",
+  "//chrome/browser/vr/*",
+  "//chrome/browser/web_applications/*",
+  "//chrome/browser/webauthn/*",
+  "//chrome/browser/webshare/*",
+  "//chrome/browser/win/*",
+
+  "//chrome/build/*",
+
+  #"//chrome/child/*",  # 1 error on Windows
   "//chrome/chrome_cleaner/*",
+
+  #"//chrome/chrome_watcher/*",  # 3 errors on Windows
   "//chrome/common/*",
+
+  #"//chrome/elevation_service/*",  # 1 error on Windows
+  #"//chrome/gpu/*",  # 7 errors
   "//chrome/installer/*",
-  "//chrome/profiling",
-  "//chrome/third_party/mozilla_security_manager/*",
+
+  #"//chrome/install_static/*",  # 8 errors on Windows
+  "//chrome/nacl/*",
+
+  #"//chrome/notification_helper/*",  # 4 errors on Windows
+  #"//chrome/renderer/*",  # ~30 errors
+  #"//chrome/service/*",  # 2 errors
+  #"//chrome/services/*",  # ~30 errors
+  #"//chrome/test/*",  # ~3000 errors
+  "//chrome/third_party/*",
   "//chrome/tools/*",
   "//chrome/utility/*",
+
   "//chromecast/*",
   "//chromeos/*",
   "//chrome_elf/*",
@@ -171,14 +266,19 @@
   "//device/*",
 
   #"//extensions/*",  # Lots of errors.
+  "//extensions:extensions_resources",
+  "//extensions:extensions_browsertests",
   "//extensions:extensions_unittests",
+  "//extensions/browser",
   "//extensions/browser:browser_tests",
   "//extensions/browser:unit_tests",
   "//extensions/browser/install:*",
-  "//extensions/common:common",
-  "//extensions/common:unit_tests",
+  "//extensions/common/*",
+  "//extensions/components/javascript_dialog_extensions_client",
+  "//extensions/components/native_app_window",
   "//extensions/renderer:unit_tests",
   "//extensions/shell/*",
+  "//extensions/strings/*",
   "//gin/*",
   "//google_apis/*",
   "//google_update/*",
@@ -214,24 +314,297 @@
   "//testing/*",
 
   #"//third_party/*",  # May not ever want this.
+  "//third_party/Python-Markdown/*",
+
+  # "//third_party/SPIRV-Tools/*",  # 30ish errors
+  "//third_party/WebKit/*",
+  "//third_party/abseil-cpp/*",
+  "//third_party/accessibility-audit/*",
+  "//third_party/accessibility_test_framework/*",
+  "//third_party/adobe/*",
+  "//third_party/afl/*",
+  "//third_party/analytics/*",
+  "//third_party/android_build_tools/*",
+  "//third_party/android_crazy_linker/*",
+  "//third_party/android_data_chart/*",
+  "//third_party/android_deps/*",
+  "//third_party/android_media/*",
+  "//third_party/android_ndk/*",
+  "//third_party/android_opengl/*",
+  "//third_party/android_platform/*",
+  "//third_party/android_protobuf/*",
+  "//third_party/android_sdk/*",
+  "//third_party/android_support_test_runner/*",
+  "//third_party/android_swipe_refresh/*",
+  "//third_party/android_system_sdk/*",
+  "//third_party/android_testrunner/*",
+  "//third_party/android_tools/*",
+
+  # "//third_party/angle/*",  # 30ish errors
+  "//third_party/apache-portable-runtime/*",
+  "//third_party/apache_velocity/*",
+  "//third_party/apache-win32/*",
+  "//third_party/apk-patch-size-estimator/*",
+  "//third_party/apple_apsl/*",
+  "//third_party/appurify-python/*",
+  "//third_party/arcore-android-sdk/*",
+  "//third_party/ashmem/*",
+  "//third_party/auto/*",
+  "//third_party/axe-core/*",
+  "//third_party/bazel/*",
+  "//third_party/bidichecker/*",
+  "//third_party/binutils/*",
+  "//third_party/blanketjs/*",
+
+  # "//third_party/blink/*",  # Errors: https://crbug.com/800764
   #"//third_party/breakpad/*",  # Small errors.
   "//third_party/boringssl/*",
+  "//third_party/bouncycastle/*",
   "//third_party/brotli/*",
-  "//third_party/fuchsia-sdk/*",
-  "//third_party/hunspell/*",
-  "//third_party/leveldatabase/*",
+  "//third_party/bspatch/*",
+  "//third_party/byte_buddy/*",
+  "//third_party/cacheinvalidation/*",
+  "//third_party/catapult/*",
+  "//third_party/cct_dynamic_module/*",
 
-  #"//third_party/libaddressinput/*",  # Small errors.
+  # "//third_party/ced/*",  # 6 errors
+  "//third_party/chaijs/*",
+  "//third_party/checkstyle/*",
+  "//third_party/chromevox/*",
+  "//third_party/chromite/*",
+  "//third_party/cld_2/*",
+  "//third_party/cld_3/*",
+  "//third_party/closure_compiler/*",
+  "//third_party/colorama/*",
+
+  # "//third_party/crashpad/*", 20ish errors
+  "//third_party/crc32c/*",
+  "//third_party/cros_system_api/*",
+  "//third_party/custom_tabs_client/*",
+  "//third_party/cython/*",
+  "//third_party/d3/*",
+  "//third_party/dawn/*",
+  "//third_party/decklink/*",
+  "//third_party/depot_tools/*",
+  "//third_party/deqp/*",
+  "//third_party/devscripts/*",
+  "//third_party/devtools-node-modules/*",
+  "//third_party/dom_distiller_js/*",
+  "//third_party/elfutils/*",
+  "//third_party/errorprone/*",
+  "//third_party/espresso/*",
+  "//third_party/eu-strip/*",
+  "//third_party/expat/*",
+  "//third_party/eyesfree/*",
+  "//third_party/feed/*",
+
+  # "//third_party/ffmpeg/*",  # android_cronet only https://crbug.com/898793
+  "//third_party/fips181/*",
+  "//third_party/flac/*",
+  "//third_party/flatbuffers/*",
+  "//third_party/flot/*",
+  "//third_party/fontconfig/*",
+  "//third_party/freetype/*",
+  "//third_party/freetype2/*",
+  "//third_party/freetype-android/*",
+  "//third_party/fuchsia-sdk/*",
+  "//third_party/gestures/*",
+  "//third_party/gif_player/*",
+  "//third_party/glfw/*",
+  "//third_party/glslang/*",
+  "//third_party/glslang-angle/*",
+  "//third_party/google_appengine_cloudstorage/*",
+  "//third_party/google_input_tools/*",
+  "//third_party/googletest/*",
+  "//third_party/google_toolbox_for_mac/*",
+  "//third_party/google-truth/*",
+  "//third_party/gradle_wrapper/*",
+  "//third_party/gson/*",
+  "//third_party/guava/*",
+  "//third_party/gvr-android-keyboard/*",
+  "//third_party/gvr-android-sdk/*",
+  "//third_party/hamcrest/*",
+  "//third_party/harfbuzz-ng/*",
+  "//third_party/hunspell/*",
+  "//third_party/hunspell/*",
+  "//third_party/hunspell_dictionaries/*",
+  "//third_party/iaccessible2/*",
+  "//third_party/iccjpeg/*",
+
+  # "//third_party/icu/*",  # Many errors
+  "//third_party/icu4j/*",
+  "//third_party/ijar/*",
+  "//third_party/ink/*",
+  "//third_party/inspector_protocol/*",
+  "//third_party/instrumented_libraries/*",
+  "//third_party/intellij/*",
+  "//third_party/isimpledom/*",
+  "//third_party/javax_inject/*",
+  "//third_party/jinja2/*",
+  "//third_party/jmake/*",
+  "//third_party/jsoncpp/*",
+  "//third_party/jsr-305/*",
+  "//third_party/jstemplate/*",
+  "//third_party/junit/*",
+  "//third_party/khronos/*",
+  "//third_party/lcov/*",
+  "//third_party/leakcanary/*",
+  "//third_party/leveldatabase/*",
+  "//third_party/libFuzzer/*",
+  "//third_party/libXNVCtrl/*",
+  "//third_party/libaddressinput/*",
+
+  # "//third_party/libaom/*",  # https://crbug.com/899771
+  "//third_party/libc++/*",
+  "//third_party/libc++abi/*",
+  "//third_party/libcxx-pretty-printers/*",
+  "//third_party/libdrm/*",
+  "//third_party/libevdev/*",
+  "//third_party/libexif/*",
+  "//third_party/libjingle/*",
+
+  # "//third_party/libjingle_xmpp/*",  # 30ish errors
+  "//third_party/libjpeg/*",
+
+  # "//third_party/libjpeg_turbo/*",  # 3 errors
+  # "//third_party/liblouis/*",  # Small errors
+  "//third_party/libovr/*",
   "//third_party/libphonenumber/*",
+  "//third_party/libpng/*",
+  "//third_party/libprotobuf-mutator/*",
+  "//third_party/libsecret/*",
+  "//third_party/libsrtp/*",
+  "//third_party/libsync/*",
+  "//third_party/libudev/*",
+  "//third_party/libusb/*",
+
+  # "//third_party/libvpx/*",  # Many errors
+  "//third_party/libvpx_new/*",
+  "//third_party/libwebm/*",
 
   #"//third_party/libwebp/*",  # Errors: https://crbug.com/800762
+  "//third_party/libxml/*",
+  "//third_party/libxslt/*",
+  "//third_party/libyuv/*",
+  "//third_party/llvm/*",
+  "//third_party/llvm-bootstrap/*",
+  "//third_party/llvm-bootstrap-install/*",
+  "//third_party/llvm-build-tools/*",
+  "//third_party/logilab/*",
+  "//third_party/lss/*",
+  "//third_party/lzma_sdk/*",
+  "//third_party/mach_override/*",
+  "//third_party/markdown/*",
+  "//third_party/markupsafe/*",
+  "//third_party/material_design_icons/*",
+  "//third_party/mesa/*",
+  "//third_party/mesa_headers/*",
+  "//third_party/metrics_proto/*",
+  "//third_party/minigbm/*",
+  "//third_party/minizip/*",
+  "//third_party/mocha/*",
+  "//third_party/mockito/*",
+  "//third_party/modp_b64/*",
+  "//third_party/motemplate/*",
+  "//third_party/mozilla/*",
+  "//third_party/mtpd/*",
+  "//third_party/netty4/*",
+  "//third_party/netty-tcnative/*",
+  "//third_party/node/*",
+  "//third_party/nvml/*",
+  "//third_party/objenesis/*",
+  "//third_party/ocmock/*",
+  "//third_party/openh264/*",
+
+  # "//third_party/openmax_dl/*",  # 1 error
+  "//third_party/openvr/*",
+  "//third_party/opus/*",
+  "//third_party/ots/*",
+  "//third_party/ow2_asm/*",
+
+  # "//third_party/pdfium/*",  # 3 errors
+  "//third_party/perfetto/*",
+  "//third_party/pexpect/*",
+  "//third_party/ply/*",
+  "//third_party/polymer/*",
+  "//third_party/proguard/*",
+  "//third_party/protobuf/*",
+  "//third_party/pycoverage/*",
+  "//third_party/pyelftools/*",
+  "//third_party/pyftpdlib/*",
+  "//third_party/pyjson5/*",
+  "//third_party/pylint/*",
+  "//third_party/pymock/*",
+  "//third_party/pystache/*",
+  "//third_party/py_trace_event/*",
+  "//third_party/pywebsocket/*",
+  "//third_party/qcms/*",
+  "//third_party/quic_trace/*",
+  "//third_party/qunit/*",
+  "//third_party/r8/*",
+  "//third_party/re2/*",
+  "//third_party/requests/*",
+  "//third_party/retrolambda/*",
+  "//third_party/rnnoise/*",
+  "//third_party/robolectric/*",
+  "//third_party/s2cellid/*",
+  "//third_party/safe_browsing/*",
+  "//third_party/scan-build/*",
+
+  # "//third_party/sfntly/*",  # 20ish errors
+  "//third_party/shaderc/*",
+  "//third_party/simplejson/*",
+  "//third_party/sinonjs/*",
+  "//third_party/skia/*",
+  "//third_party/smhasher/*",
   "//third_party/snappy/*",
+  "//third_party/speech-dispatcher/*",
+  "//third_party/spirv-cross/*",
+  "//third_party/spirv-headers/*",
+  "//third_party/spirv-tools-angle/*",
+  "//third_party/sqlite/*",
+  "//third_party/sqlite4java/*",
+  "//third_party/stp/*",
+  "//third_party/sudden_motion_sensor/*",
 
-  #"//third_party/WebKit/*",  # Errors: https://crbug.com/800764
-  #"//third_party/webrtc/*",  # Errors: https://crbug.com/824831
+  # "//third_party/swiftshader/*",  # 1 error
+  "//third_party/swig/*",
+  "//third_party/tcmalloc/*",
+  "//third_party/test_fonts/*",
+  "//third_party/tlslite/*",
+  "//third_party/ub-uiautomator/*",
+  "//third_party/unrar/*",
+  "//third_party/usb_ids/*",
+  "//third_party/usrsctp/*",
+  "//third_party/v4l-utils/*",
+  "//third_party/valgrind/*",
+  "//third_party/visualmetrics/*",
+  "//third_party/vulkan/*",
+  "//third_party/vulkan-validation-layers/*",
+
+  # "//third_party/wayland/*",  # Small errors
+  "//third_party/wayland-protocols/*",
+  "//third_party/wds/*",
+  "//third_party/web-animations-js/*",
+  "//third_party/webdriver/*",
+  "//third_party/webgl/*",
+  "//third_party/webpagereplay/*",
+  "//third_party/webrtc/*",
   "//third_party/webrtc_overrides/*",
-  "//tools/*",
+  "//third_party/widevine/*",
+  "//third_party/win_build_output/*",
+  "//third_party/woff2/*",
+  "//third_party/wtl/*",
+  "//third_party/xdg-utils/*",
+  "//third_party/xstream/*",
+  "//third_party/yara/*",
+  "//third_party/yasm/*",
+  "//third_party/zlib/*",
+  "//third_party/webrtc/*",
+  "//third_party/webrtc_overrides/*",
+  "//third_party/woff2/*",
 
+  "//tools/*",
   "//ui/*",
   "//url/*",
 
@@ -243,13 +616,6 @@
 # to force additional review for new uses of exec_script, which is strongly
 # discouraged.
 #
-# GYPI_TO_GN
-#
-# Some of these entries are for legacy gypi_to_gn calls. We should not be
-# adding new calls to this script in the build (see //build/gypi_to_gn.py for
-# detailed advice). The only time you should be editing this list for
-# gypi_to_gn purposes is when moving an existing call to a different place.
-#
 # PLEASE READ
 #
 # You should almost never need to add new exec_script calls. exec_script is
@@ -259,7 +625,7 @@
 # additions, we keep the build fast and clean. If you think you need to add a
 # new call, please consider:
 #
-# - Do not use a script to check for the existance of a file or directory to
+# - Do not use a script to check for the existence of a file or directory to
 #   enable a different mode. Instead, use GN build args to enable or disable
 #   functionality and set options. An example is checking for a file in the
 #   src-internal repo to see if the corresponding src-internal feature should
@@ -316,17 +682,12 @@
       "//clank/java/BUILD.gn",
       "//clank/native/BUILD.gn",
 
+      "//google_apis/BUILD.gn",
+      "//printing/BUILD.gn",
+
       "//remoting/host/installer/linux/BUILD.gn",
       "//remoting/remoting_version.gni",
       "//remoting/host/installer/win/generate_clsids.gni",
 
-      # TODO(dpranke): Get these from the appropriate repos instead.
-      "//third_party/catapult/tracing/BUILD.gn",
-      "//third_party/google_input_tools/inputview.gni",
-
       "//tools/grit/grit_rule.gni",
-
-      # Not gypi-to-gn.
-      "//google_apis/BUILD.gn",
-      "//printing/BUILD.gn",
     ]
diff --git a/.vpython b/.vpython
index 13dc189..b3bb6ad 100644
--- a/.vpython
+++ b/.vpython
@@ -175,3 +175,22 @@
   version: "version:4.1"
   match_tag: < platform: "macosx_10_10_intel" >
 >
+
+# Used by:
+#   third_party/catapult
+wheel: <
+  name: "infra/python/wheels/six-py2_py3"
+  version: "version:1.10.0"
+>
+wheel: <
+  name: "infra/python/wheels/pbr-py2_py3"
+  version: "version:3.0.0"
+>
+wheel: <
+  name: "infra/python/wheels/funcsigs-py2_py3"
+  version: "version:1.0.2"
+>
+wheel: <
+  name: "infra/python/wheels/mock-py2_py3"
+  version: "version:2.0.0"
+>
diff --git a/AUTHORS b/AUTHORS
index 3489adf..751d0a4 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -18,6 +18,7 @@
 Abhishek Kanike <abhishek.ka@samsung.com>
 Abhishek Singh <abhi.rathore@samsung.com>
 Adam Bonner <abonner-chromium@solscope.com>
+Adam Kallai <kadam@inf.u-szeged.hu>
 Adam Roben <adam@github.com>
 Adam Treat <adam.treat@samsung.com>
 Addanki Gandhi Kishor <kishor.ag@samsung.com>
@@ -115,6 +116,7 @@
 Bhagirathi Satpathy <bhagirathi.s@samsung.com>
 Bhanukrushana Rout <b.rout@samsung.com>
 Biljith Jayan <billy.jayan@samsung.com>
+Boaz Sender <boaz@bocoup.com>
 Bobby Powers <bobbypowers@gmail.com>
 Branden Archer <bma4@zips.uakron.edu>
 Brendan Kirby <brendan.kirby@imgtec.com>
@@ -218,6 +220,7 @@
 Dominik Röttsches <dominik.rottsches@intel.com>
 Don Woodward <woodward@adobe.com>
 Donghee Na <corona10@gmail.com>
+Dong-hee Na <donghee.na92@gmail.com>
 Dongie Agnir <dongie.agnir@gmail.com>
 Dongjun Kim <djmix.kim@samsung.com>
 Dongseong Hwang <dongseong.hwang@intel.com>
@@ -238,6 +241,7 @@
 Egor Starkov <egor.starkov@samsung.com>
 Ehsan Akhgari <ehsan.akhgari@gmail.com>
 Elan Ruusamäe <elan.ruusamae@gmail.com>
+Ergun Erdogmus <erdogmusergun@gmail.com>
 Eric Ahn <byungwook.ahn@gmail.com>
 Eric Rescorla <ekr@rtfm.com>
 Erik Hill <erikghill@gmail.com>
@@ -245,6 +249,8 @@
 Eriq Augustine <eriq.augustine@gmail.com>
 Ernesto Mudu <ernesto.mudu@gmail.com>
 Etienne Laurin <etienne@atnnn.com>
+Eugene Kim <eugene70kim@gmail.com>
+Eunseok Oh <fivesilverstone@gmail.com>
 Evan Peterson <evan.peterson.ep@gmail.com>
 Evan Wallace <evan.exe@gmail.com>
 Evangelos Foutras <evangelos@foutrelis.com>
@@ -293,6 +299,7 @@
 Gyuyoung Kim <gyuyoung.kim@navercorp.com>
 Gzob Qq <gzobqq@gmail.com>
 Habib Virji <habib.virji@samsung.com>
+Haeun Kim <ggrace.kim93@gmail.com>
 Haeun Kim <haeungun@gmail.com>
 Haitao Feng <haitao.feng@intel.com>
 Halley Zhao <halley.zhao@intel.com>
@@ -323,6 +330,7 @@
 Hwanseung Lee <hs1217.lee@gmail.com>
 Hwanseung Lee <hs1217.lee@samsung.com>
 Hyemi Shin <hyemi.sin@samsung.com>
+HyeockJin Kim <kherootz@gmail.com>
 Hyungchan Kim <inlinechan@gmail.com>
 Hyungwook Lee <hyungwook.lee@navercorp.com>
 Hyungwook Lee <withlhw@gmail.com>
@@ -348,6 +356,8 @@
 Jaekyeom Kim <btapiz@gmail.com>
 Jaemin Seo <jaemin86.seo@samsung.com>
 Jaeseok Yoon <yjaeseok@gmail.com>
+Jaewon Choi <jaewon.james.choi@gmail.com>
+Jaeyong Bae <jdragon.bae@gmail.com>
 Jaime Soriano Pastor <jsorianopastor@gmail.com>
 Jake Helfert <jake@helfert.us>
 Jake Hendy <me@jakehendy.com>
@@ -382,6 +392,7 @@
 Jesus Sanchez-Palencia <jesus.sanchez-palencia.fernandez.fil@intel.com>
 Jiadong Zhu <jiadong.zhu@linaro.org>
 Jiajia Qin <jiajia.qin@intel.com>
+Jiajie Hu <jiajie.hu@intel.com>
 Jianjun Zhu <jianjun.zhu@intel.com>
 Jianneng Zhong <muzuiget@gmail.com>
 Jiawei Shao <jiawei.shao@intel.com>
@@ -412,6 +423,7 @@
 Jonathan Garbee <jonathan@garbee.me>
 Jonathan Hacker <jhacker@arcanefour.com>
 Jongdeok Kim <jongdeok.kim@navercorp.com>
+Jongheon Kim <sapzape@gmail.com>
 JongKwon Lee <jongkwon.lee@navercorp.com>
 Jongsoo Lee <leejongsoo@gmail.com>
 Joone Hur <joone.hur@intel.com>
@@ -432,6 +444,8 @@
 Jun Fang <jun_fang@foxitsoftware.com>
 Jun Jiang <jun.a.jiang@intel.com>
 Junchao Han <junchao.han@intel.com>
+Junghoon Lee <sjh836@gmail.com>
+Junghyuk Yoo <wjdgurdl272@gmail.com>
 JungJik Lee <jungjik.lee@samsung.com>
 Jungkee Song <jungkee.song@samsung.com>
 Junmin Zhu <junmin.zhu@intel.com>
@@ -454,6 +468,7 @@
 Kaustubh Atrawalkar <kaustubh.ra@gmail.com>
 Ke He <ke.he@intel.com>
 Keene Pan <keenepan@linpus.com>
+Keita Yoshimoto <y073k3@gmail.com>
 Keith Chen <keitchen@amazon.com>
 Kenneth Rohde Christiansen <kenneth.r.christiansen@intel.com>
 Kenneth Strickland <ken.strickland@gmail.com>
@@ -509,6 +524,7 @@
 Loo Rong Jie <loorongjie@gmail.com>
 Lorenzo Stoakes <lstoakes@gmail.com>
 Lu Guanqun <guanqun.lu@gmail.com>
+Luca Di Domenico <luca94dd@gmail.com>
 Lucie Brozkova <lucinka.brozkova@gmail.com>
 Luiz Von Dentz <luiz.von.dentz@intel.com>
 Luka Dojcilovic <l.dojcilovic@gmail.com>
@@ -586,13 +602,14 @@
 Miran Karic <miran.karic@imgtec.com>
 Mirela Budaes <mbudaes@adobe.com>
 Mirela Budaes <mbudaes@gmail.com>
-Miyoung Shin <myid.shin@samsung.com>
+Miyoung Shin <myid.shin@navercorp.com>
 Mohamed I. Hammad <ibraaaa@gmail.com>
 Mohamed Mansour <m0.interactive@gmail.com>
 Mohammad Azam <m.azam@samsung.com>
 Mohammed Wajahat Ali Siddiqui <wajahat.s@samsung.com>
 Mohan Reddy <mohan.reddy@samsung.com>
 Mohit Bhalla <bhallam@amazon.com>
+Momoko Hattori <momohatt10@gmail.com>
 Mrunal Kapade <mrunal.kapade@intel.com>
 Myeongjin Cho <myeongjin.cho@navercorp.com>
 Myles C. Maxfield <mymax@amazon.com>
@@ -693,6 +710,7 @@
 Ravi Nanjundappa <nravi.n@samsung.com>
 Ravi Phaneendra Kasibhatla <r.kasibhatla@samsung.com>
 Ravi Phaneendra Kasibhatla <ravi.kasibhatla@motorola.com>
+Raviraj Sitaram <raviraj.p.sitaram@intel.com>
 Réda Housni Alaoui <alaoui.rda@gmail.com>
 Refael Ackermann <refack@gmail.com>
 Renata Hodovan <rhodovan.u-szeged@partner.samsung.com>
@@ -733,6 +751,8 @@
 Sanghyun Park <sh919.park@samsung.com>
 Sanghyup Lee <sh53.lee@samsung.com>
 Sangjoon Je <htamop@gmail.com>
+Sangseok Jang <sangseok.jang@navercorp.com>
+Sangwoo Ko <sangwoo.ko@navercorp.com>
 Sangwoo Ko <sangwoo108@gmail.com>
 Sanjoy Pal <ncj674@motorola.com>
 Sanjoy Pal <sanjoy.pal@samsung.com>
@@ -750,6 +770,7 @@
 Sean Bryant <sean@cyberwang.net>
 Sean DuBois <seaduboi@amazon.com>
 Sebastian Amend <sebastian.amend@googlemail.com>
+Sebastian Krzyszkowiak <dos@dosowisko.net>
 Seo Sanghyeon <sanxiyn@gmail.com>
 Seokju Kwon <seokju.kwon@gmail.com>
 SeongTae Jeong <ferendevelop.gl@gmail.com>
@@ -759,6 +780,7 @@
 Sergio Carlos Morales Angeles <carloschilazo@gmail.com>
 Sergiy Byelozyorov <rryk.ua@gmail.com>
 Seshadri Mahalingam <seshadri.mahalingam@gmail.com>
+Seungkyu Lee <zx6658@gmail.com>
 Sevan Janiyan <venture37@geeklan.co.uk>
 Shahriar Rostami <shahriar.rostami@gmail.com>
 Shail Singhal <shail.s@samsung.com>
@@ -792,6 +814,7 @@
 Sohan Jyoti Ghosh <sohan.jyoti@samsung.com>
 Song YeWen <ffmpeg@gmail.com>
 Sooho Park <sooho1000@gmail.com>
+Soojung Choi <crystal2840@gmail.com>
 Soorya R <soorya.r@samsung.com>
 Soren Dreijer <dreijerbit@gmail.com>
 Srirama Chandra Sekhar Mogali <srirama.m@samsung.com>
@@ -843,8 +866,10 @@
 Timo Gurr <timo.gurr@gmail.com>
 Timo Reimann <ttr314@googlemail.com>
 Timo Witte <timo.witte@gmail.com>
+Ting Shao <ting.shao@intel.com>
 Tom Callaway <tcallawa@redhat.com>
 Tom Harwood <tfh@skip.org>
+Tom Tan <Tom.Tan@microsoft.com>
 Tomas Popela <tomas.popela@gmail.com>
 Torsten Kurbad <google@tk-webart.de>
 Trent Willis <trentmwillis@gmail.com>
@@ -869,6 +894,7 @@
 Vipul Bhasin <vipul.bhasin@gmail.com>
 Visa Putkinen <v.putkinen@partner.samsung.com>
 Vishal Bhatnagar <vishal.b@samsung.com>
+Vitaliy Kharin <kvserr@gmail.com>
 Vivek Galatage <vivek.vg@samsung.com>
 Volker Sorge <volker.sorge@gmail.com>
 Waihung Fu <fufranci@amazon.com>
@@ -903,6 +929,7 @@
 Yash Vempati <vempatiy@amazon.com>
 Ye Liu <cbakgly@gmail.com>
 Yeol Park <peary2@gmail.com>
+Yeonwoo Jo <yeonwoo.jo.92@gmail.com>
 Yi Shen <yi.shen@samsung.com>
 Yi Sun <ratsunny@gmail.com>
 Yichen Jiang <jiangyichen123@gmail.com>
@@ -947,11 +974,14 @@
 Rajesh Mahindra <rmahindra@uber.com>
 Yuan-Pin Yu <yjames@uber.com>
 Vinoth Chandar <vinoth@uber.com>
+Zheng Xu <zxu@kobo.com>
+Gaurav Dhol <gaurav.dhol@einfochips.com>

 
 ACCESS CO., LTD. <*@access-company.com>
 Akamai Inc. <*@akamai.com>
 ARM Holdings <*@arm.com>
 BlackBerry Limited <*@blackberry.com>
+Bocoup <*@bocoup.com>
 Canonical Limited <*@canonical.com>
 Cloudflare, Inc. <*@cloudflare.com>
 Code Aurora Forum <*@codeaurora.org>
@@ -978,6 +1008,8 @@
 NVIDIA Corporation <*@nvidia.com>
 Opera Software ASA <*@opera.com>
 Optical Tone Ltd <*@opticaltone.com>
+Rakuten Kobo Inc. <*@kobo.com>
+Rakuten Kobo Inc. <*@rakuten.com>
 Seznam.cz, a.s. <*@firma.seznam.cz>
 Spotify AB <*@spotify.com>
 Tableau Software <*@tableau.com>
diff --git a/BUILD.gn b/BUILD.gn
index 2543a3a..6c85e57 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -25,6 +25,7 @@
 import("//ui/ozone/ozone.gni")
 import("//v8/gni/v8.gni")
 import("//v8/snapshot_toolchain.gni")
+import("//gpu/vulkan/features.gni")
 
 if (is_android) {
   import("//build/config/android/config.gni")
@@ -103,7 +104,6 @@
       "//chrome/test:sync_integration_tests",
       "//chrome/test/chromedriver:chromedriver_unittests",
       "//components/subresource_filter/tools:subresource_filter_tools",
-      "//components/sync/tools:sync_client",
       "//components/sync/tools:sync_listen_notifications",
       "//components/zucchini:zucchini",
       "//components/zucchini:zucchini_unittests",
@@ -138,17 +138,16 @@
       "//ppapi/examples/url_loader",
       "//ppapi/examples/video_capture",
       "//ppapi/examples/video_decode",
-      "//ppapi/examples/video_effects",
       "//ppapi/examples/video_encode",
       "//printing:printing_unittests",
       "//third_party/SPIRV-Tools/src:SPIRV-Tools",
       "//third_party/SPIRV-Tools/src/test/fuzzers",
       "//third_party/cacheinvalidation:cacheinvalidation_unittests",
+      "//third_party/dawn:dawn_end2end_tests",
+      "//third_party/dawn:dawn_unittests",
       "//third_party/pdfium/samples:pdfium_test",
       "//third_party/webrtc/rtc_tools:frame_analyzer",
       "//tools/perf/clear_system_cache",
-      "//tools/traffic_annotation/auditor:traffic_annotation_auditor",
-      "//tools/traffic_annotation/auditor:traffic_annotation_auditor_unittests",
       "//ui/accessibility:accessibility_unittests",
       "//ui/accessibility/extensions",
     ]
@@ -216,7 +215,10 @@
   } else if (is_ios) {
     deps += [ "//ios:all" ]
   } else if (is_fuchsia) {
-    deps += [ ":d8_fuchsia" ]
+    deps += [
+      ":d8_fuchsia",
+      "build/fuchsia/fidlgen_js:fidlgen_js_unittests",
+    ]
   }
 
   deps += root_extra_deps
@@ -266,6 +268,20 @@
     deps += [ "//tools/xdisplaycheck" ]
   }
 
+  if (is_win) {
+    deps += [
+      "//chrome/credential_provider",
+      "//chrome/credential_provider/test:gcp_unittests",
+    ]
+  }
+
+  if (is_win || is_linux) {
+    deps += [
+      "//tools/traffic_annotation/auditor:traffic_annotation_auditor",
+      "//tools/traffic_annotation/auditor:traffic_annotation_auditor_unittests",
+    ]
+  }
+
   if (is_mac) {
     deps += [ "//chrome/installer/gcapi_mac:gcapi_example" ]
   }
@@ -326,6 +342,7 @@
         "//android_webview/test",
         "//android_webview/tools/automated_ui_tests:webview_ui_test_app",
         "//android_webview/tools/system_webview_shell",
+        "//android_webview/tools/webview_log_verbosifier:webview_log_verbosifier_apk",
         "//chrome/android:chrome_junit_tests",
         "//chrome/android:chrome_public_apk",
         "//chrome/android:chrome_public_test_apk",
@@ -371,6 +388,7 @@
       "//ash:ash_unittests",
       "//ash/app_list:app_list_demo",
       "//ash/app_list:app_list_unittests",
+      "//chrome/browser/resources/chromeos/zip_archiver/cpp:ziparchiver_unittests",
       "//chromeos:chromeos_unittests",
       "//chromeos/components:chromeos_components_unittests",
       "//chromeos/components/proximity_auth:proximity_auth_unittests",
@@ -421,7 +439,7 @@
     ]
   }
 
-  if ((is_win || is_mac || is_linux || is_chromeos) &&
+  if ((is_win || is_mac || is_linux || is_chromeos || is_fuchsia) &&
       (target_cpu == "x86" || target_cpu == "x64")) {
     deps += [ "//third_party/swiftshader" ]
   }
@@ -544,10 +562,8 @@
 
   if (is_mac) {
     deps += [
-      "//third_party/apple_sample_code",
       "//third_party/breakpad:crash_inspector",
       "//third_party/breakpad:dump_syms",
-      "//third_party/molokocacao",
     ]
     deps -= [
       # Mojo in GN contains some things which are never compiled in GYP on Mac,
@@ -670,8 +686,6 @@
       "//third_party/opus:test_opus_decode",
       "//third_party/opus:test_opus_encode",
       "//third_party/opus:test_opus_padding",
-      "//third_party/webrtc/system_wrappers:field_trial_default",
-      "//third_party/webrtc/system_wrappers:metrics_default",
       "//ui/display/types",
       "//ui/shell_dialogs:shell_dialogs_unittests",
     ]
@@ -694,8 +708,8 @@
     }
   }
 
-  if ((is_linux && !is_chromeos && !is_chromecast) || (is_win && use_drfuzz) ||
-      (use_libfuzzer && is_mac)) {
+  if ((is_linux && !is_chromeos && !is_chromecast) ||
+      (is_win && (use_drfuzz || use_libfuzzer)) || (use_libfuzzer && is_mac)) {
     deps += [
       "//testing/libfuzzer/fuzzers",
       "//testing/libfuzzer/tests:libfuzzer_tests",
@@ -726,7 +740,10 @@
       deps += [ "//chrome/browser/vr/testapp:vr_testapp" ]
     }
     if (is_android) {
-      deps += [ "//tools/perf/contrib/vr_benchmarks:vr_perf_tests" ]
+      deps += [
+        "//chrome/browser/android/vr:vr_android_unittests",
+        "//tools/perf/contrib/vr_benchmarks:vr_perf_tests",
+      ]
     }
   }
 
@@ -736,7 +753,21 @@
       "//headless:headless_shell",
       "//headless:headless_tests",
       "//webrunner",
+      "//webrunner:archive_sources",
       "//webrunner:webrunner_unittests",
+      "//webrunner/net_http:http_pkg",
+      "//webrunner/net_http:http_service_tests",
+    ]
+  }
+
+  if (enable_vulkan) {
+    deps += [ "//gpu/vulkan/demo" ]
+  }
+
+  if (use_atk) {
+    deps += [
+      "//tools/accessibility/inspect:ax_dump_events",
+      "//tools/accessibility/inspect:ax_dump_tree",
     ]
   }
 }
@@ -745,11 +776,13 @@
   # TODO(https://crbug.com/731217): This can't practically be in //v8 without
   # duplicating all the Fuchsia running infrastructure there.
   fuchsia_package("d8_fuchsia_pkg") {
+    testonly = true
     binary = "//v8:d8"
     package_name_override = "d8"
   }
 
   fuchsia_package_runner("d8_fuchsia") {
+    testonly = true
     package = ":d8_fuchsia_pkg"
     package_name_override = "d8"
   }
@@ -814,6 +847,7 @@
       "//chrome",
       "//chrome/test/chromedriver",
       "//media:media_unittests",
+      "//media/gpu:jpeg_decode_accelerator_unittest",
       "//ppapi/examples/video_decode",
       "//sandbox/linux:chrome_sandbox",
       "//sandbox/linux:sandbox_linux_unittests",
@@ -830,6 +864,9 @@
         "//media/gpu:video_encode_accelerator_unittest",
       ]
     }
+    if (use_vaapi) {
+      deps += [ "//media/gpu:jpeg_encode_accelerator_unittest" ]
+    }
   }
 }
 
@@ -892,6 +929,7 @@
     testonly = true
     data_deps = [
       ":layout_test_data_mojo_bindings",
+      ":layout_test_data_mojo_bindings_lite",
       "//content/shell:content_shell",
       "//content/test:mojo_layouttest_bindings_js_data_deps",
       "//device/bluetooth/public/mojom:fake_bluetooth_interfaces_js_data_deps",
@@ -906,7 +944,7 @@
       "//skia/public/interfaces:interfaces_js_data_deps",
       "//third_party/blink/public:blink_devtools_frontend_resources_files",
       "//third_party/blink/public:mojo_bindings_js_data_deps",
-      "//third_party/mesa:osmesa",
+      "//third_party/mesa_headers",
       "//tools/imagediff",
     ]
 
@@ -984,6 +1022,22 @@
     ]
   }
 
+  copy("layout_test_data_mojo_bindings_lite") {
+    testonly = true
+
+    sources = [
+      "$root_gen_dir/mojo/public/js/mojo_bindings_lite.js",
+    ]
+
+    outputs = [
+      "$root_gen_dir/layout_test_data/mojo/public/js/mojo_bindings_lite.js",
+    ]
+
+    deps = [
+      "//mojo/public/js:bindings_lite",
+    ]
+  }
+
   group("webkit_python_tests") {
     data = [
       "//build/android/",
@@ -1141,6 +1195,7 @@
 
 if (closure_compile) {
   group("webui_closure_compile") {
+    testonly = true
     data_deps = [
       "chrome/browser/resources:closure_compile",
       "content/browser/resources:closure_compile",
@@ -1152,9 +1207,6 @@
     if (is_android) {
       data_deps += [ "components/offline_pages/resources:closure_compile" ]
     }
-    if (is_win && is_chrome_branded) {
-      data_deps += [ "components/nux_google_apps/resources:closure_compile" ]
-    }
   }
 }
 
diff --git a/DEPS b/DEPS
index 195db254..48aed19 100644
--- a/DEPS
+++ b/DEPS
@@ -49,6 +49,11 @@
   # purposes.
   'checkout_configuration': 'default',
 
+  # By default, don't check out android. Will be overridden by gclient
+  # variables.
+  # TODO(ehmaldonado): Remove this once the bug in gclient is fixed.
+  'checkout_android': False,
+
   # Pull in Android native toolchain dependencies for Chrome OS too, so we can
   # build ARC++ support libraries.
   'checkout_android_native_support': 'checkout_android or checkout_chromeos',
@@ -70,7 +75,12 @@
   # privately accessible.
   'checkout_telemetry_dependencies': False,
 
-  # libaom provides support for AV1 but the bitstream is not frozen.
+  # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to
+  # process the raw profiles produced by instrumented targets (built with
+  # the gn arg 'use_clang_coverage').
+  'checkout_clang_coverage_tools': False,
+
+  # libaom provides support for AV1.
   'checkout_libaom': True,
 
   # By default do not check out the Oculus SDK. Only available for Googlers.
@@ -92,11 +102,12 @@
 
   'android_git': 'https://android.googlesource.com',
   'aomedia_git': 'https://aomedia.googlesource.com',
-  'chromium_git': 'https://chromium.googlesource.com',
-  'swiftshader_git': 'https://swiftshader.googlesource.com',
-  'pdfium_git': 'https://pdfium.googlesource.com',
   'boringssl_git': 'https://boringssl.googlesource.com',
+  'chromium_git': 'https://chromium.googlesource.com',
+  'dawn_git': 'https://dawn.googlesource.com',
+  'pdfium_git': 'https://pdfium.googlesource.com',
   'skia_git': 'https://skia.googlesource.com',
+  'swiftshader_git': 'https://swiftshader.googlesource.com',
   'webrtc_git': 'https://webrtc.googlesource.com',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling sfntly
@@ -105,31 +116,31 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'bc6f9c9a8c6b83bc91496c28d85541855747a5da',
+  'skia_revision': '763fc966993d712445994e53104c5be42976883b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '4fe3de13fc5c2592559bb5e49e1a81a6d09a2efd',
+  'v8_revision': '0ccf17e9a990361055b824b75cde457bf5e490f0',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
-  'swarming_revision': '486c9b53c4d54dd4b95bb6ce0e31160e600dfc11',
+  'swarming_revision': 'f78187ab77127de42555afe0ad410bebde6ac6a5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '9b6a3f92603260e8b324fa3e0e2936f4bf5ae414',
+  'angle_revision': '2197dc5290522549f5c9421b48d4eb547f4068e2',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
-  'buildtools_revision': '9a90d9aaadeb5e04327ed05775f45132e4b3523f',
+  'buildtools_revision': '13a00f110ef910a25763346d6538b60f12845656',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '9e22c542d6be9bdc4066a224264b9d3a1fb73018',
+  'swiftshader_revision': '847fc0b278f8454f8e04c89163bf840aa903df99',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '4174b5ab6ac9024acb9b42acbb61d628a2a679e3',
+  'pdfium_revision': 'f2f7c2a92321a1287798e1b7e708dd3a11243719',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -137,7 +148,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
-  'boringssl_revision': '6410e18e9190b6b0c71955119fbf3cae1b9eedb7',
+  'boringssl_revision': 'dd412c428ad7c2a60ae4709dfbad6301e499dcb8',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -153,23 +164,23 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling NaCl
   # and whatever else without interference from each other.
-  'nacl_revision': '96088f46727b75b2f6a24e1b62e5cc59ddb4612d',
+  'nacl_revision': '99673869a3cd8731d924bd32fa486feebfdc6c4f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_revision': '578bcf103a12fb742cdb314565819011d1ac12a7',
+  'freetype_revision': 'f56830ed406f90f6f53ee6367f2068a0f27bf90b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling HarfBuzz
   # and whatever else without interference from each other.
-  'harfbuzz_revision': '2b76767bf572364d3d647cdd139f2044a7ad06b2',
+  'harfbuzz_revision': '1f14107f71a6c3da8270ed21c3588f945fa91733',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '0d25dda9b148bcd2dad9e1080b1dc57eaf9d2c2a',
+  'catapult_revision': 'c39d9737dc284e8e6eac39ddfa5db5c453760598',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
-  'libfuzzer_revision': '658ff786a213703ff0df6ba4a288e9a1e218c074',
+  'libfuzzer_revision': 'a305a5eb85ed42edc5c965c14f308f576cb245ca',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-node-modules
   # and whatever else without interference from each other.
@@ -177,11 +188,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
-  'libprotobuf-mutator': '3fc43a01d721ef1bacfefed170bc22abf1b8b051',
+  'libprotobuf-mutator': 'c148984c5af61e628252ebdc5f141fe89d83106c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'feed_revision': '180fca04760493784b3183a2220fce639e96f1a5',
+  'feed_revision': '8acb73aa3e5f28938b54d35c1a6d40e02399d799',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling android_sdk_build-tools_version
   # and whatever else without interference from each other.
@@ -213,11 +224,23 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'spv_tools_revision': '714bf84e58abd9573488fc365707fb8f288ca73c',
+  'spv_tools_revision': 'fb996dce752507132c40c255898154cce6c072c5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'spv_headers_revision': 'ff684ffc6a35d2a58f0f63108877d0064ea33feb',
+  'spv_headers_revision': 'a2c529b5dda18838ab4b52f816acfebd774eaab3',
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling feed
+  # and whatever else without interference from each other.
+  'spirv_cross_revision': '69b034f26e28a76a6f4e5d9521123072b24d7ea2',
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling feed
+  # and whatever else without interference from each other.
+  'shaderc_revision': '909f0d3d31e7e7c8f39b40ba0e1dd7f99b749776',
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling feed
+  # and whatever else without interference from each other.
+  'dawn_revision': '61791eae36b8155219f6217b64b28eb4f54e3396',
 }
 
 # Only these hosts are allowed for dependencies in this DEPS file.
@@ -229,6 +252,7 @@
   'chrome-infra-packages.appspot.com',
   'chrome-internal.googlesource.com',
   'chromium.googlesource.com',
+  'dawn.googlesource.com',
   'pdfium.googlesource.com',
   'skia.googlesource.com',
   'swiftshader.googlesource.com',
@@ -239,6 +263,17 @@
   'src/chrome/browser/resources/media_router/extension/src':
     Var('chromium_git') + '/media_router.git' + '@' + '475baa8b2eb0a7a9dd1c96c9c7a6a8d9035cc8d7',
 
+  'src/android_webview/tools/cts_archive': {
+      'packages': [
+          {
+              'package': 'chromium/android_webview/tools/cts_archive',
+              'version': 'version:1.0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
   'src/buildtools':
     Var('chromium_git') + '/chromium/buildtools.git' + '@' +  Var('buildtools_revision'),
 
@@ -253,6 +288,17 @@
   'src/chrome/test/data/perf/frame_rate/content':
     Var('chromium_git') + '/chromium/frame_rate/content.git' + '@' + 'c10272c88463efeef6bb19c9ec07c42bc8fe22b9',
 
+  'src/chrome/test/data/safe_browsing/dmg': {
+    'packages': [
+      {
+        'package': 'chromium/chrome/test/data/safe_browsing/dmg',
+        'version': 'version:20180816.2',
+      },
+    ],
+    'condition': 'checkout_mac',
+    'dep_type': 'cipd',
+  },
+
   'src/chrome/test/data/xr/webvr_info':
     Var('chromium_git') + '/external/github.com/toji/webvr.info.git' + '@' + 'c58ae99b9ff9e2aa4c524633519570bf33536248',
 
@@ -260,7 +306,22 @@
     Var('chromium_git') + '/external/github.com/immersive-web/webxr-samples.git' + '@' + 'cf02f19c4ff6894705a9407722ab52551e010c60',
 
   'src/ios/third_party/earl_grey/src': {
-      'url': Var('chromium_git') + '/external/github.com/google/EarlGrey.git' + '@' + '451b6497352d0731e9827a338f32024e564078c6',
+      'url': Var('chromium_git') + '/external/github.com/google/EarlGrey.git' + '@' + '3102ef3b137f05a179628b1b9768856e5feea90e',
+      'condition': 'checkout_ios',
+  },
+
+  'src/ios/third_party/earl_grey2/src': {
+      'url': Var('chromium_git') + '/external/github.com/google/EarlGrey.git' + '@' + 'f9ae5c477b3b1f8e38559867ca21dfb034c21d92',
+      'condition': 'checkout_ios',
+  },
+
+    'src/ios/third_party/edo/src': {
+      'url': Var('chromium_git') + '/external/github.com/google/eDistantObject.git' + '@' + '4ec31ccbe1e03279619915b00ddf30af5422106e',
+      'condition': 'checkout_ios',
+  },
+
+  'src/ios/third_party/gtx/src': {
+      'url': Var('chromium_git') + '/external/github.com/google/GTXiLib.git' + '@' + '3e09baa61b2c13fe98029d53b1783f4ca9edaabf',
       'condition': 'checkout_ios',
   },
 
@@ -268,7 +329,7 @@
       'packages': [
         {
           'package': 'chromium/third_party/firebase_ios',
-          'version': 'version:5.0.1',
+          'version': 'version:5.8.0',
         },
       ],
       'condition': 'checkout_ios',
@@ -286,7 +347,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '3a50c7a3b2f4ec760d2d2405b6b9787e5493c049',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'a367adfe25465864acf7ab7396216a9e4c1cf00b',
       'condition': 'checkout_ios',
   },
 
@@ -296,7 +357,7 @@
   },
 
   'src/ios/third_party/material_internationalization_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-foundation/material-internationalization-ios.git' + '@' + '8f28a55c7f35b95a587bba01a8467ea470647873',
+      'url': Var('chromium_git') + '/external/github.com/material-foundation/material-internationalization-ios.git' + '@' + 'c62f2cacaba48f8901ad811f23c2cbc9581364aa',
       'condition': 'checkout_ios',
   },
 
@@ -306,7 +367,7 @@
   },
 
   'src/ios/third_party/material_sprited_animation_view_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-foundation/material-sprited-animation-view-ios.git' + '@' + 'c6e16d06bdafd95540c62b3402d9414692fbca81',
+      'url': Var('chromium_git') + '/external/github.com/material-foundation/material-sprited-animation-view-ios.git' + '@' + '8af9adaa182044cf2920dfb620b863669e1aeb7c',
       'condition': 'checkout_ios',
   },
 
@@ -336,7 +397,7 @@
   },
 
   'src/media/cdm/api':
-    Var('chromium_git') + '/chromium/cdm.git' + '@' + '50431fd832bbf389ee839e3f8cb68e82606f0513',
+    Var('chromium_git') + '/chromium/cdm.git' + '@' + '817c8005a57ea3ca417f767b3b3679601329afd8',
 
   'src/native_client': {
       'url': Var('chromium_git') + '/native_client/src/native_client.git' + '@' + Var('nacl_revision'),
@@ -349,10 +410,26 @@
           'package': 'infra/tools/luci/isolate/${{platform}}',
           'version': 'git_revision:bc125484b8513898f17bc2501ac5e95330f44a3b',
         },
+        {
+          'package': 'infra/tools/luci/isolated/${{platform}}',
+          'version': 'git_revision:bc125484b8513898f17bc2501ac5e95330f44a3b',
+        },
+        {
+          'package': 'infra/tools/luci/swarming/${{platform}}',
+          'version': 'git_revision:bc125484b8513898f17bc2501ac5e95330f44a3b',
+        },
       ],
       'dep_type': 'cipd',
   },
 
+  # SPIRV-Cross is in third_party/spirv-cross/spirv-cross instead of
+  # third_party/spirv-cross/src  because its header files are at the root of
+  # the repository and dependencies include them like so:
+  #   #include "spirv-cross/spirv_glsl.hpp"
+  'src/third_party/spirv-cross/spirv-cross':
+    Var('chromium_git') + '/external/github.com/KhronosGroup/SPIRV-Cross.git@' +
+        Var('spirv_cross_revision'),
+
   'src/third_party/spirv-headers/src':
     Var('chromium_git') + '/external/github.com/KhronosGroup/SPIRV-Headers.git@' +
         Var('spv_headers_revision'),
@@ -361,6 +438,10 @@
     Var('chromium_git') + '/external/github.com/KhronosGroup/SPIRV-Tools.git@' +
         Var('spv_tools_revision'),
 
+  'src/third_party/shaderc/src':
+    Var('chromium_git') + '/external/github.com/google/shaderc.git@' +
+        Var('shaderc_revision'),
+
   'src/third_party/accessibility_test_framework': {
       'packages': [
           {
@@ -378,7 +459,7 @@
   },
 
   'src/third_party/android_ndk': {
-      'url': Var('chromium_git') + '/android_ndk.git' + '@' + '5cd86312e794bdf542a3685c6f10cbb96072990b',
+      'url': Var('chromium_git') + '/android_ndk.git' + '@' + '4e2cea441bfd43f0863d14f57b1e1844260b9884',
       'condition': 'checkout_android_native_support',
   },
 
@@ -412,8 +493,19 @@
   'src/third_party/android_build_tools/aapt2': {
       'packages': [
           {
-              'package': 'chromium/third_party/android_tools_aapt2',
-              'version': 'version:3.2.0-alpha18-4804415-cr0',
+              'package': 'chromium/third_party/android_build_tools/aapt2',
+              'version': 'version:3.3.0-beta01-5013011-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_build_tools/art': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_build_tools/art',
+              'version': '87169fbc701d244c311e6aa8843591a7f1710bc0',
           },
       ],
       'condition': 'checkout_android',
@@ -424,7 +516,7 @@
       'packages': [
           {
        'package': 'chromium/third_party/android_tools_bundletool',
-       'version': 'version:0.5.0-cr0',
+       'version': 'version:0.6.0-cr0',
    },
       ],
       'condition': 'checkout_android',
@@ -476,6 +568,12 @@
   'src/third_party/angle':
     Var('chromium_git') + '/angle/angle.git' + '@' +  Var('angle_revision'),
 
+  'src/third_party/dawn':
+    Var('dawn_git') + '/dawn.git' + '@' +  Var('dawn_revision'),
+
+  'src/third_party/glfw/src':
+    Var('chromium_git') + '/external/github.com/glfw/glfw.git@' +  '096efdf798896cff80a0b2db08d7398b703406fe',
+
   'src/third_party/apache-portable-runtime/src': {
       'url': Var('chromium_git') + '/external/apache-portable-runtime.git' + '@' + 'c3f11fcd86b42922834cae91103cf068246c6bb6',
       'condition': 'checkout_android',
@@ -531,7 +629,7 @@
   },
 
   'src/third_party/breakpad/breakpad':
-    Var('chromium_git') + '/breakpad/breakpad.git' + '@' + '79ba6a494fb2097b39f76fe6a4b4b4f407e32a02',
+    Var('chromium_git') + '/breakpad/breakpad.git' + '@' + '54fa71efbe50fb2b58096d871575b59e12edba6d',
 
   'src/third_party/byte_buddy': {
       'packages': [
@@ -547,12 +645,17 @@
   'src/third_party/catapult':
     Var('chromium_git') + '/catapult.git' + '@' + Var('catapult_revision'),
 
+  'src/third_party/cct_dynamic_module/src': {
+      'url': Var('chromium_git') + '/dynamicmodule' + '@' + 'b89f5147c1fdf1d02850932ecd1ff16b8c0be545',
+      'condition': 'checkout_android',
+  },
+
   'src/third_party/ced/src':
     Var('chromium_git') + '/external/github.com/google/compact_enc_det.git' + '@' + '94c367a1fe3a13207f4b22604fcfd1d9f9ddf6d9',
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'aba1649cfb985a84ecb02a82ece69c6f4a76fb2a',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '6386fdec9f499e98c799a4aa30609e22541c867a',
       'condition': 'checkout_linux',
   },
 
@@ -567,23 +670,23 @@
 
   # For Linux and Chromium OS.
   'src/third_party/cros_system_api': {
-      'url': Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + 'a2a458bd5d690a1b7bba24d73650b19f3b9549d1',
+      'url': Var('chromium_git') + '/chromiumos/platform2/system_api.git' + '@' + '46e2b4be31c717db64047079cce5c52cbda197ff',
       'condition': 'checkout_linux',
   },
 
   'src/third_party/custom_tabs_client/src': {
-      'url': Var('chromium_git') + '/custom-tabs-client.git' + '@' + '81a14bc0885944a65afa81acd00da16cecb74b8b',
+      'url': Var('chromium_git') + '/custom-tabs-client.git' + '@' + 'c813ed8fcc4ece1838dba8dddf6d8ca39d6c6785',
       'condition': 'checkout_android',
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '284b5e0c60ac489df16a7926207c5d255d2ca6d6',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '24bca4e741a98a0f6ed9bdeb64c07816243d2873',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
 
   'src/third_party/dom_distiller_js/dist':
-    Var('chromium_git') + '/chromium/dom-distiller/dist.git' + '@' + '60b46718e28f553ab57e3d2bbda5b3b41456f417',
+    Var('chromium_git') + '/chromium/dom-distiller/dist.git' + '@' + '3093c3e238768ab27ff756bd7563ccbb12129d9f',
 
   'src/third_party/elfutils/src': {
       'url': Var('chromium_git') + '/external/elfutils.git' + '@' + '249673729a7e5dbd5de4f3760bdcaa3d23d154d7',
@@ -612,17 +715,17 @@
   },
 
   'src/third_party/ffmpeg':
-    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'de23348fef6fd063b066e9652005973f86ed52ff',
+    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '458e9fd3f8e8c913a739389c65dfaf1f77ee9106',
 
   'src/third_party/flac':
     Var('chromium_git') + '/chromium/deps/flac.git' + '@' + 'af862024c8c8fa0ae07ced05e89013d881b00596',
 
   'src/third_party/flatbuffers/src':
-    Var('chromium_git') + '/external/github.com/google/flatbuffers.git' + '@' + '01c50d57a67a52ee3cddd81b54d4647e9123a290',
+    Var('chromium_git') + '/external/github.com/google/flatbuffers.git' + '@' + 'c721009491dc8275052cf33f7334e015ed737927',
 
   # Used for embedded builds. CrOS & Linux use the system version.
   'src/third_party/fontconfig/src': {
-      'url': Var('chromium_git') + '/external/fontconfig.git' + '@' + '1451f829e750926cec27855eded71c24ac7ac7c6',
+      'url': Var('chromium_git') + '/external/fontconfig.git' + '@' + 'ba206df9b9a7ca300265f650842c1459ff7c634a',
       'condition': 'checkout_linux',
   },
 
@@ -639,7 +742,7 @@
   },
 
   'src/third_party/glslang/src':
-    Var('chromium_git') + '/external/github.com/google/glslang.git' + '@' + 'ec1476b7060306fd9109faf7a4c70a20ea3b538c',
+    Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + '0ac199df32687fe17b38cd2d0da64c3742e24fef',
 
   'src/third_party/google_toolbox_for_mac/src': {
       'url': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'),
@@ -658,7 +761,7 @@
   },
 
   'src/third_party/googletest/src':
-    Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + 'd5266326752f0a1dadbd310932d8f4fd8c3c5e7d',
+    Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '2e68926a9d4929e9289373cd49e40ddcb9a628f7',
 
   # GNU binutils assembler for x86-32.
   'src/third_party/gnu_binutils': {
@@ -718,7 +821,7 @@
     Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + 'a9bac57ce6c9d390a52ebaad3259f5fdb871210e',
 
   'src/third_party/icu':
-    Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '297a4dd02b9d36c92ab9b4f121e433c9c3bc14f8',
+    Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '42d5027992a0946942839b8821765e1512afbc21',
 
   'src/third_party/icu4j': {
       'packages': [
@@ -742,17 +845,6 @@
       'dep_type': 'cipd',
   },
 
-  'src/third_party/javax_inject': {
-      'packages': [
-          {
-              'package': 'chromium/third_party/javax_inject',
-              'version': 'version:1-cr0',
-          },
-      ],
-      'condition': 'checkout_android',
-      'dep_type': 'cipd',
-  },
-
   'src/third_party/jsoncpp/source':
     Var('chromium_git') + '/external/github.com/open-source-parsers/jsoncpp.git' + '@' + 'f572e8e42e22cfcf5ab0aea26574f408943edfa4', # from svn 248
 
@@ -766,13 +858,8 @@
       'condition': 'checkout_android',
   },
 
-  'src/third_party/leakcanary/src': {
-      'url': Var('chromium_git') + '/external/github.com/square/leakcanary.git' + '@' + '608ded739e036a3aa69db47ac43777dcee506f8e',
-      'condition': 'checkout_android',
-  },
-
   'src/third_party/leveldatabase/src':
-    Var('chromium_git') + '/external/leveldb.git' + '@' + '18683981505dc374ce29211c80a9552f8f2f4571',
+    Var('chromium_git') + '/external/leveldb.git' + '@' + '73d5834eceee8efa9a8ccfec77dc096a9e8ba18a',
 
   'src/third_party/libFuzzer/src':
     Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git' + '@' +  Var('libfuzzer_revision'),
@@ -781,7 +868,7 @@
     Var('chromium_git') + '/external/libaddressinput.git' + '@' + 'd7ed8e2f3f35ce9a3aafdfdc48745ceab66e7229',
 
   'src/third_party/libaom/source/libaom': {
-    'url': Var('aomedia_git') + '/aom.git' + '@' +  '7a76b645a08ce45ef52dfb7fd719a26c1af1da85',
+    'url': Var('aomedia_git') + '/aom.git' + '@' +  '8f2210a2e54a119bede333e9465997240fc079a9',
     'condition': 'checkout_libaom',
   },
 
@@ -798,7 +885,7 @@
   },
 
   'src/third_party/libjpeg_turbo':
-    Var('chromium_git') + '/chromium/deps/libjpeg_turbo.git' + '@' + 'a1750dbc79a8792dde3d3f7d7d8ac28ba01ac9dd',
+    Var('chromium_git') + '/chromium/deps/libjpeg_turbo.git' + '@' + '61a2bbaa9aec89cb2c882d87ace6aba9aee49bb9',
 
   'src/third_party/liblouis/src': {
       'url': Var('chromium_git') + '/external/liblouis-github.git' + '@' + '5f9c03f2a3478561deb6ae4798175094be8a26c2',
@@ -812,7 +899,7 @@
     Var('chromium_git') + '/external/github.com/google/libprotobuf-mutator.git' + '@' +  Var('libprotobuf-mutator'),
 
   'src/third_party/libsrtp':
-    Var('chromium_git') + '/chromium/deps/libsrtp.git' + '@' + 'fc2345089a6b3c5aca9ecd2e1941871a78a13e9c',
+    Var('chromium_git') + '/chromium/deps/libsrtp.git' + '@' + '650611720ecc23e0e6b32b0e3100f8b4df91696c',
 
   # Android Explicit Synchronization.
   'src/third_party/libsync/src': {
@@ -821,13 +908,13 @@
   },
 
   'src/third_party/libvpx/source/libvpx':
-    Var('chromium_git') + '/webm/libvpx.git' + '@' +  '6fd9d0244c7d8941ce0004bcd2efce5d6676bef5',
+    Var('chromium_git') + '/webm/libvpx.git' + '@' +  'fa0076282e62f649483bde868602aab86448a661',
 
   'src/third_party/libwebm/source':
-    Var('chromium_git') + '/webm/libwebm.git' + '@' + '01c1d1d76f139345c442bfc8e61b4e1cba809059',
+    Var('chromium_git') + '/webm/libwebm.git' + '@' + 'e4931ebc0a816458c18a6734e91a4d1b5acd5c56',
 
   'src/third_party/libyuv':
-    Var('chromium_git') + '/libyuv/libyuv.git' + '@' + '55f5d91f11f929c4c59c32621c3d5457cca3ab0b',  # from r1714
+    Var('chromium_git') + '/libyuv/libyuv.git' + '@' + 'b36c86fdfe746d7be904c3a565b047b24d58087e',  # from r1714
 
   'src/third_party/lighttpd': {
       'url': Var('chromium_git') + '/chromium/deps/lighttpd.git' + '@' + Var('lighttpd_revision'),
@@ -845,9 +932,6 @@
       'condition': 'checkout_ios',
   },
 
-  'src/third_party/mesa/src':
-    Var('chromium_git') + '/chromium/deps/mesa.git' + '@' + '9d9b0710470f581cb5485b02b6acd8415cc093e8',
-
   # GNU binutils assembler for x86-64.
   'src/third_party/mingw-w64/mingw/bin': {
       'url': Var('chromium_git') + '/native_client/deps/third_party/mingw-w64/mingw/bin.git' + '@' + '3cc8b140b883a9fe4986d12cfd46c16a093d3527',
@@ -856,7 +940,7 @@
 
   # Graphics buffer allocator for Chrome OS.
   'src/third_party/minigbm/src': {
-      'url': Var('chromium_git') + '/chromiumos/platform/minigbm.git' + '@' + '3cb5bbacc5c8a79105c868875222696f6b9d8296',
+      'url': Var('chromium_git') + '/chromiumos/platform/minigbm.git' + '@' + 'ff1ecaf1014df4cb9ca36c5a270647a9934aaa99',
       'condition': 'checkout_linux',
   },
 
@@ -925,13 +1009,24 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '74182d1df594d4b007526412d2a46a87a7f85f21',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  'e16778c0abc9949736587660bb2c1f71c8506bb3',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
       'condition': 'checkout_win',
   },
 
+  'src/third_party/proguard': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/proguard',
+              'version': '3bd778c422ea5496de2ef25c007a517dbb5ce5ca',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
   # Dependency of chromite.git and skia.
   'src/third_party/pyelftools': {
       'url': Var('chromium_git') + '/chromiumos/third_party/pyelftools.git' + '@' + '19b3e610c86fcadb837d252c794cb5e8008826ae',
@@ -942,19 +1037,41 @@
     Var('chromium_git') + '/external/pyftpdlib.git' + '@' + '2be6d65e31c7ee6320d059f581f05ae8d89d7e45',
 
   'src/third_party/quic_trace/src':
-    Var('chromium_git') + '/external/github.com/google/quic-trace.git' + '@' + 'c9028909ba2356e073de4ea963b56fd81417a46d',
+    Var('chromium_git') + '/external/github.com/google/quic-trace.git' + '@' + 'fe1b2587410c47adac3b26a224bc9c979024c191',
 
   'src/third_party/pywebsocket/src':
     Var('chromium_git') + '/external/github.com/google/pywebsocket.git' + '@' + '2d7b73c3acbd0f41dcab487ae5c97c6feae06ce2',
 
+  'src/third_party/qemu-linux-x64': {
+      'packages': [
+          {
+              'package': 'fuchsia/qemu/linux-amd64',
+              'version': '9cc486c5b18a0be515c39a280ca9a309c54cf994'
+          },
+      ],
+      'condition': 'host_os == "linux" and checkout_fuchsia',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/qemu-mac-x64': {
+      'packages': [
+          {
+              'package': 'fuchsia/qemu/mac-amd64',
+              'version': '2d3358ae9a569b2d4a474f498b32b202a152134f'
+          },
+      ],
+      'condition': 'host_os == "mac" and checkout_fuchsia',
+      'dep_type': 'cipd',
+  },
+
   'src/third_party/re2/src':
-    Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + '5185d85264d23cfae4b38e2703703e9a4c8e974c',
+    Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + '9a227bed7a0fde418a94c967ef92d4a1fbe5e47f',
 
   'src/third_party/r8': {
       'packages': [
           {
               'package': 'chromium/third_party/r8',
-              'version': 'version:1.2.28-cr0',
+              'version': 'version:1.4.4-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -985,9 +1102,6 @@
   'src/third_party/sfntly/src':
     Var('chromium_git') + '/external/github.com/googlei18n/sfntly.git' + '@' + Var('sfntly_revision'),
 
-  'src/third_party/shaderc/src':
-    Var('chromium_git') + '/external/github.com/google/shaderc.git' + '@' + 'cd8793c34907073025af2622c28bcee64e9879a4',
-
   'src/third_party/skia':
     Var('skia_git') + '/skia.git' + '@' +  Var('skia_revision'),
 
@@ -995,7 +1109,7 @@
     Var('chromium_git') + '/external/smhasher.git' + '@' + 'e87738e57558e0ec472b2fc3a643b838e5b6e88f',
 
   'src/third_party/snappy/src':
-    Var('chromium_git') + '/external/github.com/google/snappy.git' + '@' + 'ca37ab7fb9b718e056009babb4fea591626e5882',
+    Var('chromium_git') + '/external/github.com/google/snappy.git' + '@' + 'ea660b57d65d68d521287c903459b6dd3b2804d0',
 
   'src/third_party/sqlite4java': {
       'packages': [
@@ -1044,10 +1158,10 @@
     Var('chromium_git') + '/external/selenium/py.git' + '@' + '5fd78261a75fe08d27ca4835fb6c5ce4b42275bd',
 
   'src/third_party/webgl/src':
-    Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '21dbf06b5aa6c7dc8cf56314d4a3f96f57956c53',
+    Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '0d55c887e92b645f6effe753528323ab2ffd94c2',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '5f0ce99c04eb18313dd24b3dc31cc6246496d6d5',
+    Var('webrtc_git') + '/src.git' + '@' + '4e93329839463c51d1957682ff47f09773ec9eee',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1068,9 +1182,6 @@
   'src/third_party/yasm/source/patched-yasm':
     Var('chromium_git') + '/chromium/deps/yasm/patched-yasm.git' + '@' + '720b70524a4424b15fc57e82263568c8ba0496ad',
 
-  'src/tools/gyp':
-    Var('chromium_git') + '/external/gyp.git' + '@' + 'd61a9397e668fa9843c4aa7da9e79460fe590bfb',
-
   'src/tools/page_cycler/acid3':
     Var('chromium_git') + '/chromium/deps/acid3.git' + '@' + '6be0a66a1ebd7ebc5abc1b2f405a945f6d871521',
 
@@ -1081,7 +1192,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@36668c6ef51c6ea84bfffc9d96137008eb2a6e0f',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@5f0bf6da37059c2c7ea9b65054ada076616a2a2b',
     'condition': 'checkout_src_internal',
   },
 
@@ -1377,7 +1488,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_auth',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:15.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1388,7 +1499,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_auth_api_phone',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:15.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1399,7 +1510,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_auth_base',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:15.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1410,7 +1521,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_base',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:15.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1421,7 +1532,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_basement',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:15.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1432,7 +1543,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_cast',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:16.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1443,7 +1554,18 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_cast_framework',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:16.0.1-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_android_gms_play_services_clearcut': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_clearcut',
+              'version': 'version:15.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1454,7 +1576,18 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_fido',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:15.0.1-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_android_gms_play_services_flags': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_flags',
+              'version': 'version:15.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1465,7 +1598,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_gcm',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:15.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1476,7 +1609,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_iid',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:15.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1487,7 +1620,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_instantapps',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:16.0.0-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1498,7 +1631,40 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_location',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:15.0.1-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_android_gms_play_services_phenotype': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_phenotype',
+              'version': 'version:15.0.1-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_android_gms_play_services_places_placereport': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_places_placereport',
+              'version': 'version:15.0.1-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_android_gms_play_services_stats': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_stats',
+              'version': 'version:15.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1509,7 +1675,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_tasks',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:15.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1520,7 +1686,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_vision',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:15.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1531,7 +1697,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_vision_common',
-              'version': 'version:12.0.1-cr0',
+              'version': 'version:15.0.1-cr0',
           },
       ],
       'condition': 'checkout_android',
@@ -1549,6 +1715,171 @@
       'dep_type': 'cipd',
   },
 
+  'src/third_party/android_deps/libs/com_google_code_findbugs_jsr305': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_code_findbugs_jsr305',
+              'version': 'version:1.3.9-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_dagger_dagger': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_dagger_dagger',
+              'version': 'version:2.17-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_dagger_dagger_compiler': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_dagger_dagger_compiler',
+              'version': 'version:2.17-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_dagger_dagger_producers': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_dagger_dagger_producers',
+              'version': 'version:2.17-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_dagger_dagger_spi': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_dagger_dagger_spi',
+              'version': 'version:2.17-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_errorprone_error_prone_annotations': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_errorprone_error_prone_annotations',
+              'version': 'version:2.1.3-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_errorprone_javac_shaded': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_errorprone_javac_shaded',
+              'version': 'version:9-dev-r4023-3-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format',
+              'version': 'version:1.5-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_guava_guava': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_guava_guava',
+              'version': 'version:25.0-jre-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_google_j2objc_j2objc_annotations': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_google_j2objc_j2objc_annotations',
+              'version': 'version:1.1-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/com_squareup_javapoet': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/com_squareup_javapoet',
+              'version': 'version:1.11.0-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/javax_annotation_jsr250_api': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/javax_annotation_jsr250_api',
+              'version': 'version:1.0-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/javax_inject_javax_inject': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/javax_inject_javax_inject',
+              'version': 'version:1-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/org_checkerframework_checker_compat_qual': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/org_checkerframework_checker_compat_qual',
+              'version': 'version:2.3.0-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
+  'src/third_party/android_deps/libs/org_codehaus_mojo_animal_sniffer_annotations': {
+      'packages': [
+          {
+              'package': 'chromium/third_party/android_deps/libs/org_codehaus_mojo_animal_sniffer_annotations',
+              'version': 'version:1.14-cr0',
+          },
+      ],
+      'condition': 'checkout_android',
+      'dep_type': 'cipd',
+  },
+
   # === ANDROID_DEPS Generated Code End ===
 }
 
@@ -1673,6 +2004,14 @@
                '--arch=mips'],
   },
   {
+    'name': 'sysroot_mips64',
+    'pattern': '.',
+    'condition': 'checkout_linux and checkout_mips64',
+    'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py',
+               '--arch=mips64el'],
+  },
+
+  {
     'name': 'sysroot_x64',
     'pattern': '.',
     'condition': 'checkout_linux and checkout_x64',
@@ -1712,7 +2051,7 @@
   {
     'name': 'binutils',
     'pattern': 'src/third_party/binutils',
-    'condition': 'host_os == "linux"',
+    'condition': 'host_os == "linux" and host_cpu != "mips64"',
     'action': [
         'python',
         'src/third_party/binutils/download.py',
@@ -1722,15 +2061,22 @@
     # Note: On Win, this should run after win_toolchain, as it may use it.
     'name': 'clang',
     'pattern': '.',
-    'action': ['python', 'src/tools/clang/scripts/update.py'],
+    'action': ['python', 'src/tools/clang/scripts/update.py', '--with-android={checkout_android}'],
+  },
+  {
+    # This is supposed to support the same set of platforms as 'clang' above.
+    'name': 'clang_coverage',
+    'pattern': '.',
+    'condition': 'checkout_clang_coverage_tools',
+    'action': ['python', 'src/tools/code_coverage/update_clang_coverage_tools.py'],
   },
   {
     # Mac doesn't use lld so it's not included in the default clang bundle
-    # there.  lld is however needed in win cross builds, so download it there.
-    # Should run after the clang hook.
+    # there.  lld is however needed in win and Fuchsia cross builds, so
+    # download it there. Should run after the clang hook.
     'name': 'lld/mac',
     'pattern': '.',
-    'condition': 'host_os == "mac" and checkout_win',
+    'condition': 'host_os == "mac" and (checkout_win or checkout_fuchsia)',
     'action': ['python', 'src/tools/clang/scripts/download_lld_mac.py'],
   },
   {
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 3e7c03a7..ccfebcf 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -10,24 +10,24 @@
 
 
 _EXCLUDED_PATHS = (
-    r"^native_client_sdk[\\\/]src[\\\/]build_tools[\\\/]make_rules.py",
-    r"^native_client_sdk[\\\/]src[\\\/]build_tools[\\\/]make_simple.py",
-    r"^native_client_sdk[\\\/]src[\\\/]tools[\\\/].*.mk",
-    r"^net[\\\/]tools[\\\/]spdyshark[\\\/].*",
-    r"^skia[\\\/].*",
-    r"^third_party[\\\/](WebKit|blink)[\\\/].*",
-    r"^third_party[\\\/]breakpad[\\\/].*",
-    r"^v8[\\\/].*",
+    r"^native_client_sdk[\\/]src[\\/]build_tools[\\/]make_rules.py",
+    r"^native_client_sdk[\\/]src[\\/]build_tools[\\/]make_simple.py",
+    r"^native_client_sdk[\\/]src[\\/]tools[\\/].*.mk",
+    r"^net[\\/]tools[\\/]spdyshark[\\/].*",
+    r"^skia[\\/].*",
+    r"^third_party[\\/](WebKit|blink)[\\/].*",
+    r"^third_party[\\/]breakpad[\\/].*",
+    r"^v8[\\/].*",
     r".*MakeFile$",
     r".+_autogen\.h$",
-    r".+[\\\/]pnacl_shim\.c$",
-    r"^gpu[\\\/]config[\\\/].*_list_json\.cc$",
-    r"^chrome[\\\/]browser[\\\/]resources[\\\/]pdf[\\\/]index.js",
-    r"tools[\\\/]md_browser[\\\/].*\.css$",
+    r".+[\\/]pnacl_shim\.c$",
+    r"^gpu[\\/]config[\\/].*_list_json\.cc$",
+    r"^chrome[\\/]browser[\\/]resources[\\/]pdf[\\/]index.js",
+    r"tools[\\/]md_browser[\\/].*\.css$",
     # Test pages for Maps telemetry tests.
-    r"tools[\\\/]perf[\\\/]page_sets[\\\/]maps_perf_test.*",
+    r"tools[\\/]perf[\\/]page_sets[\\/]maps_perf_test.*",
     # Test pages for WebRTC telemetry tests.
-    r"tools[\\\/]perf[\\\/]page_sets[\\\/]webrtc_cases.*",
+    r"tools[\\/]perf[\\/]page_sets[\\/]webrtc_cases.*",
 )
 
 
@@ -44,18 +44,18 @@
 # Regular expression that matches code only used for test binaries
 # (best effort).
 _TEST_CODE_EXCLUDED_PATHS = (
-    r'.*[\\\/](fake_|test_|mock_).+%s' % _IMPLEMENTATION_EXTENSIONS,
+    r'.*[\\/](fake_|test_|mock_).+%s' % _IMPLEMENTATION_EXTENSIONS,
     r'.+_test_(base|support|util)%s' % _IMPLEMENTATION_EXTENSIONS,
     r'.+_(api|browser|eg|int|perf|pixel|unit|ui)?test(_[a-z]+)?%s' %
         _IMPLEMENTATION_EXTENSIONS,
     r'.+profile_sync_service_harness%s' % _IMPLEMENTATION_EXTENSIONS,
-    r'.*[\\\/](test|tool(s)?)[\\\/].*',
+    r'.*[\\/](test|tool(s)?)[\\/].*',
     # content_shell is used for running layout tests.
-    r'content[\\\/]shell[\\\/].*',
+    r'content[\\/]shell[\\/].*',
     # Non-production example code.
-    r'mojo[\\\/]examples[\\\/].*',
+    r'mojo[\\/]examples[\\/].*',
     # Launcher for running iOS tests on the simulator.
-    r'testing[\\\/]iossim[\\\/]iossim\.mm$',
+    r'testing[\\/]iossim[\\/]iossim\.mm$',
 )
 
 
@@ -238,9 +238,9 @@
       ),
       True,
       (
-        r"^ui[\\\/]gl[\\\/].*\.cc$",
-        r"^media[\\\/]gpu[\\\/].*\.cc$",
-        r"^gpu[\\\/].*\.cc$",
+        r"^ui[\\/]gl[\\/].*\.cc$",
+        r"^media[\\/]gpu[\\/].*\.cc$",
+        r"^gpu[\\/].*\.cc$",
       ),
     ),
     (
@@ -250,9 +250,9 @@
       ),
       True,
       (
-        r"^gpu[\\\/]ipc[\\\/]service[\\\/]gpu_watchdog_thread\.cc$",
-        r"^remoting[\\\/]host[\\\/]linux[\\\/]x_server_clipboard\.cc$",
-        r"^ui[\\\/]gfx[\\\/]x[\\\/]x11_atom_cache\.cc$",
+        r"^gpu[\\/]ipc[\\/]service[\\/]gpu_watchdog_thread\.cc$",
+        r"^remoting[\\/]host[\\/]linux[\\/]x_server_clipboard\.cc$",
+        r"^ui[\\/]gfx[\\/]x[\\/]x11_atom_cache\.cc$",
       ),
     ),
     (
@@ -321,8 +321,8 @@
       True,
       (
         # Files that #define IGNORE_EINTR.
-        r'^base[\\\/]posix[\\\/]eintr_wrapper\.h$',
-        r'^ppapi[\\\/]tests[\\\/]test_broker\.cc$',
+        r'^base[\\/]posix[\\/]eintr_wrapper\.h$',
+        r'^ppapi[\\/]tests[\\/]test_broker\.cc$',
       ),
     ),
     (
@@ -333,7 +333,7 @@
       ),
       True,
       (
-        r'extensions[\\\/]renderer[\\\/]safe_builtins\.*',
+        r'extensions[\\/]renderer[\\/]safe_builtins\.*',
       ),
     ),
     (
@@ -343,7 +343,7 @@
       ),
       True,
       (
-          r'^third_party[\\\/]abseil-cpp[\\\/].*',
+          r'^third_party[\\/]abseil-cpp[\\/].*',
       ),
     ),
     (
@@ -386,9 +386,9 @@
       ),
       False,
       (
-        r'^content[\\\/]browser[\\\/]webui[\\\/]web_ui_impl\.(cc|h)$',
-        r'^content[\\\/]public[\\\/]browser[\\\/]web_ui\.h$',
-        r'^content[\\\/]public[\\\/]test[\\\/]test_web_ui\.(cc|h)$',
+        r'^content[\\/]browser[\\/]webui[\\/]web_ui_impl\.(cc|h)$',
+        r'^content[\\/]public[\\/]browser[\\/]web_ui\.h$',
+        r'^content[\\/]public[\\/]test[\\/]test_web_ui\.(cc|h)$',
       ),
     ),
     (
@@ -557,11 +557,11 @@
       ),
       False,
       (
-        r'^ios[\\\/].*\.(cc|h)$',
-        r'.*[\\\/]ios[\\\/].*\.(cc|h)$',
+        r'^ios[\\/].*\.(cc|h)$',
+        r'.*[\\/]ios[\\/].*\.(cc|h)$',
         r'.*_ios\.(cc|h)$',
-        r'^net[\\\/].*\.(cc|h)$',
-        r'.*[\\\/]tools[\\\/].*\.(cc|h)$',
+        r'^net[\\/].*\.(cc|h)$',
+        r'.*[\\/]tools[\\/].*\.(cc|h)$',
       ),
     ),
     (
@@ -582,6 +582,14 @@
       True,
       (),
     ),
+    (
+      'ios/web/public/test/http_server',
+      (
+        'web::HTTPserver is deprecated use net::EmbeddedTestServer instead.',
+      ),
+      False,
+      (),
+    ),
 )
 
 
@@ -597,18 +605,19 @@
 )
 
 _JAVA_MULTIPLE_DEFINITION_EXCLUDED_PATHS = [
-    r".*[\\\/]BuildHooksAndroidImpl\.java",
-    r".*[\\\/]LicenseContentProvider\.java",
-    r".*[\\\/]PlatformServiceBridgeImpl.java",
+    r".*[\\/]BuildHooksAndroidImpl\.java",
+    r".*[\\/]LicenseContentProvider\.java",
+    r".*[\\/]PlatformServiceBridgeImpl.java",
+    r".*chrome[\\\/]android[\\\/]feed[\\\/]dummy[\\\/].*\.java",
 ]
 
 # These paths contain test data and other known invalid JSON files.
 _KNOWN_INVALID_JSON_FILE_PATTERNS = [
-    r'test[\\\/]data[\\\/]',
-    r'^components[\\\/]policy[\\\/]resources[\\\/]policy_templates\.json$',
-    r'^third_party[\\\/]protobuf[\\\/]',
-    r'^third_party[\\\/]WebKit[\\\/]LayoutTests[\\\/]external[\\\/]wpt[\\\/]',
-    r'^third_party[\\\/]blink[\\\/]renderer[\\\/]devtools[\\\/]protocol\.json$',
+    r'test[\\/]data[\\/]',
+    r'^components[\\/]policy[\\/]resources[\\/]policy_templates\.json$',
+    r'^third_party[\\/]protobuf[\\/]',
+    r'^third_party[\\/]WebKit[\\/]LayoutTests[\\/]external[\\/]wpt[\\/]',
+    r'^third_party[\\/]blink[\\/]renderer[\\/]devtools[\\/]protocol\.json$',
 ]
 
 
@@ -638,6 +647,7 @@
 
 
 _ANDROID_SPECIFIC_PYDEPS_FILES = [
+    'android_webview/tools/run_cts.pydeps',
     'base/android/jni_generator/jni_generator.pydeps',
     'base/android/jni_generator/jni_registration_generator.pydeps',
     'build/android/gyp/aar.pydeps',
@@ -688,6 +698,7 @@
 
 _GENERIC_PYDEPS_FILES = [
     'chrome/test/chromedriver/test/run_py_tests.pydeps',
+    'chrome/test/chromedriver/log_replay/client_replay_unittest.pydeps',
     'tools/binary_size/supersize.pydeps',
 ]
 
@@ -700,11 +711,15 @@
     '%s-chromium-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com' % s
     for s in ('afdo', 'angle', 'catapult', 'chromite', 'depot-tools',
               'fuchsia-sdk', 'nacl', 'pdfium', 'perfetto', 'skia',
-              'src-internal', 'webrtc')
+              'spirv', 'src-internal', 'webrtc')
   ) | set('%s@appspot.gserviceaccount.com' % s for s in ('findit-for-me',)
   ) | set('%s@developer.gserviceaccount.com' % s for s in ('3su6n15k.default',)
   ) | set('%s@chops-service-accounts.iam.gserviceaccount.com' % s
-          for s in ('v8-ci-autoroll-builder',))
+          for s in ('v8-ci-autoroll-builder',)
+  ) | set('%s@skia-public.iam.gserviceaccount.com' % s
+          for s in ('chromium-autoroll',)
+  ) | set('%s@skia-corp.google.com.iam.gserviceaccount.com' % s
+          for s in ('chromium-internal-autoroll',))
 
 
 def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
@@ -813,6 +828,28 @@
         files) ]
   return []
 
+def _CheckNoStrCatRedefines(input_api, output_api):
+  """Checks no windows headers with StrCat redefined are included directly."""
+  files = []
+  pattern_deny = input_api.re.compile(
+      r'^#include\s*[<"](shlwapi|atlbase|propvarutil|sphelper).h[">]',
+      input_api.re.MULTILINE)
+  pattern_allow = input_api.re.compile(
+      r'^#include\s"base/win/windows_defines.inc"',
+      input_api.re.MULTILINE)
+  for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
+    contents = input_api.ReadFile(f)
+    if pattern_deny.search(contents) and not pattern_allow.search(contents):
+      files.append(f.LocalPath())
+
+  if len(files):
+    return [output_api.PresubmitError(
+        'Do not #include shlwapi.h, atlbase.h, propvarutil.h or sphelper.h '
+        'directly since they pollute code with StrCat macro. Instead, '
+        'include matching header from base/win. See http://crbug.com/856536',
+        files) ]
+  return []
+
 
 def _CheckNoUNIT_TESTInSourceFiles(input_api, output_api):
   """Checks to make sure no source files use UNIT_TEST."""
@@ -830,6 +867,59 @@
   return [output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n' +
       '\n'.join(problems))]
 
+def _CheckNoDISABLETypoInTests(input_api, output_api):
+  """Checks to prevent attempts to disable tests with DISABLE_ prefix.
+
+  This test warns if somebody tries to disable a test with the DISABLE_ prefix
+  instead of DISABLED_. To filter false positives, reports are only generated
+  if a corresponding MAYBE_ line exists.
+  """
+  problems = []
+
+  # The following two patterns are looked for in tandem - is a test labeled
+  # as MAYBE_ followed by a DISABLE_ (instead of the correct DISABLED)
+  maybe_pattern = input_api.re.compile(r'MAYBE_([a-zA-Z0-9_]+)')
+  disable_pattern = input_api.re.compile(r'DISABLE_([a-zA-Z0-9_]+)')
+
+  # This is for the case that a test is disabled on all platforms.
+  full_disable_pattern = input_api.re.compile(
+      r'^\s*TEST[^(]*\([a-zA-Z0-9_]+,\s*DISABLE_[a-zA-Z0-9_]+\)',
+      input_api.re.MULTILINE)
+
+  for f in input_api.AffectedFiles(False):
+    if not 'test' in f.LocalPath() or not f.LocalPath().endswith('.cc'):
+      continue
+
+    # Search for MABYE_, DISABLE_ pairs.
+    disable_lines = {}  # Maps of test name to line number.
+    maybe_lines = {}
+    for line_num, line in f.ChangedContents():
+      disable_match = disable_pattern.search(line)
+      if disable_match:
+        disable_lines[disable_match.group(1)] = line_num
+      maybe_match = maybe_pattern.search(line)
+      if maybe_match:
+        maybe_lines[maybe_match.group(1)] = line_num
+
+    # Search for DISABLE_ occurrences within a TEST() macro.
+    disable_tests = set(disable_lines.keys())
+    maybe_tests = set(maybe_lines.keys())
+    for test in disable_tests.intersection(maybe_tests):
+      problems.append('    %s:%d' % (f.LocalPath(), disable_lines[test]))
+
+    contents = input_api.ReadFile(f)
+    full_disable_match = full_disable_pattern.search(contents)
+    if full_disable_match:
+      problems.append('    %s' % f.LocalPath())
+
+  if not problems:
+    return []
+  return [
+      output_api.PresubmitPromptWarning(
+          'Attempt to disable a test with DISABLE_ instead of DISABLED_?\n' +
+          '\n'.join(problems))
+  ]
+
 
 def _CheckDCHECK_IS_ONHasBraces(input_api, output_api):
   """Checks to make sure DCHECK_IS_ON() does not skip the parentheses."""
@@ -1331,7 +1421,7 @@
     """
     return input_api.FilterSourceFile(
       affected_file,
-      white_list=[r'^(android_webview|base|content|net)[\\\/].*'],
+      white_list=[r'^(android_webview|base|content|net)[\\/].*'],
       black_list=(_EXCLUDED_PATHS +
                   _TEST_CODE_EXCLUDED_PATHS +
                   input_api.DEFAULT_BLACK_LIST))
@@ -1364,7 +1454,7 @@
   """
   errors = []
   white_list = [r'.*_[a-z]_.*\.png$|.*_[a-z]\.png$']
-  black_list = [r'^native_client_sdk[\\\/]']
+  black_list = [r'^native_client_sdk[\\/]']
   file_filter = lambda f: input_api.FilterSourceFile(
       f, white_list=white_list, black_list=black_list)
   for f in input_api.AffectedFiles(include_deletes=False,
@@ -1459,7 +1549,7 @@
   virtual_depended_on_files = set()
 
   file_filter = lambda f: not input_api.re.match(
-      r"^third_party[\\\/](WebKit|blink)[\\\/].*", f.LocalPath())
+      r"^third_party[\\/](WebKit|blink)[\\/].*", f.LocalPath())
   for f in input_api.AffectedFiles(include_deletes=False,
                                    file_filter=file_filter):
     filename = input_api.os_path.basename(f.LocalPath())
@@ -1534,44 +1624,44 @@
   black_list = (_EXCLUDED_PATHS +
                 _TEST_CODE_EXCLUDED_PATHS +
                 input_api.DEFAULT_BLACK_LIST +
-                (r"^base[\\\/]logging\.h$",
-                 r"^base[\\\/]logging\.cc$",
-                 r"^chrome[\\\/]app[\\\/]chrome_main_delegate\.cc$",
-                 r"^chrome[\\\/]browser[\\\/]chrome_browser_main\.cc$",
-                 r"^chrome[\\\/]browser[\\\/]ui[\\\/]startup[\\\/]"
+                (r"^base[\\/]logging\.h$",
+                 r"^base[\\/]logging\.cc$",
+                 r"^chrome[\\/]app[\\/]chrome_main_delegate\.cc$",
+                 r"^chrome[\\/]browser[\\/]chrome_browser_main\.cc$",
+                 r"^chrome[\\/]browser[\\/]ui[\\/]startup[\\/]"
                      r"startup_browser_creator\.cc$",
-                 r"^chrome[\\\/]installer[\\\/]setup[\\\/].*",
-                 r"^chrome[\\\/]chrome_cleaner[\\\/].*",
-                 r"chrome[\\\/]browser[\\\/]diagnostics[\\\/]" +
+                 r"^chrome[\\/]installer[\\/]setup[\\/].*",
+                 r"^chrome[\\/]chrome_cleaner[\\/].*",
+                 r"chrome[\\/]browser[\\/]diagnostics[\\/]" +
                      r"diagnostics_writer\.cc$",
-                 r"^chrome_elf[\\\/]dll_hash[\\\/]dll_hash_main\.cc$",
-                 r"^chromecast[\\\/]",
-                 r"^cloud_print[\\\/]",
-                 r"^components[\\\/]browser_watcher[\\\/]"
+                 r"^chrome_elf[\\/]dll_hash[\\/]dll_hash_main\.cc$",
+                 r"^chromecast[\\/]",
+                 r"^cloud_print[\\/]",
+                 r"^components[\\/]browser_watcher[\\/]"
                      r"dump_stability_report_main_win.cc$",
-                 r"^components[\\\/]html_viewer[\\\/]"
+                 r"^components[\\/]html_viewer[\\/]"
                      r"web_test_delegate_impl\.cc$",
-                 r"^components[\\\/]zucchini[\\\/].*",
+                 r"^components[\\/]zucchini[\\/].*",
                  # TODO(peter): Remove this exception. https://crbug.com/534537
-                 r"^content[\\\/]browser[\\\/]notifications[\\\/]"
+                 r"^content[\\/]browser[\\/]notifications[\\/]"
                      r"notification_event_dispatcher_impl\.cc$",
-                 r"^content[\\\/]common[\\\/]gpu[\\\/]client[\\\/]"
+                 r"^content[\\/]common[\\/]gpu[\\/]client[\\/]"
                      r"gl_helper_benchmark\.cc$",
-                 r"^courgette[\\\/]courgette_minimal_tool\.cc$",
-                 r"^courgette[\\\/]courgette_tool\.cc$",
-                 r"^extensions[\\\/]renderer[\\\/]logging_native_handler\.cc$",
-                 r"^ipc[\\\/]ipc_logging\.cc$",
-                 r"^native_client_sdk[\\\/]",
-                 r"^remoting[\\\/]base[\\\/]logging\.h$",
-                 r"^remoting[\\\/]host[\\\/].*",
-                 r"^sandbox[\\\/]linux[\\\/].*",
-                 r"^tools[\\\/]",
-                 r"^ui[\\\/]base[\\\/]resource[\\\/]data_pack.cc$",
-                 r"^ui[\\\/]aura[\\\/]bench[\\\/]bench_main\.cc$",
-                 r"^ui[\\\/]ozone[\\\/]platform[\\\/]cast[\\\/]",
-                 r"^storage[\\\/]browser[\\\/]fileapi[\\\/]" +
+                 r"^courgette[\\/]courgette_minimal_tool\.cc$",
+                 r"^courgette[\\/]courgette_tool\.cc$",
+                 r"^extensions[\\/]renderer[\\/]logging_native_handler\.cc$",
+                 r"^ipc[\\/]ipc_logging\.cc$",
+                 r"^native_client_sdk[\\/]",
+                 r"^remoting[\\/]base[\\/]logging\.h$",
+                 r"^remoting[\\/]host[\\/].*",
+                 r"^sandbox[\\/]linux[\\/].*",
+                 r"^tools[\\/]",
+                 r"^ui[\\/]base[\\/]resource[\\/]data_pack.cc$",
+                 r"^ui[\\/]aura[\\/]bench[\\/]bench_main\.cc$",
+                 r"^ui[\\/]ozone[\\/]platform[\\/]cast[\\/]",
+                 r"^storage[\\/]browser[\\/]fileapi[\\/]" +
                      r"dump_file_system.cc$",
-                 r"^headless[\\\/]app[\\\/]headless_shell\.cc$"))
+                 r"^headless[\\/]app[\\/]headless_shell\.cc$"))
   source_file_filter = lambda x: input_api.FilterSourceFile(
       x, white_list=file_inclusion_pattern, black_list=black_list)
 
@@ -1658,6 +1748,20 @@
 
 
 def _CheckUniquePtr(input_api, output_api):
+  # Returns whether |template_str| is of the form <T, U...> for some types T
+  # and U. Assumes that |template_str| is already in the form <...>.
+  def HasMoreThanOneArg(template_str):
+    # Level of <...> nesting.
+    nesting = 0
+    for c in template_str:
+      if c == '<':
+        nesting += 1
+      elif c == '>':
+        nesting -= 1
+      elif c == ',' and nesting == 1:
+        return True
+    return False
+
   file_inclusion_pattern = [r'.+%s' % _IMPLEMENTATION_EXTENSIONS]
   sources = lambda affected_file: input_api.FilterSourceFile(
       affected_file,
@@ -1693,10 +1797,13 @@
   # Suffix saying that what follows are call parentheses with a non-empty list
   # of arguments.
   nonempty_arg_list_pattern = r'\(([^)]|$)'
+  # Put the template argument into a capture group for deeper examination later.
   return_construct_pattern = input_api.re.compile(
       start_of_expr_pattern
       + r'std::unique_ptr'
+      + '(?P<template_arg>'
       + template_arg_no_array_pattern
+      + ')'
       + nonempty_arg_list_pattern)
 
   problems_constructor = []
@@ -1709,8 +1816,14 @@
       # But allow:
       # return std::unique_ptr<T[]>(foo);
       # bar = std::unique_ptr<T[]>(foo);
+      # And also allow cases when the second template argument is present. Those
+      # cases cannot be handled by std::make_unique:
+      # return std::unique_ptr<T, U>(foo);
+      # bar = std::unique_ptr<T, U>(foo);
       local_path = f.LocalPath()
-      if return_construct_pattern.search(line):
+      return_construct_result = return_construct_pattern.search(line)
+      if return_construct_result and not HasMoreThanOneArg(
+          return_construct_result.group('template_arg')):
         problems_constructor.append(
           '%s:%d\n    %s' % (local_path, line_number, line.strip()))
       # Disallow:
@@ -1812,12 +1925,12 @@
   }
   # Most JSON files are preprocessed and support comments, but these do not.
   json_no_comments_patterns = [
-    r'^testing[\\\/]',
+    r'^testing[\\/]',
   ]
   # Only run IDL checker on files in these directories.
   idl_included_patterns = [
-    r'^chrome[\\\/]common[\\\/]extensions[\\\/]api[\\\/]',
-    r'^extensions[\\\/]common[\\\/]api[\\\/]',
+    r'^chrome[\\/]common[\\/]extensions[\\/]api[\\/]',
+    r'^extensions[\\/]common[\\/]api[\\/]',
   ]
 
   def get_action(affected_file):
@@ -1913,6 +2026,7 @@
   # matching the above patterns, which trigger false positives.
   exclude_paths = [
       'third_party/crashpad/*',
+      'third_party/protobuf/benchmarks/python/*',
       'third_party/third_party/blink/renderer/platform/bindings/*',
       'third_party/win_build_output/*',
   ]
@@ -2112,8 +2226,8 @@
       black_list=(_EXCLUDED_PATHS +
                   _TEST_CODE_EXCLUDED_PATHS +
                   input_api.DEFAULT_BLACK_LIST +
-                  (r'^chromecast[\\\/].*',
-                   r'^remoting[\\\/].*')),
+                  (r'^chromecast[\\/].*',
+                   r'^remoting[\\/].*')),
       white_list=[r'.*\.java$'])
 
   for f in input_api.AffectedSourceFiles(sources):
@@ -2143,10 +2257,13 @@
   # Do not check format of logs in the given files
   cr_log_check_excluded_paths = [
     # //chrome/android/webapk cannot depend on //base
-    r"^chrome[\\\/]android[\\\/]webapk[\\\/].*",
+    r"^chrome[\\/]android[\\/]webapk[\\/].*",
     # WebView license viewer code cannot depend on //base; used in stub APK.
-    r"^android_webview[\\\/]glue[\\\/]java[\\\/]src[\\\/]com[\\\/]android[\\\/]"
-    r"webview[\\\/]chromium[\\\/]License.*",
+    r"^android_webview[\\/]glue[\\/]java[\\/]src[\\/]com[\\/]android[\\/]"
+    r"webview[\\/]chromium[\\/]License.*",
+    # The customtabs_benchmark is a small app that does not depend on Chromium
+    # java pieces.
+    r"tools[\\/]android[\\/]customtabs_benchmark[\\/].*",
   ]
 
   cr_log_import_pattern = input_api.re.compile(
@@ -2351,7 +2468,7 @@
       black_list=(_EXCLUDED_PATHS +
                   _TEST_CODE_EXCLUDED_PATHS +
                   input_api.DEFAULT_BLACK_LIST +
-                  (r'^android_webview[\\\/]glue[\\\/].*',)),
+                  (r'^android_webview[\\/]glue[\\/].*',)),
       white_list=[r'.*\.java$'])
 
   for f in input_api.AffectedSourceFiles(sources):
@@ -2492,8 +2609,8 @@
     # It's ok for base/memory/singleton.h to have |Singleton<|.
     black_list = (_EXCLUDED_PATHS +
                   input_api.DEFAULT_BLACK_LIST +
-                  (r"^base[\\\/]memory[\\\/]singleton\.h$",
-                   r"^net[\\\/]quic[\\\/]platform[\\\/]impl[\\\/]"
+                  (r"^base[\\/]memory[\\/]singleton\.h$",
+                   r"^net[\\/]quic[\\/]platform[\\/]impl[\\/]"
                        r"quic_singleton_impl\.h$"))
     return input_api.FilterSourceFile(affected_file, black_list=black_list)
 
@@ -2641,7 +2758,7 @@
 Use of => (arrow) operator detected in:
 %s
 Please ensure your code does not run on iOS9 (=> (arrow) does not work there).
-https://chromium.googlesource.com/chromium/src/+/master/docs/es6_chromium.md#Arrow-Functions
+https://chromium.googlesource.com/chromium/src/+/master/styleguide/web/es6.md#Arrow-Functions
 """ % f.LocalPath()
           ])))
 
@@ -2655,8 +2772,8 @@
 %s
 Please ensure your code does not run on iOS9 because const/let is not fully
 supported.
-https://chromium.googlesource.com/chromium/src/+/master/docs/es6_chromium.md#let-Block_Scoped-Variables
-https://chromium.googlesource.com/chromium/src/+/master/docs/es6_chromium.md#const-Block_Scoped-Constants
+https://chromium.googlesource.com/chromium/src/+/master/styleguide/web/es6.md#let-Block_Scoped-Variables
+https://chromium.googlesource.com/chromium/src/+/master/styleguide/web/es6.md#const-Block_Scoped-Constants
 """ % f.LocalPath()
           ])))
 
@@ -2874,6 +2991,50 @@
   return []
 
 
+def _CheckCorrectProductNameInMessages(input_api, output_api):
+  """Check that Chromium-branded strings don't include "Chrome" or vice versa.
+
+  This assumes we won't intentionally reference one product from the other
+  product.
+  """
+  all_problems = []
+  test_cases = [{
+    "filename_postfix": "google_chrome_strings.grd",
+    "correct_name": "Chrome",
+    "incorrect_name": "Chromium",
+  }, {
+    "filename_postfix": "chromium_strings.grd",
+    "correct_name": "Chromium",
+    "incorrect_name": "Chrome",
+  }]
+
+  for test_case in test_cases:
+    problems = []
+    filename_filter = lambda x: x.LocalPath().endswith(
+        test_case["filename_postfix"])
+
+    # Check each new line. Can yield false positives in multiline comments, but
+    # easier than trying to parse the XML because messages can have nested
+    # children, and associating message elements with affected lines is hard.
+    for f in input_api.AffectedSourceFiles(filename_filter):
+      for line_num, line in f.ChangedContents():
+        if "<message" in line or "<!--" in line or "-->" in line:
+          continue
+        if test_case["incorrect_name"] in line:
+          problems.append(
+              "Incorrect product name in %s:%d" % (f.LocalPath(), line_num))
+
+    if problems:
+      message = (
+        "Strings in %s-branded string files should reference \"%s\", not \"%s\""
+            % (test_case["correct_name"], test_case["correct_name"],
+               test_case["incorrect_name"]))
+      all_problems.append(
+          output_api.PresubmitPromptWarning(message, items=problems))
+
+  return all_problems
+
+
 def _AndroidSpecificOnUploadChecks(input_api, output_api):
   """Groups checks that target android code."""
   results = []
@@ -2905,6 +3066,7 @@
       _CheckNoProductionCodeUsingTestOnlyFunctionsJava(input_api, output_api))
   results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
   results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
+  results.extend(_CheckNoDISABLETypoInTests(input_api, output_api))
   results.extend(_CheckDCHECK_IS_ONHasBraces(input_api, output_api))
   results.extend(_CheckNoNewWStrings(input_api, output_api))
   results.extend(_CheckNoDEPSGIT(input_api, output_api))
@@ -2950,6 +3112,7 @@
   results.extend(input_api.RunTests(
     input_api.canned_checks.CheckVPythonSpec(input_api, output_api)))
   results.extend(_CheckTranslationScreenshots(input_api, output_api))
+  results.extend(_CheckCorrectProductNameInMessages(input_api, output_api))
 
   for f in input_api.AffectedFiles():
     path, name = input_api.os_path.split(f.LocalPath())
@@ -3319,28 +3482,6 @@
   return []
 
 
-def _CheckCrbugLinksHaveHttps(input_api, output_api):
-  """Checks that crbug(.com) links are correctly prefixed by https://,
-   unless they come in the accepted form TODO(crbug.com/...)
-  """
-
-  # The cr bug strings are split to avoid matching in real presubmit
-  # checkings.
-  pattern = input_api.re.compile(r'//.*(?<!:\/\/)cr''bug[.com]*')
-  accepted_pattern = input_api.re.compile(r'//.*TODO\(cr''bug[.com]*')
-  problems = []
-  for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
-    for line_num, line in f.ChangedContents():
-      if pattern.search(line) and not accepted_pattern.search(line):
-        problems.append('    %s:%d %s' % (f.LocalPath(), line_num, line))
-
-  if problems:
-    return [output_api.PresubmitPromptWarning(
-      'Found unprefixed crbug.com URL(s), consider prepending https://\n' +
-      '\n'.join(problems))]
-  return []
-
-
 def CheckChangeOnUpload(input_api, output_api):
   results = []
   results.extend(_CommonChecks(input_api, output_api))
@@ -3351,7 +3492,6 @@
   results.extend(_AndroidSpecificOnUploadChecks(input_api, output_api))
   results.extend(_CheckSyslogUseWarning(input_api, output_api))
   results.extend(_CheckGoogleSupportAnswerUrl(input_api, output_api))
-  results.extend(_CheckCrbugLinksHaveHttps(input_api, output_api))
   results.extend(_CheckUniquePtr(input_api, output_api))
   results.extend(_CheckNewHeaderWithoutGnChange(input_api, output_api))
   return results
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py
index ce9e79b..0c23bb9 100755
--- a/PRESUBMIT_test.py
+++ b/PRESUBMIT_test.py
@@ -568,13 +568,6 @@
             'android_archive_rel_ng',
             'android_arm64_dbg_recipe',
             'android_blink_rel',
-            'android_chromium_variable',
-            'android_chromium_variable_archive',
-            'android_chromium_variable_arm64',
-            'android_chromium_variable_cast_shell',
-            'android_chromium_variable_clang',
-            'android_chromium_variable_gn',
-            'android_chromium_variable_nexus4',
             'android_clang_dbg_recipe',
             'android_compile_dbg',
             'android_compile_x64_dbg',
@@ -1618,6 +1611,125 @@
     self.assertTrue('base/another.h' in warnings[0].items)
 
 
+class CorrectProductNameInMessagesTest(unittest.TestCase):
+  def testProductNameInDesc(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockAffectedFile('chrome/app/google_chrome_strings.grd', [
+        '<message name="Foo" desc="Welcome to Chrome">',
+        '  Welcome to Chrome!',
+        '</message>',
+      ]),
+      MockAffectedFile('chrome/app/chromium_strings.grd', [
+        '<message name="Bar" desc="Welcome to Chrome">',
+        '  Welcome to Chromium!',
+        '</message>',
+      ]),
+    ]
+    warnings = PRESUBMIT._CheckCorrectProductNameInMessages(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(0, len(warnings))
+
+  def testChromeInChromium(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockAffectedFile('chrome/app/google_chrome_strings.grd', [
+        '<message name="Foo" desc="Welcome to Chrome">',
+        '  Welcome to Chrome!',
+        '</message>',
+      ]),
+      MockAffectedFile('chrome/app/chromium_strings.grd', [
+        '<message name="Bar" desc="Welcome to Chrome">',
+        '  Welcome to Chrome!',
+        '</message>',
+      ]),
+    ]
+    warnings = PRESUBMIT._CheckCorrectProductNameInMessages(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(1, len(warnings))
+    self.assertTrue('chrome/app/chromium_strings.grd' in warnings[0].items[0])
+
+  def testChromiumInChrome(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockAffectedFile('chrome/app/google_chrome_strings.grd', [
+        '<message name="Foo" desc="Welcome to Chrome">',
+        '  Welcome to Chromium!',
+        '</message>',
+      ]),
+      MockAffectedFile('chrome/app/chromium_strings.grd', [
+        '<message name="Bar" desc="Welcome to Chrome">',
+        '  Welcome to Chromium!',
+        '</message>',
+      ]),
+    ]
+    warnings = PRESUBMIT._CheckCorrectProductNameInMessages(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(1, len(warnings))
+    self.assertTrue(
+        'chrome/app/google_chrome_strings.grd:2' in warnings[0].items[0])
+
+  def testMultipleInstances(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockAffectedFile('chrome/app/chromium_strings.grd', [
+        '<message name="Bar" desc="Welcome to Chrome">',
+        '  Welcome to Chrome!',
+        '</message>',
+        '<message name="Baz" desc="A correct message">',
+        '  Chromium is the software you are using.',
+        '</message>',
+        '<message name="Bat" desc="An incorrect message">',
+        '  Google Chrome is the software you are using.',
+        '</message>',
+      ]),
+    ]
+    warnings = PRESUBMIT._CheckCorrectProductNameInMessages(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(1, len(warnings))
+    self.assertTrue(
+        'chrome/app/chromium_strings.grd:2' in warnings[0].items[0])
+    self.assertTrue(
+        'chrome/app/chromium_strings.grd:8' in warnings[0].items[1])
+
+  def testMultipleWarnings(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockAffectedFile('chrome/app/chromium_strings.grd', [
+        '<message name="Bar" desc="Welcome to Chrome">',
+        '  Welcome to Chrome!',
+        '</message>',
+        '<message name="Baz" desc="A correct message">',
+        '  Chromium is the software you are using.',
+        '</message>',
+        '<message name="Bat" desc="An incorrect message">',
+        '  Google Chrome is the software you are using.',
+        '</message>',
+      ]),
+      MockAffectedFile('components/components_google_chrome_strings.grd', [
+        '<message name="Bar" desc="Welcome to Chrome">',
+        '  Welcome to Chrome!',
+        '</message>',
+        '<message name="Baz" desc="A correct message">',
+        '  Chromium is the software you are using.',
+        '</message>',
+        '<message name="Bat" desc="An incorrect message">',
+        '  Google Chrome is the software you are using.',
+        '</message>',
+      ]),
+    ]
+    warnings = PRESUBMIT._CheckCorrectProductNameInMessages(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(2, len(warnings))
+    self.assertTrue(
+        'components/components_google_chrome_strings.grd:5'
+             in warnings[0].items[0])
+    self.assertTrue(
+        'chrome/app/chromium_strings.grd:2' in warnings[1].items[0])
+    self.assertTrue(
+        'chrome/app/chromium_strings.grd:8' in warnings[1].items[1])
+
+
 class MojoManifestOwnerTest(unittest.TestCase):
   def testMojoManifestChangeNeedsSecurityOwner(self):
     mock_input_api = MockInputApi()
@@ -1659,40 +1771,6 @@
     self.assertEqual([], errors)
 
 
-class CheckCrbugLinksHaveHttpsTest(unittest.TestCase):
-  def assertWarningsWithFile(self, content, expected_warnings, file_name):
-    input_api = MockInputApi()
-    input_api.files = [
-      MockFile(file_name, [content])
-    ]
-
-    warnings = PRESUBMIT._CheckCrbugLinksHaveHttps(input_api, MockOutputApi())
-    self.assertEqual(expected_warnings, len(warnings))
-
-  def assertWarnings(self, content, expected_warnings):
-    for f in ['somewhere/file.cc', 'file.java', 'file.py', 'file_test.cc']:
-      self.assertWarningsWithFile(content, expected_warnings, f)
-
-  # The cr bug strings are split to avoid matching in real PRESUBMIT, so meta!
-  def testNoScheme(self):
-    self.assertWarnings('// TODO(dev): cr''bug.com should be linkified', 1)
-
-  def testNoScheme2(self):
-    self.assertWarnings('// TODO(dev): (cr''bug.com) should be linkified', 1)
-
-  def testNoCom(self):
-    self.assertWarnings('// TODO(dev): cr''bug/123 should be well formed', 1)
-
-  def testHttp(self):
-    self.assertWarnings('// TODO(dev): http://cr''bug.com it\'s OK', 0)
-
-  def testHttps(self):
-    self.assertWarnings('// TODO(dev): https://cr''bug.com is just great', 0)
-
-  def testTodo(self):
-    self.assertWarnings('// TODO(cr''bug.com/123456): it\'s also OK', 0)
-
-
 class BannedFunctionCheckTest(unittest.TestCase):
 
   def testBannedIosObcjFunctions(self):
@@ -1827,17 +1905,20 @@
         'bar = std::unique_ptr<T>(',
         '    fooVeryVeryVeryLongStillGoingWellThisWillTakeAWhileFinallyThere);'
       ]),
+      MockFile('dir/multi_arg.cc', [
+          'auto p = std::unique_ptr<std::pair<T, D>>(new std::pair(T, D));']),
     ]
 
     results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi())
     self.assertEqual(1, len(results))
     self.assertTrue('std::make_unique' in results[0].message)
-    self.assertEqual(5, len(results[0].items))
+    self.assertEqual(6, len(results[0].items))
     self.assertTrue('foo.cc' in results[0].items[0])
     self.assertTrue('bar.mm' in results[0].items[1])
     self.assertTrue('mult.cc' in results[0].items[2])
     self.assertTrue('mult2.cc' in results[0].items[3])
     self.assertTrue('mult3.cc' in results[0].items[4])
+    self.assertTrue('multi_arg.cc' in results[0].items[5])
 
   def testFalsePositives(self):
     mock_input_api = MockInputApi()
@@ -1853,11 +1934,52 @@
       ]),
       MockFile('dir/nested.cc', ['set<std::unique_ptr<T>>();']),
       MockFile('dir/nested2.cc', ['map<U, std::unique_ptr<T>>();']),
+
+      # Two-argument invocation of std::unique_ptr is exempt because there is
+      # no equivalent using std::make_unique.
+      MockFile('dir/multi_arg.cc', [
+        'auto p = std::unique_ptr<T, D>(new T(), D());']),
     ]
 
     results = PRESUBMIT._CheckUniquePtr(mock_input_api, MockOutputApi())
     self.assertEqual(0, len(results))
 
+class CheckNoDirectIncludesHeadersWhichRedefineStrCat(unittest.TestCase):
+  def testBlocksDirectIncludes(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockFile('dir/foo_win.cc', ['#include "shlwapi.h"']),
+      MockFile('dir/bar.h', ['#include <propvarutil.h>']),
+      MockFile('dir/baz.h', ['#include <atlbase.h>']),
+      MockFile('dir/jumbo.h', ['#include "sphelper.h"']),
+    ]
+    results = PRESUBMIT._CheckNoStrCatRedefines(mock_input_api, MockOutputApi())
+    self.assertEquals(1, len(results))
+    self.assertEquals(4, len(results[0].items))
+    self.assertTrue('StrCat' in results[0].message)
+    self.assertTrue('foo_win.cc' in results[0].items[0])
+    self.assertTrue('bar.h' in results[0].items[1])
+    self.assertTrue('baz.h' in results[0].items[2])
+    self.assertTrue('jumbo.h' in results[0].items[3])
+
+  def testAllowsToIncludeWrapper(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockFile('dir/baz_win.cc', ['#include "base/win/shlwapi.h"']),
+      MockFile('dir/baz-win.h', ['#include "base/win/atl.h"']),
+    ]
+    results = PRESUBMIT._CheckNoStrCatRedefines(mock_input_api, MockOutputApi())
+    self.assertEquals(0, len(results))
+
+  def testAllowsToCreateWrapper(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockFile('base/win/shlwapi.h', [
+        '#include <shlwapi.h>',
+        '#include "base/win/windows_defines.inc"']),
+    ]
+    results = PRESUBMIT._CheckNoStrCatRedefines(mock_input_api, MockOutputApi())
+    self.assertEquals(0, len(results))
 
 class TranslationScreenshotsTest(unittest.TestCase):
   # An empty grd file.
@@ -2016,5 +2138,68 @@
     self.assertEqual([], warnings)
 
 
+class DISABLETypoInTest(unittest.TestCase):
+
+  def testPositive(self):
+    # Verify the typo "DISABLE_" instead of "DISABLED_" in various contexts
+    # where the desire is to disable a test.
+    tests = [
+        # Disabled on one platform:
+        '#if defined(OS_WIN)\n'
+        '#define MAYBE_FoobarTest DISABLE_FoobarTest\n'
+        '#else\n'
+        '#define MAYBE_FoobarTest FoobarTest\n'
+        '#endif\n',
+        # Disabled on one platform spread cross lines:
+        '#if defined(OS_WIN)\n'
+        '#define MAYBE_FoobarTest \\\n'
+        '    DISABLE_FoobarTest\n'
+        '#else\n'
+        '#define MAYBE_FoobarTest FoobarTest\n'
+        '#endif\n',
+        # Disabled on all platforms:
+        '  TEST_F(FoobarTest, DISABLE_Foo)\n{\n}',
+        # Disabled on all platforms but multiple lines
+        '  TEST_F(FoobarTest,\n   DISABLE_foo){\n}\n',
+    ]
+
+    for test in tests:
+      mock_input_api = MockInputApi()
+      mock_input_api.files = [
+          MockFile('some/path/foo_unittest.cc', test.splitlines()),
+      ]
+
+      results = PRESUBMIT._CheckNoDISABLETypoInTests(mock_input_api,
+                                                     MockOutputApi())
+      self.assertEqual(
+          1,
+          len(results),
+          msg=('expected len(results) == 1 but got %d in test: %s' %
+               (len(results), test)))
+      self.assertTrue(
+          'foo_unittest.cc' in results[0].message,
+          msg=('expected foo_unittest.cc in message but got %s in test %s' %
+               (results[0].message, test)))
+
+  def testIngoreNotTestFiles(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+        MockFile('some/path/foo.cc', 'TEST_F(FoobarTest, DISABLE_Foo)'),
+    ]
+
+    results = PRESUBMIT._CheckNoDISABLETypoInTests(mock_input_api,
+                                                   MockOutputApi())
+    self.assertEqual(0, len(results))
+
+  def testIngoreDeletedFiles(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+        MockFile('some/path/foo.cc', 'TEST_F(FoobarTest, Foo)', action='D'),
+    ]
+
+    results = PRESUBMIT._CheckNoDISABLETypoInTests(mock_input_api,
+                                                   MockOutputApi())
+    self.assertEqual(0, len(results))
+
 if __name__ == '__main__':
   unittest.main()
diff --git a/WATCHLISTS b/WATCHLISTS
index e48f29c..ed41ae5 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -33,11 +33,18 @@
                   'chrome/browser/android/webapps/',
     },
     'android_crash_reporting': {
-      'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/crash/'
+      'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/crash/' \
+                  'chrome/browser/android/crash/' \
+                  'components/crash/android/' \
+                  'components/minidump_uploader/'
     },
     'android_crazy_linker': {
       'filepath': 'third_party/android_crazy_linker/'
     },
+    'android_deps': {
+      'filepath': 'third_party/android_deps/' \
+                  '|tools/android/roll/android_deps/'
+    },
     'android_infobars': {
       'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/infobar/'
     },
@@ -51,6 +58,9 @@
       'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/.*ChooserDialog.java|'\
                   'chrome/android/javatests/src/org/chromium/chrome/browser/.*ChooserDialogTest.java'
     },
+    'android_lint': {
+      'filepath': 'build/android/lint/'
+    },
     'android_loading': {
       'filepath': 'tools/android/loading/'
     },
@@ -114,6 +124,9 @@
     'arc_auth': {
       'filepath': 'chrome/browser/chromeos/arc/arc_auth'
     },
+    'arc_common': {
+      'filepath': 'components/arc/common/',
+    },
     'arc_fileapi': {
       'filepath': 'chrome/browser/chromeos/arc/fileapi'
     },
@@ -169,6 +182,11 @@
                   'components/autofill/browser/webdata/|'\
                   'components/webdata/',
     },
+    'autofill_assistant': {
+      'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/|'\
+                  'chrome/browser/android/autofill_assistant/|'\
+                  'components/autofill_assistant/',
+    },
     'autofill_credit_cards': {
       'filepath': 'chrome/browser/ui/autofill/chrome_autofill_client*|'\
                   'chrome/browser/ui/autofill/save_card_*|'\
@@ -207,7 +225,7 @@
       'filepath': '^base/task/',
     },
     'base_task_scheduler': {
-      'filepath': '^base/task_scheduler',
+      'filepath': '^base/task/task_scheduler',
     },
     'base_win': {
       'filepath': '^base/win',
@@ -254,10 +272,12 @@
     'blink_bluetooth': {
       'filepath': 'third_party/(WebKit|blink)/.*[Bb]luetooth'
     },
-    'blink_canvas2d': {
+    'blink_canvas': {
       'filepath': 'third_party/blink/renderer/core/html/canvas' \
-                  '|third_party/blink/renderer/modules/canvas2d' \
-                  '|third_party/blink/renderer/platform/graphics/canvas_2d',
+                  '|third_party/blink/renderer/core/offscreencanvas' \
+                  '|third_party/blink/renderer/core/geometry' \
+                  '|third_party/blink/renderer/modules/canvas' \
+                  '|third_party/blink/renderer/platform/graphics/canvas',
     },
     'blink_client_hints': {
       'filepath': 'third_party/blink/renderer/core/loader/accept_client_hints*' \
@@ -361,9 +381,13 @@
       'filepath': 'third_party/blink/renderer/core/html/parser/'
     },
     'blink_indexed_db': {
-      'filepath': 'third_party/blink/renderer/modules/indexeddb/' \
-                  '|third_party/WebKit/LayoutTests/storage/indexeddb' \
-                  '|third_party/blink/public/platform/.*_idb'
+      'filepath': 'third_party/blink/common/indexeddb' \
+                  '|third_party/blink/public/common/indexeddb' \
+                  '|third_party/blink/public/platform/.*_idb' \
+                  '|third_party/blink/public/platform/modules/indexeddb' \
+                  '|third_party/blink/public/mojom/indexeddb' \
+                  '|third_party/blink/renderer/modules/indexeddb/' \
+                  '|third_party/WebKit/LayoutTests/storage/indexeddb'
     },
     'blink_input': {
       'filepath': 'third_party/blink/renderer/core/input/'
@@ -604,7 +628,7 @@
                   '|chrome/browser/resources/settings/',
     },
     'browsing_data': {
-      'filepath': '/browsing_data/',
+      'filepath': 'browsing_data|BrowsingData',
     },
     'bubble': {
       'filepath': 'ui/views/bubble/|'\
@@ -718,7 +742,8 @@
       'filepath': 'chromeos/CHROMEOS_LKGM',
     },
     'chromeos_login': {
-      'filepath': 'chrome/browser/chromeos/login/|'\
+      'filepath': 'ash/login/|'\
+                  'chrome/browser/chromeos/login/|'\
                   'chrome/browser/ui/webui/chromeos/login/|'\
                   'chrome/browser/resources/chromeos/login/|'\
                   'ui/login/',
@@ -933,6 +958,23 @@
     'gpu_passthrough_cmd_decoder': {
       'filepath': 'gpu/command_buffer/service/.*passthrough',
     },
+    'guest_view': {
+      'filepath': 'chrome/browser/apps/guest_view|'\
+                  'chrome/browser/extensions/api/web_view|'\
+                  'chrome/browser/guest_view|'\
+                  'chrome/common/extensions/api/webview*.json|'\
+                  'chrome/common/extensions/docs|'\
+                  'chrome/renderer/resources/extensions/web_view|'\
+                  'components/guest_view|'\
+                  'content/browser/browser_plugin|'\
+                  'content/renderer/browser_plugin|'\
+                  'extensions/browser/api/guest_view|'\
+                  'extensions/browser/guest_view|'\
+                  'extensions/common/guest_view|'\
+                  'extensions/common/mojo/guest_view.mojom|'\
+                  'extensions/common/api/*view*.json|'\
+                  'extensions/renderer/guest_view',
+    },
     'headless': {
       'filepath': 'headless/'
     },
@@ -952,11 +994,15 @@
     },
     'indexed_db': {
       'filepath': 'content/browser/indexed_db|'\
-                  'content/child/indexed_db|'\
-                  'content/common/indexed_db|'\
                   'content/public/browser/indexed_db|'\
+                  'content/renderer/indexed_db|'\
                   'content/test/data/indexeddb',
     },
+    'infra': {
+      'filepath': 'infra/config|'\
+                  'testing/buildbot|'\
+                  'tools/mb',
+    },
     'ink_drop': {
       'filepath': 'ui/views/animation/test/.*ink_drop.*|' \
                   'ui/views/animation/.*ink_drop.*'
@@ -966,6 +1012,9 @@
                   'content/renderer/input|'\
                   'ui/events/blink/'
     },
+    'input_devices': {
+      'filepath': 'ui/events/devices/',
+    },
     'installable': {
       'filepath': 'chrome/browser/installable/',
     },
@@ -1061,6 +1110,9 @@
                   '|chrome/common/media_galleries/'\
                   '|chrome/test/data/extensions/api_test/media_galleries/'
     },
+    'media_gpu': {
+      'filepath': 'media/gpu/',
+    },
     'media_mojo': {
       'filepath': 'media/mojo/'
     },
@@ -1126,16 +1178,23 @@
       'filepath': 'mojo',
     },
     'multidevice': {
-      'filepath': 'ash/multidevice_setup/'\
+      'filepath': 'ash/multi_device_setup/'\
+                  '|chrome/browser/chromeos/device_sync/'\
+                  '|chrome/browser/chromeos/multidevice_setup/'\
+                  '|chrome/browser/chromeos/secure_channel/'\
                   '|chrome/browser/resources/chromeos/multidevice_setup/'\
+                  '|chrome/browser/resources/settings/multidevice_page/'\
+                  '|chrome/browser/ui/webui/chromeos/multidevice_setup/'\
+                  '|chrome/browser/ui/webui/settings/chromeos/multidevice'\
                   '|chromeos/components/proximity_auth/'\
                   '|chromeos/services/device_sync/'\
                   '|chromeos/services/multidevice_setup/'\
                   '|chromeos/services/secure_channel/'\
-                  '|components/cryptauth/'
+                  '|components/cryptauth/'\
+                  '|ui/webui/resources/cr_components/chromeos/multidevice_setup/'
     },
     'mus': {
-      'filepath': 'services/ui/'\
+      'filepath': 'services/ws/'\
                   '|mojo/gpu/',
     },
     'nacl': {
@@ -1238,22 +1297,19 @@
                   '|chrome/android/java/src/org/chromium/chrome/browser/offlinepages/'
     },
     'omnibox': {
-      'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/omnibox/|'\
-                  'chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/|'\
-                  'chrome/browser/autocomplete/|'\
+      'filepath': 'chrome/browser/autocomplete/|'\
                   'chrome/browser/ui/location_bar/|'\
                   'chrome/browser/ui/omnibox/|'\
                   'chrome/browser/ui/.*/location_bar/|'\
                   'chrome/browser/ui/.*/omnibox/|'\
-                  'components/omnibox/|'\
-                  'ios/chrome/browser/ui/omnibox/'
+                  'components/omnibox/'
     },
     'optimization_guide': {
       'filepath': 'optimization_guide|'\
                   'optimization_hints',
     },
     'origin_trials': {
-      'filepath': 'origin_trials'\
+      'filepath': 'origin_trial'\
                   '|OriginTrial'\
                   '|ConditionalFeature',
     },
@@ -1385,12 +1441,15 @@
       'filepath': 'chrome/(browser|common|renderer)/safe_browsing/|'\
                   'components/safe_browsing/',
     },
-    'safe_browsing_db': {
-      'filepath': 'components/safe_browsing_db/',
-    },
     'screen_orientation': {
       'filepath': 'screen_orientation',
     },
+    'security': {
+      'filepath': 'base/json/'\
+                  '|base/memory/.*shared_memory'\
+                  '|components/cbor/'\
+                  '|AndroidManifest',
+    },
     'service_worker': {
       'filepath': 'content/(browser|renderer|child|common)/service_worker/',
     },
@@ -1409,6 +1468,12 @@
       'filepath': 'content/browser/site_instance|'\
         'content/browser/browsing_instance',
     },
+    'smartlock': {
+      'filepath': 'chrome/browser/apps/platform_apps/api/easy_unlock_private/'\
+                  '|chrome/browser/chromeos/login/easy_unlock/'\
+                  '|chrome/browser/resources/easy_unlock/'\
+                  '|chromeos/components/proximity_auth/'
+    },
     'smb': {
       'filepath': 'chrome/browser/chromeos/file_system_provider'\
                   '|chrome/browser/chromeos/smb_client'\
@@ -1425,6 +1490,10 @@
                   '|third_party/hunspell/'\
                   '|third_party/hunspell_dictionaries/',
     },
+    'stack_sampling_profiler': {
+      'filepath': 'components/metrics/*call_stack_profile*'\
+                  '|base/profiler/',
+    },
     'startup': {
       'filepath': 'chrome/browser/ui/startup/',
     },
@@ -1460,10 +1529,8 @@
     },
     'tab_alert_indicators': {
       'filepath': 'content/browser/media/audio_stream_monitor'\
-        '|chrome/browser/ui/cocoa/tabs/alert_indicator_button'\
-        '|chrome/browser/ui/cocoa/tabs/tab_controller\.mm'\
         '|chrome/browser/ui/tabs/tab_utils'\
-        '|chrome/browser/ui/views/tabs/alert_indicator_button'\
+        '|chrome/browser/ui/views/tabs/alert_indicator'\
         '|chrome/browser/ui/views/tabs/tab\.cc'\
         '|chrome/browser/ui/views/tabs/tab_renderer_data'\
         '|media/audio/audio_(output_controller|power_monitor)',
@@ -1512,9 +1579,7 @@
     'tether': {
       'filepath': 'chrome/browser/chromeos/tether/'\
                   '|chrome/browser/ui/ash/network/tether*'\
-                  '|chromeos/components/tether/'\
-                  '|components/cryptauth/'\
-                  '|components/proximity_auth/logging'
+                  '|chromeos/components/tether/'
     },
     'textinput': {
       'filepath': 'chrome/browser/ui/input_method'\
@@ -1575,9 +1640,6 @@
     'usb': {
       'filepath': '/usb/',
     },
-    'v4l2': {
-      'filepath': 'media/gpu/v4l2',
-    },
     'vaapi': {
       'filepath': 'media/gpu/vaapi',
     },
@@ -1709,14 +1771,17 @@
     'add_to_homescreen': ['dominickn+watch-a2hs@chromium.org',
                           'hanxi+watch@chromium.org',
                           'pkotwicz+watch@chromium.org'],
-    'android_crash_reporting': ['asvitkine+watch@chromium.org'],
+    'android_crash_reporting': ['asvitkine+watch@chromium.org',
+                                'wnwen+watch@chromium.org'],
     'android_crazy_linker': ['johnmaguire+watch@google.com'],
+    'android_deps': ['wnwen+watch@chromium.org'],
     'android_infobars': ['dfalcantara+watch@chromium.org'],
     'android_infra': ['agrieve+watch@chromium.org',
                       'estevenson+watch@chromium.org',
                       'jbudorick+watch@chromium.org'],
     'android_item_chooser_dialogs': ['juncai+watch@chromium.org',
                                      'ortuno+watch@chromium.org'],
+    'android_lint': ['wnwen+watch@chromium.org'],
     'android_loading': ['gabadie+watch@chromium.org',
                         'lizeb+watch-android-loading@chromium.org'],
     'android_media': ['mlamouri+watch-media@chromium.org'],
@@ -1740,11 +1805,11 @@
              'tfarina@chromium.org'],
     'arc': ['elijahtaylor+arcwatch@chromium.org',
             'hidehiko+watch@chromium.org',
-            'lhchavez+watch@chromium.org',
             'victorhsieh+watch@chromium.org',
             'yusukes+watch@chromium.org',
             'arc-reviews+chromium@google.com'],
     'arc_auth': ['khmel+watch@chromium.org'],
+    'arc_common': ['hashimoto+watch@chromium.org'],
     'arc_fileapi': ['nya+watch@chromium.org'],
     'arc_kiosk': ['poromov+watch@chromium.org'],
     'arc_net': ['abhishekbh@chromium.org',
@@ -1772,12 +1837,12 @@
                  'sebsg+autofillwatch@chromium.org',
                  'tmartino+autofillwatch@chromium.org',
                  'vabr+watchlistautofill@chromium.org'],
+    'autofill_assistant': ['autofill_assistant+watch@google.com'],
     'autofill_credit_cards': ['jsaul+autofillwatch@google.com'],
     'background_fetch': ['peter@chromium.org',
                          'rayankans+watch@chromium.org',
                          'nator@chromium.org'],
-    'background_sync': ['chasej+watch@chromium.org',
-                        'iclelland+watch@chromium.org',
+    'background_sync': ['iclelland+watch@chromium.org',
                         'peter@chromium.org'],
     'banners': ['dominickn+watch-banners@chromium.org',
                 'hanxi+watch@chromium.org',
@@ -1795,8 +1860,7 @@
                  'wfh+watch@chromium.org'],
     'battery_status': ['timvolodine@chromium.org'],
     'binary_size': ['agrieve+watch@chromium.org',
-                    'estevenson+watch@chromium.org',
-                    'wnwen+watch@chromium.org'],
+                    'estevenson+watch@chromium.org'],
     'blink': ['blink-reviews@chromium.org'],
     'blink_accessibility': ['aboxhall@chromium.org',
                             'dmazzoni@chromium.org',
@@ -1817,8 +1881,8 @@
     'blink_bindings_serialization': ['jbroman+watch@chromium.org'],
     'blink_bluetooth': ['mattreynolds+watch@chromium.org',
                         'ortuno+watch@chromium.org'],
-    'blink_canvas2d': ['dongseong.hwang@intel.com',
-                       'fserb@chromium.org'],
+    'blink_canvas': [ 'dongseong.hwang@intel.com',
+                      'fserb@chromium.org'],
     'blink_client_hints': ['yoav@yoav.ws'],
     'blink_clipboard': ['dcheng@chromium.org'],
     'blink_common': ['jbroman+watch@chromium.org',
@@ -1897,7 +1961,8 @@
                      'dongseong.hwang@intel.com'],
     'blink_paintworklet' : ['xidachen@chromium.org'],
     'blink_performance_timing': ['panicker+watch@chromium.org'],
-    'blink_permissions': ['mlamouri+watch-blink@chromium.org'],
+    'blink_permissions': ['mlamouri+watch-blink@chromium.org',
+                          'permissions-reviews@chromium.org'],
     'blink_platform': ['kinuko+watch@chromium.org'],
     'blink_platform_graphics': ['blink-reviews-platform-graphics@chromium.org',
                                 'dongseong.hwang@intel.com',
@@ -1928,8 +1993,7 @@
                              'shimazu+serviceworker@chromium.org'],
     'blink_service_worker_tests': ['kenjibaheux+watch@chromium.org'],
     'blink_shadow_dom': ['hayato@chromium.org'],
-    'blink_spellcheck' : ['groby+blinkspell@chromium.org',
-                          'timvolodine@chromium.org',
+    'blink_spellcheck' : ['timvolodine@chromium.org',
                           'xiaochengh+watch@chromium.org'],
     'blink_spv2_layout_tests': ['pdr+virtualspv2watchlist@chromium.org'],
     'blink_streams': ['ricea+watch@chromium.org'],
@@ -2010,8 +2074,7 @@
                    'halliwell+watch@chromium.org',
                    'lcwu+watch@chromium.org'],
     'chromecast_public': ['gfhuang+watch@chromium.org'],
-    'chromedriver': ['johnchen+watch@chromium.org',
-                     'kereliuk+watch@chromium.org'],
+    'chromedriver': ['johnchen+watch@chromium.org'],
     'chromeos': ['oshima+watch@chromium.org'],
     'chromeos_attestation': ['dkrahn+watch@chromium.org'],
     'chromeos_calculator': ['dharcourt@chromium.org'],
@@ -2020,7 +2083,8 @@
                       'bpastene+watch@chromium.org',
                       'stevenjb+watch@chromium.org'],
     'chromeos_login': ['achuith+watch@chromium.org',
-                       'alemate+watch@chromium.org'],
+                       'alemate+watch@chromium.org',
+                       'jdufault+watch@chromium.org'],
     'chromeos_net': ['stevenjb+watch@chromium.org'],
     'chromeos_power': ['derat+watch@chromium.org'],
     'chromeos_timezone': ['alemate+watch@chromium.org'],
@@ -2089,7 +2153,8 @@
     'explore_sites': ['chili+watch@chromium.org',
                       'dewittj+watch@chromium.org',
                       'dimich+watch@chromium.org',
-                      'freedjm+watch@chromium.org'],
+                      'freedjm+watch@chromium.org',
+                      'petewil+watch@chromium.org'],
     'extension': ['chromium-apps-reviews@chromium.org',
                   'extensions-reviews@chromium.org'],
     'feature_policy': ['loonybear@chromium.org',
@@ -2108,8 +2173,7 @@
     'gamepad': ['mattreynolds+watch@chromium.org'],
     'gcm': ['peter@chromium.org',
             'zea+watch@chromium.org'],
-    'generic_sensor': ['alexander.shalamov@intel.com',
-                       'juncai+watch@chromium.org',
+    'generic_sensor': ['juncai+watch@chromium.org',
                        'mattreynolds+watch@chromium.org',
                        'timvolodine@chromium.org',
                        'wanming.lin@intel.com'],
@@ -2122,15 +2186,20 @@
            'tfarina@chromium.org'],
     'gpu': ['piman+watch@chromium.org'],
     'gpu_passthrough_cmd_decoder': ['geofflang+watch@chromium.org'],
+    'guest_view': ['ekaramad@chromium.org',
+                   'mcnee@chromium.org',
+                   'wjmaclean@chromium.org'],
     'headless': ['headless-reviews@chromium.org'],
-    'history_ui': ['pam+watch@chromium.org'],
+    'history_ui': [],
     'i18n': ['jshin+watch@chromium.org'],
     'importer': ['tfarina@chromium.org'],
     'incident_reporting': ['grt+watch@chromium.org'],
     'indexed_db': ['cmumford@chromium.org',
                    'jsbell+idb@chromium.org'],
+    'infra': ['jbudorick+watch@chromium.org'],
     'ink_drop': ['bruthig+ink_drop@chromium.org'],
     'input': ['dtapuska+chromiumwatch@chromium.org'],
+    'input_devices': ['spang+watch@chromium.org'],
     'installable': ['dominickn+watch-installable@chromium.org'],
     'installer_linux': ['mmoss@chromium.org',
                         'raphael.kubo.da.costa@intel.com'],
@@ -2143,7 +2212,8 @@
                 'kmadhusu+watch@chromium.org',
                 'melevin+watch@chromium.org',
                 'samarth+watch@chromium.org',
-                'skanuj+watch@chromium.org'],
+                'skanuj+watch@chromium.org',
+                'chrome-custom-fit+reviews@google.com'],
     'ios': ['ios-reviews@chromium.org'],
     'ios_chrome': ['ios-reviews+chrome@chromium.org',
                    'noyau+watch@chromium.org',
@@ -2184,6 +2254,7 @@
     'media_controls': ['steimel+watch-mediacontrols@chromium.org'],
     'media_galleries': ['thestig@chromium.org',
                         'tommycli@chromium.org'],
+    'media_gpu': ['hiroh+watch@chromium.org'],
     'media_mojo': ['alokp+watch@chromium.org',
                    'xhwang+watch@chromium.org'],
     'media_recorder': ['emircan+watch+mediarecorder@chromium.org',
@@ -2205,11 +2276,13 @@
     'metrics_xml_files': ['asvitkine+watch@chromium.org'],
     'midi': ['toyoshim+midi@chromium.org'],
     'mojo': ['darin@chromium.org'],
-    'multidevice': ['jhawkins+watch-multidevice@chromium.org',
+    'multidevice': ['hansberry+watch-multidevice@chromium.org',
+                    'hsuregan+watch-multidevice@chromium.org',
+                    'jhawkins+watch-multidevice@chromium.org',
                     'jlklein+watch-multidevice@chromium.org',
                     'jordynass+watch-multidevice@chromium.org',
                     'khorimoto+watch-multidevice@chromium.org',
-                    'lesliewatkins+watch-multidevice@chromium.org'],
+                    'nohle+watch-multidevice@chromium.org'],
     'mus': ['rjkroege@chromium.org'],
     'nacl': ['native-client-reviews@googlegroups.com'],
     'native_client_sdk': ['binji+watch@chromium.org',
@@ -2244,11 +2317,11 @@
                       'romax+watch@chromium.org'],
     'omnibox': ['jdonnelly+watch@chromium.org'],
     'optimization_guide': ['dougarnett+watch-optguide@chromium.org',
-                           'sophiechang+watch-optguide@chromium.org',
-                           'maniscalco+watch-optguide@chromium.org'],
+                           'sophiechang+watch-optguide@chromium.org'],
     'origin_trials': ['chasej+watch@chromium.org',
                       'iclelland+watch@chromium.org'],
     'ozone': ['kalyan.kondapally@intel.com',
+              'msisov@igalia.com',
               'ozone-reviews@chromium.org'],
     'page_info' : ['raymes+watch@chromium.org'],
     'page_load_metrics' : ['bmcquade+watch@chromium.org',
@@ -2262,7 +2335,6 @@
                          'vabr+watchlistpasswordmanager@chromium.org',
                          'vasilii+watchlistpasswordmanager@chromium.org'],
     'payments': ['rouslan+payments@chromium.org',
-                 'sebsg+paymentswatch@chromium.org',
                  'gogerald+paymentswatch@chromium.org',
                  'mahmadi+paymentswatch@chromium.org',
                  'anthonyvd+paymentswatch@chromium.org'],
@@ -2276,6 +2348,7 @@
     'permissions': ['dominickn+watch-permissions@chromium.org',
                     'hanxi+watch@chromium.org',
                     'mlamouri+watch-permissions@chromium.org',
+                    'permissions-reviews@chromium.org',
                     'raymes+watch@chromium.org',
                     'timloh+watch@chromium.org'],
     'picture_in_picture': ['beaufort.francois+pip@gmail.com'],
@@ -2294,11 +2367,11 @@
     'rlz_id': ['gab+watch@chromium.org',
                'robertshield+watch@chromium.org'],
     'runtime_enabled_features': ['jmedley+watch@chromium.org'],
-    'safe_browsing': ['timvolodine@chromium.org',
+    'safe_browsing': ['drubery@chromium.org',
+                      'timvolodine@chromium.org',
                       'vakh+watch@chromium.org'],
-    'safe_browsing_db': ['timvolodine@chromium.org',
-                         'vakh+watch@chromium.org'],
     'screen_orientation': ['mlamouri+watch-screen-orientation@chromium.org'],
+    'security': ['security-watchlist@chromium.org'],
     'service_worker': ['horo+watch@chromium.org',
                        'jsbell+serviceworker@chromium.org',
                        'kinuko+serviceworker@chromium.org',
@@ -2312,12 +2385,19 @@
                       'alexmos+watch@chromium.org',
                       'creis+watch@chromium.org',
                       'nasko+codewatch@chromium.org'],
+    'smartlock': ['hansberry+watch-smartlock@chromium.org',
+                  'hsuregan+watch-multidevice@chromium.org',
+                  'jhawkins+watch-smartlock@chromium.org',
+                  'jlklein+watch-smartlock@chromium.org',
+                  'jordynass+watch-smartlock@chromium.org',
+                  'khorimoto+watch-smartlock@chromium.org',
+                  'nohle+watch-smartlock@chromium.org'],
     'smb': ['cros-enterprise-lax+smbwatch@chromium.org'],
     'source_idls': ['jmedley+watch@chromium.org'],
-    'spellcheck': ['groby+spellwatch@chromium.org',
-                   'rlp+watch@chromium.org',
+    'spellcheck': ['rlp+watch@chromium.org',
                    'rouslan+spell@chromium.org',
                    'timvolodine@chromium.org'],
+    'stack_sampling_profiler': ['chengx+watch@chromium.org'],
     'startup': ['grt+watch@chromium.org',
                 'pastarmovj+watch@chromium.org'],
     'streams': ['zork+watch@chromium.org'],
@@ -2325,7 +2405,7 @@
                    'jbroman+cpp@chromium.org',
                    'vmpstr+watch@chromium.org'],
     'subresource_filter': ['subresource-filter-reviews@chromium.org'],
-    'supervised_users': ['pam+watch@chromium.org'],
+    'supervised_users': [],
     'sync': ['sync-reviews@chromium.org'],
     'syncfs': ['kinuko+fileapi@chromium.org',
                'nhiroki@chromium.org',
@@ -2344,12 +2424,13 @@
                     'mlamouri+watch-test-runner@chromium.org',
                     'einbinder+watch-test-runner@chromium.org'],
     'tests': [],
-    'tether': ['jlklein+watch-tether@chromium.org',
+    'tether': ['hansberry+watch-tether@chromium.org',
+               'hsuregan+watch-multidevice@chromium.org',
+               'jhawkins+watch-tether@chromium.org',
+               'jlklein+watch-tether@chromium.org',
+               'jordynass+watch-tether@chromium.org',
                'khorimoto+watch-tether@chromium.org',
-               'hansberry+watch-tether@chromium.org',
-               'lesliewatkins+watch-tether@chromium.org',
-               'tengs+watch-tether@chromium.org',
-               'jhawkins+watch-tether@chromium.org'],
+               'nohle+watch-tether@chromium.org'],
     'textinput': ['nona+watch@chromium.org',
                   'shuchen+watch@chromium.org',
                   'suzhe@chromium.org',
@@ -2370,7 +2451,6 @@
     'ui_resources': ['oshima+watch@chromium.org'],
     'ui_strings': ['srahim+watch@chromium.org'],
     'usb': ['mattreynolds+watch@chromium.org'],
-    'v4l2': ['hiroh+watch@chromium.org'],
     'vaapi': ['vaapi-reviews@chromium.org'],
     'version_assembly': ['caitkp+watch@chromium.org',
                          'gab+watch@chromium.org'],
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index 04db3b4..c7cc010 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -9,6 +9,7 @@
 import("//build/config/android/config.gni")
 import("//build/config/android/rules.gni")
 import("//build/config/locales.gni")
+import("//chrome/android/trichrome.gni")
 import("//components/spellcheck/spellcheck_build_features.gni")
 import("//tools/grit/repack.gni")
 import("//tools/resources/generate_resource_whitelist.gni")
@@ -46,6 +47,7 @@
     "java/src/org/chromium/android_webview/AwCookieManager.java",
     "java/src/org/chromium/android_webview/AwDebug.java",
     "java/src/org/chromium/android_webview/AwDevToolsServer.java",
+    "java/src/org/chromium/android_webview/AwFeatureList.java",
     "java/src/org/chromium/android_webview/AwFormDatabase.java",
     "java/src/org/chromium/android_webview/AwGLFunctor.java",
     "java/src/org/chromium/android_webview/AwHttpAuthHandler.java",
@@ -106,7 +108,16 @@
 jinja_template("system_webview_manifest") {
   input = "apk/java/AndroidManifest.xml"
   output = system_webview_android_manifest
-  variables = [ "package=$system_webview_package_name" ]
+  variables = [ "manifest_package=$system_webview_package_name" ]
+}
+
+jinja_template("trichrome_webview_manifest") {
+  input = "apk/java/AndroidManifest.xml"
+  output = trichrome_webview_android_manifest
+  variables = trichrome_jinja_variables + [
+                "manifest_package=$system_webview_package_name",
+                "library=libmonochrome.so",
+              ]
 }
 
 webview_repack_locales("repack_locales") {
@@ -269,9 +280,9 @@
 
   # webui/resources has way too many resources. The whitelist is trim this down
   # to a reasonable size
-  whitelist = rebase_path("ui/grit_resources_whitelist.txt")
+  whitelist = rebase_path("ui/grit_resources_whitelist.txt", root_build_dir)
   inputs = [
-    whitelist,
+    "//android_webview/ui/grit_resources_whitelist.txt",
   ]
   grit_flags = [
     "-w",
@@ -292,9 +303,9 @@
   source_is_generated = true
 
   # See :generate_webui_resources for an explanation of the whitelist
-  whitelist = rebase_path("ui/grit_resources_whitelist.txt")
+  whitelist = rebase_path("ui/grit_resources_whitelist.txt", root_build_dir)
   inputs = [
-    whitelist,
+    "//android_webview/ui/grit_resources_whitelist.txt",
   ]
   grit_flags = [
     "-w",
@@ -317,9 +328,9 @@
   # will never display most of them, so we try to limit the included
   # strings. This whitelist trims about 50% more than the compile-based
   # whitelist generated by :system_webview_pak_whitelist.
-  whitelist = rebase_path("ui/grit_strings_whitelist.txt")
+  whitelist = rebase_path("ui/grit_strings_whitelist.txt", root_build_dir)
   inputs = [
-    whitelist,
+    "//android_webview/ui/grit_strings_whitelist.txt",
   ]
   grit_flags = [
     "-w",
@@ -443,7 +454,7 @@
     deps = [
       ":libwebviewchromium",
     ]
-    input = "$root_out_dir/libwebviewchromium$shlib_extension.whitelist"
+    input = "$root_out_dir/lib.unstripped/libwebviewchromium$shlib_extension"
     output = system_webview_pak_whitelist
   }
 }
@@ -483,6 +494,8 @@
     "browser/aw_devtools_server.h",
     "browser/aw_download_manager_delegate.cc",
     "browser/aw_download_manager_delegate.h",
+    "browser/aw_feature_list.cc",
+    "browser/aw_feature_list.h",
     "browser/aw_field_trial_creator.cc",
     "browser/aw_field_trial_creator.h",
     "browser/aw_form_database.cc",
@@ -514,6 +527,8 @@
     "browser/aw_print_manager.h",
     "browser/aw_printing_message_filter.cc",
     "browser/aw_printing_message_filter.h",
+    "browser/aw_proxying_url_loader_factory.cc",
+    "browser/aw_proxying_url_loader_factory.h",
     "browser/aw_quota_manager_bridge.cc",
     "browser/aw_quota_manager_bridge.h",
     "browser/aw_quota_permission_context.cc",
@@ -725,6 +740,7 @@
     "//components/keyed_service/content",
     "//components/metrics",
     "//components/metrics:gpu",
+    "//components/metrics:metrics",
     "//components/metrics:net",
     "//components/metrics:ui",
     "//components/minidump_uploader",
@@ -775,6 +791,7 @@
     "//net",
     "//net:extras",
     "//printing",
+    "//services/preferences/tracked:tracked",
     "//services/service_manager/public/cpp",
     "//services/viz/public/interfaces",
     "//skia",
@@ -787,6 +804,7 @@
     "//ui/gl",
     "//ui/gl/init",
     "//ui/shell_dialogs",
+    "//url",
     "//v8",
   ]
 
@@ -828,6 +846,7 @@
     "java/src/org/chromium/android_webview/AwCookieManager.java",
     "java/src/org/chromium/android_webview/AwDebug.java",
     "java/src/org/chromium/android_webview/AwDevToolsServer.java",
+    "java/src/org/chromium/android_webview/AwFeatureList.java",
     "java/src/org/chromium/android_webview/AwFormDatabase.java",
     "java/src/org/chromium/android_webview/AwGeolocationPermissions.java",
     "java/src/org/chromium/android_webview/AwGLFunctor.java",
@@ -851,6 +870,7 @@
     "java/src/org/chromium/android_webview/AwServiceWorkerController.java",
     "java/src/org/chromium/android_webview/AwServiceWorkerSettings.java",
     "java/src/org/chromium/android_webview/AwSettings.java",
+    "java/src/org/chromium/android_webview/AwSupportLibIsomorphic.java",
     "java/src/org/chromium/android_webview/AwSwitches.java",
     "java/src/org/chromium/android_webview/AwTokenBindingManager.java",
     "java/src/org/chromium/android_webview/AwTracingController.java",
@@ -899,7 +919,7 @@
     "//base:base_java",
     "//components/autofill/android:autofill_java",
     "//components/autofill/android:provider_java",
-    "//components/background_task_scheduler:background_task_scheduler_java",
+    "//components/background_task_scheduler:background_task_scheduler_task_ids_java",
     "//components/crash/android:java",
     "//components/embedder_support/android:web_contents_delegate_java",
     "//components/minidump_uploader:minidump_uploader_java",
@@ -913,7 +933,8 @@
     "//content/public/android:content_java",
     "//device/gamepad:java",
     "//net/android:net_java",
-    "//third_party/android_tools:android_support_annotations_java",
+    "//services/network/public/mojom:mojom_java",
+    "//third_party/android_deps:android_support_annotations_java",
     "//third_party/blink/public:blink_headers_java",
     "//ui/android:ui_java",
   ]
@@ -937,7 +958,9 @@
   java_files = [ "java/src/org/chromium/android_webview/VariationsUtils.java" ]
   deps = [
     "//android_webview/proto:aw_variations_seed_proto_java",
+    "//base:base_java",
     "//components/variations/android:variations_java",
+    "//third_party/protobuf:protobuf_lite_javalib",
   ]
 }
 
@@ -1002,7 +1025,7 @@
 
   deps = [
     "//base:base_java",
-    "//third_party/android_tools:android_support_annotations_java",
+    "//third_party/android_deps:android_support_annotations_java",
   ]
 
   # The appropriate .class file will be loaded via a dependency to a library
@@ -1048,8 +1071,9 @@
     ":android_webview_variations_utils_java",
     ":system_webview_manifest",
     "//base:base_java",
-    "//components/background_task_scheduler:background_task_scheduler_java",
+    "//components/background_task_scheduler:background_task_scheduler_task_ids_java",
     "//components/minidump_uploader:minidump_uploader_java",
+    "//components/variations/android:variations_java",
     "//components/version_info/android:version_constants_java",
   ]
   srcjar_deps = [
@@ -1078,12 +1102,16 @@
     version_name = chrome_version_name
     android_manifest = system_webview_android_manifest
     android_manifest_dep = ":system_webview_manifest"
-    deps = [
-      ":platform_service_bridge_upstream_implementation_java",
-      ":system_webview_resources",
-      "//android_webview/glue",
-      "//android_webview/support_library:support_lib_glue_java",
-    ]
+    deps = upstream_only_webview_deps
     apk_name = "SystemWebView"
   }
+
+  system_webview_apk_tmpl("trichrome_webview_apk") {
+    version_name = chrome_version_name
+    android_manifest = trichrome_webview_android_manifest
+    android_manifest_dep = ":trichrome_webview_manifest"
+    deps = upstream_only_webview_deps
+    apk_name = "TrichromeWebView"
+    use_trichrome_library = true
+  }
 }
diff --git a/android_webview/DEPS b/android_webview/DEPS
index 0b24be7..a522e4e 100644
--- a/android_webview/DEPS
+++ b/android_webview/DEPS
@@ -25,12 +25,15 @@
   "+jni",
   # Only this one header in media which doesn't depend on anything else.
   "+media/media_buildflags.h",
+  "+mojo/public/cpp/bindings",
   "+net",
   "+services/network/public/cpp",
+  "+services/preferences/tracked",
   "+services/service_manager/public",
   "+services/viz/public/interfaces",
   "+skia",
   "+third_party/skia/include",
+  "+third_party/boringssl/src/include",
   "+ui/android",
   "+ui/base",
   "+ui/gfx",
diff --git a/android_webview/aapt2.config b/android_webview/aapt2.config
new file mode 100644
index 0000000..6e6b76b
--- /dev/null
+++ b/android_webview/aapt2.config
@@ -0,0 +1 @@
+string/license_activity_title#no_obfuscate
diff --git a/android_webview/apk/java/AndroidManifest.xml b/android_webview/apk/java/AndroidManifest.xml
index d948a86..39f5d97 100644
--- a/android_webview/apk/java/AndroidManifest.xml
+++ b/android_webview/apk/java/AndroidManifest.xml
@@ -7,19 +7,22 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
-    package="{{package|default('com.android.webview')}}">
-    <uses-sdk android:minSdkVersion="{{minsdk|default(21)}}"
-              android:targetSdkVersion="{{targetsdk|default(28)}}">
+    package="{{manifest_package|default('com.android.webview')}}"
+    tools:ignore="MissingLeanbackLauncher">
+    <uses-sdk android:minSdkVersion="{{min_sdk_version|default(21)}}"
+              android:targetSdkVersion="{{target_sdk_version|default(28)}}">
     </uses-sdk>
 
     <uses-feature android:name="android.hardware.touchscreen"
                   android:required="false" />
+    <uses-feature android:name="android.software.leanback"
+                  android:required="false" />
 
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 
     <application android:label="Android System WebView"
-                 android:icon="@{{package|default('com.android.webview')}}:drawable/icon_webview"
+                 android:icon="@{{manifest_package|default('com.android.webview')}}:drawable/icon_webview"
                  android:name="{{ application_name|default('com.android.webview.chromium.WebViewApplication') }}"
                  android:multiArch="true"
                  android:use32bitAbi="true">
@@ -58,7 +61,7 @@
                          android:process=":webview_service" />
             {% endif %}
         {% endmacro %}
-        {{ common(package|default('com.android.webview'), library|default('libwebviewchromium.so')) }}
+        {{ common(manifest_package|default('com.android.webview'), library|default('libwebviewchromium.so')) }}
         {% if donor_package is defined %}
             <meta-data android:name="com.android.webview.WebViewDonorPackage"
                        android:value="{{ donor_package }}" />
@@ -77,5 +80,11 @@
         {% endfor %}
         <meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"
                    android:value="0" />
+        {% if trichrome_library is defined %}
+        <uses-static-library
+            android:name="{{ trichrome_library }}"
+            android:version="{{ trichrome_version }}"
+            android:certDigest="{{ trichrome_certdigest }}" />
+        {% endif %}
     </application>
 </manifest>
diff --git a/android_webview/apk/java/proguard.flags b/android_webview/apk/java/proguard.flags
index 081c39a..95fe04a 100644
--- a/android_webview/apk/java/proguard.flags
+++ b/android_webview/apk/java/proguard.flags
@@ -64,11 +64,6 @@
 }
 
 # Accessed via reflection but not present in all builds
--keep class com.android.webview.chromium.PlatformServiceBridgeGoogle {
-  void setMetricsSettingListener(...);
-  PlatformServiceBridgeGoogle(...);
-}
--dontnote com.android.webview.chromium.PlatformServiceBridgeGoogle
 -keep class com.android.webview.chromium.AwSafeBrowsingApiHandler {
   AwSafeBrowsingApiHandler(...);
 }
@@ -76,3 +71,7 @@
 
 # We strip some unused resources when preprocessing the GMS client libs.
 -dontwarn com.google.android.gms.R**
+
+# Trichrome builds don't include a native library list in the main APK; it's
+# picked up from the library APK at runtime.
+-dontwarn org.chromium.base.library_loader.NativeLibraries
diff --git a/android_webview/apk/java/src/com/android/webview/chromium/LicenseActivity.java b/android_webview/apk/java/src/com/android/webview/chromium/LicenseActivity.java
index 7427d0d..f7a4678 100644
--- a/android_webview/apk/java/src/com/android/webview/chromium/LicenseActivity.java
+++ b/android_webview/apk/java/src/com/android/webview/chromium/LicenseActivity.java
@@ -29,6 +29,9 @@
                 String.format("content://%s.%s", packageName, LICENSES_URI_SUFFIX);
         intent.setDataAndType(Uri.parse(licenseUri), LICENSES_CONTENT_TYPE);
         intent.addCategory(Intent.CATEGORY_DEFAULT);
+        // Resources are accessed via getIdentifier because resource ids in the standalone system
+        // webview apk have incorrect package_ids. Accessing resources via getIdentifier needs to be
+        // whitelisted in //android_webview/aapt2.config. see https://crbug.com/894208
         final int titleId =
                 getResources().getIdentifier("license_activity_title", "string", packageName);
         if (titleId != 0) {
diff --git a/android_webview/browser/DEPS b/android_webview/browser/DEPS
index 0b836c7..0e80ae3 100644
--- a/android_webview/browser/DEPS
+++ b/android_webview/browser/DEPS
@@ -64,11 +64,10 @@
   # AwContentBrowserClient::GetDefaultFavicon
   "!ui/resources/grit/ui_resources.h",
 
-
   # QuotaStatusCode required by AwQuotaManagerBridge.
   "+third_party/blink/public/mojom/quota",
-  # POD structure required by the find-in-page IPC messages.
-  "+third_party/blink/public/web/web_find_options.h",
   # Interface required for in-process input event handling.
-  "+third_party/blink/public/web/WebCompositorInputHandler.h"
+  "+third_party/blink/public/web/WebCompositorInputHandler.h",
+  # For find-in-page
+  "+third_party/blink/public/mojom/frame"
 ]
diff --git a/android_webview/browser/aw_autofill_client.cc b/android_webview/browser/aw_autofill_client.cc
index 929bc18..a9da842 100644
--- a/android_webview/browser/aw_autofill_client.cc
+++ b/android_webview/browser/aw_autofill_client.cc
@@ -12,6 +12,7 @@
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
 #include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
 #include "components/autofill/core/browser/autofill_popup_delegate.h"
 #include "components/autofill/core/browser/suggestion.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
@@ -39,7 +40,7 @@
 // autofill functionality at the java side. The java peer is owned by Java
 // AwContents. The native object only maintains a weak ref to it.
 AwAutofillClient::AwAutofillClient(WebContents* contents)
-    : web_contents_(contents), save_form_data_(false) {
+    : web_contents_(contents) {
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jobject> delegate;
   delegate.Reset(
@@ -75,6 +76,10 @@
   return nullptr;
 }
 
+autofill::StrikeDatabase* AwAutofillClient::GetStrikeDatabase() {
+  return nullptr;
+}
+
 ukm::UkmRecorder* AwAutofillClient::GetUkmRecorder() {
   return nullptr;
 }
@@ -184,7 +189,12 @@
 }
 
 bool AwAutofillClient::IsAutocompleteEnabled() {
-  return GetSaveFormData();
+  bool enabled = GetSaveFormData();
+  if (!autocomplete_uma_recorded_) {
+    UMA_HISTOGRAM_BOOLEAN("Autofill.AutocompleteEnabled", enabled);
+    autocomplete_uma_recorded_ = true;
+  }
+  return enabled;
 }
 
 void AwAutofillClient::PropagateAutofillPredictions(
@@ -224,10 +234,6 @@
   NOTIMPLEMENTED();
 }
 
-bool AwAutofillClient::IsAutofillSupported() {
-  return true;
-}
-
 bool AwAutofillClient::AreServerCardsSupported() {
   return true;
 }
@@ -262,7 +268,15 @@
   NOTIMPLEMENTED();
 }
 
-void AwAutofillClient::ShowLocalCardMigrationPrompt(base::OnceClosure closure) {
+void AwAutofillClient::ShowLocalCardMigrationDialog(
+    base::OnceClosure show_migration_dialog_closure) {
+  NOTIMPLEMENTED();
+}
+
+void AwAutofillClient::ConfirmMigrateLocalCardToCloud(
+    std::unique_ptr<base::DictionaryValue> legal_message,
+    const std::vector<autofill::MigratableCreditCard>& migratable_credit_cards,
+    LocalCardMigrationCallback start_migrating_cards_callback) {
   NOTIMPLEMENTED();
 }
 
@@ -276,7 +290,8 @@
 
 void AwAutofillClient::ConfirmSaveCreditCardLocally(
     const autofill::CreditCard& card,
-    const base::Closure& callback) {
+    bool show_prompt,
+    base::OnceClosure callback) {
   NOTIMPLEMENTED();
 }
 
@@ -284,6 +299,7 @@
     const autofill::CreditCard& card,
     std::unique_ptr<base::DictionaryValue> legal_message,
     bool should_request_name_from_user,
+    bool show_prompt,
     base::OnceCallback<void(const base::string16&)> callback) {
   NOTIMPLEMENTED();
 }
@@ -295,7 +311,7 @@
 }
 
 void AwAutofillClient::LoadRiskData(
-    const base::Callback<void(const std::string&)>& callback) {
+    base::OnceCallback<void(const std::string&)> callback) {
   NOTIMPLEMENTED();
 }
 
diff --git a/android_webview/browser/aw_autofill_client.h b/android_webview/browser/aw_autofill_client.h
index 1416cdc..ef7ec7d 100644
--- a/android_webview/browser/aw_autofill_client.h
+++ b/android_webview/browser/aw_autofill_client.h
@@ -13,8 +13,6 @@
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "components/autofill/core/browser/autofill_client.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/pref_service_factory.h"
 #include "content/public/browser/web_contents_user_data.h"
 #include "ui/android/view_android.h"
 
@@ -23,7 +21,9 @@
 class CardUnmaskDelegate;
 class CreditCard;
 class FormStructure;
+class MigratableCreditCard;
 class PersonalDataManager;
+class StrikeDatabase;
 }
 
 namespace content {
@@ -64,6 +64,7 @@
   PrefService* GetPrefs() override;
   syncer::SyncService* GetSyncService() override;
   identity::IdentityManager* GetIdentityManager() override;
+  autofill::StrikeDatabase* GetStrikeDatabase() override;
   ukm::UkmRecorder* GetUkmRecorder() override;
   ukm::SourceId GetUkmSourceId() override;
   autofill::AddressNormalizer* GetAddressNormalizer() override;
@@ -74,20 +75,28 @@
       UnmaskCardReason reason,
       base::WeakPtr<autofill::CardUnmaskDelegate> delegate) override;
   void OnUnmaskVerificationResult(PaymentsRpcResult result) override;
-  void ShowLocalCardMigrationPrompt(base::OnceClosure closure) override;
+  void ShowLocalCardMigrationDialog(
+      base::OnceClosure show_migration_dialog_closure) override;
+  void ConfirmMigrateLocalCardToCloud(
+      std::unique_ptr<base::DictionaryValue> legal_message,
+      const std::vector<autofill::MigratableCreditCard>&
+          migratable_credit_cards,
+      LocalCardMigrationCallback start_migrating_cards_callback) override;
   void ConfirmSaveAutofillProfile(const autofill::AutofillProfile& profile,
                                   base::OnceClosure callback) override;
   void ConfirmSaveCreditCardLocally(const autofill::CreditCard& card,
-                                    const base::Closure& callback) override;
+                                    bool show_prompt,
+                                    base::OnceClosure callback) override;
   void ConfirmSaveCreditCardToCloud(
       const autofill::CreditCard& card,
       std::unique_ptr<base::DictionaryValue> legal_message,
       bool should_request_name_from_user,
+      bool show_prompt,
       base::OnceCallback<void(const base::string16&)> callback) override;
   void ConfirmCreditCardFillAssist(const autofill::CreditCard& card,
                                    const base::Closure& callback) override;
   void LoadRiskData(
-      const base::Callback<void(const std::string&)>& callback) override;
+      base::OnceCallback<void(const std::string&)> callback) override;
   bool HasCreditCardScanFeature() override;
   void ScanCreditCard(const CreditCardScanCallback& callback) override;
   void ShowAutofillPopup(
@@ -109,7 +118,6 @@
   void DidInteractWithNonsecureCreditCardInput() override;
   bool IsContextSecure() override;
   bool ShouldShowSigninPromo() override;
-  bool IsAutofillSupported() override;
   bool AreServerCardsSupported() override;
   void ExecuteCommand(int id) override;
 
@@ -129,7 +137,7 @@
 
   // The web_contents associated with this delegate.
   content::WebContents* web_contents_;
-  bool save_form_data_;
+  bool save_form_data_ = false;
   JavaObjectWeakGlobalRef java_ref_;
 
   ui::ViewAndroid::ScopedAnchorView anchor_view_;
@@ -138,6 +146,10 @@
   std::vector<autofill::Suggestion> suggestions_;
   base::WeakPtr<autofill::AutofillPopupDelegate> delegate_;
 
+  // Tracks whether the autocomplete enabled metric has already been logged for
+  // this client.
+  bool autocomplete_uma_recorded_ = false;
+
   DISALLOW_COPY_AND_ASSIGN(AwAutofillClient);
 };
 
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc
index fd7369c..cb6a5e5 100644
--- a/android_webview/browser/aw_browser_context.cc
+++ b/android_webview/browser/aw_browser_context.cc
@@ -5,9 +5,9 @@
 #include "android_webview/browser/aw_browser_context.h"
 
 #include <memory>
+#include <string>
 #include <utility>
 
-#include "android_webview/browser/aw_browser_policy_connector.h"
 #include "android_webview/browser/aw_download_manager_delegate.h"
 #include "android_webview/browser/aw_form_database_service.h"
 #include "android_webview/browser/aw_metrics_service_client.h"
@@ -17,32 +17,25 @@
 #include "android_webview/browser/aw_safe_browsing_whitelist_manager.h"
 #include "android_webview/browser/aw_web_ui_controller_factory.h"
 #include "android_webview/browser/net/aw_url_request_context_getter.h"
-#include "android_webview/common/aw_content_client.h"
-#include "base/base_paths_android.h"
+#include "base/base_paths_posix.h"
 #include "base/bind.h"
 #include "base/path_service.h"
 #include "base/single_thread_task_runner.h"
 #include "base/task/post_task.h"
-#include "components/autofill/core/common/autofill_prefs.h"
-#include "components/metrics/metrics_service.h"
 #include "components/policy/core/browser/browser_policy_connector_base.h"
-#include "components/policy/core/browser/configuration_policy_pref_store.h"
-#include "components/policy/core/browser/url_blacklist_manager.h"
-#include "components/pref_registry/pref_registry_syncable.h"
-#include "components/prefs/in_memory_pref_store.h"
 #include "components/prefs/pref_service.h"
-#include "components/prefs/pref_service_factory.h"
-#include "components/safe_browsing/common/safe_browsing_prefs.h"
 #include "components/safe_browsing/triggers/trigger_manager.h"
 #include "components/url_formatter/url_fixer.h"
 #include "components/user_prefs/user_prefs.h"
 #include "components/visitedlink/browser/visitedlink_master.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/ssl_host_state_delegate.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
 #include "net/proxy_resolution/proxy_config_service_android.h"
 #include "net/proxy_resolution/proxy_resolution_service.h"
+#include "services/preferences/tracked/segregated_pref_store.h"
 
 using base::FilePath;
 using content::BrowserThread;
@@ -69,16 +62,12 @@
 
 const void* const kDownloadManagerDelegateKey = &kDownloadManagerDelegateKey;
 
-// Shows notifications which correspond to PersistentPrefStore's reading errors.
-void HandleReadError(PersistentPrefStore::PrefReadError error) {
-}
-
 AwBrowserContext* g_browser_context = NULL;
 
 std::unique_ptr<net::ProxyConfigServiceAndroid> CreateProxyConfigService() {
   std::unique_ptr<net::ProxyConfigServiceAndroid> config_service_android =
       std::make_unique<net::ProxyConfigServiceAndroid>(
-          BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+          base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
           base::ThreadTaskRunnerHandle::Get());
 
   // TODO(csharrison) Architect the wrapper better so we don't need a cast for
@@ -94,27 +83,27 @@
       base::CreateSequencedTaskRunnerWithTraits(
           {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
   scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
-      BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+      base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO});
   return std::make_unique<AwSafeBrowsingWhitelistManager>(
       background_task_runner, io_task_runner);
 }
 
-base::FilePath GetCacheDirForAw() {
-  FilePath cache_path;
-  base::PathService::Get(base::DIR_CACHE, &cache_path);
-  cache_path =
-      cache_path.Append(FILE_PATH_LITERAL("org.chromium.android_webview"));
-  return cache_path;
-}
-
 }  // namespace
 
-AwBrowserContext::AwBrowserContext(const FilePath path)
-    : context_storage_path_(path) {
+AwBrowserContext::AwBrowserContext(
+    const base::FilePath path,
+    std::unique_ptr<PrefService> pref_service,
+    std::unique_ptr<policy::BrowserPolicyConnectorBase> policy_connector)
+    : context_storage_path_(path),
+      user_pref_service_(std::move(pref_service)),
+      browser_policy_connector_(std::move(policy_connector)) {
   DCHECK(!g_browser_context);
   g_browser_context = this;
   BrowserContext::Initialize(this, path);
 
+  pref_change_registrar_.Init(user_pref_service_.get());
+  user_prefs::UserPrefs::Set(this, user_pref_service_.get());
+
   // This constructor is entered during the creation of ContentBrowserClient,
   // before browser threads are created. Therefore any checks to enforce
   // threading (such as BrowserThread::CurrentlyOn()) will fail here.
@@ -139,12 +128,17 @@
   return static_cast<AwBrowserContext*>(web_contents->GetBrowserContext());
 }
 
+// static
+base::FilePath AwBrowserContext::GetCacheDir() {
+  FilePath cache_path;
+  base::PathService::Get(base::DIR_CACHE, &cache_path);
+  cache_path =
+      cache_path.Append(FILE_PATH_LITERAL("org.chromium.android_webview"));
+  return cache_path;
+}
+
 void AwBrowserContext::PreMainMessageLoopRun(net::NetLog* net_log) {
-  FilePath cache_path = GetCacheDirForAw();
-
-  browser_policy_connector_.reset(new AwBrowserPolicyConnector());
-
-  InitUserPrefService();
+  FilePath cache_path = GetCacheDir();
 
   url_request_context_getter_ = new AwURLRequestContextGetter(
       cache_path, context_storage_path_.Append(kChannelIDFilename),
@@ -163,11 +157,6 @@
 
   EnsureResourceContextInitialized(this);
 
-  AwMetricsServiceClient::GetInstance()->Initialize(
-      user_pref_service_.get(),
-      content::BrowserContext::GetDefaultStoragePartition(this)
-          ->GetURLRequestContext());
-
   web_restriction_provider_.reset(
       new web_restrictions::WebRestrictionsClient());
   pref_change_registrar_.Add(
@@ -217,46 +206,12 @@
   return url_request_context_getter_.get();
 }
 
-// Create user pref service
-void AwBrowserContext::InitUserPrefService() {
-  user_prefs::PrefRegistrySyncable* pref_registry =
-      new user_prefs::PrefRegistrySyncable();
-  // We only use the autocomplete feature of Autofill, which is controlled via
-  // the manager_delegate. We don't use the rest of Autofill, which is why it is
-  // hardcoded as disabled here.
-  pref_registry->RegisterBooleanPref(autofill::prefs::kAutofillEnabled, false);
-  policy::URLBlacklistManager::RegisterProfilePrefs(pref_registry);
-
-  pref_registry->RegisterStringPref(prefs::kWebRestrictionsAuthority,
-                                    std::string());
-
-  AwURLRequestContextGetter::RegisterPrefs(pref_registry);
-  metrics::MetricsService::RegisterPrefs(pref_registry);
-  safe_browsing::RegisterProfilePrefs(pref_registry);
-
-  PrefServiceFactory pref_service_factory;
-  pref_service_factory.set_user_prefs(
-      base::MakeRefCounted<InMemoryPrefStore>());
-  pref_service_factory.set_managed_prefs(
-      base::MakeRefCounted<policy::ConfigurationPolicyPrefStore>(
-          browser_policy_connector_.get(),
-          browser_policy_connector_->GetPolicyService(),
-          browser_policy_connector_->GetHandlerList(),
-          policy::POLICY_LEVEL_MANDATORY));
-  pref_service_factory.set_read_error_callback(
-      base::BindRepeating(&HandleReadError));
-  user_pref_service_ = pref_service_factory.Create(pref_registry);
-  pref_change_registrar_.Init(user_pref_service_.get());
-
-  user_prefs::UserPrefs::Set(this, user_pref_service_.get());
-}
-
 base::FilePath AwBrowserContext::GetPath() const {
   return context_storage_path_;
 }
 
 base::FilePath AwBrowserContext::GetCachePath() const {
-  return GetCacheDirForAw();
+  return GetCacheDir();
 }
 
 bool AwBrowserContext::IsOffTheRecord() const {
diff --git a/android_webview/browser/aw_browser_context.h b/android_webview/browser/aw_browser_context.h
index 7fc8783..7dcbf5f 100644
--- a/android_webview/browser/aw_browser_context.h
+++ b/android_webview/browser/aw_browser_context.h
@@ -19,8 +19,6 @@
 #include "components/visitedlink/browser/visitedlink_delegate.h"
 #include "components/web_restrictions/browser/web_restrictions_client.h"
 #include "content/public/browser/browser_context.h"
-#include "content/public/browser/content_browser_client.h"
-#include "net/url_request/url_request_job_factory.h"
 
 class GURL;
 class PrefService;
@@ -67,7 +65,10 @@
 class AwBrowserContext : public content::BrowserContext,
                          public visitedlink::VisitedLinkDelegate {
  public:
-  AwBrowserContext(const base::FilePath path);
+  AwBrowserContext(
+      const base::FilePath path,
+      std::unique_ptr<PrefService> pref_service,
+      std::unique_ptr<policy::BrowserPolicyConnectorBase> policy_connector);
   ~AwBrowserContext() override;
 
   // Currently only one instance per process is supported.
@@ -78,6 +79,8 @@
   static AwBrowserContext* FromWebContents(
       content::WebContents* web_contents);
 
+  static base::FilePath GetCacheDir();
+
   // Maps to BrowserMainParts::PreMainMessageLoopRun.
   void PreMainMessageLoopRun(net::NetLog* net_log);
 
@@ -128,7 +131,6 @@
   AwSafeBrowsingWhitelistManager* GetSafeBrowsingWhitelistManager() const;
 
  private:
-  void InitUserPrefService();
   void OnWebRestrictionsAuthorityChanged();
 
   // The file path where data for this context is persisted.
diff --git a/android_webview/browser/aw_browser_main_parts.cc b/android_webview/browser/aw_browser_main_parts.cc
index 4a37cc9f..6c5e7db 100644
--- a/android_webview/browser/aw_browser_main_parts.cc
+++ b/android_webview/browser/aw_browser_main_parts.cc
@@ -5,12 +5,17 @@
 #include "android_webview/browser/aw_browser_main_parts.h"
 
 #include <memory>
+#include <set>
+#include <string>
+#include <utility>
 
 #include "android_webview/browser/aw_browser_context.h"
+#include "android_webview/browser/aw_browser_policy_connector.h"
 #include "android_webview/browser/aw_browser_terminator.h"
 #include "android_webview/browser/aw_content_browser_client.h"
 #include "android_webview/browser/aw_metrics_service_client.h"
 #include "android_webview/browser/net/aw_network_change_notifier_factory.h"
+#include "android_webview/browser/net/aw_url_request_context_getter.h"
 #include "android_webview/common/aw_descriptors.h"
 #include "android_webview/common/aw_paths.h"
 #include "android_webview/common/aw_resource.h"
@@ -18,18 +23,30 @@
 #include "android_webview/common/crash_reporter/aw_crash_reporter_client.h"
 #include "base/android/apk_assets.h"
 #include "base/android/build_info.h"
-#include "base/android/locale_utils.h"
 #include "base/android/memory_pressure_listener_android.h"
+#include "base/base_paths_android.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/i18n/rtl.h"
 #include "base/message_loop/message_loop.h"
 #include "base/message_loop/message_loop_current.h"
 #include "base/path_service.h"
+#include "components/autofill/core/common/autofill_prefs.h"
 #include "components/crash/content/browser/child_exit_observer_android.h"
 #include "components/crash/content/browser/crash_dump_manager_android.h"
 #include "components/heap_profiling/supervisor.h"
+#include "components/metrics/metrics_pref_names.h"
+#include "components/metrics/metrics_service.h"
+#include "components/policy/core/browser/configuration_policy_pref_store.h"
+#include "components/policy/core/browser/url_blacklist_manager.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/prefs/in_memory_pref_store.h"
+#include "components/prefs/json_pref_store.h"
+#include "components/prefs/pref_service_factory.h"
 #include "components/services/heap_profiling/public/cpp/settings.h"
+#include "components/user_prefs/user_prefs.h"
+#include "components/variations/pref_names.h"
+#include "components/variations/service/variations_service.h"
 #include "content/public/browser/android/synchronous_compositor.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
@@ -40,14 +57,85 @@
 #include "content/public/common/service_names.mojom.h"
 #include "net/android/network_change_notifier_factory_android.h"
 #include "net/base/network_change_notifier.h"
+#include "services/preferences/tracked/segregated_pref_store.h"
 #include "services/service_manager/public/cpp/connector.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/layout.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/base/resource/resource_bundle_android.h"
-#include "ui/base/ui_base_paths.h"
 #include "ui/gl/gl_surface.h"
 
+namespace {
+
+// These prefs go in the JsonPrefStore, and will persist across runs. Other
+// prefs go in the InMemoryPrefStore, and will be lost when the process ends.
+const char* const kPersistentPrefsWhitelist[] = {
+    // Random seed value for variation's entropy providers, used to assign
+    // experiment groups.
+    metrics::prefs::kMetricsLowEntropySource,
+    // Used by CachingPermutedEntropyProvider to cache generated values.
+    variations::prefs::kVariationsPermutedEntropyCache,
+};
+
+// Shows notifications which correspond to PersistentPrefStore's reading errors.
+void HandleReadError(PersistentPrefStore::PrefReadError error) {}
+
+base::FilePath GetPrefStorePath() {
+  base::FilePath path;
+  base::PathService::Get(base::DIR_ANDROID_APP_DATA, &path);
+  path = path.Append(FILE_PATH_LITERAL("pref_store"));
+  return path;
+}
+
+std::unique_ptr<PrefService> CreatePrefService(
+    policy::BrowserPolicyConnectorBase* browser_policy_connector) {
+  auto pref_registry = base::MakeRefCounted<user_prefs::PrefRegistrySyncable>();
+  // We only use the autocomplete feature of Autofill, which is controlled via
+  // the manager_delegate. We don't use the rest of Autofill, which is why it is
+  // hardcoded as disabled here.
+  // TODO(crbug.com/873740): The following also disables autocomplete.
+  // Investigate what the intended behavior is.
+  pref_registry->RegisterBooleanPref(autofill::prefs::kAutofillProfileEnabled,
+                                     false);
+  pref_registry->RegisterBooleanPref(
+      autofill::prefs::kAutofillCreditCardEnabled, false);
+  policy::URLBlacklistManager::RegisterProfilePrefs(pref_registry.get());
+
+  pref_registry->RegisterStringPref(
+      android_webview::prefs::kWebRestrictionsAuthority, std::string());
+
+  android_webview::AwURLRequestContextGetter::RegisterPrefs(
+      pref_registry.get());
+  metrics::MetricsService::RegisterPrefs(pref_registry.get());
+  variations::VariationsService::RegisterPrefs(pref_registry.get());
+  safe_browsing::RegisterProfilePrefs(pref_registry.get());
+
+  PrefServiceFactory pref_service_factory;
+
+  std::set<std::string> persistent_prefs;
+  for (const char* const pref_name : kPersistentPrefsWhitelist)
+    persistent_prefs.insert(pref_name);
+
+  // SegregatedPrefStore may be validated with a MAC (message authentication
+  // code). On Android, the store is protected by app sandboxing, so validation
+  // is unnnecessary. Thus validation_delegate is null.
+  pref_service_factory.set_user_prefs(
+      base::MakeRefCounted<SegregatedPrefStore>(
+          base::MakeRefCounted<InMemoryPrefStore>(),
+          base::MakeRefCounted<JsonPrefStore>(GetPrefStorePath()),
+          persistent_prefs, /*validation_delegate=*/nullptr));
+  pref_service_factory.set_managed_prefs(
+      base::MakeRefCounted<policy::ConfigurationPolicyPrefStore>(
+          browser_policy_connector,
+          browser_policy_connector->GetPolicyService(),
+          browser_policy_connector->GetHandlerList(),
+          policy::POLICY_LEVEL_MANDATORY));
+  pref_service_factory.set_read_error_callback(
+      base::BindRepeating(&HandleReadError));
+
+  return pref_service_factory.Create(pref_registry);
+}
+
+}  // namespace
+
 namespace android_webview {
 
 AwBrowserMainParts::AwBrowserMainParts(AwContentBrowserClient* browser_client)
@@ -57,11 +145,6 @@
 AwBrowserMainParts::~AwBrowserMainParts() {
 }
 
-bool AwBrowserMainParts::ShouldContentCreateFeatureList() {
-  // FeatureList will be created in AwFieldTrialCreator.
-  return false;
-}
-
 int AwBrowserMainParts::PreEarlyInitialization() {
   // Network change notifier factory must be singleton, only set factory
   // instance while it is not been created.
@@ -82,23 +165,6 @@
 }
 
 int AwBrowserMainParts::PreCreateThreads() {
-  ui::SetLocalePaksStoredInApk(true);
-  std::string locale = ui::ResourceBundle::InitSharedInstanceWithLocale(
-      base::android::GetDefaultLocaleString(), NULL,
-      ui::ResourceBundle::LOAD_COMMON_RESOURCES);
-  if (locale.empty()) {
-    LOG(WARNING) << "Failed to load locale .pak from the apk. "
-        "Bringing up WebView without any locale";
-  }
-  base::i18n::SetICUDefaultLocale(locale);
-
-  // Try to directly mmap the resources.pak from the apk. Fall back to load
-  // from file, using PATH_SERVICE, otherwise.
-  base::FilePath pak_file_path;
-  base::PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &pak_file_path);
-  pak_file_path = pak_file_path.AppendASCII("resources.pak");
-  ui::LoadMainAndroidPackFile("assets/resources.pak", pak_file_path);
-
   base::android::MemoryPressureListenerAndroid::Initialize(
       base::android::AttachCurrentThread());
   ::crash_reporter::ChildExitObserver::Create();
@@ -129,14 +195,20 @@
         std::make_unique<AwBrowserTerminator>(crash_dir));
   }
 
-  aw_field_trial_creator_.SetUpFieldTrials();
+  browser_policy_connector_ = std::make_unique<AwBrowserPolicyConnector>();
+  pref_service_ = CreatePrefService(browser_policy_connector_.get());
+  AwMetricsServiceClient::GetInstance()->Initialize(pref_service_.get());
+  aw_field_trial_creator_.SetUpFieldTrials(pref_service_.get());
 
   return service_manager::RESULT_CODE_NORMAL_EXIT;
 }
 
 void AwBrowserMainParts::PreMainMessageLoopRun() {
-  browser_client_->InitBrowserContext()->PreMainMessageLoopRun(
-      browser_client_->GetNetLog());
+  DCHECK(pref_service_);
+  DCHECK(browser_policy_connector_);
+  AwBrowserContext* context = browser_client_->InitBrowserContext(
+      std::move(pref_service_), std::move(browser_policy_connector_));
+  context->PreMainMessageLoopRun(browser_client_->GetNetLog());
 
   content::RenderFrameHost::AllowInjectingJavaScriptForAndroidWebView();
 }
diff --git a/android_webview/browser/aw_browser_main_parts.h b/android_webview/browser/aw_browser_main_parts.h
index 22ddfcd..e5eca00 100644
--- a/android_webview/browser/aw_browser_main_parts.h
+++ b/android_webview/browser/aw_browser_main_parts.h
@@ -16,6 +16,10 @@
 class MessageLoop;
 }
 
+namespace policy {
+class BrowserPolicyConnectorBase;
+}
+
 namespace android_webview {
 
 class AwContentBrowserClient;
@@ -26,7 +30,6 @@
   ~AwBrowserMainParts() override;
 
   // Overriding methods from content::BrowserMainParts.
-  bool ShouldContentCreateFeatureList() override;
   int PreEarlyInitialization() override;
   int PreCreateThreads() override;
   void PreMainMessageLoopRun() override;
@@ -38,6 +41,11 @@
   // Android specific UI MessageLoop.
   std::unique_ptr<base::MessageLoop> main_message_loop_;
 
+  // Created and temporarily owned by AwBrowserMainParts
+  // until ownership is transferred to AwBrowserContext.
+  std::unique_ptr<PrefService> pref_service_;
+  std::unique_ptr<policy::BrowserPolicyConnectorBase> browser_policy_connector_;
+
   AwContentBrowserClient* browser_client_;
 
   // Responsible for creating a feature list from the seed. This object must
diff --git a/android_webview/browser/aw_browser_terminator.cc b/android_webview/browser/aw_browser_terminator.cc
index d8373e8..8347981 100644
--- a/android_webview/browser/aw_browser_terminator.cc
+++ b/android_webview/browser/aw_browser_terminator.cc
@@ -15,6 +15,8 @@
 #include "base/stl_util.h"
 #include "base/sync_socket.h"
 #include "base/task/post_task.h"
+#include "components/crash/content/browser/crash_dump_manager_android.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_data.h"
 #include "content/public/browser/child_process_launcher_utils.h"
@@ -152,8 +154,8 @@
     crashed = true;
   }
 
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::UI},
       base::BindOnce(&OnRenderProcessGoneDetail, info.process_host_id, info.pid,
                      crashed));
 }
diff --git a/android_webview/browser/aw_browser_terminator.h b/android_webview/browser/aw_browser_terminator.h
index 047fb7c..e3f7e9d 100644
--- a/android_webview/browser/aw_browser_terminator.h
+++ b/android_webview/browser/aw_browser_terminator.h
@@ -9,7 +9,6 @@
 
 #include "base/synchronization/lock.h"
 #include "components/crash/content/browser/child_exit_observer_android.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
 
 namespace base {
 class SyncSocket;
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index ce2403f..cad572a 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -4,7 +4,9 @@
 
 #include "android_webview/browser/aw_content_browser_client.h"
 
+#include <string>
 #include <utility>
+#include <vector>
 
 #include "android_webview/browser/aw_browser_context.h"
 #include "android_webview/browser/aw_browser_main_parts.h"
@@ -15,6 +17,7 @@
 #include "android_webview/browser/aw_devtools_manager_delegate.h"
 #include "android_webview/browser/aw_login_delegate.h"
 #include "android_webview/browser/aw_printing_message_filter.h"
+#include "android_webview/browser/aw_proxying_url_loader_factory.h"
 #include "android_webview/browser/aw_quota_permission_context.h"
 #include "android_webview/browser/aw_settings.h"
 #include "android_webview/browser/aw_url_checker_delegate_impl.h"
@@ -38,18 +41,22 @@
 #include "base/json/json_reader.h"
 #include "base/memory/ptr_util.h"
 #include "base/path_service.h"
+#include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
 #include "components/autofill/content/browser/content_autofill_driver_factory.h"
 #include "components/cdm/browser/cdm_message_filter_android.h"
 #include "components/crash/content/browser/child_exit_observer_android.h"
 #include "components/navigation_interception/intercept_navigation_delegate.h"
 #include "components/policy/content/policy_blacklist_navigation_throttle.h"
+#include "components/policy/core/browser/browser_policy_connector_base.h"
 #include "components/safe_browsing/browser/browser_url_loader_throttle.h"
 #include "components/safe_browsing/browser/mojo_safe_browsing_impl.h"
 #include "components/safe_browsing/features.h"
 #include "components/services/heap_profiling/public/mojom/constants.mojom.h"
 #include "components/spellcheck/spellcheck_buildflags.h"
 #include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_security_policy.h"
 #include "content/public/browser/client_certificate_delegate.h"
@@ -213,12 +220,15 @@
 
 AwContentBrowserClient::~AwContentBrowserClient() {}
 
-AwBrowserContext* AwContentBrowserClient::InitBrowserContext() {
+AwBrowserContext* AwContentBrowserClient::InitBrowserContext(
+    std::unique_ptr<PrefService> pref_service,
+    std::unique_ptr<policy::BrowserPolicyConnectorBase> policy_connector) {
   base::FilePath user_data_dir;
   if (!base::PathService::Get(base::DIR_ANDROID_APP_DATA, &user_data_dir)) {
     NOTREACHED() << "Failed to get app data directory for Android WebView";
   }
-  browser_context_.reset(new AwBrowserContext(user_data_dir));
+  browser_context_ = std::make_unique<AwBrowserContext>(
+      user_data_dir, std::move(pref_service), std::move(policy_connector));
   return browser_context_.get();
 }
 
@@ -275,7 +285,7 @@
     // even if access to file: scheme is not granted to the child process.
     return !IsAndroidSpecialFileUrl(url);
   }
-  for (size_t i = 0; i < arraysize(kProtocolList); ++i) {
+  for (size_t i = 0; i < base::size(kProtocolList); ++i) {
     if (scheme == kProtocolList[i])
       return true;
   }
@@ -354,16 +364,15 @@
 void AwContentBrowserClient::AllowWorkerFileSystem(
     const GURL& url,
     content::ResourceContext* context,
-    const std::vector<std::pair<int, int> >& render_frames,
+    const std::vector<content::GlobalFrameRoutingId>& render_frames,
     base::Callback<void(bool)> callback) {
   callback.Run(true);
 }
 
 bool AwContentBrowserClient::AllowWorkerIndexedDB(
     const GURL& url,
-    const base::string16& name,
     content::ResourceContext* context,
-    const std::vector<std::pair<int, int> >& render_frames) {
+    const std::vector<content::GlobalFrameRoutingId>& render_frames) {
   return true;
 }
 
@@ -380,6 +389,16 @@
       partition->GetPath(), context->IsOffTheRecord(), std::move(callback));
 }
 
+content::GeneratedCodeCacheSettings
+AwContentBrowserClient::GetGeneratedCodeCacheSettings(
+    content::BrowserContext* context) {
+  // If we pass 0 for size, disk_cache will pick a default size using the
+  // heuristics based on available disk size. These are implemented in
+  // disk_cache::PreferredCacheSize in net/disk_cache/cache_util.cc.
+  return content::GeneratedCodeCacheSettings(true, 0,
+                                             AwBrowserContext::GetCacheDir());
+}
+
 void AwContentBrowserClient::AllowCertificateError(
     content::WebContents* web_contents,
     int cert_error,
@@ -599,12 +618,12 @@
             base::BindRepeating(
                 &AwContentBrowserClient::GetSafeBrowsingUrlCheckerDelegate,
                 base::Unretained(this))),
-        BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+        base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
   }
 #if BUILDFLAG(ENABLE_SPELLCHECK)
   registry->AddInterface(
       base::BindRepeating(&SpellCheckHostImpl::Create),
-      BrowserThread::GetTaskRunnerForThread(BrowserThread::UI));
+      base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}));
 #endif
 }
 
@@ -714,9 +733,9 @@
     scoped_refptr<net::HttpResponseHeaders> response_headers,
     bool first_auth_attempt,
     LoginAuthRequiredCallback auth_required_callback) {
-  return base::MakeRefCounted<AwLoginDelegate>(
-      auth_info, web_contents_getter, first_auth_attempt,
-      std::move(auth_required_callback));
+  return AwLoginDelegate::Create(auth_info, web_contents_getter,
+                                 first_auth_attempt,
+                                 std::move(auth_required_callback));
 }
 
 bool AwContentBrowserClient::HandleExternalProtocol(
@@ -739,6 +758,42 @@
       base::BindRepeating(&base::ASCIIToUTF16, "Heap Profiling Service");
 }
 
+bool AwContentBrowserClient::ShouldIsolateErrorPage(bool in_main_frame) {
+  return false;
+}
+
+bool AwContentBrowserClient::ShouldEnableStrictSiteIsolation() {
+  // TODO(lukasza): When/if we eventually add OOPIF support for AW we should
+  // consider running AW tests with and without site-per-process (and this might
+  // require returning true below).  Adding OOPIF support for AW is tracked by
+  // https://crbug.com/869494.
+  return false;
+}
+
+bool AwContentBrowserClient::WillCreateURLLoaderFactory(
+    content::BrowserContext* browser_context,
+    content::RenderFrameHost* frame,
+    bool is_navigation,
+    const url::Origin& request_initiator,
+    network::mojom::URLLoaderFactoryRequest* factory_request,
+    bool* bypass_redirect_checks) {
+  DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  auto proxied_request = std::move(*factory_request);
+  network::mojom::URLLoaderFactoryPtrInfo target_factory_info;
+  *factory_request = mojo::MakeRequest(&target_factory_info);
+  int process_id = is_navigation ? 0 : frame->GetProcess()->GetID();
+
+  // Android WebView has one non off-the-record browser context.
+  base::PostTaskWithTraits(
+      FROM_HERE, {content::BrowserThread::IO},
+      base::BindOnce(&AwProxyingURLLoaderFactory::CreateProxy, process_id,
+                     std::move(proxied_request), std::move(target_factory_info),
+                     nullptr /* AwInterceptedRequestHandler */));
+  return true;
+}
+
 // static
 void AwContentBrowserClient::DisableCreatingTaskScheduler() {
   g_should_create_task_scheduler = false;
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index cca2d26..1d1a5ee 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -8,6 +8,8 @@
 #include <stddef.h>
 
 #include <memory>
+#include <string>
+#include <vector>
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
@@ -15,6 +17,8 @@
 #include "content/public/browser/content_browser_client.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
 
+class PrefService;
+
 namespace content {
 class RenderFrameHost;
 }
@@ -23,6 +27,10 @@
 class NetLog;
 }
 
+namespace policy {
+class BrowserPolicyConnectorBase;
+}
+
 namespace safe_browsing {
 class UrlCheckerDelegate;
 }
@@ -44,7 +52,9 @@
 
   // Allows AwBrowserMainParts to initialize a BrowserContext at the right
   // moment during startup. AwContentBrowserClient owns the result.
-  AwBrowserContext* InitBrowserContext();
+  AwBrowserContext* InitBrowserContext(
+      std::unique_ptr<PrefService> pref_service,
+      std::unique_ptr<policy::BrowserPolicyConnectorBase> policy_connector);
 
   content::BrowserMainParts* CreateBrowserMainParts(
       const content::MainFunctionParams& parameters) override;
@@ -79,18 +89,19 @@
   void AllowWorkerFileSystem(
       const GURL& url,
       content::ResourceContext* context,
-      const std::vector<std::pair<int, int>>& render_frames,
+      const std::vector<content::GlobalFrameRoutingId>& render_frames,
       base::Callback<void(bool)> callback) override;
   bool AllowWorkerIndexedDB(
       const GURL& url,
-      const base::string16& name,
       content::ResourceContext* context,
-      const std::vector<std::pair<int, int>>& render_frames) override;
+      const std::vector<content::GlobalFrameRoutingId>& render_frames) override;
   content::QuotaPermissionContext* CreateQuotaPermissionContext() override;
   void GetQuotaSettings(
       content::BrowserContext* context,
       content::StoragePartition* partition,
       storage::OptionalQuotaSettingsCallback callback) override;
+  content::GeneratedCodeCacheSettings GetGeneratedCodeCacheSettings(
+      content::BrowserContext* context) override;
   void AllowCertificateError(
       content::WebContents* web_contents,
       int cert_error,
@@ -191,6 +202,15 @@
       ui::PageTransition page_transition,
       bool has_user_gesture) override;
   void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override;
+  bool ShouldIsolateErrorPage(bool in_main_frame) override;
+  bool ShouldEnableStrictSiteIsolation() override;
+  bool WillCreateURLLoaderFactory(
+      content::BrowserContext* browser_context,
+      content::RenderFrameHost* frame,
+      bool is_navigation,
+      const url::Origin& request_initiator,
+      network::mojom::URLLoaderFactoryRequest* factory_request,
+      bool* bypass_redirect_checks) override;
 
   static void DisableCreatingTaskScheduler();
 
diff --git a/android_webview/browser/aw_contents.cc b/android_webview/browser/aw_contents.cc
index 6e4d9f4..0cf07c5c 100644
--- a/android_webview/browser/aw_contents.cc
+++ b/android_webview/browser/aw_contents.cc
@@ -50,10 +50,12 @@
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/memory/memory_pressure_listener.h"
+#include "base/no_destructor.h"
 #include "base/pickle.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string16.h"
 #include "base/supports_user_data.h"
+#include "base/task/post_task.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/autofill/android/autofill_provider_android.h"
@@ -63,6 +65,7 @@
 #include "components/navigation_interception/intercept_navigation_delegate.h"
 #include "content/public/browser/android/child_process_importance.h"
 #include "content/public/browser/android/synchronous_compositor.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/browsing_data_remover.h"
 #include "content/public/browser/child_process_security_policy.h"
@@ -114,13 +117,13 @@
 bool g_should_download_favicons = false;
 
 std::string* g_locale() {
-  CR_DEFINE_STATIC_LOCAL(std::string, locale, ());
-  return &locale;
+  static base::NoDestructor<std::string> locale;
+  return locale.get();
 }
 
 std::string* g_locale_list() {
-  CR_DEFINE_STATIC_LOCAL(std::string, locale_list, ());
-  return &locale_list;
+  static base::NoDestructor<std::string> locale_list;
+  return locale_list.get();
 }
 
 const void* const kAwContentsUserDataKey = &kAwContentsUserDataKey;
@@ -235,7 +238,7 @@
       functor_(nullptr),
       browser_view_renderer_(
           this,
-          BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)),
+          base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI})),
       web_contents_(std::move(web_contents)),
       renderer_manager_key_(GLViewRendererManager::GetInstance()->NullKey()) {
   base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, 1);
@@ -586,8 +589,8 @@
                                  const GURL& origin) {
   JNIEnv* env = AttachCurrentThread();
   if (java_ref.get(env).obj()) {
-    content::BrowserThread::PostTask(
-        content::BrowserThread::UI, FROM_HERE,
+    base::PostTaskWithTraits(
+        FROM_HERE, {content::BrowserThread::UI},
         base::BindOnce(&ShowGeolocationPromptHelperTask, java_ref, origin));
   }
 }
@@ -1123,7 +1126,7 @@
     return gfx::Point();
   std::vector<int> location;
   base::android::JavaIntArrayToIntVector(
-      env, Java_AwContents_getLocationOnScreen(env, obj).obj(), &location);
+      env, Java_AwContents_getLocationOnScreen(env, obj), &location);
   return gfx::Point(location[0], location[1]);
 }
 
@@ -1403,6 +1406,7 @@
                                navigation_handle->IsInMainFrame(),
                                navigation_handle->HasUserGesture(),
                                net::HttpRequestHeaders());
+  request.is_renderer_initiated = navigation_handle->IsRendererInitiated();
 
   client->OnReceivedError(request, error_code, false);
 }
diff --git a/android_webview/browser/aw_contents.h b/android_webview/browser/aw_contents.h
index dc5bcc9..a621d32 100644
--- a/android_webview/browser/aw_contents.h
+++ b/android_webview/browser/aw_contents.h
@@ -19,8 +19,6 @@
 #include "android_webview/browser/gl_view_renderer_manager.h"
 #include "android_webview/browser/icon_helper.h"
 #include "android_webview/browser/permission/permission_request_handler_client.h"
-#include "android_webview/browser/render_thread_manager.h"
-#include "android_webview/browser/render_thread_manager_client.h"
 #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h"
 #include "base/android/jni_weak_ref.h"
 #include "base/android/scoped_java_ref.h"
diff --git a/android_webview/browser/aw_contents_client_bridge.cc b/android_webview/browser/aw_contents_client_bridge.cc
index aeb0656..2a8c90e 100644
--- a/android_webview/browser/aw_contents_client_bridge.cc
+++ b/android_webview/browser/aw_contents_client_bridge.cc
@@ -19,7 +19,6 @@
 #include "content/public/browser/client_certificate_delegate.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "jni/AwContentsClientBridge_jni.h"
 #include "net/cert/x509_certificate.h"
@@ -257,8 +256,8 @@
   // Convert the encoded chain to a vector of strings.
   std::vector<std::string> encoded_chain_strings;
   if (!encoded_chain_ref.is_null()) {
-    base::android::JavaArrayOfByteArrayToStringVector(
-        env, encoded_chain_ref.obj(), &encoded_chain_strings);
+    base::android::JavaArrayOfByteArrayToStringVector(env, encoded_chain_ref,
+                                                      &encoded_chain_strings);
   }
 
   std::vector<base::StringPiece> encoded_chain;
@@ -438,6 +437,7 @@
     const AwWebResourceRequest& request,
     int error_code,
     bool safebrowsing_hit) {
+  DCHECK(request.is_renderer_initiated.has_value());
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
@@ -451,7 +451,8 @@
   AwWebResourceRequest::ConvertToJava(env, request, &java_web_resource_request);
   Java_AwContentsClientBridge_onReceivedError(
       env, obj, java_web_resource_request.jurl, request.is_main_frame,
-      request.has_user_gesture, java_web_resource_request.jmethod,
+      request.has_user_gesture, *request.is_renderer_initiated,
+      java_web_resource_request.jmethod,
       java_web_resource_request.jheader_names,
       java_web_resource_request.jheader_values, error_code, jstring_description,
       safebrowsing_hit);
diff --git a/android_webview/browser/aw_contents_client_bridge_unittest.cc b/android_webview/browser/aw_contents_client_bridge_unittest.cc
index 592d310..203bcbe 100644
--- a/android_webview/browser/aw_contents_client_bridge_unittest.cc
+++ b/android_webview/browser/aw_contents_client_bridge_unittest.cc
@@ -122,8 +122,7 @@
   ScopedJavaLocalRef<jobjectArray> key_types =
       Java_MockAwContentsClientBridge_getKeyTypes(env_, jbridge_);
   std::vector<std::string> vec;
-  base::android::AppendJavaStringArrayToStringVector(env_, key_types.obj(),
-                                                     &vec);
+  base::android::AppendJavaStringArrayToStringVector(env_, key_types, &vec);
   EXPECT_EQ(1u, vec.size());
   EXPECT_EQ(expected_name, vec[0]);
 }
diff --git a/android_webview/browser/aw_contents_io_thread_client.cc b/android_webview/browser/aw_contents_io_thread_client.cc
index f621a01..c3d337f3 100644
--- a/android_webview/browser/aw_contents_io_thread_client.cc
+++ b/android_webview/browser/aw_contents_io_thread_client.cc
@@ -342,7 +342,7 @@
 std::unique_ptr<AwWebResourceResponse> RunShouldInterceptRequest(
     const AwWebResourceRequest& request,
     JavaObjectWeakGlobalRef ref) {
-  base::AssertBlockingAllowed();
+  base::AssertBlockingAllowedDeprecated();
 
   JNIEnv* env = AttachCurrentThread();
   base::android::ScopedJavaLocalRef<jobject> obj = ref.get(env);
diff --git a/android_webview/browser/aw_contents_statics.cc b/android_webview/browser/aw_contents_statics.cc
index 6f9169e..47952182 100644
--- a/android_webview/browser/aw_contents_statics.cc
+++ b/android_webview/browser/aw_contents_statics.cc
@@ -10,10 +10,13 @@
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
+#include "base/bind.h"
 #include "base/callback.h"
+#include "base/task/post_task.h"
 #include "components/google/core/common/google_util.h"
 #include "components/security_interstitials/core/urls.h"
 #include "components/version_info/version_info.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/common/url_constants.h"
@@ -50,6 +53,14 @@
   Java_AwContentsStatics_safeBrowsingWhitelistAssigned(env, callback, success);
 }
 
+void ProxyOverrideChanged(const JavaRef<jobject>& callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (callback.is_null())
+    return;
+  JNIEnv* env = AttachCurrentThread();
+  Java_AwContentsStatics_proxyOverrideChanged(env, callback);
+}
+
 }  // namespace
 
 // static
@@ -73,8 +84,8 @@
     const JavaParamRef<jclass>&,
     const JavaParamRef<jobject>& callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  BrowserThread::PostTaskAndReply(
-      BrowserThread::IO, FROM_HERE,
+  base::PostTaskWithTraitsAndReply(
+      FROM_HERE, {BrowserThread::IO},
       base::BindOnce(&NotifyClientCertificatesChanged),
       base::BindOnce(&ClientCertificatesCleared,
                      ScopedJavaGlobalRef<jobject>(env, callback)));
@@ -136,23 +147,27 @@
     const JavaParamRef<jclass>&,
     const base::android::JavaParamRef<jstring>& jhost,
     jint port,
-    const base::android::JavaParamRef<jobjectArray>& jexclusion_list) {
+    const base::android::JavaParamRef<jobjectArray>& jexclusion_list,
+    const JavaParamRef<jobject>& callback) {
   std::string host;
   base::android::ConvertJavaStringToUTF8(env, jhost, &host);
   std::vector<std::string> exclusion_list;
   base::android::AppendJavaStringArrayToStringVector(env, jexclusion_list,
                                                      &exclusion_list);
-
   AwBrowserContext::GetDefault()->GetAwURLRequestContext()->SetProxyOverride(
-      host, port, exclusion_list);
+      host, port, exclusion_list,
+      base::BindOnce(&ProxyOverrideChanged,
+                     ScopedJavaGlobalRef<jobject>(env, callback)));
 }
 
 // static
-void JNI_AwContentsStatics_ClearProxyOverride(JNIEnv* env,
-                                              const JavaParamRef<jclass>&) {
-  AwBrowserContext::GetDefault()
-      ->GetAwURLRequestContext()
-      ->ClearProxyOverride();
+void JNI_AwContentsStatics_ClearProxyOverride(
+    JNIEnv* env,
+    const JavaParamRef<jclass>&,
+    const JavaParamRef<jobject>& callback) {
+  AwBrowserContext::GetDefault()->GetAwURLRequestContext()->ClearProxyOverride(
+      base::BindOnce(&ProxyOverrideChanged,
+                     ScopedJavaGlobalRef<jobject>(env, callback)));
 }
 
 }  // namespace android_webview
diff --git a/android_webview/browser/aw_feature_list.cc b/android_webview/browser/aw_feature_list.cc
new file mode 100644
index 0000000..23e1c04
--- /dev/null
+++ b/android_webview/browser/aw_feature_list.cc
@@ -0,0 +1,61 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "android_webview/browser/aw_feature_list.h"
+
+#include <string>
+
+#include "base/android/jni_string.h"
+#include "base/feature_list.h"
+#include "base/macros.h"
+#include "base/stl_util.h"
+#include "jni/AwFeatureList_jni.h"
+
+using base::android::ConvertJavaStringToUTF8;
+using base::android::JavaParamRef;
+
+namespace android_webview {
+
+namespace {
+
+// Array of features exposed through the Java ChromeFeatureList API. Entries in
+// this array may either refer to features defined in the header of this file or
+// in other locations in the code base (e.g. content/, components/, etc).
+const base::Feature* kFeaturesExposedToJava[] = {
+    &features::kWebViewConnectionlessSafeBrowsing,
+};
+
+const base::Feature* FindFeatureExposedToJava(const std::string& feature_name) {
+  for (size_t i = 0; i < base::size(kFeaturesExposedToJava); ++i) {
+    if (kFeaturesExposedToJava[i]->name == feature_name)
+      return kFeaturesExposedToJava[i];
+  }
+  NOTREACHED() << "Queried feature cannot be found in AwFeatureList: "
+               << feature_name;
+  return nullptr;
+}
+
+}  // namespace
+
+namespace features {
+
+// Alphabetical:
+
+// Use the SafeBrowsingApiHandler which uses the connectionless GMS APIs. This
+// Feature is checked and used in downstream internal code.
+const base::Feature kWebViewConnectionlessSafeBrowsing{
+    "WebViewConnectionlessSafeBrowsing", base::FEATURE_DISABLED_BY_DEFAULT};
+
+}  // namespace features
+
+static jboolean JNI_AwFeatureList_IsEnabled(
+    JNIEnv* env,
+    const JavaParamRef<jclass>& clazz,
+    const JavaParamRef<jstring>& jfeature_name) {
+  const base::Feature* feature =
+      FindFeatureExposedToJava(ConvertJavaStringToUTF8(env, jfeature_name));
+  return base::FeatureList::IsEnabled(*feature);
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_feature_list.h b/android_webview/browser/aw_feature_list.h
new file mode 100644
index 0000000..def7cff
--- /dev/null
+++ b/android_webview/browser/aw_feature_list.h
@@ -0,0 +1,22 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ANDROID_WEBVIEW_BROWSER_AW_FEATURE_LIST_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_FEATURE_LIST_H_
+
+#include "base/feature_list.h"
+
+namespace android_webview {
+namespace features {
+
+// All features in alphabetical order. The features should be documented
+// alongside the definition of their values in the .cc file.
+
+// Alphabetical:
+extern const base::Feature kWebViewConnectionlessSafeBrowsing;
+
+}  // namespace features
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_FEATURE_LIST_H_
diff --git a/android_webview/browser/aw_field_trial_creator.cc b/android_webview/browser/aw_field_trial_creator.cc
index f491522..a332033 100644
--- a/android_webview/browser/aw_field_trial_creator.cc
+++ b/android_webview/browser/aw_field_trial_creator.cc
@@ -13,75 +13,50 @@
 #include "android_webview/browser/aw_metrics_service_client.h"
 #include "android_webview/browser/aw_variations_seed_bridge.h"
 #include "base/base_switches.h"
+#include "base/bind_helpers.h"
 #include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/path_service.h"
 #include "base/strings/string_split.h"
 #include "base/time/time.h"
 #include "cc/base/switches.h"
-#include "components/prefs/in_memory_pref_store.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/pref_service_factory.h"
 #include "components/variations/entropy_provider.h"
-#include "components/variations/pref_names.h"
-#include "components/variations/seed_response.h"
 #include "components/variations/service/safe_seed_manager.h"
-#include "components/variations/service/variations_service.h"
 
 namespace android_webview {
-namespace {
-
-// TODO(kmilka): Update to work properly in environments both with and without
-// UMA enabled.
-std::unique_ptr<const base::FieldTrial::EntropyProvider>
-CreateLowEntropyProvider(const std::string& client_id) {
-  return std::unique_ptr<const base::FieldTrial::EntropyProvider>(
-      // Since variations are only enabled for users opted in to UMA, it is
-      // acceptable to use the SHA1EntropyProvider for randomization.
-      new variations::SHA1EntropyProvider(client_id));
-}
-
-}  // anonymous namespace
 
 AwFieldTrialCreator::AwFieldTrialCreator()
     : aw_field_trials_(std::make_unique<AwFieldTrials>()) {}
 
 AwFieldTrialCreator::~AwFieldTrialCreator() {}
 
-void AwFieldTrialCreator::SetUpFieldTrials() {
-  DoSetUpFieldTrials();
+void AwFieldTrialCreator::SetUpFieldTrials(PrefService* pref_service) {
+  auto* metrics_client = AwMetricsServiceClient::GetInstance();
 
-  // If DoSetUpFieldTrials failed, it might have skipped creating
-  // FeatureList. If so, create a FeatureList without field trials.
-  if (!base::FeatureList::GetInstance()) {
-    const base::CommandLine* command_line =
-        base::CommandLine::ForCurrentProcess();
-    auto feature_list = std::make_unique<base::FeatureList>();
-    feature_list->InitializeFromCommandLine(
-        command_line->GetSwitchValueASCII(switches::kEnableFeatures),
-        command_line->GetSwitchValueASCII(switches::kDisableFeatures));
-    base::FeatureList::SetInstance(std::move(feature_list));
-  }
-}
-
-void AwFieldTrialCreator::DoSetUpFieldTrials() {
-  // If the client ID isn't available yet, don't delay startup by creating it.
-  // Instead, variations will be disabled for this run.
-  std::string client_id;
-  if (!AwMetricsServiceClient::GetPreloadedClientId(&client_id))
-    return;
-
+  // Chrome uses the default entropy provider here (rather than low entropy
+  // provider). The default provider needs to know whether UMA is enabled, but
+  // WebView determines UMA by querying GMS, which is very slow. So WebView
+  // always uses the low entropy provider. Both providers guarantee permanent
+  // consistency, which is the main requirement. The difference is that the low
+  // entropy provider has fewer unique experiment combinations. This is better
+  // for privacy (since experiment state doesn't identify users), but also means
+  // fewer combinations tested in the wild.
   DCHECK(!field_trial_list_);
   field_trial_list_ = std::make_unique<base::FieldTrialList>(
-      CreateLowEntropyProvider(client_id));
+      metrics_client->CreateLowEntropyProvider());
 
   variations::UIStringOverrider ui_string_overrider;
   client_ = std::make_unique<AwVariationsServiceClient>();
+  auto seed_store = std::make_unique<variations::VariationsSeedStore>(
+      pref_service, /*initial_seed=*/GetAndClearJavaSeed(),
+      /*on_initial_seed_stored=*/base::DoNothing());
   variations_field_trial_creator_ =
       std::make_unique<variations::VariationsFieldTrialCreator>(
-          GetLocalState(), client_.get(), ui_string_overrider,
-          GetAndClearJavaSeed());
+          pref_service, client_.get(), std::move(seed_store),
+          ui_string_overrider);
   variations_field_trial_creator_->OverrideVariationsPlatform(
       variations::Study::PLATFORM_ANDROID_WEBVIEW);
 
@@ -90,27 +65,19 @@
   // TODO(isherman): We might want a more genuine SafeSeedManager:
   // https://crbug.com/801771
   std::set<std::string> unforceable_field_trials;
-  variations::SafeSeedManager ignored_safe_seed_manager(true, GetLocalState());
-  // Populates the FieldTrialList singleton via the static member functions.
+  variations::SafeSeedManager ignored_safe_seed_manager(true, pref_service);
+
+  // Populate FieldTrialList. Since low_entropy_provider is null, it will fall
+  // back to the provider we previously gave to FieldTrialList, which is a low
+  // entropy provider. We only want one low entropy provider, because multiple
+  // CachingPermutedEntropyProvider objects would all try to cache their values
+  // in the same pref store, overwriting each other's.
   variations_field_trial_creator_->SetupFieldTrials(
       cc::switches::kEnableGpuBenchmarking, switches::kEnableFeatures,
       switches::kDisableFeatures, unforceable_field_trials,
-      std::vector<std::string>(), CreateLowEntropyProvider(client_id),
+      std::vector<std::string>(), /*low_entropy_provider=*/nullptr,
       std::make_unique<base::FeatureList>(), aw_field_trials_.get(),
       &ignored_safe_seed_manager);
 }
 
-PrefService* AwFieldTrialCreator::GetLocalState() {
-  if (!local_state_) {
-    scoped_refptr<PrefRegistrySimple> pref_registry =
-        base::MakeRefCounted<PrefRegistrySimple>();
-    variations::VariationsService::RegisterPrefs(pref_registry.get());
-
-    PrefServiceFactory factory;
-    factory.set_user_prefs(base::MakeRefCounted<InMemoryPrefStore>());
-    local_state_ = factory.Create(pref_registry.get());
-  }
-  return local_state_.get();
-}
-
 }  // namespace android_webview
diff --git a/android_webview/browser/aw_field_trial_creator.h b/android_webview/browser/aw_field_trial_creator.h
index a1bd28a..e49e7ac 100644
--- a/android_webview/browser/aw_field_trial_creator.h
+++ b/android_webview/browser/aw_field_trial_creator.h
@@ -5,11 +5,12 @@
 #ifndef ANDROID_WEBVIEW_BROWSER_AW_FIELD_TRIAL_CREATOR_H_
 #define ANDROID_WEBVIEW_BROWSER_AW_FIELD_TRIAL_CREATOR_H_
 
+#include <memory>
+
 #include "android_webview/browser/aw_field_trials.h"
 #include "android_webview/browser/aw_variations_service_client.h"
 #include "base/metrics/field_trial.h"
 #include "components/prefs/pref_service.h"
-#include "components/prefs/pref_service_factory.h"
 #include "components/variations/service/variations_field_trial_creator.h"
 
 namespace android_webview {
@@ -24,12 +25,9 @@
   ~AwFieldTrialCreator();
 
   // Sets up the field trials and related initialization.
-  void SetUpFieldTrials();
+  void SetUpFieldTrials(PrefService* pref_service);
 
  private:
-  void DoSetUpFieldTrials();
-  PrefService* GetLocalState();
-
   // Stores the seed. VariationsSeedStore keeps a raw pointer to this, so it
   // must persist for the process lifetime. Not persisted accross runs.
   std::unique_ptr<PrefService> local_state_;
diff --git a/android_webview/browser/aw_gl_functor.cc b/android_webview/browser/aw_gl_functor.cc
index f907b11..ac39690 100644
--- a/android_webview/browser/aw_gl_functor.cc
+++ b/android_webview/browser/aw_gl_functor.cc
@@ -5,6 +5,8 @@
 #include "android_webview/browser/aw_gl_functor.h"
 
 #include "android_webview/public/browser/draw_gl.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "jni/AwGLFunctor_jni.h"
 
@@ -35,7 +37,7 @@
     : java_ref_(java_ref),
       render_thread_manager_(
           this,
-          BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)) {
+          base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI})) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ++g_instance_count;
 }
diff --git a/android_webview/browser/aw_login_delegate.cc b/android_webview/browser/aw_login_delegate.cc
index 356e286..c40743f 100644
--- a/android_webview/browser/aw_login_delegate.cc
+++ b/android_webview/browser/aw_login_delegate.cc
@@ -8,6 +8,8 @@
 #include "base/android/jni_android.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
@@ -20,18 +22,26 @@
 
 namespace android_webview {
 
-AwLoginDelegate::AwLoginDelegate(
+// static
+scoped_refptr<AwLoginDelegate> AwLoginDelegate::Create(
     net::AuthChallengeInfo* auth_info,
     content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
     bool first_auth_attempt,
+    LoginAuthRequiredCallback auth_required_callback) {
+  scoped_refptr<AwLoginDelegate> instance(
+      new AwLoginDelegate(auth_info, std::move(auth_required_callback)));
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::UI},
+      base::BindOnce(&AwLoginDelegate::HandleHttpAuthRequestOnUIThread,
+                     instance, first_auth_attempt, web_contents_getter));
+  return instance;
+}
+
+AwLoginDelegate::AwLoginDelegate(
+    net::AuthChallengeInfo* auth_info,
     LoginAuthRequiredCallback auth_required_callback)
     : auth_info_(auth_info),
-      auth_required_callback_(std::move(auth_required_callback)) {
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::BindOnce(&AwLoginDelegate::HandleHttpAuthRequestOnUIThread, this,
-                     first_auth_attempt, web_contents_getter));
-}
+      auth_required_callback_(std::move(auth_required_callback)) {}
 
 AwLoginDelegate::~AwLoginDelegate() {
   // The Auth handler holds a ref count back on |this| object, so it should be
@@ -42,15 +52,15 @@
 void AwLoginDelegate::Proceed(const base::string16& user,
                               const base::string16& password) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
-                          base::BindOnce(&AwLoginDelegate::ProceedOnIOThread,
-                                         this, user, password));
+  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+                           base::BindOnce(&AwLoginDelegate::ProceedOnIOThread,
+                                          this, user, password));
 }
 
 void AwLoginDelegate::Cancel() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::IO},
       base::BindOnce(&AwLoginDelegate::CancelOnIOThread, this));
 }
 
@@ -94,8 +104,8 @@
 
 void AwLoginDelegate::DeleteAuthHandlerSoon() {
   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
+    base::PostTaskWithTraits(
+        FROM_HERE, {BrowserThread::UI},
         base::BindOnce(&AwLoginDelegate::DeleteAuthHandlerSoon, this));
     return;
   }
diff --git a/android_webview/browser/aw_login_delegate.h b/android_webview/browser/aw_login_delegate.h
index 2b67cf3..d4d4613 100644
--- a/android_webview/browser/aw_login_delegate.h
+++ b/android_webview/browser/aw_login_delegate.h
@@ -24,7 +24,7 @@
 
 class AwLoginDelegate : public content::LoginDelegate {
  public:
-  AwLoginDelegate(
+  static scoped_refptr<AwLoginDelegate> Create(
       net::AuthChallengeInfo* auth_info,
       content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
       bool first_auth_attempt,
@@ -38,6 +38,8 @@
   void OnRequestCancelled() override;
 
  private:
+  AwLoginDelegate(net::AuthChallengeInfo* auth_info,
+                  LoginAuthRequiredCallback auth_required_callback);
   ~AwLoginDelegate() override;
   void HandleHttpAuthRequestOnUIThread(
       bool first_auth_attempt,
diff --git a/android_webview/browser/aw_metrics_service_client.cc b/android_webview/browser/aw_metrics_service_client.cc
index 8156599..c8c9f91 100644
--- a/android_webview/browser/aw_metrics_service_client.cc
+++ b/android_webview/browser/aw_metrics_service_client.cc
@@ -88,19 +88,6 @@
   return g_lazy_instance_.Pointer();
 }
 
-bool AwMetricsServiceClient::GetPreloadedClientId(std::string* client_id) {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  base::android::ScopedJavaLocalRef<jbyteArray> client_id_java =
-      Java_AwMetricsServiceClient_getPreloadedClientId(env);
-  if (client_id_java.is_null())
-    return false;
-  std::vector<uint8_t> client_id_vector;
-  base::android::JavaByteArrayToByteVector(env, client_id_java.obj(),
-                                           &client_id_vector);
-  *client_id = std::string(client_id_vector.begin(), client_id_vector.end());
-  return true;
-}
-
 void AwMetricsServiceClient::LoadOrCreateClientId() {
   // This function should only be called once at start up.
   DCHECK_NE(g_client_id.Get().length(), kGuidSize);
@@ -121,8 +108,7 @@
       user_data_dir.Append(FILE_PATH_LITERAL(kGuidFileName));
 
   // Try to get an existing GUID.
-  if (GetPreloadedClientId(&g_client_id.Get()) ||
-      base::ReadFileToStringWithMaxSize(guid_file_path, &g_client_id.Get(),
+  if (base::ReadFileToStringWithMaxSize(guid_file_path, &g_client_id.Get(),
                                         kGuidSize)) {
     if (base::IsValidGUID(g_client_id.Get()))
       return;
@@ -147,15 +133,16 @@
   return g_client_id.Get();
 }
 
-void AwMetricsServiceClient::Initialize(
-    PrefService* pref_service,
-    net::URLRequestContextGetter* request_context) {
+void AwMetricsServiceClient::Initialize(PrefService* pref_service) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   DCHECK(pref_service_ == nullptr);  // Initialize should only happen once.
-  DCHECK(request_context_ == nullptr);
   pref_service_ = pref_service;
-  request_context_ = request_context;
+
+  metrics_state_manager_ = metrics::MetricsStateManager::Create(
+      pref_service_, this, base::string16(),
+      base::BindRepeating(&StoreClientInfo),
+      base::BindRepeating(&LoadClientInfo));
 
   base::PostTaskWithTraitsAndReply(
       FROM_HERE, {base::MayBlock()},
@@ -165,15 +152,14 @@
 }
 
 void AwMetricsServiceClient::InitializeWithClientId() {
-  DCHECK_EQ(g_client_id.Get().length(), kGuidSize);  // Must have client ID
+  // The client ID must be loaded (because LoadOrCreateClientId() finished), but
+  // not yet stored in prefs.
+  DCHECK_EQ(g_client_id.Get().length(), kGuidSize);
+  DCHECK(!pref_service_->HasPrefPath(metrics::prefs::kMetricsClientID));
+
   pref_service_->SetString(metrics::prefs::kMetricsClientID, g_client_id.Get());
   in_sample_ = IsInSample(g_client_id.Get());
 
-  metrics_state_manager_ = metrics::MetricsStateManager::Create(
-      pref_service_, this, base::string16(),
-      base::BindRepeating(&StoreClientInfo),
-      base::BindRepeating(&LoadClientInfo));
-
   metrics_service_.reset(new ::metrics::MetricsService(
       metrics_state_manager_.get(), this, pref_service_));
 
@@ -199,6 +185,11 @@
   Java_AwMetricsServiceClient_nativeInitialized(env);
 }
 
+std::unique_ptr<const base::FieldTrial::EntropyProvider>
+AwMetricsServiceClient::CreateLowEntropyProvider() {
+  return metrics_state_manager_->CreateLowEntropyProvider();
+}
+
 bool AwMetricsServiceClient::IsConsentGiven() const {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   return consent_;
@@ -278,7 +269,6 @@
 
 AwMetricsServiceClient::AwMetricsServiceClient()
     : pref_service_(nullptr),
-      request_context_(nullptr),
       consent_(false),
       in_sample_(false) {}
 
diff --git a/android_webview/browser/aw_metrics_service_client.h b/android_webview/browser/aw_metrics_service_client.h
index 5880206..3c420a02 100644
--- a/android_webview/browser/aw_metrics_service_client.h
+++ b/android_webview/browser/aw_metrics_service_client.h
@@ -10,10 +10,10 @@
 
 #include "base/lazy_instance.h"
 #include "base/macros.h"
+#include "base/metrics/field_trial.h"
 #include "components/metrics/enabled_state_provider.h"
 #include "components/metrics/metrics_log_uploader.h"
 #include "components/metrics/metrics_service_client.h"
-#include "components/version_info/channel.h"
 
 class PrefService;
 
@@ -21,10 +21,6 @@
 class FilePath;
 }
 
-namespace net {
-class URLRequestContextGetter;
-}
-
 namespace metrics {
 class MetricsStateManager;
 }
@@ -44,18 +40,16 @@
  public:
   static AwMetricsServiceClient* GetInstance();
 
-  // If the client ID was pre-loaded on the Java side, store it in "client_id"
-  // and return true; otherwise, return false.
-  static bool GetPreloadedClientId(std::string* client_id);
-
   // Retrieve the client ID or generate one if none exists.
   static void LoadOrCreateClientId();
 
   // Return the cached client id.
   static std::string GetClientId();
 
-  void Initialize(PrefService* pref_service,
-                  net::URLRequestContextGetter* request_context);
+  void Initialize(PrefService* pref_service);
+
+  std::unique_ptr<const base::FieldTrial::EntropyProvider>
+  CreateLowEntropyProvider();
 
   // metrics::EnabledStateProvider implementation
   bool IsConsentGiven() const override;
@@ -93,7 +87,6 @@
   std::unique_ptr<metrics::MetricsStateManager> metrics_state_manager_;
   std::unique_ptr<metrics::MetricsService> metrics_service_;
   PrefService* pref_service_;
-  net::URLRequestContextGetter* request_context_;
   bool consent_;    // = (user has consented) && !(app has opted out)
   bool in_sample_;  // Is this client enabled by sampling?
 
diff --git a/android_webview/browser/aw_pdf_exporter.cc b/android_webview/browser/aw_pdf_exporter.cc
index ee2cea5..eab60f1 100644
--- a/android_webview/browser/aw_pdf_exporter.cc
+++ b/android_webview/browser/aw_pdf_exporter.cc
@@ -21,7 +21,7 @@
 namespace {
 
 void JNI_AwPdfExporter_GetPageRanges(JNIEnv* env,
-                                     jintArray int_arr,
+                                     const JavaRef<jintArray>& int_arr,
                                      printing::PageRanges* range_vector) {
   std::vector<int> pages;
   base::android::JavaIntArrayToIntVector(env, int_arr, &pages);
@@ -56,7 +56,7 @@
 void AwPdfExporter::ExportToPdf(JNIEnv* env,
                                 const JavaParamRef<jobject>& obj,
                                 int fd,
-                                jintArray pages,
+                                const JavaParamRef<jintArray>& pages,
                                 const JavaParamRef<jobject>& cancel_signal) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   printing::PrintSettings print_settings;
@@ -68,7 +68,7 @@
       base::Bind(&AwPdfExporter::DidExportPdf, base::Unretained(this)));
 
   if (!print_manager->PrintNow())
-    DidExportPdf(fd, 0);
+    DidExportPdf(0);
 }
 
 namespace {
@@ -113,7 +113,7 @@
   settings.set_should_print_backgrounds(true);
 }
 
-void AwPdfExporter::DidExportPdf(int fd, int page_count) {
+void AwPdfExporter::DidExportPdf(int page_count) {
   JNIEnv* env = base::android::AttachCurrentThread();
   ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
   if (obj.is_null())
diff --git a/android_webview/browser/aw_pdf_exporter.h b/android_webview/browser/aw_pdf_exporter.h
index 598881a..a4ca157 100644
--- a/android_webview/browser/aw_pdf_exporter.h
+++ b/android_webview/browser/aw_pdf_exporter.h
@@ -32,7 +32,7 @@
   void ExportToPdf(JNIEnv* env,
                    const base::android::JavaParamRef<jobject>& obj,
                    int fd,
-                   jintArray pages,
+                   const base::android::JavaParamRef<jintArray>& pages,
                    const base::android::JavaParamRef<jobject>& cancel_signal);
 
  private:
@@ -40,7 +40,7 @@
                        const base::android::JavaRef<jobject>& obj,
                        const printing::PageRanges& page_ranges,
                        printing::PrintSettings& settings);
-  void DidExportPdf(int fd, int page_count);
+  void DidExportPdf(int page_count);
 
   JavaObjectWeakGlobalRef java_ref_;
   content::WebContents* web_contents_;
diff --git a/android_webview/browser/aw_permission_manager.cc b/android_webview/browser/aw_permission_manager.cc
index 249176a..3a101d3 100644
--- a/android_webview/browser/aw_permission_manager.cc
+++ b/android_webview/browser/aw_permission_manager.cc
@@ -325,6 +325,7 @@
       case PermissionType::CLIPBOARD_READ:
       case PermissionType::CLIPBOARD_WRITE:
       case PermissionType::PAYMENT_HANDLER:
+      case PermissionType::BACKGROUND_FETCH:
         NOTIMPLEMENTED() << "RequestPermissions is not implemented for "
                          << static_cast<int>(permissions[i]);
         pending_request_raw->SetPermissionStatus(permissions[i],
@@ -516,6 +517,7 @@
       case PermissionType::CLIPBOARD_READ:
       case PermissionType::CLIPBOARD_WRITE:
       case PermissionType::PAYMENT_HANDLER:
+      case PermissionType::BACKGROUND_FETCH:
         NOTIMPLEMENTED() << "CancelPermission not implemented for "
                          << static_cast<int>(permission);
         break;
diff --git a/android_webview/browser/aw_picture.h b/android_webview/browser/aw_picture.h
index 01058d81..db3566d 100644
--- a/android_webview/browser/aw_picture.h
+++ b/android_webview/browser/aw_picture.h
@@ -9,7 +9,6 @@
 
 #include "base/android/jni_weak_ref.h"
 #include "base/macros.h"
-#include "content/public/browser/web_contents_observer.h"
 #include "third_party/skia/include/core/SkRefCnt.h"
 
 class SkPicture;
diff --git a/android_webview/browser/aw_print_manager.h b/android_webview/browser/aw_print_manager.h
index b7bfb6f..f59c671 100644
--- a/android_webview/browser/aw_print_manager.h
+++ b/android_webview/browser/aw_print_manager.h
@@ -8,6 +8,7 @@
 #include "base/macros.h"
 #include "components/printing/browser/print_manager.h"
 #include "components/printing/common/print_messages.h"
+#include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents_user_data.h"
 #include "printing/print_settings.h"
 
diff --git a/android_webview/browser/aw_proxying_url_loader_factory.cc b/android_webview/browser/aw_proxying_url_loader_factory.cc
new file mode 100644
index 0000000..07ca9d2
--- /dev/null
+++ b/android_webview/browser/aw_proxying_url_loader_factory.cc
@@ -0,0 +1,439 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "android_webview/browser/aw_proxying_url_loader_factory.h"
+
+#include <utility>
+
+#include "android_webview/browser/aw_contents_client_bridge.h"
+#include "android_webview/browser/renderer_host/auto_login_parser.h"
+#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_request_id.h"
+#include "content/public/browser/resource_request_info.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/url_utils.h"
+#include "net/http/http_util.h"
+
+namespace android_webview {
+
+namespace {
+
+const char kAutoLoginHeaderName[] = "X-Auto-Login";
+
+// Handles intercepted, in-progress requests/responses, so that they can be
+// controlled and modified accordingly.
+class InterceptedRequest : public network::mojom::URLLoader,
+                           public network::mojom::URLLoaderClient {
+ public:
+  InterceptedRequest(
+      int process_id,
+      uint64_t request_id,
+      int32_t routing_id,
+      uint32_t options,
+      const network::ResourceRequest& request,
+      const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
+      network::mojom::URLLoaderRequest loader_request,
+      network::mojom::URLLoaderClientPtr client,
+      network::mojom::URLLoaderFactoryPtr target_factory);
+  ~InterceptedRequest() override;
+
+  void Restart();
+
+  // network::mojom::URLLoaderClient
+  void OnReceiveResponse(const network::ResourceResponseHead& head) override;
+  void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
+                         const network::ResourceResponseHead& head) override;
+  void OnUploadProgress(int64_t current_position,
+                        int64_t total_size,
+                        OnUploadProgressCallback callback) override;
+  void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override;
+  void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
+  void OnStartLoadingResponseBody(
+      mojo::ScopedDataPipeConsumerHandle body) override;
+  void OnComplete(const network::URLLoaderCompletionStatus& status) override;
+
+  // network::mojom::URLLoader
+  void FollowRedirect(const base::Optional<std::vector<std::string>>&
+                          to_be_removed_request_headers,
+                      const base::Optional<net::HttpRequestHeaders>&
+                          modified_request_headers) override;
+  void ProceedWithResponse() override;
+  void SetPriority(net::RequestPriority priority,
+                   int32_t intra_priority_value) override;
+  void PauseReadingBodyFromNet() override;
+  void ResumeReadingBodyFromNet() override;
+
+ private:
+  void OnRequestError(const network::URLLoaderCompletionStatus& status);
+
+  // TODO(timvolodine): consider factoring this out of this class.
+  void OnReceivedErrorToCallback(int error_code);
+
+  const int process_id_;
+  const uint64_t request_id_;
+  const int32_t routing_id_;
+  const uint32_t options_;
+
+  network::ResourceRequest request_;
+  const net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
+
+  mojo::Binding<network::mojom::URLLoader> proxied_loader_binding_;
+  network::mojom::URLLoaderClientPtr target_client_;
+
+  mojo::Binding<network::mojom::URLLoaderClient> proxied_client_binding_;
+  network::mojom::URLLoaderPtr target_loader_;
+  network::mojom::URLLoaderFactoryPtr target_factory_;
+
+  base::WeakPtrFactory<InterceptedRequest> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(InterceptedRequest);
+};
+
+InterceptedRequest::InterceptedRequest(
+    int process_id,
+    uint64_t request_id,
+    int32_t routing_id,
+    uint32_t options,
+    const network::ResourceRequest& request,
+    const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
+    network::mojom::URLLoaderRequest loader_request,
+    network::mojom::URLLoaderClientPtr client,
+    network::mojom::URLLoaderFactoryPtr target_factory)
+    : process_id_(process_id),
+      request_id_(request_id),
+      routing_id_(routing_id),
+      options_(options),
+      request_(request),
+      traffic_annotation_(traffic_annotation),
+      proxied_loader_binding_(this, std::move(loader_request)),
+      target_client_(std::move(client)),
+      proxied_client_binding_(this),
+      target_factory_(std::move(target_factory)),
+      weak_factory_(this) {
+  // If there is a client error, clean up the request.
+  target_client_.set_connection_error_handler(base::BindOnce(
+      &InterceptedRequest::OnRequestError, weak_factory_.GetWeakPtr(),
+      network::URLLoaderCompletionStatus(net::ERR_ABORTED)));
+}
+
+InterceptedRequest::~InterceptedRequest() {}
+
+void InterceptedRequest::Restart() {
+  // TODO(timvolodine): add async check shouldOverrideUrlLoading and
+  // shouldInterceptRequest.
+
+  if (!target_loader_ && target_factory_) {
+    network::mojom::URLLoaderClientPtr proxied_client;
+    proxied_client_binding_.Bind(mojo::MakeRequest(&proxied_client));
+    target_factory_->CreateLoaderAndStart(
+        mojo::MakeRequest(&target_loader_), routing_id_, request_id_, options_,
+        request_, std::move(proxied_client), traffic_annotation_);
+  }
+}
+
+namespace {
+// TODO(timvolodine): consider factoring this out of this file.
+
+AwContentsClientBridge* GetAwContentsClientBridgeFromID(int process_id,
+                                                        int render_frame_id) {
+  content::WebContents* wc =
+      process_id
+          ? content::WebContents::FromRenderFrameHost(
+                content::RenderFrameHost::FromID(process_id, render_frame_id))
+          : content::WebContents::FromFrameTreeNodeId(render_frame_id);
+  return AwContentsClientBridge::FromWebContents(wc);
+}
+
+void OnReceivedHttpErrorOnUiThread(
+    int process_id,
+    int render_frame_id,
+    const AwWebResourceRequest& request,
+    std::unique_ptr<AwContentsClientBridge::HttpErrorInfo> http_error_info) {
+  auto* client = GetAwContentsClientBridgeFromID(process_id, render_frame_id);
+  if (!client) {
+    DLOG(WARNING) << "client is null, onReceivedHttpError dropped for "
+                  << request.url;
+    return;
+  }
+  client->OnReceivedHttpError(request, std::move(http_error_info));
+}
+
+void OnReceivedErrorOnUiThread(int process_id,
+                               int render_frame_id,
+                               const AwWebResourceRequest& request,
+                               int error_code) {
+  auto* client = GetAwContentsClientBridgeFromID(process_id, render_frame_id);
+  if (!client) {
+    DLOG(WARNING) << "client is null, onReceivedError dropped for "
+                  << request.url;
+    return;
+  }
+  // TODO(timvolodine): properly handle safe_browsing_hit.
+  client->OnReceivedError(request, error_code, false /*safebrowsing_hit*/);
+}
+
+void OnNewLoginRequestOnUiThread(int process_id,
+                                 int render_frame_id,
+                                 const std::string& realm,
+                                 const std::string& account,
+                                 const std::string& args) {
+  auto* client = GetAwContentsClientBridgeFromID(process_id, render_frame_id);
+  if (!client) {
+    return;
+  }
+  client->NewLoginRequest(realm, account, args);
+}
+
+}  // namespace
+
+// URLLoaderClient methods.
+
+void InterceptedRequest::OnReceiveResponse(
+    const network::ResourceResponseHead& head) {
+  // intercept response headers here
+  // pause/resume proxied_client_binding_ if necessary
+
+  if (head.headers->response_code() >= 400) {
+    // In Android WebView the WebViewClient.onReceivedHttpError callback
+    // is invoked for any resource (main page, iframe, image, etc.) with
+    // status code >= 400.
+    std::unique_ptr<AwContentsClientBridge::HttpErrorInfo> error_info =
+        AwContentsClientBridge::ExtractHttpErrorInfo(head.headers.get());
+
+    base::PostTaskWithTraits(
+        FROM_HERE, {content::BrowserThread::UI},
+        base::BindOnce(
+            &OnReceivedHttpErrorOnUiThread, process_id_,
+            request_.render_frame_id,
+            AwWebResourceRequest(
+                request_.url.spec(), request_.method,
+                request_.resource_type == content::RESOURCE_TYPE_MAIN_FRAME,
+                request_.has_user_gesture, request_.headers),
+            std::move(error_info)));
+  }
+
+  if (request_.resource_type == content::RESOURCE_TYPE_MAIN_FRAME) {
+    // Check for x-auto-login-header
+    HeaderData header_data;
+    std::string header_string;
+    if (head.headers->GetNormalizedHeader(kAutoLoginHeaderName,
+                                          &header_string)) {
+      if (ParseHeader(header_string, ALLOW_ANY_REALM, &header_data)) {
+        // TODO(timvolodine): consider simplifying this and above callback
+        // code, crbug.com/897149.
+        base::PostTaskWithTraits(
+            FROM_HERE, {content::BrowserThread::UI},
+            base::BindOnce(&OnNewLoginRequestOnUiThread, process_id_,
+                           request_.render_frame_id, header_data.realm,
+                           header_data.account, header_data.args));
+      }
+    }
+  }
+
+  target_client_->OnReceiveResponse(head);
+}
+
+void InterceptedRequest::OnReceiveRedirect(
+    const net::RedirectInfo& redirect_info,
+    const network::ResourceResponseHead& head) {
+  // TODO(timvolodine): handle redirect override.
+  // TODO(timvolodine): handle unsafe redirect case.
+  target_client_->OnReceiveRedirect(redirect_info, head);
+  request_.url = redirect_info.new_url;
+  request_.method = redirect_info.new_method;
+  request_.site_for_cookies = redirect_info.new_site_for_cookies;
+  request_.referrer = GURL(redirect_info.new_referrer);
+  request_.referrer_policy = redirect_info.new_referrer_policy;
+}
+
+void InterceptedRequest::OnUploadProgress(int64_t current_position,
+                                          int64_t total_size,
+                                          OnUploadProgressCallback callback) {
+  target_client_->OnUploadProgress(current_position, total_size,
+                                   std::move(callback));
+}
+
+void InterceptedRequest::OnReceiveCachedMetadata(
+    const std::vector<uint8_t>& data) {
+  target_client_->OnReceiveCachedMetadata(data);
+}
+
+void InterceptedRequest::OnTransferSizeUpdated(int32_t transfer_size_diff) {
+  target_client_->OnTransferSizeUpdated(transfer_size_diff);
+}
+
+void InterceptedRequest::OnStartLoadingResponseBody(
+    mojo::ScopedDataPipeConsumerHandle body) {
+  target_client_->OnStartLoadingResponseBody(std::move(body));
+}
+
+void InterceptedRequest::OnComplete(
+    const network::URLLoaderCompletionStatus& status) {
+  if (status.error_code != net::OK) {
+    OnRequestError(status);
+    return;
+  }
+
+  target_client_->OnComplete(status);
+
+  // Deletes |this|.
+  // TODO(timvolodine): consider doing this via the factory.
+  delete this;
+}
+
+// URLLoader methods.
+
+void InterceptedRequest::FollowRedirect(
+    const base::Optional<std::vector<std::string>>&
+        to_be_removed_request_headers,
+    const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
+  if (target_loader_) {
+    target_loader_->FollowRedirect(to_be_removed_request_headers,
+                                   modified_request_headers);
+  }
+
+  Restart();
+}
+
+void InterceptedRequest::ProceedWithResponse() {
+  if (target_loader_)
+    target_loader_->ProceedWithResponse();
+}
+
+void InterceptedRequest::SetPriority(net::RequestPriority priority,
+                                     int32_t intra_priority_value) {
+  if (target_loader_)
+    target_loader_->SetPriority(priority, intra_priority_value);
+}
+
+void InterceptedRequest::PauseReadingBodyFromNet() {
+  if (target_loader_)
+    target_loader_->PauseReadingBodyFromNet();
+}
+
+void InterceptedRequest::ResumeReadingBodyFromNet() {
+  if (target_loader_)
+    target_loader_->ResumeReadingBodyFromNet();
+}
+
+void InterceptedRequest::OnRequestError(
+    const network::URLLoaderCompletionStatus& status) {
+  target_client_->OnComplete(status);
+
+  OnReceivedErrorToCallback(status.error_code);
+
+  // Deletes |this|.
+  // TODO(timvolodine): consider handling this through a data structure.
+  delete this;
+}
+
+void InterceptedRequest::OnReceivedErrorToCallback(int error_code) {
+  // TODO(timvolodine): add constructor for direct creation from
+  // network::ResourceRequest.
+  AwWebResourceRequest aw_request(
+      request_.url.spec(), request_.method,
+      request_.resource_type == content::RESOURCE_TYPE_MAIN_FRAME,
+      request_.has_user_gesture, request_.headers);
+  // Error callback now requires for |is_renderer_intiated| to be set.
+  aw_request.is_renderer_initiated = ui::PageTransitionIsWebTriggerable(
+      static_cast<ui::PageTransition>(request_.transition_type));
+
+  base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+                           base::BindOnce(&OnReceivedErrorOnUiThread,
+                                          process_id_, request_.render_frame_id,
+                                          std::move(aw_request), error_code));
+}
+
+}  // namespace
+
+//============================
+// AwProxyingURLLoaderFactory
+//============================
+
+AwProxyingURLLoaderFactory::AwProxyingURLLoaderFactory(
+    int process_id,
+    network::mojom::URLLoaderFactoryRequest loader_request,
+    network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
+    std::unique_ptr<AwInterceptedRequestHandler> request_handler)
+    : process_id_(process_id),
+      request_handler_(std::move(request_handler)),
+      weak_factory_(this) {
+  // actual creation of the factory
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  target_factory_.Bind(std::move(target_factory_info));
+  target_factory_.set_connection_error_handler(
+      base::BindOnce(&AwProxyingURLLoaderFactory::OnTargetFactoryError,
+                     base::Unretained(this)));
+  proxy_bindings_.AddBinding(this, std::move(loader_request));
+  proxy_bindings_.set_connection_error_handler(
+      base::BindRepeating(&AwProxyingURLLoaderFactory::OnProxyBindingError,
+                          base::Unretained(this)));
+}
+
+AwProxyingURLLoaderFactory::~AwProxyingURLLoaderFactory() {}
+
+// static
+void AwProxyingURLLoaderFactory::CreateProxy(
+    int process_id,
+    network::mojom::URLLoaderFactoryRequest loader_request,
+    network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
+    std::unique_ptr<AwInterceptedRequestHandler> request_handler) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+  // will manage its own lifetime
+  new AwProxyingURLLoaderFactory(process_id, std::move(loader_request),
+                                 std::move(target_factory_info),
+                                 std::move(request_handler));
+}
+
+void AwProxyingURLLoaderFactory::CreateLoaderAndStart(
+    network::mojom::URLLoaderRequest loader,
+    int32_t routing_id,
+    int32_t request_id,
+    uint32_t options,
+    const network::ResourceRequest& request,
+    network::mojom::URLLoaderClientPtr client,
+    const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
+  bool pass_through = false;
+  if (pass_through) {
+    // this is the so-called pass-through, no-op option.
+    target_factory_->CreateLoaderAndStart(
+        std::move(loader), routing_id, request_id, options, request,
+        std::move(client), traffic_annotation);
+    return;
+  }
+
+  // TODO(timvolodine): handle interception, modification (headers for
+  // webview), blocking, callbacks etc..
+
+  network::mojom::URLLoaderFactoryPtr target_factory_clone;
+  target_factory_->Clone(MakeRequest(&target_factory_clone));
+
+  // manages its own lifecycle
+  // TODO(timvolodine): consider keeping track of requests.
+  InterceptedRequest* req = new InterceptedRequest(
+      process_id_, request_id, routing_id, options, request, traffic_annotation,
+      std::move(loader), std::move(client), std::move(target_factory_clone));
+  req->Restart();
+}
+
+void AwProxyingURLLoaderFactory::OnTargetFactoryError() {
+  delete this;
+}
+
+void AwProxyingURLLoaderFactory::OnProxyBindingError() {
+  if (proxy_bindings_.empty())
+    delete this;
+}
+
+void AwProxyingURLLoaderFactory::Clone(
+    network::mojom::URLLoaderFactoryRequest loader_request) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  proxy_bindings_.AddBinding(this, std::move(loader_request));
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_proxying_url_loader_factory.h b/android_webview/browser/aw_proxying_url_loader_factory.h
new file mode 100644
index 0000000..5a673ff
--- /dev/null
+++ b/android_webview/browser/aw_proxying_url_loader_factory.h
@@ -0,0 +1,77 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ANDROID_WEBVIEW_BROWSER_AW_PROXYING_URL_LOADER_FACTORY_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_PROXYING_URL_LOADER_FACTORY_H_
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/ref_counted_delete_on_sequence.h"
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "net/base/completion_callback.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/resource_response.h"
+#include "services/network/public/mojom/url_loader.mojom.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "url/gurl.h"
+
+namespace android_webview {
+
+class AwInterceptedRequestHandler {};
+
+// URL Loader Factory for android webview, for supporting request/response
+// interception, processing and callback invocation. Currently contains basic
+// pass-through implementation.
+class AwProxyingURLLoaderFactory : public network::mojom::URLLoaderFactory {
+ public:
+  AwProxyingURLLoaderFactory(
+      int process_id,
+      network::mojom::URLLoaderFactoryRequest loader_request,
+      network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
+      std::unique_ptr<AwInterceptedRequestHandler> request_handler);
+
+  ~AwProxyingURLLoaderFactory() override;
+
+  // static
+  static void CreateProxy(
+      int process_id,
+      network::mojom::URLLoaderFactoryRequest loader,
+      network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
+      std::unique_ptr<AwInterceptedRequestHandler> request_handler);
+
+  void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader,
+                            int32_t routing_id,
+                            int32_t request_id,
+                            uint32_t options,
+                            const network::ResourceRequest& request,
+                            network::mojom::URLLoaderClientPtr client,
+                            const net::MutableNetworkTrafficAnnotationTag&
+                                traffic_annotation) override;
+
+  void Clone(network::mojom::URLLoaderFactoryRequest loader_request) override;
+
+ private:
+  void OnTargetFactoryError();
+  void OnProxyBindingError();
+
+  const int process_id_;
+  mojo::BindingSet<network::mojom::URLLoaderFactory> proxy_bindings_;
+  network::mojom::URLLoaderFactoryPtr target_factory_;
+
+  // TODO(timvolodine): consider functionality to have multiple interception
+  // handlers operating in sequence.
+  std::unique_ptr<AwInterceptedRequestHandler> request_handler_;
+  base::WeakPtrFactory<AwProxyingURLLoaderFactory> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwProxyingURLLoaderFactory);
+};
+
+}  // namespace android_webview
+
+#endif
diff --git a/android_webview/browser/aw_quota_manager_bridge.cc b/android_webview/browser/aw_quota_manager_bridge.cc
index 56737fc..bd55933 100644
--- a/android_webview/browser/aw_quota_manager_bridge.cc
+++ b/android_webview/browser/aw_quota_manager_bridge.cc
@@ -12,6 +12,8 @@
 #include "base/android/jni_string.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/common/content_client.h"
@@ -19,6 +21,7 @@
 #include "storage/browser/quota/quota_manager.h"
 #include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
 #include "url/gurl.h"
+#include "url/origin.h"
 
 using base::android::AttachCurrentThread;
 using base::android::JavaParamRef;
@@ -47,10 +50,10 @@
   friend class base::RefCountedThreadSafe<GetOriginsTask>;
   ~GetOriginsTask();
 
-  void OnOriginsObtained(const std::set<GURL>& origins,
+  void OnOriginsObtained(const std::set<url::Origin>& origins,
                          blink::mojom::StorageType type);
 
-  void OnUsageAndQuotaObtained(const GURL& origin,
+  void OnUsageAndQuotaObtained(const url::Origin& origin,
                                blink::mojom::QuotaStatusCode status_code,
                                int64_t usage,
                                int64_t quota);
@@ -82,39 +85,37 @@
 
 void GetOriginsTask::Run() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::IO},
       base::BindOnce(&QuotaManager::GetOriginsModifiedSince, quota_manager_,
                      blink::mojom::StorageType::kTemporary,
                      base::Time() /* Since beginning of time. */,
                      base::BindOnce(&GetOriginsTask::OnOriginsObtained, this)));
 }
 
-void GetOriginsTask::OnOriginsObtained(const std::set<GURL>& origins,
+void GetOriginsTask::OnOriginsObtained(const std::set<url::Origin>& origins,
                                        blink::mojom::StorageType type) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   num_callbacks_to_wait_ = origins.size();
   num_callbacks_received_ = 0u;
 
-  for (std::set<GURL>::const_iterator origin = origins.begin();
-       origin != origins.end(); ++origin) {
+  for (const url::Origin& origin : origins) {
     quota_manager_->GetUsageAndQuota(
-        *origin, type,
-        base::BindOnce(&GetOriginsTask::OnUsageAndQuotaObtained, this,
-                       *origin));
+        origin, type,
+        base::BindOnce(&GetOriginsTask::OnUsageAndQuotaObtained, this, origin));
   }
 
   CheckDone();
 }
 
 void GetOriginsTask::OnUsageAndQuotaObtained(
-    const GURL& origin,
+    const url::Origin& origin,
     blink::mojom::QuotaStatusCode status_code,
     int64_t usage,
     int64_t quota) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (status_code == blink::mojom::QuotaStatusCode::kOk) {
-    origin_.push_back(origin.spec());
+    origin_.push_back(origin.GetURL().spec());
     usage_.push_back(usage);
     quota_.push_back(quota);
   }
@@ -126,8 +127,8 @@
 void GetOriginsTask::CheckDone() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (num_callbacks_received_ == num_callbacks_to_wait_) {
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
+    base::PostTaskWithTraits(
+        FROM_HERE, {BrowserThread::UI},
         base::BindOnce(&GetOriginsTask::DoneOnUIThread, this));
   } else if (num_callbacks_received_ > num_callbacks_to_wait_) {
     NOTREACHED();
@@ -144,7 +145,7 @@
   if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
     std::move(task).Run();
   } else {
-    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(task));
+    base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(task));
   }
 }
 
@@ -213,8 +214,7 @@
           StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE |
           StoragePartition::REMOVE_DATA_MASK_WEBSQL,
       StoragePartition::QUOTA_MANAGED_STORAGE_MASK_TEMPORARY, GURL(),
-      StoragePartition::OriginMatcherFunction(), base::Time(),
-      base::Time::Max(), base::DoNothing());
+      base::Time(), base::Time::Max(), base::DoNothing());
 }
 
 void AwQuotaManagerBridge::DeleteOrigin(JNIEnv* env,
@@ -286,8 +286,9 @@
     usage = 0;
     quota = 0;
   }
-  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-                          base::BindOnce(std::move(ui_callback), usage, quota));
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::UI},
+      base::BindOnce(std::move(ui_callback), usage, quota));
 }
 
 }  // namespace
@@ -314,10 +315,12 @@
       base::BindOnce(&AwQuotaManagerBridge::QuotaUsageCallbackImpl,
                      weak_factory_.GetWeakPtr(), callback_id, is_quota);
 
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
+  // TODO(crbug.com/889590): Use helper for url::Origin creation from string.
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::IO},
       base::BindOnce(
-          &QuotaManager::GetUsageAndQuota, GetQuotaManager(), GURL(origin),
+          &QuotaManager::GetUsageAndQuota, GetQuotaManager(),
+          url::Origin::Create(GURL(origin)),
           blink::mojom::StorageType::kTemporary,
           base::BindOnce(&OnUsageAndQuotaObtained, std::move(ui_callback))));
 }
diff --git a/android_webview/browser/aw_render_thread_context_provider.cc b/android_webview/browser/aw_render_thread_context_provider.cc
index b4a2e95..95e06d5 100644
--- a/android_webview/browser/aw_render_thread_context_provider.cc
+++ b/android_webview/browser/aw_render_thread_context_provider.cc
@@ -68,7 +68,7 @@
   context_ = std::make_unique<gpu::GLInProcessContext>();
   context_->Initialize(std::move(task_executor), surface,
                        surface->IsOffscreen(), gpu::kNullSurfaceHandle,
-                       attributes, limits, nullptr, nullptr, nullptr, nullptr);
+                       attributes, limits, nullptr, nullptr, nullptr);
 
   context_->GetImplementation()->SetLostContextCallback(base::BindOnce(
       &AwRenderThreadContextProvider::OnLostContext, base::Unretained(this)));
@@ -149,6 +149,11 @@
   return gr_context_.get();
 }
 
+gpu::SharedImageInterface*
+AwRenderThreadContextProvider::SharedImageInterface() {
+  return context_->GetSharedImageInterface();
+}
+
 viz::ContextCacheController* AwRenderThreadContextProvider::CacheController() {
   DCHECK(main_thread_checker_.CalledOnValidThread());
   return cache_controller_.get();
diff --git a/android_webview/browser/aw_render_thread_context_provider.h b/android_webview/browser/aw_render_thread_context_provider.h
index 1826dba..3767baf 100644
--- a/android_webview/browser/aw_render_thread_context_provider.h
+++ b/android_webview/browser/aw_render_thread_context_provider.h
@@ -51,6 +51,7 @@
   gpu::gles2::GLES2Interface* ContextGL() override;
   gpu::ContextSupport* ContextSupport() override;
   class GrContext* GrContext() override;
+  gpu::SharedImageInterface* SharedImageInterface() override;
   viz::ContextCacheController* CacheController() override;
   base::Lock* GetLock() override;
   void AddObserver(viz::ContextLostObserver* obs) override;
@@ -74,7 +75,7 @@
   sk_sp<class GrContext> gr_context_;
   std::unique_ptr<viz::ContextCacheController> cache_controller_;
 
-  base::ObserverList<viz::ContextLostObserver> observers_;
+  base::ObserverList<viz::ContextLostObserver>::Unchecked observers_;
 
   DISALLOW_COPY_AND_ASSIGN(AwRenderThreadContextProvider);
 };
diff --git a/android_webview/browser/aw_safe_browsing_blocking_page.cc b/android_webview/browser/aw_safe_browsing_blocking_page.cc
index d37765af..7d2a75a 100644
--- a/android_webview/browser/aw_safe_browsing_blocking_page.cc
+++ b/android_webview/browser/aw_safe_browsing_blocking_page.cc
@@ -101,8 +101,8 @@
             IsMainPageLoadBlocked(unsafe_resources),
             safe_browsing::IsExtendedReportingOptInAllowed(*pref_service),
             false,  // is_off_the_record
+            false,  // is_unified_consent_enabled
             safe_browsing::IsExtendedReportingEnabled(*pref_service),
-            safe_browsing::IsScout(*pref_service),
             safe_browsing::IsExtendedReportingPolicyManaged(*pref_service),
             pref_service->GetBoolean(
                 ::prefs::kSafeBrowsingProceedAnywayDisabled),
diff --git a/android_webview/browser/aw_safe_browsing_ui_manager.cc b/android_webview/browser/aw_safe_browsing_ui_manager.cc
index aee9b17..fdf15a4 100644
--- a/android_webview/browser/aw_safe_browsing_ui_manager.cc
+++ b/android_webview/browser/aw_safe_browsing_ui_manager.cc
@@ -11,12 +11,15 @@
 #include "base/command_line.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/path_service.h"
+#include "base/task/post_task.h"
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/base_ui_manager.h"
 #include "components/safe_browsing/browser/safe_browsing_network_context.h"
 #include "components/safe_browsing/browser/safe_browsing_url_request_context_getter.h"
 #include "components/safe_browsing/common/safebrowsing_constants.h"
+#include "components/safe_browsing/db/v4_protocol_manager_util.h"
 #include "components/safe_browsing/ping_manager.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/mojom/network_service.mojom.h"
@@ -104,8 +107,8 @@
 AwSafeBrowsingUIManager::GetURLLoaderFactoryOnIOThread() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (!shared_url_loader_factory_on_io_) {
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
+    base::PostTaskWithTraits(
+        FROM_HERE, {BrowserThread::UI},
         base::BindOnce(&AwSafeBrowsingUIManager::CreateURLLoaderFactoryForIO,
                        this, MakeRequest(&url_loader_factory_on_io_)));
     shared_url_loader_factory_on_io_ =
@@ -129,18 +132,10 @@
 
   if (!ping_manager_) {
     // Lazy creation of ping manager, needs to happen on IO thread.
-    safe_browsing::SafeBrowsingProtocolConfig config;
-    config.client_name = GetProtocolConfigClientName();
-    config.disable_auto_update = false;
-    config.url_prefix = ::safe_browsing::kSbDefaultURLPrefix;
-    config.backup_connect_error_url_prefix =
-        ::safe_browsing::kSbBackupConnectErrorURLPrefix;
-    config.backup_http_error_url_prefix =
-        ::safe_browsing::kSbBackupHttpErrorURLPrefix;
-    config.backup_network_error_url_prefix =
-        ::safe_browsing::kSbBackupNetworkErrorURLPrefix;
     ping_manager_ = ::safe_browsing::PingManager::Create(
-        network_context_->GetURLLoaderFactory(), config);
+        network_context_->GetURLLoaderFactory(),
+        safe_browsing::GetV4ProtocolConfig(GetProtocolConfigClientName(),
+                                           false /* disable_auto_update */));
   }
 
   if (!serialized.empty()) {
diff --git a/android_webview/browser/aw_settings.cc b/android_webview/browser/aw_settings.cc
index a98fd91..e9aa707 100644
--- a/android_webview/browser/aw_settings.cc
+++ b/android_webview/browser/aw_settings.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 
+#include "android_webview/browser/aw_browser_context.h"
 #include "android_webview/browser/aw_content_browser_client.h"
 #include "android_webview/browser/aw_contents.h"
 #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h"
@@ -13,14 +14,17 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
 #include "base/macros.h"
+#include "base/no_destructor.h"
 #include "base/supports_user_data.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/render_view_host.h"
+#include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/renderer_preferences.h"
 #include "content/public/common/web_preferences.h"
 #include "jni/AwSettings_jni.h"
+#include "services/network/public/cpp/features.h"
 #include "ui/gfx/font_render_params.h"
 
 using base::android::ConvertJavaStringToUTF16;
@@ -36,15 +40,14 @@
 
 void PopulateFixedRendererPreferences(RendererPreferences* prefs) {
   // TODO(boliu): Deduplicate with chrome/ code.
-  CR_DEFINE_STATIC_LOCAL(
-      const gfx::FontRenderParams, params,
-      (gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), NULL)));
-  prefs->should_antialias_text = params.antialiasing;
-  prefs->use_subpixel_positioning = params.subpixel_positioning;
-  prefs->hinting = params.hinting;
-  prefs->use_autohinter = params.autohinter;
-  prefs->use_bitmaps = params.use_bitmaps;
-  prefs->subpixel_rendering = params.subpixel_rendering;
+  static const base::NoDestructor<gfx::FontRenderParams> params(
+      gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr));
+  prefs->should_antialias_text = params->antialiasing;
+  prefs->use_subpixel_positioning = params->subpixel_positioning;
+  prefs->hinting = params->hinting;
+  prefs->use_autohinter = params->autohinter;
+  prefs->use_bitmaps = params->use_bitmaps;
+  prefs->subpixel_rendering = params->subpixel_rendering;
 }
 
 void PopulateFixedWebPreferences(WebPreferences* web_prefs) {
@@ -243,6 +246,18 @@
   content::RenderViewHost* host = web_contents()->GetRenderViewHost();
   if (update_prefs && host)
     host->SyncRendererPrefs();
+
+  if (update_prefs &&
+      base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+    // make sure to update accept languages when the network service is enabled
+    AwBrowserContext* aw_browser_context =
+        AwBrowserContext::FromWebContents(web_contents());
+    // AndroidWebview does not use per-site storage partitions.
+    content::StoragePartition* storage_partition =
+        content::BrowserContext::GetDefaultStoragePartition(aw_browser_context);
+    storage_partition->GetNetworkContext()->SetAcceptLanguage(
+        prefs->accept_languages);
+  }
 }
 
 void AwSettings::UpdateOffscreenPreRasterLocked(
diff --git a/android_webview/browser/aw_url_checker_delegate_impl.cc b/android_webview/browser/aw_url_checker_delegate_impl.cc
index 0de75e6..b3a5031 100644
--- a/android_webview/browser/aw_url_checker_delegate_impl.cc
+++ b/android_webview/browser/aw_url_checker_delegate_impl.cc
@@ -10,10 +10,14 @@
 #include "android_webview/browser/aw_safe_browsing_whitelist_manager.h"
 #include "android_webview/browser/net/aw_web_resource_request.h"
 #include "base/bind.h"
+#include "base/feature_list.h"
+#include "base/task/post_task.h"
 #include "components/safe_browsing/db/database_manager.h"
 #include "components/safe_browsing/db/v4_protocol_manager_util.h"
+#include "components/safe_browsing/features.h"
 #include "components/security_interstitials/content/unsafe_resource.h"
 #include "components/security_interstitials/core/urls.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
@@ -28,8 +32,13 @@
       ui_manager_(std::move(ui_manager)),
       threat_types_(safe_browsing::CreateSBThreatTypeSet(
           {safe_browsing::SB_THREAT_TYPE_URL_MALWARE,
-           safe_browsing::SB_THREAT_TYPE_URL_PHISHING})),
-      whitelist_manager_(whitelist_manager) {}
+           safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+           safe_browsing::SB_THREAT_TYPE_URL_UNWANTED})),
+      whitelist_manager_(whitelist_manager) {
+  if (base::FeatureList::IsEnabled(safe_browsing::kBillingInterstitial)) {
+    threat_types_.insert(safe_browsing::SB_THREAT_TYPE_BILLING);
+  }
+}
 
 AwUrlCheckerDelegateImpl::~AwUrlCheckerDelegateImpl() = default;
 
@@ -45,8 +54,8 @@
   AwWebResourceRequest request(resource.url.spec(), method, is_main_frame,
                                has_user_gesture, headers);
 
-  content::BrowserThread::PostTask(
-      content::BrowserThread::UI, FROM_HERE,
+  base::PostTaskWithTraits(
+      FROM_HERE, {content::BrowserThread::UI},
       base::BindOnce(&AwUrlCheckerDelegateImpl::StartApplicationResponse,
                      ui_manager_, resource, std::move(request)));
 }
@@ -127,8 +136,8 @@
   bool proceed;
   switch (action) {
     case SafeBrowsingAction::SHOW_INTERSTITIAL:
-      content::BrowserThread::PostTask(
-          content::BrowserThread::UI, FROM_HERE,
+      base::PostTaskWithTraits(
+          FROM_HERE, {content::BrowserThread::UI},
           base::BindOnce(
               &AwUrlCheckerDelegateImpl::StartDisplayingDefaultBlockingPage,
               ui_manager, resource));
@@ -174,8 +183,8 @@
   }
 
   // Reporting back that it is not okay to proceed with loading the URL.
-  content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
-                                   base::BindOnce(resource.callback, false));
+  base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+                           base::BindOnce(resource.callback, false));
 }
 
 }  // namespace android_webview
diff --git a/android_webview/browser/aw_variations_seed_bridge.cc b/android_webview/browser/aw_variations_seed_bridge.cc
index aeee02e..7102357 100644
--- a/android_webview/browser/aw_variations_seed_bridge.cc
+++ b/android_webview/browser/aw_variations_seed_bridge.cc
@@ -36,11 +36,8 @@
       Java_AwVariationsSeedBridge_getData(env);
   Java_AwVariationsSeedBridge_clearSeed(env);
 
-  std::vector<uint8_t> u8_data;
-  JavaByteArrayToByteVector(env, j_data.obj(), &u8_data);
-
   auto java_seed = std::make_unique<variations::SeedResponse>();
-  java_seed->data = std::string(u8_data.begin(), u8_data.end());
+  base::android::JavaByteArrayToString(env, j_data, &java_seed->data);
   java_seed->signature = ConvertJavaStringToUTF8(j_signature);
   java_seed->country = ConvertJavaStringToUTF8(j_country);
   java_seed->date = ConvertJavaStringToUTF8(j_date);
diff --git a/android_webview/browser/aw_variations_service_client.cc b/android_webview/browser/aw_variations_service_client.cc
index fe14b44..af22333 100644
--- a/android_webview/browser/aw_variations_service_client.cc
+++ b/android_webview/browser/aw_variations_service_client.cc
@@ -18,7 +18,7 @@
 // Gets the version number to use for variations seed simulation. Must be called
 // on a thread where IO is allowed.
 base::Version GetVersionForSimulation() {
-  base::AssertBlockingAllowed();
+  base::AssertBlockingAllowedDeprecated();
   return version_info::GetVersion();
 }
 
@@ -28,10 +28,6 @@
 
 AwVariationsServiceClient::~AwVariationsServiceClient() {}
 
-std::string AwVariationsServiceClient::GetApplicationLocale() {
-  return std::string();
-}
-
 base::Callback<base::Version(void)>
 AwVariationsServiceClient::GetVersionForSimulationCallback() {
   return base::BindRepeating(&GetVersionForSimulation);
@@ -48,7 +44,10 @@
 }
 
 Channel AwVariationsServiceClient::GetChannel() {
-  return android_webview::GetChannel();
+  // Pretend stand-alone WebView is always "stable" for the purpose of
+  // variations. This simplifies experiment design, since stand-alone WebView
+  // need not be considered separately when choosing channels.
+  return android_webview::GetChannelOrStable();
 }
 
 bool AwVariationsServiceClient::GetSupportsPermanentConsistency() {
diff --git a/android_webview/browser/aw_variations_service_client.h b/android_webview/browser/aw_variations_service_client.h
index 0caf0fd..c313038 100644
--- a/android_webview/browser/aw_variations_service_client.h
+++ b/android_webview/browser/aw_variations_service_client.h
@@ -25,7 +25,6 @@
   ~AwVariationsServiceClient() override;
 
  private:
-  std::string GetApplicationLocale() override;
   base::Callback<base::Version(void)> GetVersionForSimulationCallback()
       override;
   scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
diff --git a/android_webview/browser/aw_web_contents_delegate.cc b/android_webview/browser/aw_web_contents_delegate.cc
index cb84f9c..f74aef0 100644
--- a/android_webview/browser/aw_web_contents_delegate.cc
+++ b/android_webview/browser/aw_web_contents_delegate.cc
@@ -20,13 +20,13 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "components/navigation_interception/intercept_navigation_delegate.h"
+#include "content/public/browser/file_select_listener.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/common/file_chooser_file_info.h"
-#include "content/public/common/file_chooser_params.h"
 #include "content/public/common/media_stream_request.h"
 #include "jni/AwWebContentsDelegate_jni.h"
 #include "net/base/escape.h"
@@ -36,7 +36,9 @@
 using base::android::ConvertUTF8ToJavaString;
 using base::android::JavaParamRef;
 using base::android::ScopedJavaLocalRef;
-using content::FileChooserParams;
+using blink::mojom::FileChooserFileInfo;
+using blink::mojom::FileChooserFileInfoPtr;
+using blink::mojom::FileChooserParams;
 using content::WebContents;
 
 namespace android_webview {
@@ -88,26 +90,31 @@
 
 void AwWebContentsDelegate::RunFileChooser(
     content::RenderFrameHost* render_frame_host,
+    std::unique_ptr<content::FileSelectListener> listener,
     const FileChooserParams& params) {
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jobject> java_delegate = GetJavaDelegate(env);
-  if (!java_delegate.obj())
+  if (!java_delegate.obj()) {
+    listener->FileSelectionCanceled();
     return;
+  }
 
   int mode_flags = 0;
-  if (params.mode == FileChooserParams::OpenMultiple) {
+  if (params.mode == FileChooserParams::Mode::kOpenMultiple) {
     mode_flags |= kFileChooserModeOpenMultiple;
-  } else if (params.mode == FileChooserParams::UploadFolder) {
+  } else if (params.mode == FileChooserParams::Mode::kUploadFolder) {
     // Folder implies multiple in Chrome.
     mode_flags |= kFileChooserModeOpenMultiple | kFileChooserModeOpenFolder;
-  } else if (params.mode == FileChooserParams::Save) {
+  } else if (params.mode == FileChooserParams::Mode::kSave) {
     // Save not supported, so cancel it.
-    render_frame_host->FilesSelectedInChooser(
-        std::vector<content::FileChooserFileInfo>(), params.mode);
+    listener->FileSelectionCanceled();
     return;
   } else {
-    DCHECK_EQ(FileChooserParams::Open, params.mode);
+    DCHECK_EQ(FileChooserParams::Mode::kOpen, params.mode);
   }
+  DCHECK(!file_select_listener_)
+      << "Multiple concurrent FileChooser requests are not supported.";
+  file_select_listener_ = std::move(listener);
   Java_AwWebContentsDelegate_runFileChooser(
       env, java_delegate, render_frame_host->GetProcess()->GetID(),
       render_frame_host->GetRoutingID(), mode_flags,
@@ -118,7 +125,7 @@
       params.default_file_name.empty()
           ? nullptr
           : ConvertUTF8ToJavaString(env, params.default_file_name.value()),
-      params.capture);
+      params.use_media_capture);
 }
 
 void AwWebContentsDelegate::AddNewContents(
@@ -267,6 +274,19 @@
   return is_fullscreen_;
 }
 
+void AwWebContentsDelegate::UpdateUserGestureCarryoverInfo(
+    content::WebContents* web_contents) {
+  auto* intercept_navigation_delegate =
+      navigation_interception::InterceptNavigationDelegate::Get(web_contents);
+  if (intercept_navigation_delegate)
+    intercept_navigation_delegate->UpdateLastUserGestureCarryoverTimestamp();
+}
+
+std::unique_ptr<content::FileSelectListener>
+AwWebContentsDelegate::TakeFileSelectListener() {
+  return std::move(file_select_listener_);
+}
+
 static void JNI_AwWebContentsDelegate_FilesSelectedInChooser(
     JNIEnv* env,
     const JavaParamRef<jclass>& clazz,
@@ -277,17 +297,29 @@
     const JavaParamRef<jobjectArray>& display_names) {
   content::RenderFrameHost* rfh =
       content::RenderFrameHost::FromID(process_id, render_id);
-  if (!rfh)
+  auto* web_contents = WebContents::FromRenderFrameHost(rfh);
+  if (!web_contents)
     return;
+  auto* delegate =
+      static_cast<AwWebContentsDelegate*>(web_contents->GetDelegate());
+  if (!delegate)
+    return;
+  std::unique_ptr<content::FileSelectListener> listener =
+      delegate->TakeFileSelectListener();
+
+  if (!file_paths.obj()) {
+    listener->FileSelectionCanceled();
+    return;
+  }
 
   std::vector<std::string> file_path_str;
-  std::vector<std::string> display_name_str;
+  std::vector<base::string16> display_name_str;
   // Note file_paths maybe NULL, but this will just yield a zero-length vector.
   base::android::AppendJavaStringArrayToStringVector(env, file_paths,
                                                      &file_path_str);
   base::android::AppendJavaStringArrayToStringVector(env, display_names,
                                                      &display_name_str);
-  std::vector<content::FileChooserFileInfo> files;
+  std::vector<FileChooserFileInfoPtr> files;
   files.reserve(file_path_str.size());
   for (size_t i = 0; i < file_path_str.size(); ++i) {
     GURL url(file_path_str[i]);
@@ -300,23 +332,23 @@
                                   net::UnescapeRule::
                                       URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS)
             : file_path_str[i]);
-    content::FileChooserFileInfo file_info;
-    file_info.file_path = path;
+    auto file_info = blink::mojom::NativeFileInfo::New();
+    file_info->file_path = path;
     if (!display_name_str[i].empty())
-      file_info.display_name = display_name_str[i];
-    files.push_back(file_info);
+      file_info->display_name = display_name_str[i];
+    files.push_back(FileChooserFileInfo::NewNativeFile(std::move(file_info)));
   }
   FileChooserParams::Mode mode;
   if (mode_flags & kFileChooserModeOpenFolder) {
-    mode = FileChooserParams::UploadFolder;
+    mode = FileChooserParams::Mode::kUploadFolder;
   } else if (mode_flags & kFileChooserModeOpenMultiple) {
-    mode = FileChooserParams::OpenMultiple;
+    mode = FileChooserParams::Mode::kOpenMultiple;
   } else {
-    mode = FileChooserParams::Open;
+    mode = FileChooserParams::Mode::kOpen;
   }
   DVLOG(0) << "File Chooser result: mode = " << mode
            << ", file paths = " << base::JoinString(file_path_str, ":");
-  rfh->FilesSelectedInChooser(files, mode);
+  listener->FileSelected(std::move(files), mode);
 }
 
 }  // namespace android_webview
diff --git a/android_webview/browser/aw_web_contents_delegate.h b/android_webview/browser/aw_web_contents_delegate.h
index e78cab1..1abe7b4 100644
--- a/android_webview/browser/aw_web_contents_delegate.h
+++ b/android_webview/browser/aw_web_contents_delegate.h
@@ -29,7 +29,8 @@
                    const std::string& request_method,
                    const base::Callback<void(bool)>& callback) override;
   void RunFileChooser(content::RenderFrameHost* render_frame_host,
-                      const content::FileChooserParams& params) override;
+                      std::unique_ptr<content::FileSelectListener> listener,
+                      const blink::mojom::FileChooserParams& params) override;
   void AddNewContents(content::WebContents* source,
                       std::unique_ptr<content::WebContents> new_contents,
                       WindowOpenDisposition disposition,
@@ -62,9 +63,17 @@
   void ExitFullscreenModeForTab(content::WebContents* web_contents) override;
   bool IsFullscreenForTabOrPending(
       const content::WebContents* web_contents) const override;
+  void UpdateUserGestureCarryoverInfo(
+      content::WebContents* web_contents) override;
+
+  std::unique_ptr<content::FileSelectListener> TakeFileSelectListener();
 
  private:
   bool is_fullscreen_;
+
+  // Maintain a FileSelectListener instance passed to RunFileChooser() until
+  // a callback is called.
+  std::unique_ptr<content::FileSelectListener> file_select_listener_;
 };
 
 }  // namespace android_webview
diff --git a/android_webview/browser/aw_web_ui_controller_factory.cc b/android_webview/browser/aw_web_ui_controller_factory.cc
index 29db65e..876da06 100644
--- a/android_webview/browser/aw_web_ui_controller_factory.cc
+++ b/android_webview/browser/aw_web_ui_controller_factory.cc
@@ -8,6 +8,7 @@
 #include "components/safe_browsing/web_ui/constants.h"
 #include "components/safe_browsing/web_ui/safe_browsing_ui.h"
 #include "content/public/browser/web_ui.h"
+#include "url/gurl.h"
 
 using content::WebUI;
 using content::WebUIController;
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc
index 2f87ef1..055c042d 100644
--- a/android_webview/browser/browser_view_renderer.cc
+++ b/android_webview/browser/browser_view_renderer.cc
@@ -15,7 +15,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/supports_user_data.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
 #include "components/viz/common/quads/compositor_frame.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
@@ -257,6 +257,12 @@
   return viewport_rect_for_tile_priority;
 }
 
+void BrowserViewRenderer::ReturnedResourceAvailable(
+    CompositorFrameConsumer* compositor_frame_consumer) {
+  DCHECK(compositor_frame_consumers_.count(compositor_frame_consumer));
+  ReturnResourceFromParent(compositor_frame_consumer);
+}
+
 void BrowserViewRenderer::OnParentDrawConstraintsUpdated(
     CompositorFrameConsumer* compositor_frame_consumer) {
   DCHECK(compositor_frame_consumer);
@@ -350,21 +356,17 @@
   SkPictureRecorder recorder;
   SkCanvas* rec_canvas = recorder.beginRecording(width, height, NULL, 0);
   if (compositor_) {
-    gfx::Vector2dF scroll_offset =
-        content::IsUseZoomForDSFEnabled()
-            ? gfx::ScaleVector2d(scroll_offset_dip_, dip_scale_)
-            : scroll_offset_dip_;
     {
       // Reset scroll back to the origin, will go back to the old
       // value when scroll_reset is out of scope.
-      base::AutoReset<gfx::Vector2dF> scroll_reset(&scroll_offset_dip_,
+      base::AutoReset<gfx::Vector2dF> scroll_reset(&scroll_offset_unscaled_,
                                                    gfx::Vector2dF());
       compositor_->DidChangeRootLayerScrollOffset(
-          gfx::ScrollOffset(scroll_offset));
+          gfx::ScrollOffset(scroll_offset_unscaled_));
       CompositeSW(rec_canvas);
     }
     compositor_->DidChangeRootLayerScrollOffset(
-        gfx::ScrollOffset(scroll_offset));
+        gfx::ScrollOffset(scroll_offset_unscaled_));
   }
   return recorder.finishRecordingAsPicture();
 }
@@ -562,53 +564,53 @@
 
 gfx::Vector2d BrowserViewRenderer::max_scroll_offset() const {
   DCHECK_GT(dip_scale_, 0.f);
-  return gfx::ToCeiledVector2d(gfx::ScaleVector2d(
-      max_scroll_offset_dip_, dip_scale_ * page_scale_factor_));
+  float scale = content::IsUseZoomForDSFEnabled()
+                    ? page_scale_factor_
+                    : dip_scale_ * page_scale_factor_;
+  return gfx::ToCeiledVector2d(
+      gfx::ScaleVector2d(max_scroll_offset_unscaled_, scale));
 }
 
 void BrowserViewRenderer::ScrollTo(const gfx::Vector2d& scroll_offset) {
   gfx::Vector2d max_offset = max_scroll_offset();
-  gfx::Vector2dF scroll_offset_dip;
+  gfx::Vector2dF scroll_offset_unscaled;
   // To preserve the invariant that scrolling to the maximum physical pixel
   // value also scrolls to the maximum dip pixel value we transform the physical
   // offset into the dip offset by using a proportion (instead of dividing by
   // dip_scale * page_scale_factor).
   if (max_offset.x()) {
-    scroll_offset_dip.set_x((scroll_offset.x() * max_scroll_offset_dip_.x()) /
-                            max_offset.x());
+    scroll_offset_unscaled.set_x(
+        (scroll_offset.x() * max_scroll_offset_unscaled_.x()) / max_offset.x());
   }
   if (max_offset.y()) {
-    scroll_offset_dip.set_y((scroll_offset.y() * max_scroll_offset_dip_.y()) /
-                            max_offset.y());
+    scroll_offset_unscaled.set_y(
+        (scroll_offset.y() * max_scroll_offset_unscaled_.y()) / max_offset.y());
   }
 
-  DCHECK_LE(0.f, scroll_offset_dip.x());
-  DCHECK_LE(0.f, scroll_offset_dip.y());
-  DCHECK(scroll_offset_dip.x() < max_scroll_offset_dip_.x() ||
-         scroll_offset_dip.x() - max_scroll_offset_dip_.x() < kEpsilon)
-      << scroll_offset_dip.x() << " " << max_scroll_offset_dip_.x();
-  DCHECK(scroll_offset_dip.y() < max_scroll_offset_dip_.y() ||
-         scroll_offset_dip.y() - max_scroll_offset_dip_.y() < kEpsilon)
-      << scroll_offset_dip.y() << " " << max_scroll_offset_dip_.y();
+  DCHECK_LE(0.f, scroll_offset_unscaled.x());
+  DCHECK_LE(0.f, scroll_offset_unscaled.y());
+  DCHECK(scroll_offset_unscaled.x() < max_scroll_offset_unscaled_.x() ||
+         scroll_offset_unscaled.x() - max_scroll_offset_unscaled_.x() <
+             kEpsilon)
+      << scroll_offset_unscaled.x() << " " << max_scroll_offset_unscaled_.x();
+  DCHECK(scroll_offset_unscaled.y() < max_scroll_offset_unscaled_.y() ||
+         scroll_offset_unscaled.y() - max_scroll_offset_unscaled_.y() <
+             kEpsilon)
+      << scroll_offset_unscaled.y() << " " << max_scroll_offset_unscaled_.y();
 
-  if (scroll_offset_dip_ == scroll_offset_dip)
+  if (scroll_offset_unscaled_ == scroll_offset_unscaled)
     return;
 
-  scroll_offset_dip_ = scroll_offset_dip;
+  scroll_offset_unscaled_ = scroll_offset_unscaled;
 
-  TRACE_EVENT_INSTANT2("android_webview",
-               "BrowserViewRenderer::ScrollTo",
-               TRACE_EVENT_SCOPE_THREAD,
-               "x",
-               scroll_offset_dip.x(),
-               "y",
-               scroll_offset_dip.y());
+  TRACE_EVENT_INSTANT2("android_webview", "BrowserViewRenderer::ScrollTo",
+                       TRACE_EVENT_SCOPE_THREAD, "x",
+                       scroll_offset_unscaled.x(), "y",
+                       scroll_offset_unscaled.y());
 
-  if (compositor_) {
-    compositor_->DidChangeRootLayerScrollOffset(gfx::ScrollOffset(
-        content::IsUseZoomForDSFEnabled() ? scroll_offset
-                                          : scroll_offset_dip_));
-  }
+  if (compositor_)
+    compositor_->DidChangeRootLayerScrollOffset(
+        gfx::ScrollOffset(scroll_offset_unscaled));
 }
 
 void BrowserViewRenderer::DidUpdateContent(
@@ -625,23 +627,25 @@
 }
 
 void BrowserViewRenderer::SetTotalRootLayerScrollOffset(
-    const gfx::Vector2dF& scroll_offset_dip) {
-  if (scroll_offset_dip_ == scroll_offset_dip)
+    const gfx::Vector2dF& scroll_offset_unscaled) {
+  if (scroll_offset_unscaled_ == scroll_offset_unscaled)
     return;
-  scroll_offset_dip_ = scroll_offset_dip;
+  scroll_offset_unscaled_ = scroll_offset_unscaled;
 
   gfx::Vector2d max_offset = max_scroll_offset();
   gfx::Vector2d scroll_offset;
   // For an explanation as to why this is done this way see the comment in
   // BrowserViewRenderer::ScrollTo.
-  if (max_scroll_offset_dip_.x()) {
-    scroll_offset.set_x((scroll_offset_dip.x() * max_offset.x()) /
-                        max_scroll_offset_dip_.x());
+  if (max_scroll_offset_unscaled_.x()) {
+    scroll_offset.set_x(
+        gfx::ToRoundedInt((scroll_offset_unscaled.x() * max_offset.x()) /
+                          max_scroll_offset_unscaled_.x()));
   }
 
-  if (max_scroll_offset_dip_.y()) {
-    scroll_offset.set_y((scroll_offset_dip.y() * max_offset.y()) /
-                        max_scroll_offset_dip_.y());
+  if (max_scroll_offset_unscaled_.y()) {
+    scroll_offset.set_y(
+        gfx::ToRoundedInt((scroll_offset_unscaled.y() * max_offset.y()) /
+                          max_scroll_offset_unscaled_.y()));
   }
 
   DCHECK_LE(0, scroll_offset.x());
@@ -663,34 +667,27 @@
   if (compositor != compositor_)
     return;
 
-  gfx::Vector2dF total_scroll_offset_dip = total_scroll_offset;
-  gfx::Vector2dF max_scroll_offset_dip = total_max_scroll_offset;
   gfx::SizeF scrollable_size_dip = scrollable_size;
-  if (content::IsUseZoomForDSFEnabled()) {
-    total_scroll_offset_dip.Scale(1 / dip_scale_);
-    max_scroll_offset_dip.Scale(1 / dip_scale_);
+  if (content::IsUseZoomForDSFEnabled())
     scrollable_size_dip.Scale(1 / dip_scale_);
-  }
 
   TRACE_EVENT_INSTANT1(
-      "android_webview",
-      "BrowserViewRenderer::UpdateRootLayerState",
-      TRACE_EVENT_SCOPE_THREAD,
-      "state",
-      RootLayerStateAsValue(total_scroll_offset_dip, scrollable_size_dip));
+      "android_webview", "BrowserViewRenderer::UpdateRootLayerState",
+      TRACE_EVENT_SCOPE_THREAD, "state",
+      RootLayerStateAsValue(total_scroll_offset, scrollable_size_dip));
 
-  DCHECK_GE(max_scroll_offset_dip.x(), 0.f);
-  DCHECK_GE(max_scroll_offset_dip.y(), 0.f);
+  DCHECK_GE(total_max_scroll_offset.x(), 0.f);
+  DCHECK_GE(total_max_scroll_offset.y(), 0.f);
   DCHECK_GT(page_scale_factor, 0.f);
   // SetDipScale should have been called at least once before this is called.
   DCHECK_GT(dip_scale_, 0.f);
 
-  if (max_scroll_offset_dip_ != max_scroll_offset_dip ||
+  if (max_scroll_offset_unscaled_ != total_max_scroll_offset ||
       scrollable_size_dip_ != scrollable_size_dip ||
       page_scale_factor_ != page_scale_factor ||
       min_page_scale_factor_ != min_page_scale_factor ||
       max_page_scale_factor_ != max_page_scale_factor) {
-    max_scroll_offset_dip_ = max_scroll_offset_dip;
+    max_scroll_offset_unscaled_ = total_max_scroll_offset;
     scrollable_size_dip_ = scrollable_size_dip;
     page_scale_factor_ = page_scale_factor;
     min_page_scale_factor_ = min_page_scale_factor;
@@ -700,21 +697,23 @@
                                page_scale_factor, min_page_scale_factor,
                                max_page_scale_factor);
   }
-  SetTotalRootLayerScrollOffset(total_scroll_offset_dip);
+  SetTotalRootLayerScrollOffset(total_scroll_offset);
 }
 
 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
 BrowserViewRenderer::RootLayerStateAsValue(
-    const gfx::Vector2dF& total_scroll_offset_dip,
+    const gfx::Vector2dF& total_scroll_offset,
     const gfx::SizeF& scrollable_size_dip) {
   std::unique_ptr<base::trace_event::TracedValue> state(
       new base::trace_event::TracedValue());
 
-  state->SetDouble("total_scroll_offset_dip.x", total_scroll_offset_dip.x());
-  state->SetDouble("total_scroll_offset_dip.y", total_scroll_offset_dip.y());
+  state->SetDouble("total_scroll_offset.x", total_scroll_offset.x());
+  state->SetDouble("total_scroll_offset.y", total_scroll_offset.y());
 
-  state->SetDouble("max_scroll_offset_dip.x", max_scroll_offset_dip_.x());
-  state->SetDouble("max_scroll_offset_dip.y", max_scroll_offset_dip_.y());
+  state->SetDouble("max_scroll_offset_unscaled.x",
+                   max_scroll_offset_unscaled_.x());
+  state->SetDouble("max_scroll_offset_unscaled.y",
+                   max_scroll_offset_unscaled_.y());
 
   state->SetDouble("scrollable_size_dip.width", scrollable_size_dip.width());
   state->SetDouble("scrollable_size_dip.height", scrollable_size_dip.height());
@@ -777,8 +776,8 @@
   base::StringAppendF(&str,
                       "global visible rect: %s ",
                       last_on_draw_global_visible_rect_.ToString().c_str());
-  base::StringAppendF(
-      &str, "scroll_offset_dip: %s ", scroll_offset_dip_.ToString().c_str());
+  base::StringAppendF(&str, "scroll_offset_unscaled: %s ",
+                      scroll_offset_unscaled_.ToString().c_str());
   base::StringAppendF(&str,
                       "overscroll_rounding_error_: %s ",
                       overscroll_rounding_error_.ToString().c_str());
diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/browser_view_renderer.h
index bfb23dd..ebd1893 100644
--- a/android_webview/browser/browser_view_renderer.h
+++ b/android_webview/browser/browser_view_renderer.h
@@ -100,7 +100,8 @@
   float dip_scale() const { return dip_scale_; }
   float page_scale_factor() const { return page_scale_factor_; }
 
-  // Set the root layer scroll offset to |new_value|.
+  // Set the root layer scroll offset to |new_value|. The |new_value| here is in
+  // physical pixel.
   void ScrollTo(const gfx::Vector2d& new_value);
 
   // Android views hierarchy gluing.
@@ -140,6 +141,8 @@
   ui::TouchHandleDrawable* CreateDrawable() override;
 
   // CompositorFrameProducer overrides
+  void ReturnedResourceAvailable(
+      CompositorFrameConsumer* compositor_frame_consumer) override;
   void OnParentDrawConstraintsUpdated(
       CompositorFrameConsumer* compositor_frame_consumer) override;
   void RemoveCompositorFrameConsumer(
@@ -224,11 +227,13 @@
 
   gfx::SizeF scrollable_size_dip_;
 
-  // TODO(miletus): Make scroll_offset_dip_ a gfx::ScrollOffset.
-  gfx::Vector2dF scroll_offset_dip_;
+  // When zoom-for-dsf enabled |max_scroll_offset_unscaled_| and
+  // |scroll_offset_unscaled_| is in physical pixel; otherwise, they are in dip
+  // TODO(miletus): Make scroll_offset_unscaled_ a gfx::ScrollOffset.
+  gfx::Vector2dF scroll_offset_unscaled_;
 
-  // TODO(miletus): Make max_scroll_offset_dip_ a gfx::ScrollOffset.
-  gfx::Vector2dF max_scroll_offset_dip_;
+  // TODO(miletus): Make max_scroll_offset_unscaled_ a gfx::ScrollOffset.
+  gfx::Vector2dF max_scroll_offset_unscaled_;
 
   // Used to prevent rounding errors from accumulating enough to generate
   // visible skew (especially noticeable when scrolling up and down in the same
diff --git a/android_webview/browser/browser_view_renderer_unittest.cc b/android_webview/browser/browser_view_renderer_unittest.cc
index 6d7b50d..f44b0ea 100644
--- a/android_webview/browser/browser_view_renderer_unittest.cc
+++ b/android_webview/browser/browser_view_renderer_unittest.cc
@@ -14,8 +14,10 @@
 #include "android_webview/browser/test/rendering_test.h"
 #include "base/location.h"
 #include "base/single_thread_task_runner.h"
+#include "base/stl_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/viz/common/quads/compositor_frame.h"
+#include "content/public/common/use_zoom_for_dsf_policy.h"
 #include "content/public/test/test_synchronous_compositor_android.h"
 
 namespace android_webview {
@@ -249,6 +251,70 @@
 
 RENDERING_TEST_F(TestAnimateInAndOutOfScreen);
 
+class TestAnimateOnScreenWithoutOnDraw : public RenderingTest {
+ public:
+  void StartTest() override {
+    browser_view_renderer_->PostInvalidate(ActiveCompositor());
+  }
+
+  void WillOnDraw() override {
+    RenderingTest::WillOnDraw();
+    // Set empty tile viewport on first frame.
+    browser_view_renderer_->PrepareToDraw(gfx::Vector2d(), gfx::Rect());
+  }
+
+  void DidOnDraw(bool success) override {
+    EXPECT_TRUE(success);
+    on_draw_count_++;
+  }
+
+  bool WillDrawOnRT(AwDrawGLInfo* draw_info) override {
+    will_draw_on_rt_count_++;
+    // What happens in practice is draw functor is skipped initially since
+    // it is offscreen so entirely clipped. Then later, the webview is moved
+    // onscreen without another OnDrawon UI thread, and draw functor is called
+    // with non-empty clip. Here in the test we pretend this second draw happens
+    // immediately.
+    bool result = RenderingTest::WillDrawOnRT(draw_info);
+    assertNonEmptyClip(draw_info);
+    return result;
+  }
+
+  void OnParentDrawConstraintsUpdated() override {
+    switch (on_draw_count_) {
+      case 0:
+        // This OnParentDrawConstraintsUpdated is generated by
+        // connecting the compositor frame consumer to the producer.
+        break;
+      case 1:
+        // DrawOnRT skipped for frame 1 so this should not happen.
+        EXPECT_TRUE(window_->on_draw_hardware_pending());
+        EndTest();
+        break;
+      case 2:
+        // Might happen due to invalidate on_draw_hardware_pending from
+        // previous frame.
+        break;
+      default:
+        FAIL();
+        break;
+    }
+  }
+
+ private:
+  void assertNonEmptyClip(AwDrawGLInfo* draw_info) {
+    gfx::Rect clip(draw_info->clip_left, draw_info->clip_top,
+                   draw_info->clip_right - draw_info->clip_left,
+                   draw_info->clip_bottom - draw_info->clip_top);
+    ASSERT_FALSE(clip.IsEmpty());
+  }
+
+  int on_draw_count_ = 0;
+  int will_draw_on_rt_count_ = 0;
+};
+
+RENDERING_TEST_F(TestAnimateOnScreenWithoutOnDraw);
+
 class CompositorNoFrameTest : public RenderingTest {
  public:
   CompositorNoFrameTest() : on_draw_count_(0) {}
@@ -408,7 +474,7 @@
         // Second output surface.
         {1u, 1u}, {1u, 1u}, {1u, 2u}, {1u, 2u}, {1u, 3u}, {1u, 3u}, {1u, 4u},
     };
-    if (frame_number >= static_cast<int>(arraysize(infos))) {
+    if (frame_number >= static_cast<int>(base::size(infos))) {
       return nullptr;
     }
 
@@ -547,4 +613,60 @@
 
 RENDERING_TEST_F(RenderThreadManagerSwitchTest);
 
+// Test for https://crbug.com/881458, this test is to make sure we will reach
+// the maximal scroll offset.
+class DidReachMaximalScrollOffsetTest : public RenderingTest {
+ public:
+  void StartTest() override {
+    browser_view_renderer_->SetDipScale(kDipScale);
+    gfx::Vector2dF total_scroll_offset = kTotalScrollOffset;
+    gfx::Vector2dF total_max_scroll_offset = kTotalMaxScrollOffset;
+    gfx::SizeF scrollable_size = kScrollableSize;
+    // When --use-zoom-for-dsf is enabled, these value are in physical pixel.
+    if (content::IsUseZoomForDSFEnabled()) {
+      total_scroll_offset.Scale(kDipScale);
+      total_max_scroll_offset.Scale(kDipScale);
+      scrollable_size.Scale(kDipScale);
+    }
+    // |UpdateRootLayerState()| will call |SetTotalRootLayerScrollOffset()|.
+    browser_view_renderer_->UpdateRootLayerState(
+        ActiveCompositor(), total_scroll_offset, total_max_scroll_offset,
+        scrollable_size, kPageScaleFactor, kMinPageScaleFactor,
+        kMaxPageScaleFactor);
+  }
+
+  void ScrollContainerViewTo(const gfx::Vector2d& new_value) override {
+    EXPECT_EQ(kExpectedScrollOffset.ToString(), new_value.ToString());
+    EndTest();
+  }
+
+ private:
+  static constexpr float kDipScale = 2.625f;
+  static const gfx::Vector2dF kTotalScrollOffset;
+  static const gfx::Vector2dF kTotalMaxScrollOffset;
+  static const gfx::SizeF kScrollableSize;
+  static constexpr float kPageScaleFactor = 1.f;
+  // These two are not used in this test.
+  static constexpr float kMinPageScaleFactor = 1.f;
+  static constexpr float kMaxPageScaleFactor = 5.f;
+
+  static const gfx::Vector2d kExpectedScrollOffset;
+};
+
+// The current scroll offset in logical pixel, which is at the end.
+const gfx::Vector2dF DidReachMaximalScrollOffsetTest::kTotalScrollOffset =
+    gfx::Vector2dF(0.f, 6132.f);
+// The maximum possible scroll offset in logical pixel.
+const gfx::Vector2dF DidReachMaximalScrollOffsetTest::kTotalMaxScrollOffset =
+    gfx::Vector2dF(0.f, 6132.f);
+// This is what passed to CTS test, not used for this test.
+const gfx::SizeF DidReachMaximalScrollOffsetTest::kScrollableSize =
+    gfx::SizeF(412.f, 6712.f);
+// In max_scroll_offset() we are using ceiling rounding for scaled scroll
+// offset. Therefore ceiling(2.625 * 6132 = 16096.5) = 16097.
+const gfx::Vector2d DidReachMaximalScrollOffsetTest::kExpectedScrollOffset =
+    gfx::Vector2d(0, 16097);
+
+RENDERING_TEST_F(DidReachMaximalScrollOffsetTest);
+
 }  // namespace android_webview
diff --git a/android_webview/browser/child_frame.h b/android_webview/browser/child_frame.h
index aea082d..8832225 100644
--- a/android_webview/browser/child_frame.h
+++ b/android_webview/browser/child_frame.h
@@ -11,8 +11,6 @@
 #include "base/containers/circular_deque.h"
 #include "base/macros.h"
 #include "content/public/browser/android/synchronous_compositor.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
 #include "ui/gfx/transform.h"
 
 namespace viz {
diff --git a/android_webview/browser/command_line_helper_unittest.cc b/android_webview/browser/command_line_helper_unittest.cc
index 326e01d..c2710a9 100644
--- a/android_webview/browser/command_line_helper_unittest.cc
+++ b/android_webview/browser/command_line_helper_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
+#include "base/stl_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using testing::Test;
@@ -53,7 +54,7 @@
 
 TEST_F(CommandLineHelperTest, EnableForNoEnabledFeatures) {
   const CommandLine::CharType* argv[] = {FILE_PATH_LITERAL("program")};
-  CommandLine command_line(arraysize(argv), argv);
+  CommandLine command_line(base::size(argv), argv);
   EnableFeatureAndVerify(command_line, "SomeSpecialFeature", "");
 }
 
@@ -61,7 +62,7 @@
   const CommandLine::CharType* argv[] = {
       FILE_PATH_LITERAL("program"),
       FILE_PATH_LITERAL("--enable-features=TestFeature")};
-  CommandLine command_line(arraysize(argv), argv);
+  CommandLine command_line(base::size(argv), argv);
   EnableFeatureAndVerify(command_line, "TestFeature,SomeSpecialFeature", "");
 }
 
@@ -69,7 +70,7 @@
   const CommandLine::CharType* argv[] = {
       FILE_PATH_LITERAL("program"),
       FILE_PATH_LITERAL("--enable-features=SomeSpecialFeature,TestFeature")};
-  CommandLine command_line(arraysize(argv), argv);
+  CommandLine command_line(base::size(argv), argv);
   EnableFeatureAndVerify(command_line, "SomeSpecialFeature,TestFeature", "");
 }
 
@@ -77,7 +78,7 @@
   const CommandLine::CharType* argv[] = {
       FILE_PATH_LITERAL("program"),
       FILE_PATH_LITERAL("--disable-features=SomeSpecialFeature")};
-  CommandLine command_line(arraysize(argv), argv);
+  CommandLine command_line(base::size(argv), argv);
   EnableFeatureAndVerify(command_line, "", "SomeSpecialFeature");
 }
 
@@ -85,7 +86,7 @@
   const CommandLine::CharType* argv[] = {
       FILE_PATH_LITERAL("program"),
       FILE_PATH_LITERAL("--disable-features=TestFeature")};
-  CommandLine command_line(arraysize(argv), argv);
+  CommandLine command_line(base::size(argv), argv);
   EnableFeatureAndVerify(command_line, "SomeSpecialFeature", "TestFeature");
 }
 
@@ -96,7 +97,7 @@
 
 TEST_F(CommandLineHelperTest, DisableForNoDisabledFeatures) {
   const CommandLine::CharType* argv[] = {FILE_PATH_LITERAL("program")};
-  CommandLine command_line(arraysize(argv), argv);
+  CommandLine command_line(base::size(argv), argv);
   DisableFeatureAndVerify(command_line, "", "SomeSpecialFeature");
 }
 
@@ -104,7 +105,7 @@
   const CommandLine::CharType* argv[] = {
       FILE_PATH_LITERAL("program"),
       FILE_PATH_LITERAL("--disable-features=TestFeature")};
-  CommandLine command_line(arraysize(argv), argv);
+  CommandLine command_line(base::size(argv), argv);
   DisableFeatureAndVerify(command_line, "", "TestFeature,SomeSpecialFeature");
 }
 
@@ -112,7 +113,7 @@
   const CommandLine::CharType* argv[] = {
       FILE_PATH_LITERAL("program"),
       FILE_PATH_LITERAL("--disable-features=SomeSpecialFeature,TestFeature")};
-  CommandLine command_line(arraysize(argv), argv);
+  CommandLine command_line(base::size(argv), argv);
   DisableFeatureAndVerify(command_line, "", "SomeSpecialFeature,TestFeature");
 }
 
@@ -120,7 +121,7 @@
   const CommandLine::CharType* argv[] = {
       FILE_PATH_LITERAL("program"),
       FILE_PATH_LITERAL("--enable-features=SomeSpecialFeature")};
-  CommandLine command_line(arraysize(argv), argv);
+  CommandLine command_line(base::size(argv), argv);
   DisableFeatureAndVerify(command_line, "SomeSpecialFeature", "");
 }
 
@@ -128,6 +129,6 @@
   const CommandLine::CharType* argv[] = {
       FILE_PATH_LITERAL("program"),
       FILE_PATH_LITERAL("--enable-features=TestFeature")};
-  CommandLine command_line(arraysize(argv), argv);
+  CommandLine command_line(base::size(argv), argv);
   DisableFeatureAndVerify(command_line, "TestFeature", "SomeSpecialFeature");
 }
diff --git a/android_webview/browser/compositor_frame_consumer.h b/android_webview/browser/compositor_frame_consumer.h
index b3f763a..4990301 100644
--- a/android_webview/browser/compositor_frame_consumer.h
+++ b/android_webview/browser/compositor_frame_consumer.h
@@ -8,10 +8,8 @@
 #include <map>
 
 #include "android_webview/browser/child_frame.h"
-#include "android_webview/browser/compositor_id.h"
 #include "android_webview/browser/parent_compositor_draw_constraints.h"
 #include "components/viz/common/resources/returned_resource.h"
-#include "content/public/browser/android/synchronous_compositor.h"
 #include "ui/gfx/geometry/vector2d.h"
 
 namespace android_webview {
diff --git a/android_webview/browser/compositor_frame_producer.h b/android_webview/browser/compositor_frame_producer.h
index 8defed5..1e33b91 100644
--- a/android_webview/browser/compositor_frame_producer.h
+++ b/android_webview/browser/compositor_frame_producer.h
@@ -11,6 +11,8 @@
 
 class CompositorFrameProducer {
  public:
+  virtual void ReturnedResourceAvailable(
+      CompositorFrameConsumer* compositor_frame_consumer) = 0;
   virtual void OnParentDrawConstraintsUpdated(
       CompositorFrameConsumer* compositor_frame_consumer) = 0;
   virtual void RemoveCompositorFrameConsumer(
diff --git a/android_webview/browser/cookie_manager.cc b/android_webview/browser/cookie_manager.cc
index 0b33a05..6429bbb 100644
--- a/android_webview/browser/cookie_manager.cc
+++ b/android_webview/browser/cookie_manager.cc
@@ -8,7 +8,6 @@
 #include <utility>
 #include <vector>
 
-#include "android_webview/browser/aw_browser_context.h"
 #include "android_webview/browser/aw_cookie_access_policy.h"
 #include "android_webview/browser/net/init_native_callback.h"
 #include "base/android/jni_string.h"
@@ -27,7 +26,6 @@
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_restrictions.h"
-#include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/cookie_store_factory.h"
 #include "jni/AwCookieManager_jni.h"
@@ -319,7 +317,7 @@
       cookie_store_created_ = true;
     }
 
-    cookie_store_ = content::CreateCookieStore(cookie_config);
+    cookie_store_ = content::CreateCookieStore(cookie_config, nullptr);
   }
 
   return cookie_store_.get();
diff --git a/android_webview/browser/deferred_gpu_command_service.cc b/android_webview/browser/deferred_gpu_command_service.cc
index 7842299..ca7382d 100644
--- a/android_webview/browser/deferred_gpu_command_service.cc
+++ b/android_webview/browser/deferred_gpu_command_service.cc
@@ -53,6 +53,78 @@
   }
 }
 
+// gpu::CommandBufferTaskExectuor::Sequence implementation that encapsulates a
+// SyncPointOrderData, and posts tasks to the task executors global task queue.
+class TaskForwardingSequence : public gpu::CommandBufferTaskExecutor::Sequence {
+ public:
+  explicit TaskForwardingSequence(DeferredGpuCommandService* service)
+      : gpu::CommandBufferTaskExecutor::Sequence(),
+        service_(service),
+        sync_point_order_data_(
+            service->sync_point_manager()->CreateSyncPointOrderData()),
+        weak_ptr_factory_(this) {}
+  ~TaskForwardingSequence() override { sync_point_order_data_->Destroy(); }
+
+  // CommandBufferTaskExecutor::Sequence implementation.
+  gpu::SequenceId GetSequenceId() override {
+    return sync_point_order_data_->sequence_id();
+  }
+
+  bool ShouldYield() override { return false; }
+
+  // Should not be called because BlockThreadOnWaitSyncToken() returns true,
+  // and the client should not disable sequences to wait for sync tokens.
+  void SetEnabled(bool enabled) override { NOTREACHED(); }
+
+  void ScheduleTask(base::OnceClosure task,
+                    std::vector<gpu::SyncToken> sync_token_fences) override {
+    uint32_t order_num =
+        sync_point_order_data_->GenerateUnprocessedOrderNumber();
+    // Use a weak ptr because the task executor holds the tasks, and the
+    // sequence will be destroyed before the task executor.
+    service_->ScheduleTask(
+        base::BindOnce(&TaskForwardingSequence::RunTask,
+                       weak_ptr_factory_.GetWeakPtr(), std::move(task),
+                       std::move(sync_token_fences), order_num),
+        false /* out_of_order */);
+  }
+
+  // Should not be called because tasks aren't reposted to wait for sync tokens,
+  // or for yielding execution since ShouldYield() returns false.
+  void ContinueTask(base::OnceClosure task) override { NOTREACHED(); }
+
+ private:
+  // Method to wrap scheduled task with the order number processing required for
+  // sync tokens.
+  void RunTask(base::OnceClosure task,
+               std::vector<gpu::SyncToken> sync_token_fences,
+               uint32_t order_num) {
+    // Block thread when waiting for sync token. This avoids blocking when we
+    // encounter the wait command later.
+    for (const auto& sync_token : sync_token_fences) {
+      base::WaitableEvent completion;
+      if (service_->sync_point_manager()->Wait(
+              sync_token, sync_point_order_data_->sequence_id(), order_num,
+              base::BindOnce(&base::WaitableEvent::Signal,
+                             base::Unretained(&completion)))) {
+        TRACE_EVENT0("android_webview",
+                     "TaskForwardingSequence::RunTask::WaitSyncToken");
+        completion.Wait();
+      }
+    }
+    sync_point_order_data_->BeginProcessingOrderNumber(order_num);
+    std::move(task).Run();
+    sync_point_order_data_->FinishProcessingOrderNumber(order_num);
+  }
+
+  // Raw ptr is ok because the task executor (service) is guaranteed to outlive
+  // its task sequences.
+  DeferredGpuCommandService* const service_;
+  scoped_refptr<gpu::SyncPointOrderData> sync_point_order_data_;
+  base::WeakPtrFactory<TaskForwardingSequence> weak_ptr_factory_;
+  DISALLOW_COPY_AND_ASSIGN(TaskForwardingSequence);
+};
+
 // static
 DeferredGpuCommandService*
 DeferredGpuCommandService::CreateDeferredGpuCommandService() {
@@ -67,8 +139,9 @@
   if (!success) {
     LOG(FATAL) << "gpu::InitializeGLThreadSafe() failed.";
   }
-  return new DeferredGpuCommandService(gpu_preferences, gpu_info,
-                                       gpu_feature_info);
+  return new DeferredGpuCommandService(
+      std::make_unique<gpu::SyncPointManager>(), gpu_preferences, gpu_info,
+      gpu_feature_info);
 }
 
 // static
@@ -79,15 +152,17 @@
 }
 
 DeferredGpuCommandService::DeferredGpuCommandService(
+    std::unique_ptr<gpu::SyncPointManager> sync_point_manager,
     const gpu::GpuPreferences& gpu_preferences,
     const gpu::GPUInfo& gpu_info,
     const gpu::GpuFeatureInfo& gpu_feature_info)
     : gpu::CommandBufferTaskExecutor(gpu_preferences,
                                      gpu_feature_info,
+                                     sync_point_manager.get(),
                                      nullptr,
                                      nullptr,
                                      gl::GLSurfaceFormat()),
-      sync_point_manager_(std::make_unique<gpu::SyncPointManager>()),
+      sync_point_manager_(std::move(sync_point_manager)),
       gpu_info_(gpu_info) {}
 
 DeferredGpuCommandService::~DeferredGpuCommandService() {
@@ -108,10 +183,14 @@
 }
 
 // Called from different threads!
-void DeferredGpuCommandService::ScheduleTask(base::OnceClosure task) {
+void DeferredGpuCommandService::ScheduleTask(base::OnceClosure task,
+                                             bool out_of_order) {
   {
     base::AutoLock lock(tasks_lock_);
-    tasks_.push(std::move(task));
+    if (out_of_order)
+      tasks_.emplace_front(std::move(task));
+    else
+      tasks_.emplace_back(std::move(task));
   }
   if (ScopedAllowGL::IsAllowed()) {
     RunTasks();
@@ -125,6 +204,15 @@
   return idle_tasks_.size();
 }
 
+std::unique_ptr<gpu::CommandBufferTaskExecutor::Sequence>
+DeferredGpuCommandService::CreateSequence() {
+  return std::make_unique<TaskForwardingSequence>(this);
+}
+
+void DeferredGpuCommandService::ScheduleOutOfOrderTask(base::OnceClosure task) {
+  ScheduleTask(std::move(task), true /* out_of_order */);
+}
+
 void DeferredGpuCommandService::ScheduleDelayedWork(
     base::OnceClosure callback) {
   {
@@ -135,10 +223,8 @@
 }
 
 void DeferredGpuCommandService::PerformIdleWork(bool is_idle) {
-  TRACE_EVENT1("android_webview",
-               "DeferredGpuCommandService::PerformIdleWork",
-               "is_idle",
-               is_idle);
+  TRACE_EVENT1("android_webview", "DeferredGpuCommandService::PerformIdleWork",
+               "is_idle", is_idle);
   DCHECK(ScopedAllowGL::IsAllowed());
   static const base::TimeDelta kMaxIdleAge =
       base::TimeDelta::FromMilliseconds(16);
@@ -170,12 +256,12 @@
   }
 }
 
-bool DeferredGpuCommandService::ForceVirtualizedGLContexts() {
+bool DeferredGpuCommandService::ForceVirtualizedGLContexts() const {
   return true;
 }
 
-gpu::SyncPointManager* DeferredGpuCommandService::sync_point_manager() {
-  return sync_point_manager_.get();
+bool DeferredGpuCommandService::ShouldCreateMemoryTracker() const {
+  return false;
 }
 
 void DeferredGpuCommandService::RunTasks() {
@@ -191,7 +277,7 @@
     {
       base::AutoLock lock(tasks_lock_);
       task = std::move(tasks_.front());
-      tasks_.pop();
+      tasks_.pop_front();
     }
     std::move(task).Run();
     {
diff --git a/android_webview/browser/deferred_gpu_command_service.h b/android_webview/browser/deferred_gpu_command_service.h
index 6fb5c5f..27d9cae 100644
--- a/android_webview/browser/deferred_gpu_command_service.h
+++ b/android_webview/browser/deferred_gpu_command_service.h
@@ -17,7 +17,6 @@
 #include "base/time/time.h"
 #include "gpu/config/gpu_info.h"
 #include "gpu/ipc/command_buffer_task_executor.h"
-#include "gpu/ipc/in_process_command_buffer.h"
 
 namespace gpu {
 struct GpuFeatureInfo;
@@ -41,46 +40,61 @@
   DISALLOW_COPY_AND_ASSIGN(ScopedAllowGL);
 };
 
+class TaskForwardingSequence;
+
 class DeferredGpuCommandService : public gpu::CommandBufferTaskExecutor {
  public:
   static DeferredGpuCommandService* GetInstance();
 
-  void ScheduleTask(base::OnceClosure task) override;
-  void ScheduleDelayedWork(base::OnceClosure task) override;
-  bool ForceVirtualizedGLContexts() override;
-  gpu::SyncPointManager* sync_point_manager() override;
-
-  void RunTasks();
-  // If |is_idle| is false, this will only run older idle tasks.
-  void PerformIdleWork(bool is_idle);
-  // Flush the idle queue until it is empty. This is different from
-  // PerformIdleWork(is_idle = true), which does not run any newly scheduled
-  // idle tasks during the idle run.
-  void PerformAllIdleWork();
-
+  // gpu::CommandBufferTaskExecutor implementation.
+  bool ForceVirtualizedGLContexts() const override;
+  bool ShouldCreateMemoryTracker() const override;
   bool BlockThreadOnWaitSyncToken() const override;
+  std::unique_ptr<gpu::CommandBufferTaskExecutor::Sequence> CreateSequence()
+      override;
+  void ScheduleOutOfOrderTask(base::OnceClosure task) override;
+  void ScheduleDelayedWork(base::OnceClosure task) override;
 
   const gpu::GPUInfo& gpu_info() const { return gpu_info_; }
 
   bool CanSupportThreadedTextureMailbox() const;
 
+  // If |is_idle| is false, this will only run older idle tasks.
+  void PerformIdleWork(bool is_idle);
+
+  // Flush the idle queue until it is empty. This is different from
+  // PerformIdleWork(is_idle = true), which does not run any newly scheduled
+  // idle tasks during the idle run.
+  void PerformAllIdleWork();
+
  protected:
   ~DeferredGpuCommandService() override;
 
  private:
   friend class ScopedAllowGL;
+  friend class TaskForwardingSequence;
+
   static void RequestProcessGL(bool for_idle);
 
-  DeferredGpuCommandService(const gpu::GpuPreferences& gpu_preferences,
-                            const gpu::GPUInfo& gpu_info,
-                            const gpu::GpuFeatureInfo& gpu_feature_info);
+  DeferredGpuCommandService(
+      std::unique_ptr<gpu::SyncPointManager> sync_point_manager,
+      const gpu::GpuPreferences& gpu_preferences,
+      const gpu::GPUInfo& gpu_info,
+      const gpu::GpuFeatureInfo& gpu_feature_info);
 
   static DeferredGpuCommandService* CreateDeferredGpuCommandService();
 
   size_t IdleQueueSize();
 
+  // Called by ScopedAllowGL and ScheduleTask().
+  void RunTasks();
+
+  // Called by TaskForwardingSequence. |out_of_order| indicates if task should
+  // be run ahead of already enqueued tasks.
+  void ScheduleTask(base::OnceClosure task, bool out_of_order);
+
   base::Lock tasks_lock_;
-  base::queue<base::OnceClosure> tasks_;
+  base::circular_deque<base::OnceClosure> tasks_;
   base::queue<std::pair<base::Time, base::OnceClosure>> idle_tasks_;
 
   std::unique_ptr<gpu::SyncPointManager> sync_point_manager_;
diff --git a/android_webview/browser/find_helper.cc b/android_webview/browser/find_helper.cc
index fd636b2..c50b2d5 100644
--- a/android_webview/browser/find_helper.cc
+++ b/android_webview/browser/find_helper.cc
@@ -7,10 +7,9 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/stop_find_action.h"
-#include "third_party/blink/public/web/web_find_options.h"
+#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
 
 using content::WebContents;
-using blink::WebFindOptions;
 
 namespace android_webview {
 
@@ -43,12 +42,12 @@
   if (MaybeHandleEmptySearch(search_string))
     return;
 
-  WebFindOptions options;
-  options.forward = true;
-  options.match_case = false;
-  options.find_next = false;
+  auto options = blink::mojom::FindOptions::New();
+  options->forward = true;
+  options->match_case = false;
+  options->find_next = false;
 
-  web_contents()->Find(current_request_id_, search_string, options);
+  web_contents()->Find(current_request_id_, search_string, std::move(options));
 }
 
 void FindHelper::HandleFindReply(int request_id,
@@ -70,12 +69,13 @@
   if (MaybeHandleEmptySearch(last_search_string_))
     return;
 
-  WebFindOptions options;
-  options.forward = forward;
-  options.match_case = false;
-  options.find_next = true;
+  auto options = blink::mojom::FindOptions::New();
+  options->forward = forward;
+  options->match_case = false;
+  options->find_next = true;
 
-  web_contents()->Find(current_request_id_, last_search_string_, options);
+  web_contents()->Find(current_request_id_, last_search_string_,
+                       std::move(options));
 }
 
 void FindHelper::ClearMatches() {
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc
index 9d8b9a5..730e062 100644
--- a/android_webview/browser/hardware_renderer.cc
+++ b/android_webview/browser/hardware_renderer.cc
@@ -33,7 +33,8 @@
       last_committed_layer_tree_frame_sink_id_(0u),
       last_submitted_layer_tree_frame_sink_id_(0u) {
   DCHECK(last_egl_context_);
-  surfaces_->GetFrameSinkManager()->RegisterFrameSinkId(frame_sink_id_);
+  surfaces_->GetFrameSinkManager()->RegisterFrameSinkId(
+      frame_sink_id_, true /* report_activation */);
   surfaces_->GetFrameSinkManager()->SetFrameSinkDebugLabel(frame_sink_id_,
                                                            "HardwareRenderer");
   CreateNewCompositorFrameSinkSupport();
@@ -163,7 +164,8 @@
 
 void HardwareRenderer::AllocateSurface() {
   DCHECK(!child_id_.is_valid());
-  child_id_ = parent_local_surface_id_allocator_->GenerateId();
+  parent_local_surface_id_allocator_->GenerateId();
+  child_id_ = parent_local_surface_id_allocator_->GetCurrentLocalSurfaceId();
   surfaces_->AddChildId(viz::SurfaceId(frame_sink_id_, child_id_));
 }
 
@@ -171,7 +173,7 @@
   DCHECK(child_id_.is_valid());
 
   surfaces_->RemoveChildId(viz::SurfaceId(frame_sink_id_, child_id_));
-  support_->EvictLastActivatedSurface();
+  support_->EvictSurface(child_id_);
   child_id_ = viz::LocalSurfaceId();
   surfaces_->GetFrameSinkManager()->surface_manager()->GarbageCollectSurfaces();
 }
diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h
index a4f94fe..083ee09 100644
--- a/android_webview/browser/hardware_renderer.h
+++ b/android_webview/browser/hardware_renderer.h
@@ -12,7 +12,6 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
-#include "components/viz/common/surfaces/surface_id.h"
 #include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
 
 struct AwDrawGLInfo;
diff --git a/android_webview/browser/input_stream_unittest.cc b/android_webview/browser/input_stream_unittest.cc
index 02d525e..b41e6e4 100644
--- a/android_webview/browser/input_stream_unittest.cc
+++ b/android_webview/browser/input_stream_unittest.cc
@@ -48,7 +48,7 @@
 
     std::unique_ptr<InputStream> input_stream(
         new InputStream(counting_jstream));
-    scoped_refptr<IOBuffer> buffer = new IOBuffer(bytes_requested);
+    auto buffer = base::MakeRefCounted<IOBuffer>(bytes_requested);
 
     EXPECT_TRUE(input_stream->Read(buffer.get(), bytes_requested, bytes_read));
     return buffer;
@@ -65,7 +65,7 @@
   std::unique_ptr<InputStream> input_stream(new InputStream(empty_jstream));
   const int bytes_requested = 10;
   int bytes_read = 0;
-  scoped_refptr<IOBuffer> buffer = new IOBuffer(bytes_requested);
+  auto buffer = base::MakeRefCounted<IOBuffer>(bytes_requested);
 
   EXPECT_TRUE(input_stream->Read(buffer.get(), bytes_requested, &bytes_read));
   EXPECT_EQ(0, bytes_read);
@@ -132,7 +132,7 @@
 
   const int bytes_requested = 10;
   int bytes_read = 0;
-  scoped_refptr<IOBuffer> buffer = new IOBuffer(bytes_requested);
+  auto buffer = base::MakeRefCounted<IOBuffer>(bytes_requested);
   EXPECT_FALSE(input_stream->Read(buffer.get(), bytes_requested, &bytes_read));
   EXPECT_EQ(0, bytes_read);
 
diff --git a/android_webview/browser/net/aw_http_user_agent_settings.cc b/android_webview/browser/net/aw_http_user_agent_settings.cc
index 6f855f4b..aab7de8 100644
--- a/android_webview/browser/net/aw_http_user_agent_settings.cc
+++ b/android_webview/browser/net/aw_http_user_agent_settings.cc
@@ -24,6 +24,8 @@
   std::string new_aw_accept_language =
       AwContentBrowserClient::GetAcceptLangsImpl();
   if (new_aw_accept_language != last_aw_accept_language_) {
+    new_aw_accept_language =
+        net::HttpUtil::ExpandLanguageList(new_aw_accept_language);
     last_http_accept_language_ =
         net::HttpUtil::GenerateAcceptLanguageHeader(new_aw_accept_language);
     last_aw_accept_language_ = new_aw_accept_language;
diff --git a/android_webview/browser/net/aw_network_delegate.cc b/android_webview/browser/net/aw_network_delegate.cc
index 6fdbbfe..9a2c354 100644
--- a/android_webview/browser/net/aw_network_delegate.cc
+++ b/android_webview/browser/net/aw_network_delegate.cc
@@ -10,6 +10,8 @@
 #include "android_webview/browser/aw_cookie_access_policy.h"
 #include "android_webview/browser/net/aw_web_resource_request.h"
 #include "base/android/build_info.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/resource_request_info.h"
 #include "net/base/completion_once_callback.h"
@@ -79,8 +81,8 @@
     std::unique_ptr<AwContentsClientBridge::HttpErrorInfo> error_info =
         AwContentsClientBridge::ExtractHttpErrorInfo(original_response_headers);
 
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
+    base::PostTaskWithTraits(
+        FROM_HERE, {BrowserThread::UI},
         base::BindOnce(&OnReceivedHttpErrorOnUiThread,
                        request_info->GetWebContentsGetterForRequest(),
                        AwWebResourceRequest(*request), std::move(error_info)));
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc
index 9d28b87..12b5ec0 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.cc
+++ b/android_webview/browser/net/aw_url_request_context_getter.cc
@@ -31,6 +31,7 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/version_info/version_info.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/cookie_store_factory.h"
@@ -38,6 +39,7 @@
 #include "content/public/common/content_switches.h"
 #include "content/public/common/url_constants.h"
 #include "net/base/cache_type.h"
+#include "net/cert/cert_verifier.h"
 #include "net/cookies/cookie_store.h"
 #include "net/dns/mapped_host_resolver.h"
 #include "net/extras/sqlite/sqlite_channel_id_store.h"
@@ -176,31 +178,6 @@
   return job_factory;
 }
 
-// For Android WebView, do not enforce policies that are not consistent with
-// the underlying OS validator.
-// This means not enforcing the Legacy Symantec PKI policies outlined in
-// https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html
-// or disabling SHA-1 for locally-installed trust anchors.
-class AwSSLConfigService : public net::SSLConfigService {
- public:
-  AwSSLConfigService() {
-    default_config_.symantec_enforcement_disabled = true;
-    default_config_.sha1_local_anchors_enabled = true;
-  }
-
-  void GetSSLConfig(net::SSLConfig* config) override {
-    *config = default_config_;
-  }
-
-  bool CanShareConnectionWithClientCerts(
-      const std::string& hostname) const override {
-    return false;
-  }
-
- private:
-  net::SSLConfig default_config_;
-};
-
 }  // namespace
 
 AwURLRequestContextGetter::AwURLRequestContextGetter(
@@ -213,12 +190,13 @@
       channel_id_path_(channel_id_path),
       net_log_(net_log),
       proxy_config_service_(std::move(config_service)),
+      proxy_config_service_android_(nullptr),
       http_user_agent_settings_(new AwHttpUserAgentSettings()) {
   // CreateSystemProxyConfigService for Android must be called on main thread.
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   scoped_refptr<base::SingleThreadTaskRunner> io_thread_proxy =
-      BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+      base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO});
 
   auth_server_whitelist_.Init(
       prefs::kAuthServerWhitelist, user_pref_service,
@@ -316,6 +294,9 @@
         net::ProxyResolutionService::CreateFixed(proxy,
                                                  NO_TRAFFIC_ANNOTATION_YET));
   } else {
+    // Retain a pointer to the config proxy service before ownership is passed
+    // on.
+    proxy_config_service_android_ = proxy_config_service_.get();
     builder.set_proxy_resolution_service(
         net::ProxyResolutionService::CreateWithoutProxyResolver(
             std::move(proxy_config_service_), net_log_));
@@ -344,9 +325,18 @@
       CreateAuthHandlerFactory(host_resolver.get()));
   builder.set_host_resolver(std::move(host_resolver));
 
-  builder.set_ssl_config_service(std::make_unique<AwSSLConfigService>());
-
   url_request_context_ = builder.Build();
+
+  // For Android WebView, do not enforce policies that are not consistent with
+  // the underlying OS validator.
+  // This means not enforcing the Legacy Symantec PKI policies outlined in
+  // https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html
+  // or disabling SHA-1 for locally-installed trust anchors.
+  net::CertVerifier::Config config;
+  config.enable_sha1_local_anchors = true;
+  config.disable_symantec_enforcement = true;
+  url_request_context_->cert_verifier()->SetConfig(config);
+
 #if DCHECK_IS_ON()
   g_created_url_request_context_builder = true;
 #endif
@@ -385,7 +375,7 @@
 
 scoped_refptr<base::SingleThreadTaskRunner>
 AwURLRequestContextGetter::GetNetworkTaskRunner() const {
-  return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+  return base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO});
 }
 
 void AwURLRequestContextGetter::SetHandlersAndInterceptors(
@@ -425,12 +415,18 @@
 void AwURLRequestContextGetter::SetProxyOverride(
     const std::string& host,
     int port,
-    const std::vector<std::string>& exclusion_list) {
-  proxy_config_service_->SetProxyOverride(host, port, exclusion_list);
+    const std::vector<std::string>& exclusion_list,
+    base::OnceClosure callback) {
+  if (proxy_config_service_android_ != NULL) {
+    proxy_config_service_android_->SetProxyOverride(host, port, exclusion_list,
+                                                    std::move(callback));
+  }
 }
 
-void AwURLRequestContextGetter::ClearProxyOverride() {
-  proxy_config_service_->ClearProxyOverride();
+void AwURLRequestContextGetter::ClearProxyOverride(base::OnceClosure callback) {
+  if (proxy_config_service_android_ != NULL) {
+    proxy_config_service_android_->ClearProxyOverride(std::move(callback));
+  }
 }
 
 }  // namespace android_webview
diff --git a/android_webview/browser/net/aw_url_request_context_getter.h b/android_webview/browser/net/aw_url_request_context_getter.h
index 792c0de..117bdba 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.h
+++ b/android_webview/browser/net/aw_url_request_context_getter.h
@@ -13,7 +13,6 @@
 #include "base/single_thread_task_runner.h"
 #include "components/prefs/pref_member.h"
 #include "content/public/browser/browser_context.h"
-#include "content/public/browser/content_browser_client.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "net/url_request/url_request_job_factory.h"
 
@@ -55,8 +54,9 @@
   // Methods to set and clear proxy override
   void SetProxyOverride(const std::string& host,
                         int port,
-                        const std::vector<std::string>& exclusion_list);
-  void ClearProxyOverride();
+                        const std::vector<std::string>& exclusion_list,
+                        base::OnceClosure callback);
+  void ClearProxyOverride(base::OnceClosure callback);
 
  private:
   friend class AwBrowserContext;
@@ -89,6 +89,7 @@
 
   net::NetLog* net_log_;
   std::unique_ptr<net::ProxyConfigServiceAndroid> proxy_config_service_;
+  net::ProxyConfigServiceAndroid* proxy_config_service_android_;
   std::unique_ptr<net::URLRequestJobFactory> job_factory_;
   std::unique_ptr<net::HttpUserAgentSettings> http_user_agent_settings_;
   std::unique_ptr<net::FileNetLogObserver> file_net_log_observer_;
diff --git a/android_webview/browser/net/aw_url_request_context_getter_unittest.cc b/android_webview/browser/net/aw_url_request_context_getter_unittest.cc
index eb990c8..9fe56f7 100644
--- a/android_webview/browser/net/aw_url_request_context_getter_unittest.cc
+++ b/android_webview/browser/net/aw_url_request_context_getter_unittest.cc
@@ -9,21 +9,29 @@
 #include "base/android/jni_android.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/ref_counted.h"
+#include "base/task/post_task.h"
 #include "components/prefs/testing_pref_service.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "net/base/net_errors.h"
+#include "net/base/test_completion_callback.h"
+#include "net/cert/cert_verifier.h"
+#include "net/cert/test_root_certs.h"
 #include "net/log/net_log.h"
+#include "net/log/net_log_with_source.h"
 #include "net/proxy_resolution/proxy_config_service.h"
 #include "net/proxy_resolution/proxy_config_service_android.h"
 #include "net/proxy_resolution/proxy_resolution_service.h"
-#include "net/ssl/ssl_config.h"
-#include "net/ssl/ssl_config_service.h"
+#include "net/test/cert_test_util.h"
+#include "net/test/gtest_util.h"
+#include "net/test/test_data_directory.h"
 #include "net/test/url_request/url_request_failed_job.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_job_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/boringssl/src/include/openssl/pool.h"
 
 namespace android_webview {
 
@@ -61,8 +69,8 @@
     std::unique_ptr<net::ProxyConfigServiceAndroid> config_service_android;
     config_service_android.reset(static_cast<net::ProxyConfigServiceAndroid*>(
         net::ProxyResolutionService::CreateSystemProxyConfigService(
-            content::BrowserThread::GetTaskRunnerForThread(
-                content::BrowserThread::IO))
+            base::CreateSingleThreadTaskRunnerWithTraits(
+                {content::BrowserThread::IO}))
             .release()));
 
     getter_ = base::MakeRefCounted<android_webview::AwURLRequestContextGetter>(
@@ -95,13 +103,33 @@
 TEST_F(AwURLRequestContextGetterTest, SymantecPoliciesExempted) {
   net::URLRequestContext* context = getter_->GetURLRequestContext();
   ASSERT_TRUE(context);
-  net::SSLConfigService* config_service = context->ssl_config_service();
-  ASSERT_TRUE(config_service);
 
-  net::SSLConfig config;
-  EXPECT_FALSE(config.symantec_enforcement_disabled);
-  config_service->GetSSLConfig(&config);
-  EXPECT_TRUE(config.symantec_enforcement_disabled);
+  scoped_refptr<net::X509Certificate> cert =
+      net::CreateCertificateChainFromFile(net::GetTestCertsDirectory(),
+                                          "www.ahrn.com.pem",
+                                          net::X509Certificate::FORMAT_AUTO);
+  ASSERT_TRUE(cert);
+  ASSERT_EQ(2u, cert->intermediate_buffers().size());
+
+  scoped_refptr<net::X509Certificate> root =
+      net::X509Certificate::CreateFromBuffer(
+          bssl::UpRef(cert->intermediate_buffers().back()), {});
+  ASSERT_TRUE(root);
+  net::ScopedTestRoot test_root(root.get());
+
+  net::CertVerifyResult result;
+  int flags = 0;
+  net::TestCompletionCallback callback;
+  std::unique_ptr<net::CertVerifier::Request> request;
+  int error = context->cert_verifier()->Verify(
+      net::CertVerifier::RequestParams(cert, "www.ahrn.com", flags,
+                                       std::string()),
+      &result, callback.callback(), &request, net::NetLogWithSource());
+  EXPECT_THAT(error, net::test::IsError(net::ERR_IO_PENDING));
+  EXPECT_TRUE(request);
+
+  error = callback.WaitForResult();
+  EXPECT_THAT(error, net::test::IsError(net::OK));
 }
 
 // Tests that SHA-1 is still allowed for locally-installed trust anchors,
@@ -110,13 +138,35 @@
 TEST_F(AwURLRequestContextGetterTest, SHA1LocalAnchorsAllowed) {
   net::URLRequestContext* context = getter_->GetURLRequestContext();
   ASSERT_TRUE(context);
-  net::SSLConfigService* config_service = context->ssl_config_service();
-  ASSERT_TRUE(config_service);
 
-  net::SSLConfig config;
-  EXPECT_FALSE(config.sha1_local_anchors_enabled);
-  config_service->GetSSLConfig(&config);
-  EXPECT_TRUE(config.sha1_local_anchors_enabled);
+  net::CertificateList certs;
+  ASSERT_TRUE(net::LoadCertificateFiles(
+      {"weak_digest_sha1_ee.pem", "weak_digest_sha1_intermediate.pem",
+       "weak_digest_sha1_root.pem"},
+      &certs));
+  ASSERT_EQ(3u, certs.size());
+
+  std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+  intermediates.push_back(bssl::UpRef(certs[1]->cert_buffer()));
+  scoped_refptr<net::X509Certificate> cert =
+      net::X509Certificate::CreateFromBuffer(
+          bssl::UpRef(certs[0]->cert_buffer()), std::move(intermediates));
+  ASSERT_TRUE(cert);
+
+  net::ScopedTestRoot test_root(certs[2].get());
+
+  net::CertVerifyResult result;
+  int flags = 0;
+  net::TestCompletionCallback callback;
+  std::unique_ptr<net::CertVerifier::Request> request;
+  int error = context->cert_verifier()->Verify(
+      net::CertVerifier::RequestParams(cert, "127.0.0.1", flags, std::string()),
+      &result, callback.callback(), &request, net::NetLogWithSource());
+  EXPECT_THAT(error, net::test::IsError(net::ERR_IO_PENDING));
+  EXPECT_TRUE(request);
+
+  error = callback.WaitForResult();
+  EXPECT_THAT(error, net::test::IsError(net::OK));
 }
 
 }  // namespace android_webview
diff --git a/android_webview/browser/net/aw_web_resource_request.cc b/android_webview/browser/net/aw_web_resource_request.cc
index 56ef792..0e7fc78 100644
--- a/android_webview/browser/net/aw_web_resource_request.cc
+++ b/android_webview/browser/net/aw_web_resource_request.cc
@@ -8,6 +8,7 @@
 #include "net/http/http_request_headers.h"
 #include "net/http/http_response_headers.h"
 #include "net/url_request/url_request.h"
+#include "ui/base/page_transition_types.h"
 
 using base::android::ConvertJavaStringToUTF16;
 using base::android::ConvertUTF8ToJavaString;
@@ -38,6 +39,8 @@
   is_main_frame =
       info && info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME;
   has_user_gesture = info && info->HasUserGesture();
+  is_renderer_initiated =
+      info && ui::PageTransitionIsWebTriggerable(info->GetPageTransition());
 
   net::HttpRequestHeaders headers;
   if (!request.GetFullRequestHeaders(&headers))
diff --git a/android_webview/browser/net/aw_web_resource_request.h b/android_webview/browser/net/aw_web_resource_request.h
index 071a415..32675bf7 100644
--- a/android_webview/browser/net/aw_web_resource_request.h
+++ b/android_webview/browser/net/aw_web_resource_request.h
@@ -10,6 +10,7 @@
 
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
+#include "base/optional.h"
 
 namespace net {
 class HttpRequestHeaders;
@@ -58,6 +59,7 @@
   bool has_user_gesture;
   std::vector<std::string> header_names;
   std::vector<std::string> header_values;
+  base::Optional<bool> is_renderer_initiated;
 };
 
 }  // namespace android_webview
diff --git a/android_webview/browser/net/aw_web_resource_response.cc b/android_webview/browser/net/aw_web_resource_response.cc
index f45174a..c6568e7 100644
--- a/android_webview/browser/net/aw_web_resource_response.cc
+++ b/android_webview/browser/net/aw_web_resource_response.cc
@@ -79,9 +79,9 @@
     return false;
   std::vector<std::string> header_names;
   std::vector<std::string> header_values;
-  AppendJavaStringArrayToStringVector(env, jstringArray_headerNames.obj(),
+  AppendJavaStringArrayToStringVector(env, jstringArray_headerNames,
                                       &header_names);
-  AppendJavaStringArrayToStringVector(env, jstringArray_headerValues.obj(),
+  AppendJavaStringArrayToStringVector(env, jstringArray_headerValues,
                                       &header_values);
   DCHECK_EQ(header_values.size(), header_names.size());
   for (size_t i = 0; i < header_names.size(); ++i) {
diff --git a/android_webview/browser/net/input_stream_reader_unittest.cc b/android_webview/browser/net/input_stream_reader_unittest.cc
index b7aec52..3125579 100644
--- a/android_webview/browser/net/input_stream_reader_unittest.cc
+++ b/android_webview/browser/net/input_stream_reader_unittest.cc
@@ -142,7 +142,7 @@
 
 TEST_F(InputStreamReaderTest, ReadFailure) {
   const int bytesToRead = 128;
-  scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(bytesToRead);
+  auto buffer = base::MakeRefCounted<net::IOBuffer>(bytesToRead);
   EXPECT_CALL(input_stream_, Read(buffer.get(), bytesToRead, NotNull()))
       .WillOnce(Return(false));
 
@@ -152,7 +152,7 @@
 TEST_F(InputStreamReaderTest, ReadNothing) {
   const int bytesToRead = 0;
   // Size of net::IOBuffer can't be 0.
-  scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(1);
+  auto buffer = base::MakeRefCounted<net::IOBuffer>(1);
   EXPECT_CALL(input_stream_, Read(buffer.get(), bytesToRead, NotNull()))
       .Times(0);
 
@@ -161,7 +161,7 @@
 
 TEST_F(InputStreamReaderTest, ReadSuccess) {
   const int bytesToRead = 128;
-  scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(bytesToRead);
+  auto buffer = base::MakeRefCounted<net::IOBuffer>(bytesToRead);
 
   EXPECT_CALL(input_stream_, Read(buffer.get(), bytesToRead, NotNull()))
       .WillOnce(DoAll(SetArgPointee<2>(bytesToRead),
diff --git a/android_webview/browser/net/token_binding_manager.cc b/android_webview/browser/net/token_binding_manager.cc
index de0bcef..e68acd8 100644
--- a/android_webview/browser/net/token_binding_manager.cc
+++ b/android_webview/browser/net/token_binding_manager.cc
@@ -6,6 +6,8 @@
 
 #include "android_webview/browser/aw_browser_context.h"
 #include "base/callback_helpers.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/storage_partition.h"
 #include "net/ssl/channel_id_service.h"
@@ -25,14 +27,14 @@
                         ChannelIDService::Request* request,
                         std::unique_ptr<crypto::ECPrivateKey>* key,
                         int status) {
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::UI},
       base::BindOnce(std::move(callback), status, base::Owned(key->release())));
 }
 
 void DeletionCompleteCallback(
     TokenBindingManager::DeletionCompleteCallback callback) {
-  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(callback));
+  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(callback));
 }
 
 void GetKeyImpl(const std::string& host,
@@ -56,8 +58,8 @@
     // The operation is pending, callback will be called async.
     return;
   }
-  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
-                          base::BindOnce(completion_callback, status));
+  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+                           base::BindOnce(completion_callback, status));
 }
 
 void DeleteKeyImpl(const std::string& host,
@@ -93,8 +95,8 @@
   scoped_refptr<net::URLRequestContextGetter> context_getter =
       content::BrowserContext::GetDefaultStoragePartition(
           AwBrowserContext::GetDefault())->GetURLRequestContext();
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::IO},
       base::BindOnce(&GetKeyImpl, host, std::move(callback), context_getter));
 }
 
@@ -103,8 +105,8 @@
   scoped_refptr<net::URLRequestContextGetter> context_getter =
       content::BrowserContext::GetDefaultStoragePartition(
           AwBrowserContext::GetDefault())->GetURLRequestContext();
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::IO},
       base::BindOnce(&DeleteKeyImpl, host, std::move(callback), context_getter,
                      false));
 }
@@ -113,8 +115,8 @@
   scoped_refptr<net::URLRequestContextGetter> context_getter =
       content::BrowserContext::GetDefaultStoragePartition(
           AwBrowserContext::GetDefault())->GetURLRequestContext();
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::IO},
       base::BindOnce(&DeleteKeyImpl, "", std::move(callback), context_getter,
                      true));
 }
diff --git a/android_webview/browser/parent_compositor_draw_constraints.cc b/android_webview/browser/parent_compositor_draw_constraints.cc
index c2f0542..f897f5f 100644
--- a/android_webview/browser/parent_compositor_draw_constraints.cc
+++ b/android_webview/browser/parent_compositor_draw_constraints.cc
@@ -9,8 +9,7 @@
 namespace android_webview {
 
 ParentCompositorDrawConstraints::ParentCompositorDrawConstraints()
-    : is_layer(false), surface_rect_empty(false) {
-}
+    : is_layer(false), surface_rect_empty(true) {}
 
 ParentCompositorDrawConstraints::ParentCompositorDrawConstraints(
     bool is_layer,
diff --git a/android_webview/browser/parent_compositor_draw_constraints.h b/android_webview/browser/parent_compositor_draw_constraints.h
index 3f1b744..390a070 100644
--- a/android_webview/browser/parent_compositor_draw_constraints.h
+++ b/android_webview/browser/parent_compositor_draw_constraints.h
@@ -5,7 +5,6 @@
 #ifndef ANDROID_WEBVIEW_BROWSER_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_
 #define ANDROID_WEBVIEW_BROWSER_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_
 
-#include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/transform.h"
 
 namespace android_webview {
diff --git a/android_webview/browser/render_thread_manager.cc b/android_webview/browser/render_thread_manager.cc
index 5ccb82c..7233bfe5 100644
--- a/android_webview/browser/render_thread_manager.cc
+++ b/android_webview/browser/render_thread_manager.cc
@@ -19,7 +19,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
+#include "base/trace_event/traced_value.h"
 #include "components/viz/common/quads/compositor_frame.h"
 
 namespace android_webview {
@@ -88,6 +88,9 @@
 
 base::LazyInstance<internal::RequestInvokeGLTracker>::DestructorAtExit
     g_request_invoke_gl_tracker = LAZY_INSTANCE_INITIALIZER;
+
+constexpr base::TimeDelta kSlightlyMoreThanOneFrame =
+    base::TimeDelta::FromMilliseconds(17);
 }
 
 RenderThreadManager::RenderThreadManager(
@@ -128,11 +131,11 @@
       callback = request_draw_gl_closure_;
     }
     // 17ms is slightly longer than a frame, hoping that it will come
-    // after the next frame so that the idle work is taken care off by
+    // after the next frame so that the idle work is taken care of by
     // the next frame instead.
     ui_loop_->PostDelayedTask(
         FROM_HERE, std::move(callback),
-        for_idle ? base::TimeDelta::FromMilliseconds(17) : base::TimeDelta());
+        for_idle ? kSlightlyMoreThanOneFrame : base::TimeDelta());
   }
 }
 
@@ -251,6 +254,9 @@
     const std::vector<viz::ReturnedResource>& resources,
     const CompositorID& compositor_id,
     uint32_t layer_tree_frame_sink_id) {
+  if (resources.empty())
+    return;
+
   base::AutoLock lock(lock_);
   ReturnedResources& returned_resources =
       returned_resources_map_[compositor_id];
@@ -260,6 +266,28 @@
   returned_resources.resources.insert(returned_resources.resources.end(),
                                       resources.begin(), resources.end());
   returned_resources.layer_tree_frame_sink_id = layer_tree_frame_sink_id;
+
+  if (!returned_resource_available_pending_) {
+    returned_resource_available_pending_ = true;
+    ui_loop_->PostDelayedTask(
+        FROM_HERE,
+        base::BindOnce(&RenderThreadManager::ReturnedResourceAvailableOnUI,
+                       ui_thread_weak_ptr_),
+        kSlightlyMoreThanOneFrame * 2);
+  }
+}
+
+void RenderThreadManager::ReturnedResourceAvailableOnUI() {
+  bool empty = false;
+  {
+    base::AutoLock lock(lock_);
+    DCHECK(returned_resource_available_pending_);
+    returned_resource_available_pending_ = false;
+    empty = returned_resources_map_.empty();
+  }
+  if (!empty && compositor_frame_producer_) {
+    compositor_frame_producer_->ReturnedResourceAvailable(this);
+  }
 }
 
 void RenderThreadManager::SwapReturnedResourcesOnUI(
diff --git a/android_webview/browser/render_thread_manager.h b/android_webview/browser/render_thread_manager.h
index 5e39764..909e16f 100644
--- a/android_webview/browser/render_thread_manager.h
+++ b/android_webview/browser/render_thread_manager.h
@@ -15,7 +15,6 @@
 #include "base/memory/weak_ptr.h"
 #include "base/single_thread_task_runner.h"
 #include "base/synchronization/lock.h"
-#include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/vector2d.h"
 
 struct AwDrawGLInfo;
@@ -91,6 +90,7 @@
   void ResetRequestInvokeGLCallback();
   void ClientRequestInvokeGLOnUI();
   void UpdateParentDrawConstraintsOnUI();
+  void ReturnedResourceAvailableOnUI();
   bool IsInsideHardwareRelease() const;
   void SetInsideHardwareRelease(bool inside);
 
@@ -116,6 +116,7 @@
   ChildFrameQueue child_frames_;
   bool inside_hardware_release_;
   ParentCompositorDrawConstraints parent_draw_constraints_;
+  bool returned_resource_available_pending_ = false;
   ReturnedResourcesMap returned_resources_map_;
   base::RepeatingClosure request_draw_gl_closure_;
 
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
index bbe8c8c..a35c743 100644
--- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
+++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 #include <string>
+#include <utility>
 
 #include "android_webview/browser/aw_browser_context.h"
 #include "android_webview/browser/aw_contents_client_bridge.h"
@@ -15,10 +16,11 @@
 #include "android_webview/browser/net/aw_web_resource_request.h"
 #include "android_webview/browser/renderer_host/auto_login_parser.h"
 #include "android_webview/common/url_constants.h"
-#include "components/navigation_interception/intercept_navigation_delegate.h"
+#include "base/task/post_task.h"
 #include "components/safe_browsing/android/safe_browsing_api_handler.h"
 #include "components/safe_browsing/features.h"
 #include "components/web_restrictions/browser/web_restrictions_resource_throttle.h"
+#include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/resource_dispatcher_host.h"
 #include "content/public/browser/resource_request_info.h"
@@ -37,7 +39,6 @@
 using content::BrowserThread;
 using content::ResourceType;
 using content::WebContents;
-using navigation_interception::InterceptNavigationDelegate;
 
 namespace {
 
@@ -249,7 +250,7 @@
         request_, net::LOAD_ONLY_FROM_CACHE | net::LOAD_SKIP_CACHE_VALIDATION);
   } else {
     AwContentsIoThreadClient::CacheMode cache_mode = io_client->GetCacheMode();
-    switch(cache_mode) {
+    switch (cache_mode) {
       case AwContentsIoThreadClient::LOAD_CACHE_ELSE_NETWORK:
         SetCacheControlFlag(request_, net::LOAD_SKIP_CACHE_VALIDATION);
         break;
@@ -323,8 +324,6 @@
   throttles->push_back(std::move(ioThreadThrottle));
 
   bool is_main_frame = resource_type == content::RESOURCE_TYPE_MAIN_FRAME;
-  if (!is_main_frame)
-    InterceptNavigationDelegate::UpdateUserGestureCarryoverInfo(request);
   throttles->push_back(
       std::make_unique<web_restrictions::WebRestrictionsResourceThrottle>(
           AwBrowserContext::GetDefault()->GetWebRestrictionProvider(),
@@ -349,8 +348,8 @@
     if (IsCancelledBySafeBrowsing(request)) {
       safebrowsing_hit = true;
     }
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
+    base::PostTaskWithTraits(
+        FROM_HERE, {BrowserThread::UI},
         base::BindOnce(&OnReceivedErrorOnUiThread,
                        request_info->GetWebContentsGetterForRequest(),
                        AwWebResourceRequest(*request),
@@ -391,8 +390,8 @@
   const content::ResourceRequestInfo* request_info =
       content::ResourceRequestInfo::ForRequest(request);
 
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::UI},
       base::BindOnce(&DownloadStartingOnUIThread,
                      request_info->GetWebContentsGetterForRequest(), url,
                      user_agent, content_disposition, mime_type,
@@ -415,8 +414,8 @@
     // Check for x-auto-login header.
     HeaderData header_data;
     if (ParserHeaderInResponse(request, ALLOW_ANY_REALM, &header_data)) {
-      BrowserThread::PostTask(
-          BrowserThread::UI, FROM_HERE,
+      base::PostTaskWithTraits(
+          FROM_HERE, {BrowserThread::UI},
           base::BindOnce(&NewLoginRequestOnUIThread,
                          request_info->GetWebContentsGetterForRequest(),
                          header_data.realm, header_data.account,
@@ -428,9 +427,9 @@
 void AwResourceDispatcherHostDelegate::RemovePendingThrottleOnIoThread(
     IoThreadClientThrottle* throttle) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  PendingThrottleMap::iterator it = pending_throttles_.find(
-      FrameRouteIDPair(throttle->render_process_id(),
-                       throttle->render_frame_id()));
+  PendingThrottleMap::iterator it =
+      pending_throttles_.find(content::GlobalFrameRoutingId(
+          throttle->render_process_id(), throttle->render_frame_id()));
   if (it != pending_throttles_.end()) {
     pending_throttles_.erase(it);
   }
@@ -440,8 +439,8 @@
 void AwResourceDispatcherHostDelegate::OnIoThreadClientReady(
     int new_render_process_id,
     int new_render_frame_id) {
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::IO},
       base::BindOnce(
           &AwResourceDispatcherHostDelegate::OnIoThreadClientReadyInternal,
           base::Unretained(
@@ -454,8 +453,8 @@
     int render_process_id,
     int render_frame_id,
     IoThreadClientThrottle* pending_throttle) {
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
+  base::PostTaskWithTraits(
+      FROM_HERE, {BrowserThread::IO},
       base::BindOnce(
           &AwResourceDispatcherHostDelegate::AddPendingThrottleOnIoThread,
           base::Unretained(
@@ -469,8 +468,8 @@
     IoThreadClientThrottle* pending_throttle) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   pending_throttles_.insert(
-      std::pair<FrameRouteIDPair, IoThreadClientThrottle*>(
-          FrameRouteIDPair(render_process_id, render_frame_id_id),
+      std::pair<content::GlobalFrameRoutingId, IoThreadClientThrottle*>(
+          content::GlobalFrameRoutingId(render_process_id, render_frame_id_id),
           pending_throttle));
 }
 
@@ -478,8 +477,9 @@
     int new_render_process_id,
     int new_render_frame_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  PendingThrottleMap::iterator it = pending_throttles_.find(
-      FrameRouteIDPair(new_render_process_id, new_render_frame_id));
+  PendingThrottleMap::iterator it =
+      pending_throttles_.find(content::GlobalFrameRoutingId(
+          new_render_process_id, new_render_frame_id));
 
   if (it != pending_throttles_.end()) {
     IoThreadClientThrottle* throttle = it->second;
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h
index 790c0dd..5ab886e 100644
--- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h
+++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h
@@ -11,6 +11,7 @@
 
 #include "base/lazy_instance.h"
 #include "base/macros.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/resource_context.h"
 #include "content/public/browser/resource_dispatcher_host_delegate.h"
 
@@ -76,8 +77,7 @@
                                content::ResourceContext* resource_context);
 
   // Pair of render_process_id and render_frame_id.
-  typedef std::pair<int, int> FrameRouteIDPair;
-  typedef std::map<FrameRouteIDPair, IoThreadClientThrottle*>
+  typedef std::map<content::GlobalFrameRoutingId, IoThreadClientThrottle*>
       PendingThrottleMap;
 
   // Only accessed on the IO thread.
diff --git a/android_webview/browser/state_serializer.cc b/android_webview/browser/state_serializer.cc
index 01032a8..9a4289b3f 100644
--- a/android_webview/browser/state_serializer.cc
+++ b/android_webview/browser/state_serializer.cc
@@ -214,7 +214,7 @@
       return false;
 
     referrer.url = GURL(referrer_url);
-    referrer.policy = static_cast<blink::WebReferrerPolicy>(policy);
+    referrer.policy = static_cast<network::mojom::ReferrerPolicy>(policy);
     entry->SetReferrer(referrer);
   }
 
diff --git a/android_webview/browser/state_serializer_unittest.cc b/android_webview/browser/state_serializer_unittest.cc
index 0c30680..8348785 100644
--- a/android_webview/browser/state_serializer_unittest.cc
+++ b/android_webview/browser/state_serializer_unittest.cc
@@ -31,7 +31,7 @@
   const GURL virtual_url("http://virtual_url");
   content::Referrer referrer;
   referrer.url = GURL("http://referrer_url");
-  referrer.policy = blink::kWebReferrerPolicyOrigin;
+  referrer.policy = network::mojom::ReferrerPolicy::kOrigin;
   const base::string16 title(base::UTF8ToUTF16("title"));
   const content::PageState page_state =
       content::PageState::CreateFromEncodedData("completely bogus state");
diff --git a/android_webview/browser/surfaces_instance.cc b/android_webview/browser/surfaces_instance.cc
index 24237157..89f331d 100644
--- a/android_webview/browser/surfaces_instance.cc
+++ b/android_webview/browser/surfaces_instance.cc
@@ -156,7 +156,8 @@
 
   if (!root_id_.is_valid() || viewport != surface_size_ ||
       device_scale_factor != device_scale_factor_) {
-    root_id_ = parent_local_surface_id_allocator_->GenerateId();
+    parent_local_surface_id_allocator_->GenerateId();
+    root_id_ = parent_local_surface_id_allocator_->GetCurrentLocalSurfaceId();
     surface_size_ = viewport;
     device_scale_factor_ = device_scale_factor;
     display_->SetLocalSurfaceId(root_id_, device_scale_factor);
diff --git a/android_webview/browser/test/fake_window.h b/android_webview/browser/test/fake_window.h
index 0f1eea8..3c1576a 100644
--- a/android_webview/browser/test/fake_window.h
+++ b/android_webview/browser/test/fake_window.h
@@ -58,6 +58,8 @@
 
   void RequestDrawGL(FakeFunctor* functor);
 
+  bool on_draw_hardware_pending() const { return on_draw_hardware_pending_; }
+
  private:
   class ScopedMakeCurrent;
 
diff --git a/android_webview/browser/tracing/aw_tracing_controller.cc b/android_webview/browser/tracing/aw_tracing_controller.cc
index 87d10e3..ecf27c5 100644
--- a/android_webview/browser/tracing/aw_tracing_controller.cc
+++ b/android_webview/browser/tracing/aw_tracing_controller.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
 
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/tracing_controller.h"
@@ -44,14 +45,14 @@
 
   void ReceiveTraceFinalContents(
       std::unique_ptr<const base::DictionaryValue> metadata) override {
-    content::BrowserThread::PostTask(
-        content::BrowserThread::UI, FROM_HERE,
+    base::PostTaskWithTraits(
+        FROM_HERE, {content::BrowserThread::UI},
         base::BindOnce(std::move(completed_callback_), std::move(metadata)));
   }
 
   void ReceiveTraceChunk(std::unique_ptr<std::string> chunk) override {
-    content::BrowserThread::PostTask(
-        content::BrowserThread::UI, FROM_HERE,
+    base::PostTaskWithTraits(
+        FROM_HERE, {content::BrowserThread::UI},
         base::BindOnce(received_chunk_callback_, std::move(chunk)));
   }
 
diff --git a/android_webview/browser/tracing/aw_tracing_controller.h b/android_webview/browser/tracing/aw_tracing_controller.h
index 509860f..5f7af6a 100644
--- a/android_webview/browser/tracing/aw_tracing_controller.h
+++ b/android_webview/browser/tracing/aw_tracing_controller.h
@@ -8,8 +8,7 @@
 #include "base/android/jni_weak_ref.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-
-#include "content/public/browser/tracing_controller.h"
+#include "base/values.h"
 
 namespace android_webview {
 
diff --git a/android_webview/common/aw_channel.cc b/android_webview/common/aw_channel.cc
index 165f5e8..ece22c8 100644
--- a/android_webview/common/aw_channel.cc
+++ b/android_webview/common/aw_channel.cc
@@ -10,13 +10,8 @@
 
 using version_info::Channel;
 
-Channel GetChannel() {
+Channel GetChannelOrStable() {
   Channel channel = version_info::GetChannel();
-  // There are separate Monochrome APKs built for each channel, but only one
-  // stand-alone WebView APK for all channels, so stand-alone WebView has
-  // channel "unknown". Pretend stand-alone WebView is always "stable" for the
-  // purpose of variations. This simplifies experiment design, since stand-alone
-  // WebView need not be considered separately when choosing channels.
   return channel == Channel::UNKNOWN ? Channel::STABLE : channel;
 }
 
diff --git a/android_webview/common/aw_channel.h b/android_webview/common/aw_channel.h
index 318d6cb..c4b9278 100644
--- a/android_webview/common/aw_channel.h
+++ b/android_webview/common/aw_channel.h
@@ -9,7 +9,10 @@
 
 namespace android_webview {
 
-version_info::Channel GetChannel();
+// There are separate Monochrome APKs built for each channel, but only one
+// stand-alone WebView APK for all channels, so stand-alone WebView has channel
+// "unknown". Return the channel if it's known, or "stable" if it's "unknown".
+version_info::Channel GetChannelOrStable();
 
 }  // namespace android_webview
 
diff --git a/android_webview/common/aw_content_client.cc b/android_webview/common/aw_content_client.cc
index fd322fa..1514c94 100644
--- a/android_webview/common/aw_content_client.cc
+++ b/android_webview/common/aw_content_client.cc
@@ -37,7 +37,8 @@
         switches::kUseMobileUserAgent)) {
     product += " Mobile";
   }
-  return content::BuildUserAgentFromProductAndExtraOSInfo(product, "; wv");
+  return content::BuildUserAgentFromProductAndExtraOSInfo(
+      product, "; wv", true /* include_android_build_number */);
 }
 
 void AwContentClient::AddAdditionalSchemes(Schemes* schemes) {
diff --git a/android_webview/common/aw_hit_test_data.h b/android_webview/common/aw_hit_test_data.h
index 8e5919b..eefce49 100644
--- a/android_webview/common/aw_hit_test_data.h
+++ b/android_webview/common/aw_hit_test_data.h
@@ -22,7 +22,7 @@
     // except the special case described below.
     // For special case of invalid or javascript scheme url that would
     // otherwise be type an LINK type, |href| will contain the javascript
-    // string in the href attribute, and |anchor_text|i and |img_src| contain
+    // string in the href attribute, and |anchor_text| and |img_src| contain
     // their normal values for the respective type.
     UNKNOWN_TYPE = 0,
 
diff --git a/android_webview/common/aw_resource.cc b/android_webview/common/aw_resource.cc
index 6400a1a..77c92d3 100644
--- a/android_webview/common/aw_resource.cc
+++ b/android_webview/common/aw_resource.cc
@@ -19,7 +19,7 @@
   std::vector<std::string> key_system_uuid_mappings;
   ScopedJavaLocalRef<jobjectArray> mappings =
       Java_AwResource_getConfigKeySystemUuidMapping(env);
-  base::android::AppendJavaStringArrayToStringVector(env, mappings.obj(),
+  base::android::AppendJavaStringArrayToStringVector(env, mappings,
                                                      &key_system_uuid_mappings);
   return key_system_uuid_mappings;
 }
diff --git a/android_webview/common/crash_reporter/aw_crash_reporter_client.cc b/android_webview/common/crash_reporter/aw_crash_reporter_client.cc
index e77c26a..f961f7d 100644
--- a/android_webview/common/crash_reporter/aw_crash_reporter_client.cc
+++ b/android_webview/common/crash_reporter/aw_crash_reporter_client.cc
@@ -73,7 +73,8 @@
                                 std::string* channel) override {
     *product_name = "AndroidWebView";
     *version = PRODUCT_VERSION;
-    *channel = version_info::GetChannelString(android_webview::GetChannel());
+    *channel =
+        version_info::GetChannelString(android_webview::GetChannelOrStable());
   }
   // Microdumps are always enabled in WebView builds, conversely to what happens
   // in the case of the other Chrome for Android builds (where they are enabled
diff --git a/android_webview/glue/BUILD.gn b/android_webview/glue/BUILD.gn
index a64e649..e97103b 100644
--- a/android_webview/glue/BUILD.gn
+++ b/android_webview/glue/BUILD.gn
@@ -24,24 +24,26 @@
       "//third_party/android_system_sdk:public_framework_system_java"
 
   java_files = [
-    "java/src/com/android/webview/chromium/ApiHelperForM.java",
-    "java/src/com/android/webview/chromium/ApiHelperForN.java",
-    "java/src/com/android/webview/chromium/ApiHelperForO.java",
-    "java/src/com/android/webview/chromium/ApiHelperForOMR1.java",
-    "java/src/com/android/webview/chromium/ApiHelperForP.java",
-    "java/src/com/android/webview/chromium/SharedStatics.java",
     "java/src/com/android/webview/chromium/CallbackConverter.java",
     "java/src/com/android/webview/chromium/ContentSettingsAdapter.java",
     "java/src/com/android/webview/chromium/CookieManagerAdapter.java",
     "java/src/com/android/webview/chromium/DrawGLFunctor.java",
     "java/src/com/android/webview/chromium/FontPreloadingWorkaround.java",
     "java/src/com/android/webview/chromium/GeolocationPermissionsAdapter.java",
+    "java/src/com/android/webview/chromium/GlueApiHelperForM.java",
+    "java/src/com/android/webview/chromium/GlueApiHelperForN.java",
+    "java/src/com/android/webview/chromium/GlueApiHelperForO.java",
+    "java/src/com/android/webview/chromium/GlueApiHelperForOMR1.java",
+    "java/src/com/android/webview/chromium/GlueApiHelperForP.java",
     "java/src/com/android/webview/chromium/GraphicsUtils.java",
     "java/src/com/android/webview/chromium/MonochromeLibraryPreloader.java",
     "java/src/com/android/webview/chromium/SafeBrowsingResponseAdapter.java",
     "java/src/com/android/webview/chromium/ServiceWorkerClientAdapter.java",
     "java/src/com/android/webview/chromium/ServiceWorkerControllerAdapter.java",
     "java/src/com/android/webview/chromium/ServiceWorkerSettingsAdapter.java",
+    "java/src/com/android/webview/chromium/SharedStatics.java",
+    "java/src/com/android/webview/chromium/SharedTracingControllerAdapter.java",
+    "java/src/com/android/webview/chromium/SplitApkWorkaround.java",
     "java/src/com/android/webview/chromium/TokenBindingManagerAdapter.java",
     "java/src/com/android/webview/chromium/TracingControllerAdapter.java",
     "java/src/com/android/webview/chromium/WebBackForwardListChromium.java",
diff --git a/android_webview/glue/generate_resource_rewriter.gni b/android_webview/glue/generate_resource_rewriter.gni
index 59581df..f867477 100644
--- a/android_webview/glue/generate_resource_rewriter.gni
+++ b/android_webview/glue/generate_resource_rewriter.gni
@@ -39,14 +39,14 @@
     deps = invoker.deps + [ ":${_build_config_target_name}" ]
     script = "//build/android/gyp/generate_resource_rewriter.py"
 
-    _rebased_build_config = rebase_path(_build_config)
+    _rebased_build_config = rebase_path(_build_config, root_build_dir)
     args = [
       "--package-name",
       invoker.package_name,
       "--dep-packages",
       "@FileArg($_rebased_build_config:resources:extra_package_names)",
       "--srcjar",
-      rebase_path(_srcjar),
+      rebase_path(_srcjar, root_build_dir),
     ]
     outputs = [
       _srcjar,
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForM.java b/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForM.java
deleted file mode 100644
index 4a107fa..0000000
--- a/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForM.java
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package com.android.webview.chromium;
-
-import android.annotation.TargetApi;
-import android.os.Build;
-import android.webkit.WebResourceError;
-import android.webkit.WebResourceRequest;
-import android.webkit.WebResourceResponse;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-import org.chromium.android_webview.AwContentsClient;
-import org.chromium.android_webview.AwWebResourceResponse;
-import org.chromium.base.annotations.DoNotInline;
-
-/**
- * Utility class to use new APIs that were added in M (API level 23). These need to exist in a
- * separate class so that Android framework can successfully verify WebView classes without
- * encountering the new APIs.
- */
-
-@DoNotInline
-@TargetApi(Build.VERSION_CODES.M)
-public final class ApiHelperForM {
-    private ApiHelperForM() {}
-
-    /**
-     * See {@link WebViewClient#onReceivedError(WebView, WebResourceRequest, WebResourceError)},
-     * which was added in M.
-     */
-    public static void onReceivedError(WebViewClient webViewClient, WebView webView,
-            AwContentsClient.AwWebResourceRequest request,
-            AwContentsClient.AwWebResourceError error) {
-        webViewClient.onReceivedError(webView, new WebResourceRequestAdapter(request),
-                new WebResourceErrorAdapter(error));
-    }
-
-    /**
-     * See {@link WebViewClient#onReceivedHttpError(WebView, WebResourceRequest,
-     * WebResourceResponse)}, which was added in M.
-     */
-    public static void onReceivedHttpError(WebViewClient webViewClient, WebView webView,
-            AwContentsClient.AwWebResourceRequest request, AwWebResourceResponse response) {
-        webViewClient.onReceivedHttpError(webView, new WebResourceRequestAdapter(request),
-                new WebResourceResponse(true, response.getMimeType(), response.getCharset(),
-                        response.getStatusCode(), response.getReasonPhrase(),
-                        response.getResponseHeaders(), response.getData()));
-    }
-
-    /**
-     * See {@link WebViewClient#onPageCommitVisible(WebView, String)}, which was added in M.
-     */
-    public static void onPageCommitVisible(
-            WebViewClient webViewClient, WebView webView, String url) {
-        webViewClient.onPageCommitVisible(webView, url);
-    }
-}
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForN.java b/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForN.java
deleted file mode 100644
index 48de6f7..0000000
--- a/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForN.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package com.android.webview.chromium;
-
-import android.annotation.TargetApi;
-import android.os.Build;
-import android.webkit.ServiceWorkerController;
-import android.webkit.TokenBindingService;
-import android.webkit.WebResourceRequest;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-import org.chromium.android_webview.AwContentsClient;
-import org.chromium.base.annotations.DoNotInline;
-
-/**
- * Utility class to use new APIs that were added in N (API level 24). These need to exist in a
- * separate class so that Android framework can successfully verify WebView classes without
- * encountering the new APIs.
- */
-@DoNotInline
-@TargetApi(Build.VERSION_CODES.N)
-public final class ApiHelperForN {
-    private ApiHelperForN() {}
-
-    /**
-     * See {@link
-     * ServiceWorkerControllerAdapter#ServiceWorkerControllerAdapter(AwServiceWorkerController)},
-     * which was added in N.
-     */
-    public static ServiceWorkerController createServiceWorkerControllerAdapter(
-            WebViewChromiumAwInit awInit) {
-        return new ServiceWorkerControllerAdapter(awInit.getServiceWorkerController());
-    }
-
-    /**
-     * See {@link
-     * TokenBindingManagerAdapter#TokenBindingManagerAdapter(WebViewChromiumFactoryProvider)}, which
-     * was added in N.
-     */
-    public static TokenBindingService createTokenBindingManagerAdapter(
-            WebViewChromiumFactoryProvider factory) {
-        return new TokenBindingManagerAdapter(factory);
-    }
-
-    /**
-     * See {@link WebViewClient#shouldOverrideUrlLoading(WebView, WebResourceRequest)}, which was
-     * added in N.
-     */
-    public static boolean shouldOverrideUrlLoading(WebViewClient webViewClient, WebView webView,
-            AwContentsClient.AwWebResourceRequest request) {
-        return webViewClient.shouldOverrideUrlLoading(
-                webView, new WebResourceRequestAdapter(request));
-    }
-}
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForO.java b/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForO.java
deleted file mode 100644
index d12c466..0000000
--- a/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForO.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package com.android.webview.chromium;
-
-import android.annotation.TargetApi;
-import android.os.Build;
-import android.webkit.RenderProcessGoneDetail;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-import org.chromium.android_webview.AwRenderProcessGoneDetail;
-import org.chromium.base.annotations.DoNotInline;
-
-/**
- * Utility class to use new APIs that were added in O (API level 26). These need to exist in a
- * separate class so that Android framework can successfully verify WebView classes without
- * encountering the new APIs.
- */
-@DoNotInline
-@TargetApi(Build.VERSION_CODES.O)
-public final class ApiHelperForO {
-    private ApiHelperForO() {}
-
-    /**
-     * See {@link WebViewClient#onRenderProcessGone(WebView, RenderProcessGoneDetail)}, which was
-     * added in O.
-     */
-    public static boolean onRenderProcessGone(
-            WebViewClient webViewClient, WebView webView, AwRenderProcessGoneDetail detail) {
-        return webViewClient.onRenderProcessGone(webView, new RenderProcessGoneDetail() {
-            @Override
-            public boolean didCrash() {
-                return detail.didCrash();
-            }
-
-            @Override
-            public int rendererPriorityAtExit() {
-                return detail.rendererPriority();
-            }
-        });
-    }
-}
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForOMR1.java b/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForOMR1.java
deleted file mode 100644
index 11340c0..0000000
--- a/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForOMR1.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package com.android.webview.chromium;
-
-import android.annotation.TargetApi;
-import android.os.Build;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-import org.chromium.android_webview.AwContentsClient;
-import org.chromium.android_webview.AwSafeBrowsingResponse;
-import org.chromium.base.Callback;
-import org.chromium.base.annotations.DoNotInline;
-
-/**
- * Utility class to use new APIs that were added in OMR1 (API level 27). These need to exist in a
- * separate class so that Android framework can successfully verify WebView classes without
- * encountering the new APIs.
- */
-@DoNotInline
-@TargetApi(Build.VERSION_CODES.O_MR1)
-public final class ApiHelperForOMR1 {
-    private ApiHelperForOMR1() {}
-
-    /**
-     * See {@link WebViewClient#onSafeBrowsingHit(WebView, WebResourceRequest, int,
-     * SafeBrowsingResponse)}, which was added in OMR1.
-     */
-    public static void onSafeBrowsingHit(WebViewClient webViewClient, WebView webView,
-            AwContentsClient.AwWebResourceRequest request, int threatType,
-            final Callback<AwSafeBrowsingResponse> callback) {
-        webViewClient.onSafeBrowsingHit(webView, new WebResourceRequestAdapter(request), threatType,
-                new SafeBrowsingResponseAdapter(callback));
-    }
-}
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForP.java b/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForP.java
deleted file mode 100644
index 71ee0058..0000000
--- a/android_webview/glue/java/src/com/android/webview/chromium/ApiHelperForP.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package com.android.webview.chromium;
-
-import android.annotation.TargetApi;
-import android.os.Build;
-
-import org.chromium.base.annotations.DoNotInline;
-
-/**
- * Utility class to use new APIs that were added in P (API level 28). These need to exist in a
- * separate class so that Android framework can successfully verify WebView classes without
- * encountering the new APIs.
- */
-@DoNotInline
-@TargetApi(Build.VERSION_CODES.P)
-public final class ApiHelperForP {
-    private ApiHelperForP() {}
-
-    /**
-     * See {@link
-     * TracingControllerAdapter#TracingControllerAdapter(WebViewChromiumFactoryProvider,
-     * AwTracingController)}, which was added in N.
-     */
-    public static TracingControllerAdapter createTracingControllerAdapter(
-            WebViewChromiumFactoryProvider provider, WebViewChromiumAwInit awInit) {
-        return new TracingControllerAdapter(provider, awInit.getAwTracingController());
-    }
-}
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/FontPreloadingWorkaround.java b/android_webview/glue/java/src/com/android/webview/chromium/FontPreloadingWorkaround.java
index e637086..e0ef2e2 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/FontPreloadingWorkaround.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/FontPreloadingWorkaround.java
@@ -9,7 +9,6 @@
 import android.content.pm.PackageManager;
 import android.os.Build;
 
-import org.chromium.base.BuildInfo;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 
@@ -42,7 +41,8 @@
      */
     public static void maybeInstallWorkaround(Context appContext) {
         // Only isolated renderer processes running on O devices need this workaround.
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || BuildInfo.isAtLeastP()
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O
+                || Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
                 || !ContextUtils.isIsolatedProcess()) {
             return;
         }
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForM.java b/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForM.java
new file mode 100644
index 0000000..d322fcf
--- /dev/null
+++ b/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForM.java
@@ -0,0 +1,53 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package com.android.webview.chromium;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.webkit.WebResourceResponse;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+import org.chromium.android_webview.AwContentsClient;
+import org.chromium.android_webview.AwWebResourceResponse;
+import org.chromium.base.annotations.DoNotInline;
+
+/**
+ * Utility class to use new APIs that were added in M (API level 23). These need to exist in a
+ * separate class so that Android framework can successfully verify glue layer classes without
+ * encountering the new APIs. Note that GlueApiHelper is only for APIs that cannot go to ApiHelper
+ * in base/, for reasons such as using system APIs or instantiating an adapter class that is
+ * specific to glue layer.
+ */
+@DoNotInline
+@TargetApi(Build.VERSION_CODES.M)
+public final class GlueApiHelperForM {
+    private GlueApiHelperForM() {}
+
+    /**
+     * See {@link WebViewClient#onReceivedError(WebView, WebResourceRequest, WebResourceError)},
+     * which was added in M.
+     */
+    public static void onReceivedError(WebViewClient webViewClient, WebView webView,
+            AwContentsClient.AwWebResourceRequest request,
+            AwContentsClient.AwWebResourceError error) {
+        webViewClient.onReceivedError(webView, new WebResourceRequestAdapter(request),
+                new WebResourceErrorAdapter(error));
+    }
+
+    /**
+     * See {@link WebViewClient#onReceivedHttpError(WebView, WebResourceRequest,
+     * WebResourceResponse)}, which was added in M.
+     *
+     * Note that creation of WebResourceResponse with 'immutable' parameter is non-public.
+     */
+    public static void onReceivedHttpError(WebViewClient webViewClient, WebView webView,
+            AwContentsClient.AwWebResourceRequest request, AwWebResourceResponse response) {
+        webViewClient.onReceivedHttpError(webView, new WebResourceRequestAdapter(request),
+                new WebResourceResponse(true, response.getMimeType(), response.getCharset(),
+                        response.getStatusCode(), response.getReasonPhrase(),
+                        response.getResponseHeaders(), response.getData()));
+    }
+}
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForN.java b/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForN.java
new file mode 100644
index 0000000..0638724
--- /dev/null
+++ b/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForN.java
@@ -0,0 +1,79 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package com.android.webview.chromium;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Canvas;
+import android.os.Build;
+import android.os.UserManager;
+import android.webkit.ServiceWorkerController;
+import android.webkit.TokenBindingService;
+import android.webkit.WebView;
+import android.webkit.WebViewDelegate;
+
+import org.chromium.base.annotations.DoNotInline;
+
+/**
+ * Utility class to use new APIs that were added in N (API level 24). These need to exist in a
+ * separate class so that Android framework can successfully verify glue layer classes without
+ * encountering the new APIs. Note that GlueApiHelper is only for APIs that cannot go to ApiHelper
+ * in base/, for reasons such as using system APIs or instantiating an adapter class that is
+ * specific to glue layer.
+ */
+@DoNotInline
+@TargetApi(Build.VERSION_CODES.N)
+public final class GlueApiHelperForN {
+    private GlueApiHelperForN() {}
+
+    /**
+     * See {@link
+     * ServiceWorkerControllerAdapter#ServiceWorkerControllerAdapter(AwServiceWorkerController)},
+     * which was added in N.
+     */
+    public static ServiceWorkerController createServiceWorkerControllerAdapter(
+            WebViewChromiumAwInit awInit) {
+        return new ServiceWorkerControllerAdapter(awInit.getServiceWorkerController());
+    }
+
+    /**
+     * See {@link
+     * TokenBindingManagerAdapter#TokenBindingManagerAdapter(WebViewChromiumFactoryProvider)}, which
+     * was added in N.
+     */
+    public static TokenBindingService createTokenBindingManagerAdapter(
+            WebViewChromiumFactoryProvider factory) {
+        return new TokenBindingManagerAdapter(factory);
+    }
+
+    /**
+     * See {@link Context#isDeviceProtectedStorage()}.
+     */
+    public static boolean isDeviceProtectedStorage(Context context) {
+        return context.isDeviceProtectedStorage();
+    }
+
+    /**
+     * See {@link UserManager#isUserUnlocked()}.
+     */
+    public static boolean isUserUnlocked(Context context) {
+        return context.getSystemService(UserManager.class).isUserUnlocked();
+    }
+
+    public static Context createCredentialProtectedStorageContext(Context context) {
+        return context.createCredentialProtectedStorageContext();
+    }
+
+    public static void callDrawGlFunction(WebViewDelegate webViewDelegate, Canvas canvas,
+            long nativeDrawGlFunctor, Runnable releasedCallback) {
+        webViewDelegate.callDrawGlFunction(canvas, nativeDrawGlFunctor, releasedCallback);
+    }
+
+    public static void super_startActivityForResult(
+            WebView.PrivateAccess webViewPrivate, Intent intent, int requestCode) {
+        webViewPrivate.super_startActivityForResult(intent, requestCode);
+    }
+}
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForO.java b/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForO.java
new file mode 100644
index 0000000..37e658f
--- /dev/null
+++ b/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForO.java
@@ -0,0 +1,54 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package com.android.webview.chromium;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.webkit.RenderProcessGoneDetail;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.webkit.WebViewDelegate;
+
+import org.chromium.android_webview.AwRenderProcessGoneDetail;
+import org.chromium.base.annotations.DoNotInline;
+
+/**
+ * Utility class to use new APIs that were added in O (API level 26). These need to exist in a
+ * separate class so that Android framework can successfully verify glue layer classes without
+ * encountering the new APIs. Note that GlueApiHelper is only for APIs that cannot go to ApiHelper
+ * in base/, for reasons such as using system APIs or instantiating an adapter class that is
+ * specific to glue layer.
+ */
+@DoNotInline
+@TargetApi(Build.VERSION_CODES.O)
+public final class GlueApiHelperForO {
+    private GlueApiHelperForO() {}
+
+    /**
+     * See {@link WebViewClient#onRenderProcessGone(WebView, RenderProcessGoneDetail)}, which was
+     * added in O.
+     *
+     * Note that we are calling into AwRenderProcessGoneDetail so leaving it here. Potentially,
+     * we might hide RenderProcessGoneDetail's constructor.
+     */
+    public static boolean onRenderProcessGone(
+            WebViewClient webViewClient, WebView webView, AwRenderProcessGoneDetail detail) {
+        return webViewClient.onRenderProcessGone(webView, new RenderProcessGoneDetail() {
+            @Override
+            public boolean didCrash() {
+                return detail.didCrash();
+            }
+
+            @Override
+            public int rendererPriorityAtExit() {
+                return detail.rendererPriority();
+            }
+        });
+    }
+
+    public static boolean isMultiProcessEnabled(WebViewDelegate webViewDelegate) {
+        return webViewDelegate.isMultiProcessEnabled();
+    }
+}
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForOMR1.java b/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForOMR1.java
new file mode 100644
index 0000000..a1f61df
--- /dev/null
+++ b/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForOMR1.java
@@ -0,0 +1,39 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package com.android.webview.chromium;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+import org.chromium.android_webview.AwContentsClient.AwWebResourceRequest;
+import org.chromium.android_webview.AwSafeBrowsingResponse;
+import org.chromium.base.Callback;
+import org.chromium.base.annotations.DoNotInline;
+
+/**
+ * Utility class to use new APIs that were added in OMR1 (API level 27). These need to exist in a
+ * separate class so that Android framework can successfully verify glue layer classes without
+ * encountering the new APIs. Note that GlueApiHelper is only for APIs that cannot go to ApiHelper
+ * in base/, for reasons such as using system APIs or instantiating an adapter class that is
+ * specific to glue layer.
+ */
+@DoNotInline
+@TargetApi(Build.VERSION_CODES.O_MR1)
+public final class GlueApiHelperForOMR1 {
+    private GlueApiHelperForOMR1() {}
+
+    /**
+     * See {@link WebViewClient#onSafeBrowsingHit(WebView, WebResourceRequest, int,
+     * SafeBrowsingResponse)}, which was added in OMR1.
+     */
+    public static void onSafeBrowsingHit(WebViewClient webViewClient, WebView webView,
+            AwWebResourceRequest request, int threatType,
+            Callback<AwSafeBrowsingResponse> callback) {
+        webViewClient.onSafeBrowsingHit(webView, new WebResourceRequestAdapter(request), threatType,
+                new SafeBrowsingResponseAdapter(callback));
+    }
+}
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForP.java b/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForP.java
new file mode 100644
index 0000000..04ff2ea
--- /dev/null
+++ b/android_webview/glue/java/src/com/android/webview/chromium/GlueApiHelperForP.java
@@ -0,0 +1,39 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package com.android.webview.chromium;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.webkit.TracingController;
+import android.webkit.WebViewDelegate;
+
+import org.chromium.base.annotations.DoNotInline;
+
+/**
+ * Utility class to use new APIs that were added in P (API level 28). These need to exist in a
+ * separate class so that Android framework can successfully verify glue layer classes without
+ * encountering the new APIs. Note that GlueApiHelper is only for APIs that cannot go to ApiHelper
+ * in base/, for reasons such as using system APIs or instantiating an adapter class that is
+ * specific to glue layer.
+ */
+@DoNotInline
+@TargetApi(Build.VERSION_CODES.P)
+public final class GlueApiHelperForP {
+    private GlueApiHelperForP() {}
+
+    /**
+     * See {@link
+     * TracingControllerAdapter#TracingControllerAdapter(WebViewChromiumFactoryProvider,
+     * AwTracingController)}, which was added in P.
+     */
+    public static TracingController createTracingControllerAdapter(
+            WebViewChromiumFactoryProvider provider, WebViewChromiumAwInit awInit) {
+        return new TracingControllerAdapter(new SharedTracingControllerAdapter(
+                awInit.getRunQueue(), awInit.getAwTracingController()));
+    }
+    public static String getDataDirectorySuffix(WebViewDelegate webViewDelegate) {
+        return webViewDelegate.getDataDirectorySuffix();
+    }
+}
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java b/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java
index 7fe5fbb..4605897 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java
@@ -118,12 +118,22 @@
                 () -> AwContentsStatics.getSafeBrowsingPrivacyPolicyUrl());
     }
 
-    public void setProxyOverride(String host, int port, String[] exclusionList) {
+    public void setProxyOverride(String host, int port, String[] exclusionList, Runnable callback) {
+        if (host == null) {
+            throw new NullPointerException("Host string should not be null");
+        }
+        if (exclusionList != null) {
+            for (String url : exclusionList) {
+                if (url == null) {
+                    throw new NullPointerException("Excluded URL strings should not be null");
+                }
+            }
+        }
         ThreadUtils.runOnUiThread(
-                () -> AwContentsStatics.setProxyOverride(host, port, exclusionList));
+                () -> AwContentsStatics.setProxyOverride(host, port, exclusionList, callback));
     }
 
-    public void clearProxyOverride() {
-        ThreadUtils.runOnUiThread(() -> AwContentsStatics.clearProxyOverride());
+    public void clearProxyOverride(Runnable callback) {
+        ThreadUtils.runOnUiThread(() -> AwContentsStatics.clearProxyOverride(callback));
     }
 }
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/SharedTracingControllerAdapter.java b/android_webview/glue/java/src/com/android/webview/chromium/SharedTracingControllerAdapter.java
new file mode 100644
index 0000000..a392579
--- /dev/null
+++ b/android_webview/glue/java/src/com/android/webview/chromium/SharedTracingControllerAdapter.java
@@ -0,0 +1,168 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package com.android.webview.chromium;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.webkit.TracingConfig;
+
+import org.chromium.android_webview.AwTracingController;
+import org.chromium.android_webview.WebViewChromiumRunQueue;
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.TraceRecordMode;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.concurrent.Executor;
+
+/**
+ * This class adapts between the common threading and parameter expectations of the
+ * webkit framework and support library APIs and those of AwTracingController and
+ * makes sure the calls happen on the UI thread.
+ * Translates predefined categories and posts callbacks.
+ *
+ * This class specifically does not rely on android.webkit.TracingConfig and uses only
+ * its constants which just need to be available at compile time.
+ */
+public class SharedTracingControllerAdapter {
+    private final WebViewChromiumRunQueue mRunQueue;
+    private final AwTracingController mAwTracingController;
+
+    public boolean isTracing() {
+        if (checkNeedsPost()) {
+            return mRunQueue.runOnUiThreadBlocking(mAwTracingController::isTracing);
+        }
+        return mAwTracingController.isTracing();
+    }
+
+    public SharedTracingControllerAdapter(
+            WebViewChromiumRunQueue runQueue, AwTracingController controller) {
+        mRunQueue = runQueue;
+        mAwTracingController = controller;
+    }
+
+    private static int convertAndroidTracingMode(int tracingMode) {
+        switch (tracingMode) {
+            case TracingConfig.RECORD_UNTIL_FULL:
+                return TraceRecordMode.RECORD_UNTIL_FULL;
+            case TracingConfig.RECORD_CONTINUOUSLY:
+                return TraceRecordMode.RECORD_CONTINUOUSLY;
+        }
+        return TraceRecordMode.RECORD_CONTINUOUSLY;
+    }
+
+    private static boolean categoryIsSet(int bitmask, int categoryMask) {
+        return (bitmask & categoryMask) == categoryMask;
+    }
+
+    private static Collection<Integer> collectPredefinedCategories(int bitmask) {
+        ArrayList<Integer> predefinedIndices = new ArrayList<>();
+        // CATEGORIES_NONE is skipped on purpose.
+        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_ALL)) {
+            predefinedIndices.add(AwTracingController.CATEGORIES_ALL);
+        }
+        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_ANDROID_WEBVIEW)) {
+            predefinedIndices.add(AwTracingController.CATEGORIES_ANDROID_WEBVIEW);
+        }
+        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_WEB_DEVELOPER)) {
+            predefinedIndices.add(AwTracingController.CATEGORIES_WEB_DEVELOPER);
+        }
+        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_INPUT_LATENCY)) {
+            predefinedIndices.add(AwTracingController.CATEGORIES_INPUT_LATENCY);
+        }
+        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_RENDERING)) {
+            predefinedIndices.add(AwTracingController.CATEGORIES_RENDERING);
+        }
+        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_JAVASCRIPT_AND_RENDERING)) {
+            predefinedIndices.add(AwTracingController.CATEGORIES_JAVASCRIPT_AND_RENDERING);
+        }
+        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_FRAME_VIEWER)) {
+            predefinedIndices.add(AwTracingController.CATEGORIES_FRAME_VIEWER);
+        }
+        return predefinedIndices;
+    }
+
+    private int startOnUI(int predefinedCategories, Collection<String> customIncludedCategories,
+                          int tracingMode) {
+        return mAwTracingController.start(
+                collectPredefinedCategories(predefinedCategories),
+                customIncludedCategories, convertAndroidTracingMode(tracingMode));
+    }
+
+    public void start(int predefinedCategories, Collection<String> customIncludedCategories,
+                      int tracingMode) {
+        int result = checkNeedsPost() ?
+            mRunQueue.runOnUiThreadBlocking(
+                    () -> startOnUI(predefinedCategories, customIncludedCategories, tracingMode)) :
+            startOnUI(predefinedCategories, customIncludedCategories, tracingMode);
+
+        if (result != AwTracingController.RESULT_SUCCESS) {
+            // make sure to throw on the original calling thread.
+            switch (result) {
+                case AwTracingController.RESULT_ALREADY_TRACING:
+                    throw new IllegalStateException(
+                            "cannot start tracing: tracing is already enabled");
+                case AwTracingController.RESULT_INVALID_CATEGORIES:
+                    throw new IllegalArgumentException(
+                            "category patterns starting with '-' or containing ','"
+                                    + " are not allowed");
+                case AwTracingController.RESULT_INVALID_MODE:
+                    throw new IllegalArgumentException("invalid tracing mode");
+            }
+        }
+    }
+
+    public boolean stop(@Nullable OutputStream outputStream, @NonNull Executor executor) {
+        return checkNeedsPost() ?
+            mRunQueue.runOnUiThreadBlocking(
+                    () -> stopOnUI(outputStream, executor)):
+            stopOnUI(outputStream, executor);
+    }
+
+    private boolean stopOnUI(@Nullable OutputStream outputStream, @NonNull Executor executor) {
+        if (outputStream == null) {
+            return mAwTracingController.stopAndFlush(null);
+        }
+
+        final OutputStream localOutputStream = outputStream;
+        return mAwTracingController.stopAndFlush(new OutputStream() {
+            @Override
+            public void write(byte[] chunk) {
+                executor.execute(() -> {
+                    try {
+                        localOutputStream.write(chunk);
+                    } catch (IOException e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+            }
+            @Override
+            public void close() {
+                executor.execute(() -> {
+                    try {
+                        localOutputStream.close();
+                    } catch (IOException e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+            }
+            @Override
+            public void write(int b) { /* should not be called */
+            }
+            @Override
+            public void flush() { /* should not be called */
+            }
+            @Override
+            public void write(byte[] b, int off, int len) { /* should not be called */
+            }
+        });
+    }
+
+    private static boolean checkNeedsPost() {
+        return !ThreadUtils.runningOnUiThread();
+    }
+}
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java
index f1039a4..17fac45 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java
@@ -8,6 +8,7 @@
 import android.webkit.WebViewClient;
 
 import org.chromium.android_webview.AwContents;
+import org.chromium.android_webview.AwRenderProcess;
 import org.chromium.android_webview.WebViewChromiumRunQueue;
 import org.chromium.base.ThreadUtils;
 import org.chromium.content_public.browser.MessagePort;
@@ -51,6 +52,14 @@
         return mWebChromeClient;
     }
 
+    public AwRenderProcess getRenderProcess() {
+        mAwInit.startYourEngines(true);
+        if (checkNeedsPost()) {
+            return mRunQueue.runOnUiThreadBlocking(() -> getRenderProcess());
+        }
+        return mAwContents.getRenderProcess();
+    }
+
     public void setAwContentsOnUiThread(AwContents awContents) {
         assert ThreadUtils.runningOnUiThread();
 
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/SplitApkWorkaround.java b/android_webview/glue/java/src/com/android/webview/chromium/SplitApkWorkaround.java
new file mode 100644
index 0000000..11cf6fa
--- /dev/null
+++ b/android_webview/glue/java/src/com/android/webview/chromium/SplitApkWorkaround.java
@@ -0,0 +1,143 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package com.android.webview.chromium;
+
+import dalvik.system.BaseDexClassLoader;
+
+import org.chromium.base.Log;
+import org.chromium.base.process_launcher.ChildProcessService.SplitApkWorkaroundResult;
+
+import java.io.File;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+/**
+ * WebView-side workaround for the Android O framework bug described in https://crbug.com/889954
+ * which affects us if we are the current WebView provider and we were installed as a split APK.
+ */
+public class SplitApkWorkaround {
+    private static final String TAG = "SplitApkWorkaround";
+
+    /**
+     * There is a framework bug in O that causes an incorrect classloader cache entry to be created
+     * when the WebView provider is installed as multiple split APKs.
+     * Use reflection to correct the cache entry during WebView zygote startup.
+     * This function runs in the WebView zygote, which cannot make any binder calls to the framework
+     * and is a very restricted environment.
+     *
+     * @param realRun If false, don't actually change any state in the framework; just verify that
+     *               the reflection succeeds.
+     * @return a value from Result describing what happened.
+     */
+    @SuppressWarnings("unchecked")
+    public static @SplitApkWorkaroundResult int apply(boolean realRun) {
+        int matchingEntries = 0;
+        int exceptionEntries = 0;
+        try {
+            // Retrieve all the required classes and fields first, such that if any of the lookups
+            // fail, we won't have done anything yet.
+            Class<?> alClass = Class.forName("android.app.ApplicationLoaders");
+            Method getDefaultMethod = alClass.getDeclaredMethod("getDefault");
+            Field mLoadersField = alClass.getDeclaredField("mLoaders");
+            mLoadersField.setAccessible(true);
+            Field pathListField = BaseDexClassLoader.class.getDeclaredField("pathList");
+            pathListField.setAccessible(true);
+            Class<?> dplClass = Class.forName("dalvik.system.DexPathList");
+            Field dexElementsField = dplClass.getDeclaredField("dexElements");
+            dexElementsField.setAccessible(true);
+            Class<?> elClass = Class.forName("dalvik.system.DexPathList$Element");
+            Field pathField = elClass.getDeclaredField("path");
+            pathField.setAccessible(true);
+
+            // Retrieve the ApplicationLoaders singleton and get the cache from inside it.
+            Object alInstance = getDefaultMethod.invoke(null);
+            Object rawLoaders = mLoadersField.get(alInstance);
+            Map<String, ClassLoader> loaders = (Map<String, ClassLoader>) rawLoaders;
+
+            // Synchronize on the map while trying to update it, as the framework does.
+            synchronized (loaders) {
+                for (Map.Entry<String, ClassLoader> entry : loaders.entrySet()) {
+                    try {
+                        if (!(entry.getValue() instanceof BaseDexClassLoader)) {
+                            // If it's some other type it can't be the right one.
+                            continue;
+                        }
+                        String cacheKey = entry.getKey();
+                        BaseDexClassLoader cl = (BaseDexClassLoader) entry.getValue();
+
+                        // Get the list of files that this classloader uses as its classpath.
+                        Object pathList = pathListField.get(cl);
+                        Object dexElements = dexElementsField.get(pathList);
+
+                        int elementCount = Array.getLength(dexElements);
+                        if (elementCount <= 1) {
+                            // If there's only one file, then this classloader cannot be affected by
+                            // the bug, so ignore it.
+                            continue;
+                        }
+
+                        // If there's more than one file, get the first file in the path.
+                        // If it's the same as our cache key, then the cache key must, by
+                        // definition, be incomplete - listing only one file when it should list
+                        // all of them.
+                        Object firstElement = Array.get(dexElements, 0);
+                        File firstPath = (File) pathField.get(firstElement);
+                        if (cacheKey.equals(firstPath.getPath())) {
+                            // Build a new, correct cache key by concatenating all the files in the
+                            // list together in order, separated by colons.
+                            String newCacheKey = cacheKey;
+                            for (int i = 1; i < elementCount; i++) {
+                                Object element = Array.get(dexElements, i);
+                                File path = (File) pathField.get(element);
+                                newCacheKey += ":" + path.getPath();
+                            }
+
+                            matchingEntries++;
+                            if (realRun) {
+                                // Add a new entry to the cache which maps the new, correct key to
+                                // the same classloader object. We do not remove the previous entry
+                                // from the cache, in case something attempts to look it up by the
+                                // old key for some reason - it shouldn't cause a problem for there
+                                // to be multiple entries mapping to the same classloader.
+                                loaders.put(newCacheKey, cl);
+                                Log.i(TAG, "Fixed classloader cache entry for " + newCacheKey);
+                            }
+                        }
+                    } catch (Exception e) {
+                        // We log and ignore it here so we can continue looping through the cache,
+                        // in the hope that the one that threw an exception wasn't the one we
+                        // were looking for.
+                        exceptionEntries++;
+                        Log.w(TAG, "Caught exception while attempting to fix classloader cache", e);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            // If we got an exception at this point we assume that we failed to fix it, since we
+            // didn't get as far as iterating over the cache entries.
+            Log.w(TAG, "Caught exception while attempting to fix classloader cache", e);
+            return SplitApkWorkaroundResult.TOPLEVEL_EXCEPTION;
+        }
+
+        // If we found at least one matching entry, then don't worry about exceptions that happened
+        // during the loop; we likely found the correct classloader, and the one that triggered an
+        // exception was probably not relevant. Distinguish one vs multiple entries, though,
+        // because multiple matches is unexpected (only one case in the code is supposed to create
+        // this situation).
+        if (matchingEntries == 1) return SplitApkWorkaroundResult.ONE_ENTRY;
+        if (matchingEntries > 1) return SplitApkWorkaroundResult.MULTIPLE_ENTRIES;
+
+        // If we didn't find any matching entries, but did get an exception during the loop, then
+        // report this, as we might have taken the exception while trying to access the entry we
+        // needed to fix.
+        if (exceptionEntries > 0) return SplitApkWorkaroundResult.LOOP_EXCEPTION;
+
+        // Otherwise, we just didn't find any entries at all, which is probably fine; not all
+        // configurations actually trigger the bug.
+        return SplitApkWorkaroundResult.NO_ENTRIES;
+    }
+}
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/TracingControllerAdapter.java b/android_webview/glue/java/src/com/android/webview/chromium/TracingControllerAdapter.java
index 5b757ba..ba4e0bd 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/TracingControllerAdapter.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/TracingControllerAdapter.java
@@ -10,32 +10,20 @@
 import android.webkit.TracingConfig;
 import android.webkit.TracingController;
 
-import org.chromium.android_webview.AwTracingController;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.TraceRecordMode;
-
-import java.io.IOException;
 import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.concurrent.Callable;
 import java.util.concurrent.Executor;
 
 /**
  * Chromium implementation of TracingController -- forwards calls to
- * the chromium internal implementation and makes sure the calls happen on the
- * UI thread. Translates predefined categories and posts callbacks.
+ * the shared internal implementation.
  */
 @SuppressLint({"NewApi", // TracingController is new in API level 28.
         "Override"}) // Remove this once lint is targeting API level 28.
 public class TracingControllerAdapter extends TracingController {
-    private final AwTracingController mAwTracingController;
-    private final WebViewChromiumFactoryProvider mFactory;
+    private final SharedTracingControllerAdapter mTracingController;
 
-    public TracingControllerAdapter(
-            WebViewChromiumFactoryProvider factory, AwTracingController controller) {
-        mFactory = factory;
-        mAwTracingController = controller;
+    public TracingControllerAdapter(SharedTracingControllerAdapter tracingController) {
+        mTracingController = tracingController;
     }
 
     @Override
@@ -44,148 +32,17 @@
             throw new IllegalArgumentException("tracingConfig cannot be null");
         }
 
-        int result = 0;
-        if (checkNeedsPost()) {
-            result = mFactory.runOnUiThreadBlocking(new Callable<Integer>() {
-                @Override
-                public Integer call() {
-                    return startOnUI(tracingConfig);
-                }
-            });
-        } else {
-            result = startOnUI(tracingConfig);
-        }
-
-        if (result != AwTracingController.RESULT_SUCCESS) {
-            // make sure to throw on the original calling thread.
-            switch (result) {
-                case AwTracingController.RESULT_ALREADY_TRACING:
-                    throw new IllegalStateException(
-                            "cannot start tracing: tracing is already enabled");
-                case AwTracingController.RESULT_INVALID_CATEGORIES:
-                    throw new IllegalArgumentException(
-                            "category patterns starting with '-' or containing ','"
-                            + " are not allowed");
-                case AwTracingController.RESULT_INVALID_MODE:
-                    throw new IllegalArgumentException("invalid tracing mode");
-            }
-        }
+        mTracingController.start(tracingConfig.getPredefinedCategories(),
+                tracingConfig.getCustomIncludedCategories(), tracingConfig.getTracingMode());
     }
 
     @Override
     public boolean stop(@Nullable OutputStream outputStream, @NonNull Executor executor) {
-        if (checkNeedsPost()) {
-            return mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
-                @Override
-                public Boolean call() {
-                    return stopOnUI(outputStream, executor);
-                }
-            });
-        }
-        return stopOnUI(outputStream, executor);
+        return mTracingController.stop(outputStream, executor);
     }
 
     @Override
     public boolean isTracing() {
-        if (checkNeedsPost()) {
-            return mFactory.runOnUiThreadBlocking(new Callable<Boolean>() {
-                @Override
-                public Boolean call() {
-                    return mAwTracingController.isTracing();
-                }
-            });
-        }
-        return mAwTracingController.isTracing();
-    }
-
-    private int convertAndroidTracingMode(int tracingMode) {
-        switch (tracingMode) {
-            case TracingConfig.RECORD_UNTIL_FULL:
-                return TraceRecordMode.RECORD_UNTIL_FULL;
-            case TracingConfig.RECORD_CONTINUOUSLY:
-                return TraceRecordMode.RECORD_CONTINUOUSLY;
-        }
-        return TraceRecordMode.RECORD_CONTINUOUSLY;
-    }
-
-    private boolean categoryIsSet(int bitmask, int categoryMask) {
-        return (bitmask & categoryMask) == categoryMask;
-    }
-
-    private Collection<Integer> collectPredefinedCategories(int bitmask) {
-        ArrayList<Integer> predefinedIndices = new ArrayList<Integer>();
-        // CATEGORIES_NONE is skipped on purpose.
-        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_ALL)) {
-            predefinedIndices.add(AwTracingController.CATEGORIES_ALL);
-        }
-        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_ANDROID_WEBVIEW)) {
-            predefinedIndices.add(AwTracingController.CATEGORIES_ANDROID_WEBVIEW);
-        }
-        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_WEB_DEVELOPER)) {
-            predefinedIndices.add(AwTracingController.CATEGORIES_WEB_DEVELOPER);
-        }
-        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_INPUT_LATENCY)) {
-            predefinedIndices.add(AwTracingController.CATEGORIES_INPUT_LATENCY);
-        }
-        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_RENDERING)) {
-            predefinedIndices.add(AwTracingController.CATEGORIES_RENDERING);
-        }
-        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_JAVASCRIPT_AND_RENDERING)) {
-            predefinedIndices.add(AwTracingController.CATEGORIES_JAVASCRIPT_AND_RENDERING);
-        }
-        if (categoryIsSet(bitmask, TracingConfig.CATEGORIES_FRAME_VIEWER)) {
-            predefinedIndices.add(AwTracingController.CATEGORIES_FRAME_VIEWER);
-        }
-        return predefinedIndices;
-    }
-
-    private int startOnUI(TracingConfig tracingConfig) {
-        return mAwTracingController.start(
-                collectPredefinedCategories(tracingConfig.getPredefinedCategories()),
-                tracingConfig.getCustomIncludedCategories(),
-                convertAndroidTracingMode(tracingConfig.getTracingMode()));
-    }
-
-    public boolean stopOnUI(@Nullable OutputStream outputStream, @NonNull Executor executor) {
-        if (outputStream == null) {
-            return mAwTracingController.stopAndFlush((OutputStream) null);
-        }
-
-        final OutputStream localOutputStream = outputStream;
-        return mAwTracingController.stopAndFlush(new OutputStream() {
-            @Override
-            public void write(byte[] chunk) {
-                executor.execute(() -> {
-                    try {
-                        localOutputStream.write(chunk);
-                    } catch (IOException e) {
-                        throw new RuntimeException(e);
-                    }
-                });
-            }
-            @Override
-            public void close() {
-                executor.execute(() -> {
-                    try {
-                        localOutputStream.close();
-                    } catch (IOException e) {
-                        throw new RuntimeException(e);
-                    }
-                });
-            }
-            @Override
-            public void write(int b) { /* should not be called */
-            }
-            @Override
-            public void flush() { /* should not be called */
-            }
-            @Override
-            public void write(byte[] b, int off, int len) { /* should not be called */
-            }
-        });
-    }
-
-    private static boolean checkNeedsPost() {
-        return !ThreadUtils.runningOnUiThread();
+        return mTracingController.isTracing();
     }
 }
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
index a78264d..d77fc1c 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
@@ -61,7 +61,6 @@
 import org.chromium.android_webview.ResourcesContextWrapperFactory;
 import org.chromium.android_webview.ScopedSysTraceEvent;
 import org.chromium.android_webview.renderer_priority.RendererPriority;
-import org.chromium.base.BuildInfo;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.metrics.CachedMetrics.TimesHistogramSample;
 import org.chromium.components.autofill.AutofillProvider;
@@ -212,7 +211,7 @@
                 mWebSettings.getAwSettings().setZeroLayoutHeightDisablesViewportQuirk(true);
             }
 
-            if (BuildInfo.targetsAtLeastP()) {
+            if (mAppTargetSdkVersion >= Build.VERSION_CODES.P) {
                 mWebSettings.getAwSettings().setCSSHexAlphaColorEnabled(true);
                 mWebSettings.getAwSettings().setScrollTopLeftInteropEnabled(true);
             }
@@ -2316,7 +2315,8 @@
         @Override
         public void super_startActivityForResult(Intent intent, int requestCode) {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-                mWebViewPrivate.super_startActivityForResult(intent, requestCode);
+                GlueApiHelperForN.super_startActivityForResult(
+                        mWebViewPrivate, intent, requestCode);
             } else {
                 try {
                     Method startActivityForResultMethod =
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java
index 9a160a0..0b141d6 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java
@@ -5,6 +5,7 @@
 package com.android.webview.chromium;
 
 import android.Manifest;
+import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -33,17 +34,21 @@
 import org.chromium.android_webview.HttpAuthDatabase;
 import org.chromium.android_webview.ScopedSysTraceEvent;
 import org.chromium.android_webview.VariationsSeedLoader;
+import org.chromium.android_webview.WebViewChromiumRunQueue;
 import org.chromium.android_webview.command_line.CommandLineUtil;
 import org.chromium.base.BuildConfig;
 import org.chromium.base.ContextUtils;
+import org.chromium.base.FieldTrialList;
 import org.chromium.base.PathService;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.TraceEvent;
+import org.chromium.base.annotations.DoNotInline;
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.library_loader.LibraryProcessType;
 import org.chromium.base.library_loader.ProcessInitException;
 import org.chromium.base.metrics.CachedMetrics;
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.task.AsyncTask;
 import org.chromium.net.NetworkChangeNotifier;
 
 /**
@@ -56,13 +61,27 @@
 
     private static final String HTTP_AUTH_DATABASE_FILE = "http_auth.db";
 
+    /**
+     * This holds objects of classes that are defined in N and above to ensure that run-time class
+     * verification does not occur until it is actually used for N and above.
+     */
+    @TargetApi(Build.VERSION_CODES.N)
+    @DoNotInline
+    private static class ObjectHolderForN {
+        public TokenBindingService mTokenBindingService;
+    }
+
     // TODO(gsennton): store aw-objects instead of adapters here
     // Initialization guarded by mLock.
     private AwBrowserContext mBrowserContext;
     private SharedStatics mSharedStatics;
     private GeolocationPermissionsAdapter mGeolocationPermissions;
     private CookieManagerAdapter mCookieManager;
-    private Object mTokenBindingManager;
+
+    @TargetApi(Build.VERSION_CODES.N)
+    private ObjectHolderForN mObjectHolderForN =
+            Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? new ObjectHolderForN() : null;
+
     private WebIconDatabaseAdapter mWebIconDatabase;
     private WebStorageAdapter mWebStorage;
     private WebViewDatabaseAdapter mWebViewDatabase;
@@ -88,7 +107,7 @@
         // WebViewChromiumFactoryProvider ctor, so 'factory' is not properly initialized yet.
     }
 
-    AwTracingController getAwTracingController() {
+    public AwTracingController getAwTracingController() {
         synchronized (mLock) {
             if (mAwTracingController == null) {
                 ensureChromiumStartedLocked(true);
@@ -182,6 +201,8 @@
             }
 
             mFactory.getRunQueue().drainQueue();
+
+            maybeLogActiveTrials(context);
         }
     }
 
@@ -371,13 +392,15 @@
         return mServiceWorkerController;
     }
 
+    @TargetApi(Build.VERSION_CODES.N)
     public TokenBindingService getTokenBindingService() {
         synchronized (mLock) {
-            if (mTokenBindingManager == null) {
-                mTokenBindingManager = ApiHelperForN.createTokenBindingManagerAdapter(mFactory);
+            if (mObjectHolderForN.mTokenBindingService == null) {
+                mObjectHolderForN.mTokenBindingService =
+                        GlueApiHelperForN.createTokenBindingManagerAdapter(mFactory);
             }
         }
-        return (TokenBindingService) mTokenBindingManager;
+        return mObjectHolderForN.mTokenBindingService;
     }
 
     public android.webkit.WebIconDatabase getWebIconDatabase() {
@@ -432,4 +455,25 @@
             mSeedLoader = null; // Allow this to be GC'd after its background thread finishes.
         }
     }
+
+    // If a certain app is installed, log field trials as they become active, for debugging
+    // purposes. Check for the app asyncronously because PackageManager is slow.
+    private static void maybeLogActiveTrials(final Context ctx) {
+        AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
+            try {
+                // This must match the package name in:
+                // android_webview/tools/webview_log_verbosifier/AndroidManifest.xml
+                ctx.getPackageManager().getPackageInfo(
+                        "org.chromium.webview_log_verbosifier", /*flags=*/0);
+            } catch (PackageManager.NameNotFoundException e) {
+                return;
+            }
+
+            ThreadUtils.postOnUiThread(() -> FieldTrialList.logActiveTrials());
+        });
+    }
+
+    public WebViewChromiumRunQueue getRunQueue() {
+        return mFactory.getRunQueue();
+    }
 }
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
index 8b99f83..3168066 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
@@ -12,9 +12,7 @@
 import android.net.Uri;
 import android.os.Build;
 import android.os.SystemClock;
-import android.os.UserManager;
 import android.provider.Settings;
-import android.util.Log;
 import android.view.ViewGroup;
 import android.webkit.CookieManager;
 import android.webkit.GeolocationPermissions;
@@ -39,14 +37,18 @@
 import org.chromium.android_webview.WebViewChromiumRunQueue;
 import org.chromium.android_webview.command_line.CommandLineUtil;
 import org.chromium.base.BuildInfo;
+import org.chromium.base.BundleUtils;
 import org.chromium.base.CommandLine;
 import org.chromium.base.ContextUtils;
+import org.chromium.base.Log;
 import org.chromium.base.PackageUtils;
 import org.chromium.base.PathUtils;
 import org.chromium.base.StrictModeContext;
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.annotations.DoNotInline;
 import org.chromium.base.library_loader.NativeLibraries;
 import org.chromium.base.metrics.CachedMetrics.TimesHistogramSample;
+import org.chromium.base.process_launcher.ChildProcessService;
 import org.chromium.components.autofill.AutofillProvider;
 import org.chromium.content_public.browser.LGEmailActionModeWorkaround;
 
@@ -62,7 +64,7 @@
  */
 @SuppressWarnings("deprecation")
 public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
-    private static final String TAG = "WebViewChromiumFactoryProvider";
+    private static final String TAG = "WVCFactoryProvider";
 
     private static final String CHROMIUM_PREFS_NAME = "WebViewChromiumPrefs";
     private static final String VERSION_CODE_PREF = "lastVersionCodeUsed";
@@ -70,6 +72,26 @@
     private static final String SUPPORT_LIB_GLUE_AND_BOUNDARY_INTERFACE_PREFIX =
             "org.chromium.support_lib_";
 
+    /**
+     * This holds objects of classes that are defined in N and above to ensure that run-time class
+     * verification does not occur until it is actually used for N and above.
+     */
+    @TargetApi(Build.VERSION_CODES.N)
+    @DoNotInline
+    private static class ObjectHolderForN {
+        public ServiceWorkerController mServiceWorkerController;
+    }
+
+    /**
+     * This holds objects of classes that are defined in P and above to ensure that run-time class
+     * verification does not occur until it is actually used for P and above.
+     */
+    @TargetApi(Build.VERSION_CODES.P)
+    @DoNotInline
+    private static class ObjectHolderForP {
+        public TracingController mTracingController;
+    }
+
     private final static Object sSingletonLock = new Object();
     private static WebViewChromiumFactoryProvider sSingleton;
 
@@ -103,13 +125,19 @@
 
     private SharedPreferences mWebViewPrefs;
     private WebViewDelegate mWebViewDelegate;
-    private TracingController mTracingController;
 
-    boolean mShouldDisableThreadChecking;
+    private boolean mShouldDisableThreadChecking;
 
     // Initialization guarded by mAwInit.getLock()
     private Statics mStaticsAdapter;
-    private Object mServiceWorkerControllerAdapter;
+
+    @TargetApi(Build.VERSION_CODES.N)
+    private ObjectHolderForN mObjectHolderForN =
+            Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? new ObjectHolderForN() : null;
+
+    @TargetApi(Build.VERSION_CODES.P)
+    private ObjectHolderForP mObjectHolderForP =
+            Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? new ObjectHolderForP() : null;
 
     /**
      * Thread-safe way to set the one and only WebViewChromiumFactoryProvider.
@@ -197,7 +225,6 @@
         }
     }
 
-    @TargetApi(Build.VERSION_CODES.N) // For getSystemService() and isUserUnlocked().
     private void initialize(WebViewDelegate webViewDelegate) {
         long startTime = SystemClock.elapsedRealtime();
         try (ScopedSysTraceEvent e1 =
@@ -214,18 +241,18 @@
 
             mAwInit = createAwInit();
             mWebViewDelegate = webViewDelegate;
-            Context ctx = mWebViewDelegate.getApplication().getApplicationContext();
+            Context ctx = webViewDelegate.getApplication().getApplicationContext();
 
             // If the application context is DE, but we have credentials, use a CE context instead
             try (ScopedSysTraceEvent e2 = ScopedSysTraceEvent.scoped(
                          "WebViewChromiumFactoryProvider.checkStorage")) {
-                checkStorageIsNotDeviceProtected(mWebViewDelegate.getApplication());
+                checkStorageIsNotDeviceProtected(webViewDelegate.getApplication());
             } catch (IllegalArgumentException e) {
                 assert Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
-                if (!ctx.getSystemService(UserManager.class).isUserUnlocked()) {
+                if (!GlueApiHelperForN.isUserUnlocked(ctx)) {
                     throw e;
                 }
-                ctx = ctx.createCredentialProtectedStorageContext();
+                ctx = GlueApiHelperForN.createCredentialProtectedStorageContext(ctx);
             }
 
             // WebView needs to make sure to always use the wrapped application context.
@@ -243,7 +270,7 @@
             boolean multiProcess = false;
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                 // Ask the system if multiprocess should be enabled on O+.
-                multiProcess = mWebViewDelegate.isMultiProcessEnabled();
+                multiProcess = webViewDelegate.isMultiProcessEnabled();
             } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                 // Check the multiprocess developer setting directly on N.
                 multiProcess = Settings.Global.getInt(
@@ -264,7 +291,7 @@
                              "WebViewChromiumFactoryProvider.loadChromiumLibrary")) {
                     String dataDirectorySuffix = null;
                     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
-                        dataDirectorySuffix = mWebViewDelegate.getDataDirectorySuffix();
+                        dataDirectorySuffix = webViewDelegate.getDataDirectorySuffix();
                     }
                     AwBrowserProcess.loadLibrary(dataDirectorySuffix);
                 }
@@ -293,7 +320,8 @@
     }
 
     /* package */ static void checkStorageIsNotDeviceProtected(Context context) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && context.isDeviceProtectedStorage()) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
+                && GlueApiHelperForN.isDeviceProtectedStorage(context)) {
             throw new IllegalArgumentException(
                     "WebView cannot be used with device protected storage");
         }
@@ -337,6 +365,17 @@
     }
 
     public static boolean preloadInZygote() {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
+                && Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
+            // If we're on O, where the split APK handling bug exists, then go through the motions
+            // of applying the workaround - don't actually change anything if Chrome is an APK (as
+            // opposed to an app bundle), but do the reflection to check for compatibility issues.
+            // The result will be logged to UMA later, because we can't do very much in the
+            // restricted environment of the WebView zygote process.
+            ChildProcessService.setSplitApkWorkaroundResult(
+                    SplitApkWorkaround.apply(/* realRun */ BundleUtils.isBundle()));
+        }
+
         for (String library : NativeLibraries.LIBRARIES) {
             System.loadLibrary(library);
         }
@@ -472,12 +511,12 @@
     @Override
     public ServiceWorkerController getServiceWorkerController() {
         synchronized (mAwInit.getLock()) {
-            if (mServiceWorkerControllerAdapter == null) {
-                mServiceWorkerControllerAdapter =
-                        ApiHelperForN.createServiceWorkerControllerAdapter(mAwInit);
+            if (mObjectHolderForN.mServiceWorkerController == null) {
+                mObjectHolderForN.mServiceWorkerController =
+                        GlueApiHelperForN.createServiceWorkerControllerAdapter(mAwInit);
             }
         }
-        return (ServiceWorkerController) mServiceWorkerControllerAdapter;
+        return mObjectHolderForN.mServiceWorkerController;
     }
 
     @Override
@@ -542,13 +581,14 @@
         synchronized (mAwInit.getLock()) {
             mAwInit.ensureChromiumStartedLocked(true);
             // ensureChromiumStartedLocked() can release the lock on first call while
-            // waiting for startup. Hence check the mTracingControler here to ensure
+            // waiting for startup. Hence check the mTracingController here to ensure
             // the singleton property.
-            if (mTracingController == null) {
-                mTracingController = ApiHelperForP.createTracingControllerAdapter(this, mAwInit);
+            if (mObjectHolderForP.mTracingController == null) {
+                mObjectHolderForP.mTracingController =
+                        GlueApiHelperForP.createTracingControllerAdapter(this, mAwInit);
             }
         }
-        return mTracingController;
+        return mObjectHolderForP.mTracingController;
     }
 
     private static class FilteredClassLoader extends ClassLoader {
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java
index 57c3099..f022593 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java
@@ -56,6 +56,8 @@
 import org.chromium.base.Log;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.TraceEvent;
+import org.chromium.base.compat.ApiHelperForM;
+import org.chromium.base.compat.ApiHelperForN;
 import org.chromium.support_lib_boundary.util.Features;
 import org.chromium.support_lib_callback_glue.SupportLibWebViewContentsClientAdapter;
 
@@ -298,7 +300,8 @@
                 result = mSupportLibClient.shouldOverrideUrlLoading(
                         mWebView, new WebResourceRequestAdapter(request));
             } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-                result = ApiHelperForN.shouldOverrideUrlLoading(mWebViewClient, mWebView, request);
+                result = ApiHelperForN.shouldOverrideUrlLoading(
+                        mWebViewClient, mWebView, new WebResourceRequestAdapter(request));
             } else {
                 result = mWebViewClient.shouldOverrideUrlLoading(mWebView, request.url);
             }
@@ -583,7 +586,7 @@
                 mSupportLibClient.onReceivedError(
                         mWebView, new WebResourceRequestAdapter(request), error);
             } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
-                ApiHelperForM.onReceivedError(mWebViewClient, mWebView, request, error);
+                GlueApiHelperForM.onReceivedError(mWebViewClient, mWebView, request, error);
             }
             // Otherwise, this is handled by {@link #onReceivedError}.
         } finally {
@@ -600,8 +603,9 @@
                 mSupportLibClient.onSafeBrowsingHit(
                         mWebView, new WebResourceRequestAdapter(request), threatType, callback);
             } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
-                ApiHelperForOMR1.onSafeBrowsingHit(
+                GlueApiHelperForOMR1.onSafeBrowsingHit(
                         mWebViewClient, mWebView, request, threatType, callback);
+
             } else {
                 callback.onResult(new AwSafeBrowsingResponse(SafeBrowsingAction.SHOW_INTERSTITIAL,
                         /* reporting */ true));
@@ -625,7 +629,7 @@
                                 response.getStatusCode(), response.getReasonPhrase(),
                                 response.getResponseHeaders(), response.getData()));
             } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
-                ApiHelperForM.onReceivedHttpError(mWebViewClient, mWebView, request, response);
+                GlueApiHelperForM.onReceivedHttpError(mWebViewClient, mWebView, request, response);
             }
             // Otherwise, the API does not exist, so do nothing.
         } finally {
@@ -1209,7 +1213,7 @@
 
         try {
             TraceEvent.begin("WebViewContentsClientAdapter.onRenderProcessGone");
-            return ApiHelperForO.onRenderProcessGone(mWebViewClient, mWebView, detail);
+            return GlueApiHelperForO.onRenderProcessGone(mWebViewClient, mWebView, detail);
         } finally {
             TraceEvent.end("WebViewContentsClientAdapter.onRenderProcessGone");
         }
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewDelegateFactory.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewDelegateFactory.java
index 25dcbec..2bec06a 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewDelegateFactory.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewDelegateFactory.java
@@ -156,7 +156,8 @@
         @Override
         public void callDrawGlFunction(
                 Canvas canvas, long nativeDrawGLFunctor, Runnable releasedRunnable) {
-            mDelegate.callDrawGlFunction(canvas, nativeDrawGLFunctor, releasedRunnable);
+            GlueApiHelperForN.callDrawGlFunction(
+                    mDelegate, canvas, nativeDrawGLFunctor, releasedRunnable);
         }
 
         @Override
@@ -205,12 +206,12 @@
 
         @Override
         public boolean isMultiProcessEnabled() {
-            return mDelegate.isMultiProcessEnabled();
+            return GlueApiHelperForO.isMultiProcessEnabled(mDelegate);
         }
 
         @Override
         public String getDataDirectorySuffix() {
-            return mDelegate.getDataDirectorySuffix();
+            return GlueApiHelperForP.getDataDirectorySuffix(mDelegate);
         }
     }
 
diff --git a/android_webview/java/src/org/chromium/android_webview/AwAutofillClient.java b/android_webview/java/src/org/chromium/android_webview/AwAutofillClient.java
index 7f2794a..4012849 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwAutofillClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwAutofillClient.java
@@ -71,7 +71,7 @@
                 return;
             }
         }
-        mAutofillPopup.filterAndShow(suggestions, isRtl);
+        mAutofillPopup.filterAndShow(suggestions, isRtl, false);
     }
 
     @CalledByNative
diff --git a/android_webview/java/src/org/chromium/android_webview/AwAutofillProvider.java b/android_webview/java/src/org/chromium/android_webview/AwAutofillProvider.java
index 347601a..4de88d9 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwAutofillProvider.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwAutofillProvider.java
@@ -17,7 +17,6 @@
 import android.view.ViewStructure;
 import android.view.autofill.AutofillValue;
 
-import org.chromium.base.BuildInfo;
 import org.chromium.base.ThreadUtils;
 import org.chromium.components.autofill.AutofillProvider;
 import org.chromium.components.autofill.FormData;
@@ -87,6 +86,7 @@
                                 .addAttribute("name", field.mName)
                                 .addAttribute("type", field.mType)
                                 .addAttribute("label", field.mLabel)
+                                .addAttribute("ua-autofill-hints", field.mHeuristicType)
                                 .addAttribute("id", field.mId);
 
                 switch (field.getControlType()) {
@@ -296,7 +296,7 @@
         // Check focusField inside short value?
         // Autofill Manager might have session that wasn't started by WebView,
         // we just always cancel existing session here.
-        if (!BuildInfo.isAtLeastP()) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
             mAutofillManager.cancel();
         }
         mAutofillManager.notifyNewSessionStarted();
@@ -337,7 +337,7 @@
     public void onTextFieldDidScroll(int index, float x, float y, float width, float height) {
         // crbug.com/730764 - from P and above, Android framework listens to the onScrollChanged()
         // and repositions the autofill UI automatically.
-        if (BuildInfo.isAtLeastP()) return;
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) return;
         if (mRequest == null) return;
 
         short sIndex = (short) index;
diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
index be40932..ddf7b3f 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
@@ -18,8 +18,6 @@
 import org.chromium.android_webview.policy.AwPolicyProvider;
 import org.chromium.android_webview.services.CrashReceiverService;
 import org.chromium.android_webview.services.ICrashReceiverService;
-import org.chromium.base.AsyncTask;
-import org.chromium.base.BuildInfo;
 import org.chromium.base.CommandLine;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
@@ -30,6 +28,7 @@
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.library_loader.LibraryProcessType;
 import org.chromium.base.library_loader.ProcessInitException;
+import org.chromium.base.task.AsyncTask;
 import org.chromium.components.minidump_uploader.CrashFileManager;
 import org.chromium.content_public.browser.BrowserStartupController;
 import org.chromium.content_public.browser.ChildProcessCreationParams;
@@ -105,7 +104,7 @@
     public static void start() {
         try (ScopedSysTraceEvent e1 = ScopedSysTraceEvent.scoped("AwBrowserProcess.start")) {
             final Context appContext = ContextUtils.getApplicationContext();
-            tryObtainingDataDirLock();
+            tryObtainingDataDirLock(appContext);
             // We must post to the UI thread to cover the case that the user
             // has invoked Chromium startup by using the (thread-safe)
             // CookieManager rather than creating a WebView.
@@ -152,12 +151,13 @@
         }
     }
 
-    private static void tryObtainingDataDirLock() {
+    private static void tryObtainingDataDirLock(final Context appContext) {
         try (ScopedSysTraceEvent e1 =
                         ScopedSysTraceEvent.scoped("AwBrowserProcess.tryObtainingDataDirLock")) {
             // Many existing apps rely on this even though it's known to be unsafe.
             // Make it fatal when on P for apps that target P or higher
-            boolean dieOnFailure = BuildInfo.isAtLeastP() && BuildInfo.targetsAtLeastP();
+            boolean dieOnFailure = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
+                    && appContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P;
 
             StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
             try {
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index 808f8df..d288af8 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -48,7 +48,6 @@
 import org.chromium.android_webview.permission.AwGeolocationCallback;
 import org.chromium.android_webview.permission.AwPermissionRequest;
 import org.chromium.android_webview.renderer_priority.RendererPriority;
-import org.chromium.base.AsyncTask;
 import org.chromium.base.Callback;
 import org.chromium.base.LocaleUtils;
 import org.chromium.base.Log;
@@ -59,7 +58,7 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.blink_public.web.WebReferrerPolicy;
+import org.chromium.base.task.AsyncTask;
 import org.chromium.components.autofill.AutofillProvider;
 import org.chromium.components.navigation_interception.InterceptNavigationDelegate;
 import org.chromium.components.navigation_interception.NavigationParams;
@@ -89,6 +88,7 @@
 import org.chromium.content_public.common.UseZoomForDSFPolicy;
 import org.chromium.device.gamepad.GamepadList;
 import org.chromium.net.NetworkChangeNotifier;
+import org.chromium.network.mojom.ReferrerPolicy;
 import org.chromium.ui.base.ActivityWindowAndroid;
 import org.chromium.ui.base.PageTransition;
 import org.chromium.ui.base.ViewAndroidDelegate;
@@ -616,7 +616,9 @@
             // The shouldOverrideUrlLoading call might have resulted in posting messages to the
             // UI thread. Using sendMessage here (instead of calling onPageStarted directly)
             // will allow those to run in order.
-            mContentsClient.getCallbackHelper().postOnPageStarted(navigationParams.url);
+            if (!navigationParams.isRendererInitiated) {
+                mContentsClient.getCallbackHelper().postOnPageStarted(navigationParams.url);
+            }
             return false;
         }
     }
@@ -1576,6 +1578,10 @@
     public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
         if (TRACE) Log.i(TAG, "%s loadUrl(extra headers)=%s", this, url);
         if (isDestroyedOrNoOperation(WARN)) return;
+        // Early out to match old WebView implementation
+        if (url == null) {
+            return;
+        }
         // TODO: We may actually want to do some sanity checks here (like filter about://chrome).
 
         // For backwards compatibility, apps targeting less than K will have JS URLs evaluated
@@ -1583,19 +1589,18 @@
         // Matching Chrome behavior more closely; apps targetting >= K that load a JS URL will
         // have the result of that URL replace the content of the current page.
         final String javaScriptScheme = "javascript:";
-        if (mAppTargetSdkVersion < Build.VERSION_CODES.KITKAT && url != null
-                && url.startsWith(javaScriptScheme)) {
+        if (mAppTargetSdkVersion < Build.VERSION_CODES.KITKAT && url.startsWith(javaScriptScheme)) {
             evaluateJavaScript(url.substring(javaScriptScheme.length()), null);
             return;
         }
 
-        LoadUrlParams params = new LoadUrlParams(url);
+        LoadUrlParams params = new LoadUrlParams(url, PageTransition.TYPED);
         if (additionalHttpHeaders != null) {
             params.setExtraHeaders(new HashMap<String, String>(additionalHttpHeaders));
         }
 
         final String dataScheme = "data:";
-        if (url != null && url.startsWith(dataScheme) && url.contains("#")) {
+        if (url.startsWith(dataScheme) && url.contains("#")) {
             RecordHistogram.recordBooleanHistogram(DATA_URI_HISTOGRAM_NAME, true);
         }
 
@@ -1741,7 +1746,7 @@
 
         // If we are reloading the same url, then set transition type as reload.
         if (params.getUrl() != null && params.getUrl().equals(mWebContents.getLastCommittedUrl())
-                && params.getTransitionType() == PageTransition.LINK) {
+                && params.getTransitionType() == PageTransition.TYPED) {
             params.setTransitionType(PageTransition.RELOAD);
         }
         params.setTransitionType(
@@ -1761,8 +1766,8 @@
         if (extraHeaders != null) {
             for (String header : extraHeaders.keySet()) {
                 if (referer.equals(header.toLowerCase(Locale.US))) {
-                    params.setReferrer(new Referrer(extraHeaders.remove(header),
-                            WebReferrerPolicy.DEFAULT));
+                    params.setReferrer(
+                            new Referrer(extraHeaders.remove(header), ReferrerPolicy.DEFAULT));
                     params.setExtraHeaders(extraHeaders);
                     break;
                 }
@@ -2244,7 +2249,6 @@
 
         // In order to maintain compatibility with the old WebView's implementation,
         // the absolute (full) url is passed in the |url| field, not only the href attribute.
-        // Note: HitTestData could be cleaned up at this point. See http://crbug.com/290992.
         data.putString("url", mPossiblyStaleHitTestData.href);
         data.putString("title", mPossiblyStaleHitTestData.anchorText);
         data.putString("src", mPossiblyStaleHitTestData.imgSrc);
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsBackgroundThreadClient.java b/android_webview/java/src/org/chromium/android_webview/AwContentsBackgroundThreadClient.java
index aa0307d1..55eec96 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsBackgroundThreadClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsBackgroundThreadClient.java
@@ -7,8 +7,6 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 
-import java.util.HashMap;
-
 /**
  * Delegate for handling callbacks. All methods are called on the background thread.
  * "Background" means something that isn't UI or IO.
@@ -25,16 +23,7 @@
     private AwWebResourceResponse shouldInterceptRequestFromNative(String url, boolean isMainFrame,
             boolean hasUserGesture, String method, String[] requestHeaderNames,
             String[] requestHeaderValues) {
-        AwContentsClient.AwWebResourceRequest request =
-                new AwContentsClient.AwWebResourceRequest();
-        request.url = url;
-        request.isMainFrame = isMainFrame;
-        request.hasUserGesture = hasUserGesture;
-        request.method = method;
-        request.requestHeaders = new HashMap<String, String>(requestHeaderNames.length);
-        for (int i = 0; i < requestHeaderNames.length; ++i) {
-            request.requestHeaders.put(requestHeaderNames[i], requestHeaderValues[i]);
-        }
-        return shouldInterceptRequest(request);
+        return shouldInterceptRequest(new AwContentsClient.AwWebResourceRequest(
+                url, isMainFrame, hasUserGesture, method, requestHeaderNames, requestHeaderValues));
     }
 }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java b/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
index ec44351..022d5fb 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
@@ -15,6 +15,8 @@
 import android.os.Looper;
 import android.os.Message;
 import android.provider.Browser;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.text.TextUtils;
 import android.view.KeyEvent;
 import android.view.View;
@@ -97,6 +99,30 @@
      * Parameters for the {@link AwContentsClient#shouldInterceptRequest} method.
      */
     public static class AwWebResourceRequest {
+        // Prefer using other constructors over this one.
+        public AwWebResourceRequest() {}
+
+        public AwWebResourceRequest(String url, boolean isMainFrame, boolean hasUserGesture,
+                String method, @Nullable HashMap<String, String> requestHeaders) {
+            this.url = url;
+            this.isMainFrame = isMainFrame;
+            this.hasUserGesture = hasUserGesture;
+            // Note: we intentionally let isRedirect default initialize to false. This is because we
+            // don't always know if this request is associated with a redirect or not.
+            this.method = method;
+            this.requestHeaders = requestHeaders;
+        }
+
+        public AwWebResourceRequest(String url, boolean isMainFrame, boolean hasUserGesture,
+                String method, @NonNull String[] requestHeaderNames,
+                @NonNull String[] requestHeaderValues) {
+            this(url, isMainFrame, hasUserGesture, method,
+                    new HashMap<String, String>(requestHeaderValues.length));
+            for (int i = 0; i < requestHeaderNames.length; ++i) {
+                this.requestHeaders.put(requestHeaderNames[i], requestHeaderValues[i]);
+            }
+        }
+
         // Url of the request.
         public String url;
         // Is this for the main frame or a child iframe?
@@ -167,12 +193,10 @@
         if (poller != null && poller.shouldCancelAllCallbacks()) return false;
 
         if (hasWebViewClient()) {
-            AwWebResourceRequest request = new AwWebResourceRequest();
-            request.url = url;
-            request.isMainFrame = isMainFrame;
-            request.hasUserGesture = hasUserGesture;
+            // Note: only GET requests can be overridden, so we hardcode the method.
+            AwWebResourceRequest request =
+                    new AwWebResourceRequest(url, isMainFrame, hasUserGesture, "GET", null);
             request.isRedirect = isRedirect;
-            request.method = "GET";  // Only GET requests can be overridden.
             return shouldOverrideUrlLoading(request);
         } else {
             return sendBrowsingIntent(context, url, hasUserGesture, isRedirect);
@@ -221,12 +245,18 @@
 
         try {
             context.startActivity(intent);
+            return true;
         } catch (ActivityNotFoundException ex) {
             Log.w(TAG, "No application can handle %s", url);
-            return false;
+        } catch (SecurityException ex) {
+            // This can happen if the Activity is exported="true", guarded by a permission, and sets
+            // up an intent filter matching this intent. This is a valid configuration for an
+            // Activity, so instead of crashing, we catch the exception and do nothing. See
+            // https://crbug.com/808494 and https://crbug.com/889300.
+            Log.w(TAG, "SecurityException when starting intent for %s", url);
         }
 
-        return true;
+        return false;
     }
 
     public static Uri[] parseFileChooserResult(int resultCode, Intent intent) {
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java b/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java
index 6e19c61..2c2aef4 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java
@@ -274,19 +274,12 @@
     @CalledByNative
     private void onReceivedError(
             // WebResourceRequest
-            String url, boolean isMainFrame, boolean hasUserGesture, String method,
-            String[] requestHeaderNames, String[] requestHeaderValues,
+            String url, boolean isMainFrame, boolean hasUserGesture, boolean isRendererInitiated,
+            String method, String[] requestHeaderNames, String[] requestHeaderValues,
             // WebResourceError
             int errorCode, String description, boolean safebrowsingHit) {
-        AwContentsClient.AwWebResourceRequest request = new AwContentsClient.AwWebResourceRequest();
-        request.url = url;
-        request.isMainFrame = isMainFrame;
-        request.hasUserGesture = hasUserGesture;
-        request.method = method;
-        request.requestHeaders = new HashMap<String, String>(requestHeaderNames.length);
-        for (int i = 0; i < requestHeaderNames.length; ++i) {
-            request.requestHeaders.put(requestHeaderNames[i], requestHeaderValues[i]);
-        }
+        AwContentsClient.AwWebResourceRequest request = new AwContentsClient.AwWebResourceRequest(
+                url, isMainFrame, hasUserGesture, method, requestHeaderNames, requestHeaderValues);
         AwContentsClient.AwWebResourceError error = new AwContentsClient.AwWebResourceError();
         error.errorCode = errorCode;
         error.description = description;
@@ -308,6 +301,9 @@
             } else {
                 error.errorCode = ErrorCodeConversionHelper.convertErrorCode(error.errorCode);
             }
+            if (request.isMainFrame && isRendererInitiated) {
+                mClient.getCallbackHelper().postOnPageStarted(request.url);
+            }
             mClient.getCallbackHelper().postOnReceivedError(request, error);
             if (request.isMainFrame) {
                 // Need to call onPageFinished after onReceivedError for backwards compatibility
@@ -324,15 +320,8 @@
             String url, boolean isMainFrame, boolean hasUserGesture, String method,
             String[] requestHeaderNames, String[] requestHeaderValues, int threatType,
             final int requestId) {
-        AwContentsClient.AwWebResourceRequest request = new AwContentsClient.AwWebResourceRequest();
-        request.url = url;
-        request.isMainFrame = isMainFrame;
-        request.hasUserGesture = hasUserGesture;
-        request.method = method;
-        request.requestHeaders = new HashMap<String, String>(requestHeaderNames.length);
-        for (int i = 0; i < requestHeaderNames.length; ++i) {
-            request.requestHeaders.put(requestHeaderNames[i], requestHeaderValues[i]);
-        }
+        AwContentsClient.AwWebResourceRequest request = new AwContentsClient.AwWebResourceRequest(
+                url, isMainFrame, hasUserGesture, method, requestHeaderNames, requestHeaderValues);
 
         // TODO(ntfschr): remove clang-format directives once crbug/764582 is resolved
         // clang-format off
@@ -354,15 +343,8 @@
             // WebResourceResponse
             String mimeType, String encoding, int statusCode, String reasonPhrase,
             String[] responseHeaderNames, String[] responseHeaderValues) {
-        AwContentsClient.AwWebResourceRequest request = new AwContentsClient.AwWebResourceRequest();
-        request.url = url;
-        request.isMainFrame = isMainFrame;
-        request.hasUserGesture = hasUserGesture;
-        request.method = method;
-        request.requestHeaders = new HashMap<String, String>(requestHeaderNames.length);
-        for (int i = 0; i < requestHeaderNames.length; ++i) {
-            request.requestHeaders.put(requestHeaderNames[i], requestHeaderValues[i]);
-        }
+        AwContentsClient.AwWebResourceRequest request = new AwContentsClient.AwWebResourceRequest(
+                url, isMainFrame, hasUserGesture, method, requestHeaderNames, requestHeaderValues);
         Map<String, String> responseHeaders =
                 new HashMap<String, String>(responseHeaderNames.length);
         // Note that we receive un-coalesced response header lines, thus we need to combine
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
index 6a12a9c..8237019 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
@@ -120,12 +120,19 @@
         nativeSetCheckClearTextPermitted(permitted);
     }
 
-    public static void setProxyOverride(String host, int port, String[] exclusionList) {
-        nativeSetProxyOverride(host, port, exclusionList);
+    @CalledByNative
+    private static void proxyOverrideChanged(Runnable callback) {
+        if (callback == null) return;
+        callback.run();
     }
 
-    public static void clearProxyOverride() {
-        nativeClearProxyOverride();
+    public static void setProxyOverride(
+            String host, int port, String[] exclusionList, Runnable callback) {
+        nativeSetProxyOverride(host, port, exclusionList, callback);
+    }
+
+    public static void clearProxyOverride(Runnable callback) {
+        nativeClearProxyOverride(callback);
     }
 
     /**
@@ -155,6 +162,6 @@
             String[] urls, Callback<Boolean> callback);
     private static native void nativeSetCheckClearTextPermitted(boolean permitted);
     private static native void nativeSetProxyOverride(
-            String host, int port, String[] exclusionList);
-    private static native void nativeClearProxyOverride();
+            String host, int port, String[] exclusionList, Runnable callback);
+    private static native void nativeClearProxyOverride(Runnable callback);
 }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwFeatureList.java b/android_webview/java/src/org/chromium/android_webview/AwFeatureList.java
new file mode 100644
index 0000000..6bbfe0c
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/AwFeatureList.java
@@ -0,0 +1,37 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.android_webview;
+
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.MainDex;
+
+/**
+ * Java accessor for base/feature_list.h state.
+ */
+@JNINamespace("android_webview")
+@MainDex
+final public class AwFeatureList {
+    // Do not instantiate this class.
+    private AwFeatureList() {}
+
+    /**
+     * Returns whether the specified feature is enabled or not.
+     *
+     * Note: Features queried through this API must be added to the array
+     * |kFeaturesExposedToJava| in android_webview/browser/aw_feature_list.cc
+     *
+     * @param featureName The name of the feature to query.
+     * @return Whether the feature is enabled or not.
+     */
+    public static boolean isEnabled(String featureName) {
+        return nativeIsEnabled(featureName);
+    }
+
+    // Alphabetical:
+    public static final String WEBVIEW_CONNECTIONLESS_SAFE_BROWSING =
+            "WebViewConnectionlessSafeBrowsing";
+
+    private static native boolean nativeIsEnabled(String featureName);
+}
diff --git a/android_webview/java/src/org/chromium/android_webview/AwMetricsServiceClient.java b/android_webview/java/src/org/chromium/android_webview/AwMetricsServiceClient.java
index 0e168e2..9dc76aa 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwMetricsServiceClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwMetricsServiceClient.java
@@ -9,15 +9,10 @@
 import android.content.pm.PackageManager;
 
 import org.chromium.base.Log;
-import org.chromium.base.PathUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
 /**
  * Determines user consent and app opt-out for metrics.
  *
@@ -31,11 +26,6 @@
  * This happens in parallel with native AwMetricsServiceClient initialization; either
  * nativeInitialized or setConsentSetting might fire first. Whichever fires second should call
  * nativeSetHaveMetricsConsent.
- *
- * Also, pre-loads the client ID for variations. Variations setup begins before native init (so it
- * can't use the native code to load the client ID), reading the client ID and other variations
- * files in the background. Completion of this task blocks WebView startup, so we want to do minimal
- * work; unlike the native loader, this loader does not create a new client ID when none is found.
  */
 @JNINamespace("android_webview")
 public class AwMetricsServiceClient {
@@ -53,55 +43,6 @@
     private static final int GUID_SIZE = 32 + 4;
     private static final String GUID_FILE_NAME = "metrics_guid";
 
-    private static byte[] sClientId;
-    private static Object sClientIdLock = new Object();
-
-    private static byte[] readFixedLengthFile(File file, int length) throws IOException {
-        if (file.length() != length) {
-            throw new IOException("File is not of expected length " + length);
-        }
-        FileInputStream in = null;
-        try {
-            in = new FileInputStream(file);
-            byte[] buf = new byte[length];
-            int read = 0;
-            int offset = 0;
-            while (offset < length) {
-                read = in.read(buf, offset, length - offset);
-                if (read < 1) throw new IOException("Premature EOF");
-                offset += read;
-            }
-            return buf;
-        } finally {
-            if (in != null) in.close();
-        }
-    }
-
-    /**
-     * Load the metrics client ID, if any.
-     */
-    public static void preloadClientId() {
-        File clientIdFile = new File(PathUtils.getDataDirectory(), GUID_FILE_NAME);
-        if (!clientIdFile.exists() || clientIdFile.length() != GUID_SIZE) return;
-        byte[] clientId = null;
-        try {
-            clientId = readFixedLengthFile(clientIdFile, GUID_SIZE);
-        } catch (IOException e) {
-            Log.e(TAG, "Failed to pre-load GUID file " + clientIdFile + " - " + e.getMessage());
-            return;
-        }
-        synchronized (sClientIdLock) {
-            sClientId = clientId;
-        }
-    }
-
-    @CalledByNative
-    public static byte[] getPreloadedClientId() {
-        synchronized (sClientIdLock) {
-            return sClientId;
-        }
-    }
-
     private static boolean isAppOptedOut(Context appContext) {
         try {
             ApplicationInfo info = appContext.getPackageManager().getApplicationInfo(
diff --git a/android_webview/java/src/org/chromium/android_webview/AwRenderProcess.java b/android_webview/java/src/org/chromium/android_webview/AwRenderProcess.java
index 68bbddb..3290a54 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwRenderProcess.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwRenderProcess.java
@@ -10,7 +10,7 @@
 /**
  */
 @JNINamespace("android_webview")
-public final class AwRenderProcess {
+public final class AwRenderProcess extends AwSupportLibIsomorphic {
     private long mNativeRenderProcess;
 
     private AwRenderProcess() {}
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConversionHelper.java b/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConversionHelper.java
index 3d6494d..d0ba8fc 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConversionHelper.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConversionHelper.java
@@ -13,18 +13,23 @@
  * constants in WebViewClient.
  */
 public final class AwSafeBrowsingConversionHelper {
-    /** The resource was blocked for an unknown reason */
+    /** The resource was blocked for an unknown reason. */
     public static final int SAFE_BROWSING_THREAT_UNKNOWN =
             WebViewClient.SAFE_BROWSING_THREAT_UNKNOWN;
-    /** The resource was blocked because it contains malware */
+    /** The resource was blocked because it contains malware. */
     public static final int SAFE_BROWSING_THREAT_MALWARE =
             WebViewClient.SAFE_BROWSING_THREAT_MALWARE;
-    /** The resource was blocked because it contains deceptive content */
+    /** The resource was blocked because it contains deceptive content. */
     public static final int SAFE_BROWSING_THREAT_PHISHING =
             WebViewClient.SAFE_BROWSING_THREAT_PHISHING;
-    /** The resource was blocked because it contains unwanted software */
+    /** The resource was blocked because it contains unwanted software. */
     public static final int SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE =
             WebViewClient.SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE;
+    /** The resource was blocked because it may trick the user into a billing agreement. */
+    // TODO(ntfschr): add a new int to the SDK.
+    public static final int SAFE_BROWSING_THREAT_BILLING =
+            WebViewClient.SAFE_BROWSING_THREAT_UNKNOWN;
+
     /**
      * Converts the threat type value from SafeBrowsing code to the WebViewClient constant.
      */
@@ -36,6 +41,8 @@
                 return SAFE_BROWSING_THREAT_PHISHING;
             case SBThreatType.URL_UNWANTED:
                 return SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE;
+            case SBThreatType.BILLING:
+                return SAFE_BROWSING_THREAT_BILLING;
             default:
                 return SAFE_BROWSING_THREAT_UNKNOWN;
         }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSettings.java b/android_webview/java/src/org/chromium/android_webview/AwSettings.java
index dce5551..d5fbe20 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwSettings.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwSettings.java
@@ -15,7 +15,7 @@
 import android.util.Log;
 import android.webkit.WebSettings;
 
-import org.chromium.base.BuildInfo;
+import org.chromium.base.ContextUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.annotations.CalledByNative;
@@ -101,8 +101,8 @@
     private boolean mSpatialNavigationEnabled;  // Default depends on device features.
     private boolean mEnableSupportedHardwareAcceleratedFeatures;
     private int mMixedContentMode = WebSettings.MIXED_CONTENT_NEVER_ALLOW;
-    private boolean mCSSHexAlphaColorEnabled = false;
-    private boolean mScrollTopLeftInteropEnabled = false;
+    private boolean mCSSHexAlphaColorEnabled;
+    private boolean mScrollTopLeftInteropEnabled;
 
     private boolean mOffscreenPreRaster;
     private int mDisabledMenuItems = WebSettings.MENU_ITEM_NONE;
@@ -599,7 +599,8 @@
     @CalledByNative
     private static boolean getAllowSniffingFileUrls() {
         // Don't allow sniffing file:// URLs for MIME type if the application targets P or later.
-        return !BuildInfo.targetsAtLeastP();
+        return ContextUtils.getApplicationContext().getApplicationInfo().targetSdkVersion
+                < Build.VERSION_CODES.P;
     }
 
     /**
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSupportLibIsomorphic.java b/android_webview/java/src/org/chromium/android_webview/AwSupportLibIsomorphic.java
new file mode 100644
index 0000000..c32c895
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/AwSupportLibIsomorphic.java
@@ -0,0 +1,23 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.android_webview;
+
+/**
+ * Abstract base class for objects that are expected to be isomorphic
+ * (i.e. have a lazy 1:1 mapping for its entire lifetime) with a support
+ * library object.
+ */
+public abstract class AwSupportLibIsomorphic {
+    private Object mSupportLibObject;
+
+    public Object getSupportLibObject() {
+        return mSupportLibObject;
+    }
+
+    public void setSupportLibObject(Object supportLibObject) {
+        assert mSupportLibObject == null;
+        mSupportLibObject = supportLibObject;
+    }
+}
diff --git a/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java b/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java
index bacce83..ad829f6 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwWebContentsDelegateAdapter.java
@@ -18,10 +18,10 @@
 import android.webkit.URLUtil;
 import android.widget.FrameLayout;
 
-import org.chromium.base.AsyncTask;
 import org.chromium.base.Callback;
 import org.chromium.base.ContentUriUtils;
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.task.AsyncTask;
 import org.chromium.content_public.browser.InvalidateTypes;
 import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.content_public.common.ResourceRequestBody;
diff --git a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
index 56fdde8..0e0200a 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
@@ -91,8 +91,9 @@
     @Override
     public void didFinishNavigation(final String url, boolean isInMainFrame, boolean isErrorPage,
             boolean hasCommitted, boolean isSameDocument, boolean isFragmentNavigation,
-            Integer pageTransition, int errorCode, String errorDescription, int httpStatusCode) {
-        if (errorCode != 0) {
+            boolean isRendererInitiated, boolean isDownload, Integer pageTransition, int errorCode,
+            String errorDescription, int httpStatusCode) {
+        if (errorCode != 0 && !isDownload) {
             didFailLoad(isInMainFrame, errorCode, errorDescription, url);
         }
 
@@ -103,7 +104,13 @@
         if (!isInMainFrame) return;
 
         AwContentsClient client = mAwContentsClient.get();
-        if (hasCommitted && client != null) {
+        if (client != null) {
+            // OnPageStarted is not called for fragment navigations.
+            // Error page is handled by AwContentsClientBridge.onReceivedError.
+            if (!isFragmentNavigation && !isErrorPage && isRendererInitiated) {
+                client.getCallbackHelper().postOnPageStarted(url);
+            }
+
             boolean isReload = pageTransition != null
                     && ((pageTransition & PageTransition.CORE_MASK) == PageTransition.RELOAD);
             client.getCallbackHelper().postDoUpdateVisitedHistory(url, isReload);
@@ -129,6 +136,7 @@
         }
 
         if (client != null && isFragmentNavigation) {
+            // Note fragment navigations do not have a matching onPageStarted.
             client.getCallbackHelper().postOnPageFinished(url);
         }
     }
diff --git a/android_webview/java/src/org/chromium/android_webview/DefaultVideoPosterRequestHandler.java b/android_webview/java/src/org/chromium/android_webview/DefaultVideoPosterRequestHandler.java
index b541494..2400c5d 100644
--- a/android_webview/java/src/org/chromium/android_webview/DefaultVideoPosterRequestHandler.java
+++ b/android_webview/java/src/org/chromium/android_webview/DefaultVideoPosterRequestHandler.java
@@ -7,8 +7,8 @@
 import android.graphics.Bitmap;
 import android.util.Log;
 
-import org.chromium.base.AsyncTask;
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.task.AsyncTask;
 
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/android_webview/java/src/org/chromium/android_webview/PlatformServiceBridge.java b/android_webview/java/src/org/chromium/android_webview/PlatformServiceBridge.java
index 91109cb..643df2a 100644
--- a/android_webview/java/src/org/chromium/android_webview/PlatformServiceBridge.java
+++ b/android_webview/java/src/org/chromium/android_webview/PlatformServiceBridge.java
@@ -5,6 +5,8 @@
 package org.chromium.android_webview;
 
 import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.support.annotation.NonNull;
 
 import org.chromium.base.Callback;
@@ -16,12 +18,14 @@
  */
 public abstract class PlatformServiceBridge {
     private static final String TAG = "PlatformServiceBrid-";
-    private static final String PLATFORM_SERVICE_BRIDGE =
-            "com.android.webview.chromium.PlatformServiceBridgeGoogle";
 
     private static PlatformServiceBridge sInstance;
     private static final Object sInstanceLock = new Object();
 
+    private static HandlerThread sHandlerThread;
+    private static Handler sHandler;
+    private static final Object sHandlerLock = new Object();
+
     protected PlatformServiceBridge() {}
 
     @SuppressWarnings("unused")
@@ -46,6 +50,18 @@
         }
     }
 
+    // Return a handler appropriate for executing blocking Platform Service tasks.
+    public static Handler getHandler() {
+        synchronized (sHandlerLock) {
+            if (sHandler == null) {
+                sHandlerThread = new HandlerThread("PlatformServiceBridgeHandlerThread");
+                sHandlerThread.start();
+                sHandler = new Handler(sHandlerThread.getLooper());
+            }
+        }
+        return sHandler;
+    }
+
     // Can WebView use Google Play Services (a.k.a. GMS)?
     public boolean canUseGms() {
         return false;
diff --git a/android_webview/java/src/org/chromium/android_webview/VariationsSeedLoader.java b/android_webview/java/src/org/chromium/android_webview/VariationsSeedLoader.java
index 9fbd9e4..ca62674 100644
--- a/android_webview/java/src/org/chromium/android_webview/VariationsSeedLoader.java
+++ b/android_webview/java/src/org/chromium/android_webview/VariationsSeedLoader.java
@@ -105,8 +105,6 @@
         private long mCurrentSeedDate = Long.MIN_VALUE;
 
         private FutureTask<SeedInfo> mLoadTask = new FutureTask<>(() -> {
-            AwMetricsServiceClient.preloadClientId();
-
             File newSeedFile = VariationsUtils.getNewSeedFile();
             File oldSeedFile = VariationsUtils.getSeedFile();
 
diff --git a/android_webview/java/src/org/chromium/android_webview/services/AwMinidumpUploaderDelegate.java b/android_webview/java/src/org/chromium/android_webview/services/AwMinidumpUploaderDelegate.java
index 89d0566..64e8fcb 100644
--- a/android_webview/java/src/org/chromium/android_webview/services/AwMinidumpUploaderDelegate.java
+++ b/android_webview/java/src/org/chromium/android_webview/services/AwMinidumpUploaderDelegate.java
@@ -25,7 +25,7 @@
 public class AwMinidumpUploaderDelegate implements MinidumpUploaderDelegate {
     private final ConnectivityManager mConnectivityManager;
 
-    private boolean mPermittedByUser = false;
+    private boolean mPermittedByUser;
 
     @VisibleForTesting
     public AwMinidumpUploaderDelegate() {
diff --git a/android_webview/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java b/android_webview/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java
index c727d7f..c34f025 100644
--- a/android_webview/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java
+++ b/android_webview/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java
@@ -4,7 +4,6 @@
 
 package org.chromium.android_webview.services;
 
-import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.app.job.JobInfo;
 import android.app.job.JobParameters;
@@ -15,9 +14,10 @@
 import android.os.Build;
 
 import org.chromium.android_webview.VariationsUtils;
-import org.chromium.base.AsyncTask;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
+import org.chromium.base.compat.ApiHelperForN;
+import org.chromium.base.task.AsyncTask;
 import org.chromium.components.background_task_scheduler.TaskIds;
 import org.chromium.components.variations.firstrun.VariationsSeedFetcher;
 import org.chromium.components.variations.firstrun.VariationsSeedFetcher.SeedInfo;
@@ -63,7 +63,6 @@
 
     // Use JobScheduler.getPendingJob() if it's available. Otherwise, fall back to iterating over
     // all jobs to find the one we want.
-    @SuppressLint("NewApi")
     private static JobInfo getPendingJob(JobScheduler scheduler, int jobId) {
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
             for (JobInfo info : scheduler.getAllPendingJobs()) {
@@ -71,8 +70,7 @@
             }
             return null;
         }
-
-        return scheduler.getPendingJob(jobId);
+        return ApiHelperForN.getPendingJob(scheduler, jobId);
     }
 
     private static JobScheduler getScheduler() {
diff --git a/android_webview/java/src/org/chromium/android_webview/services/CrashReceiverService.java b/android_webview/java/src/org/chromium/android_webview/services/CrashReceiverService.java
index 4e62b4f..43e6af9 100644
--- a/android_webview/java/src/org/chromium/android_webview/services/CrashReceiverService.java
+++ b/android_webview/java/src/org/chromium/android_webview/services/CrashReceiverService.java
@@ -32,7 +32,7 @@
     private static final String WEBVIEW_TMP_CRASH_DIR = "WebView_Crashes_Tmp";
 
     private final Object mCopyingLock = new Object();
-    private boolean mIsCopying = false;
+    private boolean mIsCopying;
 
     @Override
     public void onCreate() {
diff --git a/android_webview/java/strings/android_webview_strings.grd b/android_webview/java/strings/android_webview_strings.grd
index ab91168..3dd5770 100644
--- a/android_webview/java/strings/android_webview_strings.grd
+++ b/android_webview/java/strings/android_webview_strings.grd
@@ -50,6 +50,7 @@
     <file lang="am" path="translations/android_webview_strings_am.xtb" />
     <file lang="ar" path="translations/android_webview_strings_ar.xtb" />
     <file lang="bg" path="translations/android_webview_strings_bg.xtb" />
+    <file lang="bn" path="translations/android_webview_strings_bn.xtb" />
     <file lang="ca" path="translations/android_webview_strings_ca.xtb" />
     <file lang="cs" path="translations/android_webview_strings_cs.xtb" />
     <file lang="da" path="translations/android_webview_strings_da.xtb" />
@@ -58,10 +59,12 @@
     <file lang="en-GB" path="translations/android_webview_strings_en-GB.xtb" />
     <file lang="es" path="translations/android_webview_strings_es.xtb" />
     <file lang="es-419" path="translations/android_webview_strings_es-419.xtb" />
+    <file lang="et" path="translations/android_webview_strings_et.xtb" />
     <file lang="fa" path="translations/android_webview_strings_fa.xtb" />
     <file lang="fi" path="translations/android_webview_strings_fi.xtb" />
     <file lang="fil" path="translations/android_webview_strings_fil.xtb" />
     <file lang="fr" path="translations/android_webview_strings_fr.xtb" />
+    <file lang="gu" path="translations/android_webview_strings_gu.xtb" />
     <file lang="hi" path="translations/android_webview_strings_hi.xtb" />
     <file lang="hr" path="translations/android_webview_strings_hr.xtb" />
     <file lang="hu" path="translations/android_webview_strings_hu.xtb" />
@@ -70,8 +73,12 @@
     <file lang="iw" path="translations/android_webview_strings_iw.xtb" />
     <file lang="ja" path="translations/android_webview_strings_ja.xtb" />
     <file lang="ko" path="translations/android_webview_strings_ko.xtb" />
+    <file lang="kn" path="translations/android_webview_strings_kn.xtb" />
     <file lang="lt" path="translations/android_webview_strings_lt.xtb" />
     <file lang="lv" path="translations/android_webview_strings_lv.xtb" />
+    <file lang="ml" path="translations/android_webview_strings_ml.xtb" />
+    <file lang="mr" path="translations/android_webview_strings_mr.xtb" />
+    <file lang="ms" path="translations/android_webview_strings_ms.xtb" />
     <file lang="nl" path="translations/android_webview_strings_nl.xtb" />
     <file lang="no" path="translations/android_webview_strings_no.xtb" />
     <file lang="pl" path="translations/android_webview_strings_pl.xtb" />
@@ -84,6 +91,8 @@
     <file lang="sr" path="translations/android_webview_strings_sr.xtb" />
     <file lang="sv" path="translations/android_webview_strings_sv.xtb" />
     <file lang="sw" path="translations/android_webview_strings_sw.xtb" />
+    <file lang="ta" path="translations/android_webview_strings_ta.xtb" />
+    <file lang="te" path="translations/android_webview_strings_te.xtb" />
     <file lang="th" path="translations/android_webview_strings_th.xtb" />
     <file lang="tr" path="translations/android_webview_strings_tr.xtb" />
     <file lang="uk" path="translations/android_webview_strings_uk.xtb" />
diff --git a/android_webview/java/strings/translations/android_webview_strings_bn.xtb b/android_webview/java/strings/translations/android_webview_strings_bn.xtb
new file mode 100644
index 0000000..257ac9a
--- /dev/null
+++ b/android_webview/java/strings/translations/android_webview_strings_bn.xtb
@@ -0,0 +1,6 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="bn">
+<translation id="3572484393913897457">সিস্টেম ওয়েবভিউ লাইসেন্সগুলি</translation>
+<translation id="8916631167640856213">এই সংস্করণের Android এ এই কার্যকারিতাটি সমর্থিত নয়৷</translation>
+</translationbundle>
\ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_et.xtb b/android_webview/java/strings/translations/android_webview_strings_et.xtb
new file mode 100644
index 0000000..07ed57c
--- /dev/null
+++ b/android_webview/java/strings/translations/android_webview_strings_et.xtb
@@ -0,0 +1,6 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="et">
+<translation id="3572484393913897457">Süsteemi WebView-litsentsid</translation>
+<translation id="8916631167640856213">Seda funktsiooni Androidi selles versioonis ei toetata.</translation>
+</translationbundle>
\ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_gu.xtb b/android_webview/java/strings/translations/android_webview_strings_gu.xtb
new file mode 100644
index 0000000..001c0f4
--- /dev/null
+++ b/android_webview/java/strings/translations/android_webview_strings_gu.xtb
@@ -0,0 +1,6 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="gu">
+<translation id="3572484393913897457">સિસ્ટમ WebView લાઇસન્સ</translation>
+<translation id="8916631167640856213">આ કાર્ય Androidના આ વર્ઝનમાં સપોર્ટ નથી કરતું.</translation>
+</translationbundle>
\ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_kn.xtb b/android_webview/java/strings/translations/android_webview_strings_kn.xtb
new file mode 100644
index 0000000..4526805
--- /dev/null
+++ b/android_webview/java/strings/translations/android_webview_strings_kn.xtb
@@ -0,0 +1,6 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="kn">
+<translation id="3572484393913897457">ಸಿಸ್ಟಂ ವೆಬ್‌ವೀಕ್ಷಣೆ ಪರವಾನಗಿಗಳು</translation>
+<translation id="8916631167640856213">ಈ ಕಾರ್ಯವನ್ನು Android ನ ಈ ಆವೃತ್ತಿಯಲ್ಲಿ ಬೆಂಬಲಿಸಲಾಗುವುದಿಲ್ಲ.</translation>
+</translationbundle>
\ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_ml.xtb b/android_webview/java/strings/translations/android_webview_strings_ml.xtb
new file mode 100644
index 0000000..464b6cd
--- /dev/null
+++ b/android_webview/java/strings/translations/android_webview_strings_ml.xtb
@@ -0,0 +1,6 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ml">
+<translation id="3572484393913897457">സിസ്‌റ്റം വെബ്‌വ്യൂ ലൈസൻസുകൾ</translation>
+<translation id="8916631167640856213">ഈ പ്രവർത്തനത്തെ Android-ന്റെ ഈ പതിപ്പ് പിന്തുണയ്‌ക്കുന്നില്ല.</translation>
+</translationbundle>
\ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_mr.xtb b/android_webview/java/strings/translations/android_webview_strings_mr.xtb
new file mode 100644
index 0000000..28fa9a0
--- /dev/null
+++ b/android_webview/java/strings/translations/android_webview_strings_mr.xtb
@@ -0,0 +1,6 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="mr">
+<translation id="3572484393913897457">सिस्टम WebView परवाने</translation>
+<translation id="8916631167640856213">Android च्या या आवृत्तीमध्‍ये ही कार्यक्षमता समर्थित नाही.</translation>
+</translationbundle>
\ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_ms.xtb b/android_webview/java/strings/translations/android_webview_strings_ms.xtb
new file mode 100644
index 0000000..e9a6ce3
--- /dev/null
+++ b/android_webview/java/strings/translations/android_webview_strings_ms.xtb
@@ -0,0 +1,6 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ms">
+<translation id="3572484393913897457">Lesen WebView Sistem</translation>
+<translation id="8916631167640856213">Kefungsian ini tidak disokong dalam versi Android ini.</translation>
+</translationbundle>
\ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_ta.xtb b/android_webview/java/strings/translations/android_webview_strings_ta.xtb
new file mode 100644
index 0000000..c852c5c
--- /dev/null
+++ b/android_webview/java/strings/translations/android_webview_strings_ta.xtb
@@ -0,0 +1,6 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ta">
+<translation id="3572484393913897457">System WebView உரிமங்கள்</translation>
+<translation id="8916631167640856213">Android இன் இந்தப் பதிப்பில், இந்தச் செயல்பாடு ஆதரிக்கப்படாது.</translation>
+</translationbundle>
\ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_te.xtb b/android_webview/java/strings/translations/android_webview_strings_te.xtb
new file mode 100644
index 0000000..bbb7c8f
--- /dev/null
+++ b/android_webview/java/strings/translations/android_webview_strings_te.xtb
@@ -0,0 +1,6 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="te">
+<translation id="3572484393913897457">సిస్టమ్ వెబ్ వీక్షణ లైసెన్స్‌లు</translation>
+<translation id="8916631167640856213">ఈ Android సంస్కరణలో ఈ కార్యాచరణకు మద్దతు లేదు.</translation>
+</translationbundle>
\ No newline at end of file
diff --git a/android_webview/javatests/AndroidManifest.xml b/android_webview/javatests/AndroidManifest.xml
index b4f2aa0..5838eae 100644
--- a/android_webview/javatests/AndroidManifest.xml
+++ b/android_webview/javatests/AndroidManifest.xml
@@ -7,8 +7,7 @@
     <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="23" />
     <instrumentation android:name="org.chromium.base.test.BaseChromiumAndroidJUnitRunner"
         android:targetPackage="org.chromium.android_webview.shell"
-        android:label="Tests for org.chromium.android_webview"
-        chromium-junit4="true"/>
+        android:label="Tests for org.chromium.android_webview"/>
     <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />
     <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
     <uses-permission android:name="android.permission.READ_LOGS"/>
diff --git a/android_webview/javatests/PRESUBMIT.py b/android_webview/javatests/PRESUBMIT.py
new file mode 100644
index 0000000..67a1c4b
--- /dev/null
+++ b/android_webview/javatests/PRESUBMIT.py
@@ -0,0 +1,122 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""Presubmit tests for android_webview/javatests/
+
+Runs various style checks before upload.
+"""
+
+def CheckChangeOnUpload(input_api, output_api):
+  results = []
+  results.extend(_CheckAwJUnitTestRunner(input_api, output_api))
+  results.extend(_CheckNoSkipCommandLineAnnotation(input_api, output_api))
+  results.extend(_CheckNoSandboxedRendererSwitch(input_api, output_api))
+  return results
+
+
+def _CheckAwJUnitTestRunner(input_api, output_api):
+  """Checks that new tests use the AwJUnit4ClassRunner instead of some other
+  test runner. This is because WebView has special logic in the
+  AwJUnit4ClassRunner.
+  """
+
+  run_with_pattern = input_api.re.compile(
+      r'^@RunWith\((.*)\)$')
+  correct_runner = 'AwJUnit4ClassRunner.class'
+
+  errors = []
+
+  def _FilterFile(affected_file):
+    return input_api.FilterSourceFile(
+        affected_file,
+        black_list=input_api.DEFAULT_BLACK_LIST,
+        white_list=[r'.*\.java$'])
+
+  for f in input_api.AffectedSourceFiles(_FilterFile):
+    for line_num, line in f.ChangedContents():
+      match = run_with_pattern.search(line)
+      if match and match.group(1) != correct_runner:
+        errors.append("%s:%d" % (f.LocalPath(), line_num))
+
+  results = []
+
+  if errors:
+    results.append(output_api.PresubmitPromptWarning("""
+android_webview/javatests/ should use the AwJUnit4ClassRunner test runner, not
+any other test runner (e.g., BaseJUnit4ClassRunner).
+""", errors))
+
+  return results
+
+
+def _CheckNoSkipCommandLineAnnotation(input_api, output_api):
+  """Checks that tests do not add @SkipCommandLineParameterization annotation.
+  This was previously used to run the test in single-process-mode only (or,
+  multi-process-mode only if used with
+  @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER)). This is
+  obsolete because we have dedicated annotations (@OnlyRunInSingleProcessMode
+  and @OnlyRunInMultiProcessMode).
+  """
+
+  skip_command_line_annotation = input_api.re.compile(
+      r'^\s*@SkipCommandLineParameterization.*$')
+
+  errors = []
+
+  def _FilterFile(affected_file):
+    return input_api.FilterSourceFile(
+        affected_file,
+        black_list=input_api.DEFAULT_BLACK_LIST,
+        white_list=[r'.*\.java$'])
+
+  for f in input_api.AffectedSourceFiles(_FilterFile):
+    for line_num, line in f.ChangedContents():
+      match = skip_command_line_annotation.search(line)
+      if match:
+        errors.append("%s:%d" % (f.LocalPath(), line_num))
+
+  results = []
+
+  if errors:
+    results.append(output_api.PresubmitPromptWarning("""
+android_webview/javatests/ should not use @SkipCommandLineParameterization to
+run in either multi-process or single-process only. Instead, use @OnlyRunIn.
+""", errors))
+
+  return results
+
+
+def _CheckNoSandboxedRendererSwitch(input_api, output_api):
+  """Checks that tests do not add the AwSwitches.WEBVIEW_SANDBOXED_RENDERER
+  command line flag. Tests should instead use @OnlyRunIn(MULTI_PROCESS).
+  """
+
+  # This will not catch multi-line annotations (which are valid if adding
+  # multiple switches), but is better than nothing (and avoids false positives).
+  sandboxed_renderer_pattern = input_api.re.compile(
+      r'^\s*@CommandLineFlags\.Add\(.*'
+      r'\bAwSwitches\.WEBVIEW_SANDBOXED_RENDERER\b.*\)$')
+
+  errors = []
+
+  def _FilterFile(affected_file):
+    return input_api.FilterSourceFile(
+        affected_file,
+        black_list=input_api.DEFAULT_BLACK_LIST,
+        white_list=[r'.*\.java$'])
+
+  for f in input_api.AffectedSourceFiles(_FilterFile):
+    for line_num, line in f.ChangedContents():
+      match = sandboxed_renderer_pattern.search(line)
+      if match:
+        errors.append("%s:%d" % (f.LocalPath(), line_num))
+
+  results = []
+
+  if errors:
+    results.append(output_api.PresubmitPromptWarning("""
+android_webview/javatests/ should not use AwSwitches.WEBVIEW_SANDBOXED_RENDERER
+to run in multi-process only. Instead, use @OnlyRunIn(MULTI_PROCESS).
+""", errors))
+
+  return results
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AcceptLanguageTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AcceptLanguageTest.java
index e880d53..8f2f0eba8 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AcceptLanguageTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AcceptLanguageTest.java
@@ -9,7 +9,6 @@
 import android.os.LocaleList;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
-import android.text.TextUtils;
 
 import org.junit.After;
 import org.junit.Assert;
@@ -20,12 +19,10 @@
 
 import org.chromium.android_webview.AwContents;
 import org.chromium.android_webview.test.util.JSUtils;
-import org.chromium.base.LocaleUtils;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.net.test.EmbeddedTestServer;
 
-import java.util.Arrays;
 import java.util.Locale;
 import java.util.regex.Pattern;
 
@@ -80,6 +77,10 @@
         return COMMA_AND_OPTIONAL_Q_VALUE.split(mActivityTestRule.maybeStripDoubleQuotes(raw));
     }
 
+    private boolean isEnUsLocale() {
+        return "en-US".equals(Locale.getDefault().toLanguageTag());
+    }
+
     /**
      * Verify that the Accept Language string is correct.
      */
@@ -87,6 +88,14 @@
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testAcceptLanguage() throws Throwable {
+        // Make sure that the current locale is en-US.
+        if (!isEnUsLocale()) {
+            Locale.setDefault(new Locale("en", "US"));
+            AwContents.updateDefaultLocale();
+            mAwContents.getSettings().updateAcceptLanguages();
+        }
+        Assert.assertTrue(isEnUsLocale());
+
         mActivityTestRule.getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
 
         // This should yield a lightly formatted page with the contents of the Accept-Language
@@ -94,18 +103,18 @@
         String url = mTestServer.getURL("/echoheader?Accept-Language");
         mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
 
+        // Note that we extend the base language from language-region pair.
         String[] acceptLanguages = getAcceptLanguages(
                 mActivityTestRule.getJavaScriptResultBodyTextContent(mAwContents, mContentsClient));
-        Assert.assertEquals(LocaleUtils.getDefaultLocaleString(), acceptLanguages[0]);
+        Assert.assertArrayEquals(new String[] {"en-US", "en"}, acceptLanguages);
 
+        // Our accept language list in user agent is different from navigator.languages, which is
+        // fine.
         String[] acceptLanguagesJs = getAcceptLanguages(JSUtils.executeJavaScriptAndWaitForResult(
                 InstrumentationRegistry.getInstrumentation(), mAwContents,
                 mContentsClient.getOnEvaluateJavaScriptResultHelper(),
                 "navigator.languages.join(',')"));
-        Assert.assertEquals(acceptLanguagesJs.length, acceptLanguages.length);
-        for (int i = 0; i < acceptLanguagesJs.length; ++i) {
-            Assert.assertEquals(acceptLanguagesJs[i], acceptLanguages[i]);
-        }
+        Assert.assertArrayEquals(new String[] {"en-US"}, acceptLanguagesJs);
 
         // Test locale change at run time
         Locale.setDefault(new Locale("de", "DE"));
@@ -116,7 +125,8 @@
 
         acceptLanguages = getAcceptLanguages(
                 mActivityTestRule.getJavaScriptResultBodyTextContent(mAwContents, mContentsClient));
-        Assert.assertEquals(LocaleUtils.getDefaultLocaleString(), acceptLanguages[0]);
+        // Note that we extend the base language from language-region pair.
+        Assert.assertArrayEquals(new String[] {"de-DE", "de", "en-US", "en"}, acceptLanguages);
     }
 
     /**
@@ -130,26 +140,29 @@
     @SuppressLint("NewApi")
     @Feature({"AndroidWebView"})
     public void testAcceptLanguagesWithenUS() throws Throwable {
+        LocaleList.setDefault(new LocaleList(new Locale("ko", "KR")));
+        AwContents.updateDefaultLocale();
+        mAwContents.getSettings().updateAcceptLanguages();
+
         mActivityTestRule.getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
 
         // This should yield a lightly formatted page with the contents of the Accept-Language
-        // header, e.g. "en-US" or "de-DE,en-US;q=0.8", as the only text content.
+        // header, e.g. "en-US,en" or "de-DE,de,en-US,en;q=0.8", as the only text content.
         String url = mTestServer.getURL("/echoheader?Accept-Language");
         mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
 
-        String[] acceptLanguages = getAcceptLanguages(
-                mActivityTestRule.getJavaScriptResultBodyTextContent(mAwContents, mContentsClient));
-        Assert.assertEquals(
-                LocaleUtils.getDefaultLocaleListString(), TextUtils.join(",", acceptLanguages));
+        // Note that we extend accept languages.
+        Assert.assertArrayEquals(new String[] {"ko-KR", "ko", "en-US", "en"},
+                getAcceptLanguages(mActivityTestRule.getJavaScriptResultBodyTextContent(
+                        mAwContents, mContentsClient)));
 
+        // Our accept language list in user agent is different from navigator.languages, which is
+        // fine.
         String[] acceptLanguagesJs = getAcceptLanguages(JSUtils.executeJavaScriptAndWaitForResult(
                 InstrumentationRegistry.getInstrumentation(), mAwContents,
                 mContentsClient.getOnEvaluateJavaScriptResultHelper(),
                 "navigator.languages.join(',')"));
-        Assert.assertEquals(acceptLanguagesJs.length, acceptLanguages.length);
-        for (int i = 0; i < acceptLanguagesJs.length; ++i) {
-            Assert.assertEquals(acceptLanguagesJs[i], acceptLanguages[i]);
-        }
+        Assert.assertArrayEquals(new String[] {"ko-KR", "en-US"}, acceptLanguagesJs);
 
         // Test locales that contain "en-US" change at run time
         LocaleList.setDefault(new LocaleList(new Locale("de", "DE"), new Locale("en", "US")));
@@ -158,10 +171,11 @@
 
         mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
 
-        acceptLanguages = getAcceptLanguages(
-                mActivityTestRule.getJavaScriptResultBodyTextContent(mAwContents, mContentsClient));
-        Assert.assertEquals(
-                LocaleUtils.getDefaultLocaleListString(), TextUtils.join(",", acceptLanguages));
+        // Note that we extend the base language from language-region pair.
+        // Also, we put en-US at the lowest priority.
+        Assert.assertArrayEquals(new String[] {"de-DE", "de", "en-US", "en"},
+                getAcceptLanguages(mActivityTestRule.getJavaScriptResultBodyTextContent(
+                        mAwContents, mContentsClient)));
 
         // Test locales that contain "en-us" change at run time
         LocaleList.setDefault(new LocaleList(new Locale("de", "DE"), new Locale("en", "us")));
@@ -170,10 +184,9 @@
 
         mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
 
-        acceptLanguages = getAcceptLanguages(
-                mActivityTestRule.getJavaScriptResultBodyTextContent(mAwContents, mContentsClient));
-        Assert.assertEquals(
-                LocaleUtils.getDefaultLocaleListString(), TextUtils.join(",", acceptLanguages));
+        Assert.assertArrayEquals(new String[] {"de-DE", "de", "en-US", "en"},
+                getAcceptLanguages(mActivityTestRule.getJavaScriptResultBodyTextContent(
+                        mAwContents, mContentsClient)));
 
         // Test locales that do not contain "en-us" or "en-US" change at run time
         LocaleList.setDefault(new LocaleList(new Locale("de", "DE"), new Locale("ja", "JP")));
@@ -182,10 +195,8 @@
 
         mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
 
-        acceptLanguages = getAcceptLanguages(
-                mActivityTestRule.getJavaScriptResultBodyTextContent(mAwContents, mContentsClient));
-        String[] acceptLangs = Arrays.copyOfRange(acceptLanguages, 0, acceptLanguages.length - 1);
-        Assert.assertEquals(
-                LocaleUtils.getDefaultLocaleListString(), TextUtils.join(",", acceptLangs));
+        Assert.assertArrayEquals(new String[] {"de-DE", "de", "ja-JP", "ja", "en-US", "en"},
+                getAcceptLanguages(mActivityTestRule.getJavaScriptResultBodyTextContent(
+                        mAwContents, mContentsClient)));
     }
 }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java
index 949a139..de21c7f 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java
@@ -30,7 +30,6 @@
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.parameter.SkipCommandLineParameterization;
 import org.chromium.content_public.browser.GestureListenerManager;
 import org.chromium.content_public.browser.GestureStateListener;
 import org.chromium.content_public.common.UseZoomForDSFPolicy;
@@ -455,7 +454,7 @@
      * @RetryOnFailure
      * BUG=813837
      */
-    @SkipCommandLineParameterization // crbug.com/616505
+    // Originally flaked only in multi-process mode (http://crbug.com/616505)
     @DisabledTest
     public void testTouchScrollCanBeAlteredByUi() throws Throwable {
         final TestAwContentsClient contentsClient = new TestAwContentsClient();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java
index 4bf681d..4198eb1 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java
@@ -238,8 +238,9 @@
     private void loadPageOfSizeAndWaitForSizeChange(AwContents awContents,
             OnContentSizeChangedHelper helper, int widthCss, int heightCss,
             boolean heightPercent) throws Exception {
-
-        final String htmlData = makeHtmlPageOfSize(widthCss, heightCss, heightPercent);
+        // loadDataAsync loads HTML as a data URI, which requires encoding '#' characters as '%23'.
+        final String htmlData =
+                makeHtmlPageOfSize(widthCss, heightCss, heightPercent).replace("#", "%23");
         final int contentSizeChangeCallCount = helper.getCallCount();
         mActivityTestRule.loadDataAsync(awContents, htmlData, "text/html", false);
 
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java
index 6216f44..314ebe7 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java
@@ -30,10 +30,10 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.InMemorySharedPreferences;
-import org.chromium.content.browser.test.util.Criteria;
-import org.chromium.content.browser.test.util.CriteriaHelper;
-import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageFinishedHelper;
 import org.chromium.content_public.browser.LoadUrlParams;
+import org.chromium.content_public.browser.test.util.Criteria;
+import org.chromium.content_public.browser.test.util.CriteriaHelper;
+import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer.OnPageFinishedHelper;
 import org.chromium.net.test.util.TestWebServer;
 
 import java.lang.annotation.Annotation;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutocompleteTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutocompleteTest.java
new file mode 100644
index 0000000..9039fe9
--- /dev/null
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutocompleteTest.java
@@ -0,0 +1,171 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.android_webview.test;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.Build;
+import android.support.test.filters.SmallTest;
+import android.view.KeyEvent;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.chromium.android_webview.AwContents;
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.DisableIf;
+import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.MetricsUtils;
+import org.chromium.net.test.util.TestWebServer;
+
+import java.util.concurrent.Callable;
+
+/**
+ * AwAutocompleteTest only runs below Android O.
+ */
+@DisableIf.Build(sdk_is_greater_than = Build.VERSION_CODES.N)
+public class AwAutocompleteTest {
+    public static final String FILE = "/login.html";
+    public static final String TITLE = "DONE";
+
+    @Rule
+    public AwActivityTestRule mRule = new AwActivityTestRule();
+    private AwTestContainerView mTestContainerView;
+    private AwContents mAwContents;
+    private TestAwContentsClient mContentsClient;
+    private TestWebServer mWebServer;
+    private MetricsUtils.HistogramDelta mAutocompleteEnabled;
+    private MetricsUtils.HistogramDelta mAutocompleteDisabled;
+
+    private void loadUrlSync(String url) throws Exception {
+        mRule.loadUrlSync(
+                mTestContainerView.getAwContents(), mContentsClient.getOnPageFinishedHelper(), url);
+    }
+
+    private void initUmaDeltaSamples() {
+        mAutocompleteEnabled =
+                new MetricsUtils.HistogramDelta("Autofill.AutocompleteEnabled", 1 /*true*/);
+        mAutocompleteDisabled =
+                new MetricsUtils.HistogramDelta("Autofill.AutocompleteEnabled", 0 /*false*/);
+    }
+
+    private void verifyUmaAutocompleteEnabled(final boolean enabled) throws Throwable {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                if (enabled) {
+                    assertEquals(1, mAutocompleteEnabled.getDelta());
+                    assertEquals(0, mAutocompleteDisabled.getDelta());
+                } else {
+                    assertEquals(0, mAutocompleteEnabled.getDelta());
+                    assertEquals(1, mAutocompleteDisabled.getDelta());
+                }
+            }
+        });
+    }
+
+    private void verifyUmaNotRecorded() throws Throwable {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                assertEquals(0, mAutocompleteEnabled.getDelta());
+                assertEquals(0, mAutocompleteDisabled.getDelta());
+            }
+        });
+    }
+
+    private String executeJavaScriptAndWaitForResult(String code) throws Throwable {
+        return mRule.executeJavaScriptAndWaitForResult(
+                mTestContainerView.getAwContents(), mContentsClient, code);
+    }
+
+    private void dispatchDownAndUpKeyEvents(final int code) throws Throwable {
+        dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, code));
+        dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, code));
+    }
+
+    private boolean dispatchKeyEvent(final KeyEvent event) throws Throwable {
+        return ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
+            @Override
+            public Boolean call() {
+                return mTestContainerView.dispatchKeyEvent(event);
+            }
+        });
+    }
+
+    private void waitAutocompleteDone() throws Throwable {
+        // There is no available event to let us know that the autocomplete has done, to make test
+        // simple, just change the the title by javascript and wait for title being changed. This
+        // worked most of time. If test become flaky, this parts should be investigated first.
+        executeJavaScriptAndWaitForResult("document.title='" + TITLE + "';");
+        mRule.pollUiThread(() -> TITLE.equals(mAwContents.getTitle()));
+    }
+
+    private void loadPage() throws Throwable {
+        final String data = "<html><head></head><body><form action='a.html' name='formname'>"
+                + "<input type='text' id='text1' name='username'"
+                + " placeholder='placeholder@placeholder.com' autocomplete='username name'>"
+                + "<input type='submit'>"
+                + "</form></body></html>";
+        final String url = mWebServer.setResponse(FILE, data, null);
+        loadUrlSync(url);
+    }
+
+    private void triggerAutocomplete() throws Throwable {
+        executeJavaScriptAndWaitForResult("document.getElementById('text1').select();");
+        dispatchDownAndUpKeyEvents(KeyEvent.KEYCODE_A);
+    }
+
+    private void disableAwAutocomplete() throws Throwable {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                mAwContents.getSettings().setSaveFormData(false);
+            }
+        });
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        initUmaDeltaSamples();
+        mContentsClient = new TestAwContentsClient();
+        mTestContainerView = mRule.createAwTestContainerViewOnMainSync(mContentsClient);
+        mAwContents = mTestContainerView.getAwContents();
+        AwActivityTestRule.enableJavaScriptOnUiThread(mAwContents);
+        mWebServer = TestWebServer.start();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mWebServer.shutdown();
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"AndroidWebView"})
+    public void testAutocompleteEnabledUMA() throws Throwable {
+        loadPage();
+        // Verify that Uma isn't recorded before autocomplete is triggered.
+        verifyUmaNotRecorded();
+        triggerAutocomplete();
+        waitAutocompleteDone();
+        verifyUmaAutocompleteEnabled(true);
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"AndroidWebView"})
+    public void testAutocompleteDisabledUMA() throws Throwable {
+        disableAwAutocomplete();
+        loadPage();
+        // Verify that Uma isn't recorded before autocomplete is triggered.
+        verifyUmaNotRecorded();
+        triggerAutocomplete();
+        waitAutocompleteDone();
+        verifyUmaAutocompleteEnabled(false);
+    }
+}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
index f770888..dbd34c6 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
@@ -42,7 +42,6 @@
 import org.chromium.android_webview.AwContentsClient.AwWebResourceRequest;
 import org.chromium.android_webview.AwWebResourceResponse;
 import org.chromium.android_webview.test.AwActivityTestRule.TestDependencyFactory;
-import org.chromium.base.BuildInfo;
 import org.chromium.base.Log;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.metrics.RecordHistogram;
@@ -52,7 +51,7 @@
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.components.autofill.AutofillProvider;
 import org.chromium.components.autofill.SubmissionSource;
-import org.chromium.content.browser.test.util.DOMUtils;
+import org.chromium.content_public.browser.test.util.DOMUtils;
 import org.chromium.net.test.util.TestWebServer;
 
 import java.io.ByteArrayInputStream;
@@ -725,7 +724,7 @@
             });
         }
 
-        private int mCnt = 0;
+        private int mCnt;
         private AwAutofillTest mTest;
         private volatile Integer mSessionValue;
         private HashMap<MetricsUtils.HistogramDelta, Integer> mSessionDelta;
@@ -836,8 +835,8 @@
         TestWebServer webServer = TestWebServer.start();
         final String data = "<html><head></head><body><form action='a.html' name='formname'>"
                 + "<label>User Name:</label>"
-                + "<input type='text' id='text1' name='username' maxlength='30'"
-                + " placeholder='placeholder@placeholder.com' autocomplete='username name'>"
+                + "<input type='text' id='text1' name='name' maxlength='30'"
+                + " placeholder='placeholder@placeholder.com' autocomplete='name given-name'>"
                 + "<input type='checkbox' id='checkbox1' name='showpassword'>"
                 + "<select id='select1' name='month'>"
                 + "<option value='1'>Jan</option>"
@@ -881,14 +880,15 @@
             TestViewStructure child0 = viewStructure.getChild(0);
             assertEquals(View.AUTOFILL_TYPE_TEXT, child0.getAutofillType());
             assertEquals("placeholder@placeholder.com", child0.getHint());
-            assertEquals("username", child0.getAutofillHints()[0]);
-            assertEquals("name", child0.getAutofillHints()[1]);
+            assertEquals("name", child0.getAutofillHints()[0]);
+            assertEquals("given-name", child0.getAutofillHints()[1]);
             TestViewStructure.AwHtmlInfo htmlInfo0 = child0.getHtmlInfo();
             assertEquals("text", htmlInfo0.getAttribute("type"));
             assertEquals("text1", htmlInfo0.getAttribute("id"));
-            assertEquals("username", htmlInfo0.getAttribute("name"));
+            assertEquals("name", htmlInfo0.getAttribute("name"));
             assertEquals("User Name:", htmlInfo0.getAttribute("label"));
             assertEquals("30", htmlInfo0.getAttribute("maxlength"));
+            assertEquals("NAME_FIRST", htmlInfo0.getAttribute("ua-autofill-hints"));
 
             // Verify checkbox control filled correctly in ViewStructure.
             TestViewStructure child1 = viewStructure.getChild(1);
@@ -901,6 +901,7 @@
             assertEquals("showpassword", htmlInfo1.getAttribute("name"));
             assertEquals("", htmlInfo1.getAttribute("label"));
             assertNull(htmlInfo1.getAttribute("maxlength"));
+            assertNull(htmlInfo1.getAttribute("ua-autofill-hints"));
 
             // Verify select control filled correctly in ViewStructure.
             TestViewStructure child2 = viewStructure.getChild(2);
@@ -1023,7 +1024,7 @@
             assertEquals(1, values.size());
             assertEquals("a", values.get(0).second.getTextValue());
             executeJavaScriptAndWaitForResult("document.getElementById('text1').value='c';");
-            if (BuildInfo.isAtLeastP()) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                 // There is no AUTOFILL_CANCEL from Android P.
                 assertEquals(4, getCallbackCount());
             } else {
@@ -1482,6 +1483,69 @@
     @Test
     @SmallTest
     @Feature({"AndroidWebView"})
+    public void testUaAutofillHints() throws Throwable {
+        TestWebServer webServer = TestWebServer.start();
+        final String data = "<html><head></head><body><form action='a.html' name='formname'>"
+                + "<label for=\"frmAddressB\">Address</label>"
+                + "<input name=\"bill-address\" id=\"frmAddressB\">"
+                + "<label for=\"frmCityB\">City</label>"
+                + "<input name=\"bill-city\" id=\"frmCityB\">"
+                + "<label for=\"frmStateB\">State</label>"
+                + "<input name=\"bill-state\" id=\"frmStateB\">"
+                + "<label for=\"frmZipB\">Zip</label>"
+                + "<input name=\"bill-zip\" id=\"frmZipB\">"
+                + "<input type='checkbox' id='checkbox1' name='showpassword'>"
+                + "<label for=\"frmCountryB\">Country</label>"
+                + "<input name=\"bill-country\" id=\"frmCountryB\">"
+                + "<input type='submit'>"
+                + "</form></body></html>";
+        final int totalControls = 6;
+        try {
+            int cnt = 0;
+            final String url = webServer.setResponse(FILE, data, null);
+            loadUrlSync(url);
+            executeJavaScriptAndWaitForResult("document.getElementById('frmAddressB').select();");
+            dispatchDownAndUpKeyEvents(KeyEvent.KEYCODE_A);
+            // Note that we currently call ENTER/EXIT one more time.
+            cnt += waitForCallbackAndVerifyTypes(cnt,
+                    new Integer[] {AUTOFILL_CANCEL, AUTOFILL_VIEW_ENTERED, AUTOFILL_VIEW_EXITED,
+                            AUTOFILL_VIEW_ENTERED, AUTOFILL_VALUE_CHANGED});
+            invokeOnProvideAutoFillVirtualStructure();
+            TestViewStructure viewStructure = mTestValues.testViewStructure;
+            assertNotNull(viewStructure);
+            assertEquals(totalControls, viewStructure.getChildCount());
+
+            TestViewStructure child0 = viewStructure.getChild(0);
+            TestViewStructure.AwHtmlInfo htmlInfo0 = child0.getHtmlInfo();
+            assertEquals("ADDRESS_HOME_LINE1", htmlInfo0.getAttribute("ua-autofill-hints"));
+
+            TestViewStructure child1 = viewStructure.getChild(1);
+            TestViewStructure.AwHtmlInfo htmlInfo1 = child1.getHtmlInfo();
+            assertEquals("ADDRESS_HOME_CITY", htmlInfo1.getAttribute("ua-autofill-hints"));
+
+            TestViewStructure child2 = viewStructure.getChild(2);
+            TestViewStructure.AwHtmlInfo htmlInfo2 = child2.getHtmlInfo();
+            assertEquals("ADDRESS_HOME_STATE", htmlInfo2.getAttribute("ua-autofill-hints"));
+
+            TestViewStructure child3 = viewStructure.getChild(3);
+            TestViewStructure.AwHtmlInfo htmlInfo3 = child3.getHtmlInfo();
+            assertEquals("ADDRESS_HOME_ZIP", htmlInfo3.getAttribute("ua-autofill-hints"));
+
+            TestViewStructure child4 = viewStructure.getChild(4);
+            TestViewStructure.AwHtmlInfo htmlInfo4 = child4.getHtmlInfo();
+            assertNull(htmlInfo4.getAttribute("ua-autofill-hints"));
+
+            TestViewStructure child5 = viewStructure.getChild(5);
+            TestViewStructure.AwHtmlInfo htmlInfo5 = child5.getHtmlInfo();
+            assertEquals("ADDRESS_HOME_COUNTRY", htmlInfo5.getAttribute("ua-autofill-hints"));
+        } finally {
+            webServer.shutdown();
+        }
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"AndroidWebView"})
     public void testUMAUserSelectSuggestionUserChangeFormFormSubmitted() throws Throwable {
         TestWebServer webServer = TestWebServer.start();
         try {
@@ -1869,7 +1933,7 @@
             throws InterruptedException, TimeoutException {
         Integer[] adjustedEventArray;
         // Didn't call cancel after Android P.
-        if (BuildInfo.isAtLeastP()) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
             ArrayList<Integer> adjusted = new ArrayList<Integer>();
             for (Integer event : expectedEventArray) {
                 if (event != AUTOFILL_CANCEL) adjusted.add(event);
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientCallbackHelperTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientCallbackHelperTest.java
index b2ccb3f..a390df5be 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientCallbackHelperTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientCallbackHelperTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS;
+
 import android.graphics.Picture;
 import android.os.Handler;
 import android.os.Looper;
@@ -19,13 +21,13 @@
 import org.chromium.android_webview.AwContentsClient;
 import org.chromium.android_webview.AwContentsClientCallbackHelper;
 import org.chromium.android_webview.test.TestAwContentsClient.OnDownloadStartHelper;
+import org.chromium.android_webview.test.TestAwContentsClient.OnLoadResourceHelper;
 import org.chromium.android_webview.test.TestAwContentsClient.OnReceivedLoginRequestHelper;
 import org.chromium.android_webview.test.TestAwContentsClient.PictureListenerHelper;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.parameter.SkipCommandLineParameterization;
-import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageStartedHelper;
-import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnReceivedErrorHelper;
+import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer.OnPageStartedHelper;
+import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer.OnReceivedErrorHelper;
 
 import java.util.concurrent.Callable;
 
@@ -33,51 +35,11 @@
  * Test suite for AwContentsClientCallbackHelper.
  */
 @RunWith(AwJUnit4ClassRunner.class)
-@SkipCommandLineParameterization // These are unit tests. No need to repeat for multiprocess.
+@OnlyRunIn(SINGLE_PROCESS) // These are unit tests. No need to repeat for multiprocess.
 public class AwContentsClientCallbackHelperTest {
     @Rule
     public AwActivityTestRule mActivityTestRule = new AwActivityTestRule();
 
-    /**
-     * Callback helper for OnLoadedResource.
-     */
-    public static class OnLoadResourceHelper extends CallbackHelper {
-        private String mLastLoadedResource;
-
-        public String getLastLoadedResource() {
-            assert getCallCount() > 0;
-            return mLastLoadedResource;
-        }
-
-        public void notifyCalled(String url) {
-            mLastLoadedResource = url;
-            notifyCalled();
-        }
-    }
-
-    /**
-     * TestAwContentsClient extended with OnLoadResourceHelper.
-     */
-    public static class TestAwContentsClient
-            extends org.chromium.android_webview.test.TestAwContentsClient {
-
-        private final OnLoadResourceHelper mOnLoadResourceHelper;
-
-        public TestAwContentsClient() {
-            super();
-            mOnLoadResourceHelper = new OnLoadResourceHelper();
-        }
-
-        public OnLoadResourceHelper getOnLoadResourceHelper() {
-            return mOnLoadResourceHelper;
-        }
-
-        @Override
-        public void onLoadResource(String url) {
-            mOnLoadResourceHelper.notifyCalled(url);
-        }
-    }
-
     private static class TestCancelCallbackPoller
             implements AwContentsClientCallbackHelper.CancelCallbackPoller {
         private boolean mCancelled;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
index 4a966773..9c63efc 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
@@ -20,15 +20,16 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.android_webview.test.util.JSUtils;
 import org.chromium.android_webview.test.util.JavascriptEventObserver;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
-import org.chromium.content.browser.test.util.Criteria;
-import org.chromium.content.browser.test.util.CriteriaHelper;
-import org.chromium.content.browser.test.util.DOMUtils;
-import org.chromium.content.browser.test.util.TouchCommon;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_public.browser.test.util.Criteria;
+import org.chromium.content_public.browser.test.util.CriteriaHelper;
+import org.chromium.content_public.browser.test.util.DOMUtils;
+import org.chromium.content_public.browser.test.util.TouchCommon;
 
 import java.util.concurrent.TimeoutException;
 
@@ -70,13 +71,11 @@
         mTestContainerView.getAwContents().getSettings().setFullscreenSupported(true);
     }
 
-    /*
     @MediumTest
     @Feature({"AndroidWebView"})
     @DisableHardwareAccelerationForTest
-    */
     @Test
-    @DisabledTest(message = "crbug.com/618749")
+    @DisabledTest(message = "crbug.com/618749") // turning this on as an experiment.
     public void testFullscreenVideoInSoftwareModeDoesNotDeadlock() throws Throwable {
         // Although fullscreen video is not supported without hardware acceleration
         // we should not deadlock if apps try to use it.
@@ -87,33 +86,26 @@
         mContentsClient.waitForCustomViewHidden();
     }
 
-    /*
     @MediumTest
     @Feature({"AndroidWebView"})
     @DisableHardwareAccelerationForTest
-    */
     @Test
-    @DisabledTest(message = "crbug.com/618749")
     public void testFullscreenForNonVideoElementIsSupportedInSoftwareMode() throws Throwable {
         // Fullscreen for non-video elements is supported and works as expected. Note that
         // this test is the same as testOnShowAndHideCustomViewWithCallback_videoInsideDiv below.
         doTestOnShowAndHideCustomViewWithCallback(VIDEO_INSIDE_DIV_TEST_URL);
     }
 
-    /*
     @MediumTest
     @Feature({"AndroidWebView"})
-    */
     @Test
     @DisabledTest(message = "crbug.com/618749")
     public void testOnShowAndHideCustomViewWithCallback_video() throws Throwable {
         doTestOnShowAndHideCustomViewWithCallback(VIDEO_TEST_URL);
     }
 
-    /*
     @MediumTest
     @Feature({"AndroidWebView"})
-    */
     @Test
     @DisabledTest(message = "crbug.com/618749")
     public void testOnShowAndHideCustomViewWithCallback_videoInsideDiv() throws Throwable {
@@ -125,20 +117,16 @@
                 () -> mContentsClient.getExitCallback().onCustomViewHidden());
     }
 
-    /*
     @MediumTest
     @Feature({"AndroidWebView"})
-    */
     @Test
     @DisabledTest(message = "crbug.com/618749")
     public void testOnShowAndHideCustomViewWithJavascript_video() throws Throwable {
         doTestOnShowAndHideCustomViewWithJavascript(VIDEO_TEST_URL);
     }
 
-    /*
     @MediumTest
     @Feature({"AndroidWebView"})
-    */
     @Test
     @DisabledTest(message = "crbug.com/618749")
     public void testOnShowAndHideCustomViewWithJavascript_videoInsideDiv() throws Throwable {
@@ -150,21 +138,17 @@
                 videoTestUrl, () -> DOMUtils.exitFullscreen(mTestContainerView.getWebContents()));
     }
 
-    /*
     @MediumTest
     @Feature({"AndroidWebView"})
-    @SkipCommandLineParameterization  // crbug.com/616501
-    */
     @Test
+    // Originally flaked only in multi-process mode (http://crbug.com/616501)
     @DisabledTest(message = "crbug.com/618749")
     public void testOnShowAndHideCustomViewWithBackKey_video() throws Throwable {
         doTestOnShowAndHideCustomViewWithBackKey(VIDEO_TEST_URL);
     }
 
-    /*
     @MediumTest
     @Feature({"AndroidWebView"})
-    */
     @Test
     @DisabledTest(message = "crbug.com/618749")
     public void testOnShowAndHideCustomViewWithBackKey_videoInsideDiv() throws Throwable {
@@ -188,9 +172,8 @@
     }
 
     @Test
-    //@MediumTest
-    //@Feature({"AndroidWebView"})
-    @DisabledTest(message = "crbug.com/789306")
+    @MediumTest
+    @Feature({"AndroidWebView"})
     public void testExitFullscreenEndsIfAppInvokesCallbackFromOnHideCustomView() throws Throwable {
         mContentsClient.setOnHideCustomViewRunnable(
                 () -> mContentsClient.getExitCallback().onCustomViewHidden());
@@ -296,12 +279,9 @@
         assertWaitForKeepScreenOnActive(mTestContainerView, false);
     }
 
-    /*
     @MediumTest
     @Feature({"AndroidWebView"})
-    */
     @Test
-    @DisabledTest(message = "crbug.com/808444")
     public void testPowerSaveBlockerIsTransferredToFullscreen() throws Throwable {
         Assert.assertFalse(DOMUtils.isFullscreen(getWebContentsOnUiThread()));
         loadTestPage(VIDEO_INSIDE_DIV_TEST_URL);
@@ -312,7 +292,8 @@
 
         // Enter fullscreen and verify that the power save blocker is
         // still there.
-        DOMUtils.clickNode(mTestContainerView.getWebContents(), CUSTOM_FULLSCREEN_CONTROL_ID);
+        JSUtils.clickNodeWithUserGesture(
+                mTestContainerView.getWebContents(), CUSTOM_FULLSCREEN_CONTROL_ID);
         mContentsClient.waitForCustomViewShown();
         assertKeepScreenOnActive(mTestContainerView, true);
 
@@ -358,7 +339,8 @@
             // (containing the fullscreen <video>) so we just rely on that fact here.
             TouchCommon.singleClickView(mContentsClient.getCustomView());
         } else {
-            DOMUtils.clickNode(mTestContainerView.getWebContents(), CUSTOM_PLAY_CONTROL_ID);
+            JSUtils.clickNodeWithUserGesture(
+                    mTestContainerView.getWebContents(), CUSTOM_PLAY_CONTROL_ID);
         }
     }
 
@@ -467,7 +449,8 @@
 
     private void loadTestPageAndClickFullscreen(String videoTestUrl) throws Exception {
         loadTestPage(videoTestUrl);
-        DOMUtils.clickNode(mTestContainerView.getWebContents(), CUSTOM_FULLSCREEN_CONTROL_ID);
+        JSUtils.clickNodeWithUserGesture(
+                mTestContainerView.getWebContents(), CUSTOM_FULLSCREEN_CONTROL_ID);
     }
 
     private void loadTestPage(String videoTestUrl) throws Exception {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnFormResubmissionTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnFormResubmissionTest.java
index 01f4787..5af215d 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnFormResubmissionTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnFormResubmissionTest.java
@@ -20,7 +20,7 @@
 
 import org.chromium.android_webview.AwContents;
 import org.chromium.base.test.util.Feature;
-import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
+import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer;
 import org.chromium.net.test.util.TestWebServer;
 
 import java.util.concurrent.TimeUnit;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnRenderProcessGoneTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnRenderProcessGoneTest.java
index d71fea1..e0a332e 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnRenderProcessGoneTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnRenderProcessGoneTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.MULTI_PROCESS;
+
 import android.support.test.filters.SmallTest;
 
 import org.junit.Assert;
@@ -14,14 +16,11 @@
 import org.chromium.android_webview.AwContents;
 import org.chromium.android_webview.AwRenderProcess;
 import org.chromium.android_webview.AwRenderProcessGoneDetail;
-import org.chromium.android_webview.AwSwitches;
 import org.chromium.android_webview.renderer_priority.RendererPriority;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
-import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.parameter.SkipCommandLineParameterization;
 import org.chromium.content_public.common.ContentUrlConstants;
 
 import java.util.concurrent.TimeUnit;
@@ -107,8 +106,7 @@
     @DisabledTest // http://crbug.com/689292
     @Feature({"AndroidWebView"})
     @SmallTest
-    @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER)
-    @SkipCommandLineParameterization
+    @OnlyRunIn(MULTI_PROCESS)
     public void testOnRenderProcessCrash() throws Throwable {
         createAndTerminateRenderProcess(
                 (AwContents awContents) -> { awContents.loadUrl("chrome://crash"); }, true);
@@ -117,8 +115,7 @@
     @Test
     @Feature({"AndroidWebView"})
     @SmallTest
-    @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER)
-    @SkipCommandLineParameterization
+    @OnlyRunIn(MULTI_PROCESS)
     public void testOnRenderProcessKill() throws Throwable {
         createAndTerminateRenderProcess(
                 (AwContents awContents) -> { awContents.loadUrl("chrome://kill"); }, false);
@@ -127,8 +124,7 @@
     @Test
     @Feature({"AndroidWebView"})
     @SmallTest
-    @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER)
-    @SkipCommandLineParameterization
+    @OnlyRunIn(MULTI_PROCESS)
     public void testRenderProcessTermination() throws Throwable {
         createAndTerminateRenderProcess(
                 (AwContents awContents) -> { awContents.getRenderProcess().terminate(); }, false);
@@ -137,8 +133,7 @@
     @Test
     @Feature({"AndroidWebView"})
     @SmallTest
-    @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER)
-    @SkipCommandLineParameterization
+    @OnlyRunIn(MULTI_PROCESS)
     public void testRenderProcessDifferentAfterRestart() throws Throwable {
         AwRenderProcess renderProcess1 = createAndTerminateRenderProcess(
                 (AwContents awContents) -> { awContents.getRenderProcess().terminate(); }, false);
@@ -150,8 +145,7 @@
     @Test
     @Feature({"AndroidWebView"})
     @SmallTest
-    @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER)
-    @SkipCommandLineParameterization
+    @OnlyRunIn(MULTI_PROCESS)
     public void testRenderProcessCanNotTerminateBeforeStart() throws Throwable {
         RenderProcessGoneTestAwContentsClient contentsClient =
                 new RenderProcessGoneTestAwContentsClient();
@@ -166,8 +160,7 @@
     @Test
     @Feature({"AndroidWebView"})
     @SmallTest
-    @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER)
-    @SkipCommandLineParameterization
+    @OnlyRunIn(MULTI_PROCESS)
     public void testRenderProcessSameBeforeAndAfterStart() throws Throwable {
         RenderProcessGoneTestAwContentsClient contentsClient =
                 new RenderProcessGoneTestAwContentsClient();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnScaleChangedTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnScaleChangedTest.java
index e5707a7..e29b6f8 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnScaleChangedTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientOnScaleChangedTest.java
@@ -15,8 +15,8 @@
 import org.chromium.android_webview.AwContents;
 import org.chromium.android_webview.test.util.CommonResources;
 import org.chromium.base.ThreadUtils;
-import org.chromium.content.browser.test.util.Criteria;
-import org.chromium.content.browser.test.util.CriteriaHelper;
+import org.chromium.content_public.browser.test.util.Criteria;
+import org.chromium.content_public.browser.test.util.CriteriaHelper;
 
 /**
  * Tests for the WebViewClient.onScaleChanged.
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java
index ac4bc94..8143935 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldInterceptRequestTest.java
@@ -23,7 +23,7 @@
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.TestFileUtil;
-import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnReceivedErrorHelper;
+import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer.OnReceivedErrorHelper;
 import org.chromium.net.test.util.TestWebServer;
 
 import java.io.ByteArrayInputStream;
@@ -81,20 +81,6 @@
             }
         }
 
-        public static class OnLoadResourceHelper extends CallbackHelper {
-            private String mUrl;
-
-            public String getUrl() {
-                assert getCallCount() > 0;
-                return mUrl;