diff --git a/DEPS b/DEPS
index 6ba7951..4dda9f72 100644
--- a/DEPS
+++ b/DEPS
@@ -45,7 +45,7 @@
   # 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': '9acf4ad109f6d4c642272132133addc2c7dbeb97',
+  'v8_revision': '8b35cb30de6b2ed5e57ff35064870b60a18960ba',
   # 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.
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 79f94ae8b..05b748a 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -3339,12 +3339,6 @@
      FEATURE_VALUE_TYPE(features::kCaptureThumbnailOnNavigatingAway)},
 
 #if defined(OS_CHROMEOS)
-    {"use-cros-midi-service", flag_descriptions::kUseCrosMidiServiceName,
-     flag_descriptions::kUseCrosMidiServiceNameDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(midi::features::kMidiManagerCros)},
-#endif  // defined(OS_CHROMEOS)
-
-#if defined(OS_CHROMEOS)
     {"disable-lock-screen-apps", flag_descriptions::kDisableLockScreenAppsName,
      flag_descriptions::kDisableLockScreenAppsDescription, kOsCrOS,
      SINGLE_VALUE_TYPE(chromeos::switches::kDisableLockScreenApps)},
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 798f3df..685c912c5 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -211,6 +211,7 @@
 #include "device/usb/public/interfaces/device_manager.mojom.h"
 #include "extensions/features/features.h"
 #include "google_apis/gaia/gaia_urls.h"
+#include "google_apis/google_api_keys.h"
 #include "gpu/config/gpu_switches.h"
 #include "media/audio/audio_manager.h"
 #include "media/media_features.h"
@@ -2105,6 +2106,10 @@
   return NULL;
 }
 
+std::string ChromeContentBrowserClient::GetGeolocationApiKey() {
+  return google_apis::GetAPIKey();
+}
+
 QuotaPermissionContext*
 ChromeContentBrowserClient::CreateQuotaPermissionContext() {
   return new ChromeQuotaPermissionContext();
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index f766e0e..dce1c50 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -180,6 +180,7 @@
   net::URLRequestContext* OverrideRequestContextForURL(
       const GURL& url,
       content::ResourceContext* context) override;
+  std::string GetGeolocationApiKey() override;
   content::QuotaPermissionContext* CreateQuotaPermissionContext() override;
   void GetQuotaSettings(
       content::BrowserContext* context,
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index ec9d80a3..8fcb692 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -2563,11 +2563,6 @@
     "Enables inspection of native UI elements. For local inspection use "
     "chrome://inspect#other";
 
-const char kUseCrosMidiServiceName[] = "Use Chrome OS MIDI Service";
-const char kUseCrosMidiServiceNameDescription[] =
-    "Use Chrome OS MIDI Service for Web MIDI and allow ARC to support Android "
-    "MIDI.";
-
 const char kUseMusName[] = "Mus";
 const char kUseMusDescription[] = "Enable the Mojo UI service.";
 const char kEnableMashDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 67262e3f..1732445 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1566,9 +1566,6 @@
 extern const char kUiDevToolsName[];
 extern const char kUiDevToolsDescription[];
 
-extern const char kUseCrosMidiServiceName[];
-extern const char kUseCrosMidiServiceNameDescription[];
-
 extern const char kUseMusName[];
 extern const char kUseMusDescription[];
 extern const char kEnableMashDescription[];
diff --git a/chrome/browser/geolocation/geolocation_browsertest.cc b/chrome/browser/geolocation/geolocation_browsertest.cc
index c8e8f63..5e91d7f8 100644
--- a/chrome/browser/geolocation/geolocation_browsertest.cc
+++ b/chrome/browser/geolocation/geolocation_browsertest.cc
@@ -35,7 +35,11 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
 #include "device/geolocation/geoposition.h"
+#include "device/geolocation/network_location_request.h"
+#include "google_apis/google_api_keys.h"
+#include "net/base/escape.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/url_request/test_url_fetcher_factory.h"
 
 namespace {
 
@@ -165,6 +169,39 @@
   DISALLOW_COPY_AND_ASSIGN(PermissionRequestObserver);
 };
 
+// Observer that waits until a TestURLFetcher with the specified fetcher_id
+// starts, after which it is made available through .fetcher().
+class TestURLFetcherObserver : public net::TestURLFetcher::DelegateForTests {
+ public:
+  explicit TestURLFetcherObserver(int expected_fetcher_id)
+      : expected_fetcher_id_(expected_fetcher_id) {
+    factory_.SetDelegateForTests(this);
+  }
+  virtual ~TestURLFetcherObserver() {}
+
+  void Wait() { loop_.Run(); }
+
+  net::TestURLFetcher* fetcher() { return fetcher_; }
+
+  // net::TestURLFetcher::DelegateForTests:
+  void OnRequestStart(int fetcher_id) override {
+    if (fetcher_id == expected_fetcher_id_) {
+      fetcher_ = factory_.GetFetcherByID(fetcher_id);
+      fetcher_->SetDelegateForTests(nullptr);
+      factory_.SetDelegateForTests(nullptr);
+      loop_.Quit();
+    }
+  }
+  void OnChunkUpload(int fetcher_id) override {}
+  void OnRequestEnd(int fetcher_id) override {}
+
+ private:
+  const int expected_fetcher_id_;
+  net::TestURLFetcher* fetcher_ = nullptr;
+  net::TestURLFetcherFactory factory_;
+  base::RunLoop loop_;
+};
+
 }  // namespace
 
 
@@ -458,6 +495,36 @@
   ExpectPosition(fake_latitude(), fake_longitude());
 }
 
+#if defined(OS_CHROMEOS)
+// ChromeOS fails to perform network geolocation when zero wifi networks are
+// detected in a scan: https://crbug.com/767300.
+#define MAYBE_UrlWithApiKey DISABLED_UrlWithApiKey
+#else
+#define MAYBE_UrlWithApiKey UrlWithApiKey
+#endif
+// Tests that Chrome makes a network geolocation request to the correct URL
+// including Google API key query param.
+IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_UrlWithApiKey) {
+  ASSERT_NO_FATAL_FAILURE(Initialize(INITIALIZATION_DEFAULT));
+
+  // Unique ID (derived from Gerrit CL number):
+  device::NetworkLocationRequest::url_fetcher_id_for_tests = 675023;
+
+  // Intercept the URLFetcher from network geolocation request.
+  TestURLFetcherObserver observer(
+      device::NetworkLocationRequest::url_fetcher_id_for_tests);
+  ASSERT_TRUE(WatchPositionAndGrantPermission());
+  observer.Wait();
+  DCHECK(observer.fetcher());
+
+  // Verify full URL including Google API key.
+  const std::string expected_url =
+      "https://www.googleapis.com/geolocation/v1/geolocate?key=" +
+      net::EscapeQueryParamValue(google_apis::GetAPIKey(), true);
+  EXPECT_EQ(expected_url,
+            observer.fetcher()->GetOriginalURL().possibly_invalid_spec());
+}
+
 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, ErrorOnPermissionDenied) {
   ASSERT_NO_FATAL_FAILURE(Initialize(INITIALIZATION_DEFAULT));
   EXPECT_TRUE(WatchPositionAndDenyPermission());
diff --git a/chrome/browser/media/webrtc/media_stream_devices_controller.cc b/chrome/browser/media/webrtc/media_stream_devices_controller.cc
index cc59ecc6f..08fa971 100644
--- a/chrome/browser/media/webrtc/media_stream_devices_controller.cc
+++ b/chrome/browser/media/webrtc/media_stream_devices_controller.cc
@@ -437,8 +437,10 @@
   }
 
   content_settings_->OnMediaStreamPermissionSet(
-      request_.security_origin, microphone_camera_state, selected_audio_device,
-      selected_video_device, requested_audio_device, requested_video_device);
+      PermissionManager::Get(profile_)->GetCanonicalOrigin(
+          request_.security_origin),
+      microphone_camera_state, selected_audio_device, selected_video_device,
+      requested_audio_device, requested_video_device);
 }
 
 ContentSetting MediaStreamDevicesController::GetContentSetting(
diff --git a/chrome/browser/permissions/permission_manager.cc b/chrome/browser/permissions/permission_manager.cc
index 563a03d..d2d6177 100644
--- a/chrome/browser/permissions/permission_manager.cc
+++ b/chrome/browser/permissions/permission_manager.cc
@@ -24,10 +24,12 @@
 #include "chrome/browser/permissions/permission_result.h"
 #include "chrome/browser/permissions/permission_uma_util.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
 #include "chrome/browser/storage/durable_storage_permission_context.h"
 #include "chrome/browser/tab_contents/tab_util.h"
 #include "chrome/browser/vr/vr_tab_helper.h"
 #include "chrome/common/features.h"
+#include "chrome/common/url_constants.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/permission_type.h"
@@ -309,6 +311,13 @@
   }
 }
 
+GURL PermissionManager::GetCanonicalOrigin(const GURL& url) const {
+  if (url.GetOrigin() == GURL(chrome::kChromeSearchLocalNtpUrl).GetOrigin())
+    return GURL(UIThreadSearchTermsData(profile_).GoogleBaseURLValue());
+
+  return url;
+}
+
 int PermissionManager::RequestPermission(
     ContentSettingsType content_settings_type,
     content::RenderFrameHost* render_frame_host,
@@ -344,6 +353,7 @@
   }
 
   GURL embedding_origin = web_contents->GetLastCommittedURL().GetOrigin();
+  GURL canonical_requesting_origin = GetCanonicalOrigin(requesting_origin);
 
   int request_id = pending_requests_.Add(base::MakeUnique<PendingRequest>(
       render_frame_host, permissions, callback));
@@ -358,7 +368,7 @@
     auto callback = base::MakeUnique<PermissionResponseCallback>(
         weak_ptr_factory_.GetWeakPtr(), request_id, i);
     context->RequestPermission(
-        web_contents, request, requesting_origin, user_gesture,
+        web_contents, request, canonical_requesting_origin, user_gesture,
         base::Bind(
             &PermissionResponseCallback::OnPermissionsRequestResponseStatus,
             base::Passed(&callback)));
@@ -479,8 +489,7 @@
       GetPermissionContext(PermissionTypeToContentSetting(permission));
   if (!context)
     return;
-
-  context->ResetPermission(requesting_origin.GetOrigin(),
+  context->ResetPermission(GetCanonicalOrigin(requesting_origin).GetOrigin(),
                            embedding_origin.GetOrigin());
 }
 
@@ -499,7 +508,7 @@
       GetPermissionContext(PermissionTypeToContentSetting(permission));
   if (context) {
     result = context->UpdatePermissionStatusWithDeviceStatus(
-        result, requesting_origin, embedding_origin);
+        result, GetCanonicalOrigin(requesting_origin), embedding_origin);
   }
 
   return ContentSettingToPermissionStatus(result.content_setting);
@@ -517,7 +526,7 @@
   ContentSettingsType content_type = PermissionTypeToContentSetting(permission);
   auto subscription = base::MakeUnique<Subscription>();
   subscription->permission = content_type;
-  subscription->requesting_origin = requesting_origin;
+  subscription->requesting_origin = GetCanonicalOrigin(requesting_origin);
   subscription->embedding_origin = embedding_origin;
   subscription->callback = base::Bind(&SubscriptionCallbackWrapper, callback);
 
@@ -589,9 +598,10 @@
     content::RenderFrameHost* render_frame_host,
     const GURL& requesting_origin,
     const GURL& embedding_origin) {
+  GURL canonical_requesting_origin = GetCanonicalOrigin(requesting_origin);
   PermissionContextBase* context = GetPermissionContext(permission);
   PermissionResult result = context->GetPermissionStatus(
-      render_frame_host, requesting_origin.GetOrigin(),
+      render_frame_host, canonical_requesting_origin.GetOrigin(),
       embedding_origin.GetOrigin());
   DCHECK(result.content_setting == CONTENT_SETTING_ALLOW ||
          result.content_setting == CONTENT_SETTING_ASK ||
diff --git a/chrome/browser/permissions/permission_manager.h b/chrome/browser/permissions/permission_manager.h
index 4b770f1..f747a35 100644
--- a/chrome/browser/permissions/permission_manager.h
+++ b/chrome/browser/permissions/permission_manager.h
@@ -34,6 +34,15 @@
   explicit PermissionManager(Profile* profile);
   ~PermissionManager() override;
 
+  // Converts from |url|'s actual origin to the "canonical origin" that should
+  // be used for the purpose of requesting/storing permissions. For example, the
+  // origin of the local NTP gets mapped to the Google base URL instead. All the
+  // public methods below, such as RequestPermission or GetPermissionStatus,
+  // take the actual origin and do the canonicalization internally. You only
+  // need to call this directly if you do something else with the origin, such
+  // as display it in the UI.
+  GURL GetCanonicalOrigin(const GURL& url) const;
+
   // Callers from within chrome/ should use the methods which take the
   // ContentSettingsType enum. The methods which take PermissionType values
   // are for the content::PermissionManager overrides and shouldn't be used
diff --git a/chrome/browser/permissions/permission_manager_unittest.cc b/chrome/browser/permissions/permission_manager_unittest.cc
index 06d7010..cc096534 100644
--- a/chrome/browser/permissions/permission_manager_unittest.cc
+++ b/chrome/browser/permissions/permission_manager_unittest.cc
@@ -10,8 +10,10 @@
 #include "chrome/browser/permissions/permission_manager_factory.h"
 #include "chrome/browser/permissions/permission_request_manager.h"
 #include "chrome/browser/permissions/permission_result.h"
+#include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
 #include "chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h"
 #include "chrome/browser/vr/vr_tab_helper.h"
+#include "chrome/common/url_constants.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
@@ -96,6 +98,10 @@
     return other_url_;
   }
 
+  GURL google_base_url() const {
+    return GURL(UIThreadSearchTermsData(profile_.get()).GoogleBaseURLValue());
+  }
+
   bool callback_called() const {
     return callback_called_;
   }
@@ -494,3 +500,29 @@
   EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
   EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
 }
+
+TEST_F(PermissionManagerTest, GetCanonicalOrigin) {
+  const GURL google_com("https://www.google.com");
+  const GURL google_de("https://www.google.de");
+  const GURL other_url("https://other.url");
+  const GURL google_base = google_base_url().GetOrigin();
+  const GURL local_ntp = GURL(chrome::kChromeSearchLocalNtpUrl).GetOrigin();
+  const GURL remote_ntp = GURL(std::string("chrome-search://") +
+                               chrome::kChromeSearchRemoteNtpHost);
+  const GURL other_chrome_search = GURL("chrome-search://not-local-ntp");
+
+  // "Normal" URLs are not affected by GetCanonicalOrigin.
+  EXPECT_EQ(google_com, GetPermissionManager()->GetCanonicalOrigin(google_com));
+  EXPECT_EQ(google_de, GetPermissionManager()->GetCanonicalOrigin(google_de));
+  EXPECT_EQ(other_url, GetPermissionManager()->GetCanonicalOrigin(other_url));
+  EXPECT_EQ(google_base,
+            GetPermissionManager()->GetCanonicalOrigin(google_base));
+
+  // The local NTP URL gets mapped to the Google base URL.
+  EXPECT_EQ(google_base, GetPermissionManager()->GetCanonicalOrigin(local_ntp));
+  // However, other chrome-search:// URLs, including the remote NTP URL, are
+  // not affected.
+  EXPECT_EQ(remote_ntp, GetPermissionManager()->GetCanonicalOrigin(remote_ntp));
+  EXPECT_EQ(other_chrome_search,
+            GetPermissionManager()->GetCanonicalOrigin(other_chrome_search));
+}
diff --git a/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.cc b/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.cc
index 3447053..7be876e 100644
--- a/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.cc
+++ b/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.cc
@@ -40,8 +40,10 @@
   prompts_.push_back(prompt);
   show_count_++;
   requests_count_ = delegate->Requests().size();
-  for (const PermissionRequest* request : delegate->Requests())
+  for (const PermissionRequest* request : delegate->Requests()) {
     request_types_seen_.push_back(request->GetPermissionRequestType());
+    request_origins_seen_.push_back(request->GetOrigin());
+  }
 
   if (!show_bubble_quit_closure_.is_null())
     show_bubble_quit_closure_.Run();
@@ -60,6 +62,7 @@
   show_count_ = 0;
   requests_count_ = 0;
   request_types_seen_.clear();
+  request_origins_seen_.clear();
 }
 
 void MockPermissionPromptFactory::DocumentOnLoadCompletedInMainFrame() {
@@ -78,6 +81,10 @@
   return base::ContainsValue(request_types_seen_, type);
 }
 
+bool MockPermissionPromptFactory::RequestOriginSeen(const GURL& origin) {
+  return base::ContainsValue(request_origins_seen_, origin);
+}
+
 void MockPermissionPromptFactory::WaitForPermissionBubble() {
   if (is_visible())
     return;
diff --git a/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h b/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h
index 2671e919..4db9673 100644
--- a/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h
+++ b/chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h
@@ -11,6 +11,7 @@
 #include "chrome/browser/permissions/permission_request.h"
 #include "chrome/browser/permissions/permission_request_manager.h"
 #include "chrome/browser/ui/permission_bubble/permission_prompt.h"
+#include "url/gurl.h"
 
 class MockPermissionPrompt;
 
@@ -57,6 +58,8 @@
   int TotalRequestCount();
   // Whether the specified permission was shown in a prompt.
   bool RequestTypeSeen(PermissionRequestType type);
+  // Whether a prompt with the given origin was shown.
+  bool RequestOriginSeen(const GURL& origin);
 
   void WaitForPermissionBubble();
 
@@ -75,6 +78,7 @@
   int show_count_;
   int requests_count_;
   std::vector<PermissionRequestType> request_types_seen_;
+  std::vector<GURL> request_origins_seen_;
 
   std::vector<MockPermissionPrompt*> prompts_;
   PermissionRequestManager::AutoResponseType response_type_;
diff --git a/chrome/browser/ui/search/local_ntp_browsertest.cc b/chrome/browser/ui/search/local_ntp_browsertest.cc
index 0ff9490..cf428cd 100644
--- a/chrome/browser/ui/search/local_ntp_browsertest.cc
+++ b/chrome/browser/ui/search/local_ntp_browsertest.cc
@@ -15,6 +15,10 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/permissions/permission_manager.h"
+#include "chrome/browser/permissions/permission_manager_factory.h"
+#include "chrome/browser/permissions/permission_request_manager.h"
+#include "chrome/browser/permissions/permission_result.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/one_google_bar/one_google_bar_data.h"
 #include "chrome/browser/search/one_google_bar/one_google_bar_fetcher.h"
@@ -22,9 +26,11 @@
 #include "chrome/browser/search/one_google_bar/one_google_bar_service_factory.h"
 #include "chrome/browser/search/search.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
+#include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
 #include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h"
 #include "chrome/browser/ui/search/instant_test_utils.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_features.h"
@@ -32,6 +38,7 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/content_settings/core/common/content_settings.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/prefs/pref_service.h"
 #include "components/search_engines/template_url.h"
@@ -39,8 +46,10 @@
 #include "components/search_engines/template_url_service.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "content/public/test/test_utils.h"
+#include "media/base/media_switches.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "ui/base/resource/resource_bundle.h"
 
@@ -591,6 +600,12 @@
     InProcessBrowserTest::SetUp();
   }
 
+  void SetUpCommandLine(base::CommandLine* cmdline) override {
+    // Requesting microphone permission doesn't work unless there's a device
+    // available.
+    cmdline->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
+  }
+
   base::test::ScopedFeatureList feature_list_;
 };
 
@@ -622,3 +637,61 @@
   // We shouldn't have gotten any console error messages.
   EXPECT_TRUE(console_observer.message().empty()) << console_observer.message();
 }
+
+IN_PROC_BROWSER_TEST_F(LocalNTPVoiceSearchSmokeTest, MicrophonePermission) {
+  // Open a new NTP.
+  content::WebContents* active_tab =
+      OpenNewTab(browser(), GURL(chrome::kChromeUINewTabURL));
+  ASSERT_TRUE(search::IsInstantNTP(active_tab));
+  ASSERT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl),
+            active_tab->GetController().GetVisibleEntry()->GetURL());
+
+  PermissionRequestManager* request_manager =
+      PermissionRequestManager::FromWebContents(active_tab);
+  MockPermissionPromptFactory prompt_factory(request_manager);
+
+  PermissionManager* permission_manager =
+      PermissionManagerFactory::GetForProfile(browser()->profile());
+
+  // Make sure microphone permission for the NTP isn't set yet.
+  const PermissionResult mic_permission_before =
+      permission_manager->GetPermissionStatus(
+          CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
+          GURL(chrome::kChromeSearchLocalNtpUrl).GetOrigin(),
+          GURL(chrome::kChromeUINewTabURL).GetOrigin());
+  ASSERT_EQ(CONTENT_SETTING_ASK, mic_permission_before.content_setting);
+  ASSERT_EQ(PermissionStatusSource::UNSPECIFIED, mic_permission_before.source);
+
+  ASSERT_EQ(0, prompt_factory.TotalRequestCount());
+
+  // Auto-approve the permissions bubble as soon as it shows up.
+  prompt_factory.set_response_type(PermissionRequestManager::ACCEPT_ALL);
+
+  // Click on the microphone button, which will trigger a permission request.
+  ASSERT_TRUE(content::ExecuteScript(
+      active_tab, "document.getElementById('fakebox-microphone').click();"));
+
+  // Make sure the request arrived.
+  prompt_factory.WaitForPermissionBubble();
+  EXPECT_EQ(1, prompt_factory.show_count());
+  EXPECT_EQ(1, prompt_factory.request_count());
+  EXPECT_EQ(1, prompt_factory.TotalRequestCount());
+  EXPECT_TRUE(prompt_factory.RequestTypeSeen(
+      PermissionRequestType::PERMISSION_MEDIASTREAM_MIC));
+  // ...and that it showed the Google base URL, not the NTP URL.
+  const GURL google_base_url(
+      UIThreadSearchTermsData(browser()->profile()).GoogleBaseURLValue());
+  EXPECT_TRUE(prompt_factory.RequestOriginSeen(google_base_url.GetOrigin()));
+  EXPECT_FALSE(prompt_factory.RequestOriginSeen(
+      GURL(chrome::kChromeUINewTabURL).GetOrigin()));
+  EXPECT_FALSE(prompt_factory.RequestOriginSeen(
+      GURL(chrome::kChromeSearchLocalNtpUrl).GetOrigin()));
+
+  // Now microphone permission for the NTP should be set.
+  const PermissionResult mic_permission_after =
+      permission_manager->GetPermissionStatus(
+          CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
+          GURL(chrome::kChromeSearchLocalNtpUrl).GetOrigin(),
+          GURL(chrome::kChromeUINewTabURL).GetOrigin());
+  EXPECT_EQ(CONTENT_SETTING_ALLOW, mic_permission_after.content_setting);
+}
diff --git a/components/search_engines/keyword_table.cc b/components/search_engines/keyword_table.cc
index c384e81..bcd3fc0 100644
--- a/components/search_engines/keyword_table.cc
+++ b/components/search_engines/keyword_table.cc
@@ -62,15 +62,18 @@
     columns.push_back("logo_id");
   }
   columns.push_back("created_by_policy");
-  columns.push_back("instant_url");
+  if (version <= 75) {
+    // Column removed after version 75.
+    columns.push_back("instant_url");
+  }
   columns.push_back("last_modified");
   columns.push_back("sync_guid");
   if (version >= 47) {
     // Column added in version 47.
     columns.push_back("alternate_urls");
   }
-  if (version >= 49) {
-    // Column added in version 49.
+  if (version >= 49 && version <= 75) {
+    // Column added in version 49 and removed after version 75.
     columns.push_back("search_terms_replacement_key");
   }
   if (version >= 52) {
@@ -78,7 +81,13 @@
     columns.push_back("image_url");
     columns.push_back("search_url_post_params");
     columns.push_back("suggest_url_post_params");
+  }
+  if (version >= 52 && version <= 75) {
+    // Column added in version 52 and removed after version 75.
     columns.push_back("instant_url_post_params");
+  }
+  if (version >= 52) {
+    // Column added in version 52.
     columns.push_back("image_url_post_params");
   }
   if (version >= 53) {
@@ -130,18 +139,15 @@
   s->BindString(starting_column + 9, data.suggestions_url);
   s->BindInt(starting_column + 10, data.prepopulate_id);
   s->BindBool(starting_column + 11, data.created_by_policy);
-  s->BindString(starting_column + 12, std::string());
-  s->BindInt64(starting_column + 13, data.last_modified.ToTimeT());
-  s->BindString(starting_column + 14, data.sync_guid);
-  s->BindString(starting_column + 15, alternate_urls);
-  s->BindString(starting_column + 16, std::string());
-  s->BindString(starting_column + 17, data.image_url);
-  s->BindString(starting_column + 18, data.search_url_post_params);
-  s->BindString(starting_column + 19, data.suggestions_url_post_params);
-  s->BindString(starting_column + 20, std::string());
-  s->BindString(starting_column + 21, data.image_url_post_params);
-  s->BindString(starting_column + 22, data.new_tab_url);
-  s->BindInt64(starting_column + 23, data.last_visited.ToTimeT());
+  s->BindInt64(starting_column + 12, data.last_modified.ToTimeT());
+  s->BindString(starting_column + 13, data.sync_guid);
+  s->BindString(starting_column + 14, alternate_urls);
+  s->BindString(starting_column + 15, data.image_url);
+  s->BindString(starting_column + 16, data.search_url_post_params);
+  s->BindString(starting_column + 17, data.suggestions_url_post_params);
+  s->BindString(starting_column + 18, data.image_url_post_params);
+  s->BindString(starting_column + 19, data.new_tab_url);
+  s->BindInt64(starting_column + 20, data.last_visited.ToTimeT());
 }
 
 WebDatabaseTable::TypeKey GetKey() {
@@ -168,32 +174,30 @@
 
 bool KeywordTable::CreateTablesIfNecessary() {
   return db_->DoesTableExist("keywords") ||
-      db_->Execute("CREATE TABLE keywords ("
-          "id INTEGER PRIMARY KEY,"
-          "short_name VARCHAR NOT NULL,"
-          "keyword VARCHAR NOT NULL,"
-          "favicon_url VARCHAR NOT NULL,"
-          "url VARCHAR NOT NULL,"
-          "safe_for_autoreplace INTEGER,"
-          "originating_url VARCHAR,"
-          "date_created INTEGER DEFAULT 0,"
-          "usage_count INTEGER DEFAULT 0,"
-          "input_encodings VARCHAR,"
-          "suggest_url VARCHAR,"
-          "prepopulate_id INTEGER DEFAULT 0,"
-          "created_by_policy INTEGER DEFAULT 0,"
-          "instant_url VARCHAR,"
-          "last_modified INTEGER DEFAULT 0,"
-          "sync_guid VARCHAR,"
-          "alternate_urls VARCHAR,"
-          "search_terms_replacement_key VARCHAR,"
-          "image_url VARCHAR,"
-          "search_url_post_params VARCHAR,"
-          "suggest_url_post_params VARCHAR,"
-          "instant_url_post_params VARCHAR,"
-          "image_url_post_params VARCHAR,"
-          "new_tab_url VARCHAR,"
-          " last_visited INTEGER DEFAULT 0)");
+         db_->Execute(
+             "CREATE TABLE keywords ("
+             "id INTEGER PRIMARY KEY,"
+             "short_name VARCHAR NOT NULL,"
+             "keyword VARCHAR NOT NULL,"
+             "favicon_url VARCHAR NOT NULL,"
+             "url VARCHAR NOT NULL,"
+             "safe_for_autoreplace INTEGER,"
+             "originating_url VARCHAR,"
+             "date_created INTEGER DEFAULT 0,"
+             "usage_count INTEGER DEFAULT 0,"
+             "input_encodings VARCHAR,"
+             "suggest_url VARCHAR,"
+             "prepopulate_id INTEGER DEFAULT 0,"
+             "created_by_policy INTEGER DEFAULT 0,"
+             "last_modified INTEGER DEFAULT 0,"
+             "sync_guid VARCHAR,"
+             "alternate_urls VARCHAR,"
+             "image_url VARCHAR,"
+             "search_url_post_params VARCHAR,"
+             "suggest_url_post_params VARCHAR,"
+             "image_url_post_params VARCHAR,"
+             "new_tab_url VARCHAR,"
+             "last_visited INTEGER DEFAULT 0)");
 }
 
 bool KeywordTable::IsSyncable() {
@@ -215,6 +219,9 @@
       return MigrateToVersion68RemoveShowInDefaultListColumn();
     case 69:
       return MigrateToVersion69AddLastVisitedColumn();
+    case 76:
+      *update_compatible_version = true;
+      return MigrateToVersion76RemoveInstantColumns();
   }
 
   return true;
@@ -349,6 +356,46 @@
                       "INTEGER DEFAULT 0");
 }
 
+// SQLite does not support DROP COLUMN operation. So a new table is created
+// without the removed columns. Data from all but the dropped columns of the old
+// table is copied into it. After that, the old table is dropped and the new
+// table is renamed to it.
+bool KeywordTable::MigrateToVersion76RemoveInstantColumns() {
+  sql::Transaction transaction(db_);
+  std::string query_str =
+      std::string("INSERT INTO temp_keywords SELECT " +
+                  ColumnsForVersion(76, false) + " FROM keywords");
+  const char* clone_query = query_str.c_str();
+  return transaction.Begin() &&
+         db_->Execute(
+             "CREATE TABLE temp_keywords ("
+             "id INTEGER PRIMARY KEY,"
+             "short_name VARCHAR NOT NULL,"
+             "keyword VARCHAR NOT NULL,"
+             "favicon_url VARCHAR NOT NULL,"
+             "url VARCHAR NOT NULL,"
+             "safe_for_autoreplace INTEGER,"
+             "originating_url VARCHAR,"
+             "date_created INTEGER DEFAULT 0,"
+             "usage_count INTEGER DEFAULT 0,"
+             "input_encodings VARCHAR,"
+             "suggest_url VARCHAR,"
+             "prepopulate_id INTEGER DEFAULT 0,"
+             "created_by_policy INTEGER DEFAULT 0,"
+             "last_modified INTEGER DEFAULT 0,"
+             "sync_guid VARCHAR,"
+             "alternate_urls VARCHAR,"
+             "image_url VARCHAR,"
+             "search_url_post_params VARCHAR,"
+             "suggest_url_post_params VARCHAR,"
+             "image_url_post_params VARCHAR,"
+             "new_tab_url VARCHAR,"
+             "last_visited INTEGER DEFAULT 0)") &&
+         db_->Execute(clone_query) && db_->Execute("DROP TABLE keywords") &&
+         db_->Execute("ALTER TABLE temp_keywords RENAME TO keywords") &&
+         transaction.Commit();
+}
+
 // static
 bool KeywordTable::GetKeywordDataFromStatement(const sql::Statement& s,
                                                TemplateURLData* data) {
@@ -364,11 +411,11 @@
     return false;
   data->SetURL(s.ColumnString(4));
   data->suggestions_url = s.ColumnString(10);
-  data->image_url = s.ColumnString(18);
-  data->new_tab_url = s.ColumnString(23);
-  data->search_url_post_params = s.ColumnString(19);
-  data->suggestions_url_post_params = s.ColumnString(20);
-  data->image_url_post_params = s.ColumnString(22);
+  data->image_url = s.ColumnString(16);
+  data->new_tab_url = s.ColumnString(20);
+  data->search_url_post_params = s.ColumnString(17);
+  data->suggestions_url_post_params = s.ColumnString(18);
+  data->image_url_post_params = s.ColumnString(19);
   data->favicon_url = GURL(s.ColumnString(3));
   data->originating_url = GURL(s.ColumnString(6));
   data->safe_for_autoreplace = s.ColumnBool(5);
@@ -376,16 +423,16 @@
       s.ColumnString(9), ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
   data->id = s.ColumnInt64(0);
   data->date_created = Time::FromTimeT(s.ColumnInt64(7));
-  data->last_modified = Time::FromTimeT(s.ColumnInt64(14));
+  data->last_modified = Time::FromTimeT(s.ColumnInt64(13));
   data->created_by_policy = s.ColumnBool(12);
   data->usage_count = s.ColumnInt(8);
   data->prepopulate_id = s.ColumnInt(11);
-  data->sync_guid = s.ColumnString(15);
+  data->sync_guid = s.ColumnString(14);
 
   data->alternate_urls.clear();
   base::JSONReader json_reader;
   std::unique_ptr<base::Value> value(
-      json_reader.ReadToValue(s.ColumnString(16)));
+      json_reader.ReadToValue(s.ColumnString(15)));
   base::ListValue* alternate_urls_value;
   if (value.get() && value->GetAsList(&alternate_urls_value)) {
     std::string alternate_url;
@@ -395,16 +442,16 @@
     }
   }
 
-  data->last_visited = Time::FromTimeT(s.ColumnInt64(24));
+  data->last_visited = Time::FromTimeT(s.ColumnInt64(21));
 
   return true;
 }
 
 bool KeywordTable::AddKeyword(const TemplateURLData& data) {
   DCHECK(data.id);
-  std::string query("INSERT INTO keywords (" + GetKeywordColumns() + ") "
-                    "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,"
-                    "        ?,?)");
+  std::string query("INSERT INTO keywords (" + GetKeywordColumns() +
+                    ") "
+                    "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
   sql::Statement s(db_->GetCachedStatement(SQL_FROM_HERE, query.c_str()));
   BindURLToStatement(data, &s, 0, 1);
 
@@ -426,13 +473,11 @@
       SQL_FROM_HERE,
       "UPDATE keywords SET short_name=?, keyword=?, favicon_url=?, url=?, "
       "safe_for_autoreplace=?, originating_url=?, date_created=?, "
-      "usage_count=?, input_encodings=?, suggest_url=?, "
-      "prepopulate_id=?, created_by_policy=?, instant_url=?, "
-      "last_modified=?, sync_guid=?, alternate_urls=?, "
-      "search_terms_replacement_key=?, image_url=?, search_url_post_params=?, "
-      "suggest_url_post_params=?, instant_url_post_params=?, "
+      "usage_count=?, input_encodings=?, suggest_url=?, prepopulate_id=?, "
+      "created_by_policy=?, last_modified=?, sync_guid=?, alternate_urls=?, "
+      "image_url=?, search_url_post_params=?, suggest_url_post_params=?, "
       "image_url_post_params=?, new_tab_url=?, last_visited=? WHERE id=?"));
-  BindURLToStatement(data, &s, 24, 0);  // "24" binds id() as the last item.
+  BindURLToStatement(data, &s, 21, 0);  // "21" binds id() as the last item.
 
   return s.Run();
 }
diff --git a/components/search_engines/keyword_table.h b/components/search_engines/keyword_table.h
index 90a4257..86059ab8 100644
--- a/components/search_engines/keyword_table.h
+++ b/components/search_engines/keyword_table.h
@@ -48,25 +48,18 @@
 //   prepopulate_id         See TemplateURLData::prepopulate_id.
 //   created_by_policy      See TemplateURLData::created_by_policy.  This was
 //                          added in version 26.
-//   instant_url            See TemplateURLData::instant_url.  This was added in
-//                          version 29.
 //   last_modified          See TemplateURLData::last_modified.  This was added
 //                          in version 38.
 //   sync_guid              See TemplateURLData::sync_guid. This was added in
 //                          version 39.
 //   alternate_urls         See TemplateURLData::alternate_urls. This was added
 //                          in version 47.
-//   search_terms_replacement_key
-//                          See TemplateURLData::search_terms_replacement_key.
-//                          This was added in version 49.
 //   image_url              See TemplateURLData::image_url. This was added in
 //                          version 52.
 //   search_url_post_params See TemplateURLData::search_url_post_params. This
 //                          was added in version 52.
 //   suggest_url_post_params See TemplateURLData::suggestions_url_post_params.
 //                          This was added in version 52.
-//   instant_url_post_params See TemplateURLData::instant_url_post_params. This
-//                          was added in version 52.
 //   image_url_post_params  See TemplateURLData::image_url_post_params. This
 //                          was added in version 52.
 //   new_tab_url            See TemplateURLData::new_tab_url. This was added in
@@ -132,10 +125,10 @@
   bool MigrateToVersion59RemoveExtensionKeywords();
   bool MigrateToVersion68RemoveShowInDefaultListColumn();
   bool MigrateToVersion69AddLastVisitedColumn();
+  bool MigrateToVersion76RemoveInstantColumns();
 
  private:
   friend class KeywordTableTest;
-  FRIEND_TEST_ALL_PREFIXES(WebDatabaseMigrationTest, MigrateVersion44ToCurrent);
 
   // NOTE: Since the table columns have changed in different versions, many
   // functions below take a |table_version| argument which dictates which
diff --git a/components/test/data/web_database/version_75.sql b/components/test/data/web_database/version_75.sql
new file mode 100644
index 0000000..de766ceba9
--- /dev/null
+++ b/components/test/data/web_database/version_75.sql
@@ -0,0 +1,26 @@
+PRAGMA foreign_keys=OFF;
+BEGIN TRANSACTION;
+CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR);
+INSERT INTO "meta" VALUES('mmap_status','-1');
+INSERT INTO "meta" VALUES('version','75');
+INSERT INTO "meta" VALUES('last_compatible_version','72');
+CREATE TABLE token_service (service VARCHAR PRIMARY KEY NOT NULL,encrypted_token BLOB);
+CREATE TABLE keywords (id INTEGER PRIMARY KEY,short_name VARCHAR NOT NULL,keyword VARCHAR NOT NULL,favicon_url VARCHAR NOT NULL,url VARCHAR NOT NULL,safe_for_autoreplace INTEGER,originating_url VARCHAR,date_created INTEGER DEFAULT 0,usage_count INTEGER DEFAULT 0,input_encodings VARCHAR,suggest_url VARCHAR,prepopulate_id INTEGER DEFAULT 0,created_by_policy INTEGER DEFAULT 0,instant_url VARCHAR,last_modified INTEGER DEFAULT 0,sync_guid VARCHAR,alternate_urls VARCHAR,search_terms_replacement_key VARCHAR,image_url VARCHAR,search_url_post_params VARCHAR,suggest_url_post_params VARCHAR,instant_url_post_params VARCHAR,image_url_post_params VARCHAR,new_tab_url VARCHAR, last_visited INTEGER DEFAULT 0);
+CREATE TABLE autofill (name VARCHAR, value VARCHAR, value_lower VARCHAR, date_created INTEGER DEFAULT 0, date_last_used INTEGER DEFAULT 0, count INTEGER DEFAULT 1, PRIMARY KEY (name, value));
+CREATE TABLE credit_cards ( guid VARCHAR PRIMARY KEY, name_on_card VARCHAR, expiration_month INTEGER, expiration_year INTEGER, card_number_encrypted BLOB, date_modified INTEGER NOT NULL DEFAULT 0, origin VARCHAR DEFAULT '', use_count INTEGER NOT NULL DEFAULT 0, use_date INTEGER NOT NULL DEFAULT 0, billing_address_id VARCHAR);
+CREATE TABLE autofill_profiles ( guid VARCHAR PRIMARY KEY, company_name VARCHAR, street_address VARCHAR, dependent_locality VARCHAR, city VARCHAR, state VARCHAR, zipcode VARCHAR, sorting_code VARCHAR, country_code VARCHAR, date_modified INTEGER NOT NULL DEFAULT 0, origin VARCHAR DEFAULT '', language_code VARCHAR, use_count INTEGER NOT NULL DEFAULT 0, use_date INTEGER NOT NULL DEFAULT 0, validity_bitfield UNSIGNED NOT NULL DEFAULT 0);
+INSERT INTO "autofill_profiles" VALUES('00000000-0000-0000-0000-000000000001','Google Inc','340 Main St','','Los Angeles','CA','90291','','US',1395948829,'Chrome settings','en',12,12,0);
+CREATE TABLE autofill_profile_names ( guid VARCHAR, first_name VARCHAR, middle_name VARCHAR, last_name VARCHAR, full_name VARCHAR);
+CREATE TABLE autofill_profile_emails ( guid VARCHAR, email VARCHAR);
+CREATE TABLE autofill_profile_phones ( guid VARCHAR, number VARCHAR);
+CREATE TABLE autofill_profiles_trash ( guid VARCHAR);
+CREATE TABLE masked_credit_cards (id VARCHAR,status VARCHAR,name_on_card VARCHAR,network VARCHAR,last_four VARCHAR,exp_month INTEGER DEFAULT 0,exp_year INTEGER DEFAULT 0, bank_name VARCHAR, type INTEGER DEFAULT 0);
+CREATE TABLE unmasked_credit_cards (id VARCHAR,card_number_encrypted VARCHAR, use_count INTEGER NOT NULL DEFAULT 0, use_date INTEGER NOT NULL DEFAULT 0, unmask_date INTEGER NOT NULL DEFAULT 0);
+CREATE TABLE server_card_metadata (id VARCHAR NOT NULL,use_count INTEGER NOT NULL DEFAULT 0, use_date INTEGER NOT NULL DEFAULT 0, billing_address_id VARCHAR);
+CREATE TABLE server_addresses (id VARCHAR,company_name VARCHAR,street_address VARCHAR,address_1 VARCHAR,address_2 VARCHAR,address_3 VARCHAR,address_4 VARCHAR,postal_code VARCHAR,sorting_code VARCHAR,country_code VARCHAR,language_code VARCHAR, recipient_name VARCHAR, phone_number VARCHAR);
+CREATE TABLE server_address_metadata (id VARCHAR NOT NULL,use_count INTEGER NOT NULL DEFAULT 0, use_date INTEGER NOT NULL DEFAULT 0, has_converted BOOL NOT NULL DEFAULT FALSE);
+CREATE TABLE autofill_sync_metadata (storage_key VARCHAR PRIMARY KEY NOT NULL,value BLOB);
+CREATE TABLE autofill_model_type_state (id INTEGER PRIMARY KEY, value BLOB);
+CREATE INDEX autofill_name ON autofill (name);
+CREATE INDEX autofill_name_value_lower ON autofill (name, value_lower);
+COMMIT;
diff --git a/components/translate/core/browser/translate_prefs.cc b/components/translate/core/browser/translate_prefs.cc
index 3437031..9c96713d 100644
--- a/components/translate/core/browser/translate_prefs.cc
+++ b/components/translate/core/browser/translate_prefs.cc
@@ -7,6 +7,7 @@
 #include <set>
 #include <utility>
 
+#include "base/feature_list.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
@@ -104,6 +105,9 @@
 const base::Feature kTranslateUI2016Q2{"TranslateUI2016Q2",
                                        base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kImprovedLanguageSettings{
+    "ImprovedLanguageSettings", base::FEATURE_DISABLED_BY_DEFAULT};
+
 DenialTimeUpdate::DenialTimeUpdate(PrefService* prefs,
                                    const std::string& language,
                                    size_t max_denial_count)
@@ -469,18 +473,21 @@
 
 void TranslatePrefs::UpdateLanguageList(
     const std::vector<std::string>& languages) {
-#if defined(OS_CHROMEOS)
   std::string languages_str = base::JoinString(languages, ",");
-  prefs_->SetString(preferred_languages_pref_.c_str(), languages_str);
+
+#if defined(OS_CHROMEOS)
+  prefs_->SetString(preferred_languages_pref_, languages_str);
 #endif
 
   // Save the same language list as accept languages preference as well, but we
   // need to expand the language list, to make it more acceptable. For instance,
   // some web sites don't understand 'en-US' but 'en'. See crosbug.com/9884.
-  std::vector<base::StringPiece> accept_languages;
-  ExpandLanguageCodes(languages, &accept_languages);
-  std::string accept_languages_str = base::JoinString(accept_languages, ",");
-  prefs_->SetString(accept_languages_pref_, accept_languages_str);
+  if (!base::FeatureList::IsEnabled(kImprovedLanguageSettings)) {
+    std::vector<base::StringPiece> accept_languages;
+    ExpandLanguageCodes(languages, &accept_languages);
+    languages_str = base::JoinString(accept_languages, ",");
+  }
+  prefs_->SetString(accept_languages_pref_, languages_str);
 }
 
 bool TranslatePrefs::CanTranslateLanguage(
diff --git a/components/translate/core/browser/translate_prefs.h b/components/translate/core/browser/translate_prefs.h
index f3ee614d..5edf073 100644
--- a/components/translate/core/browser/translate_prefs.h
+++ b/components/translate/core/browser/translate_prefs.h
@@ -35,6 +35,10 @@
 // Feature flag for "Translate UI 2016 Q2" project.
 extern const base::Feature kTranslateUI2016Q2;
 
+// Enables or disables the new improved language settings.
+// These settings support the new UI.
+extern const base::Feature kImprovedLanguageSettings;
+
 // The trial (study) name in finch study config.
 extern const char kTranslateUI2016Q2TrialName[];
 
diff --git a/components/translate/core/browser/translate_prefs_unittest.cc b/components/translate/core/browser/translate_prefs_unittest.cc
index 17ee464..6bec1a7 100644
--- a/components/translate/core/browser/translate_prefs_unittest.cc
+++ b/components/translate/core/browser/translate_prefs_unittest.cc
@@ -18,6 +18,8 @@
 #include "components/translate/core/browser/translate_download_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using base::test::ScopedFeatureList;
+
 namespace {
 
 const char kTestLanguage[] = "en";
@@ -62,6 +64,20 @@
     return update.GetOldestDenialTime();
   }
 
+  void ExpectLanguagePrefs(const std::string& expected_str) {
+    if (expected_str.empty()) {
+      EXPECT_TRUE(prefs_->GetString(kAcceptLanguagesPref).empty());
+#if defined(OS_CHROMEOS)
+      EXPECT_TRUE(prefs_->GetString(kPreferredLanguagesPref).empty());
+#endif
+    } else {
+      EXPECT_EQ(expected_str, prefs_->GetString(kAcceptLanguagesPref));
+#if defined(OS_CHROMEOS)
+      EXPECT_EQ(expected_str, prefs_->GetString(kPreferredLanguagesPref));
+#endif
+    }
+  }
+
   std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> prefs_;
   std::unique_ptr<translate::TranslatePrefs> translate_prefs_;
 
@@ -220,21 +236,73 @@
             now_ - base::TimeDelta::FromMinutes(2));
 }
 
+// The logic of UpdateLanguageList() changes based on the value of feature
+// kImprovedLanguageSettings, which is a boolean.
+// We write two separate test cases for true and false.
 TEST_F(TranslatePrefTest, UpdateLanguageList) {
-  // Test with basic set of languages (no country codes).
-  std::vector<std::string> languages{"en", "ja"};
-  translate_prefs_->UpdateLanguageList(languages);
-  EXPECT_EQ("en,ja", prefs_->GetString(kAcceptLanguagesPref));
+  ScopedFeatureList disable_feature;
+  disable_feature.InitAndDisableFeature(translate::kImprovedLanguageSettings);
 
-  // Test with languages that have country codes. Expect accepted languages both
-  // with and without a country code. (See documentation for
-  // ExpandLanguageCodes.)
-  languages = {"en-US", "ja", "en-CA"};
+  // Empty update.
+  std::vector<std::string> languages;
   translate_prefs_->UpdateLanguageList(languages);
+  ExpectLanguagePrefs("");
+
+  // One language.
+  languages = {"en"};
+  translate_prefs_->UpdateLanguageList(languages);
+  ExpectLanguagePrefs("en");
+
+  // More than one language.
+  languages = {"en", "ja", "it"};
+  translate_prefs_->UpdateLanguageList(languages);
+  ExpectLanguagePrefs("en,ja,it");
+
+  // Locale-specific codes.
+  // The list is exanded by adding the base languagese.
+  languages = {"en-US", "ja", "en-CA", "fr-CA"};
+  translate_prefs_->UpdateLanguageList(languages);
+  EXPECT_EQ("en-US,en,ja,en-CA,fr-CA,fr",
+            prefs_->GetString(kAcceptLanguagesPref));
 #if defined(OS_CHROMEOS)
-  EXPECT_EQ("en-US,ja,en-CA", prefs_->GetString(kPreferredLanguagesPref));
+  EXPECT_EQ("en-US,ja,en-CA,fr-CA", prefs_->GetString(kPreferredLanguagesPref));
 #endif
-  EXPECT_EQ("en-US,en,ja,en-CA", prefs_->GetString(kAcceptLanguagesPref));
+
+  // List already expanded.
+  languages = {"en-US", "en", "fr", "fr-CA"};
+  translate_prefs_->UpdateLanguageList(languages);
+  ExpectLanguagePrefs("en-US,en,fr,fr-CA");
+}
+
+TEST_F(TranslatePrefTest, UpdateLanguageListFeatureEnabled) {
+  ScopedFeatureList enable_feature;
+  enable_feature.InitAndEnableFeature(translate::kImprovedLanguageSettings);
+
+  // Empty update.
+  std::vector<std::string> languages;
+  translate_prefs_->UpdateLanguageList(languages);
+  ExpectLanguagePrefs("");
+
+  // One language.
+  languages = {"en"};
+  translate_prefs_->UpdateLanguageList(languages);
+  ExpectLanguagePrefs("en");
+
+  // More than one language.
+  languages = {"en", "ja", "it"};
+  translate_prefs_->UpdateLanguageList(languages);
+  ExpectLanguagePrefs("en,ja,it");
+
+  // Locale-specific codes.
+  // The list is exanded by adding the base languagese.
+  languages = {"en-US", "ja", "en-CA", "fr-CA"};
+  translate_prefs_->UpdateLanguageList(languages);
+  ExpectLanguagePrefs("en-US,ja,en-CA,fr-CA");
+
+  // List already expanded.
+  languages = {"en-US", "en", "fr", "fr-CA"};
+  translate_prefs_->UpdateLanguageList(languages);
+  ExpectLanguagePrefs("en-US,en,fr,fr-CA");
 }
 
 TEST_F(TranslatePrefTest, ULPPrefs) {
diff --git a/components/webdata/common/BUILD.gn b/components/webdata/common/BUILD.gn
index d55783da..188da12 100644
--- a/components/webdata/common/BUILD.gn
+++ b/components/webdata/common/BUILD.gn
@@ -62,6 +62,7 @@
     "//components/test/data/web_database/version_73.sql",
     "//components/test/data/web_database/version_73_with_type_column.sql",
     "//components/test/data/web_database/version_74.sql",
+    "//components/test/data/web_database/version_75.sql",
   ]
   outputs = [
     "{{bundle_resources_dir}}/" +
diff --git a/components/webdata/common/web_database.cc b/components/webdata/common/web_database.cc
index e954603..2058577 100644
--- a/components/webdata/common/web_database.cc
+++ b/components/webdata/common/web_database.cc
@@ -13,7 +13,7 @@
 // corresponding changes must happen in the unit tests, and new migration test
 // added.  See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|.
 // static
-const int WebDatabase::kCurrentVersionNumber = 75;
+const int WebDatabase::kCurrentVersionNumber = 76;
 
 const int WebDatabase::kDeprecatedVersionNumber = 51;
 
diff --git a/components/webdata/common/web_database_migration_unittest.cc b/components/webdata/common/web_database_migration_unittest.cc
index ed46c3c..e4ba6d9 100644
--- a/components/webdata/common/web_database_migration_unittest.cc
+++ b/components/webdata/common/web_database_migration_unittest.cc
@@ -130,7 +130,7 @@
   DISALLOW_COPY_AND_ASSIGN(WebDatabaseMigrationTest);
 };
 
-const int WebDatabaseMigrationTest::kCurrentTestedVersionNumber = 75;
+const int WebDatabaseMigrationTest::kCurrentTestedVersionNumber = 76;
 
 void WebDatabaseMigrationTest::LoadDatabase(
     const base::FilePath::StringType& file) {
@@ -225,8 +225,6 @@
     ASSERT_FALSE(
         connection.DoesColumnExist("keywords", "suggest_url_post_params"));
     ASSERT_FALSE(
-        connection.DoesColumnExist("keywords", "instant_url_post_params"));
-    ASSERT_FALSE(
         connection.DoesColumnExist("keywords", "image_url_post_params"));
   }
 
@@ -249,8 +247,6 @@
     EXPECT_TRUE(
         connection.DoesColumnExist("keywords", "suggest_url_post_params"));
     EXPECT_TRUE(
-        connection.DoesColumnExist("keywords", "instant_url_post_params"));
-    EXPECT_TRUE(
         connection.DoesColumnExist("keywords", "image_url_post_params"));
   }
 }
@@ -1470,3 +1466,42 @@
     ASSERT_FALSE(s_profiles.Step());
   }
 }
+
+// Tests deletion of Instant-related columns in keywords table.
+TEST_F(WebDatabaseMigrationTest, MigrateVersion75ToCurrent) {
+  ASSERT_NO_FATAL_FAILURE(LoadDatabase(FILE_PATH_LITERAL("version_75.sql")));
+
+  // Verify pre-conditions.
+  {
+    sql::Connection connection;
+    ASSERT_TRUE(connection.Open(GetDatabasePath()));
+    ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
+
+    sql::MetaTable meta_table;
+    ASSERT_TRUE(meta_table.Init(&connection, 75, 75));
+
+    EXPECT_TRUE(connection.DoesColumnExist("keywords", "instant_url"));
+    EXPECT_TRUE(
+        connection.DoesColumnExist("keywords", "instant_url_post_params"));
+    EXPECT_TRUE(
+        connection.DoesColumnExist("keywords", "search_terms_replacement_key"));
+  }
+
+  DoMigration();
+
+  // Verify post-conditions.
+  {
+    sql::Connection connection;
+    ASSERT_TRUE(connection.Open(GetDatabasePath()));
+    ASSERT_TRUE(sql::MetaTable::DoesTableExist(&connection));
+
+    // Check version.
+    EXPECT_EQ(kCurrentTestedVersionNumber, VersionFromConnection(&connection));
+
+    EXPECT_FALSE(connection.DoesColumnExist("keywords", "instant_url"));
+    EXPECT_FALSE(
+        connection.DoesColumnExist("keywords", "instant_url_post_params"));
+    EXPECT_FALSE(
+        connection.DoesColumnExist("keywords", "search_terms_replacement_key"));
+  }
+}
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc
index 1947a15..dde1b0c7a 100644
--- a/content/browser/service_manager/service_manager_context.cc
+++ b/content/browser/service_manager/service_manager_context.cc
@@ -35,6 +35,7 @@
 #include "content/public/common/content_switches.h"
 #include "content/public/common/service_manager_connection.h"
 #include "content/public/common/service_names.mojom.h"
+#include "device/geolocation/geolocation_provider.h"
 #include "media/mojo/features.h"
 #include "media/mojo/interfaces/constants.mojom.h"
 #include "mojo/edk/embedder/embedder.h"
@@ -341,6 +342,13 @@
   packaged_services_connection_->AddEmbeddedService(device::mojom::kServiceName,
                                                     device_info);
 
+  // Pipe embedder-supplied API key through to GeolocationProvider.
+  // TODO(amoylan): Once GeolocationProvider hangs off DeviceService
+  // (https://crbug.com/709301), pass this via CreateDeviceService above
+  // instead.
+  device::GeolocationProvider::SetApiKey(
+      GetContentClient()->browser()->GetGeolocationApiKey());
+
   if (base::FeatureList::IsEnabled(features::kGlobalResourceCoordinator)) {
     service_manager::EmbeddedServiceInfo resource_coordinator_info;
     resource_coordinator_info.factory =
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc
index 988fcca2..215a03c 100644
--- a/content/child/resource_dispatcher.cc
+++ b/content/child/resource_dispatcher.cc
@@ -557,6 +557,7 @@
     std::unique_ptr<ResourceRequest> request,
     int routing_id,
     const url::Origin& frame_origin,
+    const net::NetworkTrafficAnnotationTag& traffic_annotation,
     SyncLoadResponse* response,
     blink::WebURLRequest::LoadingIPCType ipc_type,
     mojom::URLLoaderFactory* url_loader_factory,
@@ -581,8 +582,9 @@
         FROM_HERE,
         base::BindOnce(&SyncLoadContext::StartAsyncWithWaitableEvent,
                        std::move(request), routing_id, frame_origin,
-                       std::move(url_loader_factory_copy), std::move(throttles),
-                       base::Unretained(response), base::Unretained(&event)));
+                       traffic_annotation, std::move(url_loader_factory_copy),
+                       std::move(throttles), base::Unretained(response),
+                       base::Unretained(&event)));
 
     event.Wait();
   } else {
@@ -618,6 +620,7 @@
     int routing_id,
     scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner,
     const url::Origin& frame_origin,
+    const net::NetworkTrafficAnnotationTag& traffic_annotation,
     bool is_sync,
     std::unique_ptr<RequestPeer> peer,
     blink::WebURLRequest::LoadingIPCType ipc_type,
@@ -652,30 +655,6 @@
     return request_id;
   }
 
-  net::NetworkTrafficAnnotationTag traffic_annotation =
-      net::DefineNetworkTrafficAnnotation("blink_resource_loader", R"(
-      semantics {
-        sender: "Blink Resource Loader"
-        description:
-          "Blink initiated request, which includes all resources for "
-          "normal page loads, chrome URLs, resources for installed "
-          "extensions, as well as downloads."
-        trigger:
-          "Navigating to a URL or downloading a file. A webpage, "
-          "ServiceWorker, chrome:// page, or extension may also initiate "
-          "requests in the background."
-        data: "Anything the initiator wants to send."
-        destination: OTHER
-      }
-      policy {
-        cookies_allowed: YES
-        cookies_store: "user"
-        setting: "These requests cannot be disabled in settings."
-        policy_exception_justification:
-          "Not implemented. Without these requests, Chrome will be unable "
-          "to load any webpage."
-      })");
-
   if (ipc_type == blink::WebURLRequest::LoadingIPCType::kMojo) {
     scoped_refptr<base::SingleThreadTaskRunner> task_runner =
         loading_task_runner ? loading_task_runner : thread_task_runner_;
diff --git a/content/child/resource_dispatcher.h b/content/child/resource_dispatcher.h
index aea67d9..599eeac 100644
--- a/content/child/resource_dispatcher.h
+++ b/content/child/resource_dispatcher.h
@@ -29,6 +29,7 @@
 #include "ipc/ipc_sender.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "net/base/request_priority.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
 #include "third_party/WebKit/public/platform/WebURLRequest.h"
 #include "url/gurl.h"
 #include "url/origin.h"
@@ -91,6 +92,7 @@
       std::unique_ptr<ResourceRequest> request,
       int routing_id,
       const url::Origin& frame_origin,
+      const net::NetworkTrafficAnnotationTag& traffic_annotation,
       SyncLoadResponse* response,
       blink::WebURLRequest::LoadingIPCType ipc_type,
       mojom::URLLoaderFactory* url_loader_factory,
@@ -111,6 +113,7 @@
       int routing_id,
       scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner,
       const url::Origin& frame_origin,
+      const net::NetworkTrafficAnnotationTag& traffic_annotation,
       bool is_sync,
       std::unique_ptr<RequestPeer> peer,
       blink::WebURLRequest::LoadingIPCType ipc_type,
diff --git a/content/child/resource_dispatcher_unittest.cc b/content/child/resource_dispatcher_unittest.cc
index 82510673..4b16b12 100644
--- a/content/child/resource_dispatcher_unittest.cc
+++ b/content/child/resource_dispatcher_unittest.cc
@@ -37,6 +37,7 @@
 #include "net/base/net_errors.h"
 #include "net/base/request_priority.h"
 #include "net/http/http_response_headers.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
 #include "url/gurl.h"
@@ -228,7 +229,8 @@
     std::unique_ptr<TestRequestPeer> peer(
         new TestRequestPeer(dispatcher(), peer_context));
     int request_id = dispatcher()->StartAsync(
-        std::move(request), 0, nullptr, url::Origin(), false, std::move(peer),
+        std::move(request), 0, nullptr, url::Origin(),
+        TRAFFIC_ANNOTATION_FOR_TESTS, false, std::move(peer),
         blink::WebURLRequest::LoadingIPCType::kChromeIPC, nullptr,
         std::vector<std::unique_ptr<URLLoaderThrottle>>(),
         mojo::ScopedDataPipeConsumerHandle());
diff --git a/content/child/sync_load_context.cc b/content/child/sync_load_context.cc
index 08171352..3d0cf50 100644
--- a/content/child/sync_load_context.cc
+++ b/content/child/sync_load_context.cc
@@ -21,6 +21,7 @@
     std::unique_ptr<ResourceRequest> request,
     int routing_id,
     const url::Origin& frame_origin,
+    const net::NetworkTrafficAnnotationTag& traffic_annotation,
     mojom::URLLoaderFactoryPtrInfo url_loader_factory_pipe,
     std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
     SyncLoadResponse* response,
@@ -29,8 +30,9 @@
       request.get(), std::move(url_loader_factory_pipe), response, event);
 
   context->request_id_ = context->resource_dispatcher_->StartAsync(
-      std::move(request), routing_id, nullptr, frame_origin, true /* is_sync */,
-      base::WrapUnique(context), blink::WebURLRequest::LoadingIPCType::kMojo,
+      std::move(request), routing_id, nullptr, frame_origin, traffic_annotation,
+      true /* is_sync */, base::WrapUnique(context),
+      blink::WebURLRequest::LoadingIPCType::kMojo,
       context->url_loader_factory_.get(), std::move(throttles),
       mojo::ScopedDataPipeConsumerHandle());
 }
diff --git a/content/child/sync_load_context.h b/content/child/sync_load_context.h
index d2df986..d3d8e15 100644
--- a/content/child/sync_load_context.h
+++ b/content/child/sync_load_context.h
@@ -9,6 +9,7 @@
 #include "content/child/resource_dispatcher.h"
 #include "content/public/child/request_peer.h"
 #include "content/public/common/url_loader_factory.mojom.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
 
 namespace base {
 class WaitableEvent;
@@ -34,6 +35,7 @@
       std::unique_ptr<ResourceRequest> request,
       int routing_id,
       const url::Origin& frame_origin,
+      const net::NetworkTrafficAnnotationTag& traffic_annotation,
       mojom::URLLoaderFactoryPtrInfo url_loader_factory_pipe,
       std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
       SyncLoadResponse* response,
diff --git a/content/child/url_loader_client_impl_unittest.cc b/content/child/url_loader_client_impl_unittest.cc
index 16b229b9..63f50b57 100644
--- a/content/child/url_loader_client_impl_unittest.cc
+++ b/content/child/url_loader_client_impl_unittest.cc
@@ -30,7 +30,8 @@
     mojo_binding_.Bind(mojo::MakeRequest(&url_loader_factory_proxy_));
 
     request_id_ = dispatcher_->StartAsync(
-        base::MakeUnique<ResourceRequest>(), 0, nullptr, url::Origin(), false,
+        base::MakeUnique<ResourceRequest>(), 0, nullptr, url::Origin(),
+        TRAFFIC_ANNOTATION_FOR_TESTS, false,
         base::MakeUnique<TestRequestPeer>(dispatcher_.get(),
                                           &request_peer_context_),
         blink::WebURLRequest::LoadingIPCType::kMojo,
diff --git a/content/child/url_response_body_consumer_unittest.cc b/content/child/url_response_body_consumer_unittest.cc
index 0bfadb86..824e442f 100644
--- a/content/child/url_response_body_consumer_unittest.cc
+++ b/content/child/url_response_body_consumer_unittest.cc
@@ -20,6 +20,7 @@
 #include "content/public/common/resource_request_completion_status.h"
 #include "content/public/common/service_worker_modes.h"
 #include "net/base/request_priority.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 #include "url/origin.h"
@@ -137,7 +138,8 @@
   int SetUpRequestPeer(std::unique_ptr<ResourceRequest> request,
                        TestRequestPeer::Context* context) {
     return dispatcher_->StartAsync(
-        std::move(request), 0, nullptr, url::Origin(), false,
+        std::move(request), 0, nullptr, url::Origin(),
+        TRAFFIC_ANNOTATION_FOR_TESTS, false,
         base::MakeUnique<TestRequestPeer>(context, message_loop_.task_runner()),
         blink::WebURLRequest::LoadingIPCType::kChromeIPC, nullptr,
         std::vector<std::unique_ptr<URLLoaderThrottle>>(),
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc
index e1d1eae..09d8f646 100644
--- a/content/child/web_url_loader_impl.cc
+++ b/content/child/web_url_loader_impl.cc
@@ -392,6 +392,9 @@
   bool CanHandleDataURLRequestLocally(const WebURLRequest& request) const;
   void HandleDataURL();
 
+  static net::NetworkTrafficAnnotationTag GetTrafficAnnotationTag(
+      const blink::WebURLRequest& request);
+
   WebURLLoaderImpl* loader_;
 
   WebURL url_;
@@ -654,8 +657,8 @@
 
     resource_dispatcher_->StartSync(
         std::move(resource_request), request.RequestorID(),
-        extra_data->frame_origin(), sync_load_response,
-        request.GetLoadingIPCType(), url_loader_factory_,
+        extra_data->frame_origin(), GetTrafficAnnotationTag(request),
+        sync_load_response, request.GetLoadingIPCType(), url_loader_factory_,
         extra_data->TakeURLLoaderThrottles());
     return;
   }
@@ -664,7 +667,8 @@
                          TRACE_EVENT_FLAG_FLOW_OUT);
   request_id_ = resource_dispatcher_->StartAsync(
       std::move(resource_request), request.RequestorID(), task_runner_,
-      extra_data->frame_origin(), false /* is_sync */,
+      extra_data->frame_origin(), GetTrafficAnnotationTag(request),
+      false /* is_sync */,
       base::MakeUnique<WebURLLoaderImpl::RequestPeerImpl>(this),
       request.GetLoadingIPCType(), url_loader_factory_,
       extra_data->TakeURLLoaderThrottles(), std::move(consumer_handle));
@@ -998,6 +1002,116 @@
                      data.size());
 }
 
+// static
+net::NetworkTrafficAnnotationTag
+WebURLLoaderImpl::Context::GetTrafficAnnotationTag(
+    const blink::WebURLRequest& request) {
+  switch (request.GetRequestContext()) {
+    case WebURLRequest::kRequestContextUnspecified:
+    case WebURLRequest::kRequestContextAudio:
+    case WebURLRequest::kRequestContextBeacon:
+    case WebURLRequest::kRequestContextCSPReport:
+    case WebURLRequest::kRequestContextDownload:
+    case WebURLRequest::kRequestContextEventSource:
+    case WebURLRequest::kRequestContextFetch:
+    case WebURLRequest::kRequestContextFont:
+    case WebURLRequest::kRequestContextForm:
+    case WebURLRequest::kRequestContextFrame:
+    case WebURLRequest::kRequestContextHyperlink:
+    case WebURLRequest::kRequestContextIframe:
+    case WebURLRequest::kRequestContextImage:
+    case WebURLRequest::kRequestContextImageSet:
+    case WebURLRequest::kRequestContextImport:
+    case WebURLRequest::kRequestContextInternal:
+    case WebURLRequest::kRequestContextLocation:
+    case WebURLRequest::kRequestContextManifest:
+    case WebURLRequest::kRequestContextPing:
+    case WebURLRequest::kRequestContextPrefetch:
+    case WebURLRequest::kRequestContextScript:
+    case WebURLRequest::kRequestContextServiceWorker:
+    case WebURLRequest::kRequestContextSharedWorker:
+    case WebURLRequest::kRequestContextSubresource:
+    case WebURLRequest::kRequestContextStyle:
+    case WebURLRequest::kRequestContextTrack:
+    case WebURLRequest::kRequestContextVideo:
+    case WebURLRequest::kRequestContextWorker:
+    case WebURLRequest::kRequestContextXMLHttpRequest:
+    case WebURLRequest::kRequestContextXSLT:
+      return net::DefineNetworkTrafficAnnotation("blink_resource_loader", R"(
+      semantics {
+        sender: "Blink Resource Loader"
+        description:
+          "Blink-initiated request, which includes all resources for "
+          "normal page loads, chrome URLs, and downloads."
+        trigger:
+          "The user navigates to a URL or downloads a file. Also when a "
+          "webpage, ServiceWorker, or chrome:// uses any network communication."
+        data: "Anything the initiator wants to send."
+        destination: OTHER
+      }
+      policy {
+        cookies_allowed: YES
+        cookies_store: "user"
+        setting: "These requests cannot be disabled in settings."
+        policy_exception_justification:
+          "Not implemented. Without these requests, Chrome will be unable "
+          "to load any webpage."
+      })");
+
+    case WebURLRequest::kRequestContextEmbed:
+    case WebURLRequest::kRequestContextObject:
+    case WebURLRequest::kRequestContextPlugin:
+      return net::DefineNetworkTrafficAnnotation(
+          "blink_extension_resource_loader", R"(
+        semantics {
+          sender: "Blink Resource Loader"
+          description:
+            "Blink-initiated request for resources required for NaCl instances "
+            "tagged with <embed> or <object>, or installed extensions."
+          trigger:
+            "An extension or NaCl instance may initiate a request at any time, "
+            "even in the background."
+          data: "Anything the initiator wants to send."
+          destination: OTHER
+        }
+        policy {
+          cookies_allowed: YES
+          cookies_store: "user"
+          setting:
+            "These requests cannot be disabled in settings, but they are "
+            "sent only if user installs extensions."
+          chrome_policy {
+            ExtensionInstallBlacklist {
+              ExtensionInstallBlacklist: {
+                entries: '*'
+              }
+            }
+          }
+        })");
+
+    case WebURLRequest::kRequestContextFavicon:
+      return net::DefineNetworkTrafficAnnotation("favicon_loader", R"(
+        semantics {
+          sender: "Blink Resource Loader"
+          description:
+            "Chrome sends a request to download favicon for a URL."
+          trigger:
+            "Navigating to a URL."
+          data: "None."
+          destination: WEBSITE
+        }
+        policy {
+          cookies_allowed: YES
+          cookies_store: "user"
+          setting: "These requests cannot be disabled in settings."
+          policy_exception_justification:
+            "Not implemented."
+        })");
+  }
+
+  return net::NetworkTrafficAnnotationTag::NotReached();
+}
+
 // WebURLLoaderImpl::RequestPeerImpl ------------------------------------------
 
 WebURLLoaderImpl::RequestPeerImpl::RequestPeerImpl(Context* context)
diff --git a/content/child/web_url_loader_impl_unittest.cc b/content/child/web_url_loader_impl_unittest.cc
index 1cabac2..ccdaa78 100644
--- a/content/child/web_url_loader_impl_unittest.cc
+++ b/content/child/web_url_loader_impl_unittest.cc
@@ -30,6 +30,7 @@
 #include "net/base/net_errors.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "net/url_request/redirect_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/WebString.h"
@@ -71,6 +72,7 @@
       std::unique_ptr<ResourceRequest> request,
       int routing_id,
       const url::Origin& frame_origin,
+      const net::NetworkTrafficAnnotationTag& traffic_annotation,
       SyncLoadResponse* response,
       blink::WebURLRequest::LoadingIPCType ipc_type,
       mojom::URLLoaderFactory* url_loader_factory,
@@ -83,6 +85,7 @@
       int routing_id,
       scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner,
       const url::Origin& frame_origin,
+      const net::NetworkTrafficAnnotationTag& traffic_annotation,
       bool is_sync,
       std::unique_ptr<RequestPeer> peer,
       blink::WebURLRequest::LoadingIPCType ipc_type,
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 3b5f1b51..a205964 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -270,6 +270,10 @@
   return nullptr;
 }
 
+std::string ContentBrowserClient::GetGeolocationApiKey() {
+  return std::string();
+}
+
 std::string ContentBrowserClient::GetStoragePartitionIdForSite(
     BrowserContext* browser_context,
     const GURL& site) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 4734a72..8e25eacc 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -434,6 +434,12 @@
   virtual net::URLRequestContext* OverrideRequestContextForURL(
       const GURL& url, ResourceContext* context);
 
+  // Allows an embedder to provide a Google API Key to use for network
+  // geolocation queries.
+  // * May be called from any thread.
+  // * Default implementation returns empty string, meaning send no API key.
+  virtual std::string GetGeolocationApiKey();
+
   // Allow the embedder to specify a string version of the storage partition
   // config with a site.
   virtual std::string GetStoragePartitionIdForSite(
diff --git a/dbus/end_to_end_async_unittest.cc b/dbus/end_to_end_async_unittest.cc
index 2de55c3..d96ebda 100644
--- a/dbus/end_to_end_async_unittest.cc
+++ b/dbus/end_to_end_async_unittest.cc
@@ -512,32 +512,13 @@
   ASSERT_EQ(DBUS_ERROR_FAILED, error_names_[0]);
 }
 
-TEST_F(EndToEndAsyncTest, InvalidObjectPath) {
-  // Trailing '/' is only allowed for the root path.
-  const ObjectPath invalid_object_path("/org/chromium/TestObject/");
-
-  // Replace object proxy with new one.
-  object_proxy_ = bus_->GetObjectProxy(test_service_->service_name(),
-                                       invalid_object_path);
-
-  MethodCall method_call("org.chromium.TestInterface", "Echo");
-
-  const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
-  CallMethodWithErrorCallback(&method_call, timeout_ms);
-  WaitForErrors(1);
-
-  // Should fail because of the invalid path.
-  ASSERT_TRUE(response_strings_.empty());
-  ASSERT_EQ("", error_names_[0]);
-}
-
 TEST_F(EndToEndAsyncTest, InvalidServiceName) {
   // Bus name cannot contain '/'.
   const std::string invalid_service_name = ":1/2";
 
   // Replace object proxy with new one.
-  object_proxy_ = bus_->GetObjectProxy(
-      invalid_service_name, ObjectPath("org.chromium.TestObject"));
+  object_proxy_ = bus_->GetObjectProxy(invalid_service_name,
+                                       ObjectPath("/org/chromium/TestObject"));
 
   MethodCall method_call("org.chromium.TestInterface", "Echo");
 
diff --git a/dbus/end_to_end_sync_unittest.cc b/dbus/end_to_end_sync_unittest.cc
index 4eb9cd1..d0dafcc 100644
--- a/dbus/end_to_end_sync_unittest.cc
+++ b/dbus/end_to_end_sync_unittest.cc
@@ -108,29 +108,13 @@
   ASSERT_FALSE(response.get());
 }
 
-TEST_F(EndToEndSyncTest, InvalidObjectPath) {
-  // Trailing '/' is only allowed for the root path.
-  const ObjectPath invalid_object_path("/org/chromium/TestObject/");
-
-  // Replace object proxy with new one.
-  object_proxy_ = client_bus_->GetObjectProxy(test_service_->service_name(),
-                                              invalid_object_path);
-
-  MethodCall method_call("org.chromium.TestInterface", "Echo");
-
-  const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
-  std::unique_ptr<Response> response(
-      object_proxy_->CallMethodAndBlock(&method_call, timeout_ms));
-  ASSERT_FALSE(response.get());
-}
-
 TEST_F(EndToEndSyncTest, InvalidServiceName) {
   // Bus name cannot contain '/'.
   const std::string invalid_service_name = ":1/2";
 
   // Replace object proxy with new one.
   object_proxy_ = client_bus_->GetObjectProxy(
-      invalid_service_name, ObjectPath("org.chromium.TestObject"));
+      invalid_service_name, ObjectPath("/org/chromium/TestObject"));
 
   MethodCall method_call("org.chromium.TestInterface", "Echo");
 
diff --git a/dbus/exported_object.cc b/dbus/exported_object.cc
index 2047f3f..47d0660 100644
--- a/dbus/exported_object.cc
+++ b/dbus/exported_object.cc
@@ -34,6 +34,7 @@
     : bus_(bus),
       object_path_(object_path),
       object_is_registered_(false) {
+  LOG_IF(FATAL, !object_path_.IsValid()) << object_path_.value();
 }
 
 ExportedObject::~ExportedObject() {
diff --git a/dbus/message.cc b/dbus/message.cc
index 9505dbb4..ec0b2234 100644
--- a/dbus/message.cc
+++ b/dbus/message.cc
@@ -459,7 +459,7 @@
   // dbus_message_iter_append_basic() used in AppendBasic() expects four
   // bytes for DBUS_TYPE_BOOLEAN, so we must pass a dbus_bool_t, instead
   // of a bool, to AppendBasic().
-  dbus_bool_t dbus_value = value;
+  dbus_bool_t dbus_value = value ? 1 : 0;
   AppendBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
 }
 
diff --git a/dbus/object_manager.cc b/dbus/object_manager.cc
index 3a39cd6..cdcd63a 100644
--- a/dbus/object_manager.cc
+++ b/dbus/object_manager.cc
@@ -38,6 +38,7 @@
       setup_success_(false),
       cleanup_called_(false),
       weak_ptr_factory_(this) {
+  LOG_IF(FATAL, !object_path_.IsValid()) << object_path_.value();
   DVLOG(1) << "Creating ObjectManager for " << service_name_
            << " " << object_path_.value();
   DCHECK(bus_);
diff --git a/dbus/object_proxy.cc b/dbus/object_proxy.cc
index 729df1f..4d4ef121 100644
--- a/dbus/object_proxy.cc
+++ b/dbus/object_proxy.cc
@@ -62,6 +62,7 @@
       object_path_(object_path),
       ignore_service_unknown_errors_(
           options & IGNORE_SERVICE_UNKNOWN_ERRORS) {
+  LOG_IF(FATAL, !object_path_.IsValid()) << object_path_.value();
 }
 
 ObjectProxy::~ObjectProxy() {
diff --git a/device/geolocation/BUILD.gn b/device/geolocation/BUILD.gn
index 4539c83..0d865cbc 100644
--- a/device/geolocation/BUILD.gn
+++ b/device/geolocation/BUILD.gn
@@ -64,7 +64,6 @@
 
   deps = [
     "//base",
-    "//google_apis:google_apis",
     "//mojo/edk/system",
     "//mojo/public/cpp/bindings",
     "//net",
diff --git a/device/geolocation/DEPS b/device/geolocation/DEPS
index 70aa741..d3e3a8c 100644
--- a/device/geolocation/DEPS
+++ b/device/geolocation/DEPS
@@ -1,7 +1,6 @@
 include_rules = [
   "+chromeos",
   "+dbus",
-  "+google_apis",
   "+jni",
   "+net",
   "+third_party/cros_system_api/dbus",
diff --git a/device/geolocation/geolocation_provider.h b/device/geolocation/geolocation_provider.h
index 07f58fe4..a9d95c9 100644
--- a/device/geolocation/geolocation_provider.h
+++ b/device/geolocation/geolocation_provider.h
@@ -30,9 +30,15 @@
   DEVICE_GEOLOCATION_EXPORT static GeolocationProvider* GetInstance();
 
   // Optional: provide a Delegate to override typical services.
+  // Call before using Init() on the singleton GetInstance(), and call no more
+  // than once.
   DEVICE_GEOLOCATION_EXPORT static void SetGeolocationDelegate(
       GeolocationDelegate* delegate);
 
+  // Optional: Provide a Google API key for network geolocation requests.
+  // Call before using Init() on the singleton GetInstance().
+  DEVICE_GEOLOCATION_EXPORT static void SetApiKey(const std::string& api_key);
+
   typedef base::Callback<void(const Geoposition&)> LocationUpdateCallback;
   typedef base::CallbackList<void(const Geoposition&)>::Subscription
       Subscription;
diff --git a/device/geolocation/geolocation_provider_impl.cc b/device/geolocation/geolocation_provider_impl.cc
index 3ea97c9..4f4773c 100644
--- a/device/geolocation/geolocation_provider_impl.cc
+++ b/device/geolocation/geolocation_provider_impl.cc
@@ -24,7 +24,8 @@
 namespace {
 base::LazyInstance<std::unique_ptr<GeolocationDelegate>>::Leaky g_delegate =
     LAZY_INSTANCE_INITIALIZER;
-}  // anonymous namespace
+base::LazyInstance<std::string>::Leaky g_api_key = LAZY_INSTANCE_INITIALIZER;
+}  // namespace
 
 // static
 GeolocationProvider* GeolocationProvider::GetInstance() {
@@ -38,6 +39,11 @@
   g_delegate.Get().reset(delegate);
 }
 
+// static
+void GeolocationProvider::SetApiKey(const std::string& api_key) {
+  g_api_key.Get() = api_key;
+}
+
 std::unique_ptr<GeolocationProvider::Subscription>
 GeolocationProviderImpl::AddLocationUpdateCallback(
     const LocationUpdateCallback& callback,
@@ -187,17 +193,18 @@
 void GeolocationProviderImpl::Init() {
   DCHECK(OnGeolocationThread());
 
-  if (!arbitrator_) {
-    LocationProvider::LocationProviderUpdateCallback callback = base::Bind(
-        &GeolocationProviderImpl::OnLocationUpdate, base::Unretained(this));
-    // Use the embedder's |g_delegate| or fall back to the default one.
-    if (!g_delegate.Get())
-      g_delegate.Get().reset(new GeolocationDelegate);
+  if (arbitrator_)
+    return;
 
-    arbitrator_ = std::make_unique<LocationArbitrator>(
-        base::WrapUnique(g_delegate.Get().get()));
-    arbitrator_->SetUpdateCallback(callback);
-  }
+  LocationProvider::LocationProviderUpdateCallback callback = base::Bind(
+      &GeolocationProviderImpl::OnLocationUpdate, base::Unretained(this));
+  // Use the embedder's |g_delegate| or fall back to the default one.
+  if (!g_delegate.Get())
+    g_delegate.Get().reset(new GeolocationDelegate);
+
+  arbitrator_ = std::make_unique<LocationArbitrator>(
+      base::WrapUnique(g_delegate.Get().get()), g_api_key.Get());
+  arbitrator_->SetUpdateCallback(callback);
 }
 
 void GeolocationProviderImpl::CleanUp() {
diff --git a/device/geolocation/location_arbitrator.cc b/device/geolocation/location_arbitrator.cc
index ad02d19..4d221eb 100644
--- a/device/geolocation/location_arbitrator.cc
+++ b/device/geolocation/location_arbitrator.cc
@@ -15,14 +15,8 @@
 #include "device/geolocation/access_token_store.h"
 #include "device/geolocation/geolocation_delegate.h"
 #include "device/geolocation/network_location_provider.h"
-#include "url/gurl.h"
 
 namespace device {
-namespace {
-
-const char* kDefaultNetworkProviderUrl =
-    "https://www.googleapis.com/geolocation/v1/geolocate";
-}  // namespace
 
 // To avoid oscillations, set this to twice the expected update interval of a
 // a GPS-type location provider (in case it misses a beat) plus a little.
@@ -30,18 +24,16 @@
     11 * base::Time::kMillisecondsPerSecond;
 
 LocationArbitrator::LocationArbitrator(
-    std::unique_ptr<GeolocationDelegate> delegate)
+    std::unique_ptr<GeolocationDelegate> delegate,
+    const std::string& api_key)
     : delegate_(std::move(delegate)),
+      api_key_(api_key),
       position_provider_(nullptr),
       is_permission_granted_(false),
       is_running_(false) {}
 
 LocationArbitrator::~LocationArbitrator() {}
 
-GURL LocationArbitrator::DefaultNetworkProviderURL() {
-  return GURL(kDefaultNetworkProviderUrl);
-}
-
 bool LocationArbitrator::HasPermissionBeenGrantedForTest() const {
   return is_permission_granted_;
 }
@@ -65,7 +57,6 @@
     const scoped_refptr<AccessTokenStore> access_token_store =
         GetAccessTokenStore();
     if (access_token_store) {
-      DCHECK(DefaultNetworkProviderURL().is_valid());
       token_store_callback_.Reset(
           base::Bind(&LocationArbitrator::OnAccessTokenStoresLoaded,
                      base::Unretained(this)));
@@ -106,13 +97,8 @@
 void LocationArbitrator::OnAccessTokenStoresLoaded(
     AccessTokenStore::AccessTokenMap access_token_map,
     const scoped_refptr<net::URLRequestContextGetter>& context_getter) {
-  // If there are no access tokens, boot strap it with the default server URL.
-  if (access_token_map.empty())
-    access_token_map[DefaultNetworkProviderURL()];
-  for (const auto& entry : access_token_map) {
-    RegisterProvider(NewNetworkLocationProvider(
-        GetAccessTokenStore(), context_getter, entry.first, entry.second));
-  }
+  // Create a NetworkLocationProvider using the provided request context.
+  RegisterProvider(NewNetworkLocationProvider(context_getter, api_key_));
   DoStartProviders();
 }
 
@@ -169,15 +155,13 @@
 
 std::unique_ptr<LocationProvider>
 LocationArbitrator::NewNetworkLocationProvider(
-    const scoped_refptr<AccessTokenStore>& access_token_store,
     const scoped_refptr<net::URLRequestContextGetter>& context,
-    const GURL& url,
-    const base::string16& access_token) {
+    const std::string& api_key) {
 #if defined(OS_ANDROID)
   // Android uses its own SystemLocationProvider.
   return nullptr;
 #else
-  return std::make_unique<NetworkLocationProvider>(context, url);
+  return std::make_unique<NetworkLocationProvider>(context, api_key);
 #endif
 }
 
diff --git a/device/geolocation/location_arbitrator.h b/device/geolocation/location_arbitrator.h
index 343d366..122973e 100644
--- a/device/geolocation/location_arbitrator.h
+++ b/device/geolocation/location_arbitrator.h
@@ -40,7 +40,8 @@
   // (regardles of relative accuracy). Public for tests.
   static const int64_t kFixStaleTimeoutMilliseconds;
 
-  explicit LocationArbitrator(std::unique_ptr<GeolocationDelegate> delegate);
+  LocationArbitrator(std::unique_ptr<GeolocationDelegate> delegate,
+                     const std::string& api_key);
   ~LocationArbitrator() override;
 
   static GURL DefaultNetworkProviderURL();
@@ -59,10 +60,8 @@
   // testing classes.
   virtual scoped_refptr<AccessTokenStore> NewAccessTokenStore();
   virtual std::unique_ptr<LocationProvider> NewNetworkLocationProvider(
-      const scoped_refptr<AccessTokenStore>& access_token_store,
       const scoped_refptr<net::URLRequestContextGetter>& context,
-      const GURL& url,
-      const base::string16& access_token);
+      const std::string& api_key);
   virtual std::unique_ptr<LocationProvider> NewSystemLocationProvider();
   virtual base::Time GetTimeNow() const;
 
@@ -92,7 +91,8 @@
                            const Geoposition& new_position,
                            bool from_same_provider) const;
 
-  std::unique_ptr<GeolocationDelegate> delegate_;
+  const std::unique_ptr<GeolocationDelegate> delegate_;
+  const std::string api_key_;
 
   scoped_refptr<AccessTokenStore> access_token_store_;
   LocationProvider::LocationProviderUpdateCallback arbitrator_update_callback_;
diff --git a/device/geolocation/location_arbitrator_unittest.cc b/device/geolocation/location_arbitrator_unittest.cc
index 4353b3cf..ea4ee5c 100644
--- a/device/geolocation/location_arbitrator_unittest.cc
+++ b/device/geolocation/location_arbitrator_unittest.cc
@@ -113,17 +113,17 @@
  public:
   TestingLocationArbitrator(const LocationProviderUpdateCallback& callback,
                             std::unique_ptr<GeolocationDelegate> delegate)
-      : LocationArbitrator(std::move(delegate)), cell_(nullptr), gps_(nullptr) {
+      : LocationArbitrator(std::move(delegate), std::string() /* api_key */),
+        cell_(nullptr),
+        gps_(nullptr) {
     SetUpdateCallback(callback);
   }
 
   base::Time GetTimeNow() const override { return GetTimeNowForTest(); }
 
   std::unique_ptr<LocationProvider> NewNetworkLocationProvider(
-      const scoped_refptr<AccessTokenStore>& access_token_store,
       const scoped_refptr<net::URLRequestContextGetter>& context,
-      const GURL& url,
-      const base::string16& access_token) override {
+      const std::string& api_key) override {
     cell_ = new FakeLocationProvider;
     return base::WrapUnique(cell_);
   }
diff --git a/device/geolocation/network_location_provider.cc b/device/geolocation/network_location_provider.cc
index d22b5767..9f7e93d 100644
--- a/device/geolocation/network_location_provider.cc
+++ b/device/geolocation/network_location_provider.cc
@@ -91,17 +91,10 @@
   return !key->empty();
 }
 
-// NetworkLocationProvider factory function
-LocationProvider* NewNetworkLocationProvider(
-    const scoped_refptr<net::URLRequestContextGetter>& context,
-    const GURL& url) {
-  return new NetworkLocationProvider(context, url);
-}
-
 // NetworkLocationProvider
 NetworkLocationProvider::NetworkLocationProvider(
     const scoped_refptr<net::URLRequestContextGetter>& url_context_getter,
-    const GURL& url)
+    const std::string& api_key)
     : wifi_data_provider_manager_(nullptr),
       wifi_data_update_callback_(
           base::Bind(&NetworkLocationProvider::OnWifiDataUpdate,
@@ -111,7 +104,7 @@
       is_new_data_available_(false),
       request_(new NetworkLocationRequest(
           url_context_getter,
-          url,
+          api_key,
           base::Bind(&NetworkLocationProvider::OnLocationResponse,
                      base::Unretained(this)))),
       position_cache_(new PositionCache),
diff --git a/device/geolocation/network_location_provider.h b/device/geolocation/network_location_provider.h
index 884924a..a43b698 100644
--- a/device/geolocation/network_location_provider.h
+++ b/device/geolocation/network_location_provider.h
@@ -61,9 +61,9 @@
     CacheAgeList cache_age_list_;  // Oldest first.
   };
 
-  NetworkLocationProvider(
+  DEVICE_GEOLOCATION_EXPORT NetworkLocationProvider(
       const scoped_refptr<net::URLRequestContextGetter>& context,
-      const GURL& url);
+      const std::string& api_key);
   ~NetworkLocationProvider() override;
 
   // LocationProvider implementation
@@ -111,7 +111,7 @@
 
   bool is_new_data_available_;
 
-  // The network location request object, and the url it uses.
+  // The network location request object.
   const std::unique_ptr<NetworkLocationRequest> request_;
 
   // The cache of positions.
@@ -124,12 +124,6 @@
   DISALLOW_COPY_AND_ASSIGN(NetworkLocationProvider);
 };
 
-// Factory functions for the various types of location provider to abstract
-// over the platform-dependent implementations.
-DEVICE_GEOLOCATION_EXPORT LocationProvider* NewNetworkLocationProvider(
-    const scoped_refptr<net::URLRequestContextGetter>& context,
-    const GURL& url);
-
 }  // namespace device
 
 #endif  // DEVICE_GEOLOCATION_NETWORK_LOCATION_PROVIDER_H_
diff --git a/device/geolocation/network_location_provider_unittest.cc b/device/geolocation/network_location_provider_unittest.cc
index feb60b1..f150db0 100644
--- a/device/geolocation/network_location_provider_unittest.cc
+++ b/device/geolocation/network_location_provider_unittest.cc
@@ -30,9 +30,6 @@
 
 namespace device {
 
-// Constants used in multiple tests.
-const char kTestServerUrl[] = "https://www.geolocation.test/service";
-
 // Stops the specified (nested) message loop when the listener is called back.
 class MessageLoopQuitListener {
  public:
@@ -116,10 +113,11 @@
     WifiDataProviderManager::ResetFactoryForTesting();
   }
 
-  LocationProvider* CreateProvider(bool set_permission_granted) {
-    LocationProvider* provider = NewNetworkLocationProvider(
-        nullptr,  // No URLContextGetter needed, using test urlfecther factory.
-        test_server_url_);
+  LocationProvider* CreateProvider(bool set_permission_granted,
+                                   const std::string& api_key = std::string()) {
+    // No URLContextGetter needed: The request within the provider is tested
+    // directly using TestURLFetcherFactory.
+    LocationProvider* provider = new NetworkLocationProvider(nullptr, api_key);
     if (set_permission_granted)
       provider->OnPermissionGranted();
     return provider;
@@ -127,8 +125,7 @@
 
  protected:
   GeolocationNetworkProviderTest()
-      : test_server_url_(kTestServerUrl),
-        wifi_data_provider_(MockWifiDataProvider::CreateInstance()) {
+      : wifi_data_provider_(MockWifiDataProvider::CreateInstance()) {
     // TODO(joth): Really these should be in SetUp, not here, but they take no
     // effect on Mac OS Release builds if done there. I kid not. Figure out why.
     WifiDataProviderManager::SetFactoryForTesting(
@@ -228,20 +225,6 @@
     return testing::AssertionSuccess();
   }
 
-  static GURL UrlWithoutQuery(const GURL& url) {
-    url::Replacements<char> replacements;
-    replacements.ClearQuery();
-    return url.ReplaceComponents(replacements);
-  }
-
-  testing::AssertionResult IsTestServerUrl(const GURL& request_url) {
-    const GURL a(UrlWithoutQuery(test_server_url_));
-    const GURL b(UrlWithoutQuery(request_url));
-    if (a == b)
-      return testing::AssertionSuccess();
-    return testing::AssertionFailure() << a << " != " << b;
-  }
-
   // Checks that |request| contains valid JSON upload data. The Wifi access
   // points specified in the JSON are validated against the first
   // |expected_wifi_aps| access points, starting from position
@@ -249,17 +232,6 @@
   void CheckRequestIsValid(const net::TestURLFetcher& request,
                            int expected_wifi_aps,
                            int wifi_start_index) {
-    const GURL& request_url = request.GetOriginalURL();
-
-    EXPECT_TRUE(IsTestServerUrl(request_url));
-
-    // Check to see that the api key is being appended for the default
-    // network provider url.
-    bool is_default_url =
-        UrlWithoutQuery(request_url) ==
-        UrlWithoutQuery(LocationArbitrator::DefaultNetworkProviderURL());
-    EXPECT_EQ(is_default_url, !request_url.query().empty());
-
     const std::string& upload_data = request.upload_data();
     ASSERT_FALSE(upload_data.empty());
     std::string json_parse_error_msg;
@@ -297,10 +269,8 @@
     } else {
       ASSERT_FALSE(request_json->HasKey("wifiAccessPoints"));
     }
-    EXPECT_TRUE(request_url.is_valid());
   }
 
-  GURL test_server_url_;
   const base::MessageLoop main_message_loop_;
   const net::TestURLFetcherFactory url_fetcher_factory_;
   const scoped_refptr<MockWifiDataProvider> wifi_data_provider_;
@@ -315,20 +285,32 @@
   SUCCEED();
 }
 
-// Tests that, after StartProvider(), a TestURLFetcher can be extracted,
-// representing a valid request.
-TEST_F(GeolocationNetworkProviderTest, StartProvider) {
-  std::unique_ptr<LocationProvider> provider(CreateProvider(true));
+// Tests that, with an empty api_key, no query string parameter is included in
+// the request.
+TEST_F(GeolocationNetworkProviderTest, EmptyApiKey) {
+  const std::string api_key = "";
+  std::unique_ptr<LocationProvider> provider(CreateProvider(true, api_key));
   EXPECT_TRUE(provider->StartProvider(false));
   net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id();
   ASSERT_TRUE(fetcher);
-  CheckRequestIsValid(*fetcher, 0, 0);
+  EXPECT_FALSE(fetcher->GetOriginalURL().has_query());
 }
 
-// Tests StartProvider() in the special case that the endpoint URL is the
-// DefaultNetworkProviderURL.
-TEST_F(GeolocationNetworkProviderTest, StartProviderDefaultUrl) {
-  test_server_url_ = LocationArbitrator::DefaultNetworkProviderURL();
+// Tests that, with non-empty api_key, a "key" query string parameter is
+// included in the request.
+TEST_F(GeolocationNetworkProviderTest, NonEmptyApiKey) {
+  const std::string api_key = "something";
+  std::unique_ptr<LocationProvider> provider(CreateProvider(true, api_key));
+  EXPECT_TRUE(provider->StartProvider(false));
+  net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id();
+  ASSERT_TRUE(fetcher);
+  EXPECT_TRUE(fetcher->GetOriginalURL().has_query());
+  EXPECT_TRUE(fetcher->GetOriginalURL().query_piece().starts_with("key="));
+}
+
+// Tests that, after StartProvider(), a TestURLFetcher can be extracted,
+// representing a valid request.
+TEST_F(GeolocationNetworkProviderTest, StartProvider) {
   std::unique_ptr<LocationProvider> provider(CreateProvider(true));
   EXPECT_TRUE(provider->StartProvider(false));
   net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id();
@@ -371,14 +353,12 @@
 
   net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id();
   ASSERT_TRUE(fetcher);
-  EXPECT_TRUE(IsTestServerUrl(fetcher->GetOriginalURL()));
 
   // 1. Complete the network request with bad position fix.
   const char* kNoFixNetworkResponse =
       "{"
       "  \"status\": \"ZERO_RESULTS\""
       "}";
-  fetcher->set_url(test_server_url_);
   fetcher->set_status(net::URLRequestStatus());
   fetcher->set_response_code(200);  // OK
   fetcher->SetResponseString(kNoFixNetworkResponse);
@@ -405,7 +385,6 @@
       "    \"lng\": -0.1"
       "  }"
       "}";
-  fetcher->set_url(test_server_url_);
   fetcher->set_status(net::URLRequestStatus());
   fetcher->set_response_code(200);  // OK
   fetcher->SetResponseString(kReferenceNetworkResponse);
@@ -440,7 +419,6 @@
   CheckRequestIsValid(*fetcher, kThirdScanAps, 0);
 
   // 6. ...reply with a network error.
-  fetcher->set_url(test_server_url_);
   fetcher->set_status(net::URLRequestStatus::FromError(net::ERR_FAILED));
   fetcher->set_response_code(200);  // should be ignored
   fetcher->SetResponseString(std::string());
@@ -511,8 +489,6 @@
 
   fetcher = get_url_fetcher_and_advance_id();
   ASSERT_TRUE(fetcher);
-
-  EXPECT_TRUE(IsTestServerUrl(fetcher->GetOriginalURL()));
 }
 
 // Tests that, even if new Wifi data arrives, the provider doesn't initiate its
diff --git a/device/geolocation/network_location_request.cc b/device/geolocation/network_location_request.cc
index e3c2025..7d424fa 100644
--- a/device/geolocation/network_location_request.cc
+++ b/device/geolocation/network_location_request.cc
@@ -21,7 +21,6 @@
 #include "base/values.h"
 #include "device/geolocation/geoposition.h"
 #include "device/geolocation/location_arbitrator.h"
-#include "google_apis/google_api_keys.h"
 #include "net/base/escape.h"
 #include "net/base/load_flags.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
@@ -32,6 +31,9 @@
 namespace device {
 namespace {
 
+const char kNetworkLocationBaseUrl[] =
+    "https://www.googleapis.com/geolocation/v1/geolocate";
+
 const char kLocationString[] = "location";
 const char kLatitudeString[] = "lat";
 const char kLongitudeString[] = "lng";
@@ -72,8 +74,11 @@
 }
 
 // Local functions
-// Creates the request url to send to the server.
-GURL FormRequestURL(const GURL& url);
+
+// Returns a URL for a request to the Google Maps geolocation API. If the
+// specified |api_key| is not empty, it is escaped and included as a query
+// string parameter.
+GURL FormRequestURL(const std::string& api_key);
 
 void FormUploadData(const WifiData& wifi_data,
                     const base::Time& wifi_timestamp,
@@ -103,11 +108,11 @@
 
 NetworkLocationRequest::NetworkLocationRequest(
     const scoped_refptr<net::URLRequestContextGetter>& context,
-    const GURL& url,
+    const std::string& api_key,
     LocationResponseCallback callback)
-    : url_context_(context), location_response_callback_(callback), url_(url) {
-  DCHECK(url.is_valid());
-}
+    : url_context_(context),
+      api_key_(api_key),
+      location_response_callback_(callback) {}
 
 NetworkLocationRequest::~NetworkLocationRequest() {}
 
@@ -123,7 +128,6 @@
   wifi_data_ = wifi_data;
   wifi_timestamp_ = wifi_timestamp;
 
-  GURL request_url = FormRequestURL(url_);
   net::NetworkTrafficAnnotationTag traffic_annotation =
       net::DefineNetworkTrafficAnnotation("device_geolocation_request", R"(
         semantics {
@@ -148,6 +152,8 @@
             }
           }
         })");
+  const GURL request_url = FormRequestURL(api_key_);
+  DCHECK(request_url.is_valid());
   url_fetcher_ =
       net::URLFetcher::Create(url_fetcher_id_for_tests, request_url,
                               net::URLFetcher::POST, this, traffic_annotation);
@@ -204,18 +210,16 @@
   }
 };
 
-GURL FormRequestURL(const GURL& url) {
-  if (url == LocationArbitrator::DefaultNetworkProviderURL()) {
-    std::string api_key = google_apis::GetAPIKey();
-    if (!api_key.empty()) {
-      std::string query(url.query());
-      if (!query.empty())
-        query += "&";
-      query += "key=" + net::EscapeQueryParamValue(api_key, true);
-      GURL::Replacements replacements;
-      replacements.SetQueryStr(query);
-      return url.ReplaceComponents(replacements);
-    }
+GURL FormRequestURL(const std::string& api_key) {
+  GURL url(kNetworkLocationBaseUrl);
+  if (!api_key.empty()) {
+    std::string query(url.query());
+    if (!query.empty())
+      query += "&";
+    query += "key=" + net::EscapeQueryParamValue(api_key, true);
+    GURL::Replacements replacements;
+    replacements.SetQueryStr(query);
+    return url.ReplaceComponents(replacements);
   }
   return url;
 }
diff --git a/device/geolocation/network_location_request.h b/device/geolocation/network_location_request.h
index 8215101..c58529d 100644
--- a/device/geolocation/network_location_request.h
+++ b/device/geolocation/network_location_request.h
@@ -39,10 +39,9 @@
                               const WifiData& /* wifi_data */)>
       LocationResponseCallback;
 
-  // |url| is the server address to which the request wil be sent.
   NetworkLocationRequest(
       const scoped_refptr<net::URLRequestContextGetter>& context,
-      const GURL& url,
+      const std::string& api_key,
       LocationResponseCallback callback);
   ~NetworkLocationRequest() override;
 
@@ -51,15 +50,14 @@
   bool MakeRequest(const WifiData& wifi_data, const base::Time& wifi_timestamp);
 
   bool is_request_pending() const { return url_fetcher_ != NULL; }
-  const GURL& url() const { return url_; }
 
  private:
   // net::URLFetcherDelegate
   void OnURLFetchComplete(const net::URLFetcher* source) override;
 
   const scoped_refptr<net::URLRequestContextGetter> url_context_;
+  const std::string api_key_;
   const LocationResponseCallback location_response_callback_;
-  const GURL url_;
   std::unique_ptr<net::URLFetcher> url_fetcher_;
 
   // Keep a copy of the data sent in the request, so we can refer back to it
diff --git a/ios/tools/coverage/coverage.py b/ios/tools/coverage/coverage.py
index 05436f0..c1bdb1a 100755
--- a/ios/tools/coverage/coverage.py
+++ b/ios/tools/coverage/coverage.py
@@ -37,6 +37,7 @@
 import json
 import os
 import subprocess
+import webbrowser
 
 BUILD_DIRECTORY = 'out/Coverage-iphonesimulator'
 DEFAULT_GOMA_JOBS = 50
@@ -211,6 +212,30 @@
     return self._coverage[path]['total'], self._coverage[path]['executed']
 
 
+def _GenerateLineByLineFileCoverageInHtml(
+    target, profdata_path, file_line_coverage_report, output_dir):
+  """Generate per file line-by-line coverage in html using 'llvm-cov show'.
+
+  For a file with absolute path /a/b/x.cc, a html report is generated as:
+  output_dir/a/b/x.cc.html. An index html file is also generated as:
+  output_dir/index.html.
+
+  Args:
+    target: A string representing the name of the target to be tested.
+    profdata_path: A string representing the path to the profdata file.
+    file_line_coverage_report: A FileLineCoverageReport object.
+    output_dir: output directory for generated html files.
+  """
+  application_path = _GetApplicationBundlePath(target)
+  binary_path = os.path.join(application_path, target)
+  cmd = ['xcrun', 'llvm-cov', 'show', '-instr-profile', profdata_path,
+         '-arch=x86_64', binary_path, '-format=html', '-show-expansions']
+  cmd.append('-output-dir=' + output_dir)
+  cmd.extend(file_line_coverage_report.GetListOfFiles())
+
+  subprocess.check_call(cmd)
+
+
 def _CreateCoverageProfileDataForTarget(target, jobs_count=None,
                                         gtest_filter=None):
   """Builds and runs target to generate the coverage profile data.
@@ -716,6 +741,9 @@
                           help='Skip building test target and running tests '
                                'and re-use the specified profile data file.')
 
+  arg_parser.add_argument('-o', '--output-dir', type=str, required=True,
+                          help='Output directory for html report.')
+
   arg_parser.add_argument('--gtest_filter', type=str,
                           help='Only run unit tests whose full name matches '
                                'the filter.')
@@ -795,6 +823,13 @@
       top_level_dir)
   _PrintLineCoverageStats(total, executed)
 
+  _GenerateLineByLineFileCoverageInHtml(
+      target, profdata_path, file_line_coverage_report, args.output_dir)
+
+  html_index_file_path = 'file://' + os.path.abspath(
+      os.path.join(args.output_dir, 'index.html'))
+  webbrowser.open(html_index_file_path)
+
 
 if __name__ == '__main__':
   sys.exit(Main())
diff --git a/media/midi/BUILD.gn b/media/midi/BUILD.gn
index 22649bf..e69fe0d 100644
--- a/media/midi/BUILD.gn
+++ b/media/midi/BUILD.gn
@@ -154,17 +154,6 @@
     }
   }
 
-  if (is_chromeos) {
-    # CrOS version can be used with target_os="chromeos" on Linux.
-    # MIDI Service client library should be added here. We would have a separate
-    # build flag, use_midis, to use the real MIDI Service on Chrome OS device
-    # builds, and add a mocked service for unit tests to run on Linux.
-    sources += [
-      "chromeos/midi_manager_cros.cc",
-      "chromeos/midi_manager_cros.h",
-    ]
-  }
-
   if (use_alsa && use_udev) {
     deps += [
       "//crypto",
diff --git a/media/midi/chromeos/midi_manager_cros.cc b/media/midi/chromeos/midi_manager_cros.cc
deleted file mode 100644
index b554e0ab..0000000
--- a/media/midi/chromeos/midi_manager_cros.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2017 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 "media/midi/chromeos/midi_manager_cros.h"
-
-#include "media/midi/midi_manager_alsa.h"
-#include "media/midi/midi_switches.h"
-
-namespace midi {
-
-MidiManagerCros::MidiManagerCros(MidiService* service) : MidiManager(service) {}
-
-MidiManagerCros::~MidiManagerCros() = default;
-
-MidiManager* MidiManager::Create(MidiService* service) {
-  // Note: Because of crbug.com/719489, chrome://flags does not affect
-  // base::FeatureList::IsEnabled when you build target_os="chromeos" on Linux.
-  if (base::FeatureList::IsEnabled(features::kMidiManagerCros))
-    return new MidiManagerCros(service);
-  return new MidiManagerAlsa(service);
-}
-
-}  // namespace midi
diff --git a/media/midi/chromeos/midi_manager_cros.h b/media/midi/chromeos/midi_manager_cros.h
deleted file mode 100644
index 4a8f94a..0000000
--- a/media/midi/chromeos/midi_manager_cros.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 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 MEDIA_MIDI_CHROMEOS_MIDI_MANAGER_CROS_H_
-#define MEDIA_MIDI_CHROMEOS_MIDI_MANAGER_CROS_H_
-
-#include "media/midi/midi_export.h"
-#include "media/midi/midi_manager.h"
-
-namespace midi {
-
-class MIDI_EXPORT MidiManagerCros final : public MidiManager {
- public:
-  explicit MidiManagerCros(MidiService* service);
-  ~MidiManagerCros() override;
-
-  DISALLOW_COPY_AND_ASSIGN(MidiManagerCros);
-};
-
-}  // namespace midi
-
-#endif  // MEDIA_MIDI_CHROMEOS_MIDI_MANAGER_CROS_H_
diff --git a/media/midi/midi_manager_alsa.cc b/media/midi/midi_manager_alsa.cc
index 8810a14..5bd03f8a 100644
--- a/media/midi/midi_manager_alsa.cc
+++ b/media/midi/midi_manager_alsa.cc
@@ -1383,10 +1383,8 @@
   return ScopedSndMidiEventPtr(coder);
 }
 
-#if !defined(OS_CHROMEOS)
 MidiManager* MidiManager::Create(MidiService* service) {
   return new MidiManagerAlsa(service);
 }
-#endif
 
 }  // namespace midi
diff --git a/media/midi/midi_switches.cc b/media/midi/midi_switches.cc
index c64c544..96e7974b 100644
--- a/media/midi/midi_switches.cc
+++ b/media/midi/midi_switches.cc
@@ -18,11 +18,6 @@
                                       base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if defined(OS_CHROMEOS)
-const base::Feature kMidiManagerCros{"MidiManagerCros",
-                                     base::FEATURE_DISABLED_BY_DEFAULT};
-#endif
-
 const base::Feature kMidiManagerDynamicInstantiation{
     "MidiManagerDynamicInstantiation", base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/media/midi/midi_switches.h b/media/midi/midi_switches.h
index e6b3526..b5e45b0 100644
--- a/media/midi/midi_switches.h
+++ b/media/midi/midi_switches.h
@@ -22,10 +22,6 @@
 MIDI_EXPORT extern const base::Feature kMidiManagerWinrt;
 #endif
 
-#if defined(OS_CHROMEOS)
-MIDI_EXPORT extern const base::Feature kMidiManagerCros;
-#endif
-
 MIDI_EXPORT extern const base::Feature kMidiManagerDynamicInstantiation;
 
 }  // namespace features
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
index b60014a..262978b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any-expected.txt
@@ -1,6 +1,6 @@
 This is a testharness.js-based test.
 PASS CORS that succeeds with credentials: false; method: GET (allowed: get); header: X-Test,1 (allowed: x-test)
-FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+PASS CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test)
 FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *)
 PASS CORS that fails with credentials: true; method: PUT (allowed: *); header:  (allowed: )
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
index b60014a..262978b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/cors/cors-preflight-star.any.worker-expected.txt
@@ -1,6 +1,6 @@
 This is a testharness.js-based test.
 PASS CORS that succeeds with credentials: false; method: GET (allowed: get); header: X-Test,1 (allowed: x-test)
-FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+PASS CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test)
 FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
 PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *)
 PASS CORS that fails with credentials: true; method: PUT (allowed: *); header:  (allowed: )
diff --git a/third_party/WebKit/Source/build/scripts/make_event_factory.py b/third_party/WebKit/Source/build/scripts/make_event_factory.py
index 8cac11b0..456a86d5 100755
--- a/third_party/WebKit/Source/build/scripts/make_event_factory.py
+++ b/third_party/WebKit/Source/build/scripts/make_event_factory.py
@@ -151,16 +151,8 @@
             # Avoid duplicate includes.
             if cpp_name in includes:
                 continue
-            if self.suffix == 'Modules':
-                subdir_name = 'modules'
-            else:
-                subdir_name = 'core'
-            binding_name = self.get_file_basename('V8' + name_utilities.script_name(entry))
-            includes[cpp_name] = '#include "%(path)s"\n#include "bindings/%(subdir_name)s/v8/%(binding_name)s.h"' % {
-                'binding_name': binding_name,
-                'path': self._headers_header_include_path(entry),
-                'subdir_name': subdir_name,
-            }
+            includes[cpp_name] = ('#include "%s"' %
+                                  self._headers_header_include_path(entry))
         return includes.values()
 
     def generate_headers_header(self):
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp
index 306932f..876cdb5 100644
--- a/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -2417,6 +2417,7 @@
 ShadowRoot* Element::attachShadow(const ScriptState* script_state,
                                   const ShadowRootInit& shadow_root_init_dict,
                                   ExceptionState& exception_state) {
+  DCHECK(shadow_root_init_dict.hasMode());
   HostsUsingFeatures::CountMainWorldOnly(
       script_state, GetDocument(),
       HostsUsingFeatures::Feature::kElementAttachShadow);
@@ -2427,31 +2428,22 @@
     return nullptr;
   }
 
-  if (shadow_root_init_dict.hasMode() && GetShadowRoot()) {
+  if (GetShadowRoot()) {
     exception_state.ThrowDOMException(kInvalidStateError,
                                       "Shadow root cannot be created on a host "
                                       "which already hosts a shadow tree.");
     return nullptr;
   }
 
-  ShadowRootType type = ShadowRootType::V0;
-  if (shadow_root_init_dict.hasMode())
-    type = shadow_root_init_dict.mode() == "open" ? ShadowRootType::kOpen
-                                                  : ShadowRootType::kClosed;
+  ShadowRootType type = shadow_root_init_dict.mode() == "open"
+                            ? ShadowRootType::kOpen
+                            : ShadowRootType::kClosed;
 
-  if (type == ShadowRootType::kClosed)
-    UseCounter::Count(GetDocument(), WebFeature::kElementAttachShadowClosed);
-  else if (type == ShadowRootType::kOpen)
+  if (type == ShadowRootType::kOpen)
     UseCounter::Count(GetDocument(), WebFeature::kElementAttachShadowOpen);
+  else
+    UseCounter::Count(GetDocument(), WebFeature::kElementAttachShadowClosed);
 
-  if (!AreAuthorShadowsAllowed()) {
-    exception_state.ThrowDOMException(
-        kHierarchyRequestError,
-        "Author-created shadow roots are disabled for this element.");
-    return nullptr;
-  }
-
-  DCHECK(!shadow_root_init_dict.hasMode() || !GetShadowRoot());
   bool delegateFocus = shadow_root_init_dict.hasDelegatesFocus() &&
                        shadow_root_init_dict.delegatesFocus();
   return &AttachShadowRootInternal(type, delegateFocus);
diff --git a/third_party/WebKit/Source/core/editing/LayoutSelection.cpp b/third_party/WebKit/Source/core/editing/LayoutSelection.cpp
index b80f01a4..b598598 100644
--- a/third_party/WebKit/Source/core/editing/LayoutSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/LayoutSelection.cpp
@@ -212,62 +212,28 @@
 
 // This class represents a selection range in layout tree for marking
 // SelectionState
-// TODO(yoichio): Remove unused functionality comparing to SelectionPaintRange.
 class SelectionMarkingRange {
   STACK_ALLOCATED();
 
  public:
   SelectionMarkingRange() = default;
-  SelectionMarkingRange(LayoutObject* start_layout_object,
-                        int start_offset,
-                        LayoutObject* end_layout_object,
-                        int end_offset,
+  SelectionMarkingRange(SelectionPaintRange paint_range,
                         PaintInvalidationSet invalidation_set)
-      : start_layout_object_(start_layout_object),
-        start_offset_(start_offset),
-        end_layout_object_(end_layout_object),
-        end_offset_(end_offset),
+      : paint_range_(paint_range),
         invalidation_set_(std::move(invalidation_set)) {}
   SelectionMarkingRange(SelectionMarkingRange&& other) {
-    start_layout_object_ = other.start_layout_object_;
-    start_offset_ = other.start_offset_;
-    end_layout_object_ = other.end_layout_object_;
-    end_offset_ = other.end_offset_;
+    paint_range_ = other.paint_range_;
     invalidation_set_ = std::move(other.invalidation_set_);
   }
 
-  SelectionPaintRange ToPaintRange() const {
-    return {start_layout_object_, start_offset_, end_layout_object_,
-            end_offset_};
-  };
+  SelectionPaintRange PaintRange() const { return paint_range_; };
 
-  LayoutObject* StartLayoutObject() const {
-    DCHECK(!IsNull());
-    return start_layout_object_;
-  }
-  int StartOffset() const {
-    DCHECK(!IsNull());
-    return start_offset_;
-  }
-  LayoutObject* EndLayoutObject() const {
-    DCHECK(!IsNull());
-    return end_layout_object_;
-  }
-  int EndOffset() const {
-    DCHECK(!IsNull());
-    return end_offset_;
-  }
   const PaintInvalidationSet& InvalidationSet() const {
     return invalidation_set_;
   }
 
-  bool IsNull() const { return !start_layout_object_; }
-
  private:
-  LayoutObject* start_layout_object_ = nullptr;
-  int start_offset_ = -1;
-  LayoutObject* end_layout_object_ = nullptr;
-  int end_offset_ = -1;
+  SelectionPaintRange paint_range_;
   PaintInvalidationSet invalidation_set_;
 
  private:
@@ -416,7 +382,7 @@
     }
     MarkSelected(&invalidation_set, layout_object,
                  SelectionState::kStartAndEnd);
-    return {layout_object, start_offset, layout_object, end_offset,
+    return {{layout_object, start_offset, layout_object, end_offset},
             std::move(invalidation_set)};
   }
   DCHECK_LE(start_offset, end_offset);
@@ -429,17 +395,17 @@
     DCHECK_GT(static_cast<unsigned>(end_offset), remaining_part->Start());
     MarkSelected(&invalidation_set, remaining_part,
                  SelectionState::kStartAndEnd);
-    return {remaining_part,
-            static_cast<int>(start_offset - remaining_part->Start()),
-            remaining_part,
-            static_cast<int>(end_offset - remaining_part->Start()),
+    return {{remaining_part,
+             static_cast<int>(start_offset - remaining_part->Start()),
+             remaining_part,
+             static_cast<int>(end_offset - remaining_part->Start())},
             std::move(invalidation_set)};
   }
   if (static_cast<unsigned>(end_offset) <= remaining_part->Start()) {
     // Case 2: The selection starts and ends in first letter part.
     MarkSelected(&invalidation_set, first_letter_part,
                  SelectionState::kStartAndEnd);
-    return {first_letter_part, start_offset, first_letter_part, end_offset,
+    return {{first_letter_part, start_offset, first_letter_part, end_offset},
             std::move(invalidation_set)};
   }
 
@@ -448,8 +414,8 @@
   DCHECK_GT(static_cast<unsigned>(end_offset), remaining_part->Start());
   MarkSelected(&invalidation_set, first_letter_part, SelectionState::kStart);
   MarkSelected(&invalidation_set, remaining_part, SelectionState::kEnd);
-  return {first_letter_part, start_offset, remaining_part,
-          static_cast<int>(end_offset - remaining_part->Start()),
+  return {{first_letter_part, start_offset, remaining_part,
+           static_cast<int>(end_offset - remaining_part->Start())},
           std::move(invalidation_set)};
 }
 
@@ -471,7 +437,7 @@
     MarkSelected(&invalidation_set, start_layout_object,
                  SelectionState::kStart);
     MarkSelected(&invalidation_set, end_layout_object, SelectionState::kEnd);
-    return {start_layout_object, start_offset, end_layout_object, end_offset,
+    return {{start_layout_object, start_offset, end_layout_object, end_offset},
             std::move(invalidation_set)};
   }
   if (!start_first_letter_part) {
@@ -483,8 +449,9 @@
                    SelectionState::kStart);
       MarkSelected(&invalidation_set, end_first_letter_part,
                    SelectionState::kEnd);
-      return {start_layout_object, start_offset, end_first_letter_part,
-              end_offset, std::move(invalidation_set)};
+      return {{start_layout_object, start_offset, end_first_letter_part,
+               end_offset},
+              std::move(invalidation_set)};
     }
     // Case 2: The selection ends in remaining part
     DCHECK_GT(static_cast<unsigned>(end_offset), end_remaining_part->Start());
@@ -493,8 +460,8 @@
     MarkSelected(&invalidation_set, end_first_letter_part,
                  SelectionState::kInside);
     MarkSelected(&invalidation_set, end_remaining_part, SelectionState::kEnd);
-    return {start_layout_object, start_offset, end_remaining_part,
-            static_cast<int>(end_offset - end_remaining_part->Start()),
+    return {{start_layout_object, start_offset, end_remaining_part,
+             static_cast<int>(end_offset - end_remaining_part->Start())},
             std::move(invalidation_set)};
   }
   if (!end_first_letter_part) {
@@ -507,16 +474,18 @@
       MarkSelected(&invalidation_set, start_remaining_part,
                    SelectionState::kInside);
       MarkSelected(&invalidation_set, end_layout_object, SelectionState::kEnd);
-      return {start_first_letter_part, start_offset, end_layout_object,
-              end_offset, std::move(invalidation_set)};
+      return {{start_first_letter_part, start_offset, end_layout_object,
+               end_offset},
+              std::move(invalidation_set)};
     }
     // Case 4: The selection starts in remaining part.
     MarkSelected(&invalidation_set, start_remaining_part,
                  SelectionState::kStart);
     MarkSelected(&invalidation_set, end_layout_object, SelectionState::kEnd);
-    return {start_remaining_part,
-            static_cast<int>(start_offset - start_remaining_part->Start()),
-            end_layout_object, end_offset, std::move(invalidation_set)};
+    return {{start_remaining_part,
+             static_cast<int>(start_offset - start_remaining_part->Start()),
+             end_layout_object, end_offset},
+            std::move(invalidation_set)};
   }
   LayoutTextFragment* const start_remaining_part =
       ToLayoutTextFragment(start_layout_object);
@@ -531,8 +500,9 @@
                  SelectionState::kInside);
     MarkSelected(&invalidation_set, end_first_letter_part,
                  SelectionState::kEnd);
-    return {start_first_letter_part, start_offset, end_first_letter_part,
-            end_offset, std::move(invalidation_set)};
+    return {{start_first_letter_part, start_offset, end_first_letter_part,
+             end_offset},
+            std::move(invalidation_set)};
   }
   if (static_cast<unsigned>(start_offset) < start_remaining_part->Start()) {
     // Case 6: The selection starts in first-letter part and ends in remaining
@@ -545,8 +515,8 @@
     MarkSelected(&invalidation_set, end_first_letter_part,
                  SelectionState::kInside);
     MarkSelected(&invalidation_set, end_remaining_part, SelectionState::kEnd);
-    return {start_first_letter_part, start_offset, end_remaining_part,
-            static_cast<int>(end_offset - end_remaining_part->Start()),
+    return {{start_first_letter_part, start_offset, end_remaining_part,
+             static_cast<int>(end_offset - end_remaining_part->Start())},
             std::move(invalidation_set)};
   }
   if (static_cast<unsigned>(end_offset) <= end_remaining_part->Start()) {
@@ -558,9 +528,10 @@
                  SelectionState::kStart);
     MarkSelected(&invalidation_set, end_first_letter_part,
                  SelectionState::kEnd);
-    return {start_remaining_part,
-            static_cast<int>(start_offset - start_remaining_part->Start()),
-            end_first_letter_part, end_offset, std::move(invalidation_set)};
+    return {{start_remaining_part,
+             static_cast<int>(start_offset - start_remaining_part->Start()),
+             end_first_letter_part, end_offset},
+            std::move(invalidation_set)};
   }
   // Case 8: The selection starts in remaining part and ends in remaining part.
   DCHECK_GE(static_cast<unsigned>(start_offset), start_remaining_part->Start());
@@ -569,10 +540,10 @@
   MarkSelected(&invalidation_set, end_first_letter_part,
                SelectionState::kInside);
   MarkSelected(&invalidation_set, end_remaining_part, SelectionState::kEnd);
-  return {start_remaining_part,
-          static_cast<int>(start_offset - start_remaining_part->Start()),
-          end_remaining_part,
-          static_cast<int>(end_offset - end_remaining_part->Start()),
+  return {{start_remaining_part,
+           static_cast<int>(start_offset - start_remaining_part->Start()),
+           end_remaining_part,
+           static_cast<int>(end_offset - end_remaining_part->Start())},
           std::move(invalidation_set)};
 }
 
@@ -652,13 +623,14 @@
       frame_selection_->GetDocument().Lifecycle());
   const SelectionMarkingRange& new_range =
       CalcSelectionRangeAndSetSelectionState(*frame_selection_);
-  if (new_range.IsNull()) {
+  const SelectionPaintRange& new_paint_range = new_range.PaintRange();
+  if (new_paint_range.IsNull()) {
     ClearSelection();
     return;
   }
   DCHECK(frame_selection_->GetDocument().GetLayoutView()->GetFrameView());
   SetShouldInvalidateSelection(new_range, paint_range_);
-  paint_range_ = new_range.ToPaintRange();
+  paint_range_ = new_paint_range;
   // TODO(yoichio): Remove this if state.
   // This SelectionState reassignment is ad-hoc patch for
   // prohibiting use-after-free(crbug.com/752715).
diff --git a/third_party/WebKit/Source/core/editing/LayoutSelection.h b/third_party/WebKit/Source/core/editing/LayoutSelection.h
index ebedb1e..928e685 100644
--- a/third_party/WebKit/Source/core/editing/LayoutSelection.h
+++ b/third_party/WebKit/Source/core/editing/LayoutSelection.h
@@ -42,8 +42,6 @@
 // editing/ passes them as offsets in the DOM tree but layout uses them as
 // offset in the layout tree. This doesn't work in the cases of
 // CSS first-letter or character transform. See crbug.com/17528.
-// TODO(yoichio): Remove unused functionality comparing to
-// SelectionMarkingRange.
 class SelectionPaintRange {
   DISALLOW_NEW();
 
diff --git a/third_party/WebKit/Source/core/editing/LayoutSelectionTest.cpp b/third_party/WebKit/Source/core/editing/LayoutSelectionTest.cpp
index feac94f..7cb3d6f3 100644
--- a/third_party/WebKit/Source/core/editing/LayoutSelectionTest.cpp
+++ b/third_party/WebKit/Source/core/editing/LayoutSelectionTest.cpp
@@ -74,6 +74,7 @@
 USING_LAYOUTOBJECT_FUNC(IsBR);
 USING_LAYOUTOBJECT_FUNC(IsListItem);
 USING_LAYOUTOBJECT_FUNC(IsListMarker);
+USING_LAYOUTOBJECT_FUNC(IsLayoutImage);
 
 static IsTypeOf IsLayoutTextFragmentOf(const String& text) {
   return WTF::Bind(
@@ -102,14 +103,18 @@
                              const String& text,
                              SelectionState state,
                              InvalidateOption invalidate) {
-  if (!TestLayoutObjectState(object, state, invalidate))
-    return false;
-
-  if (!object->IsText())
-    return false;
-  if (text != ToLayoutText(object)->GetText())
-    return false;
-  return true;
+  return TestLayoutObject(
+      object,
+      WTF::Bind(
+          [](const String& text, const LayoutObject& object) {
+            if (!object.IsText())
+              return false;
+            if (text != ToLayoutText(object).GetText())
+              return false;
+            return true;
+          },
+          text),
+      state, invalidate);
 }
 
 #define TEST_NEXT(predicate, state, invalidate)                             \
@@ -394,4 +399,14 @@
                                .Build());
   Selection().CommitAppearanceIfNeeded();
 }
+
+TEST_F(LayoutSelectionTest, SelectImage) {
+  const SelectionInDOMTree& selection =
+      SetSelectionTextToBody("^<img style=\"width:100px; height:100px\"/>|");
+  Selection().SetSelection(selection);
+  Selection().CommitAppearanceIfNeeded();
+  TEST_NEXT(IsLayoutBlock, kStartAndEnd, ShouldInvalidate);
+  TEST_NEXT(IsLayoutImage, kStartAndEnd, ShouldInvalidate);
+  TEST_NO_NEXT_LAYOUT_OBJECT();
+}
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
index bd7892a..02e9c155 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -347,7 +347,6 @@
 
   SimplifiedBackwardsTextIteratorAlgorithm<Strategy> it(
       EphemeralRangeTemplate<Strategy>(start, end));
-  int remaining_length = 0;
   unsigned next = 0;
   bool need_more_context = false;
   while (!it.AtEnd()) {
@@ -362,10 +361,8 @@
                                string.Size() - suffix_length,
                                kMayHaveMoreContext, need_more_context);
       } while (!next && run_offset < it.length());
-      if (next) {
-        remaining_length = it.length() - run_offset;
+      if (next)
         break;
-      }
     } else {
       // Treat bullets used in the text security mode as regular
       // characters when looking for boundaries
@@ -387,13 +384,6 @@
   if (!next)
     return it.AtEnd() ? it.StartPosition() : pos;
 
-  Node* node = it.StartContainer();
-  int boundary_offset = remaining_length + next;
-  if (node->IsTextNode() && boundary_offset <= node->MaxCharacterOffset()) {
-    // The next variable contains a usable index into a text node
-    return PositionTemplate<Strategy>(node, boundary_offset);
-  }
-
   // Use the character iterator to translate the next value into a DOM
   // position.
   BackwardsCharacterIteratorAlgorithm<Strategy> char_it(
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnitsWordTest.cpp b/third_party/WebKit/Source/core/editing/VisibleUnitsWordTest.cpp
index becbcc61..735a8f9 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnitsWordTest.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleUnitsWordTest.cpp
@@ -46,20 +46,19 @@
 
 TEST_F(VisibleUnitsWordTest, StartOfWordFirstLetter) {
   InsertStyleElement("p::first-letter {font-size:200%;}");
-  // TODO(editing-dev): We should make expected texts as same as
-  // "StartOfWordBasic".
+  // Note: Expectations should match with |StartOfWordBasic|.
   EXPECT_EQ("<p> |(1) abc def</p>", DoStartOfWord("<p>| (1) abc def</p>"));
   EXPECT_EQ("<p> |(1) abc def</p>", DoStartOfWord("<p> |(1) abc def</p>"));
   EXPECT_EQ("<p> (|1) abc def</p>", DoStartOfWord("<p> (|1) abc def</p>"));
   EXPECT_EQ("<p> (1|) abc def</p>", DoStartOfWord("<p> (1|) abc def</p>"));
   EXPECT_EQ("<p> (1)| abc def</p>", DoStartOfWord("<p> (1)| abc def</p>"));
-  EXPECT_EQ("<p> |(1) abc def</p>", DoStartOfWord("<p> (1) |abc def</p>"));
-  EXPECT_EQ("<p> |(1) abc def</p>", DoStartOfWord("<p> (1) a|bc def</p>"));
-  EXPECT_EQ("<p> |(1) abc def</p>", DoStartOfWord("<p> (1) ab|c def</p>"));
-  EXPECT_EQ("<p> (1)| abc def</p>", DoStartOfWord("<p> (1) abc| def</p>"));
-  EXPECT_EQ("<p> (1) |abc def</p>", DoStartOfWord("<p> (1) abc |def</p>"));
-  EXPECT_EQ("<p> (1) |abc def</p>", DoStartOfWord("<p> (1) abc d|ef</p>"));
-  EXPECT_EQ("<p> (1) |abc def</p>", DoStartOfWord("<p> (1) abc de|f</p>"));
+  EXPECT_EQ("<p> (1) |abc def</p>", DoStartOfWord("<p> (1) |abc def</p>"));
+  EXPECT_EQ("<p> (1) |abc def</p>", DoStartOfWord("<p> (1) a|bc def</p>"));
+  EXPECT_EQ("<p> (1) |abc def</p>", DoStartOfWord("<p> (1) ab|c def</p>"));
+  EXPECT_EQ("<p> (1) abc| def</p>", DoStartOfWord("<p> (1) abc| def</p>"));
+  EXPECT_EQ("<p> (1) abc |def</p>", DoStartOfWord("<p> (1) abc |def</p>"));
+  EXPECT_EQ("<p> (1) abc |def</p>", DoStartOfWord("<p> (1) abc d|ef</p>"));
+  EXPECT_EQ("<p> (1) abc |def</p>", DoStartOfWord("<p> (1) abc de|f</p>"));
   EXPECT_EQ("<p> (1) abc def|</p>", DoStartOfWord("<p> (1) abc def|</p>"));
   EXPECT_EQ("<p> (1) abc def|</p>", DoStartOfWord("<p> (1) abc def</p>|"));
 }
diff --git a/third_party/WebKit/Source/core/editing/testing/SelectionSample.cpp b/third_party/WebKit/Source/core/editing/testing/SelectionSample.cpp
index 5ad20afe..0a144bb 100644
--- a/third_party/WebKit/Source/core/editing/testing/SelectionSample.cpp
+++ b/third_party/WebKit/Source/core/editing/testing/SelectionSample.cpp
@@ -9,16 +9,45 @@
 
 #include "core/dom/Attribute.h"
 #include "core/dom/CharacterData.h"
+#include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/dom/ProcessingInstruction.h"
+#include "core/dom/ShadowRootInit.h"
 #include "core/editing/EditingUtilities.h"
 #include "core/editing/SelectionTemplate.h"
+#include "core/html/HTMLCollection.h"
+#include "core/html/HTMLTemplateElement.h"
 #include "platform/wtf/text/StringBuilder.h"
 
 namespace blink {
 
 namespace {
 
+void ConvertTemplatesToShadowRoots(HTMLElement& element) {
+  // |element| and descendant elements can have TEMPLATE element with
+  // |data-mode="open"|, which is required. Each elemnt can have only one
+  // TEMPLATE element.
+  HTMLCollection* const templates = element.getElementsByTagName("template");
+  HeapVector<Member<Element>> template_vector;
+  for (Element* template_element : *templates)
+    template_vector.push_back(template_element);
+  for (Element* template_element : template_vector) {
+    const AtomicString& data_mode = template_element->getAttribute("data-mode");
+    DCHECK_EQ(data_mode, "open");
+
+    Element* const parent = template_element->parentElement();
+    parent->removeChild(template_element);
+
+    Document* const document = element.ownerDocument();
+    ShadowRoot& shadow_root =
+        parent->AttachShadowRootInternal(ShadowRootType::kOpen);
+    Node* const fragment =
+        document->importNode(toHTMLTemplateElement(template_element)->content(),
+                             true, ASSERT_NO_EXCEPTION);
+    shadow_root.AppendChild(fragment);
+  }
+}
+
 // Parse selection text notation into Selection object.
 template <typename Strategy>
 class Parser final {
@@ -309,6 +338,11 @@
 
 }  // namespace
 
+void SelectionSample::ConvertTemplatesToShadowRootsForTesring(
+    HTMLElement& element) {
+  ConvertTemplatesToShadowRoots(element);
+}
+
 SelectionInDOMTree SelectionSample::SetSelectionText(
     HTMLElement* element,
     const std::string& selection_text) {
diff --git a/third_party/WebKit/Source/core/editing/testing/SelectionSample.h b/third_party/WebKit/Source/core/editing/testing/SelectionSample.h
index 3b4111d..04fa6b67 100644
--- a/third_party/WebKit/Source/core/editing/testing/SelectionSample.h
+++ b/third_party/WebKit/Source/core/editing/testing/SelectionSample.h
@@ -36,6 +36,7 @@
   // Note: We don't escape "--" in comment.
   static std::string GetSelectionText(const ContainerNode&,
                                       const SelectionInDOMTree&);
+  static void ConvertTemplatesToShadowRootsForTesring(HTMLElement&);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/testing/SelectionSampleTest.cpp b/third_party/WebKit/Source/core/editing/testing/SelectionSampleTest.cpp
index fdf03e4..9935431 100644
--- a/third_party/WebKit/Source/core/editing/testing/SelectionSampleTest.cpp
+++ b/third_party/WebKit/Source/core/editing/testing/SelectionSampleTest.cpp
@@ -208,4 +208,66 @@
       << "When BR has child nodes, it is not void element.";
 }
 
+TEST_F(SelectionSampleTest, ConvertTemplatesToShadowRoots) {
+  SetBodyContent(
+      "<div id=host>"
+        "<template data-mode='open'>"
+          "<div>shadow_first</div>"
+          "<div>shadow_second</div>"
+        "</template>"
+      "</div>");
+  Element* body = GetDocument().body();
+  Element* host = body->getElementById("host");
+  SelectionSample::ConvertTemplatesToShadowRootsForTesring(
+      *(ToHTMLElement(host)));
+  ShadowRoot* shadow_root = host->ShadowRootIfV1();
+  ASSERT_TRUE(shadow_root->IsShadowRoot());
+  EXPECT_EQ("<div>shadow_first</div><div>shadow_second</div>",
+            shadow_root->InnerHTMLAsString());
+}
+
+TEST_F(SelectionSampleTest, ConvertTemplatesToShadowRootsNoTemplates) {
+  SetBodyContent(
+      "<div id=host>"
+        "<div>first</div>"
+        "<div>second</div>"
+      "</div>");
+  Element* body = GetDocument().body();
+  Element* host = body->getElementById("host");
+  SelectionSample::ConvertTemplatesToShadowRootsForTesring(
+      *(ToHTMLElement(host)));
+  EXPECT_FALSE(host->ShadowRootIfV1());
+  EXPECT_EQ("<div>first</div><div>second</div>", host->InnerHTMLAsString());
+}
+
+TEST_F(SelectionSampleTest, ConvertTemplatesToShadowRootsMultipleTemplates) {
+  SetBodyContent(
+      "<div id=host1>"
+        "<template data-mode='open'>"
+          "<div>shadow_first</div>"
+          "<div>shadow_second</div>"
+        "</template>"
+      "</div>"
+      "<div id=host2>"
+        "<template data-mode='open'>"
+          "<div>shadow_third</div>"
+          "<div>shadow_forth</div>"
+        "</template>"
+      "</div>");
+  Element* body = GetDocument().body();
+  Element* host1 = body->getElementById("host1");
+  Element* host2 = body->getElementById("host2");
+  SelectionSample::ConvertTemplatesToShadowRootsForTesring(
+      *(ToHTMLElement(body)));
+  ShadowRoot* shadow_root_1 = host1->ShadowRootIfV1();
+  ShadowRoot* shadow_root_2 = host2->ShadowRootIfV1();
+
+  EXPECT_TRUE(shadow_root_1->IsShadowRoot());
+  EXPECT_EQ("<div>shadow_first</div><div>shadow_second</div>",
+            shadow_root_1->InnerHTMLAsString());
+  EXPECT_TRUE(shadow_root_2->IsShadowRoot());
+  EXPECT_EQ("<div>shadow_third</div><div>shadow_forth</div>",
+            shadow_root_2->InnerHTMLAsString());
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/HTMLTemplateElement.h b/third_party/WebKit/Source/core/html/HTMLTemplateElement.h
index 290822c3..829a7b7 100644
--- a/third_party/WebKit/Source/core/html/HTMLTemplateElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLTemplateElement.h
@@ -39,7 +39,7 @@
 class DocumentFragment;
 class TemplateContentDocumentFragment;
 
-class HTMLTemplateElement final : public HTMLElement {
+class CORE_EXPORT HTMLTemplateElement final : public HTMLElement {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
diff --git a/third_party/WebKit/Source/core/layout/BUILD.gn b/third_party/WebKit/Source/core/layout/BUILD.gn
index bdb064f..e04fb35 100644
--- a/third_party/WebKit/Source/core/layout/BUILD.gn
+++ b/third_party/WebKit/Source/core/layout/BUILD.gn
@@ -232,6 +232,10 @@
     "TableLayoutAlgorithmFixed.h",
     "TextAutosizer.cpp",
     "TextAutosizer.h",
+    "TextDecorationOffset.cpp",
+    "TextDecorationOffset.h",
+    "TextDecorationOffsetBase",
+    "TextDecorationOffsetBase.cpp",
     "TextRunConstructor.cpp",
     "TextRunConstructor.h",
     "TracedLayoutObject.cpp",
@@ -297,6 +301,7 @@
     "line/LineBreaker.h",
     "line/LineInfo.h",
     "line/LineLayoutState.h",
+    "line/LineVerticalPositionType.h",
     "line/LineWidth.cpp",
     "line/LineWidth.h",
     "line/RootInlineBox.cpp",
diff --git a/third_party/WebKit/Source/core/layout/TextDecorationOffset.cpp b/third_party/WebKit/Source/core/layout/TextDecorationOffset.cpp
new file mode 100644
index 0000000..75fe76dd
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/TextDecorationOffset.cpp
@@ -0,0 +1,35 @@
+// Copyright 2014 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 "core/layout/TextDecorationOffset.h"
+#include "core/layout/line/InlineTextBox.h"
+#include "core/layout/line/RootInlineBox.h"
+#include "platform/fonts/FontMetrics.h"
+
+namespace blink {
+
+int TextDecorationOffset::ComputeUnderlineOffsetForUnder(
+    float text_decoration_thickness,
+    LineVerticalPositionType position_type) {
+  const RootInlineBox& root = inline_text_box_->Root();
+  FontBaseline baseline_type = root.BaselineType();
+  LayoutUnit offset = inline_text_box_->OffsetTo(position_type, baseline_type);
+
+  // Compute offset to the farthest position of the decorating box.
+  LayoutUnit logical_top = inline_text_box_->LogicalTop();
+  LayoutUnit position = logical_top + offset;
+  LayoutUnit farthest = root.FarthestPositionForUnderline(
+      decorating_box_, position_type, baseline_type, position);
+  // Round() looks more logical but Floor() produces better results in
+  // positive/negative offsets, in horizontal/vertical flows, on Win/Mac/Linux.
+  int offset_int = (farthest - logical_top).Floor();
+
+  // Gaps are not needed for TextTop because it generally has internal
+  // leadings.
+  if (position_type == LineVerticalPositionType::TextTop)
+    return offset_int;
+  return !IsLineOverSide(position_type) ? offset_int + 1 : offset_int - 1;
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/TextDecorationOffset.h b/third_party/WebKit/Source/core/layout/TextDecorationOffset.h
new file mode 100644
index 0000000..ea115c4
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/TextDecorationOffset.h
@@ -0,0 +1,39 @@
+// Copyright 2014 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 TextDecorationOffset_h
+#define TextDecorationOffset_h
+
+#include "core/CoreExport.h"
+#include "core/layout/TextDecorationOffsetBase.h"
+#include "core/layout/api/LineLayoutItem.h"
+
+namespace blink {
+
+class ComputedStyle;
+class InlineTextBox;
+
+class CORE_EXPORT TextDecorationOffset : public TextDecorationOffsetBase {
+  STACK_ALLOCATED();
+
+ public:
+  TextDecorationOffset(const ComputedStyle& style,
+                       const InlineTextBox* inline_text_box,
+                       LineLayoutItem decorating_box)
+      : TextDecorationOffsetBase(style),
+        inline_text_box_(inline_text_box),
+        decorating_box_(decorating_box) {}
+  ~TextDecorationOffset() {}
+
+  int ComputeUnderlineOffsetForUnder(float text_decoration_thickness,
+                                     LineVerticalPositionType) override;
+
+ private:
+  const InlineTextBox* inline_text_box_;
+  LineLayoutItem decorating_box_;
+};
+
+}  // namespace blink
+
+#endif  // TextDecorationOffset_h
diff --git a/third_party/WebKit/Source/core/layout/TextDecorationOffsetBase.cpp b/third_party/WebKit/Source/core/layout/TextDecorationOffsetBase.cpp
new file mode 100644
index 0000000..022e11a
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/TextDecorationOffsetBase.cpp
@@ -0,0 +1,54 @@
+// Copyright 2014 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 "core/layout/TextDecorationOffsetBase.h"
+#include "core/layout/line/LineVerticalPositionType.h"
+#include "core/paint/DecorationInfo.h"
+#include "platform/fonts/FontMetrics.h"
+
+namespace blink {
+
+int TextDecorationOffsetBase::ComputeUnderlineOffsetForRoman(
+    const FontMetrics& font_metrics,
+    float text_decoration_thickness) {
+  // Compute the gap between the font and the underline. Use at least one
+  // pixel gap, if underline is thick then use a bigger gap.
+  int gap = 0;
+
+  // Underline position of zero means draw underline on Baseline Position,
+  // in Blink we need at least 1-pixel gap to adding following check.
+  // Positive underline Position means underline should be drawn above baseline
+  // and negative value means drawing below baseline, negating the value as in
+  // Blink downward Y-increases.
+
+  if (font_metrics.UnderlinePosition())
+    gap = -font_metrics.UnderlinePosition();
+  else
+    gap = std::max<int>(1, ceilf(text_decoration_thickness / 2.f));
+
+  // Position underline near the alphabetic baseline.
+  return font_metrics.Ascent() + gap;
+}
+
+int TextDecorationOffsetBase::ComputeUnderlineOffset(
+    ResolvedUnderlinePosition underline_position,
+    const FontMetrics& font_metrics,
+    float text_decoration_thickness) {
+  switch (underline_position) {
+    default:
+      NOTREACHED();
+    // Fall through.
+    case ResolvedUnderlinePosition::kRoman:
+      return ComputeUnderlineOffsetForRoman(font_metrics,
+                                            text_decoration_thickness);
+    case ResolvedUnderlinePosition::kUnder:
+      // Position underline at the under edge of the lowest element's
+      // content box.
+      return ComputeUnderlineOffsetForUnder(
+          text_decoration_thickness,
+          LineVerticalPositionType::BottomOfEmHeight);
+  }
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/TextDecorationOffsetBase.h b/third_party/WebKit/Source/core/layout/TextDecorationOffsetBase.h
new file mode 100644
index 0000000..9c046b03
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/TextDecorationOffsetBase.h
@@ -0,0 +1,42 @@
+// Copyright 2014 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 TextDecorationOffsetBase_h
+#define TextDecorationOffsetBase_h
+
+#include "core/CoreExport.h"
+#include "platform/LayoutUnit.h"
+#include "platform/fonts/FontBaseline.h"
+
+namespace blink {
+
+class ComputedStyle;
+enum class LineVerticalPositionType;
+enum class ResolvedUnderlinePosition;
+class FontMetrics;
+
+class CORE_EXPORT TextDecorationOffsetBase {
+  STACK_ALLOCATED();
+
+ public:
+  TextDecorationOffsetBase(const ComputedStyle& style) : style_(style) {}
+  ~TextDecorationOffsetBase() {}
+
+  virtual int ComputeUnderlineOffsetForUnder(float text_decoration_thickness,
+                                             LineVerticalPositionType) = 0;
+
+  int ComputeUnderlineOffsetForRoman(const FontMetrics&,
+                                     float text_decoration_thickness);
+
+  int ComputeUnderlineOffset(ResolvedUnderlinePosition,
+                             const FontMetrics&,
+                             float text_decoration_thickness);
+
+ protected:
+  const ComputedStyle& style_;
+};
+
+}  // namespace blink
+
+#endif  // TextDecorationOffsetBase_h
diff --git a/third_party/WebKit/Source/core/layout/line/InlineBox.h b/third_party/WebKit/Source/core/layout/line/InlineBox.h
index 25933ee..66e8e1af 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineBox.h
+++ b/third_party/WebKit/Source/core/layout/line/InlineBox.h
@@ -26,6 +26,7 @@
 #include "core/layout/api/LineLayoutBoxModel.h"
 #include "core/layout/api/LineLayoutItem.h"
 #include "core/layout/api/SelectionState.h"
+#include "core/layout/line/LineVerticalPositionType.h"
 #include "platform/graphics/paint/DisplayItemClient.h"
 #include "platform/text/TextDirection.h"
 
@@ -39,19 +40,6 @@
 
 enum MarkLineBoxes { kMarkLineBoxesDirty, kDontMarkLineBoxes };
 
-enum class LineVerticalPositionType {
-  // TextTop and TextBottom are the top/bottom of the content area.
-  // This is where 'vertical-align: text-top/text-bottom' aligns to.
-  // This is explicitly undefined in CSS2.
-  // https://drafts.csswg.org/css2/visudet.html#inline-non-replaced
-  TextTop,
-  TextBottom,
-  // Em height as being discussed in Font Metrics API.
-  // https://drafts.css-houdini.org/font-metrics-api-1/#fontmetrics
-  TopOfEmHeight,
-  BottomOfEmHeight
-};
-
 // Returns whether the position type is CSS "line-over"; i.e., ascender side
 // or "top" side of a line box.
 // https://drafts.csswg.org/css-writing-modes-3/#line-over
diff --git a/third_party/WebKit/Source/core/layout/line/LineVerticalPositionType.h b/third_party/WebKit/Source/core/layout/line/LineVerticalPositionType.h
new file mode 100644
index 0000000..c03c77b
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/line/LineVerticalPositionType.h
@@ -0,0 +1,25 @@
+// Copyright 2014 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 LineVerticalPositionType_h
+#define LineVerticalPositionType_h
+
+namespace blink {
+
+enum class LineVerticalPositionType {
+  // TextTop and TextBottom are the top/bottom of the content area.
+  // This is where 'vertical-align: text-top/text-bottom' aligns to.
+  // This is explicitly undefined in CSS2.
+  // https://drafts.csswg.org/css2/visudet.html#inline-non-replaced
+  TextTop,
+  TextBottom,
+  // Em height as being discussed in Font Metrics API.
+  // https://drafts.css-houdini.org/font-metrics-api-1/#fontmetrics
+  TopOfEmHeight,
+  BottomOfEmHeight
+};
+
+}  // namespace blink
+
+#endif  // LineVerticalPositionType_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
index 7b3d02a..2abf2d8 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -308,7 +308,13 @@
       HandleFloat(previous_inflow_position, ToNGBlockNode(child),
                   ToNGBlockBreakToken(child_break_token));
     } else {
-      if (!HandleInflow(child, child_break_token, &previous_inflow_position)) {
+      bool success = child.CreatesNewFormattingContext()
+                         ? HandleNewFormattingContext(child, child_break_token,
+                                                      &previous_inflow_position)
+                         : HandleInflow(child, child_break_token,
+                                        &previous_inflow_position);
+
+      if (!success) {
         // We need to abort the layout, as our BFC offset was resolved.
         container_builder_.SwapUnpositionedFloats(&unpositioned_floats_);
         return container_builder_.Abort(NGLayoutResult::kBfcOffsetResolved);
@@ -475,6 +481,154 @@
   }
 }
 
+bool NGBlockLayoutAlgorithm::HandleNewFormattingContext(
+    NGLayoutInputNode child,
+    NGBreakToken* child_break_token,
+    NGPreviousInflowPosition* previous_inflow_position) {
+  DCHECK(child);
+  DCHECK(!child.IsFloating());
+  DCHECK(!child.IsOutOfFlowPositioned());
+  DCHECK(child.CreatesNewFormattingContext());
+
+  const ComputedStyle& child_style = child.Style();
+  const EClear child_clear = child_style.Clear();
+  const TextDirection direction = ConstraintSpace().Direction();
+
+  // Perform layout on the child.
+  NGInflowChildData child_data =
+      ComputeChildData(*previous_inflow_position, child, child_break_token);
+  RefPtr<NGConstraintSpace> child_space =
+      CreateConstraintSpaceForChild(child, child_data);
+  RefPtr<NGLayoutResult> layout_result =
+      child.Layout(*child_space, child_break_token);
+
+  // We must have an actual fragment at this stage.
+  DCHECK(layout_result->PhysicalFragment());
+  const auto& physical_fragment = *layout_result->PhysicalFragment();
+  NGFragment fragment(ConstraintSpace().WritingMode(), physical_fragment);
+
+  LayoutUnit child_bfc_offset_estimate =
+      child_data.bfc_offset_estimate.block_offset;
+
+  // 1. Position all pending floats to a temporary space, which is a copy of
+  //    the current exclusion space.
+  NGExclusionSpace tmp_exclusion_space(*exclusion_space_);
+  PositionFloats(child_bfc_offset_estimate, child_bfc_offset_estimate,
+                 unpositioned_floats_, ConstraintSpace(),
+                 container_builder_.Size().inline_size, &tmp_exclusion_space);
+
+  NGBfcOffset origin_offset = {
+      ConstraintSpace().BfcOffset().line_offset +
+          border_scrollbar_padding_.LineLeft(direction) +
+          child_data.margins.LineLeft(direction),
+      child_bfc_offset_estimate};
+  AdjustToClearance(tmp_exclusion_space.ClearanceOffset(child_clear),
+                    &origin_offset);
+
+  // 2. Find an estimated layout opportunity for our fragment.
+  NGLogicalSize fragment_size(fragment.InlineSize(), fragment.BlockSize());
+
+  // TODO(ikilpatrick): child_space.AvailableSize() is probably wrong as the
+  // area we need to search shrinks by the origin_offset and LineRight margin.
+  NGLayoutOpportunity opportunity = tmp_exclusion_space.FindLayoutOpportunity(
+      origin_offset, child_space->AvailableSize(), fragment_size);
+
+  NGMarginStrut margin_strut = previous_inflow_position->margin_strut;
+
+  // 3. If the found opportunity lies on the same line with our estimated
+  //    child's BFC offset then merge fragment's margins with the current
+  //    MarginStrut.
+  if (opportunity.offset.block_offset == child_bfc_offset_estimate)
+    margin_strut.Append(child_data.margins.block_start,
+                        child_style.HasMarginBeforeQuirk());
+  child_bfc_offset_estimate += margin_strut.Sum();
+
+  // 4. The child's BFC block offset is known here.
+  bool updated = MaybeUpdateFragmentBfcOffset(
+      ConstraintSpace(), child_bfc_offset_estimate, &container_builder_);
+
+  if (updated && abort_when_bfc_resolved_)
+    return false;
+
+  PositionPendingFloats(ConstraintSpace(), child_bfc_offset_estimate,
+                        &container_builder_, &unpositioned_floats_,
+                        exclusion_space_.get());
+
+  origin_offset = {ConstraintSpace().BfcOffset().line_offset +
+                       border_scrollbar_padding_.LineLeft(direction) +
+                       child_data.margins.LineLeft(direction),
+                   child_bfc_offset_estimate};
+  AdjustToClearance(exclusion_space_->ClearanceOffset(child_clear),
+                    &origin_offset);
+
+  // 5. Find the final layout opportunity for the fragment after all pending
+  // floats are positioned at the correct BFC block's offset.
+  // TODO(ikilpatrick): child_space.AvailableSize() is probably wrong as the
+  // area we need to search shrinks by the origin_offset and LineRight margin.
+  opportunity = exclusion_space_->FindLayoutOpportunity(
+      origin_offset, child_space->AvailableSize(), fragment_size);
+
+  // Auto-margins are applied within the layout opportunity which fits.
+  // TODO(ikilpatrick): Some of these calculations should be pulled into
+  // ApplyAutoMargins.
+  NGBoxStrut margins(child_data.margins);
+  ApplyAutoMargins(child_style, opportunity.InlineSize(), fragment.InlineSize(),
+                   &margins);
+  margins.inline_end =
+      opportunity.InlineSize() - margins.inline_start - fragment.InlineSize();
+
+  bool is_ltr = direction == TextDirection::kLtr;
+  bool is_line_left_auto_margin =
+      (is_ltr && child_style.MarginStart().IsAuto()) ||
+      (!is_ltr && child_style.MarginEnd().IsAuto());
+
+  LayoutUnit line_left_auto_margin =
+      is_line_left_auto_margin ? margins.LineLeft(direction) : LayoutUnit();
+
+  // We try and position the child within the block formatting context. This
+  // may cause our BFC offset to be resolved, in which case we should abort our
+  // layout if needed.
+  NGBfcOffset child_bfc_offset(
+      opportunity.offset.line_offset + line_left_auto_margin,
+      opportunity.offset.block_offset);
+
+  NGLogicalOffset logical_offset =
+      CalculateLogicalOffset(fragment, child_data.margins, child_bfc_offset);
+
+  if (ConstraintSpace().HasBlockFragmentation() &&
+      ShouldBreakBeforeChild(child, physical_fragment,
+                             logical_offset.block_offset)) {
+    // TODO(mstensho): Make sure that we're at a valid point [1] before
+    // breaking. It's not allowed to break between the content edge of a
+    // container and its first child, if they are adjacent. If we're not allowed
+    // to break here, we need to attempt to propagate the break further up the
+    // ancestry.
+    //
+    // [1] https://drafts.csswg.org/css-break/#possible-breaks
+
+    // The remaining part of the fragmentainer (the unusable space for child
+    // content, due to the break) should still be occupied by this container.
+    content_size_ = FragmentainerSpaceAvailable();
+    // Drop the fragment on the floor and retry at the start of the next
+    // fragmentainer.
+    container_builder_.AddBreakBeforeChild(child);
+    container_builder_.SetDidBreak();
+    return true;
+  }
+
+  UpdateContentSize(child_data.margins, logical_offset,
+                    /* is_empty_block */ false, fragment);
+
+  container_builder_.AddChild(layout_result, logical_offset);
+  container_builder_.PropagateBreak(layout_result);
+
+  *previous_inflow_position = ComputeInflowPosition(
+      *previous_inflow_position, child, child_data, child_bfc_offset,
+      logical_offset, *layout_result, fragment,
+      /* empty_block_affected_by_clearance */ false);
+  return true;
+}
+
 bool NGBlockLayoutAlgorithm::HandleInflow(
     NGLayoutInputNode child,
     NGBreakToken* child_break_token,
@@ -483,14 +637,12 @@
   DCHECK(!child.IsFloating());
   DCHECK(!child.IsOutOfFlowPositioned());
 
-  bool is_new_fc = child.CreatesNewFormattingContext();
-
   // TODO(ikilpatrick): We may only want to position pending floats if there is
   // something that we *might* clear in the unpositioned list. E.g. we may
   // clear an already placed left float, but the unpositioned list may only have
   // right floats.
   bool should_position_pending_floats =
-      !is_new_fc && child.IsBlock() &&
+      child.IsBlock() &&
       ClearanceMayAffectLayout(*exclusion_space_, unpositioned_floats_,
                                child.Style());
 
@@ -540,6 +692,8 @@
   RefPtr<NGLayoutResult> layout_result =
       child.Layout(*child_space, child_break_token);
 
+  bool is_empty_block = IsEmptyBlock(child, *layout_result);
+
   // If we don't know our BFC offset yet, we need to copy the list of
   // unpositioned floats from the child's layout result.
   //
@@ -551,7 +705,7 @@
   //
   // TODO(ikilpatrick): a more optimal version of this is to set
   // abort_when_bfc_resolved_, if the child tree _added_ any floats.
-  if (!container_builder_.BfcOffset() && !is_new_fc) {
+  if (!container_builder_.BfcOffset()) {
     unpositioned_floats_ = layout_result->UnpositionedFloats();
     abort_when_bfc_resolved_ |= !layout_result->UnpositionedFloats().IsEmpty();
     if (child_space->FloatsBfcOffset())
@@ -563,8 +717,6 @@
   // to our parent.
   if (layout_result->Status() == NGLayoutResult::kBfcOffsetResolved &&
       !container_builder_.BfcOffset()) {
-    DCHECK(!is_new_fc);
-
     MaybeUpdateFragmentBfcOffset(
         ConstraintSpace(), layout_result->BfcOffset().value().block_offset,
         &container_builder_);
@@ -582,7 +734,7 @@
   //
   // The exclusion space is then updated when the child undergoes relayout
   // below.
-  if (layout_result->Status() == NGLayoutResult::kSuccess && !is_new_fc) {
+  if (layout_result->Status() == NGLayoutResult::kSuccess) {
     DCHECK(layout_result->ExclusionSpace());
     exclusion_space_ =
         WTF::MakeUnique<NGExclusionSpace>(*layout_result->ExclusionSpace());
@@ -596,11 +748,7 @@
   // may cause our BFC offset to be resolved, in which case we should abort our
   // layout if needed.
   WTF::Optional<NGBfcOffset> child_bfc_offset;
-  if (is_new_fc) {
-    if (!PositionNewFc(child, *previous_inflow_position, *layout_result,
-                       child_data, *child_space, &child_bfc_offset))
-      return false;
-  } else if (layout_result->BfcOffset()) {
+  if (layout_result->BfcOffset()) {
     if (!PositionWithBfcOffset(layout_result->BfcOffset().value(),
                                &child_bfc_offset))
       return false;
@@ -609,7 +757,7 @@
         PositionWithParentBfc(child, *child_space, child_data, *layout_result,
                               &empty_block_affected_by_clearance);
   } else
-    DCHECK(IsEmptyBlock(child, *layout_result));
+    DCHECK(is_empty_block);
 
   // We need to re-layout a child if it was affected by clearance in order to
   // produce a new margin strut. For example:
@@ -655,7 +803,6 @@
 
     DCHECK_EQ(layout_result->Status(), NGLayoutResult::kSuccess);
 
-    DCHECK(!is_new_fc);
     DCHECK(layout_result->ExclusionSpace());
     exclusion_space_ =
         WTF::MakeUnique<NGExclusionSpace>(*layout_result->ExclusionSpace());
@@ -690,22 +837,8 @@
     return true;
   }
 
-  // Only modify content_size_ if the fragment is non-empty block.
-  //
-  // Empty blocks don't immediately contribute to our size, instead we wait to
-  // see what the final margin produced, e.g.
-  // <div style="display: flow-root">
-  //   <div style="margin-top: -8px"></div>
-  //   <div style="margin-top: 10px"></div>
-  // </div>
-  if (!IsEmptyBlock(child, *layout_result)) {
-    DCHECK(container_builder_.BfcOffset());
-    content_size_ = std::max(
-        content_size_, logical_offset.block_offset + fragment.BlockSize());
-  }
-  max_inline_size_ = std::max(
-      max_inline_size_, fragment.InlineSize() + child_data.margins.InlineSum() +
-                            border_scrollbar_padding_.InlineSum());
+  UpdateContentSize(child_data.margins, logical_offset, is_empty_block,
+                    fragment);
 
   container_builder_.AddChild(layout_result, logical_offset);
   container_builder_.PropagateBreak(layout_result);
@@ -816,106 +949,6 @@
           empty_or_sibling_empty_affected_by_clearance};
 }
 
-bool NGBlockLayoutAlgorithm::PositionNewFc(
-    const NGLayoutInputNode& child,
-    const NGPreviousInflowPosition& previous_inflow_position,
-    const NGLayoutResult& layout_result,
-    const NGInflowChildData& child_data,
-    const NGConstraintSpace& child_space,
-    WTF::Optional<NGBfcOffset>* child_bfc_offset) {
-  const ComputedStyle& child_style = child.Style();
-  const EClear child_clear = child_style.Clear();
-  const TextDirection direction = ConstraintSpace().Direction();
-
-  DCHECK(layout_result.PhysicalFragment());
-  NGFragment fragment(ConstraintSpace().WritingMode(),
-                      *layout_result.PhysicalFragment());
-
-  LayoutUnit child_bfc_offset_estimate =
-      child_data.bfc_offset_estimate.block_offset;
-
-  // 1. Position all pending floats to a temporary space, which is a copy of
-  //    the current exclusion space.
-  NGExclusionSpace tmp_exclusion_space(*exclusion_space_);
-  PositionFloats(child_bfc_offset_estimate, child_bfc_offset_estimate,
-                 unpositioned_floats_, ConstraintSpace(),
-                 container_builder_.Size().inline_size, &tmp_exclusion_space);
-
-  NGBfcOffset origin_offset = {
-      ConstraintSpace().BfcOffset().line_offset +
-          border_scrollbar_padding_.LineLeft(direction) +
-          child_data.margins.LineLeft(direction),
-      child_bfc_offset_estimate};
-  AdjustToClearance(tmp_exclusion_space.ClearanceOffset(child_clear),
-                    &origin_offset);
-
-  // 2. Find an estimated layout opportunity for our fragment.
-  NGLogicalSize fragment_size(fragment.InlineSize(), fragment.BlockSize());
-
-  // TODO(ikilpatrick): child_space.AvailableSize() is probably wrong as the
-  // area we need to search shrinks by the origin_offset and LineRight margin.
-  NGLayoutOpportunity opportunity = tmp_exclusion_space.FindLayoutOpportunity(
-      origin_offset, child_space.AvailableSize(), fragment_size);
-
-  NGMarginStrut margin_strut = previous_inflow_position.margin_strut;
-
-  // 3. If the found opportunity lies on the same line with our estimated
-  //    child's BFC offset then merge fragment's margins with the current
-  //    MarginStrut.
-  if (opportunity.offset.block_offset == child_bfc_offset_estimate)
-    margin_strut.Append(child_data.margins.block_start,
-                        child_style.HasMarginBeforeQuirk());
-  child_bfc_offset_estimate += margin_strut.Sum();
-
-  // 4. The child's BFC block offset is known here.
-  bool updated = MaybeUpdateFragmentBfcOffset(
-      ConstraintSpace(), child_bfc_offset_estimate, &container_builder_);
-
-  if (updated && abort_when_bfc_resolved_)
-    return false;
-
-  PositionPendingFloats(ConstraintSpace(), child_bfc_offset_estimate,
-                        &container_builder_, &unpositioned_floats_,
-                        exclusion_space_.get());
-
-  origin_offset = {ConstraintSpace().BfcOffset().line_offset +
-                       border_scrollbar_padding_.LineLeft(direction) +
-                       child_data.margins.LineLeft(direction),
-                   child_bfc_offset_estimate};
-  AdjustToClearance(exclusion_space_->ClearanceOffset(child_clear),
-                    &origin_offset);
-
-  // 5. Find the final layout opportunity for the fragment after all pending
-  // floats are positioned at the correct BFC block's offset.
-  // TODO(ikilpatrick): child_space.AvailableSize() is probably wrong as the
-  // area we need to search shrinks by the origin_offset and LineRight margin.
-  opportunity = exclusion_space_->FindLayoutOpportunity(
-      origin_offset, child_space.AvailableSize(), fragment_size);
-
-  // Auto-margins are applied within the layout opportunity which fits.
-  // TODO(ikilpatrick): Some of these calculations should be pulled into
-  // ApplyAutoMargins.
-  NGBoxStrut margins(child_data.margins);
-  ApplyAutoMargins(child_style, opportunity.InlineSize(), fragment.InlineSize(),
-                   &margins);
-  margins.inline_end =
-      opportunity.InlineSize() - margins.inline_start - fragment.InlineSize();
-
-  bool is_ltr = direction == TextDirection::kLtr;
-  bool is_line_left_auto_margin =
-      (is_ltr && child_style.MarginStart().IsAuto()) ||
-      (!is_ltr && child_style.MarginEnd().IsAuto());
-
-  LayoutUnit line_left_auto_margin =
-      is_line_left_auto_margin ? margins.LineLeft(direction) : LayoutUnit();
-
-  *child_bfc_offset =
-      NGBfcOffset{opportunity.offset.line_offset + line_left_auto_margin,
-                  opportunity.offset.block_offset};
-
-  return true;
-}
-
 bool NGBlockLayoutAlgorithm::PositionWithBfcOffset(
     const NGBfcOffset& bfc_offset,
     WTF::Optional<NGBfcOffset>* child_bfc_offset) {
@@ -1194,4 +1227,29 @@
   }
 }
 
+// TODO(ikilpatrick): Remove/simplify this to just calculate/update
+// content_size_ as max_inline_size_ is not currently used.
+void NGBlockLayoutAlgorithm::UpdateContentSize(
+    const NGBoxStrut& margins,
+    const NGLogicalOffset& logical_offset,
+    bool is_empty_block,
+    const NGFragment& fragment) {
+  // Only modify content_size_ if the fragment is non-empty block.
+  //
+  // Empty blocks don't immediately contribute to our size, instead we wait to
+  // see what the final margin produced, e.g.
+  // <div style="display: flow-root">
+  //   <div style="margin-top: -8px"></div>
+  //   <div style="margin-top: 10px"></div>
+  // </div>
+  if (!is_empty_block) {
+    DCHECK(container_builder_.BfcOffset());
+    content_size_ = std::max(
+        content_size_, logical_offset.block_offset + fragment.BlockSize());
+  }
+  max_inline_size_ =
+      std::max(max_inline_size_, fragment.InlineSize() + margins.InlineSum() +
+                                     border_scrollbar_padding_.InlineSum());
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
index 4c58839..e9629326 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
@@ -91,31 +91,6 @@
       const NGFragment& fragment,
       bool empty_block_affected_by_clearance);
 
-  // Positions the fragment that establishes a new formatting context.
-  //
-  // This uses Layout Opportunity iterator to position the fragment.
-  // That's because an element that establishes a new block formatting context
-  // must not overlap the margin box of any floats in the same block formatting
-  // context as the element itself.
-  //
-  // So if necessary, we clear the new BFC by placing it below any preceding
-  // floats or place it adjacent to such floats if there is sufficient space.
-  //
-  // Example:
-  // <div id="container">
-  //   <div id="float"></div>
-  //   <div id="new-fc" style="margin-top: 20px;"></div>
-  // </div>
-  // 1) If #new-fc is small enough to fit the available space right from #float
-  //    then it will be placed there and we collapse its margin.
-  // 2) If #new-fc is too big then we need to clear its position and place it
-  //    below #float ignoring its vertical margin.
-  bool PositionNewFc(const NGLayoutInputNode& child,
-                     const NGPreviousInflowPosition&,
-                     const NGLayoutResult&,
-                     const NGInflowChildData& child_data,
-                     const NGConstraintSpace& child_space,
-                     WTF::Optional<NGBfcOffset>* child_bfc_offset);
 
   // Positions the fragment that knows its BFC offset.
   WTF::Optional<NGBfcOffset> PositionWithBfcOffset(
@@ -141,9 +116,30 @@
                    NGBlockNode,
                    NGBlockBreakToken*);
 
-  // Handle an in-flow child. Returns true if everything went smoothly and we
-  // can continue to the next sibling. Returns false if we need to abort,
-  // because a previously unknown BFC offset now has been resolved.
+  // This uses the NGLayoutOpporunityIterator to position the fragment.
+  //
+  // An element that establishes a new formatting context must not overlap the
+  // margin box of any floats within the current BFC.
+  //
+  // Example:
+  // <div id="container">
+  //   <div id="float"></div>
+  //   <div id="new-fc" style="margin-top: 20px;"></div>
+  // </div>
+  // 1) If #new-fc is small enough to fit the available space right from #float
+  //    then it will be placed there and we collapse its margin.
+  // 2) If #new-fc is too big then we need to clear its position and place it
+  //    below #float ignoring its vertical margin.
+  //
+  // Returns false if we need to abort layout, because a previously unknown BFC
+  // offset has now been resolved.
+  bool HandleNewFormattingContext(NGLayoutInputNode child,
+                                  NGBreakToken* child_break_token,
+                                  NGPreviousInflowPosition*);
+
+  // Handle an in-flow child.
+  // Returns false if we need to abort layout, because a previously unknown BFC
+  // offset has now been resolved. (Same as HandleNewFormattingContext).
   bool HandleInflow(NGLayoutInputNode child,
                     NGBreakToken* child_break_token,
                     NGPreviousInflowPosition*);
@@ -172,6 +168,11 @@
                    const NGPhysicalFragment*,
                    LayoutUnit child_offset);
 
+  void UpdateContentSize(const NGBoxStrut& margins,
+                         const NGLogicalOffset& logical_offset,
+                         bool is_empty_block,
+                         const NGFragment&);
+
   // Calculates logical offset for the current fragment using either
   // {@code content_size_} when the fragment doesn't know it's offset
   // or {@code known_fragment_offset} if the fragment knows it's offset
diff --git a/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp b/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp
index eecf24d..7b898eab 100644
--- a/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp
@@ -12,6 +12,7 @@
 #include "core/frame/LocalFrame.h"
 #include "core/layout/LayoutTextCombine.h"
 #include "core/layout/LayoutTheme.h"
+#include "core/layout/TextDecorationOffset.h"
 #include "core/layout/api/LineLayoutAPIShim.h"
 #include "core/layout/api/LineLayoutBox.h"
 #include "core/layout/line/InlineTextBox.h"
@@ -75,76 +76,6 @@
   }
 }
 
-static int ComputeUnderlineOffsetForUnder(
-    const ComputedStyle& style,
-    const InlineTextBox* inline_text_box,
-    LineLayoutItem decorating_box,
-    float text_decoration_thickness,
-    LineVerticalPositionType position_type) {
-  const RootInlineBox& root = inline_text_box->Root();
-  FontBaseline baseline_type = root.BaselineType();
-  LayoutUnit offset = inline_text_box->OffsetTo(position_type, baseline_type);
-
-  // Compute offset to the farthest position of the decorating box.
-  LayoutUnit logical_top = inline_text_box->LogicalTop();
-  LayoutUnit position = logical_top + offset;
-  LayoutUnit farthest = root.FarthestPositionForUnderline(
-      decorating_box, position_type, baseline_type, position);
-  // Round() looks more logical but Floor() produces better results in
-  // positive/negative offsets, in horizontal/vertical flows, on Win/Mac/Linux.
-  int offset_int = (farthest - logical_top).Floor();
-
-  // Gaps are not needed for TextTop because it generally has internal
-  // leadings.
-  if (position_type == LineVerticalPositionType::TextTop)
-    return offset_int;
-  return !IsLineOverSide(position_type) ? offset_int + 1 : offset_int - 1;
-}
-
-static int ComputeUnderlineOffsetForRoman(
-    const FontMetrics& font_metrics,
-    const float text_decoration_thickness) {
-  // Compute the gap between the font and the underline. Use at least one
-  // pixel gap, if underline is thick then use a bigger gap.
-  int gap = 0;
-
-  // Underline position of zero means draw underline on Baseline Position,
-  // in Blink we need at least 1-pixel gap to adding following check.
-  // Positive underline Position means underline should be drawn above baseline
-  // and negative value means drawing below baseline, negating the value as in
-  // Blink downward Y-increases.
-
-  if (font_metrics.UnderlinePosition())
-    gap = -font_metrics.UnderlinePosition();
-  else
-    gap = std::max<int>(1, ceilf(text_decoration_thickness / 2.f));
-
-  // Position underline near the alphabetic baseline.
-  return font_metrics.Ascent() + gap;
-}
-
-static int ComputeUnderlineOffset(ResolvedUnderlinePosition underline_position,
-                                  const ComputedStyle& style,
-                                  const FontMetrics& font_metrics,
-                                  const InlineTextBox* inline_text_box,
-                                  LineLayoutItem decorating_box,
-                                  const float text_decoration_thickness) {
-  switch (underline_position) {
-    default:
-      NOTREACHED();
-    // Fall through.
-    case ResolvedUnderlinePosition::kRoman:
-      return ComputeUnderlineOffsetForRoman(font_metrics,
-                                            text_decoration_thickness);
-    case ResolvedUnderlinePosition::kUnder:
-      // Position underline at the under edge of the lowest element's
-      // content box.
-      return ComputeUnderlineOffsetForUnder(
-          style, inline_text_box, decorating_box, text_decoration_thickness,
-          LineVerticalPositionType::BottomOfEmHeight);
-  }
-}
-
 static const int kMisspellingLineThickness = 3;
 
 LayoutObject& InlineTextBoxPainter::InlineLayoutObject() const {
@@ -222,28 +153,29 @@
     underline_position = ResolvedUnderlinePosition::kUnder;
   }
 
+  TextDecorationOffset decoration_offset(*decoration_info.style, &box,
+                                         decorating_box);
   for (const AppliedTextDecoration& decoration : decorations) {
     TextDecoration lines = decoration.Lines();
     bool has_underline = EnumHasFlags(lines, TextDecoration::kUnderline);
     bool has_overline = EnumHasFlags(lines, TextDecoration::kOverline);
-    if (flip_underline_and_overline) {
+    if (flip_underline_and_overline)
       std::swap(has_underline, has_overline);
-    }
     if (has_underline && decoration_info.font_data) {
-      const int underline_offset = ComputeUnderlineOffset(
-          underline_position, *decoration_info.style,
-          decoration_info.font_data->GetFontMetrics(), &box, decorating_box,
+      const int underline_offset = decoration_offset.ComputeUnderlineOffset(
+          underline_position, decoration_info.font_data->GetFontMetrics(),
           decoration_info.thickness);
       text_painter.PaintDecorationUnderOrOverLine(
           context, decoration_info, decoration, underline_offset,
           decoration_info.double_offset);
     }
     if (has_overline) {
-      const int overline_offset = ComputeUnderlineOffsetForUnder(
-          *decoration_info.style, &box, decorating_box,
-          decoration_info.thickness,
-          flip_underline_and_overline ? LineVerticalPositionType::TopOfEmHeight
-                                      : LineVerticalPositionType::TextTop);
+      const int overline_offset =
+          decoration_offset.ComputeUnderlineOffsetForUnder(
+              decoration_info.thickness,
+              flip_underline_and_overline
+                  ? LineVerticalPositionType::TopOfEmHeight
+                  : LineVerticalPositionType::TextTop);
       text_painter.PaintDecorationUnderOrOverLine(
           context, decoration_info, decoration, overline_offset,
           -decoration_info.double_offset);
diff --git a/third_party/WebKit/Source/platform/exported/WebCORSPreflightResultCache.cpp b/third_party/WebKit/Source/platform/exported/WebCORSPreflightResultCache.cpp
index 515250c..43d894c 100644
--- a/third_party/WebKit/Source/platform/exported/WebCORSPreflightResultCache.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebCORSPreflightResultCache.cpp
@@ -167,7 +167,11 @@
     const WebString& method,
     WebString& error_description) const {
   if (methods_.find(method.Ascii().data()) != methods_.end() ||
-      FetchUtils::IsCORSSafelistedMethod(method))
+      FetchUtils::IsCORSSafelistedMethod(method)) {
+    return true;
+  }
+
+  if (!credentials_ && methods_.find("*") != methods_.end())
     return true;
 
   error_description.Assign(WebString::FromASCII("Method " + method.Ascii() +
diff --git a/third_party/WebKit/Source/platform/wtf/RefPtr.h b/third_party/WebKit/Source/platform/wtf/RefPtr.h
index 214619a5..b635862 100644
--- a/third_party/WebKit/Source/platform/wtf/RefPtr.h
+++ b/third_party/WebKit/Source/platform/wtf/RefPtr.h
@@ -82,15 +82,6 @@
   RefPtr(RefPtr<U>&& o, EnsurePtrConvertibleArgDecl(U, T))
       : ptr_(o.LeakRef()) {}
 
-  // Hash table deleted values, which are only constructed and never copied or
-  // destroyed.
-  // TODO(tzik): Remove this after updating callsites of this to use
-  // HashTraits<RefPtr<>>::{ConstructDeletedValue,IsHashTableDeletedValue}.
-  RefPtr(HashTableDeletedValueType) : ptr_(HashTableDeletedValue()) {}
-  bool IsHashTableDeletedValue() const {
-    return ptr_ == HashTableDeletedValue();
-  }
-
   ALWAYS_INLINE ~RefPtr() { DerefIfNotNull(ptr_); }
 
   ALWAYS_INLINE T* Get() const { return ptr_; }
@@ -118,8 +109,6 @@
 
   void Swap(RefPtr&);
 
-  static T* HashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
-
  private:
   friend RefPtr AdoptRef<T>(T*);
 
diff --git a/third_party/WebKit/Source/platform/wtf/text/AtomicString.h b/third_party/WebKit/Source/platform/wtf/text/AtomicString.h
index 7b2069b..235430e 100644
--- a/third_party/WebKit/Source/platform/wtf/text/AtomicString.h
+++ b/third_party/WebKit/Source/platform/wtf/text/AtomicString.h
@@ -78,16 +78,6 @@
   explicit AtomicString(StringImpl* impl) : string_(Add(impl)) {}
   explicit AtomicString(const String& s) : string_(Add(s.Impl())) {}
 
-  // Hash table deleted values, which are only constructed and never copied or
-  // destroyed.
-  // TODO(tzik): Remove this after updating callsites of this to use
-  // HashTraits<AtomicString>::{ConstructDeletedValue,IsHashTableDeletedValue}.
-  AtomicString(WTF::HashTableDeletedValueType)
-      : string_(WTF::kHashTableDeletedValue) {}
-  bool IsHashTableDeletedValue() const {
-    return string_.IsHashTableDeletedValue();
-  }
-
   explicit operator bool() const { return !IsNull(); }
   operator const String&() const { return string_; }
   const String& GetString() const { return string_; }
diff --git a/third_party/WebKit/Source/platform/wtf/text/WTFString.h b/third_party/WebKit/Source/platform/wtf/text/WTFString.h
index b7918c71..949075a 100644
--- a/third_party/WebKit/Source/platform/wtf/text/WTFString.h
+++ b/third_party/WebKit/Source/platform/wtf/text/WTFString.h
@@ -496,15 +496,6 @@
     return impl_ ? impl_->CharactersSizeInBytes() : 0;
   }
 
-  // Hash table deleted values, which are only constructed and never copied or
-  // destroyed.
-  // TODO(tzik): Remove this after updating callsites of this to use
-  // HashTraits<String>::{ConstructDeletedValue,IsHashTableDeletedValue}.
-  String(WTF::HashTableDeletedValueType) : impl_(WTF::kHashTableDeletedValue) {}
-  bool IsHashTableDeletedValue() const {
-    return impl_.IsHashTableDeletedValue();
-  }
-
 #ifndef NDEBUG
   // For use in the debugger.
   void Show() const;
diff --git a/third_party/WebKit/public/platform/WebCORSPreflightResultCache.h b/third_party/WebKit/public/platform/WebCORSPreflightResultCache.h
index c1b1042..06d69d5 100644
--- a/third_party/WebKit/public/platform/WebCORSPreflightResultCache.h
+++ b/third_party/WebKit/public/platform/WebCORSPreflightResultCache.h
@@ -51,7 +51,7 @@
       const WebHTTPHeaderMap&,
       WebString& error_description);
 
-  bool AllowsCrossOriginMethod(const WebString&,
+  bool AllowsCrossOriginMethod(const WebString& method,
                                WebString& error_description) const;
   bool AllowsCrossOriginHeaders(const WebHTTPHeaderMap&,
                                 WebString& error_description) const;
diff --git a/tools/gn/format_test_data/062.gn b/tools/gn/format_test_data/062.gn
index d7fbb3c..8c4cc7d 100644
--- a/tools/gn/format_test_data/062.gn
+++ b/tools/gn/format_test_data/062.gn
@@ -110,3 +110,13 @@
   "srtp/crypto/rng/prng.c",
   "srtp/crypto/rng/rand_source.c",
 ]
+
+# Try "public" too. It should be treated the same.
+public = [
+  # Let's sort
+  "this", "into", "word", "salad",
+
+  # But leave
+  "these", "two"
+  # alone!
+]
diff --git a/tools/gn/format_test_data/062.golden b/tools/gn/format_test_data/062.golden
index e939e449..b5545101 100644
--- a/tools/gn/format_test_data/062.golden
+++ b/tools/gn/format_test_data/062.golden
@@ -115,3 +115,18 @@
   "srtp/srtp/ekt.c",
   "srtp/srtp/srtp.c",
 ]
+
+# Try "public" too. It should be treated the same.
+public = [
+  # Let's sort
+  "into",
+  "salad",
+  "this",
+  "word",
+
+  # But leave
+  "these",
+  "two",
+
+  # alone!
+]
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 4dc6878..8641f36 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -11850,7 +11850,7 @@
 </enum>
 
 <enum name="ExtensionEvents">
-<!-- Generated from extensions/browser/extension_event_histogram_value.h.-->
+<!-- Generated from extensions/browser/extension_event_histogram_value.h -->
 
   <int value="0" label="UNKNOWN"/>
   <int value="1" label="FOR_TEST"/>
@@ -12293,7 +12293,7 @@
 </enum>
 
 <enum name="ExtensionFunctions">
-<!-- Generated from extensions/browser/extension_function_histogram_value.h.-->
+<!-- Generated from extensions/browser/extension_function_histogram_value.h -->
 
   <int value="0" label="UNKNOWN"/>
   <int value="1" label="WEBNAVIGATION_GETALLFRAMES"/>
@@ -12800,9 +12800,9 @@
   <int value="500" label="DELETED_WEBVIEW_STOP"/>
   <int value="501" label="DELETED_WEBVIEW_RELOAD"/>
   <int value="502" label="DELETED_WEBVIEW_TERMINATE"/>
-  <int value="503" label="DELETED_TYPES_PRIVATE_CHROMEDIRECTSETTING_GET"/>
-  <int value="504" label="DELETED_TYPES_PRIVATE_CHROMEDIRECTSETTING_SET"/>
-  <int value="505" label="DELETED_TYPES_PRIVATE_CHROMEDIRECTSETTING_CLEAR"/>
+  <int value="503" label="TYPES_PRIVATE_CHROMEDIRECTSETTING_GET"/>
+  <int value="504" label="TYPES_PRIVATE_CHROMEDIRECTSETTING_SET"/>
+  <int value="505" label="TYPES_PRIVATE_CHROMEDIRECTSETTING_CLEAR"/>
   <int value="506" label="DELETED_EXPERIMENTAL_SYSTEMINFO_STORAGE_EJECTDEVICE"/>
   <int value="507" label="SYSTEM_CPU_GETINFO"/>
   <int value="508" label="BOOKMARKMANAGERPRIVATE_REMOVETREES"/>
@@ -13520,6 +13520,7 @@
   <int value="1193" label="NETWORKINGPRIVATE_SELECTCELLULARMOBILENETWORK"/>
   <int value="1194" label="PASSWORDSPRIVATE_IMPORTPASSWORDS"/>
   <int value="1195" label="PASSWORDSPRIVATE_EXPORTPASSWORDS"/>
+  <int value="1196" label="LANGUAGESETTINGSPRIVATE_SETTRANSLATEFORLANGUAGE"/>
 </enum>
 
 <enum name="ExtensionIconState">
@@ -24102,6 +24103,7 @@
   <int value="862453793" label="TranslateUI2016Q2:enabled"/>
   <int value="867512869" label="mark-non-secure-as"/>
   <int value="869531646" label="enable-session-crashed-bubble"/>
+  <int value="871713352" label="ImprovedLanguageSettings:enabled"/>
   <int value="879699575" label="disable-gesture-tap-highlight"/>
   <int value="879992337" label="disable-pull-to-refresh-effect"/>
   <int value="880510010" label="enable-permissions-bubbles"/>
@@ -24246,6 +24248,7 @@
   <int value="1276209777" label="ntp-switch-to-existing-tab"/>
   <int value="1279584261" label="enable-carrier-switching"/>
   <int value="1280614081" label="show-overdraw-feedback"/>
+  <int value="1283908088" label="ImprovedLanguageSettings:disabled"/>
   <int value="1283956865" label="force-tablet-mode"/>
   <int value="1283960113" label="disable-fixed-position-compositing"/>
   <int value="1284910808" label="disable-checker-imaging"/>
@@ -39039,6 +39042,7 @@
   <int value="82462683" label="gaia_oauth_client_refresh_token"/>
   <int value="83476155" label="gaia_oauth_client_get_user_info"/>
   <int value="84045030" label="payment_manifest_downloader"/>
+  <int value="84165821" label="blink_extension_resource_loader"/>
   <int value="84212388" label="omnibox_suggest_deletion"/>
   <int value="84575287" label="background_performance_tracer"/>
   <int value="84889397" label="cryptauth_enrollment_flow_setup"/>
@@ -39077,6 +39081,7 @@
   <int value="111565057" label="devtools_hard_coded_data_source"/>
   <int value="111712433" label="cloud_print"/>
   <int value="111904019" label="affiliation_lookup"/>
+  <int value="112189210" label="favicon_loader"/>
   <int value="112303907" label="blob_read"/>
   <int value="113231892" label="url_fetcher_downloader"/>
   <int value="113553577" label="certificate_verifier"/>
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 980ecf2..a1f3c58 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -18,6 +18,7 @@
  <item id="autofill_upload" hash_code="104798869" content_hash_code="110634763" os_list="linux,windows"/>
  <item id="background_fetch_context" hash_code="16469669" content_hash_code="52235434" os_list="linux,windows"/>
  <item id="background_performance_tracer" hash_code="84575287" content_hash_code="120154250" os_list="linux,windows"/>
+ <item id="blink_extension_resource_loader" hash_code="84165821" content_hash_code="3695143" os_list="linux,windows"/>
  <item id="blink_resource_loader" hash_code="101845102" content_hash_code="69137084" os_list="linux,windows"/>
  <item id="blob_read" hash_code="112303907" content_hash_code="135449692" os_list="linux,windows"/>
  <item id="blob_reader" hash_code="5154306" content_hash_code="39702178" os_list="linux,windows"/>
@@ -74,6 +75,7 @@
  <item id="extension_manifest_fetcher" hash_code="5151071" content_hash_code="57885402" os_list="linux,windows"/>
  <item id="external_policy_fetcher" hash_code="9459438" content_hash_code="64260484" os_list="linux,windows"/>
  <item id="family_info" hash_code="30913825" content_hash_code="25369370" os_list="linux,windows"/>
+ <item id="favicon_loader" hash_code="112189210" content_hash_code="70773116" os_list="linux,windows"/>
  <item id="gaia_auth_check_connection_info" hash_code="4598626" content_hash_code="57347000" os_list="linux,windows"/>
  <item id="gaia_auth_exchange_cookies" hash_code="134289752" content_hash_code="66433230" os_list="linux,windows"/>
  <item id="gaia_auth_exchange_device_id" hash_code="39877119" content_hash_code="61857947" os_list="linux,windows"/>
diff --git a/ui/keyboard/keyboard_controller_unittest.cc b/ui/keyboard/keyboard_controller_unittest.cc
index 2d5d165..b1e23d9 100644
--- a/ui/keyboard/keyboard_controller_unittest.cc
+++ b/ui/keyboard/keyboard_controller_unittest.cc
@@ -690,6 +690,27 @@
   EXPECT_EQ(1.0, layer->opacity());
 }
 
+TEST_P(KeyboardControllerAnimationTest, SetBoundsOnOldKeyboardUiReference) {
+  ScopedAccessibilityKeyboardEnabler scoped_keyboard_enabler;
+
+  // Ensure keyboard ui is populated
+  ui::Layer* layer = keyboard_container()->layer();
+  ShowKeyboard();
+  RunAnimationForLayer(layer);
+
+  ASSERT_TRUE(controller()->ui());
+
+  aura::Window* container_window = controller()->GetContainerWindow();
+
+  // Simulate removal of keyboard controller from root window as done by
+  // RootWindowController::DeactivateKeyboard()
+  container_window->parent()->RemoveChild(container_window);
+
+  // lingering handle to the contents window is adjusted.
+  // container_window's LayoutManager should abort silently and not crash.
+  controller()->ui()->GetContentsWindow()->SetBounds(gfx::Rect());
+}
+
 TEST_P(KeyboardControllerTest, DisplayChangeShouldNotifyBoundsChange) {
   ScopedTouchKeyboardEnabler scoped_keyboard_enabler;
   ui::DummyTextInputClient input_client(ui::TEXT_INPUT_TYPE_TEXT);
diff --git a/ui/keyboard/keyboard_layout_manager.cc b/ui/keyboard/keyboard_layout_manager.cc
index 1f6fa8e..68d3497 100644
--- a/ui/keyboard/keyboard_layout_manager.cc
+++ b/ui/keyboard/keyboard_layout_manager.cc
@@ -29,7 +29,6 @@
 void KeyboardLayoutManager::SetChildBounds(aura::Window* child,
                                            const gfx::Rect& requested_bounds) {
   DCHECK(child == contents_window_);
-
   TRACE_EVENT0("vk", "KeyboardLayoutSetChildBounds");
 
   // Request to change the bounds of the contents window
@@ -39,6 +38,11 @@
 
   const aura::Window* root_window =
       controller_->GetContainerWindow()->GetRootWindow();
+
+  // If the keyboard has been deactivated, this reference will be null.
+  if (!root_window)
+    return;
+
   gfx::Rect new_bounds = requested_bounds;
 
   // Honors only the height of the request bounds