diff --git a/DEPS b/DEPS
index 4489316..df88395 100644
--- a/DEPS
+++ b/DEPS
@@ -40,7 +40,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '019be7b472a5a628e54822bddaa101fcda49da93',
+  'skia_revision': '64d8be00b85c398a757126ed9767ff57e646a1d5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
diff --git a/build/install-build-deps-android.sh b/build/install-build-deps-android.sh
index 172279b..0261b37 100755
--- a/build/install-build-deps-android.sh
+++ b/build/install-build-deps-android.sh
@@ -55,7 +55,7 @@
 # be installed manually on late-model versions.
 
 # common
-sudo apt-get -y install lighttpd python-pexpect xvfb x11-utils
+sudo apt-get -y install lib32z1 lighttpd python-pexpect xvfb x11-utils
 
 # Some binaries in the Android SDK require 32-bit libraries on the host.
 # See https://developer.android.com/sdk/installing/index.html?pkg=tools
diff --git a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
index 98b7e135..10b1c54e 100644
--- a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
+++ b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "chrome/browser/chromeos/arc/arc_optin_uma.h"
 #include "chrome/browser/chromeos/arc/arc_session_manager.h"
@@ -29,6 +30,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/fake_session_manager_client.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_service_manager.h"
 #include "components/arc/test/fake_arc_bridge_service.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/core/account_id/account_id.h"
@@ -70,12 +72,14 @@
     profile_ = profile_builder.Build();
     StartPreferenceSyncing();
 
-    bridge_service_.reset(new FakeArcBridgeService());
-    arc_session_manager_.reset(new ArcSessionManager(bridge_service_.get()));
+    ArcServiceManager::SetArcBridgeServiceForTesting(
+        base::MakeUnique<FakeArcBridgeService>());
+    arc_service_manager_ = base::MakeUnique<ArcServiceManager>(nullptr);
+    arc_session_manager_ = base::MakeUnique<ArcSessionManager>(
+        arc_service_manager_->arc_bridge_service());
 
     // Check initial conditions.
-    EXPECT_EQ(bridge_service_.get(), ArcBridgeService::Get());
-    EXPECT_TRUE(ArcBridgeService::Get()->stopped());
+    EXPECT_TRUE(bridge_service()->stopped());
 
     const AccountId account_id(
         AccountId::FromUserEmailGaiaId("user@gmail.com", "1234567890"));
@@ -87,6 +91,8 @@
 
   void TearDown() override {
     chromeos::WallpaperManager::Shutdown();
+    arc_session_manager_.reset();
+    arc_service_manager_.reset();
     chromeos::DBusThreadManager::Shutdown();
   }
 
@@ -97,7 +103,10 @@
 
  protected:
   Profile* profile() { return profile_.get(); }
-  FakeArcBridgeService* bridge_service() { return bridge_service_.get(); }
+  FakeArcBridgeService* bridge_service() {
+    return static_cast<FakeArcBridgeService*>(
+        arc_service_manager_->arc_bridge_service());
+  }
   ArcSessionManager* arc_session_manager() {
     return arc_session_manager_.get();
   }
@@ -126,8 +135,8 @@
   }
 
   content::TestBrowserThreadBundle thread_bundle_;
-  std::unique_ptr<FakeArcBridgeService> bridge_service_;
   std::unique_ptr<TestingProfile> profile_;
+  std::unique_ptr<ArcServiceManager> arc_service_manager_;
   std::unique_ptr<ArcSessionManager> arc_session_manager_;
   chromeos::ScopedUserManagerEnabler user_manager_enabler_;
   base::ScopedTempDir temp_dir_;
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util_unittest.cc
index 41beed7..7b46293 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util_unittest.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util_unittest.cc
@@ -6,11 +6,13 @@
 #include <string>
 
 #include "base/location.h"
+#include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util.h"
 #include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_url_util.h"
 #include "chrome/browser/chromeos/fileapi/external_file_url_util.h"
+#include "components/arc/arc_service_manager.h"
 #include "components/arc/test/fake_arc_bridge_service.h"
 #include "components/arc/test/fake_file_system_instance.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -36,12 +38,17 @@
 
 class ArcContentFileSystemAsyncFileUtilTest : public testing::Test {
  public:
-  ArcContentFileSystemAsyncFileUtilTest() {
-    fake_arc_bridge_service_.file_system()->SetInstance(&file_system_);
-  }
-
+  ArcContentFileSystemAsyncFileUtilTest() = default;
   ~ArcContentFileSystemAsyncFileUtilTest() override = default;
 
+  void SetUp() override {
+    ArcServiceManager::SetArcBridgeServiceForTesting(
+        base::MakeUnique<FakeArcBridgeService>());
+    arc_service_manager_ = base::MakeUnique<ArcServiceManager>(nullptr);
+    arc_service_manager_->arc_bridge_service()->file_system()->SetInstance(
+        &file_system_);
+  }
+
  protected:
   storage::FileSystemURL ExternalFileURLToFileSystemURL(const GURL& url) {
     base::FilePath mount_point_virtual_path =
@@ -56,7 +63,7 @@
   }
 
   content::TestBrowserThreadBundle thread_bundle_;
-  FakeArcBridgeService fake_arc_bridge_service_;
+  std::unique_ptr<ArcServiceManager> arc_service_manager_;
   ArcFileSystemInstanceTestImpl file_system_;
   ArcContentFileSystemAsyncFileUtil async_file_util_;
 
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc
index 81de469a..c886e6d 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc
@@ -2,14 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <memory>
 #include <string>
 #include <utility>
 
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/location.h"
+#include "base/memory/ptr_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.h"
+#include "components/arc/arc_service_manager.h"
 #include "components/arc/test/fake_arc_bridge_service.h"
 #include "components/arc/test/fake_file_system_instance.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -80,15 +83,19 @@
     base::FilePath path = temp_dir_.GetPath().AppendASCII("bar");
     ASSERT_TRUE(base::WriteFile(path, kData, arraysize(kData)));
 
-    file_system_.reset(new ArcFileSystemInstanceTestImpl(path));
+    file_system_ = base::MakeUnique<ArcFileSystemInstanceTestImpl>(path);
 
-    fake_arc_bridge_service_.file_system()->SetInstance(file_system_.get());
+    ArcServiceManager::SetArcBridgeServiceForTesting(
+        base::MakeUnique<FakeArcBridgeService>());
+    arc_service_manager_ = base::MakeUnique<ArcServiceManager>(nullptr);
+    arc_service_manager_->arc_bridge_service()->file_system()->SetInstance(
+        file_system_.get());
   }
 
  private:
   base::ScopedTempDir temp_dir_;
   content::TestBrowserThreadBundle thread_bundle_;
-  FakeArcBridgeService fake_arc_bridge_service_;
+  std::unique_ptr<ArcServiceManager> arc_service_manager_;
   std::unique_ptr<ArcFileSystemInstanceTestImpl> file_system_;
 
   DISALLOW_COPY_AND_ASSIGN(ArcContentFileSystemFileStreamReaderTest);
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_instance_util.cc b/chrome/browser/chromeos/arc/fileapi/arc_file_system_instance_util.cc
index ca461d36..c2b4deba 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_file_system_instance_util.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_instance_util.cc
@@ -4,7 +4,10 @@
 
 #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_instance_util.h"
 
+#include <string>
+
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_service_manager.h"
 #include "content/public/browser/browser_thread.h"
 #include "url/gurl.h"
 
@@ -17,6 +20,22 @@
 constexpr uint32_t kGetFileSizeVersion = 1;
 constexpr uint32_t kOpenFileToReadVersion = 1;
 
+// Returns FileSystemInstance for the given |min_version|, if found.
+// Otherwise, nullptr.
+mojom::FileSystemInstance* GetFileSystemInstance(
+    const std::string& method_name_for_logging,
+    uint32_t min_version) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  auto* arc_service_manager = arc::ArcServiceManager::Get();
+  if (!arc_service_manager) {
+    LOG(ERROR) << "Failed to get ArcServiceManager.";
+    return nullptr;
+  }
+  return arc_service_manager->arc_bridge_service()
+      ->file_system()
+      ->GetInstanceForMethod(method_name_for_logging, min_version);
+}
+
 void OnGetFileSize(const GetFileSizeCallback& callback, int64_t size) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
@@ -26,17 +45,9 @@
 void GetFileSizeOnUIThread(const GURL& arc_url,
                            const GetFileSizeCallback& callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  auto* arc_bridge_service = arc::ArcBridgeService::Get();
-  if (!arc_bridge_service) {
-    LOG(ERROR) << "Failed to get ArcBridgeService.";
-    OnGetFileSize(callback, -1);
-    return;
-  }
-  mojom::FileSystemInstance* file_system_instance =
-      arc_bridge_service->file_system()->GetInstanceForMethod(
-          "GetFileSize", kGetFileSizeVersion);
+  auto* file_system_instance =
+      GetFileSystemInstance("GetFileSize", kGetFileSizeVersion);
   if (!file_system_instance) {
-    LOG(ERROR) << "Failed to get FileSystemInstance.";
     OnGetFileSize(callback, -1);
     return;
   }
@@ -54,17 +65,9 @@
 void OpenFileToReadOnUIThread(const GURL& arc_url,
                               const OpenFileToReadCallback& callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  auto* arc_bridge_service = arc::ArcBridgeService::Get();
-  if (!arc_bridge_service) {
-    LOG(ERROR) << "Failed to get ArcBridgeService.";
-    OnOpenFileToRead(callback, mojo::ScopedHandle());
-    return;
-  }
-  mojom::FileSystemInstance* file_system_instance =
-      arc_bridge_service->file_system()->GetInstanceForMethod(
-          "OpenFileToRead", kOpenFileToReadVersion);
+  auto* file_system_instance =
+      GetFileSystemInstance("OpenFileToRead", kOpenFileToReadVersion);
   if (!file_system_instance) {
-    LOG(ERROR) << "Failed to get FileSystemInstance.";
     OnOpenFileToRead(callback, mojo::ScopedHandle());
     return;
   }
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
index 0611d93d..07ef511 100644
--- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
+++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
@@ -218,12 +218,17 @@
     SetupNetworkEnvironment();
     RunUntilIdle();
 
-    ArcBridgeService::Get()->intent_helper()->SetInstance(
-        fake_intent_helper_instance_.get());
+    ArcServiceManager::Get()
+        ->arc_bridge_service()
+        ->intent_helper()
+        ->SetInstance(fake_intent_helper_instance_.get());
   }
 
   void TearDownOnMainThread() override {
-    ArcBridgeService::Get()->intent_helper()->SetInstance(nullptr);
+    ArcServiceManager::Get()
+        ->arc_bridge_service()
+        ->intent_helper()
+        ->SetInstance(nullptr);
   }
 
   void UpdatePolicy(const policy::PolicyMap& policy) {
diff --git a/chrome/browser/chromeos/policy/device_status_collector.cc b/chrome/browser/chromeos/policy/device_status_collector.cc
index 7c1fea9..eee5156 100644
--- a/chrome/browser/chromeos/policy/device_status_collector.cc
+++ b/chrome/browser/chromeos/policy/device_status_collector.cc
@@ -47,6 +47,7 @@
 #include "chromeos/settings/cros_settings_names.h"
 #include "chromeos/system/statistics_provider.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_service_manager.h"
 #include "components/arc/common/enterprise_reporting.mojom.h"
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
 #include "components/policy/proto/device_management_backend.pb.h"
@@ -218,10 +219,11 @@
 
 bool ReadAndroidStatus(
     const policy::DeviceStatusCollector::AndroidStatusReceiver& receiver) {
-  auto* const arc_service = arc::ArcBridgeService::Get();
-  if (!arc_service)
+  auto* const arc_service_manager = arc::ArcServiceManager::Get();
+  if (!arc_service_manager)
     return false;
-  auto* const instance_holder = arc_service->enterprise_reporting();
+  auto* const instance_holder =
+      arc_service_manager->arc_bridge_service()->enterprise_reporting();
   if (!instance_holder)
     return false;
   auto* const instance = instance_holder->GetInstanceForMethod("GetStatus", 1);
diff --git a/chrome/browser/memory/tab_manager_delegate_chromeos.cc b/chrome/browser/memory/tab_manager_delegate_chromeos.cc
index b9f1d3e..0ca9a01 100644
--- a/chrome/browser/memory/tab_manager_delegate_chromeos.cc
+++ b/chrome/browser/memory/tab_manager_delegate_chromeos.cc
@@ -36,6 +36,7 @@
 #include "chrome/common/chrome_features.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_service_manager.h"
 #include "components/arc/common/process.mojom.h"
 #include "components/exo/shell_surface.h"
 #include "content/public/browser/browser_thread.h"
@@ -545,13 +546,14 @@
 }
 
 bool TabManagerDelegate::KillArcProcess(const int nspid) {
-  auto* arc_bridge_service = arc::ArcBridgeService::Get();
-  if (!arc_bridge_service)
+  auto* arc_service_manager = arc::ArcServiceManager::Get();
+  if (!arc_service_manager)
     return false;
 
   auto* arc_process_instance =
-      arc_bridge_service->process()->GetInstanceForMethod(
-          "KillProcess", kMinVersionForKillProcess);
+      arc_service_manager->arc_bridge_service()
+          ->process()
+          ->GetInstanceForMethod("KillProcess", kMinVersionForKillProcess);
   if (!arc_process_instance)
     return false;
 
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index 5d9eaa9c..a284e2e 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -4008,7 +4008,7 @@
 
   const PrefService* const pref = browser()->profile()->GetPrefs();
   const arc::ArcBridgeService* const arc_bridge_service =
-      arc::ArcBridgeService::Get();
+      arc::ArcServiceManager::Get()->arc_bridge_service();
 
   // ARC is switched off by default.
   EXPECT_TRUE(arc_bridge_service->stopped());
diff --git a/chrome/browser/prefs/tracked/pref_hash_browsertest.cc b/chrome/browser/prefs/tracked/pref_hash_browsertest.cc
index ea7def8..5685dca6 100644
--- a/chrome/browser/prefs/tracked/pref_hash_browsertest.cc
+++ b/chrome/browser/prefs/tracked/pref_hash_browsertest.cc
@@ -10,12 +10,14 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/json/json_file_value_serializer.h"
+#include "base/json/json_reader.h"
 #include "base/metrics/histogram_base.h"
 #include "base/metrics/histogram_samples.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
@@ -30,6 +32,7 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/search_engines/default_search_manager.h"
+#include "components/search_engines/template_url_data.h"
 #include "components/user_prefs/tracked/tracked_preference_histogram_names.h"
 #include "extensions/browser/pref_names.h"
 #include "extensions/common/extension.h"
@@ -1171,3 +1174,119 @@
 PREF_HASH_BROWSER_TEST(PrefHashBrowserTestRegistryValidationFailure,
                        RegistryValidationFailure);
 #endif
+
+// Verifies that all preferences related to choice of default search engine are
+// protected.
+class PrefHashBrowserTestDefaultSearch : public PrefHashBrowserTestBase {
+ public:
+  void SetupPreferences() override {
+    // Set user selected default search engine.
+    DefaultSearchManager default_search_manager(
+        profile()->GetPrefs(), DefaultSearchManager::ObserverCallback());
+    DefaultSearchManager::Source dse_source =
+        static_cast<DefaultSearchManager::Source>(-1);
+
+    TemplateURLData user_dse;
+    user_dse.SetKeyword(base::UTF8ToUTF16("userkeyword"));
+    user_dse.SetShortName(base::UTF8ToUTF16("username"));
+    user_dse.SetURL("http://user_default_engine/search?q=good_user_query");
+    default_search_manager.SetUserSelectedDefaultSearchEngine(user_dse);
+
+    const TemplateURLData* current_dse =
+        default_search_manager.GetDefaultSearchEngine(&dse_source);
+    EXPECT_EQ(DefaultSearchManager::FROM_USER, dse_source);
+    EXPECT_EQ(current_dse->keyword(), base::UTF8ToUTF16("userkeyword"));
+    EXPECT_EQ(current_dse->short_name(), base::UTF8ToUTF16("username"));
+    EXPECT_EQ(current_dse->url(),
+              "http://user_default_engine/search?q=good_user_query");
+  }
+
+  void AttackPreferencesOnDisk(
+      base::DictionaryValue* unprotected_preferences,
+      base::DictionaryValue* protected_preferences) override {
+    static constexpr char default_search_provider_data[] = R"(
+    {
+      "default_search_provider_data" : {
+        "template_url_data" : {
+          "keyword" : "badkeyword",
+          "short_name" : "badname",
+          "url" : "http://bad_default_engine/search?q=dirty_user_query"
+        }
+      }
+    })";
+    static constexpr char search_provider_overrides[] = R"(
+    {
+      "search_provider_overrides" : [
+        {
+          "keyword" : "badkeyword",
+          "name" : "badname",
+          "search_url" : "http://bad_default_engine/search?q=dirty_user_query",
+          "encoding" : "utf-8",
+          "id" : 1
+        }, {
+          "keyword" : "badkeyword2",
+          "name" : "badname2",
+          "search_url" : "http://bad_default_engine2/search?q=dirty_user_query",
+          "encoding" : "utf-8",
+          "id" : 2
+        }
+      ]
+    })";
+    static constexpr char default_search_provider[] = R"(
+    {
+      "default_search_provider" : {
+        "keyword" : "badkeyword",
+        "name" : "badname",
+        "search_url" : "http://bad_default_engine/search?q=dirty_user_query"
+      }
+    })";
+
+    // Try to override default search in all three of available preferences.
+    auto attack1 = base::DictionaryValue::From(
+        base::JSONReader::Read(default_search_provider_data));
+    auto attack2 = base::DictionaryValue::From(
+        base::JSONReader::Read(search_provider_overrides));
+    auto attack3 = base::DictionaryValue::From(
+        base::JSONReader::Read(default_search_provider));
+    unprotected_preferences->MergeDictionary(attack1.get());
+    unprotected_preferences->MergeDictionary(attack2.get());
+    unprotected_preferences->MergeDictionary(attack3.get());
+    if (protected_preferences) {
+      // Override here, too.
+      protected_preferences->MergeDictionary(attack1.get());
+      protected_preferences->MergeDictionary(attack2.get());
+      protected_preferences->MergeDictionary(attack3.get());
+    }
+  }
+
+  void VerifyReactionToPrefAttack() override {
+    DefaultSearchManager default_search_manager(
+        profile()->GetPrefs(), DefaultSearchManager::ObserverCallback());
+    DefaultSearchManager::Source dse_source =
+        static_cast<DefaultSearchManager::Source>(-1);
+
+    const TemplateURLData* current_dse =
+        default_search_manager.GetDefaultSearchEngine(&dse_source);
+
+    if (protection_level_ < PROTECTION_ENABLED_DSE) {
+// This doesn't work on OS_CHROMEOS because we fail to attack Preferences.
+#if !defined(OS_CHROMEOS)
+      // Attack is successful.
+      EXPECT_EQ(DefaultSearchManager::FROM_USER, dse_source);
+      EXPECT_EQ(current_dse->keyword(), base::UTF8ToUTF16("badkeyword"));
+      EXPECT_EQ(current_dse->short_name(), base::UTF8ToUTF16("badname"));
+      EXPECT_EQ(current_dse->url(),
+                "http://bad_default_engine/search?q=dirty_user_query");
+#endif
+    } else {
+      // Attack fails.
+      EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK, dse_source);
+      EXPECT_NE(current_dse->keyword(), base::UTF8ToUTF16("badkeyword"));
+      EXPECT_NE(current_dse->short_name(), base::UTF8ToUTF16("badname"));
+      EXPECT_NE(current_dse->url(),
+                "http://bad_default_engine/search?q=dirty_user_query");
+    }
+  }
+};
+
+PREF_HASH_BROWSER_TEST(PrefHashBrowserTestDefaultSearch, SearchProtected);
diff --git a/chrome/browser/speech/tts_chromeos.cc b/chrome/browser/speech/tts_chromeos.cc
index d7f9465f9..cb7749a6 100644
--- a/chrome/browser/speech/tts_chromeos.cc
+++ b/chrome/browser/speech/tts_chromeos.cc
@@ -5,6 +5,7 @@
 #include "base/macros.h"
 #include "chrome/browser/speech/tts_platform.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_service_manager.h"
 #include "components/arc/common/tts.mojom.h"
 #include "content/public/browser/browser_thread.h"
 
@@ -17,10 +18,12 @@
 arc::mojom::TtsInstance* GetArcTts(const std::string& method_name_for_logging,
                                    uint32_t min_version) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  return arc::ArcBridgeService::Get()
-             ? arc::ArcBridgeService::Get()->tts()->GetInstanceForMethod(
-                   method_name_for_logging, min_version)
-             : nullptr;
+  auto* const arc_service_manager = arc::ArcServiceManager::Get();
+  if (!arc_service_manager)
+    return nullptr;
+
+  return arc_service_manager->arc_bridge_service()->tts()->GetInstanceForMethod(
+      method_name_for_logging, min_version);
 }
 
 }  // namespace
@@ -31,8 +34,11 @@
  public:
   // TtsPlatformImpl overrides:
   bool PlatformImplAvailable() override {
-    return arc::ArcBridgeService::Get() &&
-           arc::ArcBridgeService::Get()->tts()->has_instance();
+    return arc::ArcServiceManager::Get() &&
+           arc::ArcServiceManager::Get()
+               ->arc_bridge_service()
+               ->tts()
+               ->has_instance();
   }
 
   bool LoadBuiltInTtsExtension(
diff --git a/chrome/browser/task_manager/providers/arc/arc_process_task.cc b/chrome/browser/task_manager/providers/arc/arc_process_task.cc
index b664ec71..bc19b00f 100644
--- a/chrome/browser/task_manager/providers/arc/arc_process_task.cc
+++ b/chrome/browser/task_manager/providers/arc/arc_process_task.cc
@@ -107,12 +107,18 @@
 
   if (result == arc::ActivityIconLoader::GetResult::FAILED_ARC_NOT_READY) {
     // Need to retry loading the icon.
-    arc::ArcBridgeService::Get()->intent_helper()->AddObserver(this);
+    arc::ArcServiceManager::Get()
+        ->arc_bridge_service()
+        ->intent_helper()
+        ->AddObserver(this);
   }
 }
 
 ArcProcessTask::~ArcProcessTask() {
-  arc::ArcBridgeService::Get()->intent_helper()->RemoveObserver(this);
+  arc::ArcServiceManager::Get()
+      ->arc_bridge_service()
+      ->intent_helper()
+      ->RemoveObserver(this);
 }
 
 Task::Type ArcProcessTask::GetType() const {
@@ -131,8 +137,10 @@
 
 void ArcProcessTask::Kill() {
   auto* process_instance =
-      arc::ArcBridgeService::Get()->process()->GetInstanceForMethod(
-          "KillProcess", kKillProcessMinInstanceVersion);
+      arc::ArcServiceManager::Get()
+          ->arc_bridge_service()
+          ->process()
+          ->GetInstanceForMethod("KillProcess", kKillProcessMinInstanceVersion);
   if (!process_instance)
     return;
   process_instance->KillProcess(nspid_, "Killed manually from Task Manager");
@@ -143,7 +151,10 @@
 
   VLOG(2) << "intent_helper instance is ready. Fetching the icon for "
           << package_name_;
-  arc::ArcBridgeService::Get()->intent_helper()->RemoveObserver(this);
+  arc::ArcServiceManager::Get()
+      ->arc_bridge_service()
+      ->intent_helper()
+      ->RemoveObserver(this);
 
   // Instead of calling into StartIconLoading() directly, return to the main
   // loop first to make sure other ArcBridgeService observers are notified.
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
index c64051c..c7c8218 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -21,7 +21,7 @@
 #include "chrome/browser/ui/app_list/arc/arc_package_syncable_service.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
-#include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_service_manager.h"
 #include "components/crx_file/id_util.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/scoped_user_pref_update.h"
@@ -255,16 +255,12 @@
 }
 
 ArcAppListPrefs::~ArcAppListPrefs() {
-  // A reference to ArcBridgeService is kept here so that it would crash the
-  // tests where ArcBridgeService and ArcAppListPrefs are not destroyed in right
-  // order.
-  arc::ArcBridgeService* bridge_service = arc::ArcBridgeService::Get();
-  if (bridge_service)
-    app_instance_holder_->RemoveObserver(this);
-
   arc::ArcSessionManager* arc_session_manager = arc::ArcSessionManager::Get();
-  if (arc_session_manager)
-    arc_session_manager->RemoveObserver(this);
+  if (!arc_session_manager)
+    return;
+  DCHECK(arc::ArcServiceManager::Get());
+  arc_session_manager->RemoveObserver(this);
+  app_instance_holder_->RemoveObserver(this);
 }
 
 void ArcAppListPrefs::StartPrefs() {
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.cc
index 543e394..f77c557 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.cc
@@ -8,6 +8,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_service_manager.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "content/public/browser/browser_context.h"
 
@@ -58,11 +59,12 @@
         profile, sync_test_app_instance_holders_[context].get());
   }
 
-  arc::ArcBridgeService* bridge_service = arc::ArcBridgeService::Get();
-  if (!bridge_service)
+  auto* arc_service_manager = arc::ArcServiceManager::Get();
+  if (!arc_service_manager)
     return nullptr;
 
-  return ArcAppListPrefs::Create(profile, bridge_service->app());
+  return ArcAppListPrefs::Create(
+      profile, arc_service_manager->arc_bridge_service()->app());
 }
 
 content::BrowserContext* ArcAppListPrefsFactory::GetBrowserContextToUse(
diff --git a/chrome/browser/ui/app_list/arc/arc_app_test.cc b/chrome/browser/ui/app_list/arc/arc_app_test.cc
index 380890d..858101b 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_test.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_test.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/app_list/arc/arc_app_test.h"
 
 #include "base/command_line.h"
+#include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/chromeos/arc/arc_session_manager.h"
@@ -17,6 +18,7 @@
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_service_manager.h"
 #include "components/arc/test/fake_app_instance.h"
 #include "components/arc/test/fake_arc_bridge_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -76,9 +78,11 @@
     ArcAppListPrefsFactory::GetInstance()->RecreateServiceInstanceForTesting(
         profile_);
   }
-  bridge_service_.reset(new arc::FakeArcBridgeService());
-
-  arc_session_manager_.reset(new arc::ArcSessionManager(bridge_service_.get()));
+  arc::ArcServiceManager::SetArcBridgeServiceForTesting(
+      base::MakeUnique<arc::FakeArcBridgeService>());
+  arc_service_manager_ = base::MakeUnique<arc::ArcServiceManager>(nullptr);
+  arc_session_manager_ = base::MakeUnique<arc::ArcSessionManager>(
+      arc_service_manager_->arc_bridge_service());
   DCHECK(arc::ArcSessionManager::Get());
   arc::ArcSessionManager::DisableUIForTesting();
   arc_session_manager_->OnPrimaryUserProfilePrepared(profile_);
@@ -91,11 +95,11 @@
 
   arc_session_manager_->EnableArc();
   app_instance_.reset(new arc::FakeAppInstance(arc_app_list_pref_));
-  bridge_service_->app()->SetInstance(app_instance_.get());
+  arc_service_manager_->arc_bridge_service()->app()->SetInstance(
+      app_instance_.get());
 
   // Check initial conditions.
-  EXPECT_EQ(bridge_service_.get(), arc::ArcBridgeService::Get());
-  EXPECT_FALSE(arc::ArcBridgeService::Get()->ready());
+  EXPECT_FALSE(arc_service_manager_->arc_bridge_service()->ready());
 }
 
 void ArcAppTest::CreateFakeAppsAndPackages() {
@@ -161,7 +165,7 @@
 void ArcAppTest::TearDown() {
   app_instance_.reset();
   arc_session_manager_.reset();
-  bridge_service_.reset();
+  arc_service_manager_.reset();
   if (dbus_thread_manager_initialized_) {
     // DBusThreadManager may be initialized from other testing utility,
     // such as ash::test::AshTestHelper::SetUp(), so Shutdown() only when
@@ -173,13 +177,14 @@
 }
 
 void ArcAppTest::StopArcInstance() {
-  bridge_service_->app()->SetInstance(nullptr);
+  arc_service_manager_->arc_bridge_service()->app()->SetInstance(nullptr);
 }
 
 void ArcAppTest::RestartArcInstance() {
-  bridge_service_->app()->SetInstance(nullptr);
-  app_instance_.reset(new arc::FakeAppInstance(arc_app_list_pref_));
-  bridge_service_->app()->SetInstance(app_instance_.get());
+  auto* bridge_service = arc_service_manager_->arc_bridge_service();
+  bridge_service->app()->SetInstance(nullptr);
+  app_instance_ = base::MakeUnique<arc::FakeAppInstance>(arc_app_list_pref_);
+  bridge_service->app()->SetInstance(app_instance_.get());
 }
 
 const user_manager::User* ArcAppTest::CreateUserAndLogin() {
diff --git a/chrome/browser/ui/app_list/arc/arc_app_test.h b/chrome/browser/ui/app_list/arc/arc_app_test.h
index a5453a3..077510b 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_test.h
+++ b/chrome/browser/ui/app_list/arc/arc_app_test.h
@@ -17,8 +17,8 @@
 class AppInfo;
 class ArcPackageInfo;
 }
+class ArcServiceManager;
 class ArcSessionManager;
-class FakeArcBridgeService;
 class FakeAppInstance;
 }
 
@@ -73,8 +73,6 @@
 
   chromeos::FakeChromeUserManager* GetUserManager();
 
-  arc::FakeArcBridgeService* bridge_service() { return bridge_service_.get(); }
-
   arc::FakeAppInstance* app_instance() { return app_instance_.get(); }
 
   ArcAppListPrefs* arc_app_list_prefs() { return arc_app_list_pref_; }
@@ -82,6 +80,9 @@
   arc::ArcSessionManager* arc_session_manager() {
     return arc_session_manager_.get();
   }
+  arc::ArcServiceManager* arc_service_manager() {
+    return arc_service_manager_.get();
+  }
 
  private:
   const user_manager::User* CreateUserAndLogin();
@@ -93,9 +94,10 @@
 
   ArcAppListPrefs* arc_app_list_pref_ = nullptr;
 
-  std::unique_ptr<arc::FakeArcBridgeService> bridge_service_;
-  std::unique_ptr<arc::FakeAppInstance> app_instance_;
+  std::unique_ptr<arc::ArcServiceManager> arc_service_manager_;
   std::unique_ptr<arc::ArcSessionManager> arc_session_manager_;
+  std::unique_ptr<arc::FakeAppInstance> app_instance_;
+
   std::unique_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_;
   std::vector<arc::mojom::AppInfo> fake_apps_;
   std::vector<arc::mojom::AppInfo> fake_default_apps_;
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.cc b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
index f96112e..fc90010 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_utils.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
@@ -20,6 +20,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager_client.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_service_manager.h"
 #include "components/arc/common/intent_helper.mojom.h"
 #include "ui/aura/window.h"
 #include "ui/display/display.h"
@@ -69,15 +70,15 @@
 // happens.
 arc::mojom::AppInstance* GetAppInstance(uint32_t required_version,
                                         const std::string& service_name) {
-  arc::ArcBridgeService* bridge_service = arc::ArcBridgeService::Get();
-  if (!bridge_service) {
+  auto* arc_service_manager = arc::ArcServiceManager::Get();
+  if (!arc_service_manager) {
     VLOG(2) << "Request to " << service_name
             << " when bridge service is not ready.";
     return nullptr;
   }
 
-  return bridge_service->app()->GetInstanceForMethod(service_name.c_str(),
-                                                     required_version);
+  return arc_service_manager->arc_bridge_service()->app()->GetInstanceForMethod(
+      service_name, required_version);
 }
 
 // Helper function which returns the IntentHelperInstance. Create related logs
@@ -85,15 +86,16 @@
 arc::mojom::IntentHelperInstance* GetIntentHelperInstance(
     uint32_t required_version,
     const std::string& service_name) {
-  arc::ArcBridgeService* bridge_service = arc::ArcBridgeService::Get();
-  if (!bridge_service) {
+  auto* arc_service_manager = arc::ArcServiceManager::Get();
+  if (!arc_service_manager) {
     VLOG(2) << "Request to " << service_name
             << " when bridge service is not ready.";
     return nullptr;
   }
 
-  return bridge_service->intent_helper()->GetInstanceForMethod(
-      service_name.c_str(), required_version);
+  return arc_service_manager->arc_bridge_service()
+      ->intent_helper()
+      ->GetInstanceForMethod(service_name, required_version);
 }
 
 void PrioritizeArcInstanceCallback(bool success) {
diff --git a/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc b/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc
index 3fd3dc4..a3816d76a 100644
--- a/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chromeos/chromeos_switches.h"
-#include "components/arc/arc_bridge_service.h"
 #include "components/arc/common/app.mojom.h"
 #include "components/arc/test/fake_app_instance.h"
 #include "content/public/test/test_utils.h"
@@ -37,15 +36,12 @@
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
         chromeos::switches::kEnableArc);
 
-    // A valid |arc_app_list_prefs_| is needed for the Arc bridge service and
-    // the Arc session manager.
     arc_app_list_pref_ = ArcAppListPrefs::Get(profile_);
     if (!arc_app_list_pref_) {
       ArcAppListPrefsFactory::GetInstance()->RecreateServiceInstanceForTesting(
           profile_);
     }
 
-    DCHECK(ArcBridgeService::Get());
     ArcSessionManager* session_manager = ArcSessionManager::Get();
     DCHECK(session_manager);
     ArcSessionManager::DisableUIForTesting();
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 2bbc8a6..13c35f6 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-9056.0.0
\ No newline at end of file
+9059.0.0
\ No newline at end of file
diff --git a/components/arc/arc_service_manager.cc b/components/arc/arc_service_manager.cc
index c871824..fd92b9d 100644
--- a/components/arc/arc_service_manager.cc
+++ b/components/arc/arc_service_manager.cc
@@ -51,7 +51,8 @@
 
 // static
 ArcServiceManager* ArcServiceManager::Get() {
-  DCHECK(g_arc_service_manager);
+  if (!g_arc_service_manager)
+    return nullptr;
   DCHECK(g_arc_service_manager->thread_checker_.CalledOnValidThread());
   return g_arc_service_manager;
 }
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge.cc b/components/arc/intent_helper/arc_intent_helper_bridge.cc
index 391c28e..53b0b414 100644
--- a/components/arc/intent_helper/arc_intent_helper_bridge.cc
+++ b/components/arc/intent_helper/arc_intent_helper_bridge.cc
@@ -14,6 +14,7 @@
 #include "base/command_line.h"
 #include "base/memory/weak_ptr.h"
 #include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_service_manager.h"
 #include "components/arc/intent_helper/activity_icon_loader.h"
 #include "components/arc/intent_helper/link_handler_model_impl.h"
 #include "components/arc/intent_helper/local_activity_resolver.h"
@@ -130,8 +131,8 @@
     const std::string& method_name_for_logging,
     uint32_t min_instance_version,
     GetResult* out_error_code) {
-  ArcBridgeService* bridge_service = ArcBridgeService::Get();
-  if (!bridge_service) {
+  auto* arc_service_manager = ArcServiceManager::Get();
+  if (!arc_service_manager) {
     if (!ArcBridgeService::GetEnabled(base::CommandLine::ForCurrentProcess())) {
       VLOG(2) << "ARC bridge is not supported.";
       if (out_error_code)
@@ -144,14 +145,16 @@
     return nullptr;
   }
 
-  if (!bridge_service->intent_helper()->has_instance()) {
+  auto* intent_helper_holder =
+      arc_service_manager->arc_bridge_service()->intent_helper();
+  if (!intent_helper_holder->has_instance()) {
     VLOG(2) << "ARC intent helper instance is not ready.";
     if (out_error_code)
       *out_error_code = GetResult::FAILED_ARC_NOT_READY;
     return nullptr;
   }
 
-  auto* instance = bridge_service->intent_helper()->GetInstanceForMethod(
+  auto* instance = intent_helper_holder->GetInstanceForMethod(
       method_name_for_logging, min_instance_version);
   if (!instance) {
     if (out_error_code)
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 968802f5..625c629 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -1817,8 +1817,14 @@
 
   size_t malloc_usage = 0;
   std::unique_ptr<HANDLE[]> heaps(new HANDLE[number_of_heaps]);
-  ::GetProcessHeaps(number_of_heaps, heaps.get());
-  for (size_t i = 0; i < number_of_heaps; i++) {
+  // If some heaps were gone between the first GetProcessHeaps and here,
+  // GetProcessHeaps obtains small number of heaps.
+  // If some new heaps were available between the first GetProcessHeaps and
+  // here, GetProcessHeaps returns larger number than number_of_heaps.
+  // So we need to see min(number_of_obtained_heaps, number_of_heaps).
+  DWORD number_of_obtained_heaps =
+      ::GetProcessHeaps(number_of_heaps, heaps.get());
+  for (size_t i = 0; i < number_of_heaps && i < number_of_obtained_heaps; i++) {
     PROCESS_HEAP_ENTRY heap_entry;
     ::HeapLock(heaps[i]);
     heap_entry.lpData = NULL;
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
index 92b9b11..0db1e47 100644
--- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -43,6 +43,7 @@
     # All platforms.
     self.Flaky('conformance2/query/occlusion-query.html', bug=603168)
     self.Fail('conformance2/glsl3/tricky-loop-conditions.html', bug=483282)
+    self.Flaky('conformance2/misc/uninitialized-test-2.html', bug=671791)
     self.Fail('conformance2/rendering/depth-stencil-feedback-loop.html',
         bug=660844) # WebGL 2.0.1
     self.Fail('conformance2/rendering/rendering-sampling-feedback-loop.html',
@@ -622,8 +623,6 @@
     self.Fail('deqp/functional/gles3/transformfeedback/array_separate*.html',
         ['linux', 'amd'], bug=483282)
 
-    self.Fail('conformance2/misc/uninitialized-test-2.html',
-        ['linux', 'amd'], bug=483282)
     self.Fail('conformance2/rendering/blitframebuffer-filter-srgb.html',
         ['linux', 'amd'], bug=634525)
     self.Fail('conformance2/rendering/blitframebuffer-outside-readbuffer.html',
diff --git a/docs/android_build_instructions.md b/docs/android_build_instructions.md
index 6244076d..ee3c399e 100644
--- a/docs/android_build_instructions.md
+++ b/docs/android_build_instructions.md
@@ -98,10 +98,6 @@
 Android-specific dependencies (you need some of the regular Linux dependencies
 because an Android build includes a bunch of the Linux tools and utilities).
 
-*** aside
-If you're running Debian, you'll also need to install the package `lib32z1`.
-***
-
 ### Run the hooks
 
 Once you've run `install-build-deps` at least once, you can now run the
diff --git a/extensions/browser/app_window/app_window.cc b/extensions/browser/app_window/app_window.cc
index 682ac11..69126c3 100644
--- a/extensions/browser/app_window/app_window.cc
+++ b/extensions/browser/app_window/app_window.cc
@@ -303,16 +303,9 @@
 
   UpdateExtensionAppIcon();
   // Download showInShelf=true window icon.
-  if (window_icon_url_.is_valid()) {
-    image_loader_ptr_factory_.InvalidateWeakPtrs();
-    web_contents()->DownloadImage(
-        window_icon_url_,
-        true,   // is a favicon
-        0,      // no maximum size
-        false,  // normal cache policy
-        base::Bind(&AppWindow::DidDownloadFavicon,
-                   image_loader_ptr_factory_.GetWeakPtr()));
-  }
+  if (window_icon_url_.is_valid())
+    SetAppIconUrl(window_icon_url_);
+
   AppWindowRegistry::Get(browser_context_)->AddAppWindow(this);
 
   if (new_params.hidden) {
@@ -573,9 +566,13 @@
   image_loader_ptr_factory_.InvalidateWeakPtrs();
 
   // Reset |app_icon_image_| to abort pending image load (if any).
-  app_icon_image_.reset();
+  if (!show_in_shelf_) {
+    app_icon_image_.reset();
+    app_icon_url_ = url;
+  } else {
+    window_icon_url_ = url;
+  }
 
-  app_icon_url_ = url;
   web_contents()->DownloadImage(
       url,
       true,   // is a favicon
@@ -604,8 +601,20 @@
             ? image
             : gfx::Image(*ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
                   IDR_APP_DEFAULT_ICON));
-    app_icon_ = gfx::Image(gfx::ImageSkiaOperations::CreateIconWithBadge(
-        base_image.AsImageSkia(), app_icon_image_->image_skia()));
+    // Scale the icon to EXTENSION_ICON_LARGE.
+    const int large_icon_size = extension_misc::EXTENSION_ICON_LARGE;
+    if (base_image.Width() != large_icon_size ||
+        base_image.Height() != large_icon_size) {
+      gfx::ImageSkia resized_image =
+          gfx::ImageSkiaOperations::CreateResizedImage(
+              base_image.AsImageSkia(), skia::ImageOperations::RESIZE_BEST,
+              gfx::Size(large_icon_size, large_icon_size));
+      app_icon_ = gfx::Image(gfx::ImageSkiaOperations::CreateIconWithBadge(
+          resized_image, app_icon_image_->image_skia()));
+    } else {
+      app_icon_ = gfx::Image(gfx::ImageSkiaOperations::CreateIconWithBadge(
+          base_image.AsImageSkia(), app_icon_image_->image_skia()));
+    }
   } else {
     if (image.IsEmpty())
       return;
@@ -818,7 +827,9 @@
 void AppWindow::OnExtensionIconImageChanged(IconImage* image) {
   DCHECK_EQ(app_icon_image_.get(), image);
 
-  UpdateAppIcon(gfx::Image(app_icon_image_->image_skia()));
+  // Update app_icon if no valid window icon url is set.
+  if (!window_icon_url_.is_valid())
+    UpdateAppIcon(gfx::Image(app_icon_image_->image_skia()));
 }
 
 void AppWindow::UpdateExtensionAppIcon() {
diff --git a/ios/build/chrome_build.gni b/ios/build/chrome_build.gni
new file mode 100644
index 0000000..a5a1394
--- /dev/null
+++ b/ios/build/chrome_build.gni
@@ -0,0 +1,57 @@
+# Copyright 2016 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.
+
+import("//build/config/chrome_build.gni")
+import("//build/config/ios/ios_sdk.gni")
+import("//build/config/mac/symbols.gni")
+
+declare_args() {
+  # Enable today extension.
+  ios_enable_today_extension = true
+
+  # Enable share extension.
+  ios_enable_share_extension = true
+
+  # Value of the encryption export compliance code. See "Cryptography and
+  # U.S. Export Compliance" in "Submitting the App to App Review" in the
+  # Apple developer documentation (https://goo.gl/yv1xEF).
+  ios_encryption_export_compliance_code = ""
+
+  # List of plist templates to merge when generating chrome Info.plist.
+  ios_chrome_info_plist_additions = []
+
+  # List of plist templates to merge when generating chrome entitlements.
+  ios_chrome_entitlements_additions = []
+}
+
+# Configure whether breakpad support is enabled.
+breakpad_enabled = is_official_build && is_chrome_branded
+
+if (breakpad_enabled) {
+  breakpad_enabled_as_int = 1
+  is_official_release = enable_dsyms && !use_ios_simulator &&
+                        current_toolchain == default_toolchain
+} else {
+  breakpad_enabled_as_int = 0
+  is_official_release = false
+}
+
+chromium_bundle_id = "chrome.ios.herebedragons"
+chromium_handoff_id = "$ios_app_bundle_id_prefix.chrome.handoff"
+
+if (is_chrome_branded) {
+  chromium_short_name = "Chrome"
+  url_channel_scheme = "googlechrome-dev"
+  url_secure_scheme = "googlechromes"
+  url_ssoauth_scheme = "$ios_app_bundle_id_prefix.sso.chrome.stable"
+  url_unsecure_scheme = "googlechrome"
+  url_x_callback_scheme = "googlechrome-x-callback"
+} else {
+  chromium_short_name = "Chromium"
+  url_channel_scheme = "chromium-dev"
+  url_secure_scheme = "chromiums"
+  url_ssoauth_scheme = "$ios_app_bundle_id_prefix.sso.chromium"
+  url_unsecure_scheme = "chromium"
+  url_x_callback_scheme = "chromium-x-callback"
+}
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn
index 4d197e3..9dcfaf89 100644
--- a/ios/chrome/app/BUILD.gn
+++ b/ios/chrome/app/BUILD.gn
@@ -2,6 +2,10 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/ios/rules.gni")
+import("//build/mac/tweak_info_plist.gni")
+import("//ios/build/chrome_build.gni")
+
 source_set("app") {
   sources = [
     "deferred_initialization_runner.h",
@@ -60,3 +64,33 @@
     "{{bundle_resources_dir}}/{{source_file_part}}",
   ]
 }
+
+tweak_info_plist("info_plist") {
+  info_plists = [
+    "resources/Info.plist",
+    "resources/ChromeAddition+Info.plist",
+  ]
+  if (ios_chrome_info_plist_additions != []) {
+    info_plists += ios_chrome_info_plist_additions
+  }
+  if (ios_encryption_export_compliance_code != "") {
+    info_plists += [ "resources/EncryptionExportCompliance+Info.plist" ]
+  }
+  args = [
+    "--breakpad=$breakpad_enabled_as_int",
+    "--branding=$chromium_short_name",
+  ]
+}
+
+compile_plist("entitlements") {
+  format = "xml1"
+  plist_templates = [ "resources/Chrome.entitlements" ]
+  if (ios_chrome_entitlements_additions != []) {
+    plist_templates += ios_chrome_entitlements_additions
+  }
+  if (!ios_automatically_manage_certs) {
+    plist_templates += [ "resources/AssociatedDomains.entitlements" ]
+  }
+  substitutions = [ "IOS_BUNDLE_ID_PREFIX=$ios_app_bundle_id_prefix" ]
+  output_name = "$target_gen_dir/$chromium_short_name.entitlements"
+}
diff --git a/ios/chrome/app/resources/AssociatedDomains.entitlements b/ios/chrome/app/resources/AssociatedDomains.entitlements
new file mode 100644
index 0000000..d8cf1bd
--- /dev/null
+++ b/ios/chrome/app/resources/AssociatedDomains.entitlements
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>com.apple.developer.associated-domains</key>
+	<array>
+		<string>applinks:goo.gl</string>
+	</array>
+</dict>
+</plist>
diff --git a/ios/chrome/app/resources/BUILD.gn b/ios/chrome/app/resources/BUILD.gn
index 59974ad6..f83e2dc4 100644
--- a/ios/chrome/app/resources/BUILD.gn
+++ b/ios/chrome/app/resources/BUILD.gn
@@ -80,6 +80,20 @@
   ]
 }
 
+bundle_data("quick_action_icons") {
+  sources = [
+    "quick_action_new_incognito_tab@2x.png",
+    "quick_action_new_incognito_tab@3x.png",
+    "quick_action_new_tab@2x.png",
+    "quick_action_new_tab@3x.png",
+    "quick_action_voice_search@2x.png",
+    "quick_action_voice_search@3x.png",
+  ]
+  outputs = [
+    "{{bundle_resources_dir}}/{{source_file_part}}",
+  ]
+}
+
 bundle_data("launchscreen_assets") {
   sources = [
     "launchscreen_images.xcassets/Contents.json",
diff --git a/ios/chrome/app/resources/Chrome.entitlements b/ios/chrome/app/resources/Chrome.entitlements
new file mode 100644
index 0000000..ece1274
--- /dev/null
+++ b/ios/chrome/app/resources/Chrome.entitlements
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>application-identifier</key>
+	<string>$(AppIdentifierPrefix)$(CFBundleIdentifier)</string>
+	<key>com.apple.security.application-groups</key>
+	<array>
+		<string>group.${IOS_BUNDLE_ID_PREFIX}.chrome</string>
+	</array>
+</dict>
+</plist>
diff --git a/ios/chrome/app/resources/ChromeAddition+Info.plist b/ios/chrome/app/resources/ChromeAddition+Info.plist
new file mode 100644
index 0000000..d316b24b
--- /dev/null
+++ b/ios/chrome/app/resources/ChromeAddition+Info.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>UIApplicationDelegate</key>
+	<string>MainApplicationDelegate</string>
+</dict>
+</plist>
diff --git a/ios/chrome/app/resources/EarlGreyAddition+Info.plist b/ios/chrome/app/resources/EarlGreyAddition+Info.plist
new file mode 100644
index 0000000..46ef4149
--- /dev/null
+++ b/ios/chrome/app/resources/EarlGreyAddition+Info.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>UIApplicationDelegate</key>
+	<string>${EG_MAIN_APPLICATION_DELEGATE}</string>
+	<key>UIFileSharingEnabled</key>
+	<true/>
+</dict>
+</plist>
diff --git a/ios/chrome/app/resources/EncryptionExportCompliance+Info.plist b/ios/chrome/app/resources/EncryptionExportCompliance+Info.plist
new file mode 100644
index 0000000..a784434
--- /dev/null
+++ b/ios/chrome/app/resources/EncryptionExportCompliance+Info.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ITSAppUsesNonExemptEncryption</key>
+	<true/>
+	<key>ITSEncryptionExportComplianceCode</key>
+	<string>${ENCRYPTION_EXPORT_COMPLIANCE_CODE}</string>
+</dict>
+</plist>
diff --git a/ios/chrome/app/resources/Info.plist b/ios/chrome/app/resources/Info.plist
new file mode 100644
index 0000000..3950ccd2
--- /dev/null
+++ b/ios/chrome/app/resources/Info.plist
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDisplayName</key>
+	<string>${CHROMIUM_SHORT_NAME}</string>
+	<key>CFBundleDocumentTypes</key>
+	<array>
+		<dict>
+			<key>LSItemContentTypes</key>
+			<array>
+				<string>com.adobe.pdf</string>
+			</array>
+			<key>CFBundleTypeName</key>
+			<string>PDF</string>
+			<key>LSHandlerRank</key>
+			<string>Alternate</string>
+		</dict>
+	</array>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIcons</key>
+	<dict>
+		<key>CFBundlePrimaryIcon</key>
+		<dict>
+			<key>CFBundleIconFiles</key>
+			<array>
+				<string>Icon-120.png</string>
+				<string>Icon-152.png</string>
+				<string>Icon-167.png</string>
+				<string>Icon-180.png</string>
+				<string>Icon-29.png</string>
+				<string>Icon-40.png</string>
+				<string>Icon-58.png</string>
+				<string>Icon-76.png</string>
+				<string>Icon-80.png</string>
+				<string>Icon-87.png</string>
+			</array>
+			<key>UIPrerenderedIcon</key>
+			<true/>
+		</dict>
+	</dict>
+	<key>CFBundleIdentifier</key>
+	<string>${IOS_BUNDLE_ID_PREFIX}.${CHROMIUM_BUNDLE_ID:rfc1034identifier}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${CHROMIUM_SHORT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleURLTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleURLName</key>
+			<string>${IOS_BUNDLE_ID_PREFIX}.${CHROMIUM_BUNDLE_ID:rfc1034identifier}</string>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>${CHROMIUM_URL_SCHEME_1}</string>
+				<string>${CHROMIUM_URL_SCHEME_2}</string>
+				<string>${CHROMIUM_URL_SCHEME_3}</string>
+				<string>${CHROMIUM_URL_SCHEME_4}</string>
+				<string>${SSOAUTH_URL_SCHEME}</string>
+			</array>
+		</dict>
+	</array>
+	<key>CFBundleVersion</key>
+	<string>0.0.0</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>NSAppTransportSecurity</key>
+	<dict>
+		<key>NSAllowsArbitraryLoads</key>
+		<true/>
+	</dict>
+	<key>NSUserActivityTypes</key>
+	<array>
+		<string>${CHROMIUM_HANDOFF_ID}</string>
+	</array>
+	<key>UIBackgroundModes</key>
+	<array>
+		<string>fetch</string>
+		<string>audio</string>
+	</array>
+	<key>UIApplicationShortcutItems</key>
+	<array>
+		<dict>
+			<key>UIApplicationShortcutItemIconFile</key>
+			<string>quick_action_new_tab</string>
+			<key>UIApplicationShortcutItemTitle</key>
+			<string>IDS_IOS_APPLICATION_SHORTCUT_NEWTAB_TITLE</string>
+			<key>UIApplicationShortcutItemType</key>
+			<string>OpenNewTab</string>
+		</dict>
+		<dict>
+			<key>UIApplicationShortcutItemIconFile</key>
+			<string>quick_action_new_incognito_tab</string>
+			<key>UIApplicationShortcutItemTitle</key>
+			<string>IDS_IOS_APPLICATION_SHORTCUT_NEWINCOGNITOTAB_TITLE</string>
+			<key>UIApplicationShortcutItemType</key>
+			<string>OpenIncognitoTab</string>
+		</dict>
+		<dict>
+			<key>UIApplicationShortcutItemIconFile</key>
+			<string>quick_action_voice_search</string>
+			<key>UIApplicationShortcutItemTitle</key>
+			<string>IDS_IOS_APPLICATION_SHORTCUT_VOICE_SEARCH_TITLE</string>
+			<key>UIApplicationShortcutItemType</key>
+			<string>OpenVoiceSearch</string>
+		</dict>
+	</array>
+	<key>UIPrerenderedIcon</key>
+	<true/>
+	<key>UIRequiresPersistentWiFi</key>
+	<true/>
+	<key>UIStatusBarStyle</key>
+	<string>UIStatusBarStyleLightContent</string>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UTImportedTypeDeclarations</key>
+	<array>
+		<dict>
+			<key>UTTypeConformsTo</key>
+			<array>
+				<string>public.url</string>
+				<string>org.appextension.find-login-action</string>
+			</array>
+			<key>UTTypeDescription</key>
+			<string>Chrome Password Fill by App Extension Action</string>
+			<key>UTTypeIdentifier</key>
+			<string>org.appextension.chrome-password-action</string>
+		</dict>
+		<dict>
+			<key>UTTypeConformsTo</key>
+			<array>
+				<string>public.url</string>
+			</array>
+			<key>UTTypeDescription</key>
+			<string>1Password Find Login Action</string>
+			<key>UTTypeIdentifier</key>
+			<string>org.appextension.find-login-action</string>
+		</dict>
+	</array>
+	<key>UILaunchStoryboardName</key>
+	<string>LaunchScreen</string>
+	<key>SSOAuthURLScheme</key>
+	<string>${SSOAUTH_URL_SCHEME}</string>
+	<key>NSCameraUsageDescription</key>
+	<string>IDS_IOS_CAMERA_USAGE_DESCRIPTION</string>
+	<key>NSLocationWhenInUseUsageDescription</key>
+	<string>IDS_IOS_LOCATION_WHEN_IN_USE_USAGE_DESCRIPTION</string>
+	<key>NSMicrophoneUsageDescription</key>
+	<string>IDS_IOS_MICROPHONE_USAGE_DESCRIPTION</string>
+	<key>NSPhotoLibraryUsageDescription</key>
+	<string>IDS_IOS_PHOTO_LIBRARY_USAGE_DESCRIPTION</string>
+	<key>NSBluetoothPeripheralUsageDescription</key>
+	<string>IDS_IOS_BLUETOOTH_USAGE_DESCRIPTION</string>
+</dict>
+</plist>
diff --git a/ios/chrome/app/resources/quick_action_new_incognito_tab@2x.png b/ios/chrome/app/resources/quick_action_new_incognito_tab@2x.png
new file mode 100644
index 0000000..636b00b
--- /dev/null
+++ b/ios/chrome/app/resources/quick_action_new_incognito_tab@2x.png
Binary files differ
diff --git a/ios/chrome/app/resources/quick_action_new_incognito_tab@3x.png b/ios/chrome/app/resources/quick_action_new_incognito_tab@3x.png
new file mode 100644
index 0000000..b683c15a
--- /dev/null
+++ b/ios/chrome/app/resources/quick_action_new_incognito_tab@3x.png
Binary files differ
diff --git a/ios/chrome/app/resources/quick_action_new_tab@2x.png b/ios/chrome/app/resources/quick_action_new_tab@2x.png
new file mode 100644
index 0000000..45c4614
--- /dev/null
+++ b/ios/chrome/app/resources/quick_action_new_tab@2x.png
Binary files differ
diff --git a/ios/chrome/app/resources/quick_action_new_tab@3x.png b/ios/chrome/app/resources/quick_action_new_tab@3x.png
new file mode 100644
index 0000000..df4d68e
--- /dev/null
+++ b/ios/chrome/app/resources/quick_action_new_tab@3x.png
Binary files differ
diff --git a/ios/chrome/app/resources/quick_action_voice_search@2x.png b/ios/chrome/app/resources/quick_action_voice_search@2x.png
new file mode 100644
index 0000000..db711a6
--- /dev/null
+++ b/ios/chrome/app/resources/quick_action_voice_search@2x.png
Binary files differ
diff --git a/ios/chrome/app/resources/quick_action_voice_search@3x.png b/ios/chrome/app/resources/quick_action_voice_search@3x.png
new file mode 100644
index 0000000..cbb9647
--- /dev/null
+++ b/ios/chrome/app/resources/quick_action_voice_search@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn
index 135f162..9a17561 100644
--- a/ios/chrome/browser/ui/BUILD.gn
+++ b/ios/chrome/browser/ui/BUILD.gn
@@ -44,6 +44,7 @@
   deps = [
     "//base",
     "//base:i18n",
+    "//ios/chrome/app/resources:terms_of_service_bundle",
     "//ios/chrome/browser",
     "//ios/chrome/browser/favicon",
     "//ios/chrome/browser/ui/commands",
diff --git a/ios/public/provider/chrome/browser/build_config.gni b/ios/public/provider/chrome/browser/build_config.gni
index 14d9d84..aaf2ee9 100644
--- a/ios/public/provider/chrome/browser/build_config.gni
+++ b/ios/public/provider/chrome/browser/build_config.gni
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/config/chrome_build.gni")
-
 declare_args() {
   # Label of the target providing application icons.  This target must be a
   # bundle_data target that copy Icon-*.png files in the application bundle.
diff --git a/media/capture/BUILD.gn b/media/capture/BUILD.gn
index d5481f0..5c80e201 100644
--- a/media/capture/BUILD.gn
+++ b/media/capture/BUILD.gn
@@ -30,6 +30,8 @@
     "video/file_video_capture_device.h",
     "video/file_video_capture_device_factory.cc",
     "video/file_video_capture_device_factory.h",
+    "video/linux/camera_facing_chromeos.cc",
+    "video/linux/camera_facing_chromeos.h",
     "video/linux/v4l2_capture_delegate.cc",
     "video/linux/v4l2_capture_delegate.h",
     "video/linux/video_capture_device_chromeos.cc",
@@ -169,6 +171,7 @@
     "content/smooth_event_sampler_unittest.cc",
     "content/video_capture_oracle_unittest.cc",
     "video/fake_video_capture_device_unittest.cc",
+    "video/linux/camera_facing_chromeos_unittest.cc",
     "video/mac/video_capture_device_factory_mac_unittest.mm",
     "video/video_capture_device_unittest.cc",
   ]
diff --git a/media/capture/video/linux/camera_facing_chromeos.cc b/media/capture/video/linux/camera_facing_chromeos.cc
new file mode 100644
index 0000000..c8aedbd
--- /dev/null
+++ b/media/capture/video/linux/camera_facing_chromeos.cc
@@ -0,0 +1,185 @@
+// Copyright 2016 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 "camera_facing_chromeos.h"
+
+#include <base/files/file_util.h>
+#include <base/logging.h>
+#include <base/strings/stringprintf.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/string_piece.h>
+#include <base/strings/string_split.h>
+#include <base/strings/string_util.h>
+
+namespace media {
+
+namespace {
+
+bool GetCameraId(const base::StringPiece& sub_key, int* camera_id) {
+  const base::StringPiece camera_id_prefix = "camera";
+  if (!sub_key.starts_with(camera_id_prefix))
+    return false;
+  return base::StringToInt(sub_key.substr(camera_id_prefix.size()), camera_id);
+}
+}
+
+// /etc/camera/camera_characteristics.conf contains camera information which
+// driver cannot provide.
+static const char kCameraCharacteristicsConfigFile[] =
+    "/etc/camera/camera_characteristics.conf";
+static const char kLensFacing[] = "lens_facing";
+static const char kUsbVidPid[] = "usb_vid_pid";
+static const char kUsbPath[] = "usb_path";
+
+CameraFacingChromeOS::CameraFacingChromeOS() {
+  InitializeDeviceInfo(std::string(kCameraCharacteristicsConfigFile));
+}
+
+CameraFacingChromeOS::CameraFacingChromeOS(
+    const std::string& config_file_path) {
+  InitializeDeviceInfo(config_file_path);
+}
+
+CameraFacingChromeOS::~CameraFacingChromeOS() {}
+
+CameraFacingChromeOS::LensFacing CameraFacingChromeOS::GetCameraFacing(
+    const std::string& device_id,
+    const std::string& model_id) const {
+  std::string usb_id = GetUsbId(device_id);
+  const auto& usb_id_to_camera_id_const = usb_id_to_camera_id_;
+  const auto& model_id_to_camera_id_const = model_id_to_camera_id_;
+  const auto& camera_id_to_facing_const = camera_id_to_facing_;
+  auto usb_id_iter = usb_id_to_camera_id_const.find(usb_id);
+  int camera_id;
+  if (usb_id_iter == usb_id_to_camera_id_const.end()) {
+    // Can't find Usb ID. Fall back to use model_id.
+    auto model_id_iter = model_id_to_camera_id_const.find(model_id);
+    if (model_id_iter == model_id_to_camera_id_const.end()) {
+      DLOG(ERROR) << "Can't find model ID in config file: " << model_id;
+      return kLensFacingDefault;
+    }
+    camera_id = model_id_iter->second;
+  } else {
+    camera_id = usb_id_iter->second;
+  }
+
+  auto camera_id_iter = camera_id_to_facing_const.find(camera_id);
+  if (camera_id_iter == camera_id_to_facing_const.end()) {
+    DLOG(ERROR) << "Can't find lens_facing of camera ID " << camera_id
+                << " in config file";
+    return kLensFacingDefault;
+  }
+  return camera_id_iter->second;
+}
+
+std::string CameraFacingChromeOS::GetUsbId(const std::string& device_id) const {
+  // |device_id| is of the form "/dev/video2".  We want to retrieve "video2"
+  // into |file_name|.
+  const std::string device_dir = "/dev/";
+  if (!base::StartsWith(device_id, device_dir, base::CompareCase::SENSITIVE)) {
+    DLOG(ERROR) << "device_id is invalid: " << device_id;
+    return std::string();
+  }
+  const std::string file_name = device_id.substr(device_dir.length());
+
+  // Usb ID can be obtained by "readlink /sys/class/video4linux/video2/device".
+  const std::string symlink =
+      base::StringPrintf("/sys/class/video4linux/%s/device", file_name.c_str());
+  base::FilePath symlinkTarget;
+  if (!base::ReadSymbolicLink(base::FilePath(symlink), &symlinkTarget)) {
+    DPLOG(ERROR) << "Failed to readlink: " << symlink;
+    return std::string();
+  }
+
+  // |symlinkTarget| is of the format "../../../A-B:C.D". Remove the path
+  // prefix.
+  base::StringPiece usb_part = symlinkTarget.BaseName().value();
+
+  // |usb_part| is of the format "A-B:C.D" or "A-B.C:D". We want everything
+  // before ":".
+  std::vector<base::StringPiece> usb_id_pieces = base::SplitStringPiece(
+      usb_part, ":", base::WhitespaceHandling::TRIM_WHITESPACE,
+      base::SplitResult::SPLIT_WANT_ALL);
+
+  if (usb_id_pieces.empty()) {
+    DLOG(ERROR) << "Error after split: " << usb_part;
+    return std::string();
+  }
+  return usb_id_pieces[0].as_string();
+}
+
+void CameraFacingChromeOS::InitializeDeviceInfo(
+    const std::string& config_file_path) {
+  const base::FilePath path(config_file_path);
+  std::string content;
+  if (!base::ReadFileToString(path, &content)) {
+    DPLOG(ERROR) << "ReadFileToString fails";
+    return;
+  }
+  const std::vector<base::StringPiece> lines = base::SplitStringPiece(
+      content, "\n", base::WhitespaceHandling::TRIM_WHITESPACE,
+      base::SplitResult::SPLIT_WANT_NONEMPTY);
+
+  for (const base::StringPiece& line : lines) {
+    if (line.starts_with("#"))  // Ignore the comments that starts with "#".
+      continue;
+    const std::vector<base::StringPiece> key_value = base::SplitStringPiece(
+        line, "=", base::WhitespaceHandling::TRIM_WHITESPACE,
+        base::SplitResult::SPLIT_WANT_ALL);
+    if (key_value.size() != 2) {
+      DLOG(ERROR) << "Invalid line in config file: " << line;
+      continue;
+    }
+    const auto& key = key_value[0];
+    const auto& value = key_value[1];
+    const std::vector<base::StringPiece> sub_keys = base::SplitStringPiece(
+        key, ".", base::WhitespaceHandling::TRIM_WHITESPACE,
+        base::SplitResult::SPLIT_WANT_ALL);
+
+    if (sub_keys.size() < 1) {
+      DLOG(ERROR) << "No valid sub key exists. Line format is invalid: "
+                  << line;
+      continue;
+    }
+    int camera_id = 0;
+    if (!GetCameraId(sub_keys[0], &camera_id)) {
+      DLOG(ERROR) << "Invalid sub key for camera id: " << sub_keys[0];
+      continue;
+    }
+
+    if (sub_keys.size() == 2 && sub_keys[1] == kLensFacing) {
+      int lens_facing = -1;
+      if (!base::StringToInt(value, &lens_facing)) {
+        DLOG(ERROR) << "Invalid value for lens_facing: " << value;
+        continue;
+      }
+      switch (lens_facing) {
+        case LensFacing::FRONT:
+          camera_id_to_facing_[camera_id] = LensFacing::FRONT;
+          break;
+        case LensFacing::BACK:
+          camera_id_to_facing_[camera_id] = LensFacing::BACK;
+          break;
+        default:
+          DLOG(ERROR) << "Invalid value for lens_facing: " << lens_facing;
+          continue;
+      }
+    } else if (sub_keys.size() == 3 && sub_keys[2] == kUsbVidPid) {
+      if (value.empty()) {
+        DLOG(ERROR) << "model_id is empty";
+        continue;
+      }
+      model_id_to_camera_id_[value.as_string()] = camera_id;
+    } else if (sub_keys.size() == 3 && sub_keys[2] == kUsbPath) {
+      if (value.empty()) {
+        DLOG(ERROR) << "usb_path is empty";
+        continue;
+      }
+      usb_id_to_camera_id_[value.as_string()] = camera_id;
+    }
+    // Ignore unknown or unutilized attributes.
+  }
+}
+
+}  // namespace media
diff --git a/media/capture/video/linux/camera_facing_chromeos.h b/media/capture/video/linux/camera_facing_chromeos.h
new file mode 100644
index 0000000..e03a03f
--- /dev/null
+++ b/media/capture/video/linux/camera_facing_chromeos.h
@@ -0,0 +1,82 @@
+// Copyright 2016 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_CAPTURE_VIDEO_LINUX_CAMERA_FACING_CHROMEOS_H_
+#define MEDIA_CAPTURE_VIDEO_LINUX_CAMERA_FACING_CHROMEOS_H_
+
+#include <stddef.h>
+
+#include <string>
+#include <unordered_map>
+
+#include <base/strings/string_piece.h>
+#include "media/capture/capture_export.h"
+
+namespace media {
+
+// CameraFacingChromeOS reads the file /etc/camera/camera_characteristics.conf
+// and populates |camera_id_to_facing_|, |usb_id_to_camera_id_| and
+// |model_id_to_camera_id_|.
+//
+// Each line in the config file can be:
+// 1. Empty line
+// 2. Line starts with '#': comments
+// 3. Line follows the format:
+// camera[camera_id].[root_level_attribute]=[value] OR
+// camera[camera_id].module[module_id].[module_level_attribute]=[value]
+//
+// There are several assumptions of the config file:
+//  1. One camera ID has exactly one lens_facing attribute, at root level.
+//  2. usb_path is specified at module level. usb_path may not present at all,
+//  but if it presents, the same usb_path does not appear accross different
+//  camera IDs.
+//  3. usb_vid_pid is specified at module level. If usb_path does not present,
+//  each module needs to have one unique usb_vid_pid.
+//
+// Example of the config file:
+//  camera0.lens_facing=0
+//  camera0.sensor_orientation=0
+//  camera0.module0.usb_vid_pid=0123:4567
+//  camera0.module0.horizontal_view_angle=68.4
+//  camera0.module0.lens_info_available_focal_lengths=1.64
+//  camera0.module0.lens_info_minimum_focus_distance=0.22
+//  camera0.module0.lens_info_optimal_focus_distance=0.5
+//  camera0.module0.vertical_view_angle=41.6
+//  camera0.module1.usb_vid_pid=89ab:cdef
+//  camera0.module1.lens_info_available_focal_lengths=1.69,2
+//  camera1.lens_facing=1
+//  camera1.sensor_orientation=180
+class CAPTURE_EXPORT CameraFacingChromeOS {
+ public:
+  enum LensFacing { FRONT = 0, BACK = 1 };
+
+  CameraFacingChromeOS();
+  CAPTURE_EXPORT CameraFacingChromeOS(const std::string& config_file_path);
+  CAPTURE_EXPORT ~CameraFacingChromeOS();
+
+  // Get camera facing by specifying USB vid and pid and device path. |model_id|
+  // should be formatted as "vid:pid". |device_id| is something like
+  // "/dev/video2". It first tries to match usb path, obtained from |device_id|.
+  // If fails, |model_id| is then used.
+  // Returns LensFacing::FRONT or LensFacing::BACK.
+  // Default is LensFacing::FRONT.
+  CAPTURE_EXPORT LensFacing GetCameraFacing(const std::string& device_id,
+                                            const std::string& model_id) const;
+
+  static const LensFacing kLensFacingDefault = LensFacing::FRONT;
+
+ private:
+  std::string GetUsbId(const std::string& device_id) const;
+  // Read file content and populate |camera_id_to_facing_|,
+  // |usb_id_to_camera_id_| and |model_id_to_camera_id_|.
+  void InitializeDeviceInfo(const std::string& config_file_path);
+
+  std::unordered_map<int, LensFacing> camera_id_to_facing_;
+  std::unordered_map<std::string, int> usb_id_to_camera_id_;
+  std::unordered_map<std::string, int> model_id_to_camera_id_;
+};
+
+}  // namespace media
+
+#endif  // MEDIA_CAPTURE_VIDEO_LINUX_CAMERA_FACING_CHROMEOS_H_
diff --git a/media/capture/video/linux/camera_facing_chromeos_unittest.cc b/media/capture/video/linux/camera_facing_chromeos_unittest.cc
new file mode 100644
index 0000000..0592810
--- /dev/null
+++ b/media/capture/video/linux/camera_facing_chromeos_unittest.cc
@@ -0,0 +1,41 @@
+// Copyright 2016 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 <string>
+
+#include "media/capture/video/linux/camera_facing_chromeos.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include <base/files/file_util.h>
+#include <base/files/file.h>
+
+namespace media {
+
+namespace {
+
+const char kConfigFileContent[] =
+    "camera0.lens_facing=1\ncamera0.sensor_orientation=0\ncamera0.module0.usb_"
+    "vid_pid=04f2:b53a\n";
+}
+
+TEST(CameraFacingChromeOSTest, ParseSuccessfully) {
+  const char file_name[] = "fake_camera_characteristics.conf";
+  base::WriteFile(base::FilePath(file_name), kConfigFileContent,
+                  sizeof(kConfigFileContent));
+
+  std::string file_name_str(file_name);
+  CameraFacingChromeOS camera_facing(file_name_str);
+  EXPECT_EQ(CameraFacingChromeOS::LensFacing::BACK,
+            camera_facing.GetCameraFacing(std::string("/dev/video2"),
+                                          std::string("04f2:b53a")));
+}
+
+TEST(CameraFacingChromeOSTest, ConfigFileNotExist) {
+  CameraFacingChromeOS camera_facing(std::string("file_not_exist"));
+  EXPECT_EQ(CameraFacingChromeOS::LensFacing::FRONT,
+            camera_facing.GetCameraFacing(std::string("/dev/video2"),
+                                          std::string("04f2:b53a")));
+}
+
+}  // namespace media
diff --git a/media/capture/video/linux/video_capture_device_chromeos.cc b/media/capture/video/linux/video_capture_device_chromeos.cc
index 1e6006c7..9e8dd19 100644
--- a/media/capture/video/linux/video_capture_device_chromeos.cc
+++ b/media/capture/video/linux/video_capture_device_chromeos.cc
@@ -7,6 +7,7 @@
 #include <stdint.h>
 
 #include "base/bind.h"
+#include "base/lazy_instance.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
@@ -17,6 +18,13 @@
 
 namespace media {
 
+namespace {
+
+base::LazyInstance<CameraFacingChromeOS>::Leaky g_camera_facing_ =
+    LAZY_INSTANCE_INITIALIZER;
+
+}  // namespace
+
 // This is a delegate class used to transfer Display change events from the UI
 // thread to the media thread.
 class VideoCaptureDeviceChromeOS::ScreenObserverDelegate
@@ -99,12 +107,55 @@
     const VideoCaptureDeviceDescriptor& device_descriptor)
     : VideoCaptureDeviceLinux(device_descriptor),
       screen_observer_delegate_(
-          new ScreenObserverDelegate(this, ui_task_runner)) {}
+          new ScreenObserverDelegate(this, ui_task_runner)),
+      lens_facing_(
+          g_camera_facing_.Get().GetCameraFacing(device_descriptor.device_id,
+                                                 device_descriptor.model_id)) {}
 
 VideoCaptureDeviceChromeOS::~VideoCaptureDeviceChromeOS() {
   screen_observer_delegate_->RemoveObserver();
 }
 
+void VideoCaptureDeviceChromeOS::SetRotation(int rotation) {
+  // We assume external camera is facing the users. If not, the users can
+  // rotate the camera manually by themselves.
+  if (lens_facing_ == CameraFacingChromeOS::LensFacing::BACK) {
+    // Original frame when |rotation| = 0
+    // -----------------------
+    // |          *          |
+    // |         * *         |
+    // |        *   *        |
+    // |       *******       |
+    // |      *       *      |
+    // |     *         *     |
+    // -----------------------
+    //
+    // |rotation| = 90, this is what back camera sees
+    // -----------------------
+    // |    ********         |
+    // |       *   ****      |
+    // |       *      ***    |
+    // |       *      ***    |
+    // |       *   ****      |
+    // |    ********         |
+    // -----------------------
+    //
+    // |rotation| = 90, this is what front camera sees
+    // -----------------------
+    // |         ********    |
+    // |      ****   *       |
+    // |    ***      *       |
+    // |    ***      *       |
+    // |      ****   *       |
+    // |         ********    |
+    // -----------------------
+    //
+    // Therefore, for back camera, we need to rotate (360 - |rotation|).
+    rotation = (360 - rotation) % 360;
+  }
+  VideoCaptureDeviceLinux::SetRotation(rotation);
+}
+
 void VideoCaptureDeviceChromeOS::SetDisplayRotation(
     const display::Display& display) {
   if (display.IsInternal())
diff --git a/media/capture/video/linux/video_capture_device_chromeos.h b/media/capture/video/linux/video_capture_device_chromeos.h
index cd33a5c..8a08c98 100644
--- a/media/capture/video/linux/video_capture_device_chromeos.h
+++ b/media/capture/video/linux/video_capture_device_chromeos.h
@@ -6,6 +6,7 @@
 #define MEDIA_CAPTURE_VIDEO_LINUX_VIDEO_CAPTURE_DEVICE_CHROMEOS_H_
 
 #include "base/macros.h"
+#include "media/capture/video/linux/camera_facing_chromeos.h"
 #include "media/capture/video/linux/video_capture_device_linux.h"
 
 namespace display {
@@ -24,11 +25,15 @@
       const VideoCaptureDeviceDescriptor& device_descriptor);
   ~VideoCaptureDeviceChromeOS() override;
 
+ protected:
+  void SetRotation(int rotation) override;
+
  private:
   class ScreenObserverDelegate;
 
   void SetDisplayRotation(const display::Display& display);
   scoped_refptr<ScreenObserverDelegate> screen_observer_delegate_;
+  const CameraFacingChromeOS::LensFacing lens_facing_;
   DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureDeviceChromeOS);
 };
 
diff --git a/media/capture/video/linux/video_capture_device_linux.cc b/media/capture/video/linux/video_capture_device_linux.cc
index c6269ac..d9b25b4 100644
--- a/media/capture/video/linux/video_capture_device_linux.cc
+++ b/media/capture/video/linux/video_capture_device_linux.cc
@@ -37,8 +37,8 @@
 
 VideoCaptureDeviceLinux::VideoCaptureDeviceLinux(
     const VideoCaptureDeviceDescriptor& device_descriptor)
-    : v4l2_thread_("V4L2CaptureThread"),
-      device_descriptor_(device_descriptor) {}
+    : device_descriptor_(device_descriptor),
+      v4l2_thread_("V4L2CaptureThread") {}
 
 VideoCaptureDeviceLinux::~VideoCaptureDeviceLinux() {
   // Check if the thread is running.
diff --git a/media/capture/video/linux/video_capture_device_linux.h b/media/capture/video/linux/video_capture_device_linux.h
index 0fcf1cd8..f836800 100644
--- a/media/capture/video/linux/video_capture_device_linux.h
+++ b/media/capture/video/linux/video_capture_device_linux.h
@@ -45,7 +45,9 @@
                        SetPhotoOptionsCallback callback) override;
 
  protected:
-  void SetRotation(int rotation);
+  virtual void SetRotation(int rotation);
+
+  const VideoCaptureDeviceDescriptor device_descriptor_;
 
  private:
   static int TranslatePowerLineFrequencyToV4L2(PowerLineFrequency frequency);
@@ -60,8 +62,6 @@
 
   base::Thread v4l2_thread_;  // Thread used for reading data from the device.
 
-  const VideoCaptureDeviceDescriptor device_descriptor_;
-
   DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureDeviceLinux);
 };
 
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index c67f4b9b..198f007 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -663,7 +663,7 @@
 crbug.com/563265 editing/spelling/spellcheck-editable-on-focus-sync.html [ Skip ]
 
 crbug.com/657946 [ Mac ] virtual/color_space/fast/canvas/color-space/display_linear-rgb.html [ Failure ]
-crbug.com/671048 [ Win ] virtual/color_space/fast/canvas/color-space/display_linear-rgb.html [ Failure ]
+crbug.com/671048 [ Linux Win ] virtual/color_space/fast/canvas/color-space/display_linear-rgb.html [ Failure ]
 
 crbug.com/538697 [ Win7 Debug ] virtual/threaded/printing/webgl-oversized-printing.html [ Failure Crash ]
 crbug.com/538697 [ Win7 Debug ] printing/webgl-oversized-printing.html [ Failure Crash ]
diff --git a/third_party/WebKit/LayoutTests/shadow-dom/host-link-style.html b/third_party/WebKit/LayoutTests/shadow-dom/host-link-style.html
index b9b171c..137673c 100644
--- a/third_party/WebKit/LayoutTests/shadow-dom/host-link-style.html
+++ b/third_party/WebKit/LayoutTests/shadow-dom/host-link-style.html
@@ -1,11 +1,20 @@
 <!DOCTYPE html>
 <script src="../resources/testharness.js"></script>
 <script src="../resources/testharnessreport.js"></script>
-<div id="host">This text should have a green background.</div>
+<div id="host1">This text should have a green background.</div>
+<div id="host2">This text should not have a red background.</div>
 <script>
     test(() => {
-        var root = host.attachShadow({mode:'open'});
+        var root = host1.attachShadow({mode:'open'});
         root.innerHTML = '<link rel="stylesheet" href="data:text/css,:host{background:green}"><slot />';
-        assert_equals(getComputedStyle(host).backgroundColor, "rgb(0, 128, 0)", "Host background should be green.");
+        assert_equals(getComputedStyle(host1).backgroundColor, "rgb(0, 128, 0)", "Host background should be green.");
     }, "Check that :host rule from link stylesheet applies to host element.");
+
+    test(() => {
+        var root = host2.attachShadow({mode:'open'});
+        root.innerHTML = '<link rel="stylesheet" href="data:text/css,:host{background:red}"><slot />';
+        assert_equals(getComputedStyle(host2).backgroundColor, "rgb(255, 0, 0)", "Host background should be red.");
+        root.querySelector("link").remove();
+        assert_equals(getComputedStyle(host2).backgroundColor, "rgba(0, 0, 0, 0)", "Host background should be transparent.");
+    }, "Check that :host rule from link stylesheet no longer applies after the sheet is removed.");
 </script>
diff --git a/third_party/WebKit/Source/bindings/IDLExtendedAttributes.md b/third_party/WebKit/Source/bindings/IDLExtendedAttributes.md
index ee8567e..f203d1a 100644
--- a/third_party/WebKit/Source/bindings/IDLExtendedAttributes.md
+++ b/third_party/WebKit/Source/bindings/IDLExtendedAttributes.md
@@ -1612,20 +1612,3 @@
 * `[PerWorldBindings]` :: interacts with `[LogActivity]`
 * `[OverrideBuiltins]` :: used on named accessors
 * `[ImplementedInPrivateScript]`, `[OnlyExposedToPrivateScript]`
-
--------------
-
-Derived from: [http://trac.webkit.org/wiki/WebKitIDL](http://trac.webkit.org/wiki/WebKitIDL) Licensed under [BSD](http://www.webkit.org/coding/bsd-license.html):
-
-*** aside
-BSD License
-Copyright (C) 2009 Apple Inc. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-***
diff --git a/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp b/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp
index ea4afe7..1051ee1 100644
--- a/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp
+++ b/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp
@@ -166,13 +166,18 @@
   Document* owner = ownerDocument();
   if (!owner)
     return;
+  if (ownerNode() && ownerNode()->isConnected())
+    owner->styleEngine().setNeedsActiveStyleUpdate(ownerNode()->treeScope());
+
+  // TODO(rune@opera.com): resolverChanged() can be removed once stylesheet
+  // updates are async. https://crbug.com/567021
 
   // Need FullStyleUpdate when insertRule or deleteRule,
   // because StyleSheetCollection::analyzeStyleSheetChange cannot detect partial
   // rule update.
   StyleResolverUpdateMode updateMode =
       updateType != PartialRuleUpdate ? AnalyzedStyleUpdate : FullStyleUpdate;
-  owner->styleEngine().setNeedsActiveStyleUpdate(this, updateMode);
+  owner->styleEngine().resolverChanged(updateMode);
 }
 
 void CSSStyleSheet::reattachChildRuleCSSOMWrappers() {
diff --git a/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp b/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp
index 051b670..85976c3e 100644
--- a/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp
+++ b/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp
@@ -269,10 +269,12 @@
     return;
 
   // No need to remove XSLStyleSheet from StyleEngine.
-  if (!DocumentXSLT::processingInstructionRemovedFromDocument(document(), this))
-    document().styleEngine().removeStyleSheetCandidateNode(*this);
+  if (!DocumentXSLT::processingInstructionRemovedFromDocument(document(),
+                                                              this)) {
+    document().styleEngine().removeStyleSheetCandidateNode(*this,
+                                                           *insertionPoint);
+  }
 
-  StyleSheet* removedSheet = m_sheet;
   if (m_sheet) {
     DCHECK_EQ(m_sheet->ownerNode(), this);
     clearSheet();
@@ -281,11 +283,12 @@
   // No need to remove pending sheets.
   clearResource();
 
+  // TODO(rune@opera.com): resolverChanged() can be removed once stylesheet
+  // updates are async. https://crbug.com/567021
   // If we're in document teardown, then we don't need to do any notification of
   // our sheet's removal.
   if (document().isActive())
-    document().styleEngine().setNeedsActiveStyleUpdate(removedSheet,
-                                                       FullStyleUpdate);
+    document().styleEngine().resolverChanged(FullStyleUpdate);
 }
 
 void ProcessingInstruction::clearSheet() {
diff --git a/third_party/WebKit/Source/core/dom/StyleElement.cpp b/third_party/WebKit/Source/core/dom/StyleElement.cpp
index 22f54058..b403f52 100644
--- a/third_party/WebKit/Source/core/dom/StyleElement.cpp
+++ b/third_party/WebKit/Source/core/dom/StyleElement.cpp
@@ -77,22 +77,19 @@
 
   Document& document = element.document();
   if (m_registeredAsCandidate) {
-    ShadowRoot* shadowRoot = element.containingShadowRoot();
-    if (!shadowRoot)
-      shadowRoot = insertionPoint->containingShadowRoot();
-
-    document.styleEngine().removeStyleSheetCandidateNode(
-        element, shadowRoot ? *toTreeScope(shadowRoot) : toTreeScope(document));
+    document.styleEngine().removeStyleSheetCandidateNode(element,
+                                                         *insertionPoint);
     m_registeredAsCandidate = false;
   }
 
-  StyleSheet* removedSheet = m_sheet.get();
-
-  if (m_sheet)
+  if (m_sheet) {
     clearSheet(element);
-  if (removedSheet)
-    document.styleEngine().setNeedsActiveStyleUpdate(removedSheet,
-                                                     AnalyzedStyleUpdate);
+    if (element.isConnected()) {
+      // TODO(rune@opera.com): resolverChanged() can be removed once stylesheet
+      // updates are async. https://crbug.com/567021
+      document.styleEngine().resolverChanged(AnalyzedStyleUpdate);
+    }
+  }
 }
 
 StyleElement::ProcessingResult StyleElement::childrenChanged(Element& element) {
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.cpp b/third_party/WebKit/Source/core/dom/StyleEngine.cpp
index c3443800..3830d87 100644
--- a/third_party/WebKit/Source/core/dom/StyleEngine.cpp
+++ b/third_party/WebKit/Source/core/dom/StyleEngine.cpp
@@ -185,23 +185,11 @@
   document().didRemoveAllPendingStylesheet();
 }
 
-void StyleEngine::setNeedsActiveStyleUpdate(
-    StyleSheet* sheet,
-    StyleResolverUpdateMode updateMode) {
-  // resolverChanged() is called for inactive non-master documents because
-  // import documents are inactive documents. resolverChanged() for imports
-  // will call resolverChanged() for the master document and update the active
-  // stylesheets including the ones from the import.
+void StyleEngine::setNeedsActiveStyleUpdate(TreeScope& treeScope) {
   if (!document().isActive() && isMaster())
     return;
 
-  if (sheet && document().isActive()) {
-    Node* node = sheet->ownerNode();
-    if (node && node->isConnected())
-      markTreeScopeDirty(node->treeScope());
-  }
-
-  resolverChanged(updateMode);
+  markTreeScopeDirty(treeScope);
 }
 
 void StyleEngine::addStyleSheetCandidateNode(Node& node) {
@@ -220,14 +208,17 @@
     m_activeTreeScopes.add(&treeScope);
 }
 
-void StyleEngine::removeStyleSheetCandidateNode(Node& node) {
-  removeStyleSheetCandidateNode(node, *m_document);
-}
-
 void StyleEngine::removeStyleSheetCandidateNode(Node& node,
-                                                TreeScope& treeScope) {
+                                                ContainerNode& insertionPoint) {
   DCHECK(!isXSLStyleSheet(node));
+  DCHECK(insertionPoint.isConnected());
 
+  ShadowRoot* shadowRoot = node.containingShadowRoot();
+  if (!shadowRoot)
+    shadowRoot = insertionPoint.containingShadowRoot();
+
+  TreeScope& treeScope =
+      shadowRoot ? *toTreeScope(shadowRoot) : toTreeScope(document());
   TreeScopeStyleSheetCollection* collection =
       styleSheetCollectionFor(treeScope);
   // After detaching document, collection could be null. In the case,
@@ -247,6 +238,12 @@
   resolverChanged(AnalyzedStyleUpdate);
 }
 
+void StyleEngine::mediaQueriesChangedInScope(TreeScope& treeScope) {
+  if (ScopedStyleResolver* resolver = treeScope.scopedStyleResolver())
+    resolver->setNeedsAppendAllSheets();
+  setNeedsActiveStyleUpdate(treeScope);
+}
+
 void StyleEngine::watchedSelectorsChanged() {
   m_globalRuleSet.initWatchedSelectorsRuleSet(document());
   // TODO(rune@opera.com): Should be able to use RuleSetInvalidation here.
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.h b/third_party/WebKit/Source/core/dom/StyleEngine.h
index 008236fb..bd4e74ba3 100644
--- a/third_party/WebKit/Source/core/dom/StyleEngine.h
+++ b/third_party/WebKit/Source/core/dom/StyleEngine.h
@@ -61,7 +61,6 @@
 class ShadowTreeStyleSheetCollection;
 class StyleRuleFontFace;
 class StyleRuleUsageTracker;
-class StyleSheet;
 class StyleSheetContents;
 class ViewportStyleResolver;
 
@@ -103,11 +102,11 @@
   const HeapVector<Member<CSSStyleSheet>> activeStyleSheetsForInspector() const;
 
   bool needsActiveStyleUpdate() const;
-  void setNeedsActiveStyleUpdate(StyleSheet*, StyleResolverUpdateMode);
+  void setNeedsActiveStyleUpdate(TreeScope&);
   void addStyleSheetCandidateNode(Node&);
-  void removeStyleSheetCandidateNode(Node&);
-  void removeStyleSheetCandidateNode(Node&, TreeScope&);
+  void removeStyleSheetCandidateNode(Node&, ContainerNode& insertionPoint);
   void modifiedStyleSheetCandidateNode(Node&);
+  void mediaQueriesChangedInScope(TreeScope&);
   void watchedSelectorsChanged();
   void initialViewportChanged();
   void viewportRulesChanged();
diff --git a/third_party/WebKit/Source/core/dom/StyleEngineTest.cpp b/third_party/WebKit/Source/core/dom/StyleEngineTest.cpp
index d3c2223..fcac598 100644
--- a/third_party/WebKit/Source/core/dom/StyleEngineTest.cpp
+++ b/third_party/WebKit/Source/core/dom/StyleEngineTest.cpp
@@ -320,4 +320,58 @@
   EXPECT_FALSE(document().styleEngine().hasViewportDependentMediaQueries());
 }
 
+TEST_F(StyleEngineTest, StyleMediaAttributeStyleChange) {
+  document().body()->setInnerHTML(
+      "<style id='s1' media='(max-width: 1px)'>#t1 { color: green }</style>"
+      "<div id='t1'>Green</div><div></div>");
+  document().view()->updateAllLifecyclePhases();
+
+  Element* t1 = document().getElementById("t1");
+  ASSERT_TRUE(t1);
+  ASSERT_TRUE(t1->computedStyle());
+  EXPECT_EQ(makeRGB(0, 0, 0),
+            t1->computedStyle()->visitedDependentColor(CSSPropertyColor));
+
+  unsigned beforeCount = styleEngine().styleForElementCount();
+
+  Element* s1 = document().getElementById("s1");
+  s1->setAttribute(blink::HTMLNames::mediaAttr, "(max-width: 2000px)");
+  document().view()->updateAllLifecyclePhases();
+
+  unsigned afterCount = styleEngine().styleForElementCount();
+  // TODO(rune@opera.com): Should be 1u for ruleset based invalidations.
+  EXPECT_EQ(8u, afterCount - beforeCount);
+
+  ASSERT_TRUE(t1->computedStyle());
+  EXPECT_EQ(makeRGB(0, 128, 0),
+            t1->computedStyle()->visitedDependentColor(CSSPropertyColor));
+}
+
+TEST_F(StyleEngineTest, StyleMediaAttributeNoStyleChange) {
+  document().body()->setInnerHTML(
+      "<style id='s1' media='(max-width: 1000px)'>#t1 { color: green }</style>"
+      "<div id='t1'>Green</div><div></div>");
+  document().view()->updateAllLifecyclePhases();
+
+  Element* t1 = document().getElementById("t1");
+  ASSERT_TRUE(t1);
+  ASSERT_TRUE(t1->computedStyle());
+  EXPECT_EQ(makeRGB(0, 128, 0),
+            t1->computedStyle()->visitedDependentColor(CSSPropertyColor));
+
+  unsigned beforeCount = styleEngine().styleForElementCount();
+
+  Element* s1 = document().getElementById("s1");
+  s1->setAttribute(blink::HTMLNames::mediaAttr, "(max-width: 2000px)");
+  document().view()->updateAllLifecyclePhases();
+
+  unsigned afterCount = styleEngine().styleForElementCount();
+  // TODO(rune@opera.com): Should be 0 for ruleset based invalidations.
+  EXPECT_EQ(8u, afterCount - beforeCount);
+
+  ASSERT_TRUE(t1->computedStyle());
+  EXPECT_EQ(makeRGB(0, 128, 0),
+            t1->computedStyle()->visitedDependentColor(CSSPropertyColor));
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
index 06a8129..c73e440 100644
--- a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
@@ -216,15 +216,15 @@
     DCHECK(!linkStyle() || !linkStyle()->hasSheet());
     return;
   }
-  document().styleEngine().removeStyleSheetCandidateNode(*this);
-
-  StyleSheet* removedSheet = sheet();
+  document().styleEngine().removeStyleSheetCandidateNode(*this,
+                                                         *insertionPoint);
 
   if (m_link)
     m_link->ownerRemoved();
 
-  document().styleEngine().setNeedsActiveStyleUpdate(removedSheet,
-                                                     FullStyleUpdate);
+  // TODO(rune@opera.com): resolverChanged() can be removed once stylesheet
+  // updates are async. https://crbug.com/567021
+  document().styleEngine().resolverChanged(AnalyzedStyleUpdate);
 }
 
 void HTMLLinkElement::finishParsingChildren() {
diff --git a/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp b/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
index d3b1f7f..59c00ce 100644
--- a/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
@@ -57,8 +57,10 @@
   } else if (name == mediaAttr && isConnected() && document().isActive() &&
              m_sheet) {
     m_sheet->setMediaQueries(MediaQuerySet::create(value));
-    document().styleEngine().setNeedsActiveStyleUpdate(m_sheet.get(),
-                                                       FullStyleUpdate);
+    document().styleEngine().mediaQueriesChangedInScope(treeScope());
+    // TODO(rune@opera.com): resolverChanged() can be removed once stylesheet
+    // updates are async. https://crbug.com/567021
+    document().styleEngine().resolverChanged(FullStyleUpdate);
   } else {
     HTMLElement::parseAttribute(name, oldValue, value);
   }
diff --git a/third_party/WebKit/Source/core/html/LinkStyle.cpp b/third_party/WebKit/Source/core/html/LinkStyle.cpp
index 412fe942..9460d3c1 100644
--- a/third_party/WebKit/Source/core/html/LinkStyle.cpp
+++ b/third_party/WebKit/Source/core/html/LinkStyle.cpp
@@ -387,10 +387,11 @@
 
   if (loadStylesheetIfNeeded(builder, type) == NotNeeded && m_sheet) {
     // we no longer contain a stylesheet, e.g. perhaps rel or type was changed
-    StyleSheet* removedSheet = m_sheet.get();
     clearSheet();
-    document().styleEngine().setNeedsActiveStyleUpdate(removedSheet,
-                                                       FullStyleUpdate);
+    document().styleEngine().setNeedsActiveStyleUpdate(m_owner->treeScope());
+    // TODO(rune@opera.com): resolverChanged() can be removed once stylesheet
+    // updates are async. https://crbug.com/567021
+    document().styleEngine().resolverChanged(FullStyleUpdate);
   }
 }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
index 79350deb..2603bac9 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -3560,7 +3560,7 @@
 }
 
 void LayoutBlockFlow::removeFloatingObjectsBelow(FloatingObject* lastFloat,
-                                                 int logicalOffset) {
+                                                 LayoutUnit logicalOffset) {
   if (!containsFloats())
     return;
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
index 75f15e5a..a20021e 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
@@ -505,7 +505,7 @@
                                              LayoutUnit logicalTopOffset) const;
 
   void removeFloatingObject(LayoutBox*);
-  void removeFloatingObjectsBelow(FloatingObject*, int logicalOffset);
+  void removeFloatingObjectsBelow(FloatingObject*, LayoutUnit logicalOffset);
 
   LayoutUnit getClearDelta(LayoutBox* child, LayoutUnit yPos);
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
index 7958a9a..5a4a7f0 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
@@ -1010,8 +1010,7 @@
     FloatingObject* lastFloatFromPreviousLine,
     InlineBidiResolver& resolver,
     const InlineIterator& oldEnd) {
-  removeFloatingObjectsBelow(lastFloatFromPreviousLine,
-                             oldLogicalHeight.toInt());
+  removeFloatingObjectsBelow(lastFloatFromPreviousLine, oldLogicalHeight);
   setLogicalHeight(newLogicalHeight);
   resolver.setPositionIgnoringNestedIsolates(oldEnd);
   return oldEnd;
diff --git a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc
index bc084491..1153b6b 100644
--- a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc
+++ b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc
@@ -4,8 +4,6 @@
 
 #include "core/layout/ng/layout_ng_block_flow.h"
 #include "core/layout/ng/ng_constraint_space.h"
-#include "core/layout/ng/ng_block_layout_algorithm.h"
-#include "core/layout/ng/ng_fragment_base.h"
 #include "core/layout/LayoutAnalyzer.h"
 
 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 b8880d7..e7e7375 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
@@ -7,17 +7,19 @@
 
 #include "core/CoreExport.h"
 #include "core/layout/ng/ng_block_node.h"
-#include "core/layout/ng/ng_constraint_space_builder.h"
-#include "core/layout/ng/ng_fragment_builder.h"
 #include "core/layout/ng/ng_layout_algorithm.h"
+#include "core/layout/ng/ng_units.h"
 #include "wtf/RefPtr.h"
 
 namespace blink {
 
 class ComputedStyle;
-class NGConstraintSpace;
-class NGPhysicalFragmentBase;
 class NGBreakToken;
+class NGConstraintSpace;
+class NGConstraintSpaceBuilder;
+class NGFragment;
+class NGFragmentBuilder;
+class NGPhysicalFragmentBase;
 
 // A class for general block layout (e.g. a <div> with no special style).
 // Lays out the children in sequence.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
index 1114647c..c9c627e 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
@@ -11,14 +11,13 @@
 #include "core/layout/ng/ng_block_layout_algorithm.h"
 #include "core/layout/ng/ng_constraint_space_builder.h"
 #include "core/layout/ng/ng_constraint_space.h"
-#include "core/layout/ng/ng_inline_layout_algorithm.h"
 #include "core/layout/ng/ng_fragment.h"
 #include "core/layout/ng/ng_fragment_builder.h"
+#include "core/layout/ng/ng_inline_node.h"
 #include "core/layout/ng/ng_layout_coordinator.h"
 #include "core/layout/ng/ng_length_utils.h"
 #include "core/layout/ng/ng_writing_mode.h"
 #include "platform/RuntimeEnabledFeatures.h"
-#include "platform/text/TextDirection.h"
 
 namespace blink {
 
@@ -35,6 +34,11 @@
   DCHECK(style_);
 }
 
+// Need an explicit destructor in the .cc file, or the MSWIN compiler will
+// produce an error when attempting to generate a default one, if the .h file is
+// included from a compilation unit that lacks the ComputedStyle definition.
+NGBlockNode::~NGBlockNode() {}
+
 bool NGBlockNode::Layout(const NGConstraintSpace* constraint_space,
                          NGFragmentBase** out) {
   DCHECK(!minmax_algorithm_)
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
index bb783e49..d23ea7b 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
@@ -31,6 +31,8 @@
   // TODO(layout-ng): make it private and declare a friend class to use in tests
   explicit NGBlockNode(ComputedStyle*);
 
+  ~NGBlockNode() override;
+
   bool Layout(const NGConstraintSpace*, NGFragmentBase**) override;
   NGBlockNode* NextSibling() override;
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
index a415147..d52d225 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
@@ -6,10 +6,8 @@
 
 #include "core/layout/LayoutBlock.h"
 #include "core/layout/LayoutView.h"
-#include "core/layout/ng/ng_constraint_space.h"
 #include "core/layout/ng/ng_constraint_space_builder.h"
 #include "core/layout/ng/ng_layout_opportunity_iterator.h"
-#include "core/layout/ng/ng_units.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
index 56e0daaf..4d9f9b3 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
@@ -6,12 +6,10 @@
 #define NGConstraintSpace_h
 
 #include "core/CoreExport.h"
-#include "core/layout/ng/ng_macros.h"
 #include "core/layout/ng/ng_units.h"
 #include "core/layout/ng/ng_writing_mode.h"
 #include "platform/heap/Handle.h"
 #include "wtf/text/WTFString.h"
-#include "wtf/Vector.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h
index ccff60e..b1ac274 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h
@@ -5,7 +5,7 @@
 #ifndef NGConstraintSpaceBuilder_h
 #define NGConstraintSpaceBuilder_h
 
-#include "core/layout/ng/ng_fragment.h"
+#include "core/layout/ng/ng_constraint_space.h"
 #include "core/layout/ng/ng_units.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment.h
index b755256..b08d214 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment.h
@@ -7,13 +7,9 @@
 
 #include "core/CoreExport.h"
 #include "core/layout/ng/ng_fragment_base.h"
-#include "core/layout/ng/ng_constraint_space.h"
 #include "core/layout/ng/ng_physical_fragment.h"
 #include "core/layout/ng/ng_units.h"
 #include "core/layout/ng/ng_writing_mode.h"
-#include "platform/LayoutUnit.h"
-#include "platform/heap/Handle.h"
-#include "wtf/Vector.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.cc
index 63ed43c..67c6250 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.cc
@@ -4,8 +4,6 @@
 
 #include "core/layout/ng/ng_fragment_base.h"
 
-#include "core/layout/ng/ng_physical_fragment_base.h"
-
 namespace blink {
 
 LayoutUnit NGFragmentBase::InlineSize() const {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.h
index f1f10cd..5c08e2f 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.h
@@ -8,10 +8,8 @@
 #include "core/CoreExport.h"
 #include "core/layout/ng/ng_physical_fragment_base.h"
 #include "core/layout/ng/ng_writing_mode.h"
-#include "core/layout/ng/ng_units.h"
 #include "platform/LayoutUnit.h"
 #include "platform/heap/Handle.h"
-#include "wtf/Vector.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
index 4875abf2d..925eecd 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
@@ -3,8 +3,10 @@
 // found in the LICENSE file.
 
 #include "core/layout/ng/ng_fragment_builder.h"
+
 #include "core/layout/ng/ng_block_node.h"
-#include "core/style/ComputedStyle.h"
+#include "core/layout/ng/ng_fragment_base.h"
+#include "core/layout/ng/ng_physical_fragment.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
index ac703db..1021544 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
@@ -5,11 +5,14 @@
 #ifndef NGFragmentBuilder_h
 #define NGFragmentBuilder_h
 
-#include "core/layout/ng/ng_fragment.h"
+#include "core/layout/ng/ng_physical_fragment_base.h"
 #include "core/layout/ng/ng_units.h"
 
 namespace blink {
 
+class NGFragmentBase;
+class NGPhysicalFragment;
+
 class CORE_EXPORT NGFragmentBuilder final
     : public GarbageCollectedFinalized<NGFragmentBuilder> {
  public:
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc
index 9f24a7b..1cbd272 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc
@@ -8,6 +8,7 @@
 #include "core/layout/ng/ng_constraint_space.h"
 #include "core/layout/ng/ng_fragment_builder.h"
 #include "core/layout/ng/ng_inline_node.h"
+#include "core/layout/ng/ng_physical_fragment.h"
 #include "core/style/ComputedStyle.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.h
index 21bebc49..31589fe2 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.h
@@ -6,15 +6,15 @@
 #define NGInlineLayoutAlgorithm_h
 
 #include "core/CoreExport.h"
-#include "core/layout/ng/ng_inline_node.h"
 #include "core/layout/ng/ng_layout_algorithm.h"
 #include "wtf/RefPtr.h"
 
 namespace blink {
 
 class ComputedStyle;
-class NGConstraintSpace;
 class NGBreakToken;
+class NGConstraintSpace;
+class NGInlineNode;
 
 // A class for inline layout (e.g. a anonymous block with inline-level children
 // only).
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc
index 647d1db..c4b588e 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc
@@ -4,20 +4,15 @@
 
 #include "core/layout/ng/ng_inline_node.h"
 
-#include "core/layout/LayoutBlockFlow.h"
-#include "core/style/ComputedStyle.h"
-#include "core/layout/ng/layout_ng_block_flow.h"
+#include "core/layout/LayoutObject.h"
+#include "core/layout/LayoutText.h"
 #include "core/layout/ng/ng_bidi_paragraph.h"
 #include "core/layout/ng/ng_layout_inline_items_builder.h"
 #include "core/layout/ng/ng_text_layout_algorithm.h"
 #include "core/layout/ng/ng_constraint_space_builder.h"
-#include "core/layout/ng/ng_constraint_space.h"
 #include "core/layout/ng/ng_physical_text_fragment.h"
 #include "core/layout/ng/ng_text_fragment.h"
-#include "core/layout/ng/ng_fragment_builder.h"
-#include "core/layout/ng/ng_length_utils.h"
-#include "core/layout/ng/ng_writing_mode.h"
-#include "platform/text/TextDirection.h"
+#include "core/style/ComputedStyle.h"
 #include "platform/fonts/shaping/CachingWordShaper.h"
 #include "platform/fonts/shaping/CachingWordShapeIterator.h"
 #include "wtf/text/CharacterNames.h"
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.cc
index e1331c4..15adc8a 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_coordinator.cc
@@ -5,7 +5,6 @@
 #include "core/layout/ng/ng_layout_coordinator.h"
 
 #include "core/layout/ng/ng_layout_input_node.h"
-#include "core/layout/ng/ng_physical_fragment_base.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_inline_items_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_inline_items_builder.cc
index 11a3c50..dc1c7543 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_inline_items_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_inline_items_builder.cc
@@ -5,7 +5,6 @@
 #include "core/layout/ng/ng_layout_inline_items_builder.h"
 
 #include "core/layout/LayoutObject.h"
-#include "core/layout/LayoutText.h"
 #include "core/layout/ng/ng_inline_node.h"
 #include "core/style/ComputedStyle.h"
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.h
index 0dc3d82c..7241c00 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.h
@@ -10,7 +10,6 @@
 #include "core/layout/ng/ng_layout_opportunity_tree_node.h"
 #include "core/layout/ng/ng_units.h"
 #include "platform/heap/Handle.h"
-#include "wtf/text/WTFString.h"
 #include "wtf/Optional.h"
 #include "wtf/Vector.h"
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_tree_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_tree_node.cc
index c7a1c6a..aa211bf 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_tree_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_tree_node.cc
@@ -4,9 +4,6 @@
 
 #include "core/layout/ng/ng_layout_opportunity_tree_node.h"
 
-#include "platform/heap/Handle.h"
-#include "core/layout/ng/ng_constraint_space.h"
-
 namespace blink {
 
 NGLayoutOpportunityTreeNode::NGLayoutOpportunityTreeNode(
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
index 50b6417c..0802881 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
@@ -5,7 +5,7 @@
 #include "core/layout/ng/ng_length_utils.h"
 
 #include "core/layout/ng/ng_constraint_space.h"
-#include "core/layout/ng/ng_fragment.h"
+#include "core/layout/ng/ng_fragment_base.h"
 #include "core/style/ComputedStyle.h"
 #include "platform/LayoutUnit.h"
 #include "platform/Length.h"
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc
index dd9da9c7..2a7cf51 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc
@@ -3,9 +3,6 @@
 // found in the LICENSE file.
 
 #include "core/layout/ng/ng_physical_fragment.h"
-#include "core/layout/ng/ng_block_layout_algorithm.h"
-#include "core/layout/ng/ng_block_node.h"
-#include "core/style/ComputedStyle.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment_base.cc b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment_base.cc
index 0afd97a..ee6b7b7 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment_base.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment_base.cc
@@ -4,9 +4,9 @@
 
 #include "core/layout/ng/ng_physical_fragment_base.h"
 
+#include "core/layout/ng/ng_break_token.h"
 #include "core/layout/ng/ng_physical_fragment.h"
 #include "core/layout/ng/ng_physical_text_fragment.h"
-#include "core/style/ComputedStyle.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment_base.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment_base.h
index 5356b33..7a933a2 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment_base.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment_base.h
@@ -6,8 +6,6 @@
 #define NGPhysicalFragmentBase_h
 
 #include "core/CoreExport.h"
-#include "core/layout/ng/ng_break_token.h"
-#include "core/layout/ng/ng_constraint_space.h"
 #include "core/layout/ng/ng_units.h"
 #include "platform/LayoutUnit.h"
 #include "platform/heap/Handle.h"
@@ -16,6 +14,7 @@
 namespace blink {
 
 class NGBlockNode;
+class NGBreakToken;
 
 // The NGPhysicalFragmentBase contains the output information from layout. The
 // fragment stores all of its information in the physical coordinate system for
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_text_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_text_fragment.h
index 63b7868..ab4b00a7 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_physical_text_fragment.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_text_fragment.h
@@ -8,9 +8,7 @@
 #include "core/CoreExport.h"
 #include "core/layout/ng/ng_block_node.h"
 #include "core/layout/ng/ng_physical_fragment_base.h"
-#include "platform/LayoutUnit.h"
 #include "platform/heap/Handle.h"
-#include "wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_text_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_text_fragment.h
index 40b4b25..a4addc7 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_text_fragment.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_text_fragment.h
@@ -8,10 +8,6 @@
 #include "core/CoreExport.h"
 #include "core/layout/ng/ng_fragment_base.h"
 #include "core/layout/ng/ng_physical_text_fragment.h"
-#include "core/style/ComputedStyle.h"
-#include "platform/LayoutUnit.h"
-#include "platform/heap/Handle.h"
-#include "wtf/text/WTFString.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc
index 887b2d5..4de2cda 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.cc
@@ -6,6 +6,7 @@
 
 #include "core/layout/ng/ng_break_token.h"
 #include "core/layout/ng/ng_constraint_space.h"
+#include "core/layout/ng/ng_inline_node.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.h
index 9fdc770..2150df5 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_text_layout_algorithm.h
@@ -6,15 +6,13 @@
 #define NGInlineLayoutAlgorithm_h
 
 #include "core/CoreExport.h"
-#include "core/layout/ng/ng_inline_node.h"
 #include "core/layout/ng/ng_layout_algorithm.h"
-#include "wtf/RefPtr.h"
 
 namespace blink {
 
-class ComputedStyle;
-class NGConstraintSpace;
 class NGBreakToken;
+class NGConstraintSpace;
+class NGInlineNode;
 
 // A class for text layout. This takes a NGInlineNode which consists only
 // non-atomic inlines and produces NGTextFragments.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_units.cc b/third_party/WebKit/Source/core/layout/ng/ng_units.cc
index 35bf7b16..52713fa 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_units.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_units.cc
@@ -4,8 +4,6 @@
 
 #include "core/layout/ng/ng_units.h"
 
-#include "core/layout/ng/ng_writing_mode.h"
-
 namespace blink {
 
 LayoutUnit MinAndMaxContentSizes::ShrinkToFit(LayoutUnit available_size) const {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_units_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_units_test.cc
index 839a6e1d..2fcc1ad 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_units_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_units_test.cc
@@ -4,8 +4,6 @@
 
 #include "core/layout/ng/ng_units.h"
 
-#include "platform/text/TextDirection.h"
-#include "core/layout/ng/ng_writing_mode.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_writing_mode.cc b/third_party/WebKit/Source/core/layout/ng/ng_writing_mode.cc
index 6d7a150..9dab422 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_writing_mode.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_writing_mode.cc
@@ -4,7 +4,6 @@
 
 #include "core/layout/ng/ng_writing_mode.h"
 
-#include "platform/text/WritingMode.h"
 #include "wtf/Assertions.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/xml/XPathFunctions.cpp b/third_party/WebKit/Source/core/xml/XPathFunctions.cpp
index 90f18471..aae17d9 100644
--- a/third_party/WebKit/Source/core/xml/XPathFunctions.cpp
+++ b/third_party/WebKit/Source/core/xml/XPathFunctions.cpp
@@ -334,15 +334,12 @@
   StringBuilder idList;  // A whitespace-separated list of IDs
 
   if (a.isNodeSet()) {
-    const NodeSet& nodes = a.toNodeSet(&context);
-    for (size_t i = 0; i < nodes.size(); ++i) {
-      String str = stringValue(nodes[i]);
-      idList.append(str);
+    for (const auto& node : a.toNodeSet(&context)) {
+      idList.append(stringValue(node));
       idList.append(' ');
     }
   } else {
-    String str = a.toString();
-    idList.append(str);
+    idList.append(a.toString());
   }
 
   TreeScope& contextScope = context.node->treeScope();
@@ -677,8 +674,8 @@
   // addition is not associative.  However, this is unlikely to ever become a
   // practical issue, and sorting is slow.
 
-  for (unsigned i = 0; i < nodes.size(); i++)
-    sum += Value(stringValue(nodes[i])).toNumber();
+  for (const auto& node : nodes)
+    sum += Value(stringValue(node)).toNumber();
 
   return sum;
 }
diff --git a/third_party/WebKit/Source/core/xml/XPathNodeSet.h b/third_party/WebKit/Source/core/xml/XPathNodeSet.h
index 00549aea..6ba8ee1 100644
--- a/third_party/WebKit/Source/core/xml/XPathNodeSet.h
+++ b/third_party/WebKit/Source/core/xml/XPathNodeSet.h
@@ -43,6 +43,12 @@
   size_t size() const { return m_nodes.size(); }
   bool isEmpty() const { return !m_nodes.size(); }
   Node* operator[](unsigned i) const { return m_nodes.at(i).get(); }
+  HeapVector<Member<Node>>::iterator begin() { return m_nodes.begin(); }
+  HeapVector<Member<Node>>::iterator end() { return m_nodes.end(); }
+  HeapVector<Member<Node>>::const_iterator begin() const {
+    return m_nodes.begin();
+  }
+  HeapVector<Member<Node>>::const_iterator end() const { return m_nodes.end(); }
   void reserveCapacity(size_t newCapacity) {
     m_nodes.reserveCapacity(newCapacity);
   }
diff --git a/third_party/WebKit/Source/core/xml/XPathParser.cpp b/third_party/WebKit/Source/core/xml/XPathParser.cpp
index 28a64bf..c481438 100644
--- a/third_party/WebKit/Source/core/xml/XPathParser.cpp
+++ b/third_party/WebKit/Source/core/xml/XPathParser.cpp
@@ -85,8 +85,8 @@
       {"preceding", Step::PrecedingAxis},
       {"preceding-sibling", Step::PrecedingSiblingAxis},
       {"self", Step::SelfAxis}};
-  for (unsigned i = 0; i < sizeof(axisNameList) / sizeof(axisNameList[0]); ++i)
-    axisNames.set(axisNameList[i].name, axisNameList[i].axis);
+  for (const auto& axisName : axisNameList)
+    axisNames.set(axisName.name, axisName.axis);
 }
 
 static bool isAxisName(const String& name, Step::Axis& type) {
diff --git a/third_party/WebKit/Source/core/xml/XPathPath.cpp b/third_party/WebKit/Source/core/xml/XPathPath.cpp
index cca8b44..f5eb17a 100644
--- a/third_party/WebKit/Source/core/xml/XPathPath.cpp
+++ b/third_party/WebKit/Source/core/xml/XPathPath.cpp
@@ -58,18 +58,16 @@
   NodeSet& nodes = v.modifiableNodeSet(evaluationContext);
   nodes.sort();
 
-  for (unsigned i = 0; i < m_predicates.size(); i++) {
+  for (const auto& predicate : m_predicates) {
     NodeSet* newNodes = NodeSet::create();
     evaluationContext.size = nodes.size();
     evaluationContext.position = 0;
 
-    for (unsigned j = 0; j < nodes.size(); j++) {
-      Node* node = nodes[j];
-
+    for (const auto& node : nodes) {
       evaluationContext.node = node;
       ++evaluationContext.position;
 
-      if (m_predicates[i]->evaluate(evaluationContext))
+      if (predicate->evaluate(evaluationContext))
         newNodes->append(node);
     }
     nodes.swap(*newNodes);
@@ -119,8 +117,7 @@
 void LocationPath::evaluate(EvaluationContext& context, NodeSet& nodes) const {
   bool resultIsSorted = nodes.isSorted();
 
-  for (unsigned i = 0; i < m_steps.size(); i++) {
-    Step* step = m_steps[i];
+  for (const auto& step : m_steps) {
     NodeSet* newNodes = NodeSet::create();
     HeapHashSet<Member<Node>> newNodesSet;
 
@@ -140,15 +137,14 @@
                                         step->getAxis() == Step::SelfAxis))
       newNodes->markSubtreesDisjoint(true);
 
-    for (unsigned j = 0; j < nodes.size(); j++) {
+    for (const auto& inputNode : nodes) {
       NodeSet* matches = NodeSet::create();
-      step->evaluate(context, nodes[j], *matches);
+      step->evaluate(context, inputNode, *matches);
 
       if (!matches->isSorted())
         resultIsSorted = false;
 
-      for (size_t nodeIndex = 0; nodeIndex < matches->size(); ++nodeIndex) {
-        Node* node = (*matches)[nodeIndex];
+      for (const auto& node : *matches) {
         if (!needToCheckForDuplicateNodes || newNodesSet.add(node).isNewEntry)
           newNodes->append(node);
       }
diff --git a/third_party/WebKit/Source/core/xml/XPathPredicate.cpp b/third_party/WebKit/Source/core/xml/XPathPredicate.cpp
index 847a749..55b27b89 100644
--- a/third_party/WebKit/Source/core/xml/XPathPredicate.cpp
+++ b/third_party/WebKit/Source/core/xml/XPathPredicate.cpp
@@ -110,10 +110,9 @@
       // performing the comparison on the string-values of the two nodes
       // is true.
       const NodeSet& rhsSet = rhs.toNodeSet(&context);
-      for (unsigned lindex = 0; lindex < lhsSet.size(); ++lindex) {
-        for (unsigned rindex = 0; rindex < rhsSet.size(); ++rindex) {
-          if (compare(context, stringValue(lhsSet[lindex]),
-                      stringValue(rhsSet[rindex])))
+      for (const auto& leftNode : lhsSet) {
+        for (const auto& rightNode : rhsSet) {
+          if (compare(context, stringValue(leftNode), stringValue(rightNode)))
             return true;
         }
       }
@@ -126,9 +125,8 @@
       // comparison on the number to be compared and on the result of
       // converting the string-value of that node to a number using the
       // number function is true.
-      for (unsigned lindex = 0; lindex < lhsSet.size(); ++lindex) {
-        if (compare(context, Value(stringValue(lhsSet[lindex])).toNumber(),
-                    rhs))
+      for (const auto& leftNode : lhsSet) {
+        if (compare(context, Value(stringValue(leftNode)).toNumber(), rhs))
           return true;
       }
       return false;
@@ -139,8 +137,8 @@
       // a node in the node-set such that the result of performing the
       // comparison on the string-value of the node and the other string
       // is true.
-      for (unsigned lindex = 0; lindex < lhsSet.size(); ++lindex) {
-        if (compare(context, stringValue(lhsSet[lindex]), rhs))
+      for (const auto& leftNode : lhsSet) {
+        if (compare(context, stringValue(leftNode), rhs))
           return true;
       }
       return false;
@@ -158,16 +156,15 @@
   if (rhs.isNodeSet()) {
     const NodeSet& rhsSet = rhs.toNodeSet(&context);
     if (lhs.isNumber()) {
-      for (unsigned rindex = 0; rindex < rhsSet.size(); ++rindex) {
-        if (compare(context, lhs,
-                    Value(stringValue(rhsSet[rindex])).toNumber()))
+      for (const auto& rightNode : rhsSet) {
+        if (compare(context, lhs, Value(stringValue(rightNode)).toNumber()))
           return true;
       }
       return false;
     }
     if (lhs.isString()) {
-      for (unsigned rindex = 0; rindex < rhsSet.size(); ++rindex) {
-        if (compare(context, lhs, stringValue(rhsSet[rindex])))
+      for (const auto& rightNode : rhsSet) {
+        if (compare(context, lhs, stringValue(rightNode)))
           return true;
       }
       return false;
@@ -242,11 +239,10 @@
   const NodeSet& rhsNodes = rhs.toNodeSet(&context);
 
   HeapHashSet<Member<Node>> nodes;
-  for (size_t i = 0; i < resultSet.size(); ++i)
-    nodes.add(resultSet[i]);
+  for (const auto& node : resultSet)
+    nodes.add(node);
 
-  for (size_t i = 0; i < rhsNodes.size(); ++i) {
-    Node* node = rhsNodes[i];
+  for (const auto& node : rhsNodes) {
     if (nodes.add(node).isNewEntry)
       resultSet.append(node);
   }
diff --git a/third_party/WebKit/Source/core/xml/XPathStep.cpp b/third_party/WebKit/Source/core/xml/XPathStep.cpp
index 1ec9760..3872240 100644
--- a/third_party/WebKit/Source/core/xml/XPathStep.cpp
+++ b/third_party/WebKit/Source/core/xml/XPathStep.cpp
@@ -65,8 +65,7 @@
   // list sensitive, or to first predicate that is only context position
   // sensitive, e.g. foo[position() mod 2 = 0].
   HeapVector<Member<Predicate>> remainingPredicates;
-  for (size_t i = 0; i < m_predicates.size(); ++i) {
-    Predicate* predicate = m_predicates[i];
+  for (const auto& predicate : m_predicates) {
     if ((!predicate->isContextPositionSensitive() ||
          nodeTest().mergedPredicates().isEmpty()) &&
         !predicate->isContextSizeSensitive() && remainingPredicates.isEmpty()) {
@@ -105,15 +104,13 @@
 }
 
 bool Step::predicatesAreContextListInsensitive() const {
-  for (size_t i = 0; i < m_predicates.size(); ++i) {
-    Predicate* predicate = m_predicates[i].get();
+  for (const auto& predicate : m_predicates) {
     if (predicate->isContextPositionSensitive() ||
         predicate->isContextSizeSensitive())
       return false;
   }
 
-  for (size_t i = 0; i < nodeTest().mergedPredicates().size(); ++i) {
-    Predicate* predicate = nodeTest().mergedPredicates()[i].get();
+  for (const auto& predicate : nodeTest().mergedPredicates()) {
     if (predicate->isContextPositionSensitive() ||
         predicate->isContextSizeSensitive())
       return false;
@@ -130,9 +127,7 @@
   nodesInAxis(evaluationContext, context, nodes);
 
   // Check predicates that couldn't be merged into node test.
-  for (unsigned i = 0; i < m_predicates.size(); i++) {
-    Predicate* predicate = m_predicates[i].get();
-
+  for (const auto& predicate : m_predicates) {
     NodeSet* newNodes = NodeSet::create();
     if (!nodes.isSorted())
       newNodes->markSorted(false);
@@ -246,11 +241,7 @@
   // Only the first merged predicate may depend on position.
   ++evaluationContext.position;
 
-  const HeapVector<Member<Predicate>>& mergedPredicates =
-      nodeTest.mergedPredicates();
-  for (unsigned i = 0; i < mergedPredicates.size(); i++) {
-    Predicate* predicate = mergedPredicates[i].get();
-
+  for (const auto& predicate : nodeTest.mergedPredicates()) {
     evaluationContext.node = node;
     // No need to set context size - we only get here when evaluating
     // predicates that do not depend on it.
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLContextObject.cpp b/third_party/WebKit/Source/modules/webgl/WebGLContextObject.cpp
index 0965b282..c3d03cf 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLContextObject.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLContextObject.cpp
@@ -30,7 +30,7 @@
 namespace blink {
 
 WebGLContextObject::WebGLContextObject(WebGLRenderingContextBase* context)
-    : WebGLObject(context), m_context(context) {}
+    : WebGLObject(context), m_context(this, context) {}
 
 bool WebGLContextObject::validate(
     const WebGLContextGroup*,
@@ -55,4 +55,9 @@
   WebGLObject::trace(visitor);
 }
 
+DEFINE_TRACE_WRAPPERS(WebGLContextObject) {
+  visitor->traceWrappers(m_context);
+  WebGLObject::traceWrappers(visitor);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLContextObject.h b/third_party/WebKit/Source/modules/webgl/WebGLContextObject.h
index ca65a06..9e70743 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLContextObject.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGLContextObject.h
@@ -26,6 +26,7 @@
 #ifndef WebGLContextObject_h
 #define WebGLContextObject_h
 
+#include "bindings/core/v8/TraceWrapperMember.h"
 #include "modules/webgl/WebGLObject.h"
 
 namespace blink {
@@ -43,6 +44,8 @@
 
   DECLARE_VIRTUAL_TRACE();
 
+  DECLARE_VIRTUAL_TRACE_WRAPPERS();
+
  protected:
   explicit WebGLContextObject(WebGLRenderingContextBase*);
 
@@ -53,7 +56,7 @@
   gpu::gles2::GLES2Interface* getAGLInterface() const final;
 
  private:
-  Member<WebGLRenderingContextBase> m_context;
+  TraceWrapperMember<WebGLRenderingContextBase> m_context;
 };
 
 }  // namespace blink
diff --git a/ui/file_manager/integration_tests/testing_provider/background.js b/ui/file_manager/integration_tests/testing_provider/background.js
index 5d41be1..f3377f4e 100644
--- a/ui/file_manager/integration_tests/testing_provider/background.js
+++ b/ui/file_manager/integration_tests/testing_provider/background.js
@@ -49,7 +49,7 @@
 
 chrome.fileSystemProvider.onGetActionsRequested.addListener(
     function(options, onSuccess, onError) {
-      onSucces([]);
+      onSuccess([]);
     });
 
 // If the manifest for device or file source is used, then mount a fake file
diff --git a/ui/message_center/BUILD.gn b/ui/message_center/BUILD.gn
index 69e04c40..6eae813 100644
--- a/ui/message_center/BUILD.gn
+++ b/ui/message_center/BUILD.gn
@@ -240,6 +240,7 @@
         "views/bounded_label_unittest.cc",
         "views/custom_notification_view_unittest.cc",
         "views/message_center_view_unittest.cc",
+        "views/message_list_view_unittest.cc",
         "views/message_popup_collection_unittest.cc",
         "views/notification_view_unittest.cc",
         "views/notifier_settings_view_unittest.cc",
diff --git a/ui/message_center/views/message_center_view.cc b/ui/message_center/views/message_center_view.cc
index b95ebf55..105ce6d 100644
--- a/ui/message_center/views/message_center_view.cc
+++ b/ui/message_center/views/message_center_view.cc
@@ -104,8 +104,9 @@
   scroller_->layer()->SetFillsBoundsOpaquely(false);
   scroller_->layer()->SetMasksToBounds(true);
 
-  message_list_view_.reset(new MessageListView(this, top_down));
+  message_list_view_.reset(new MessageListView(top_down));
   message_list_view_->set_owned_by_client();
+  message_list_view_->AddObserver(this);
 
   // We want to swap the contents of the scroll view between the empty list
   // view and the message list view, without constructing them afresh each
@@ -129,6 +130,8 @@
 }
 
 MessageCenterView::~MessageCenterView() {
+  message_list_view_->RemoveObserver(this);
+
   if (!is_closing_)
     message_center_->RemoveObserver(this);
 }
diff --git a/ui/message_center/views/message_center_view.h b/ui/message_center/views/message_center_view.h
index 843a080..2db4bc2 100644
--- a/ui/message_center/views/message_center_view.h
+++ b/ui/message_center/views/message_center_view.h
@@ -13,6 +13,7 @@
 #include "ui/message_center/message_center_observer.h"
 #include "ui/message_center/notification_list.h"
 #include "ui/message_center/views/message_center_controller.h"
+#include "ui/message_center/views/message_list_view.h"
 #include "ui/message_center/views/message_view.h"
 #include "ui/views/view.h"
 
@@ -34,10 +35,12 @@
 // button bar, settings view, scrol view, and message list view.  Acts as a
 // controller for the message list view, passing data back and forth to message
 // center.
-class MESSAGE_CENTER_EXPORT MessageCenterView : public views::View,
-                                                public MessageCenterObserver,
-                                                public MessageCenterController,
-                                                public gfx::AnimationDelegate {
+class MESSAGE_CENTER_EXPORT MessageCenterView
+    : public views::View,
+      public MessageCenterObserver,
+      public MessageCenterController,
+      public MessageListView::Observer,
+      public gfx::AnimationDelegate {
  public:
   MessageCenterView(MessageCenter* message_center,
                     MessageCenterTray* tray,
@@ -49,7 +52,6 @@
   void SetNotifications(const NotificationList::Notifications& notifications);
 
   void ClearAllClosableNotifications();
-  void OnAllNotificationsCleared();
 
   size_t NumMessageViewsForTest() const;
 
@@ -86,6 +88,9 @@
                                  int button_index) override;
   void ClickOnSettingsButton(const std::string& notification_id) override;
 
+  // Overridden from MessageListView::Observer:
+  void OnAllNotificationsCleared() override;
+
   // Overridden from gfx::AnimationDelegate:
   void AnimationEnded(const gfx::Animation* animation) override;
   void AnimationProgressed(const gfx::Animation* animation) override;
diff --git a/ui/message_center/views/message_list_view.cc b/ui/message_center/views/message_list_view.cc
index 7439364..055a7be 100644
--- a/ui/message_center/views/message_list_view.cc
+++ b/ui/message_center/views/message_list_view.cc
@@ -23,10 +23,8 @@
 const int kAnimateClearingNextNotificationDelayMS = 40;
 }  // namespace
 
-MessageListView::MessageListView(MessageCenterView* message_center_view,
-                                 bool top_down)
-    : message_center_view_(message_center_view),
-      reposition_top_(-1),
+MessageListView::MessageListView(bool top_down)
+    : reposition_top_(-1),
       fixed_height_(0),
       has_deferred_task_(false),
       clear_all_started_(false),
@@ -215,12 +213,21 @@
     clearing_all_views_.push_back(child);
   }
   if (clearing_all_views_.empty()) {
-    message_center_view()->OnAllNotificationsCleared();
+    for (auto& observer : observers_)
+      observer.OnAllNotificationsCleared();
   } else {
     DoUpdateIfPossible();
   }
 }
 
+void MessageListView::AddObserver(MessageListView::Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void MessageListView::RemoveObserver(MessageListView::Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
 void MessageListView::OnBoundsAnimatorProgressed(
     views::BoundsAnimator* animator) {
   DCHECK_EQ(&animator_, animator);
@@ -238,7 +245,8 @@
 
   if (clear_all_started_) {
     clear_all_started_ = false;
-    message_center_view()->OnAllNotificationsCleared();
+    for (auto& observer : observers_)
+      observer.OnAllNotificationsCleared();
   }
 
   if (has_deferred_task_) {
diff --git a/ui/message_center/views/message_list_view.h b/ui/message_center/views/message_list_view.h
index 0f381d3..ee3564d 100644
--- a/ui/message_center/views/message_list_view.h
+++ b/ui/message_center/views/message_list_view.h
@@ -24,17 +24,21 @@
 
 namespace message_center {
 
-class MessageCenterView;
 class MessageView;
 
 // Displays a list of messages for rich notifications. Functions as an array of
 // MessageViews and animates them on transitions. It also supports
 // repositioning.
-class MessageListView : public views::View,
-                        public views::BoundsAnimatorObserver {
+class MESSAGE_CENTER_EXPORT MessageListView
+    : public views::View,
+      public views::BoundsAnimatorObserver {
  public:
-  explicit MessageListView(MessageCenterView* message_center_view,
-                           bool top_down);
+  class Observer {
+   public:
+    virtual void OnAllNotificationsCleared() = 0;
+  };
+
+  explicit MessageListView(bool top_down);
   ~MessageListView() override;
 
   void AddNotificationAt(MessageView* view, int i);
@@ -44,7 +48,10 @@
   void ResetRepositionSession();
   void ClearAllClosableNotifications(const gfx::Rect& visible_scroll_rect);
 
-  MESSAGE_CENTER_EXPORT void SetRepositionTargetForTest(
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
+  void SetRepositionTargetForTest(
       const gfx::Rect& target_rect);
 
  protected:
@@ -61,6 +68,7 @@
 
  private:
   friend class MessageCenterViewTest;
+  friend class MessageListViewTest;
 
   bool IsValidChild(const views::View* child) const;
   void DoUpdateIfPossible();
@@ -81,11 +89,10 @@
 
   // Animate clearing one notification.
   void AnimateClearingOneNotification();
-  MessageCenterView* message_center_view() const {
-    return message_center_view_;
-  }
 
-  MessageCenterView* message_center_view_;  // Weak reference.
+  // List of MessageListView::Observer
+  base::ObserverList<Observer> observers_;
+
   // The top position of the reposition target rectangle.
   int reposition_top_;
   int fixed_height_;
@@ -107,4 +114,5 @@
 };
 
 }  // namespace message_center
+
 #endif  // UI_MESSAGE_CENTER_VIEWS_MESSAGE_LIST_VIEW_H_
diff --git a/ui/message_center/views/message_list_view_unittest.cc b/ui/message_center/views/message_list_view_unittest.cc
new file mode 100644
index 0000000..895f043
--- /dev/null
+++ b/ui/message_center/views/message_list_view_unittest.cc
@@ -0,0 +1,185 @@
+// Copyright 2016 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 <map>
+#include <memory>
+#include <utility>
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/message_center/fake_message_center.h"
+#include "ui/message_center/notification.h"
+#include "ui/message_center/notification_list.h"
+#include "ui/message_center/views/message_center_controller.h"
+#include "ui/message_center/views/message_list_view.h"
+#include "ui/message_center/views/notification_view.h"
+#include "ui/views/test/views_test_base.h"
+
+namespace message_center {
+
+static const char* kNotificationId1 = "notification id 1";
+
+namespace {
+
+/* Types **********************************************************************/
+
+enum CallType { GET_PREFERRED_SIZE, GET_HEIGHT_FOR_WIDTH, LAYOUT };
+
+/* Instrumented/Mock NotificationView subclass ********************************/
+
+class MockNotificationView : public NotificationView {
+ public:
+  class Test {
+   public:
+    virtual void RegisterCall(CallType type) = 0;
+  };
+
+  MockNotificationView(MessageCenterController* controller,
+                       const Notification& notification,
+                       Test* test);
+  ~MockNotificationView() override;
+
+  gfx::Size GetPreferredSize() const override;
+  int GetHeightForWidth(int w) const override;
+  void Layout() override;
+
+ private:
+  Test* test_;
+
+  DISALLOW_COPY_AND_ASSIGN(MockNotificationView);
+};
+
+MockNotificationView::MockNotificationView(MessageCenterController* controller,
+                                           const Notification& notification,
+                                           Test* test)
+    : NotificationView(controller, notification), test_(test) {}
+
+MockNotificationView::~MockNotificationView() {}
+
+gfx::Size MockNotificationView::GetPreferredSize() const {
+  test_->RegisterCall(GET_PREFERRED_SIZE);
+  DCHECK(child_count() > 0);
+  return NotificationView::GetPreferredSize();
+}
+
+int MockNotificationView::GetHeightForWidth(int width) const {
+  test_->RegisterCall(GET_HEIGHT_FOR_WIDTH);
+  DCHECK(child_count() > 0);
+  return NotificationView::GetHeightForWidth(width);
+}
+
+void MockNotificationView::Layout() {
+  test_->RegisterCall(LAYOUT);
+  DCHECK(child_count() > 0);
+  NotificationView::Layout();
+}
+
+}  // anonymous namespace
+
+/* Test fixture ***************************************************************/
+
+class MessageListViewTest : public views::ViewsTestBase,
+                            public MockNotificationView::Test,
+                            public MessageListView::Observer,
+                            public MessageCenterController {
+ public:
+  MessageListViewTest() {}
+
+  ~MessageListViewTest() override {}
+
+  void SetUp() override {
+    views::ViewsTestBase::SetUp();
+
+    message_list_view_.reset(new MessageListView(false /* top_down */));
+    message_list_view_->AddObserver(this);
+    message_list_view_->set_owned_by_client();
+
+    widget_.reset(new views::Widget());
+    views::Widget::InitParams params =
+        CreateParams(views::Widget::InitParams::TYPE_POPUP);
+    params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+    params.bounds = gfx::Rect(50, 50, 650, 650);
+    widget_->Init(params);
+    views::View* root = widget_->GetRootView();
+    root->AddChildView(message_list_view_.get());
+    widget_->Show();
+    widget_->Activate();
+  }
+
+  void TearDown() override {
+    widget_->CloseNow();
+    widget_.reset();
+
+    message_list_view_->RemoveObserver(this);
+    message_list_view_.reset();
+
+    views::ViewsTestBase::TearDown();
+  }
+
+ protected:
+  MessageListView* message_list_view() const {
+    return message_list_view_.get();
+  }
+
+  MockNotificationView* CreateNotificationView(
+      const Notification& notification) {
+    return new MockNotificationView(this, notification, this);
+  }
+
+ private:
+  // MockNotificationView::Test override
+  void RegisterCall(CallType type) override {}
+
+  // MessageListView::Observer override
+  void OnAllNotificationsCleared() override {}
+
+  // MessageCenterController override:
+  void ClickOnNotification(const std::string& notification_id) override {}
+  void RemoveNotification(const std::string& notification_id,
+                          bool by_user) override {}
+  std::unique_ptr<ui::MenuModel> CreateMenuModel(
+      const NotifierId& notifier_id,
+      const base::string16& display_source) override {
+    NOTREACHED();
+    return nullptr;
+  }
+  bool HasClickedListener(const std::string& notification_id) override {
+    return false;
+  }
+  void ClickOnNotificationButton(const std::string& notification_id,
+                                 int button_index) override {}
+  void ClickOnSettingsButton(const std::string& notification_id) override {}
+
+  // Widget to host a MessageListView.
+  std::unique_ptr<views::Widget> widget_;
+  // MessageListView to be tested.
+  std::unique_ptr<MessageListView> message_list_view_;
+
+  DISALLOW_COPY_AND_ASSIGN(MessageListViewTest);
+};
+
+/* Unit tests *****************************************************************/
+
+TEST_F(MessageListViewTest, AddNotification) {
+  // Create a dummy notification.
+  auto notification_view = CreateNotificationView(
+      Notification(NOTIFICATION_TYPE_SIMPLE, std::string(kNotificationId1),
+                   base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message1"),
+                   gfx::Image(), base::UTF8ToUTF16("display source"), GURL(),
+                   NotifierId(NotifierId::APPLICATION, "extension_id"),
+                   message_center::RichNotificationData(), nullptr));
+
+  EXPECT_EQ(0, message_list_view()->child_count());
+  EXPECT_FALSE(message_list_view()->Contains(notification_view));
+
+  // Add a notification.
+  message_list_view()->AddNotificationAt(notification_view, 0);
+
+  EXPECT_EQ(1, message_list_view()->child_count());
+  EXPECT_TRUE(message_list_view()->Contains(notification_view));
+}
+
+}  // namespace