diff --git a/DEPS b/DEPS
index 3ac3a07..d628be0 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '1a263aeb090c3c950c9a574da66a2e8a3c38348e',
+  'v8_revision': '959f3e87036a789d42526e703903bbab2541d7af',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
diff --git a/chrome/browser/media/webrtc/media_stream_devices_controller.cc b/chrome/browser/media/webrtc/media_stream_devices_controller.cc
index ca998fe..7fd2557 100644
--- a/chrome/browser/media/webrtc/media_stream_devices_controller.cc
+++ b/chrome/browser/media/webrtc/media_stream_devices_controller.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h"
 #include "chrome/browser/media/webrtc/media_stream_device_permissions.h"
 #include "chrome/browser/permissions/permission_manager.h"
+#include "chrome/browser/permissions/permission_request_manager.h"
 #include "chrome/browser/permissions/permission_result.h"
 #include "chrome/browser/permissions/permission_uma_util.h"
 #include "chrome/browser/permissions/permission_util.h"
@@ -53,7 +54,6 @@
 #include "content/public/browser/android/content_view_core.h"
 #include "ui/android/window_android.h"
 #else  // !defined(OS_ANDROID)
-#include "chrome/browser/permissions/permission_request_manager.h"
 #include "ui/vector_icons/vector_icons.h"
 #endif
 
@@ -465,7 +465,8 @@
     Profile* profile =
         Profile::FromBrowserContext(web_contents->GetBrowserContext());
     if (base::FeatureList::IsEnabled(
-            features::kUsePermissionManagerForMediaRequests)) {
+            features::kUsePermissionManagerForMediaRequests) &&
+        PermissionRequestManager::IsEnabled()) {
       std::vector<ContentSettingsType> content_settings_types;
 
       if (is_asking_for_audio)
diff --git a/components/navigation_interception/intercept_navigation_throttle.cc b/components/navigation_interception/intercept_navigation_throttle.cc
index 25875f0..a6bbcd0 100644
--- a/components/navigation_interception/intercept_navigation_throttle.cc
+++ b/components/navigation_interception/intercept_navigation_throttle.cc
@@ -14,7 +14,7 @@
 
 namespace {
 
-using ChecksPerformedCallback = base::Callback<void(bool, bool)>;
+using ChecksPerformedCallback = base::Callback<void(bool)>;
 
 // This is used to run |should_ignore_callback| if it can destroy the
 // WebContents (and the InterceptNavigationThrottle along). In that case,
@@ -31,10 +31,7 @@
   // If the InterceptNavigationThrottle that called RunCallback is still alive
   // after |should_ignore_callback| has run, this will run
   // InterceptNavigationThrottle::OnAsynchronousChecksPerformed.
-  // TODO(clamy): remove this boolean after crbug.com/570200 is fixed.
-  bool throttle_was_destroyed = !throttle.get();
-  on_checks_performed_callback.Run(should_ignore_navigation,
-                                   throttle_was_destroyed);
+  on_checks_performed_callback.Run(should_ignore_navigation);
 }
 
 }  // namespace
@@ -120,16 +117,12 @@
 }
 
 void InterceptNavigationThrottle::OnAsynchronousChecksPerformed(
-    bool should_ignore_navigation,
-    bool throttle_was_destroyed) {
-  CHECK(!throttle_was_destroyed);
-  content::NavigationHandle* handle = navigation_handle();
-  CHECK(handle);
+    bool should_ignore_navigation) {
   if (should_ignore_navigation) {
     navigation_handle()->CancelDeferredNavigation(
         content::NavigationThrottle::CANCEL_AND_IGNORE);
   } else {
-    handle->Resume();
+    navigation_handle()->Resume();
   }
 }
 
diff --git a/components/navigation_interception/intercept_navigation_throttle.h b/components/navigation_interception/intercept_navigation_throttle.h
index d8aee34..09158b8 100644
--- a/components/navigation_interception/intercept_navigation_throttle.h
+++ b/components/navigation_interception/intercept_navigation_throttle.h
@@ -44,10 +44,7 @@
 
   // Called to perform the checks asynchronously
   void RunCallbackAsynchronously(const NavigationParams& navigation_params);
-  // TODO(clamy): remove |throttle_was_destroyed| once crbug.com/570200 is
-  // fixed.
-  void OnAsynchronousChecksPerformed(bool should_ignore_navigation,
-                                     bool throttle_was_destroyed);
+  void OnAsynchronousChecksPerformed(bool should_ignore_navigation);
 
   CheckCallback should_ignore_callback_;
 
diff --git a/components/ntp_snippets/remote/remote_suggestion.cc b/components/ntp_snippets/remote/remote_suggestion.cc
index 4e652399..fe07a1cf 100644
--- a/components/ntp_snippets/remote/remote_suggestion.cc
+++ b/components/ntp_snippets/remote/remote_suggestion.cc
@@ -329,22 +329,6 @@
   return snippet;
 }
 
-// static
-std::unique_ptr<RemoteSuggestion> RemoteSuggestion::CreateForTesting(
-    const std::string& id,
-    int remote_category_id,
-    const GURL& url,
-    const std::string& publisher_name,
-    const GURL& amp_url) {
-  auto snippet =
-      MakeUnique(std::vector<std::string>(1, id), remote_category_id);
-  snippet->url_ = url;
-  snippet->publisher_name_ = publisher_name;
-  snippet->amp_url_ = amp_url;
-
-  return snippet;
-}
-
 SnippetProto RemoteSuggestion::ToProto() const {
   SnippetProto result;
   for (const std::string& id : ids_) {
diff --git a/components/ntp_snippets/remote/remote_suggestion.h b/components/ntp_snippets/remote/remote_suggestion.h
index 615c4fb..83adde34 100644
--- a/components/ntp_snippets/remote/remote_suggestion.h
+++ b/components/ntp_snippets/remote/remote_suggestion.h
@@ -54,14 +54,6 @@
   static std::unique_ptr<RemoteSuggestion> CreateFromProto(
       const SnippetProto& proto);
 
-  // TODO(treib): Make tests use the public interface and remove this.
-  static std::unique_ptr<RemoteSuggestion> CreateForTesting(
-      const std::string& id,
-      int remote_category_id,
-      const GURL& url,
-      const std::string& publisher_name,
-      const GURL& amp_url);
-
   // Creates a protocol buffer corresponding to this suggestion, for persisting.
   SnippetProto ToProto() const;
 
diff --git a/components/ntp_snippets/remote/remote_suggestions_database_unittest.cc b/components/ntp_snippets/remote/remote_suggestions_database_unittest.cc
index fd3e732..f9b6a397b 100644
--- a/components/ntp_snippets/remote/remote_suggestions_database_unittest.cc
+++ b/components/ntp_snippets/remote/remote_suggestions_database_unittest.cc
@@ -41,9 +41,14 @@
 namespace {
 
 std::unique_ptr<RemoteSuggestion> CreateTestSuggestion() {
-  return RemoteSuggestion::CreateForTesting(
-      "http://localhost", kArticlesRemoteId, GURL("http://localhost"),
-      "Publisher", GURL("http://amp"));
+  SnippetProto proto;
+  proto.add_ids("http://localhost");
+  proto.set_remote_category_id(1);  // Articles
+  auto* source = proto.add_sources();
+  source->set_url("http://localhost");
+  source->set_publisher_name("Publisher");
+  source->set_amp_url("http://amp");
+  return RemoteSuggestion::CreateFromProto(proto);
 }
 
 MATCHER_P(SnippetEq, snippet, "") {
diff --git a/content/browser/devtools/devtools_url_interceptor_request_job.cc b/content/browser/devtools/devtools_url_interceptor_request_job.cc
index 87271df..ef62d008 100644
--- a/content/browser/devtools/devtools_url_interceptor_request_job.cc
+++ b/content/browser/devtools/devtools_url_interceptor_request_job.cc
@@ -6,6 +6,7 @@
 
 #include "base/memory/ptr_util.h"
 #include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
 #include "content/browser/devtools/protocol/network_handler.h"
 #include "content/browser/devtools/protocol/page.h"
 #include "net/base/elements_upload_data_stream.h"
@@ -91,6 +92,21 @@
       std::move(headers_object), http_status_code, redirect_url);
 }
 
+void SendAuthRequiredEventOnUiThread(
+    base::WeakPtr<protocol::NetworkHandler> network_handler,
+    std::string interception_id,
+    std::unique_ptr<protocol::Network::Request> network_request,
+    std::string resource_type,
+    std::unique_ptr<protocol::Network::AuthChallenge> auth_challenge) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (!network_handler)
+    return;
+  network_handler->frontend()->RequestIntercepted(
+      interception_id, std::move(network_request), resource_type,
+      protocol::Maybe<protocol::Network::Headers>(), protocol::Maybe<int>(),
+      protocol::Maybe<protocol::String>(), std::move(auth_challenge));
+}
+
 class ProxyUploadElementReader : public net::UploadElementReader {
  public:
   explicit ProxyUploadElementReader(net::UploadElementReader* reader)
@@ -163,7 +179,7 @@
                        original_request->extra_request_headers(),
                        original_request->priority(),
                        original_request->context()),
-      waiting_for_user_response_(false),
+      waiting_for_user_response_(WaitingForUserResponse::NOT_WAITING),
       intercepting_requests_(true),
       killed_(false),
       interception_id_(interception_id),
@@ -196,7 +212,8 @@
     sub_request_.reset(new SubRequest(request_details_, this,
                                       devtools_url_request_interceptor_state_));
   } else {
-    waiting_for_user_response_ = true;
+    waiting_for_user_response_ =
+        WaitingForUserResponse::WAITING_FOR_INTERCEPTION_RESPONSE;
     std::unique_ptr<protocol::Network::Request> network_request =
         protocol::NetworkHandler::CreateRequestFromURLRequest(request());
     BrowserThread::PostTask(
@@ -310,12 +327,32 @@
   DCHECK_EQ(request, sub_request_->request());
   auth_info_ = auth_info;
 
-  // This notification came from the sub requests URLRequest::Delegate and we
-  // must proxy it the origional URLRequest::Delegate.  We can't do that
-  // directly but by implementing NeedsAuth and calling NotifyHeadersComplete
-  // triggers it. To close the loop we also need to implement
-  // GetAuthChallengeInfo, SetAuth and CancelAuth.
-  NotifyHeadersComplete();
+  // This notification came from the sub requests URLRequest::Delegate and
+  // depending on what the protocol user wants us to do we must either cancel
+  // the auth, provide the credentials or proxy it the original
+  // URLRequest::Delegate.
+
+  waiting_for_user_response_ =
+      WaitingForUserResponse::WAITING_FOR_AUTH_RESPONSE;
+
+  std::unique_ptr<protocol::Network::Request> network_request =
+      protocol::NetworkHandler::CreateRequestFromURLRequest(this->request());
+  std::unique_ptr<protocol::Network::AuthChallenge> auth_challenge =
+      protocol::Network::AuthChallenge::Create()
+          .SetSource(auth_info->is_proxy
+                         ? protocol::Network::AuthChallenge::SourceEnum::Proxy
+                         : protocol::Network::AuthChallenge::SourceEnum::Server)
+          .SetOrigin(auth_info->challenger.Serialize())
+          .SetScheme(auth_info->scheme)
+          .SetRealm(auth_info->realm)
+          .Build();
+
+  BrowserThread::PostTask(
+      BrowserThread::UI, FROM_HERE,
+      base::Bind(SendAuthRequiredEventOnUiThread, network_handler_,
+                 interception_id_, base::Passed(&network_request),
+                 ResourceTypeToString(resource_type_),
+                 base::Passed(&auth_challenge)));
 }
 
 void DevToolsURLInterceptorRequestJob::OnCertificateRequested(
@@ -396,7 +433,8 @@
   sub_request_->Cancel();
   sub_request_.reset();
 
-  waiting_for_user_response_ = true;
+  waiting_for_user_response_ =
+      WaitingForUserResponse::WAITING_FOR_INTERCEPTION_RESPONSE;
 
   std::unique_ptr<protocol::Network::Request> network_request =
       protocol::NetworkHandler::CreateRequestFromURLRequest(this->request());
@@ -416,25 +454,85 @@
   intercepting_requests_ = false;
 
   // Allow the request to continue if we're waiting for user input.
-  ContinueInterceptedRequest(
+  ProcessInterceptionRespose(
       base::MakeUnique<DevToolsURLRequestInterceptor::Modifications>(
           base::nullopt, base::nullopt, protocol::Maybe<std::string>(),
           protocol::Maybe<std::string>(), protocol::Maybe<std::string>(),
-          protocol::Maybe<protocol::Network::Headers>()));
+          protocol::Maybe<protocol::Network::Headers>(),
+          protocol::Maybe<protocol::Network::AuthChallengeResponse>()));
 }
 
-bool DevToolsURLInterceptorRequestJob::ContinueInterceptedRequest(
+void DevToolsURLInterceptorRequestJob::ContinueInterceptedRequest(
+    std::unique_ptr<DevToolsURLRequestInterceptor::Modifications> modifications,
+    std::unique_ptr<ContinueInterceptedRequestCallback> callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  switch (waiting_for_user_response_) {
+    case WaitingForUserResponse::NOT_WAITING:
+      BrowserThread::PostTask(
+          BrowserThread::UI, FROM_HERE,
+          base::BindOnce(&ContinueInterceptedRequestCallback::sendFailure,
+                         base::Passed(std::move(callback)),
+                         protocol::Response::InvalidParams(
+                             "Response already processed.")));
+      break;
+
+    case WaitingForUserResponse::WAITING_FOR_INTERCEPTION_RESPONSE:
+      if (modifications->auth_challenge_response.isJust()) {
+        BrowserThread::PostTask(
+            BrowserThread::UI, FROM_HERE,
+            base::BindOnce(&ContinueInterceptedRequestCallback::sendFailure,
+                           base::Passed(std::move(callback)),
+                           protocol::Response::InvalidParams(
+                               "authChallengeResponse not expected.")));
+        break;
+      }
+      ProcessInterceptionRespose(std::move(modifications));
+      BrowserThread::PostTask(
+          BrowserThread::UI, FROM_HERE,
+          base::BindOnce(&ContinueInterceptedRequestCallback::sendSuccess,
+                         base::Passed(std::move(callback))));
+      break;
+
+    case WaitingForUserResponse::WAITING_FOR_AUTH_RESPONSE:
+      if (!modifications->auth_challenge_response.isJust()) {
+        BrowserThread::PostTask(
+            BrowserThread::UI, FROM_HERE,
+            base::BindOnce(&ContinueInterceptedRequestCallback::sendFailure,
+                           base::Passed(std::move(callback)),
+                           protocol::Response::InvalidParams(
+                               "authChallengeResponse required.")));
+        break;
+      }
+      if (ProcessAuthRespose(std::move(modifications))) {
+        BrowserThread::PostTask(
+            BrowserThread::UI, FROM_HERE,
+            base::BindOnce(&ContinueInterceptedRequestCallback::sendSuccess,
+                           base::Passed(std::move(callback))));
+      } else {
+        BrowserThread::PostTask(
+            BrowserThread::UI, FROM_HERE,
+            base::BindOnce(&ContinueInterceptedRequestCallback::sendFailure,
+                           base::Passed(std::move(callback)),
+                           protocol::Response::InvalidParams(
+                               "Unrecognized authChallengeResponse.")));
+      }
+      break;
+
+    default:
+      NOTREACHED();
+      break;
+  }
+}
+
+void DevToolsURLInterceptorRequestJob::ProcessInterceptionRespose(
     std::unique_ptr<DevToolsURLRequestInterceptor::Modifications>
         modifications) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (!waiting_for_user_response_)
-    return false;
-  waiting_for_user_response_ = false;
+  waiting_for_user_response_ = WaitingForUserResponse::NOT_WAITING;
 
   if (modifications->error_reason) {
     NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
                                            *modifications->error_reason));
-    return true;
+    return;
   }
 
   if (modifications->raw_response) {
@@ -447,7 +545,7 @@
           request(), interception_id_);
     }
     NotifyHeadersComplete();
-    return true;
+    return;
   }
 
   if (redirect_) {
@@ -505,7 +603,43 @@
     sub_request_.reset(new SubRequest(request_details_, this,
                                       devtools_url_request_interceptor_state_));
   }
-  return true;
+}
+
+bool DevToolsURLInterceptorRequestJob::ProcessAuthRespose(
+    std::unique_ptr<DevToolsURLRequestInterceptor::Modifications>
+        modifications) {
+  waiting_for_user_response_ = WaitingForUserResponse::NOT_WAITING;
+
+  protocol::Network::AuthChallengeResponse* auth_challenge_response =
+      modifications->auth_challenge_response.fromJust();
+
+  if (auth_challenge_response->GetResponse() ==
+      protocol::Network::AuthChallengeResponse::ResponseEnum::Default) {
+    // The user wants the default behavior, we must proxy the auth request to
+    // the original URLRequest::Delegate.  We can't do that directly but by
+    // implementing NeedsAuth and calling NotifyHeadersComplete we trigger it.
+    // To close the loop we also need to implement GetAuthChallengeInfo, SetAuth
+    // and CancelAuth.
+    NotifyHeadersComplete();
+    return true;
+  }
+
+  if (auth_challenge_response->GetResponse() ==
+      protocol::Network::AuthChallengeResponse::ResponseEnum::CancelAuth) {
+    CancelAuth();
+    return true;
+  }
+
+  if (auth_challenge_response->GetResponse() ==
+      protocol::Network::AuthChallengeResponse::ResponseEnum::
+          ProvideCredentials) {
+    SetAuth(net::AuthCredentials(
+        base::UTF8ToUTF16(auth_challenge_response->GetUsername("").c_str()),
+        base::UTF8ToUTF16(auth_challenge_response->GetPassword("").c_str())));
+    return true;
+  }
+
+  return false;
 }
 
 DevToolsURLInterceptorRequestJob::RequestDetails::RequestDetails(
diff --git a/content/browser/devtools/devtools_url_interceptor_request_job.h b/content/browser/devtools/devtools_url_interceptor_request_job.h
index 7d5968d..8ec210c 100644
--- a/content/browser/devtools/devtools_url_interceptor_request_job.h
+++ b/content/browser/devtools/devtools_url_interceptor_request_job.h
@@ -74,11 +74,14 @@
   // Must be called on IO thread.
   void StopIntercepting();
 
-  // Must be called only once per interception. Returns true on success or false
-  // otherwise. Must be called on IO thread.
-  bool ContinueInterceptedRequest(
+  using ContinueInterceptedRequestCallback =
+      protocol::Network::Backend::ContinueInterceptedRequestCallback;
+
+  // Must be called only once per interception. Must be called on IO thread.
+  void ContinueInterceptedRequest(
       std::unique_ptr<DevToolsURLRequestInterceptor::Modifications>
-          modifications);
+          modifications,
+      std::unique_ptr<ContinueInterceptedRequestCallback> callback);
 
   WebContents* web_contents() const { return web_contents_; }
 
@@ -166,13 +169,27 @@
   // |mock_response_|.  In some cases (e.g. file access) this may be null.
   const net::HttpResponseHeaders* GetHttpResponseHeaders() const;
 
+  void ProcessInterceptionRespose(
+      std::unique_ptr<DevToolsURLRequestInterceptor::Modifications>
+          modification);
+
+  bool ProcessAuthRespose(
+      std::unique_ptr<DevToolsURLRequestInterceptor::Modifications>
+          modification);
+
+  enum class WaitingForUserResponse {
+    NOT_WAITING,
+    WAITING_FOR_INTERCEPTION_RESPONSE,
+    WAITING_FOR_AUTH_RESPONSE,
+  };
+
   scoped_refptr<DevToolsURLRequestInterceptor::State>
       devtools_url_request_interceptor_state_;
   RequestDetails request_details_;
   std::unique_ptr<SubRequest> sub_request_;
   std::unique_ptr<MockResponseDetails> mock_response_details_;
   std::unique_ptr<net::RedirectInfo> redirect_;
-  bool waiting_for_user_response_;
+  WaitingForUserResponse waiting_for_user_response_;
   bool intercepting_requests_;
   bool killed_;
   scoped_refptr<net::AuthChallengeInfo> auth_info_;
diff --git a/content/browser/devtools/devtools_url_request_interceptor.cc b/content/browser/devtools/devtools_url_request_interceptor.cc
index dd5b83a..de4f70f 100644
--- a/content/browser/devtools/devtools_url_request_interceptor.cc
+++ b/content/browser/devtools/devtools_url_request_interceptor.cc
@@ -115,19 +115,8 @@
     return;
   }
 
-  if (job->ContinueInterceptedRequest(std::move(modifications))) {
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
-        base::BindOnce(&ContinueInterceptedRequestCallback::sendSuccess,
-                       base::Passed(std::move(callback))));
-  } else {
-    BrowserThread::PostTask(
-        BrowserThread::UI, FROM_HERE,
-        base::BindOnce(
-            &ContinueInterceptedRequestCallback::sendFailure,
-            base::Passed(std::move(callback)),
-            protocol::Response::InvalidParams("Response already processed.")));
-  }
+  job->ContinueInterceptedRequest(std::move(modifications),
+                                  std::move(callback));
 }
 
 DevToolsURLInterceptorRequestJob* DevToolsURLRequestInterceptor::State::
@@ -377,13 +366,16 @@
     protocol::Maybe<std::string> modified_url,
     protocol::Maybe<std::string> modified_method,
     protocol::Maybe<std::string> modified_post_data,
-    protocol::Maybe<protocol::Network::Headers> modified_headers)
+    protocol::Maybe<protocol::Network::Headers> modified_headers,
+    protocol::Maybe<protocol::Network::AuthChallengeResponse>
+        auth_challenge_response)
     : error_reason(std::move(error_reason)),
       raw_response(std::move(raw_response)),
       modified_url(std::move(modified_url)),
       modified_method(std::move(modified_method)),
       modified_post_data(std::move(modified_post_data)),
-      modified_headers(std::move(modified_headers)) {}
+      modified_headers(std::move(modified_headers)),
+      auth_challenge_response(std::move(auth_challenge_response)) {}
 
 DevToolsURLRequestInterceptor::Modifications::~Modifications() {}
 
diff --git a/content/browser/devtools/devtools_url_request_interceptor.h b/content/browser/devtools/devtools_url_request_interceptor.h
index 512347b..cfd139a 100644
--- a/content/browser/devtools/devtools_url_request_interceptor.h
+++ b/content/browser/devtools/devtools_url_request_interceptor.h
@@ -57,7 +57,9 @@
                   protocol::Maybe<std::string> modified_url,
                   protocol::Maybe<std::string> modified_method,
                   protocol::Maybe<std::string> modified_post_data,
-                  protocol::Maybe<protocol::Network::Headers> modified_headers);
+                  protocol::Maybe<protocol::Network::Headers> modified_headers,
+                  protocol::Maybe<protocol::Network::AuthChallengeResponse>
+                      auth_challenge_response);
     ~Modifications();
 
     bool RequestShouldContineUnchanged() const;
@@ -72,6 +74,10 @@
     protocol::Maybe<std::string> modified_method;
     protocol::Maybe<std::string> modified_post_data;
     protocol::Maybe<protocol::Network::Headers> modified_headers;
+
+    // AuthChallengeResponse is mutually exclusive with the above.
+    protocol::Maybe<protocol::Network::AuthChallengeResponse>
+        auth_challenge_response;
   };
 
   // The State needs to be accessed on both UI and IO threads.
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc
index 4538cdc7..5c2c7238 100644
--- a/content/browser/devtools/protocol/network_handler.cc
+++ b/content/browser/devtools/protocol/network_handler.cc
@@ -886,6 +886,7 @@
     Maybe<std::string> method,
     Maybe<std::string> post_data,
     Maybe<protocol::Network::Headers> headers,
+    Maybe<protocol::Network::AuthChallengeResponse> auth_challenge_response,
     std::unique_ptr<ContinueInterceptedRequestCallback> callback) {
   DevToolsURLRequestInterceptor* devtools_url_request_interceptor =
       DevToolsURLRequestInterceptor::FromBrowserContext(
@@ -913,7 +914,8 @@
       interception_id,
       base::MakeUnique<DevToolsURLRequestInterceptor::Modifications>(
           std::move(error), std::move(raw_response), std::move(url),
-          std::move(method), std::move(post_data), std::move(headers)),
+          std::move(method), std::move(post_data), std::move(headers),
+          std::move(auth_challenge_response)),
       std::move(callback));
 }
 
diff --git a/content/browser/devtools/protocol/network_handler.h b/content/browser/devtools/protocol/network_handler.h
index 754a487..2f450db2 100644
--- a/content/browser/devtools/protocol/network_handler.h
+++ b/content/browser/devtools/protocol/network_handler.h
@@ -79,6 +79,7 @@
       Maybe<std::string> method,
       Maybe<std::string> post_data,
       Maybe<protocol::Network::Headers> headers,
+      Maybe<protocol::Network::AuthChallengeResponse> auth_challenge_response,
       std::unique_ptr<ContinueInterceptedRequestCallback> callback) override;
 
   void NavigationPreloadRequestSent(int worker_version_id,
diff --git a/content/browser/devtools/protocol_config.json b/content/browser/devtools/protocol_config.json
index 302f33b6..2b3209c2 100644
--- a/content/browser/devtools/protocol_config.json
+++ b/content/browser/devtools/protocol_config.json
@@ -39,7 +39,7 @@
                 "domain": "Network",
                 "include": ["enable", "disable", "clearBrowserCache", "clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookie", "setCookie", "setUserAgentOverride", "canEmulateNetworkConditions", "enableRequestInterception", "continueInterceptedRequest"],
                 "include_types": ["CookieSameSite", "Cookie", "Response", "Headers", "Request", "ResourceTiming", "SecurityDetails", "SignedCertificateTimestamp", "Initiator", "ResourcePriority", "RequestWillBeSentNotification", "ResponseReceivedNotification", "LoadingFinishedNotification", "LoadingFailedNotification", "RequestWillBeSentNotification", 
-                                  "ErrorReason", "RequestInterceptedNotification"],
+                                  "ErrorReason", "RequestInterceptedNotification", "AuthChallenge", "AuthChallengeResponse"],
                 "include_events": ["requestWillBeSent", "responseReceived", "loadingFinished", "loadingFailed", "requestIntercepted"],
                 "async": ["clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookie", "setCookie", "continueInterceptedRequest"]
             },
diff --git a/content/browser/renderer_host/media/audio_input_device_manager.cc b/content/browser/renderer_host/media/audio_input_device_manager.cc
index caa8320..75f91ee 100644
--- a/content/browser/renderer_host/media/audio_input_device_manager.cc
+++ b/content/browser/renderer_host/media/audio_input_device_manager.cc
@@ -5,6 +5,7 @@
 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
 
 #include <memory>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/command_line.h"
@@ -115,29 +116,27 @@
 
   // Post a callback through the listener on IO thread since
   // MediaStreamManager is expecting the callback asynchronously.
-  BrowserThread::PostTask(BrowserThread::IO,
-                          FROM_HERE,
-                          base::Bind(&AudioInputDeviceManager::ClosedOnIOThread,
-                                     this, stream_type, session_id));
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      base::BindOnce(&AudioInputDeviceManager::ClosedOnIOThread, this,
+                     stream_type, session_id));
 }
 
 #if defined(OS_CHROMEOS)
 void AudioInputDeviceManager::RegisterKeyboardMicStream(
-    const base::Closure& callback) {
+    base::OnceClosure callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   ++keyboard_mic_streams_count_;
   if (keyboard_mic_streams_count_ == 1) {
     BrowserThread::PostTaskAndReply(
-        BrowserThread::UI,
-        FROM_HERE,
-        base::Bind(
+        BrowserThread::UI, FROM_HERE,
+        base::BindOnce(
             &AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread,
-            this,
-            true),
-        callback);
+            this, true),
+        std::move(callback));
   } else {
-    callback.Run();
+    std::move(callback).Run();
   }
 }
 
@@ -148,12 +147,10 @@
   DCHECK_GE(keyboard_mic_streams_count_, 0);
   if (keyboard_mic_streams_count_ == 0) {
     BrowserThread::PostTask(
-        BrowserThread::UI,
-        FROM_HERE,
-        base::Bind(
+        BrowserThread::UI, FROM_HERE,
+        base::BindOnce(
             &AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread,
-            this,
-            false));
+            this, false));
   }
 }
 #endif
diff --git a/content/browser/renderer_host/media/audio_input_device_manager.h b/content/browser/renderer_host/media/audio_input_device_manager.h
index e1237f1..a2923c9 100644
--- a/content/browser/renderer_host/media/audio_input_device_manager.h
+++ b/content/browser/renderer_host/media/audio_input_device_manager.h
@@ -59,7 +59,7 @@
   // inactivates the keyboard mic accordingly. The (in)activation is done on the
   // UI thread and for the register case a callback must therefor be provided
   // which is called when activated.
-  void RegisterKeyboardMicStream(const base::Closure& callback);
+  void RegisterKeyboardMicStream(base::OnceClosure callback);
   void UnregisterKeyboardMicStream();
 #endif
 
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.cc b/content/browser/renderer_host/media/audio_input_renderer_host.cc
index 6c98e53..83e4dd3 100644
--- a/content/browser/renderer_host/media/audio_input_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_input_renderer_host.cc
@@ -139,23 +139,24 @@
     media::AudioInputController* controller) {
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(&AudioInputRendererHost::DoCompleteCreation, this,
-                 base::RetainedRef(controller)));
+      base::BindOnce(&AudioInputRendererHost::DoCompleteCreation, this,
+                     base::RetainedRef(controller)));
 }
 
 void AudioInputRendererHost::OnError(media::AudioInputController* controller,
     media::AudioInputController::ErrorCode error_code) {
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
-      base::Bind(&AudioInputRendererHost::DoHandleError, this,
-                 base::RetainedRef(controller), error_code));
+      base::BindOnce(&AudioInputRendererHost::DoHandleError, this,
+                     base::RetainedRef(controller), error_code));
 }
 
 void AudioInputRendererHost::OnLog(media::AudioInputController* controller,
                                    const std::string& message) {
-  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
-                          base::Bind(&AudioInputRendererHost::DoLog, this,
-                                     base::RetainedRef(controller), message));
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      base::BindOnce(&AudioInputRendererHost::DoLog, this,
+                     base::RetainedRef(controller), message));
 }
 
 void AudioInputRendererHost::set_renderer_pid(int32_t renderer_pid) {
@@ -259,8 +260,8 @@
       media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) {
     media_stream_manager_->audio_input_device_manager()
         ->RegisterKeyboardMicStream(
-            base::Bind(&AudioInputRendererHost::DoCreateStream, this, stream_id,
-                       render_frame_id, session_id, config));
+            base::BindOnce(&AudioInputRendererHost::DoCreateStream, this,
+                           stream_id, render_frame_id, session_id, config));
   } else {
     DoCreateStream(stream_id, render_frame_id, session_id, config);
   }
@@ -384,12 +385,9 @@
 
 #if BUILDFLAG(ENABLE_WEBRTC)
   BrowserThread::PostTask(
-      BrowserThread::UI,
-      FROM_HERE,
-      base::Bind(
-          &AudioInputRendererHost::MaybeEnableDebugRecordingForId,
-          this,
-          stream_id));
+      BrowserThread::UI, FROM_HERE,
+      base::BindOnce(&AudioInputRendererHost::MaybeEnableDebugRecordingForId,
+                     this, stream_id));
 #endif
 }
 
@@ -459,8 +457,8 @@
 
   if (!entry->pending_close) {
     LogMessage(entry->stream_id, "CloseAndDeleteStream", true);
-    entry->controller->Close(base::Bind(&AudioInputRendererHost::DeleteEntry,
-                                        this, entry));
+    entry->controller->Close(
+        base::BindOnce(&AudioInputRendererHost::DeleteEntry, this, entry));
     entry->pending_close = true;
     audio_log_->OnClosed(entry->stream_id);
   }
@@ -535,7 +533,7 @@
   if (WebRTCInternals::GetInstance()->IsAudioDebugRecordingsEnabled()) {
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
-        base::Bind(
+        base::BindOnce(
             &AudioInputRendererHost::
                 AddExtensionsToPathAndEnableDebugRecordingForId,
             this,
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc b/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
index 425e7da..24881e1 100644
--- a/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
+++ b/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
@@ -176,10 +176,9 @@
                              type) {
     GetTaskRunnerForTesting()->PostTask(
         FROM_HERE,
-        base::Bind(&AudioInputController::EventHandler::OnCreated,
-                   base::Unretained(event_handler), base::Unretained(this)));
-    ON_CALL(*this, Close(_))
-        .WillByDefault(Invoke(this, &MockAudioInputController::ExecuteClose));
+        base::BindOnce(&AudioInputController::EventHandler::OnCreated,
+                       base::Unretained(event_handler),
+                       base::Unretained(this)));
     ON_CALL(*this, EnableDebugRecording(_))
         .WillByDefault(SaveArg<0>(&file_name));
   }
@@ -189,12 +188,21 @@
   // File name that we pretend to do a debug recording to, if any.
   base::FilePath debug_file_name() { return file_name; }
 
+  void Close(base::OnceClosure cl) override {
+    DidClose();
+    // Hop to audio manager thread before calling task, since this is the real
+    // behavior.
+    GetTaskRunnerForTesting()->PostTaskAndReply(
+        FROM_HERE, base::BindOnce([]() {}), std::move(cl));
+  }
+
   MOCK_METHOD0(Record, void());
-  MOCK_METHOD1(Close, void(const base::Closure&));
   MOCK_METHOD1(SetVolume, void(double));
   MOCK_METHOD1(EnableDebugRecording, void(const base::FilePath&));
   MOCK_METHOD0(DisableDebugRecording, void());
 
+  MOCK_METHOD0(DidClose, void());
+
   // AudioInputCallback impl, irrelevant to us.
   MOCK_METHOD4(
       OnData,
@@ -205,13 +213,6 @@
   ~MockAudioInputController() override = default;
 
  private:
-  void ExecuteClose(const base::Closure& task) {
-    // Hop to audio manager thread before calling task, since this is the real
-    // behavior.
-    GetTaskRunnerForTesting()->PostTaskAndReply(FROM_HERE, base::Bind([]() {}),
-                                                task);
-  }
-
   base::FilePath file_name;
 };
 
@@ -340,7 +341,7 @@
       kStreamId, kRenderFrameId, session_id, DefaultConfig()));
 
   base::RunLoop().RunUntilIdle();
-  EXPECT_CALL(*controller_factory_.controller(0), Close(_));
+  EXPECT_CALL(*controller_factory_.controller(0), DidClose());
 }
 
 // If authorization hasn't been granted, only reply with and error and do
@@ -366,7 +367,7 @@
       kStreamId, kRenderFrameId, session_id, DefaultConfig()));
 
   base::RunLoop().RunUntilIdle();
-  EXPECT_CALL(*controller_factory_.controller(0), Close(_));
+  EXPECT_CALL(*controller_factory_.controller(0), DidClose());
 }
 
 // Checks that stream is started when calling record.
@@ -383,7 +384,7 @@
   base::RunLoop().RunUntilIdle();
 
   EXPECT_CALL(*controller_factory_.controller(0), Record());
-  EXPECT_CALL(*controller_factory_.controller(0), Close(_));
+  EXPECT_CALL(*controller_factory_.controller(0), DidClose());
 
   airh_->OnMessageReceived(AudioInputHostMsg_RecordStream(kStreamId));
   base::RunLoop().RunUntilIdle();
@@ -407,7 +408,7 @@
 
   EXPECT_CALL(*controller_factory_.controller(0), SetVolume(0.5));
   EXPECT_CALL(*controller_factory_.controller(0), Record());
-  EXPECT_CALL(*controller_factory_.controller(0), Close(_));
+  EXPECT_CALL(*controller_factory_.controller(0), DidClose());
 
   airh_->OnMessageReceived(AudioInputHostMsg_SetVolume(kStreamId, 0.5));
   airh_->OnMessageReceived(AudioInputHostMsg_RecordStream(kStreamId));
@@ -430,7 +431,7 @@
       kStreamId, kRenderFrameId, session_id, DefaultConfig()));
   base::RunLoop().RunUntilIdle();
 
-  EXPECT_CALL(*controller_factory_.controller(0), Close(_));
+  EXPECT_CALL(*controller_factory_.controller(0), DidClose());
   EXPECT_CALL(renderer_, WasShutDown());
 
   airh_->OnMessageReceived(AudioInputHostMsg_SetVolume(kStreamId, 5));
@@ -451,7 +452,7 @@
       kStreamId, kRenderFrameId, session_id, DefaultConfig()));
   base::RunLoop().RunUntilIdle();
 
-  EXPECT_CALL(*controller_factory_.controller(0), Close(_));
+  EXPECT_CALL(*controller_factory_.controller(0), DidClose());
   EXPECT_CALL(renderer_, WasShutDown());
 
   airh_->OnMessageReceived(AudioInputHostMsg_SetVolume(kStreamId, -0.5));
@@ -475,7 +476,7 @@
       kStreamId, kRenderFrameId, session_id, DefaultConfig()));
   base::RunLoop().RunUntilIdle();
 
-  EXPECT_CALL(*controller_factory_.controller(0), Close(_));
+  EXPECT_CALL(*controller_factory_.controller(0), DidClose());
 }
 
 // Checks that when two streams are created, messages are routed to the correct
@@ -512,8 +513,8 @@
   airh_->DisableDebugRecording();
 #endif  // ENABLE_WEBRTC
 
-  EXPECT_CALL(*controller_factory_.controller(0), Close(_));
-  EXPECT_CALL(*controller_factory_.controller(1), Close(_));
+  EXPECT_CALL(*controller_factory_.controller(0), DidClose());
+  EXPECT_CALL(*controller_factory_.controller(1), DidClose());
 }
 
 // Checks that the stream is properly cleaned up and a notification is sent to
@@ -530,7 +531,7 @@
       kStreamId, kRenderFrameId, session_id, DefaultConfig()));
 
   base::RunLoop().RunUntilIdle();
-  EXPECT_CALL(*controller_factory_.controller(0), Close(_));
+  EXPECT_CALL(*controller_factory_.controller(0), DidClose());
   EXPECT_CALL(renderer_, NotifyStreamError(kStreamId));
 
   controller_factory_.controller(0)->handler()->OnError(
@@ -562,7 +563,7 @@
       kStreamId, kRenderFrameId, session_id, DefaultConfig()));
   base::RunLoop().RunUntilIdle();
 
-  EXPECT_CALL(*controller_factory_.controller(0), Close(_));
+  EXPECT_CALL(*controller_factory_.controller(0), DidClose());
 }
 
 }  // namespace content
diff --git a/docs/updating_clang.md b/docs/updating_clang.md
index d412d3a..d337089 100644
--- a/docs/updating_clang.md
+++ b/docs/updating_clang.md
@@ -2,7 +2,7 @@
 
 1.  Sync your Chromium tree to the latest revision to pick up any plugin
     changes
-1.  Run `python tools/clang/scripts/upload_revision.py --clang_revision=NNNN`
+1.  Run `python tools/clang/scripts/upload_revision.py NNNN`
     with the target LLVM SVN revision number. This creates a roll CL on a new
     branch, uploads it and starts tryjobs that build the compiler binaries into
     a staging bucket on Google Cloud Storage (GCS).
diff --git a/ios/chrome/browser/ui/tools_menu/BUILD.gn b/ios/chrome/browser/ui/tools_menu/BUILD.gn
index 7865a46..15dde6b1 100644
--- a/ios/chrome/browser/ui/tools_menu/BUILD.gn
+++ b/ios/chrome/browser/ui/tools_menu/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 source_set("tools_menu") {
+  configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
     "reading_list_menu_view_item.h",
     "reading_list_menu_view_item.mm",
diff --git a/ios/chrome/browser/ui/tools_menu/reading_list_menu_view_item.mm b/ios/chrome/browser/ui/tools_menu/reading_list_menu_view_item.mm
index faedbaf..b959513 100644
--- a/ios/chrome/browser/ui/tools_menu/reading_list_menu_view_item.mm
+++ b/ios/chrome/browser/ui/tools_menu/reading_list_menu_view_item.mm
@@ -5,11 +5,14 @@
 #import "ios/chrome/browser/ui/tools_menu/reading_list_menu_view_item.h"
 
 #include "base/mac/foundation_util.h"
-#import "base/mac/scoped_nsobject.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/chrome/browser/ui/reading_list/number_badge_view.h"
 #import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace {
 // ID for cell reuse
 static NSString* const kReadingListCellID = @"ReadingListCellID";
@@ -17,7 +20,7 @@
 }  // namespace
 
 @interface ReadingListMenuViewCell () {
-  base::scoped_nsobject<NumberBadgeView> _badge;
+  NumberBadgeView* _badge;
 }
 @end
 
@@ -42,7 +45,7 @@
 
   [super initializeViews];
 
-  _badge.reset([[NumberBadgeView alloc] initWithFrame:CGRectZero]);
+  _badge = [[NumberBadgeView alloc] initWithFrame:CGRectZero];
   [_badge setTranslatesAutoresizingMaskIntoConstraints:NO];
   [self.contentView addSubview:_badge];
 
@@ -65,7 +68,7 @@
       addObject:[self.title.centerYAnchor
                     constraintEqualToAnchor:self.contentView.centerYAnchor]];
   [constraintsToApply
-      addObject:[_badge.get().centerYAnchor
+      addObject:[_badge.centerYAnchor
                     constraintEqualToAnchor:self.contentView.centerYAnchor]];
 
   [NSLayoutConstraint activateConstraints:constraintsToApply];
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_constants.mm b/ios/chrome/browser/ui/tools_menu/tools_menu_constants.mm
index 3c3b5e5a..59908cf 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_constants.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_constants.mm
@@ -4,6 +4,10 @@
 
 #include "ios/chrome/browser/ui/tools_menu/tools_menu_constants.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 NSString* const kToolsMenuNewTabId = @"kToolsMenuNewTabId";
 NSString* const kToolsMenuNewIncognitoTabId = @"kToolsMenuNewIncognitoTabId";
 NSString* const kToolsMenuCloseAllTabsId = @"kToolsMenuCloseAllTabsId";
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_model.mm b/ios/chrome/browser/ui/tools_menu/tools_menu_model.mm
index 7fc0a436..f4d45676 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_model.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_model.mm
@@ -15,6 +15,10 @@
 #import "ios/public/provider/chrome/browser/user_feedback/user_feedback_provider.h"
 #include "ios/web/public/user_agent.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 // Menu items can be marked as visible or not when Incognito is enabled.
 // The following bits are used for |visibility| field in |MenuItemInfo|.
 const NSInteger kVisibleIncognitoOnly = 1 << 0;
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h b/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h
index 4ef3a53..53c4fc6 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h
@@ -53,12 +53,12 @@
 @property(nonatomic, assign) BOOL isCurrentPageBookmarked;
 @property(nonatomic, assign) BOOL isTabLoading;
 // The tool button to be shown hovering above the popup.
-@property(nonatomic, readonly) UIButton* toolsButton;
+@property(nonatomic, readonly, weak) UIButton* toolsButton;
 
 // Keeps track of the items in tools menu.
 @property(nonatomic, copy) NSArray* menuItems;
 
-@property(nonatomic, assign) id<ToolsPopupTableDelegate> delegate;
+@property(nonatomic, weak) id<ToolsPopupTableDelegate> delegate;
 
 // Initializes the Tools popup menu.
 - (void)initializeMenuWithConfiguration:(ToolsMenuConfiguration*)configuration;
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.mm b/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.mm
index 372c0d0..8f0e860 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.mm
@@ -7,10 +7,7 @@
 #include <stdint.h>
 
 #include "base/ios/ios_util.h"
-#import "base/ios/weak_nsobject.h"
 #include "base/logging.h"
-#include "base/mac/objc_property_releaser.h"
-#include "base/mac/scoped_nsobject.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/histogram_macros.h"
 #include "components/strings/grit/components_strings.h"
@@ -37,6 +34,11 @@
 #include "ios/web/public/user_agent.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/l10n/l10n_util_mac.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 using ios::material::TimingFunction;
 
 namespace {
@@ -105,14 +107,13 @@
 @interface ToolsMenuViewController ()<UICollectionViewDelegateFlowLayout,
                                       UICollectionViewDataSource,
                                       ReadingListMenuNotificationDelegate> {
-  base::mac::ObjCPropertyReleaser _propertyReleaser_ToolsMenuViewController;
   BOOL _waitForInk;
   // Weak pointer to ReadingListMenuNotifier, used to set the starting values
   // for the reading list badge.
-  base::WeakNSObject<ReadingListMenuNotifier> _readingListMenuNotifier;
+  __weak ReadingListMenuNotifier* _readingListMenuNotifier;
 }
-@property(nonatomic, retain) ToolsMenuCollectionView* menuView;
-@property(nonatomic, retain) MDCInkView* touchFeedbackView;
+@property(nonatomic, strong) ToolsMenuCollectionView* menuView;
+@property(nonatomic, strong) MDCInkView* touchFeedbackView;
 @property(nonatomic, assign) ToolbarType toolbarType;
 // Populated by the configuration object in |initializeMenuWithConfiguration:|
 // stores the time this view controller was requested by the user for the
@@ -217,7 +218,7 @@
   self.requestStartTime = configuration.requestStartTime;
 
   if (configuration.readingListMenuNotifier) {
-    _readingListMenuNotifier.reset(configuration.readingListMenuNotifier);
+    _readingListMenuNotifier = configuration.readingListMenuNotifier;
     [configuration.readingListMenuNotifier setDelegate:self];
   }
 
@@ -331,29 +332,6 @@
 
 #pragma mark - UIViewController Overrides
 
-- (instancetype)initWithNibName:(NSString*)nibNameOrNil
-                         bundle:(NSBundle*)nibBundleOrNil {
-  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
-  if (self)
-    [self commonInitialization];
-
-  return self;
-}
-
-- (instancetype)initWithCoder:(NSCoder*)aDecoder {
-  self = [super initWithCoder:aDecoder];
-  if (self)
-    [self commonInitialization];
-
-  return self;
-}
-
-- (void)commonInitialization {
-  _propertyReleaser_ToolsMenuViewController.Init(
-      self, [ToolsMenuViewController class]);
-  _readingListMenuNotifier.reset();
-}
-
 - (void)loadView {
   [super loadView];
 
@@ -364,8 +342,8 @@
 
   _touchFeedbackView = [[MDCInkView alloc] initWithFrame:CGRectZero];
 
-  base::scoped_nsobject<UICollectionViewFlowLayout> menuItemsLayout(
-      [[UICollectionViewFlowLayout alloc] init]);
+  UICollectionViewFlowLayout* menuItemsLayout =
+      [[UICollectionViewFlowLayout alloc] init];
 
   _menuView = [[ToolsMenuCollectionView alloc] initWithFrame:[rootView bounds]
                                         collectionViewLayout:menuItemsLayout];
@@ -464,10 +442,10 @@
   [CATransaction commit];
 
   [[self readingListCell]
-      updateBadgeCount:_readingListMenuNotifier.get().readingListUnreadCount
+      updateBadgeCount:_readingListMenuNotifier.readingListUnreadCount
               animated:YES];
   [[self readingListCell]
-      updateSeenState:_readingListMenuNotifier.get().readingListUnseenItemsExist
+      updateSeenState:_readingListMenuNotifier.readingListUnseenItemsExist
              animated:YES];
 }
 
@@ -543,7 +521,7 @@
     didUnhighlightItemAtIndexPath:(NSIndexPath*)path {
   CGPoint touchPoint = [view touchEndPoint];
   touchPoint = [view convertPoint:touchPoint toView:_touchFeedbackView];
-  base::WeakNSObject<MDCInkView> inkView(_touchFeedbackView);
+  __weak MDCInkView* inkView = _touchFeedbackView;
   _waitForInk = YES;
   [_touchFeedbackView startTouchEndedAnimationAtPoint:touchPoint
                                            completion:^{
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.h b/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.h
index 2cb597e..8afe3e8 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.h
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.h
@@ -14,7 +14,7 @@
 @property(nonatomic, copy) NSString* title;
 @property(nonatomic, assign) NSInteger tag;
 @property(nonatomic, assign) BOOL active;
-@property(nonatomic, assign) ToolsMenuViewCell* tableViewCell;
+@property(nonatomic, weak) ToolsMenuViewCell* tableViewCell;
 
 + (NSString*)cellID;
 + (Class)cellClass;
@@ -25,7 +25,7 @@
 @end
 
 @interface ToolsMenuViewCell : UICollectionViewCell
-@property(nonatomic, retain) UILabel* title;
+@property(nonatomic, strong) UILabel* title;
 @property(nonatomic, readonly) CGFloat horizontalMargin;
 
 - (void)configureForMenuItem:(ToolsMenuViewItem*)item;
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.mm b/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.mm
index 0392cd8..dc01e5ba 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.mm
@@ -5,10 +5,13 @@
 #import "ios/chrome/browser/ui/tools_menu/tools_menu_view_item.h"
 
 #include "base/i18n/rtl.h"
-#include "base/mac/objc_property_releaser.h"
 #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
 #include "ui/base/l10n/l10n_util.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace {
 const CGFloat kToolsMenuItemHorizontalMargin = 16;
 // Increase the margin for RTL so the labels don't overlap the tools icon.
@@ -16,10 +19,7 @@
 static NSString* const kMenuItemCellID = @"MenuItemCellID";
 }
 
-@implementation ToolsMenuViewItem {
-  base::mac::ObjCPropertyReleaser _propertyReleaser_ToolsMenuViewItem;
-}
-
+@implementation ToolsMenuViewItem
 @synthesize accessibilityIdentifier = _accessibilityIdentifier;
 @synthesize active = _active;
 @synthesize title = _title;
@@ -29,7 +29,6 @@
 - (id)init {
   self = [super init];
   if (self) {
-    _propertyReleaser_ToolsMenuViewItem.Init(self, [ToolsMenuViewItem class]);
     _active = YES;
   }
 
@@ -47,7 +46,7 @@
 + (instancetype)menuItemWithTitle:(NSString*)title
           accessibilityIdentifier:(NSString*)accessibilityIdentifier
                           command:(int)commandID {
-  ToolsMenuViewItem* menuItem = [[[self alloc] init] autorelease];
+  ToolsMenuViewItem* menuItem = [[self alloc] init];
   [menuItem setAccessibilityLabel:title];
   [menuItem setAccessibilityIdentifier:accessibilityIdentifier];
   [menuItem setTag:commandID];
@@ -58,10 +57,7 @@
 
 @end
 
-@implementation ToolsMenuViewCell {
-  base::mac::ObjCPropertyReleaser _propertyReleaser_ToolsMenuViewCell;
-}
-
+@implementation ToolsMenuViewCell
 @synthesize title = _title;
 @synthesize horizontalMargin = _horizontalMargin;
 
@@ -82,7 +78,6 @@
 }
 
 - (void)commonInitialization {
-  _propertyReleaser_ToolsMenuViewCell.Init(self, [ToolsMenuViewCell class]);
   _horizontalMargin = !base::i18n::IsRTL() ? kToolsMenuItemHorizontalMargin
                                            : kToolsMenuItemHorizontalMarginRTL;
   [self setBackgroundColor:[UIColor whiteColor]];
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_view_tools_cell.mm b/ios/chrome/browser/ui/tools_menu/tools_menu_view_tools_cell.mm
index e5c3b10..2ae9d1b 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_view_tools_cell.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_view_tools_cell.mm
@@ -4,7 +4,6 @@
 
 #import "ios/chrome/browser/ui/tools_menu/tools_menu_view_tools_cell.h"
 
-#include "base/mac/objc_property_releaser.h"
 #include "components/strings/grit/components_strings.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
@@ -18,9 +17,11 @@
 // IDC_MinimumLabelValue) to avoid collisions.
 #define IDC_TEMP_EDIT_BOOKMARK 3900
 
-@implementation ToolsMenuViewToolsCell {
-  base::mac::ObjCPropertyReleaser _propertyReleaser_ToolsMenuViewToolsCell;
-}
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation ToolsMenuViewToolsCell
 
 @synthesize reloadButton = _reloadButton;
 @synthesize shareButton = _shareButton;
@@ -46,9 +47,6 @@
 }
 
 - (void)commonInitialization {
-  _propertyReleaser_ToolsMenuViewToolsCell.Init(self,
-                                                [ToolsMenuViewToolsCell class]);
-
   [self setBackgroundColor:[UIColor whiteColor]];
   [self setOpaque:YES];
 
diff --git a/ios/chrome/browser/ui/tools_menu/tools_popup_controller.mm b/ios/chrome/browser/ui/tools_menu/tools_popup_controller.mm
index 13da1c8..8cc88f5 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_popup_controller.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_popup_controller.mm
@@ -7,15 +7,19 @@
 #import <QuartzCore/QuartzCore.h>
 
 #include "base/logging.h"
-#include "base/mac/scoped_nsobject.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
+#import "ios/chrome/browser/ui/popup_menu/popup_menu_view.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
 #import "ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/shared/chrome/browser/ui/tools_menu/tools_menu_configuration.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 using base::UserMetricsAction;
 
 NSString* const kToolsMenuTableViewId = @"kToolsMenuTableViewId";
@@ -33,9 +37,9 @@
 }  // namespace
 
 @interface ToolsPopupController ()<ToolsPopupTableDelegate> {
-  base::scoped_nsobject<ToolsMenuViewController> _toolsMenuViewController;
+  ToolsMenuViewController* _toolsMenuViewController;
   // Container view of the menu items table.
-  base::scoped_nsobject<UIView> _toolsTableViewContainer;
+  UIView* _toolsTableViewContainer;
 }
 @end
 
@@ -46,8 +50,8 @@
   DCHECK(configuration.displayView);
   self = [super initWithParentView:configuration.displayView];
   if (self) {
-    _toolsMenuViewController.reset([[ToolsMenuViewController alloc] init]);
-    _toolsTableViewContainer.reset([[_toolsMenuViewController view] retain]);
+    _toolsMenuViewController = [[ToolsMenuViewController alloc] init];
+    _toolsTableViewContainer = [_toolsMenuViewController view];
     [_toolsTableViewContainer layer].cornerRadius = 2;
     [_toolsTableViewContainer layer].masksToBounds = YES;
     [_toolsMenuViewController initializeMenuWithConfiguration:configuration];
@@ -114,7 +118,6 @@
 - (void)dealloc {
   [_toolsTableViewContainer removeFromSuperview];
   [_toolsMenuViewController setDelegate:nil];
-  [super dealloc];
 }
 
 - (void)fadeInPopupFromSource:(CGPoint)source
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc
index 5c8997e0..7d2a2cb 100644
--- a/media/audio/audio_input_controller.cc
+++ b/media/audio/audio_input_controller.cc
@@ -133,7 +133,7 @@
     error_during_callback_ = true;
     controller_->task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&AudioInputController::DoReportError, weak_controller_));
+        base::BindOnce(&AudioInputController::DoReportError, weak_controller_));
   }
 
   void DeliverDataToSyncWriter(const AudioBus* source,
@@ -155,9 +155,9 @@
       // Use event handler on the audio thread to relay a message to the ARIH
       // in content which does the actual logging on the IO thread.
       controller_->task_runner_->PostTask(
-          FROM_HERE,
-          base::Bind(&AudioInputController::DoLogAudioLevels, weak_controller_,
-                     average_power_dbfs, mic_volume_percent));
+          FROM_HERE, base::BindOnce(&AudioInputController::DoLogAudioLevels,
+                                    weak_controller_, average_power_dbfs,
+                                    mic_volume_percent));
     }
   }
 
@@ -232,9 +232,9 @@
   // Create and open a new audio input stream from the existing
   // audio-device thread. Use the provided audio-input device.
   if (!controller->task_runner_->PostTask(
-          FROM_HERE, base::Bind(&AudioInputController::DoCreate, controller,
-                                base::Unretained(audio_manager), params,
-                                device_id, enable_agc))) {
+          FROM_HERE, base::BindOnce(&AudioInputController::DoCreate, controller,
+                                    base::Unretained(audio_manager), params,
+                                    device_id, enable_agc))) {
     controller = nullptr;
   }
 
@@ -267,8 +267,9 @@
                                user_input_monitor, params, VIRTUAL));
 
   if (!controller->task_runner_->PostTask(
-          FROM_HERE, base::Bind(&AudioInputController::DoCreateForStream,
-                                controller, stream, /*enable_agc*/ false))) {
+          FROM_HERE,
+          base::BindOnce(&AudioInputController::DoCreateForStream, controller,
+                         stream, /*enable_agc*/ false))) {
     controller = nullptr;
   }
 
@@ -277,22 +278,24 @@
 
 void AudioInputController::Record() {
   DCHECK(creator_task_runner_->BelongsToCurrentThread());
-  task_runner_->PostTask(FROM_HERE, base::Bind(
-      &AudioInputController::DoRecord, this));
+  task_runner_->PostTask(FROM_HERE,
+                         base::BindOnce(&AudioInputController::DoRecord, this));
 }
 
-void AudioInputController::Close(const base::Closure& closed_task) {
+void AudioInputController::Close(base::OnceClosure closed_task) {
   DCHECK(!closed_task.is_null());
   DCHECK(creator_task_runner_->BelongsToCurrentThread());
 
   task_runner_->PostTaskAndReply(
-      FROM_HERE, base::Bind(&AudioInputController::DoClose, this), closed_task);
+      FROM_HERE, base::BindOnce(&AudioInputController::DoClose, this),
+      std::move(closed_task));
 }
 
 void AudioInputController::SetVolume(double volume) {
   DCHECK(creator_task_runner_->BelongsToCurrentThread());
-  task_runner_->PostTask(FROM_HERE, base::Bind(
-      &AudioInputController::DoSetVolume, this, volume));
+  task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&AudioInputController::DoSetVolume, this, volume));
 }
 
 void AudioInputController::DoCreate(AudioManager* audio_manager,
@@ -315,7 +318,8 @@
   // MakeAudioInputStream might fail and return nullptr. If so,
   // DoCreateForStream will handle and report it.
   auto* stream = audio_manager->MakeAudioInputStream(
-      params, device_id, base::Bind(&AudioInputController::LogMessage, this));
+      params, device_id,
+      base::BindRepeating(&AudioInputController::LogMessage, this));
   DoCreateForStream(stream, enable_agc);
 }
 
@@ -509,8 +513,8 @@
 #if BUILDFLAG(ENABLE_WEBRTC)
   DCHECK(creator_task_runner_->BelongsToCurrentThread());
   task_runner_->PostTask(
-      FROM_HERE, base::Bind(&AudioInputController::DoEnableDebugRecording, this,
-                            file_name));
+      FROM_HERE, base::BindOnce(&AudioInputController::DoEnableDebugRecording,
+                                this, file_name));
 #endif
 }
 
@@ -519,7 +523,7 @@
   DCHECK(creator_task_runner_->BelongsToCurrentThread());
   task_runner_->PostTask(
       FROM_HERE,
-      base::Bind(&AudioInputController::DoDisableDebugRecording, this));
+      base::BindOnce(&AudioInputController::DoDisableDebugRecording, this));
 #endif
 }
 
diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h
index ff0022d..8b71705 100644
--- a/media/audio/audio_input_controller.h
+++ b/media/audio/audio_input_controller.h
@@ -200,7 +200,7 @@
   // It is safe to call this method more than once. Calls after the first one
   // will have no effect.
   // This method trampolines to the audio thread.
-  virtual void Close(const base::Closure& closed_task);
+  virtual void Close(base::OnceClosure closed_task);
 
   // Sets the capture volume of the input stream. The value 0.0 corresponds
   // to muted and 1.0 to maximum volume.
diff --git a/media/audio/audio_input_controller_unittest.cc b/media/audio/audio_input_controller_unittest.cc
index 3d9ba1a..4e2a714 100644
--- a/media/audio/audio_input_controller_unittest.cc
+++ b/media/audio/audio_input_controller_unittest.cc
@@ -96,8 +96,8 @@
 
   void SuspendAudioThread() {
     audio_task_runner()->PostTask(
-        FROM_HERE, base::Bind(&AudioInputControllerTest::WaitForResume,
-                              base::Unretained(this)));
+        FROM_HERE, base::BindOnce(&AudioInputControllerTest::WaitForResume,
+                                  base::Unretained(this)));
   }
 
   void ResumeAudioThread() { suspend_event_.Signal(); }
diff --git a/media/audio/test_audio_input_controller_factory.cc b/media/audio/test_audio_input_controller_factory.cc
index 82abd4d..1bbf4a4 100644
--- a/media/audio/test_audio_input_controller_factory.cc
+++ b/media/audio/test_audio_input_controller_factory.cc
@@ -3,6 +3,9 @@
 // found in the LICENSE file.
 
 #include "media/audio/test_audio_input_controller_factory.h"
+
+#include <utility>
+
 #include "media/audio/audio_io.h"
 
 namespace media {
@@ -36,8 +39,8 @@
     factory_->delegate_->TestAudioControllerOpened(this);
 }
 
-void TestAudioInputController::Close(const base::Closure& closed_task) {
-  GetTaskRunnerForTesting()->PostTask(FROM_HERE, closed_task);
+void TestAudioInputController::Close(base::OnceClosure closed_task) {
+  GetTaskRunnerForTesting()->PostTask(FROM_HERE, std::move(closed_task));
   if (factory_->delegate_)
     factory_->delegate_->TestAudioControllerClosed(this);
 }
diff --git a/media/audio/test_audio_input_controller_factory.h b/media/audio/test_audio_input_controller_factory.h
index f776e0ae..37ac3c9 100644
--- a/media/audio/test_audio_input_controller_factory.h
+++ b/media/audio/test_audio_input_controller_factory.h
@@ -74,7 +74,7 @@
   void Record() override;
 
   // Ensure that the closure is run on the audio-manager thread.
-  void Close(const base::Closure& closed_task) override;
+  void Close(base::OnceClosure closed_task) override;
 
   const AudioParameters& audio_parameters() const {
     return audio_parameters_;
diff --git a/media/base/android/media_service_throttler.cc b/media/base/android/media_service_throttler.cc
index 3a46dd9..42552e801 100644
--- a/media/base/android/media_service_throttler.cc
+++ b/media/base/android/media_service_throttler.cc
@@ -56,11 +56,6 @@
 // Max number of clients to schedule immediately (e.g when loading a new page).
 const uint32_t kMaxBurstClients = 10;
 
-// Sliding window of time during which we allow clients to be scheduled
-// immediately, to accomodate for a "bursts" of requests when loading new pages.
-const base::TimeDelta kMinDelayWindow =
-    (kLinearThrottlingDelay + kBaseExponentialDelay) * kMaxBurstClients;
-
 // The throttling progression based on number of crashes looks as follows:
 //
 // | # crashes | period  | clients/sec | clients/mins | # burst clients
@@ -141,7 +136,8 @@
 
   // If the scheduling delay is low enough, schedule it immediately instead.
   // This allows up to kMaxBurstClients clients to be scheduled immediately.
-  if (delay <= kMinDelayWindow)
+  if (delay <=
+      (kLinearThrottlingDelay + kBaseExponentialDelay) * kMaxBurstClients)
     return base::TimeDelta();
 
   return delay;
diff --git a/media/gpu/rendering_helper.cc b/media/gpu/rendering_helper.cc
index e6696ed..693daf2 100644
--- a/media/gpu/rendering_helper.cc
+++ b/media/gpu/rendering_helper.cc
@@ -710,37 +710,20 @@
   thumbnails_texture_id_ = 0;
 }
 
-void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb,
-                                         bool* alpha_solid,
-                                         base::WaitableEvent* done) {
+void RenderingHelper::GetThumbnailsAsRGBA(std::vector<unsigned char>* rgba,
+                                          base::WaitableEvent* done) {
   CHECK(render_as_thumbnails_);
 
   const size_t num_pixels = thumbnails_fbo_size_.GetArea();
-  std::vector<unsigned char> rgba;
-  rgba.resize(num_pixels * 4);
+  rgba->resize(num_pixels * 4);
   glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_);
   glPixelStorei(GL_PACK_ALIGNMENT, 1);
   // We can only count on GL_RGBA/GL_UNSIGNED_BYTE support.
-  glReadPixels(0, 0,
-               thumbnails_fbo_size_.width(), thumbnails_fbo_size_.height(),
-               GL_RGBA,
-               GL_UNSIGNED_BYTE,
-               &rgba[0]);
+  glReadPixels(0, 0, thumbnails_fbo_size_.width(),
+               thumbnails_fbo_size_.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+               &(*rgba)[0]);
   glBindFramebufferEXT(GL_FRAMEBUFFER,
                        gl_surface_->GetBackingFramebufferObject());
-  rgb->resize(num_pixels * 3);
-  // Drop the alpha channel, but check as we go that it is all 0xff.
-  bool solid = true;
-  unsigned char* rgb_ptr = &((*rgb)[0]);
-  unsigned char* rgba_ptr = &rgba[0];
-  for (size_t i = 0; i < num_pixels; ++i) {
-    *rgb_ptr++ = *rgba_ptr++;
-    *rgb_ptr++ = *rgba_ptr++;
-    *rgb_ptr++ = *rgba_ptr++;
-    solid = solid && (*rgba_ptr == 0xff);
-    rgba_ptr++;
-  }
-  *alpha_solid = solid;
 
   done->Signal();
 }
diff --git a/media/gpu/rendering_helper.h b/media/gpu/rendering_helper.h
index 03c15be..54dcbed 100644
--- a/media/gpu/rendering_helper.h
+++ b/media/gpu/rendering_helper.h
@@ -139,11 +139,9 @@
   // Get the GL context.
   gl::GLContext* GetGLContext();
 
-  // Get rendered thumbnails as RGB.
-  // Sets alpha_solid to true if the alpha channel is entirely 0xff.
-  void GetThumbnailsAsRGB(std::vector<unsigned char>* rgb,
-                          bool* alpha_solid,
-                          base::WaitableEvent* done);
+  // Get rendered thumbnails as RGBA.
+  void GetThumbnailsAsRGBA(std::vector<unsigned char>* rgba,
+                           base::WaitableEvent* done);
 
  private:
   struct RenderedVideo {
diff --git a/media/gpu/video_decode_accelerator_unittest.cc b/media/gpu/video_decode_accelerator_unittest.cc
index 991394b3..7174f7a 100644
--- a/media/gpu/video_decode_accelerator_unittest.cc
+++ b/media/gpu/video_decode_accelerator_unittest.cc
@@ -1527,16 +1527,33 @@
   }
 
   if (render_as_thumbnails) {
-    std::vector<unsigned char> rgb;
-    bool alpha_solid;
+    std::vector<unsigned char> rgba;
     base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                              base::WaitableEvent::InitialState::NOT_SIGNALED);
     g_env->GetRenderingTaskRunner()->PostTask(
-        FROM_HERE, base::Bind(&RenderingHelper::GetThumbnailsAsRGB,
-                              base::Unretained(&rendering_helper_), &rgb,
-                              &alpha_solid, &done));
+        FROM_HERE,
+        base::Bind(&RenderingHelper::GetThumbnailsAsRGBA,
+                   base::Unretained(&rendering_helper_), &rgba, &done));
     done.Wait();
 
+    std::vector<unsigned char> rgb;
+    size_t num_pixels = rgba.size() / 4;
+
+    rgb.resize(num_pixels * 3);
+    // Drop the alpha channel, but check as we go that it is all 0xff.
+    bool solid = true;
+    unsigned char* rgb_ptr = &rgb[0];
+    unsigned char* rgba_ptr = &rgba[0];
+    for (size_t i = 0; i < num_pixels; i++) {
+      *rgb_ptr++ = *rgba_ptr++;
+      *rgb_ptr++ = *rgba_ptr++;
+      *rgb_ptr++ = *rgba_ptr++;
+      solid = solid && (*rgba_ptr == 0xff);
+      rgba_ptr++;
+    }
+
+    EXPECT_EQ(solid, true) << "RGBA frame had incorrect alpha";
+
     std::vector<std::string> golden_md5s;
     std::string md5_string = base::MD5String(
         base::StringPiece(reinterpret_cast<char*>(&rgb[0]), rgb.size()));
@@ -1544,15 +1561,12 @@
     std::vector<std::string>::iterator match =
         find(golden_md5s.begin(), golden_md5s.end(), md5_string);
     if (match == golden_md5s.end()) {
-      // Convert raw RGB into PNG for export.
+      // Convert raw RGBA into PNG for export.
       std::vector<unsigned char> png;
-      gfx::PNGCodec::Encode(&rgb[0],
-                            gfx::PNGCodec::FORMAT_RGB,
+      gfx::PNGCodec::Encode(&rgba[0], gfx::PNGCodec::FORMAT_RGBA,
                             kThumbnailsPageSize,
-                            kThumbnailsPageSize.width() * 3,
-                            true,
-                            std::vector<gfx::PNGCodec::Comment>(),
-                            &png);
+                            kThumbnailsPageSize.width() * 4, true,
+                            std::vector<gfx::PNGCodec::Comment>(), &png);
 
       LOG(ERROR) << "Unknown thumbnails MD5: " << md5_string;
 
@@ -1577,7 +1591,6 @@
       EXPECT_EQ(num_bytes, static_cast<int>(png.size()));
     }
     EXPECT_NE(match, golden_md5s.end());
-    EXPECT_EQ(alpha_solid, true) << "RGBA frame had incorrect alpha";
   }
 
   // Output the frame delivery time to file
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 410a968..ce3bb269 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -3338,6 +3338,21 @@
             ]
         }
     ],
+    "WebManifestIcons": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "FaviconsFromWebManifest"
+                    ]
+                }
+            ]
+        }
+    ],
     "WebRTC-EnableWebRtcEcdsa": [
         {
             "platforms": [
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 7c016d6..4512fec7 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1676,7 +1676,6 @@
 crbug.com/579493 http/tests/security/xss-DENIED-xsl-document-securityOrigin.xml [ Timeout ]
 crbug.com/579493 virtual/mojo-loading/http/tests/security/xss-DENIED-xsl-document-securityOrigin.xml [ Timeout ]
 
-crbug.com/572723 inspector/sources/debugger/debugger-disable-enable.html [ Pass Failure Timeout ]
 crbug.com/572723 inspector/sources/debugger/debugger-uncaught-promise-on-pause.html [ Timeout Pass ]
 
 crbug.com/634264 http/tests/security/xss-DENIED-cross-origin-stack-overflow.html [ Crash Timeout ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-networkState-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-networkState-expected.txt
index ec0c6864..27feb34 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-networkState-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-networkState-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = The play() request was interrupted by a new load request.
+Harness Error. harness_status.status = 1 , harness_status.message = The play() request was interrupted by a new load request. https://goo.gl/LdLk22
 PASS invoking load by setting src when networkState is not NETWORK_EMPTY 
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media-source/mediasource-duration-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/media-source/mediasource-duration-expected.txt
index 11c5ee93..6b96e07b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/media-source/mediasource-duration-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/media-source/mediasource-duration-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = The play() request was interrupted by a call to pause().
+Harness Error. harness_status.status = 1 , harness_status.message = The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
 PASS Test seek starts on duration truncation below currentTime 
 PASS Test appendBuffer completes previous seek to truncated duration 
 PASS Test endOfStream completes previous seek to truncated duration 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/slotchange-event-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/slotchange-event-expected.txt
deleted file mode 100644
index a3475b7..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/slotchange-event-expected.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = Uncaught Error: assert_equals: slotchange must not be fired on a slot element if the assigned nodes changed after the slot was removed expected 2 but got 0
-PASS slotchange event must fire on a default slot element inside an open shadow root  in a document 
-PASS slotchange event must fire on a default slot element inside a closed shadow root  in a document 
-PASS slotchange event must fire on a default slot element inside an open shadow root  not in a document 
-PASS slotchange event must fire on a default slot element inside a closed shadow root  not in a document 
-PASS slotchange event must fire on a named slot element insidean open shadow root  in a document 
-PASS slotchange event must fire on a named slot element insidea closed shadow root  in a document 
-PASS slotchange event must fire on a named slot element insidean open shadow root  not in a document 
-PASS slotchange event must fire on a named slot element insidea closed shadow root  not in a document 
-PASS slotchange event must not fire on a slot element inside an open shadow root  in a document when another slot's assigned nodes change 
-PASS slotchange event must not fire on a slot element inside a closed shadow root  in a document when another slot's assigned nodes change 
-PASS slotchange event must not fire on a slot element inside an open shadow root  not in a document when another slot's assigned nodes change 
-PASS slotchange event must not fire on a slot element inside a closed shadow root  not in a document when another slot's assigned nodes change 
-FAIL slotchange event must fire on a slot element when a shadow host has a slotable and the slot was inserted and must not fire when the shadow host was mutated after the slot was removed inside an open shadow root  in a document assert_equals: slotchange must be fired on a slot element if there is assigned nodes when the slot was inserted expected 1 but got 0
-FAIL slotchange event must fire on a slot element when a shadow host has a slotable and the slot was inserted and must not fire when the shadow host was mutated after the slot was removed inside a closed shadow root  in a document assert_equals: slotchange must be fired on a slot element if there is assigned nodes when the slot was inserted expected 1 but got 0
-FAIL slotchange event must fire on a slot element when a shadow host has a slotable and the slot was inserted and must not fire when the shadow host was mutated after the slot was removed inside an open shadow root  not in a document assert_equals: slotchange must be fired on a slot element if there is assigned nodes when the slot was inserted expected 1 but got 0
-FAIL slotchange event must fire on a slot element when a shadow host has a slotable and the slot was inserted and must not fire when the shadow host was mutated after the slot was removed inside a closed shadow root  not in a document assert_equals: slotchange must be fired on a slot element if there is assigned nodes when the slot was inserted expected 1 but got 0
-PASS slotchange event must fire on a slot element inside an open shadow root  in a document even if the slot was removed immediately after the assigned nodes were mutated 
-PASS slotchange event must fire on a slot element inside a closed shadow root  in a document even if the slot was removed immediately after the assigned nodes were mutated 
-PASS slotchange event must fire on a slot element inside an open shadow root  not in a document even if the slot was removed immediately after the assigned nodes were mutated 
-PASS slotchange event must fire on a slot element inside a closed shadow root  not in a document even if the slot was removed immediately after the assigned nodes were mutated 
-PASS slotchange event must fire on a slot element inside an open shadow root  in a document when innerHTML modifies the children of the shadow host 
-PASS slotchange event must fire on a slot element inside a closed shadow root  in a document when innerHTML modifies the children of the shadow host 
-PASS slotchange event must fire on a slot element inside an open shadow root  not in a document when innerHTML modifies the children of the shadow host 
-PASS slotchange event must fire on a slot element inside a closed shadow root  not in a document when innerHTML modifies the children of the shadow host 
-FAIL slotchange event must fire on a slot element inside an open shadow root  in a document when nested slots's contents change assert_equals: slotchange event's target must be the inner slot element at 1st slotchange expected Element node <slot></slot> but got Element node <slot></slot>
-FAIL slotchange event must fire on a slot element inside a closed shadow root  in a document when nested slots's contents change assert_equals: slotchange event's target must be the inner slot element at 1st slotchange expected Element node <slot></slot> but got Element node <slot></slot>
-FAIL slotchange event must fire on a slot element inside an open shadow root  not in a document when nested slots's contents change assert_equals: slotchange event's target must be the inner slot element at 1st slotchange expected Element node <slot></slot> but got Element node <slot></slot>
-FAIL slotchange event must fire on a slot element inside a closed shadow root  not in a document when nested slots's contents change assert_equals: slotchange event's target must be the inner slot element at 1st slotchange expected Element node <slot></slot> but got Element node <slot></slot>
-PASS slotchange event must fire at the end of current microtask after mutation observers are invoked inside an open shadow root  in a document when slots's contents change 
-PASS slotchange event must fire at the end of current microtask after mutation observers are invoked inside a closed shadow root  in a document when slots's contents change 
-PASS slotchange event must fire at the end of current microtask after mutation observers are invoked inside an open shadow root  not in a document when slots's contents change 
-PASS slotchange event must fire at the end of current microtask after mutation observers are invoked inside a closed shadow root  not in a document when slots's contents change 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/slots-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/slots-expected.txt
deleted file mode 100644
index b4b83e8..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/slots-expected.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-This is a testharness.js-based test.
-PASS Slots: Basic. 
-PASS Slots: Slots in closed. 
-PASS Slots: Slots not in a shadow tree. 
-FAIL Slots: Distributed nooes for Slots not in a shadow tree. assert_array_equals: lengths differ, expected 0 got 1
-PASS Slots: Name matching 
-PASS Slots: No direct host child. 
-PASS Slots: Default Slot. 
-PASS Slots: Slot in Slot does not matter in assignment. 
-PASS Slots: Slot is assigned to another slot 
-PASS Slots: Open > Closed. 
-PASS Slots: Closed > Closed. 
-PASS Slots: Closed > Open. 
-PASS Slots: Complex case: Basi line. 
-PASS Slots: Mutation: appendChild. 
-PASS Slots: Mutation: Change slot= attribute 1. 
-PASS Slots: Mutation: Change slot= attribute 2. 
-PASS Slots: Mutation: Change slot= attribute 3. 
-PASS Slots: Mutation: Remove a child. 
-PASS Slots: Mutation: Add a slot: after. 
-PASS Slots: Mutation: Add a slot: before. 
-PASS Slots: Mutation: Remove a slot. 
-PASS Slots: Mutation: Change slot name= attribute. 
-PASS Slots: Mutation: Change slot slot= attribute. 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/slots-fallback-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/slots-fallback-expected.txt
deleted file mode 100644
index 18e357b..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/slots-fallback-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS Slots fallback: Basic. 
-PASS Slots fallback: Slots in Slots. 
-PASS Slots fallback: Fallback contents should not be used if a node is assigned. 
-PASS Slots fallback: Slots in Slots: Assinged nodes should be used as fallback contents of another slot 
-PASS Slots fallback: Complex case. 
-PASS Slots fallback: Mutation. Append fallback contents. 
-PASS Slots fallback: Mutation. Remove fallback contents. 
-PASS Slots fallback: Mutation. Assign a node to a slot so that fallback contens are no longer used. 
-PASS Slots fallback: Mutation. Remove an assigned node from a slot so that fallback contens will be used. 
-FAIL Slots fallback: Mutation.  Remove a slot which is a fallback content of another slot. assert_array_equals: fall back contents should be empty because s1 is not in a shadow tree. lengths differ, expected 0 got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/slots-fallback-in-document-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/slots-fallback-in-document-expected.txt
deleted file mode 100644
index 229f763..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/shadow-dom/slots-fallback-in-document-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL Children of a slot in a document tree should not be counted in flattened assigned nodes. assert_array_equals: lengths differ, expected 1 got 0
-PASS Slot fallback content in shadow tree should be counted in flattened assigned nodes. 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel-expected.txt
new file mode 100644
index 0000000..426a47a7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel-expected.txt
@@ -0,0 +1,18 @@
+Tests canceling an HTTP auth challenge via DevTools protocol.
+
+Test started
+Network agent enabled
+Request interception enabled
+Page agent enabled
+Runtime agent enabled
+Network.requestIntercepted ID 1 GET iframe-auth-js.html type: Document
+allowRequest ID 1
+Network.responseReceived iframe-auth-js.html 200 text/html
+Network.requestIntercepted ID 2 GET unauthorised.pl type: Script
+allowRequest ID 2
+Auth required for ID 2
+----- Cancel Auth -----
+Network.responseReceived unauthorised.pl 401 text/plain
+Network.loadingFailed unauthorised.pl 
+Page.frameStoppedLoading
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel.html
new file mode 100644
index 0000000..7ab183b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel.html
@@ -0,0 +1,30 @@
+<html>
+<head>
+<script type="text/javascript" src="../inspector-protocol-test.js"></script>
+<script type="text/javascript" src="interception-test.js"></script>
+
+<script>
+function appendIframe()
+{
+    var iframe = document.createElement("iframe");
+    iframe.src = "resources/iframe-auth-js.html";
+    document.body.appendChild(iframe);
+}
+
+function test()
+{
+    var requestInterceptedDict = {
+        "iframe-auth-js.html": InspectorTest.allowRequest,
+        "unauthorised.pl": InspectorTest.allowRequest,
+        "unauthorised.pl+Auth": InspectorTest.cancelAuth
+    };
+
+    InspectorTest.startInterceptionTest(requestInterceptedDict, 0);
+}
+</script>
+</head>
+<body onload="runTest();">
+<p>Tests canceling an HTTP auth challenge via DevTools protocol.</a>
+</p>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials-expected.txt
new file mode 100644
index 0000000..07e3a42
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials-expected.txt
@@ -0,0 +1,18 @@
+CONSOLE MESSAGE: line 1: Credentials accepted!
+Tests providing HTTP auth credentials over DevTools protocol.
+
+Test started
+Network agent enabled
+Request interception enabled
+Page agent enabled
+Runtime agent enabled
+Network.requestIntercepted ID 1 GET iframe-auth-js.html type: Document
+allowRequest ID 1
+Network.responseReceived iframe-auth-js.html 200 text/html
+Network.requestIntercepted ID 2 GET unauthorised.pl type: Script
+allowRequest ID 2
+Auth required for ID 2
+----- Provide Auth Credentials -----
+Network.responseReceived unauthorised.pl 200 text/javascript
+Page.frameStoppedLoading
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials.html
new file mode 100644
index 0000000..f740c45
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials.html
@@ -0,0 +1,33 @@
+<html>
+<head>
+<script type="text/javascript" src="../inspector-protocol-test.js"></script>
+<script type="text/javascript" src="interception-test.js"></script>
+
+<script>
+function appendIframe()
+{
+    var iframe = document.createElement("iframe");
+    iframe.src = "resources/iframe-auth-js.html";
+    document.body.appendChild(iframe);
+}
+
+function test()
+{
+    var requestInterceptedDict = {
+        "iframe-auth-js.html": InspectorTest.allowRequest,
+        "unauthorised.pl": InspectorTest.allowRequest,
+        "unauthorised.pl+Auth": function(event) {
+            InspectorTest.provideAuthCredentials(
+                event, "TestUser", "TestPassword");
+        }
+    };
+
+    InspectorTest.startInterceptionTest(requestInterceptedDict, 1);
+}
+</script>
+</head>
+<body onload="runTest();">
+<p>Tests providing HTTP auth credentials over DevTools protocol.</a>
+</p>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-test.js
index 8c267c6..ef14c50 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-test.js
@@ -133,7 +133,11 @@
                              JSON.stringify(event.params));
             return;
         }
-        if (event.params.hasOwnProperty("redirectUrl")) {
+        if (event.params.hasOwnProperty("authChallenge")) {
+            log(id, "Auth required for " + id);
+            requestInterceptedDict[filename + '+Auth'](event);
+            return;
+        } else if (event.params.hasOwnProperty("redirectUrl")) {
             log(id, "Network.requestIntercepted " + id + " " +
                     event.params.redirectStatusCode + " redirect " +
                     interceptionRequestParams[id].url.split('/').pop() +
@@ -257,4 +261,35 @@
     });
 }
 
+InspectorTest.cancelAuth = function(event) {
+    var id = canonicalId(event.params.interceptionId);
+    log(id, "----- Cancel Auth -----");
+    InspectorTest.sendCommand("Network.continueInterceptedRequest", {
+        "interceptionId": event.params.interceptionId,
+        "authChallengeResponse": {"response": "CancelAuth"}
+    });
+}
+
+InspectorTest.defaultAuth = function(event) {
+    var id = canonicalId(event.params.interceptionId);
+    log(id, "----- Use Default Auth -----");
+    InspectorTest.sendCommand("Network.continueInterceptedRequest", {
+        "interceptionId": event.params.interceptionId,
+        "authChallengeResponse": {"response": "Default"}
+    });
+}
+
+InspectorTest.provideAuthCredentials = function(event, username, password) {
+    var id = canonicalId(event.params.interceptionId);
+    log(id, "----- Provide Auth Credentials -----");
+    InspectorTest.sendCommand("Network.continueInterceptedRequest", {
+        "interceptionId": event.params.interceptionId,
+        "authChallengeResponse": {
+            "response": "ProvideCredentials",
+            "username": username,
+            "password": password
+        }
+    });
+}
+
 }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/resources/.htaccess b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/resources/.htaccess
new file mode 100644
index 0000000..06565469
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/resources/.htaccess
@@ -0,0 +1,2 @@
+RewriteEngine on
+RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/resources/iframe-auth-js.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/resources/iframe-auth-js.html
new file mode 100644
index 0000000..19cc3dd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/resources/iframe-auth-js.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="unauthorised.pl"></script>
+</head>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/resources/unauthorised.pl b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/resources/unauthorised.pl
index 51d3f227..2c6cac24 100755
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/resources/unauthorised.pl
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/resources/unauthorised.pl
@@ -1,4 +1,17 @@
 #!/usr/bin/perl
+use MIME::Base64;
 
-print "Status: 401 Unauthorized\r\n";
-print "WWW-Authenticate: Basic realm=\"WebKit Test Realm\"\r\n\r\n";
+if (!defined $ENV{HTTP_AUTHORIZATION}) {
+  print "Status: 401 Unauthorized\r\n";
+  print "WWW-Authenticate: Basic realm=\"WebKit Test Realm\"\r\n\r\n";
+} else {
+  my $auth = decode_base64(substr($ENV{HTTP_AUTHORIZATION},6));
+
+  if ($auth eq "TestUser:TestPassword") {
+    print "Content-type: text/javascript\r\n\r\n";
+    print "console.log('Credentials accepted!');";
+  } else {
+    print "Status: 401 Unauthorized\r\n";
+    print "WWW-Authenticate: Basic realm=\"WebKit Test Realm\"\r\n\r\n";
+  }
+}
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail-expected.txt
index 0d493d0..5415e7a0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail-expected.txt
@@ -11,6 +11,8 @@
 Network.responseReceived xhr-iframe-auth-fail.html 200 text/html
 Network.requestIntercepted ID 2 GET unauthorised.pl type: XHR
 allowRequest ID 2
+Auth required for ID 2
+----- Use Default Auth -----
 Network.responseReceived unauthorised.pl 401 text/plain
 Page.frameStoppedLoading
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail.html
index 4827e705..54e9f17 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail.html
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail.html
@@ -16,6 +16,7 @@
     var requestInterceptedDict = {
         "xhr-iframe-auth-fail.html": InspectorTest.allowRequest,
         "unauthorised.pl": InspectorTest.allowRequest,
+        "unauthorised.pl+Auth": InspectorTest.defaultAuth,
     };
 
     InspectorTest.startInterceptionTest(requestInterceptedDict, 1);
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/debugger-disable-enable.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger/debugger-disable-enable.html
index 61106d6..4b36a85 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger/debugger-disable-enable.html
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger/debugger-disable-enable.html
@@ -25,7 +25,7 @@
         InspectorTest.addResult("Main resource was shown.");
         InspectorTest.setBreakpoint(sourceFrame, 8, "", true);
         InspectorTest.debuggerModel.addEventListener(SDK.DebuggerModel.Events.DebuggerWasDisabled, step3, this);
-        InspectorTest.debuggerModel.disableDebugger();
+        InspectorTest.debuggerModel._disableDebugger();
     }
 
     function step3()
@@ -39,7 +39,7 @@
     {
         InspectorTest.addResult("function evaluated without a pause on the breakpoint.");
         InspectorTest.debuggerModel.addEventListener(SDK.DebuggerModel.Events.DebuggerWasEnabled, step5, this);
-        InspectorTest.debuggerModel.enableDebugger();
+        InspectorTest.debuggerModel._enableDebugger();
     }
 
     function step5()
diff --git a/third_party/WebKit/LayoutTests/media/W3C/audio/events/event_pause_manual-expected.txt b/third_party/WebKit/LayoutTests/media/W3C/audio/events/event_pause_manual-expected.txt
index 2aea92f..8c4a5928 100644
--- a/third_party/WebKit/LayoutTests/media/W3C/audio/events/event_pause_manual-expected.txt
+++ b/third_party/WebKit/LayoutTests/media/W3C/audio/events/event_pause_manual-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause().
+CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
 calling play() then pause() on non-autoplay video should trigger pause event
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/media/W3C/audio/events/event_play_manual-expected.txt b/third_party/WebKit/LayoutTests/media/W3C/audio/events/event_play_manual-expected.txt
index 567b44d3..085e5e93 100644
--- a/third_party/WebKit/LayoutTests/media/W3C/audio/events/event_play_manual-expected.txt
+++ b/third_party/WebKit/LayoutTests/media/W3C/audio/events/event_play_manual-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause().
+CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
 calling play() on video should trigger play event
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/media/W3C/audio/paused/paused_true_during_pause-expected.txt b/third_party/WebKit/LayoutTests/media/W3C/audio/paused/paused_true_during_pause-expected.txt
index 4f57da11..1f581ce3 100644
--- a/third_party/WebKit/LayoutTests/media/W3C/audio/paused/paused_true_during_pause-expected.txt
+++ b/third_party/WebKit/LayoutTests/media/W3C/audio/paused/paused_true_during_pause-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause().
+CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
 audio.paused should be true during pause event
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/media/W3C/video/events/event_pause_manual-expected.txt b/third_party/WebKit/LayoutTests/media/W3C/video/events/event_pause_manual-expected.txt
index 2aea92f..8c4a5928 100644
--- a/third_party/WebKit/LayoutTests/media/W3C/video/events/event_pause_manual-expected.txt
+++ b/third_party/WebKit/LayoutTests/media/W3C/video/events/event_pause_manual-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause().
+CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
 calling play() then pause() on non-autoplay video should trigger pause event
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/media/W3C/video/events/event_play_manual-expected.txt b/third_party/WebKit/LayoutTests/media/W3C/video/events/event_play_manual-expected.txt
index 567b44d3..085e5e93 100644
--- a/third_party/WebKit/LayoutTests/media/W3C/video/events/event_play_manual-expected.txt
+++ b/third_party/WebKit/LayoutTests/media/W3C/video/events/event_play_manual-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause().
+CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
 calling play() on video should trigger play event
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/media/W3C/video/paused/paused_true_during_pause-expected.txt b/third_party/WebKit/LayoutTests/media/W3C/video/paused/paused_true_during_pause-expected.txt
index e2723f2..3d84cef 100644
--- a/third_party/WebKit/LayoutTests/media/W3C/video/paused/paused_true_during_pause-expected.txt
+++ b/third_party/WebKit/LayoutTests/media/W3C/video/paused/paused_true_during_pause-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause().
+CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
 video.paused should be true during pause event
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/media/media-play-promise.html b/third_party/WebKit/LayoutTests/media/media-play-promise.html
index d83ff1e1..e70ef77a 100644
--- a/third_party/WebKit/LayoutTests/media/media-play-promise.html
+++ b/third_party/WebKit/LayoutTests/media/media-play-promise.html
@@ -296,14 +296,14 @@
         audio.play().then(t.unreached_func(), t.step_func(function(e) {
             assert_equals(e.name, 'AbortError');
             assert_equals(e.message,
-                'The play() request was interrupted by a call to pause().');
+                'The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22');
             firstPromiseRejected = true;
         }));
 
         audio.play().then(t.unreached_func(), t.step_func_done(function(e) {
             assert_equals(e.name, 'AbortError');
             assert_equals(e.message,
-                'The play() request was interrupted by a call to pause().');
+                'The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22');
             assert_true(firstPromiseRejected);
         }));
 
diff --git a/third_party/WebKit/LayoutTests/media/video-display-none-crash-expected.txt b/third_party/WebKit/LayoutTests/media/video-display-none-crash-expected.txt
index 0b158f4..dfc25b5 100644
--- a/third_party/WebKit/LayoutTests/media/video-display-none-crash-expected.txt
+++ b/third_party/WebKit/LayoutTests/media/video-display-none-crash-expected.txt
@@ -1,6 +1,6 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause().
+CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
 This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = The play() request was interrupted by a call to pause().
+Harness Error. harness_status.status = 1 , harness_status.message = The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
 PASS Test that pause() after changing display to "none" doesn't cause a crash. 
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/media/video-play-pause-events-expected.txt b/third_party/WebKit/LayoutTests/media/video-play-pause-events-expected.txt
index 5222de8..6aed1115 100644
--- a/third_party/WebKit/LayoutTests/media/video-play-pause-events-expected.txt
+++ b/third_party/WebKit/LayoutTests/media/video-play-pause-events-expected.txt
@@ -1,6 +1,6 @@
-CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause().
+CONSOLE ERROR: Uncaught (in promise) AbortError: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
 This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = The play() request was interrupted by a call to pause().
+Harness Error. harness_status.status = 1 , harness_status.message = The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
 PASS Test that calling play() and pause() triggers async play, timeupdate and pause events. 
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
index fd5cd920..59a4c3d 100644
--- a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
+++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -920,16 +920,16 @@
 inline CSSIdentifierValue::CSSIdentifierValue(EResize e)
     : CSSValue(kIdentifierClass) {
   switch (e) {
-    case RESIZE_BOTH:
+    case EResize::kBoth:
       value_id_ = CSSValueBoth;
       break;
-    case RESIZE_HORIZONTAL:
+    case EResize::kHorizontal:
       value_id_ = CSSValueHorizontal;
       break;
-    case RESIZE_VERTICAL:
+    case EResize::kVertical:
       value_id_ = CSSValueVertical;
       break;
-    case RESIZE_NONE:
+    case EResize::kNone:
       value_id_ = CSSValueNone;
       break;
   }
@@ -939,23 +939,23 @@
 inline EResize CSSIdentifierValue::ConvertTo() const {
   switch (value_id_) {
     case CSSValueBoth:
-      return RESIZE_BOTH;
+      return EResize::kBoth;
     case CSSValueHorizontal:
-      return RESIZE_HORIZONTAL;
+      return EResize::kHorizontal;
     case CSSValueVertical:
-      return RESIZE_VERTICAL;
+      return EResize::kVertical;
     case CSSValueAuto:
       // Depends on settings, thus should be handled by the caller.
       NOTREACHED();
-      return RESIZE_NONE;
+      return EResize::kNone;
     case CSSValueNone:
-      return RESIZE_NONE;
+      return EResize::kNone;
     default:
       break;
   }
 
   NOTREACHED();
-  return RESIZE_NONE;
+  return EResize::kNone;
 }
 
 template <>
@@ -1008,24 +1008,24 @@
 }
 
 template <>
-inline TextDecorationStyle CSSIdentifierValue::ConvertTo() const {
+inline ETextDecorationStyle CSSIdentifierValue::ConvertTo() const {
   switch (value_id_) {
     case CSSValueSolid:
-      return kTextDecorationStyleSolid;
+      return ETextDecorationStyle::kSolid;
     case CSSValueDouble:
-      return kTextDecorationStyleDouble;
+      return ETextDecorationStyle::kDouble;
     case CSSValueDotted:
-      return kTextDecorationStyleDotted;
+      return ETextDecorationStyle::kDotted;
     case CSSValueDashed:
-      return kTextDecorationStyleDashed;
+      return ETextDecorationStyle::kDashed;
     case CSSValueWavy:
-      return kTextDecorationStyleWavy;
+      return ETextDecorationStyle::kWavy;
     default:
       break;
   }
 
   NOTREACHED();
-  return kTextDecorationStyleSolid;
+  return ETextDecorationStyle::kSolid;
 }
 
 template <>
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index 31f66dc2..53d72324 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -1965,11 +1965,10 @@
     {
       name: "resize",
       custom_value: true,
-      type_name: "EResize",
       field_template: "storage_only",
       field_group: "rare-non-inherited",
       field_size: 2,
-      default_value: "RESIZE_NONE",
+      default_value: "EResize::kNone",
     },
     {
       name: "right",
@@ -2466,10 +2465,9 @@
     {
       name: "text-decoration-style",
       runtime_flag: "CSS3TextDecorations",
-      type_name: "TextDecorationStyle",
       field_template: "storage_only",
       field_group: "rare-non-inherited",
-      default_value: "kTextDecorationStyleSolid",
+      default_value: "ETextDecorationStyle::kSolid",
       field_size: 3,
     },
     {
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index 560d2fc..581c9758 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -1147,17 +1147,17 @@
 }
 
 static CSSValue* ValueForTextDecorationStyle(
-    TextDecorationStyle text_decoration_style) {
+    ETextDecorationStyle text_decoration_style) {
   switch (text_decoration_style) {
-    case kTextDecorationStyleSolid:
+    case ETextDecorationStyle::kSolid:
       return CSSIdentifierValue::Create(CSSValueSolid);
-    case kTextDecorationStyleDouble:
+    case ETextDecorationStyle::kDouble:
       return CSSIdentifierValue::Create(CSSValueDouble);
-    case kTextDecorationStyleDotted:
+    case ETextDecorationStyle::kDotted:
       return CSSIdentifierValue::Create(CSSValueDotted);
-    case kTextDecorationStyleDashed:
+    case ETextDecorationStyle::kDashed:
       return CSSIdentifierValue::Create(CSSValueDashed);
-    case kTextDecorationStyleWavy:
+    case ETextDecorationStyle::kWavy:
       return CSSIdentifierValue::Create(CSSValueWavy);
   }
 
@@ -2877,7 +2877,7 @@
     case CSSPropertyTextDecorationSkip:
       return ValueForTextDecorationSkip(style.GetTextDecorationSkip());
     case CSSPropertyTextDecorationStyle:
-      return ValueForTextDecorationStyle(style.GetTextDecorationStyle());
+      return ValueForTextDecorationStyle(style.TextDecorationStyle());
     case CSSPropertyTextDecorationColor:
       return CurrentColorOrValidColor(style, style.TextDecorationColor());
     case CSSPropertyTextJustify:
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
index ba892c3..e10b6c2 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
@@ -326,10 +326,12 @@
     const CSSValue& value) {
   const CSSIdentifierValue& identifier_value = ToCSSIdentifierValue(value);
 
-  EResize r = RESIZE_NONE;
+  EResize r = EResize::kNone;
   if (identifier_value.GetValueID() == CSSValueAuto) {
-    if (Settings* settings = state.GetDocument().GetSettings())
-      r = settings->GetTextAreasAreResizable() ? RESIZE_BOTH : RESIZE_NONE;
+    if (Settings* settings = state.GetDocument().GetSettings()) {
+      r = settings->GetTextAreasAreResizable() ? EResize::kBoth
+                                               : EResize::kNone;
+    }
   } else {
     r = identifier_value.ConvertTo<EResize>();
   }
diff --git a/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp b/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp
index b13ce66a..b5fd1cf 100644
--- a/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp
+++ b/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp
@@ -201,6 +201,15 @@
   return nullptr;
 }
 
+Element* DocumentOrderedMap::GetCachedFirstElementWithoutAccessingNodeTree(
+    const AtomicString& key) {
+  MapEntry* entry = map_.at(key);
+  if (!entry)
+    return nullptr;
+  DCHECK(entry->count);
+  return entry->element;
+}
+
 DEFINE_TRACE(DocumentOrderedMap) {
   visitor->Trace(map_);
 }
diff --git a/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h b/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h
index ca8d1eb..568bd38 100644
--- a/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h
+++ b/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h
@@ -61,6 +61,9 @@
                                                         const TreeScope&) const;
   Element* GetElementByMapName(const AtomicString&, const TreeScope&) const;
   HTMLSlotElement* GetSlotByName(const AtomicString&, const TreeScope&) const;
+  // Don't use this unless the caller can know the internal state of
+  // DocumentOrderedMap exactly.
+  Element* GetCachedFirstElementWithoutAccessingNodeTree(const AtomicString&);
 
   DECLARE_TRACE();
 
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp
index f0992ff..61eadd4b 100644
--- a/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -2563,37 +2563,38 @@
 void Node::CheckSlotChange(SlotChangeType slot_change_type) {
   // Common check logic is used in both cases, "after inserted" and "before
   // removed".
+
+  // Relevant DOM Standard:
+  // https://dom.spec.whatwg.org/#concept-node-insert
+  // https://dom.spec.whatwg.org/#concept-node-remove
+
+  // This function is usually called while DOM Mutation is still in-progress.
+  // For "after inserted" case, we assume that a parent and a child have been
+  // already connected. For "before removed" case, we assume that a parent and a
+  // child have not been disconnected yet.
+
   if (!IsSlotable())
     return;
+
   if (ShadowRoot* root = V1ShadowRootOfParent()) {
-    // Relevant DOM Standard:
-    // https://dom.spec.whatwg.org/#concept-node-insert
-    // - 6.1.2: If parent is a shadow host and node is a slotable, then assign a
-    //   slot for node.
-    // https://dom.spec.whatwg.org/#concept-node-remove
-    // - 10. If node is assigned, then run assign slotables for node’s assigned
-    //   slot.
+    // A shadow host's child can be assigned to a slot in the host's shadow
+    // tree.
 
     // Although DOM Standard requires "assign a slot for node / run assign
     // slotables" at this timing, we skip it as an optimization.
     if (HTMLSlotElement* slot = root->AssignedSlotFor(*this))
       slot->DidSlotChange(slot_change_type);
-  } else {
-    // Relevant DOM Standard:
-    // https://dom.spec.whatwg.org/#concept-node-insert
-    // - 6.1.3: If parent is a slot whose assigned nodes is the empty list, then
-    //   run signal a slot change for parent.
-    // https://dom.spec.whatwg.org/#concept-node-remove
-    // - 11. If parent is a slot whose assigned nodes is the empty list, then
-    //   run signal a slot change for parent.
+  } else if (IsInV1ShadowTree()) {
+    // Checking for fallback content if the node is in a v1 shadow tree.
     Element* parent = parentElement();
     if (parent && isHTMLSlotElement(parent)) {
       HTMLSlotElement& parent_slot = toHTMLSlotElement(*parent);
-      // TODO(hayato): Support slotchange for slots in non-shadow trees.
-      if (ShadowRoot* root = ContainingShadowRoot()) {
-        if (root && root->IsV1() && !parent_slot.HasAssignedNodesSlow())
-          parent_slot.DidSlotChange(slot_change_type);
-      }
+      DCHECK(parent_slot.SupportsDistribution());
+      // The parent_slot's assigned nodes might not be calculated because they
+      // are lazy evaluated later at UpdateDistribution() so we have to check it
+      // here.
+      if (!parent_slot.HasAssignedNodesSlow())
+        parent_slot.DidSlotChange(slot_change_type);
     }
   }
 }
diff --git a/third_party/WebKit/Source/core/dom/Node.h b/third_party/WebKit/Source/core/dom/Node.h
index f5e2e77..3cbca5e 100644
--- a/third_party/WebKit/Source/core/dom/Node.h
+++ b/third_party/WebKit/Source/core/dom/Node.h
@@ -97,8 +97,8 @@
 };
 
 enum class SlotChangeType {
-  kInitial,
-  kChained,
+  kSignalSlotChangeEvent,
+  kSuppressSlotChangeEvent,
 };
 
 class NodeRenderingData {
@@ -819,10 +819,10 @@
 
   void CheckSlotChange(SlotChangeType);
   void CheckSlotChangeAfterInserted() {
-    CheckSlotChange(SlotChangeType::kInitial);
+    CheckSlotChange(SlotChangeType::kSignalSlotChangeEvent);
   }
   void CheckSlotChangeBeforeRemoved() {
-    CheckSlotChange(SlotChangeType::kInitial);
+    CheckSlotChange(SlotChangeType::kSignalSlotChangeEvent);
   }
 
   // If the node is a plugin, then this returns its WebPluginContainerBase.
@@ -904,8 +904,8 @@
   enum ConstructionType {
     kCreateOther = kDefaultNodeFlags,
     kCreateText = kDefaultNodeFlags | kIsTextFlag,
-    kCreateContainer = kDefaultNodeFlags | kChildNeedsStyleRecalcFlag |
-                       kIsContainerFlag,
+    kCreateContainer =
+        kDefaultNodeFlags | kChildNeedsStyleRecalcFlag | kIsContainerFlag,
     kCreateElement = kCreateContainer | kIsElementFlag,
     kCreateShadowRoot =
         kCreateContainer | kIsDocumentFragmentFlag | kIsInShadowTreeFlag,
diff --git a/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.cpp b/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.cpp
index 5c63c216..72d983d 100644
--- a/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.cpp
+++ b/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.cpp
@@ -18,47 +18,136 @@
 void SlotAssignment::DidAddSlot(HTMLSlotElement& slot) {
   // Relevant DOM Standard:
   // https://dom.spec.whatwg.org/#concept-node-insert
-  // 6.4:  Run assign slotables for a tree with node's tree and a set containing
-  // each inclusive descendant of node that is a slot.
+
+  // |slot| was already connected to the tree, however, |slot_map_| doesn't
+  // reflect the insertion yet.
 
   ++slot_count_;
   needs_collect_slots_ = true;
 
-  if (!slot_map_->Contains(slot.GetName())) {
-    slot_map_->Add(slot.GetName(), &slot);
-    return;
-  }
-
-  HTMLSlotElement& old_active = *FindSlotByName(slot.GetName());
-  DCHECK_NE(old_active, slot);
-  slot_map_->Add(slot.GetName(), &slot);
-  if (FindSlotByName(slot.GetName()) == old_active)
-    return;
-  // |oldActive| is no longer an active slot.
-  if (old_active.FindHostChildWithSameSlotName())
-    old_active.DidSlotChange(SlotChangeType::kInitial);
-  // TODO(hayato): We should not enqeueue a slotchange event for |oldActive|
-  // if |oldActive| was inserted together with |slot|.
-  // This could happen if |oldActive| and |slot| are descendants of the inserted
-  // node, and |oldActive| is preceding |slot|.
+  DCHECK(!slot_map_->Contains(slot.GetName()) ||
+         GetCachedFirstSlotWithoutAccessingNodeTree(slot.GetName()));
+  DidAddSlotInternal(slot);
+  // Ensures that DocumentOrderedMap has a cache if there is a slot for the
+  // name.
+  DCHECK(GetCachedFirstSlotWithoutAccessingNodeTree(slot.GetName()));
 }
 
-void SlotAssignment::SlotRemoved(HTMLSlotElement& slot) {
+void SlotAssignment::DidRemoveSlot(HTMLSlotElement& slot) {
+  // Relevant DOM Standard:
+  // https://dom.spec.whatwg.org/#concept-node-remove
+
+  // |slot| was already removed from the tree, however, |slot_map_| doesn't
+  // reflect the removal yet.
+
   DCHECK_GT(slot_count_, 0u);
   --slot_count_;
   needs_collect_slots_ = true;
 
-  DCHECK(slot_map_->Contains(slot.GetName()));
-  HTMLSlotElement* old_active = FindSlotByName(slot.GetName());
-  slot_map_->Remove(slot.GetName(), &slot);
-  HTMLSlotElement* new_active = FindSlotByName(slot.GetName());
-  if (new_active && new_active != old_active) {
-    // |newActive| slot becomes an active slot.
-    if (new_active->FindHostChildWithSameSlotName())
-      new_active->DidSlotChange(SlotChangeType::kInitial);
-    // TODO(hayato): Prevent a false-positive slotchange.
-    // This could happen if more than one slots which have the same name are
-    // descendants of the removed node.
+  DCHECK(GetCachedFirstSlotWithoutAccessingNodeTree(slot.GetName()));
+  DidRemoveSlotInternal(slot, slot.GetName(), SlotMutationType::kRemoved);
+  // Ensures that DocumentOrderedMap has a cache if there is a slot for the
+  // name.
+  DCHECK(!slot_map_->Contains(slot.GetName()) ||
+         GetCachedFirstSlotWithoutAccessingNodeTree(slot.GetName()));
+}
+
+void SlotAssignment::DidAddSlotInternal(HTMLSlotElement& slot) {
+  // There are the following 3 cases for addition:
+  //         Before:              After:
+  // case 1: []                -> [*slot*]
+  // case 2: [old_active, ...] -> [*slot*, old_active, ...]
+  // case 3: [old_active, ...] -> [old_active, ..., *slot*, ...]
+
+  // TODO(hayato): Explain the details in README.md file.
+
+  const AtomicString& slot_name = slot.GetName();
+
+  // At this timing, we can't use FindSlotByName because what we are interested
+  // in is the first slot *before* |slot| was inserted. Here, |slot| was already
+  // disconnected from the tree. Thus, we can't use on FindBySlotName because
+  // it might scan the current tree and return a wrong result.
+  HTMLSlotElement* old_active =
+      GetCachedFirstSlotWithoutAccessingNodeTree(slot_name);
+  DCHECK(!old_active || old_active != slot);
+
+  // This might invalidate the slot_map's cache.
+  slot_map_->Add(slot_name, &slot);
+
+  // This also ensures that DocumentOrderedMap has a cache for the first
+  // element.
+  HTMLSlotElement* new_active = FindSlotByName(slot_name);
+  DCHECK(new_active);
+  DCHECK(new_active == slot || new_active == old_active);
+
+  if (new_active == slot) {
+    // case 1 or 2
+    if (FindHostChildBySlotName(slot_name)) {
+      // |slot| got assigned nodes
+      slot.DidSlotChange(SlotChangeType::kSignalSlotChangeEvent);
+      if (old_active) {
+        // case 2
+        //  |old_active| lost assigned nodes.
+        old_active->DidSlotChange(SlotChangeType::kSignalSlotChangeEvent);
+      }
+    } else {
+      // |slot| is active, but it doesn't have assigned nodes.
+      // Fallback might matter.
+      slot.CheckFallbackAfterInsertedIntoShadowTree();
+    }
+  } else {
+    // case 3
+    slot.CheckFallbackAfterInsertedIntoShadowTree();
+  }
+}
+
+void SlotAssignment::DidRemoveSlotInternal(
+    HTMLSlotElement& slot,
+    const AtomicString& slot_name,
+    SlotMutationType slot_mutation_type) {
+  // There are the following 3 cases for removal:
+  //         Before:                            After:
+  // case 1: [*slot*]                        -> []
+  // case 2: [*slot*, new_active, ...]       -> [new_active, ...]
+  // case 3: [new_active, ..., *slot*, ...]  -> [new_active, ...]
+
+  // TODO(hayato): Explain the details in README.md file.
+
+  // At this timing, we can't use FindSlotByName because what we are interested
+  // in is the first slot *before* |slot| was removed. Here, |slot| was already
+  // connected to the tree. Thus, we can't use FindBySlotName because
+  // it might scan the current tree and return a wrong result.
+  HTMLSlotElement* old_active =
+      GetCachedFirstSlotWithoutAccessingNodeTree(slot_name);
+  DCHECK(old_active);
+  slot_map_->Remove(slot_name, &slot);
+  // This also ensures that DocumentOrderedMap has a cache for the first
+  // element.
+  HTMLSlotElement* new_active = FindSlotByName(slot_name);
+  DCHECK(!new_active || new_active != slot);
+
+  if (old_active == slot) {
+    // case 1 or 2
+    if (FindHostChildBySlotName(slot_name)) {
+      // |slot| lost assigned nodes
+      if (slot_mutation_type == SlotMutationType::kRemoved) {
+        slot.DidSlotChangeAfterRemovedFromShadowTree();
+      } else {
+        slot.DidSlotChangeAfterRenaming();
+      }
+      if (new_active) {
+        // case 2
+        // |new_active| got assigned nodes
+        new_active->DidSlotChange(SlotChangeType::kSignalSlotChangeEvent);
+      }
+    } else {
+      // |slot| was active, but it didn't have assigned nodes.
+      // Fallback might matter.
+      slot.CheckFallbackAfterRemovedFromShadowTree();
+    }
+  } else {
+    // case 3
+    slot.CheckFallbackAfterRemovedFromShadowTree();
   }
 }
 
@@ -74,33 +163,25 @@
   return false;
 }
 
-void SlotAssignment::SlotRenamed(const AtomicString& old_slot_name,
-                                 HTMLSlotElement& slot) {
-  // |slot| has already new name. Thus, we can not use
-  // slot.hasAssignedNodesSynchronously.
-  bool has_assigned_nodes_before = (FindSlotByName(old_slot_name) == &slot) &&
-                                   FindHostChildBySlotName(old_slot_name);
-
-  slot_map_->Remove(old_slot_name, &slot);
-  slot_map_->Add(slot.GetName(), &slot);
-
-  bool has_assigned_nodes_after = slot.HasAssignedNodesSlow();
-
-  if (has_assigned_nodes_before || has_assigned_nodes_after)
-    slot.DidSlotChange(SlotChangeType::kInitial);
+void SlotAssignment::DidRenameSlot(const AtomicString& old_slot_name,
+                                   HTMLSlotElement& slot) {
+  // Rename can be thought as "Remove and then Add", except that
+  // we don't need to set needs_collect_slots_.
+  DCHECK(GetCachedFirstSlotWithoutAccessingNodeTree(old_slot_name));
+  DidRemoveSlotInternal(slot, old_slot_name, SlotMutationType::kRenamed);
+  DidAddSlotInternal(slot);
+  DCHECK(GetCachedFirstSlotWithoutAccessingNodeTree(slot.GetName()));
 }
 
 void SlotAssignment::DidChangeHostChildSlotName(const AtomicString& old_value,
                                                 const AtomicString& new_value) {
   if (HTMLSlotElement* slot =
           FindSlotByName(HTMLSlotElement::NormalizeSlotName(old_value))) {
-    slot->DidSlotChange(SlotChangeType::kInitial);
-    owner_->Owner()->SetNeedsDistributionRecalc();
+    slot->DidSlotChange(SlotChangeType::kSignalSlotChangeEvent);
   }
   if (HTMLSlotElement* slot =
           FindSlotByName(HTMLSlotElement::NormalizeSlotName(new_value))) {
-    slot->DidSlotChange(SlotChangeType::kInitial);
-    owner_->Owner()->SetNeedsDistributionRecalc();
+    slot->DidSlotChange(SlotChangeType::kSignalSlotChangeEvent);
   }
 }
 
@@ -171,6 +252,15 @@
   DCHECK_EQ(slots_.size(), slot_count_);
 }
 
+HTMLSlotElement* SlotAssignment::GetCachedFirstSlotWithoutAccessingNodeTree(
+    const AtomicString& slot_name) {
+  if (Element* slot =
+          slot_map_->GetCachedFirstElementWithoutAccessingNodeTree(slot_name)) {
+    return toHTMLSlotElement(slot);
+  }
+  return nullptr;
+}
+
 DEFINE_TRACE(SlotAssignment) {
   visitor->Trace(slots_);
   visitor->Trace(slot_map_);
diff --git a/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.h b/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.h
index 95d68ee..4152aa36 100644
--- a/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.h
+++ b/third_party/WebKit/Source/core/dom/shadow/SlotAssignment.h
@@ -18,8 +18,6 @@
 class Node;
 class ShadowRoot;
 
-// TODO(hayato): Support SlotAssignment for non-shadow trees, e.g. a document
-// tree.
 class SlotAssignment final : public GarbageCollected<SlotAssignment> {
  public:
   static SlotAssignment* Create(ShadowRoot& owner) {
@@ -43,8 +41,8 @@
   const HeapVector<Member<HTMLSlotElement>>& Slots();
 
   void DidAddSlot(HTMLSlotElement&);
-  void SlotRemoved(HTMLSlotElement&);
-  void SlotRenamed(const AtomicString& old_name, HTMLSlotElement&);
+  void DidRemoveSlot(HTMLSlotElement&);
+  void DidRenameSlot(const AtomicString& old_name, HTMLSlotElement&);
   void DidChangeHostChildSlotName(const AtomicString& old_value,
                                   const AtomicString& new_value);
 
@@ -55,11 +53,23 @@
  private:
   explicit SlotAssignment(ShadowRoot& owner);
 
+  enum class SlotMutationType {
+    kRemoved,
+    kRenamed,
+  };
+
   void CollectSlots();
+  HTMLSlotElement* GetCachedFirstSlotWithoutAccessingNodeTree(
+      const AtomicString& slot_name);
 
   void ResolveAssignment();
   void DistributeTo(Node&, HTMLSlotElement&);
 
+  void DidAddSlotInternal(HTMLSlotElement&);
+  void DidRemoveSlotInternal(HTMLSlotElement&,
+                             const AtomicString& slot_name,
+                             SlotMutationType);
+
   HeapVector<Member<HTMLSlotElement>> slots_;
   Member<DocumentOrderedMap> slot_map_;
   WeakMember<ShadowRoot> owner_;
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
index 6eb6d29..a532c034 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -1454,6 +1454,22 @@
   return true;
 }
 
+// Returns true if |text_layout_object| has visible first-letter.
+bool HasVisibleFirstLetter(const LayoutText& text_layout_object) {
+  if (!text_layout_object.IsTextFragment())
+    return false;
+  const LayoutTextFragment& layout_text_fragment =
+      ToLayoutTextFragment(text_layout_object);
+  if (!layout_text_fragment.IsRemainingTextLayoutObject())
+    return false;
+  const LayoutObject* first_letter_layout_object =
+      layout_text_fragment.GetFirstLetterPseudoElement()->GetLayoutObject();
+  if (!first_letter_layout_object)
+    return false;
+  return first_letter_layout_object->Style()->Visibility() ==
+         EVisibility::kVisible;
+}
+
 // TODO(editing-dev): This function is just moved out from
 // |MostBackwardCaretPosition()|. We should study this function more and
 // name it appropriately. See https://trac.webkit.org/changeset/32438/
@@ -1466,20 +1482,11 @@
   InlineTextBox* const last_text_box = text_layout_object->LastTextBox();
   for (InlineTextBox* box : InlineTextBoxesOf(*text_layout_object)) {
     if (text_offset == box->Start()) {
-      if (text_layout_object->IsTextFragment() &&
-          ToLayoutTextFragment(text_layout_object)
-              ->IsRemainingTextLayoutObject()) {
+      if (HasVisibleFirstLetter(*text_layout_object)) {
         // |offset_in_node| is at start of remaining text of
         // |Text| node with :first-letter.
         DCHECK_GE(offset_in_node, 1);
-        LayoutObject* first_letter_layout_object =
-            ToLayoutTextFragment(text_layout_object)
-                ->GetFirstLetterPseudoElement()
-                ->GetLayoutObject();
-        if (first_letter_layout_object &&
-            first_letter_layout_object->Style()->Visibility() ==
-                EVisibility::kVisible)
-          return true;
+        return true;
       }
       continue;
     }
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index 485f7fd..97fe01e 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -893,9 +893,9 @@
 
       // 4.6.2 - Take pending play promises and reject pending play promises
       // with the result and an "AbortError" DOMException.
-      RejectPlayPromises(
-          kAbortError,
-          "The play() request was interrupted by a new load request.");
+      RejectPlayPromises(kAbortError,
+                         "The play() request was interrupted by a new load "
+                         "request. https://goo.gl/LdLk22");
     }
 
     // 4.7 - If seeking is true, set it to false.
@@ -3943,14 +3943,15 @@
   // used by the object, the string isn't saved.
   DCHECK(play_promise_error_code_ == kAbortError ||
          play_promise_error_code_ == kNotSupportedError);
-  if (play_promise_error_code_ == kAbortError)
-    RejectPlayPromisesInternal(
-        kAbortError,
-        "The play() request was interrupted by a call to pause().");
-  else
+  if (play_promise_error_code_ == kAbortError) {
+    RejectPlayPromisesInternal(kAbortError,
+                               "The play() request was interrupted by a call "
+                               "to pause(). https://goo.gl/LdLk22");
+  } else {
     RejectPlayPromisesInternal(
         kNotSupportedError,
         "Failed to load because no supported source was found.");
+  }
 }
 
 void HTMLMediaElement::RejectPlayPromises(ExceptionCode code,
diff --git a/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp b/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp
index 9303949..54d3b49 100644
--- a/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp
@@ -70,36 +70,10 @@
     const AssignedNodesOptions& options) {
   UpdateDistribution();
   if (options.hasFlatten() && options.flatten())
-    return GetDistributedNodesForBinding();
+    return GetDistributedNodes();
   return assigned_nodes_;
 }
 
-const HeapVector<Member<Node>>
-HTMLSlotElement::GetDistributedNodesForBinding() {
-  DCHECK(!NeedsDistributionRecalc());
-  if (SupportsDistribution())
-    return distributed_nodes_;
-
-  // If a slot does not support distribution, its m_distributedNodes should not
-  // be used.  Instead, calculate distribution manually here. This happens only
-  // in a slot in non-shadow trees, so its assigned nodes are always empty.
-  HeapVector<Member<Node>> distributed_nodes;
-  Node* child = NodeTraversal::FirstChild(*this);
-  while (child) {
-    if (!child->IsSlotable()) {
-      child = NodeTraversal::NextSkippingChildren(*child, this);
-      continue;
-    }
-    if (isHTMLSlotElement(child)) {
-      child = NodeTraversal::Next(*child, this);
-    } else {
-      distributed_nodes.push_back(child);
-      child = NodeTraversal::NextSkippingChildren(*child, this);
-    }
-  }
-  return distributed_nodes;
-}
-
 const HeapVector<Member<Node>>& HTMLSlotElement::GetDistributedNodes() {
   DCHECK(!NeedsDistributionRecalc());
   DCHECK(SupportsDistribution() || distributed_nodes_.IsEmpty());
@@ -114,7 +88,8 @@
 void HTMLSlotElement::ResolveDistributedNodes() {
   for (auto& node : assigned_nodes_) {
     DCHECK(node->IsSlotable());
-    if (isHTMLSlotElement(*node))
+    if (isHTMLSlotElement(*node) &&
+        toHTMLSlotElement(*node).SupportsDistribution())
       AppendDistributedNodesFrom(toHTMLSlotElement(*node));
     else
       AppendDistributedNode(*node);
@@ -217,7 +192,7 @@
   if (params.name == nameAttr) {
     if (ShadowRoot* root = ContainingShadowRoot()) {
       if (root->IsV1() && params.old_value != params.new_value) {
-        root->GetSlotAssignment().SlotRenamed(
+        root->GetSlotAssignment().DidRenameSlot(
             NormalizeSlotName(params.old_value), *this);
       }
     }
@@ -225,70 +200,52 @@
   HTMLElement::AttributeChanged(params);
 }
 
-static bool WasInDifferentShadowTreeBeforeInserted(
-    HTMLSlotElement& slot,
-    ContainerNode& insertion_point) {
-  ShadowRoot* root1 = slot.ContainingShadowRoot();
-  ShadowRoot* root2 = insertion_point.ContainingShadowRoot();
-  if (root1 && root2 && root1 == root2)
-    return false;
-  return root1;
-}
-
 Node::InsertionNotificationRequest HTMLSlotElement::InsertedInto(
     ContainerNode* insertion_point) {
   HTMLElement::InsertedInto(insertion_point);
-  ShadowRoot* root = ContainingShadowRoot();
-  if (root) {
+  if (SupportsDistribution()) {
+    ShadowRoot* root = ContainingShadowRoot();
+    DCHECK(root);
+    DCHECK(root->IsV1());
     DCHECK(root->Owner());
-    root->Owner()->SetNeedsDistributionRecalc();
-    // Relevant DOM Standard: https://dom.spec.whatwg.org/#concept-node-insert
-    // - 6.4:  Run assign slotables for a tree with node's tree and a set
-    // containing each inclusive descendant of node that is a slot.
-    if (root->IsV1() &&
-        !WasInDifferentShadowTreeBeforeInserted(*this, *insertion_point))
+    if (root == insertion_point->ContainingShadowRoot()) {
+      // This slot is inserted into the same tree of |insertion_point|
       root->DidAddSlot(*this);
+    }
   }
-
-  // We could have been distributed into in a detached subtree, make sure to
-  // clear the distribution when inserted again to avoid cycles.
-  ClearDistribution();
-
   return kInsertionDone;
 }
 
-static ShadowRoot* ContainingShadowRootBeforeRemoved(
-    Node& removed_descendant,
-    ContainerNode& insertion_point) {
-  if (ShadowRoot* root = removed_descendant.ContainingShadowRoot())
-    return root;
-  return insertion_point.ContainingShadowRoot();
-}
-
 void HTMLSlotElement::RemovedFrom(ContainerNode* insertion_point) {
   // `removedFrom` is called after the node is removed from the tree.
   // That means:
   // 1. If this slot is still in a tree scope, it means the slot has been in a
   // shadow tree. An inclusive shadow-including ancestor of the shadow host was
   // originally removed from its parent.
-  // 2. Or (this slot is now not in a tree scope), this slot's inclusive
+  // 2. Or (this slot is not in a tree scope), this slot's inclusive
   // ancestor was orginally removed from its parent (== insertion point). This
-  // slot and the originally removed node was in the same tree.
+  // slot and the originally removed node was in the same tree before removal.
 
-  ShadowRoot* root = ContainingShadowRootBeforeRemoved(*this, *insertion_point);
-  if (root) {
-    if (ElementShadow* root_owner = root->Owner())
-      root_owner->SetNeedsDistributionRecalc();
-  }
+  // For exmaple, given the following trees, (srN: = shadow root, sN: = slot)
+  // a
+  // |- b --sr1
+  // |- c   |--d
+  //           |- e-----sr2
+  //              |- s1 |--f
+  //                    |--s2
 
-  // Since this insertion point is no longer visible from the shadow subtree, it
-  // need to clean itself up.
-  ClearDistribution();
+  // If we call 'e.remove()', then:
+  // - For slot s1, s1.removedFrom(d) is called.
+  // - For slot s2, s2.removedFrom(d) is called.
 
-  if (root && root->IsV1() &&
-      root == insertion_point->GetTreeScope().RootNode()) {
-    // This slot was in a shadow tree and got disconnected from the shadow root.
-    root->GetSlotAssignment().SlotRemoved(*this);
+  // ContainingShadowRoot() is okay to use here because 1) It doesn't use
+  // kIsInShadowTreeFlag flag, and 2) TreeScope has been alreay updated for the
+  // slot.
+  if (insertion_point->IsInV1ShadowTree() && !ContainingShadowRoot()) {
+    // This slot was in a shadow tree and got disconnected from the shadow tree
+    insertion_point->ContainingShadowRoot()->GetSlotAssignment().DidRemoveSlot(
+        *this);
+    ClearDistribution();
   }
 
   HTMLElement::RemovedFrom(insertion_point);
@@ -331,18 +288,55 @@
   old_distributed_nodes_.clear();
 }
 
+void HTMLSlotElement::DidSlotChangeAfterRemovedFromShadowTree() {
+  DCHECK(!ContainingShadowRoot());
+  EnqueueSlotChangeEvent();
+  CheckSlotChange(SlotChangeType::kSuppressSlotChangeEvent);
+}
+
+void HTMLSlotElement::DidSlotChangeAfterRenaming() {
+  DCHECK(SupportsDistribution());
+  EnqueueSlotChangeEvent();
+  ContainingShadowRoot()->Owner()->SetNeedsDistributionRecalc();
+  CheckSlotChange(SlotChangeType::kSuppressSlotChangeEvent);
+}
+
 void HTMLSlotElement::DidSlotChange(SlotChangeType slot_change_type) {
-  if (slot_change_type == SlotChangeType::kInitial)
+  DCHECK(SupportsDistribution());
+  if (slot_change_type == SlotChangeType::kSignalSlotChangeEvent)
     EnqueueSlotChangeEvent();
-  ShadowRoot* root = ContainingShadowRoot();
-  // TODO(hayato): Relax this check if slots in non-shadow trees are well
-  // supported.
-  DCHECK(root);
-  DCHECK(root->IsV1());
-  root->Owner()->SetNeedsDistributionRecalc();
+  ContainingShadowRoot()->Owner()->SetNeedsDistributionRecalc();
   // Check slotchange recursively since this slotchange may cause another
   // slotchange.
-  CheckSlotChange(SlotChangeType::kChained);
+  CheckSlotChange(SlotChangeType::kSuppressSlotChangeEvent);
+}
+
+void HTMLSlotElement::CheckFallbackAfterInsertedIntoShadowTree() {
+  DCHECK(SupportsDistribution());
+  if (HasSlotableChild()) {
+    // We use kSuppress here because a slotchange event shouldn't be
+    // dispatched if a slot being inserted don't get any assigned
+    // node, but has a slotable child, according to DOM Standard.
+    DidSlotChange(SlotChangeType::kSuppressSlotChangeEvent);
+  }
+}
+
+void HTMLSlotElement::CheckFallbackAfterRemovedFromShadowTree() {
+  if (HasSlotableChild()) {
+    // Since a slot was removed from a shadow tree,
+    // we don't need to set dirty flag for a disconnected tree.
+    // However, we need to call CheckSlotChange because we might need to set a
+    // dirty flag for a shadow tree which a parent of the slot may host.
+    CheckSlotChange(SlotChangeType::kSuppressSlotChangeEvent);
+  }
+}
+
+bool HTMLSlotElement::HasSlotableChild() const {
+  for (auto& child : NodeTraversal::ChildrenOf(*this)) {
+    if (child.IsSlotable())
+      return true;
+  }
+  return false;
 }
 
 void HTMLSlotElement::EnqueueSlotChangeEvent() {
diff --git a/third_party/WebKit/Source/core/html/HTMLSlotElement.h b/third_party/WebKit/Source/core/html/HTMLSlotElement.h
index dffa5dfc..53e4ba7 100644
--- a/third_party/WebKit/Source/core/html/HTMLSlotElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLSlotElement.h
@@ -46,7 +46,6 @@
 
   const HeapVector<Member<Node>>& AssignedNodes();
   const HeapVector<Member<Node>>& GetDistributedNodes();
-  const HeapVector<Member<Node>> GetDistributedNodesForBinding();
   const HeapVector<Member<Node>> assignedNodesForBinding(
       const AssignedNodesOptions&);
 
@@ -93,7 +92,13 @@
   void SaveAndClearDistribution();
 
   bool SupportsDistribution() const { return IsInV1ShadowTree(); }
+
+  void CheckFallbackAfterInsertedIntoShadowTree();
+  void CheckFallbackAfterRemovedFromShadowTree();
+
   void DidSlotChange(SlotChangeType);
+  void DidSlotChangeAfterRemovedFromShadowTree();
+  void DidSlotChangeAfterRenaming();
   void DispatchSlotChangeEvent();
   void ClearSlotChangeEventEnqueued() { slotchange_event_enqueued_ = false; }
 
@@ -110,6 +115,8 @@
 
   void EnqueueSlotChangeEvent();
 
+  bool HasSlotableChild() const;
+
   HeapVector<Member<Node>> assigned_nodes_;
   HeapVector<Member<Node>> distributed_nodes_;
   HeapVector<Member<Node>> old_distributed_nodes_;
diff --git a/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp b/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp
index 7acd760b..3e0da90 100644
--- a/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp
+++ b/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp
@@ -55,6 +55,7 @@
   if (document_) {
     if (document_->Parser())
       document_->Parser()->RemoveClient(this);
+    document_->ClearImportsController();
     document_.Clear();
   }
   ClearResource();
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.json b/third_party/WebKit/Source/core/inspector/browser_protocol.json
index 7b65e82..450a9a1 100644
--- a/third_party/WebKit/Source/core/inspector/browser_protocol.json
+++ b/third_party/WebKit/Source/core/inspector/browser_protocol.json
@@ -1338,6 +1338,29 @@
                     { "name": "sameSite", "$ref": "CookieSameSite", "optional": true, "description": "Cookie SameSite type." }
                 ],
                 "experimental": true
+            },
+            {
+                "id": "AuthChallenge",
+                "type": "object",
+                "description": "Authorization challenge for HTTP status code 401 or 407.",
+                "properties": [
+                    { "name": "source", "type": "string", "optional": true, "enum": ["Server", "Proxy"], "description": "Source of the authentication challenge." },
+                    { "name": "origin", "type": "string", "description": "Origin of the challenger." },
+                    { "name": "scheme", "type": "string", "description": "The authentication scheme used, such as basic or digest" },
+                    { "name": "realm", "type": "string", "description": "The realm of the challenge. May be empty." }
+                ],
+                "experimental": true
+            },
+            {
+                "id": "AuthChallengeResponse",
+                "type": "object",
+                "description": "Response to an AuthChallenge.",
+                "properties": [
+                    { "name": "response", "type": "string", "enum": ["Default", "CancelAuth", "ProvideCredentials"], "description": "The decision on what to do in response to the authorization challenge.  Default means deferring to the default behavior of the net stack, which will likely either the Cancel authentication or display a popup dialog box." },
+                    { "name": "username", "type": "string", "optional": true, "description": "The username to provide, possibly empty. Should only be set if response is ProvideCredentials." },
+                    { "name": "password", "type": "string", "optional": true, "description": "The password to provide, possibly empty. Should only be set if response is ProvideCredentials." }
+                ],
+                "experimental": true
             }
         ],
         "commands": [
@@ -1529,12 +1552,13 @@
                 "description": "Response to Network.requestIntercepted which either modifies the request to continue with any modifications, or blocks it, or completes it with the provided response bytes. If a network fetch occurs as a result which encounters a redirect an additional Network.requestIntercepted event will be sent with the same InterceptionId.",
                 "parameters": [
                     { "name": "interceptionId", "$ref": "InterceptionId" },
-                    { "name": "errorReason", "$ref": "ErrorReason", "optional": true, "description": "If set this causes the request to fail with the given reason." },
-                    { "name": "rawResponse", "type": "string", "optional": true, "description": "If set the requests completes using with the provided base64 encoded raw response, including HTTP status line and headers etc..." },
-                    { "name": "url", "type": "string", "optional": true, "description": "If set the request url will be modified in a way that's not observable by page." },
-                    { "name": "method", "type": "string", "optional": true, "description": "If set this allows the request method to be overridden."},
-                    { "name": "postData", "type": "string", "optional": true, "description": "If set this allows postData to be set."},
-                    { "name": "headers", "$ref": "Headers", "optional": true, "description": "If set this allows the request headers to be changed."}
+                    { "name": "errorReason", "$ref": "ErrorReason", "optional": true, "description": "If set this causes the request to fail with the given reason. Must not be set in response to an authChallenge." },
+                    { "name": "rawResponse", "type": "string", "optional": true, "description": "If set the requests completes using with the provided base64 encoded raw response, including HTTP status line and headers etc... Must not be set in response to an authChallenge." },
+                    { "name": "url", "type": "string", "optional": true, "description": "If set the request url will be modified in a way that's not observable by page. Must not be set in response to an authChallenge." },
+                    { "name": "method", "type": "string", "optional": true, "description": "If set this allows the request method to be overridden. Must not be set in response to an authChallenge."},
+                    { "name": "postData", "type": "string", "optional": true, "description": "If set this allows postData to be set. Must not be set in response to an authChallenge."},
+                    { "name": "headers", "$ref": "Headers", "optional": true, "description": "If set this allows the request headers to be changed. Must not be set in response to an authChallenge."},
+                    { "name": "authChallengeResponse", "$ref": "AuthChallengeResponse", "optional": true, "description": "Response to a requestIntercepted with an authChallenge. Must not be set otherwise." }
                 ],
                 "experimental": true
             }
@@ -1702,12 +1726,13 @@
                 "name": "requestIntercepted",
                 "description": "Details of an intercepted HTTP request, which must be either allowed, blocked, modified or mocked.",
                 "parameters": [
-                    { "name": "interceptionId", "$ref": "InterceptionId", "description": "Each request the page makes will have a unique id, however if any redirects are encountered while processing that fetch, they will be reported with the same id as the original fetch." },
+                    { "name": "interceptionId", "$ref": "InterceptionId", "description": "Each request the page makes will have a unique id, however if any redirects are encountered while processing that fetch, they will be reported with the same id as the original fetch. Likewise if HTTP authentication is needed then the same fetch id will be used." },
                     { "name": "request", "$ref": "Request" },
                     { "name": "resourceType", "$ref": "Page.ResourceType", "description": "How the requested resource will be used." },
                     { "name": "redirectHeaders", "$ref": "Headers", "optional": true, "description": "HTTP response headers, only sent if a redirect was intercepted." },
                     { "name": "redirectStatusCode", "type": "integer", "optional": true, "description": "HTTP response code, only sent if a redirect was intercepted." },
-                    { "name": "redirectUrl", "optional": true, "type": "string", "description": "Redirect location, only sent if a redirect was intercepted."}
+                    { "name": "redirectUrl", "optional": true, "type": "string", "description": "Redirect location, only sent if a redirect was intercepted."},
+                    { "name": "authChallenge", "$ref": "AuthChallenge", "optional": true, "description": "Details of the Authorization Challenge encountered. If this is set then continueInterceptedRequest must contain an authChallengeResponse." }
                 ],
                 "experimental": true
             }
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index f448d46..1e3b17b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -955,7 +955,7 @@
   // hasOverflowClip(). However, they do "implicitly" clip their contents, so
   // we want to allow resizing them also.
   return (HasOverflowClip() || IsLayoutIFrame()) &&
-         Style()->Resize() != RESIZE_NONE;
+         Style()->Resize() != EResize::kNone;
 }
 
 void LayoutBox::AddLayerHitTestRects(LayerHitTestRects& layer_rects,
diff --git a/third_party/WebKit/Source/core/layout/LayoutIFrame.cpp b/third_party/WebKit/Source/core/layout/LayoutIFrame.cpp
index aa47aba..73abc66 100644
--- a/third_party/WebKit/Source/core/layout/LayoutIFrame.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutIFrame.cpp
@@ -40,7 +40,7 @@
 }
 
 PaintLayerType LayoutIFrame::LayerTypeRequired() const {
-  if (Style()->Resize() != RESIZE_NONE)
+  if (Style()->Resize() != EResize::kNone)
     return kNormalPaintLayer;
   return LayoutEmbeddedContent::LayerTypeRequired();
 }
diff --git a/third_party/WebKit/Source/core/paint/AppliedDecorationPainter.cpp b/third_party/WebKit/Source/core/paint/AppliedDecorationPainter.cpp
index 236501e..31111b6e 100644
--- a/third_party/WebKit/Source/core/paint/AppliedDecorationPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/AppliedDecorationPainter.cpp
@@ -11,22 +11,22 @@
 namespace {
 
 static StrokeStyle TextDecorationStyleToStrokeStyle(
-    TextDecorationStyle decoration_style) {
+    ETextDecorationStyle decoration_style) {
   StrokeStyle stroke_style = kSolidStroke;
   switch (decoration_style) {
-    case kTextDecorationStyleSolid:
+    case ETextDecorationStyle::kSolid:
       stroke_style = kSolidStroke;
       break;
-    case kTextDecorationStyleDouble:
+    case ETextDecorationStyle::kDouble:
       stroke_style = kDoubleStroke;
       break;
-    case kTextDecorationStyleDotted:
+    case ETextDecorationStyle::kDotted:
       stroke_style = kDottedStroke;
       break;
-    case kTextDecorationStyleDashed:
+    case ETextDecorationStyle::kDashed:
       stroke_style = kDashedStroke;
       break;
-    case kTextDecorationStyleWavy:
+    case ETextDecorationStyle::kWavy:
       stroke_style = kWavyStroke;
       break;
   }
@@ -77,18 +77,18 @@
   stroke_data.SetThickness(decoration_info_.thickness);
 
   switch (decoration_.Style()) {
-    case kTextDecorationStyleDotted:
-    case kTextDecorationStyleDashed: {
+    case ETextDecorationStyle::kDotted:
+    case ETextDecorationStyle::kDashed: {
       stroke_data.SetStyle(
           TextDecorationStyleToStrokeStyle(decoration_.Style()));
       return PrepareDottedDashedStrokePath().StrokeBoundingRect(
           stroke_data, Path::BoundsType::kExact);
     }
-    case kTextDecorationStyleWavy:
+    case ETextDecorationStyle::kWavy:
       return PrepareWavyStrokePath().StrokeBoundingRect(
           stroke_data, Path::BoundsType::kExact);
       break;
-    case kTextDecorationStyleDouble:
+    case ETextDecorationStyle::kDouble:
       if (double_offset_ > 0) {
         return FloatRect(start_point_.X(), start_point_.Y(),
                          decoration_info_.width,
@@ -98,7 +98,7 @@
                        decoration_info_.width,
                        -double_offset_ + decoration_info_.thickness);
       break;
-    case kTextDecorationStyleSolid:
+    case ETextDecorationStyle::kSolid:
       return FloatRect(start_point_.X(), start_point_.Y(),
                        decoration_info_.width, decoration_info_.thickness);
     default:
@@ -114,17 +114,17 @@
   context_.SetStrokeColor(decoration_.GetColor());
 
   switch (decoration_.Style()) {
-    case kTextDecorationStyleWavy:
+    case ETextDecorationStyle::kWavy:
       StrokeWavyTextDecoration();
       break;
-    case kTextDecorationStyleDotted:
-    case kTextDecorationStyleDashed:
+    case ETextDecorationStyle::kDotted:
+    case ETextDecorationStyle::kDashed:
       context_.SetShouldAntialias(decoration_info_.antialias);
     // Fall through
     default:
       context_.DrawLineForText(start_point_, decoration_info_.width);
 
-      if (decoration_.Style() == kTextDecorationStyleDouble) {
+      if (decoration_.Style() == ETextDecorationStyle::kDouble) {
         context_.DrawLineForText(start_point_ + FloatPoint(0, double_offset_),
                                  decoration_info_.width);
       }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
index 40145b0..34436a65 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -1580,7 +1580,7 @@
   return scrollable_area_ &&
          (scrollable_area_->HasScrollbar() ||
           scrollable_area_->ScrollCorner() ||
-          GetLayoutObject().Style()->Resize() != RESIZE_NONE);
+          GetLayoutObject().Style()->Resize() != EResize::kNone);
 }
 
 void PaintLayer::AppendSingleFragmentIgnoringPagination(
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index d0e528f9..48713d5 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -314,7 +314,7 @@
   // (b) Both scrollbars are present.
   bool has_horizontal_bar = HorizontalScrollbar();
   bool has_vertical_bar = VerticalScrollbar();
-  bool has_resizer = Box().Style()->Resize() != RESIZE_NONE;
+  bool has_resizer = Box().Style()->Resize() != EResize::kNone;
   if ((has_horizontal_bar && has_vertical_bar) ||
       (has_resizer && (has_horizontal_bar || has_vertical_bar))) {
     return CornerRect(
@@ -1468,7 +1468,7 @@
     return false;
 
   IntRect resize_control_rect;
-  if (Box().Style()->Resize() != RESIZE_NONE) {
+  if (Box().Style()->Resize() != EResize::kNone) {
     resize_control_rect = ResizerCornerRect(
         Box().PixelSnappedBorderBoxRect(Layer()->SubpixelAccumulation()),
         kResizerForPointer);
@@ -1522,7 +1522,7 @@
 IntRect PaintLayerScrollableArea::ResizerCornerRect(
     const IntRect& bounds,
     ResizerHitTestType resizer_hit_test_type) const {
-  if (Box().Style()->Resize() == RESIZE_NONE)
+  if (Box().Style()->Resize() == EResize::kNone)
     return IntRect();
   IntRect corner =
       CornerRect(Box(), HorizontalScrollbar(), VerticalScrollbar(), bounds);
@@ -1699,7 +1699,7 @@
       Box().Style()->BoxSizing() == EBoxSizing::kBorderBox;
 
   EResize resize = Box().Style()->Resize();
-  if (resize != RESIZE_VERTICAL && difference.Width()) {
+  if (resize != EResize::kVertical && difference.Width()) {
     if (element->IsFormControlElement()) {
       // Make implicit margins from the theme explicit (see
       // <http://bugs.webkit.org/show_bug.cgi?id=9547>).
@@ -1719,7 +1719,7 @@
                                     CSSPrimitiveValue::UnitType::kPixels);
   }
 
-  if (resize != RESIZE_HORIZONTAL && difference.Height()) {
+  if (resize != EResize::kHorizontal && difference.Height()) {
     if (element->IsFormControlElement()) {
       // Make implicit margins from the theme explicit (see
       // <http://bugs.webkit.org/show_bug.cgi?id=9547>).
diff --git a/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp b/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
index 4831db9..ad0caa3 100644
--- a/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
@@ -24,7 +24,7 @@
 void ScrollableAreaPainter::PaintResizer(GraphicsContext& context,
                                          const IntPoint& paint_offset,
                                          const CullRect& cull_rect) {
-  if (GetScrollableArea().Box().Style()->Resize() == RESIZE_NONE)
+  if (GetScrollableArea().Box().Style()->Resize() == EResize::kNone)
     return;
 
   IntRect abs_rect = GetScrollableArea().ResizerCornerRect(
diff --git a/third_party/WebKit/Source/core/paint/TextPainterBase.cpp b/third_party/WebKit/Source/core/paint/TextPainterBase.cpp
index 1130238d..d8796d51 100644
--- a/third_party/WebKit/Source/core/paint/TextPainterBase.cpp
+++ b/third_party/WebKit/Source/core/paint/TextPainterBase.cpp
@@ -219,9 +219,9 @@
 
 static bool ShouldSetDecorationAntialias(const ComputedStyle& style) {
   for (const auto& decoration : style.AppliedTextDecorations()) {
-    TextDecorationStyle decoration_style = decoration.Style();
-    if (decoration_style == kTextDecorationStyleDotted ||
-        decoration_style == kTextDecorationStyleDashed)
+    ETextDecorationStyle decoration_style = decoration.Style();
+    if (decoration_style == ETextDecorationStyle::kDotted ||
+        decoration_style == ETextDecorationStyle::kDashed)
       return true;
   }
   return false;
diff --git a/third_party/WebKit/Source/core/style/AppliedTextDecoration.cpp b/third_party/WebKit/Source/core/style/AppliedTextDecoration.cpp
index c1b4b9a..c343d309 100644
--- a/third_party/WebKit/Source/core/style/AppliedTextDecoration.cpp
+++ b/third_party/WebKit/Source/core/style/AppliedTextDecoration.cpp
@@ -7,9 +7,11 @@
 namespace blink {
 
 AppliedTextDecoration::AppliedTextDecoration(TextDecoration line,
-                                             TextDecorationStyle style,
+                                             ETextDecorationStyle style,
                                              Color color)
-    : lines_(static_cast<unsigned>(line)), style_(style), color_(color) {}
+    : lines_(static_cast<unsigned>(line)),
+      style_(static_cast<unsigned>(style)),
+      color_(color) {}
 
 bool AppliedTextDecoration::operator==(const AppliedTextDecoration& o) const {
   return color_ == o.color_ && lines_ == o.lines_ && style_ == o.style_;
diff --git a/third_party/WebKit/Source/core/style/AppliedTextDecoration.h b/third_party/WebKit/Source/core/style/AppliedTextDecoration.h
index 42752c3..b0955df 100644
--- a/third_party/WebKit/Source/core/style/AppliedTextDecoration.h
+++ b/third_party/WebKit/Source/core/style/AppliedTextDecoration.h
@@ -15,11 +15,11 @@
   DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
 
  public:
-  AppliedTextDecoration(TextDecoration, TextDecorationStyle, Color);
+  AppliedTextDecoration(TextDecoration, ETextDecorationStyle, Color);
 
   TextDecoration Lines() const { return static_cast<TextDecoration>(lines_); }
-  TextDecorationStyle Style() const {
-    return static_cast<TextDecorationStyle>(style_);
+  ETextDecorationStyle Style() const {
+    return static_cast<ETextDecorationStyle>(style_);
   }
   Color GetColor() const { return color_; }
   void SetColor(Color color) { color_ = color; }
@@ -31,7 +31,7 @@
 
  private:
   unsigned lines_ : kTextDecorationBits;
-  unsigned style_ : 3;  // TextDecorationStyle
+  unsigned style_ : 3;  // ETextDecorationStyle
   Color color_;
 };
 
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
index 11bc94c..c698908 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -1420,7 +1420,7 @@
     DEFINE_STATIC_LOCAL(
         Vector<AppliedTextDecoration>, underline,
         (1, AppliedTextDecoration(
-                TextDecoration::kUnderline, kTextDecorationStyleSolid,
+                TextDecoration::kUnderline, ETextDecorationStyle::kSolid,
                 VisitedDependentColor(CSSPropertyTextDecorationColor))));
     // Since we only have one of these in memory, just update the color before
     // returning.
@@ -1715,7 +1715,7 @@
        current_text_decoration_color != parent_text_decoration_color)) {
     SetHasSimpleUnderlineInternal(false);
     AddAppliedTextDecoration(AppliedTextDecoration(
-        TextDecoration::kUnderline, kTextDecorationStyleSolid,
+        TextDecoration::kUnderline, ETextDecorationStyle::kSolid,
         parent_text_decoration_color));
   }
   if (override_existing_colors && AppliedTextDecorationsInternal())
@@ -1726,9 +1726,9 @@
   // To save memory, we don't use AppliedTextDecoration objects in the common
   // case of a single simple underline of currentColor.
   TextDecoration decoration_lines = GetTextDecoration();
-  TextDecorationStyle decoration_style = GetTextDecorationStyle();
+  ETextDecorationStyle decoration_style = TextDecorationStyle();
   bool is_simple_underline = decoration_lines == TextDecoration::kUnderline &&
-                             decoration_style == kTextDecorationStyleSolid &&
+                             decoration_style == ETextDecorationStyle::kSolid &&
                              TextDecorationColor().IsCurrentColor();
   if (is_simple_underline && !AppliedTextDecorationsInternal()) {
     SetHasSimpleUnderlineInternal(true);
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h
index 1a0ccffe..82bac06 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -1165,11 +1165,13 @@
   }
 
   // resize
-  static EResize InitialResize() { return RESIZE_NONE; }
+  static EResize InitialResize() { return EResize::kNone; }
   EResize Resize() const {
     return static_cast<EResize>(rare_non_inherited_data_->resize_);
   }
-  void SetResize(EResize r) { SET_VAR(rare_non_inherited_data_, resize_, r); }
+  void SetResize(EResize r) {
+    SET_VAR(rare_non_inherited_data_, resize_, static_cast<unsigned>(r));
+  }
 
   // Transform properties.
   // transform (aka -webkit-transform)
@@ -1516,15 +1518,16 @@
   }
 
   // text-decoration-style
-  static TextDecorationStyle InitialTextDecorationStyle() {
-    return kTextDecorationStyleSolid;
+  static ETextDecorationStyle InitialTextDecorationStyle() {
+    return ETextDecorationStyle::kSolid;
   }
-  TextDecorationStyle GetTextDecorationStyle() const {
-    return static_cast<TextDecorationStyle>(
+  ETextDecorationStyle TextDecorationStyle() const {
+    return static_cast<ETextDecorationStyle>(
         rare_non_inherited_data_->text_decoration_style_);
   }
-  void SetTextDecorationStyle(TextDecorationStyle v) {
-    SET_VAR(rare_non_inherited_data_, text_decoration_style_, v);
+  void SetTextDecorationStyle(ETextDecorationStyle v) {
+    SET_VAR(rare_non_inherited_data_, text_decoration_style_,
+            static_cast<unsigned>(v));
   }
 
   // text-decoration-skip
@@ -3209,7 +3212,7 @@
   bool HasBoxDecorations() const {
     return HasBorderDecoration() || HasBorderRadius() || HasOutline() ||
            HasAppearance() || BoxShadow() || HasFilterInducingProperty() ||
-           HasBackdropFilter() || Resize() != RESIZE_NONE;
+           HasBackdropFilter() || Resize() != EResize::kNone;
   }
 
   // "Box decoration background" includes all box decorations and backgrounds
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
index 7975b43..c3447f4 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
@@ -166,7 +166,7 @@
 enum EFlexWrap { kFlexNoWrap, kFlexWrap, kFlexWrapReverse };
 
 // CSS3 Image Values
-enum EResize { RESIZE_NONE, RESIZE_BOTH, RESIZE_HORIZONTAL, RESIZE_VERTICAL };
+enum class EResize { kNone, kBoth, kHorizontal, kVertical };
 
 enum QuoteType { OPEN_QUOTE, CLOSE_QUOTE, NO_OPEN_QUOTE, NO_CLOSE_QUOTE };
 
@@ -193,13 +193,7 @@
                                          static_cast<unsigned>(b));
 }
 
-enum TextDecorationStyle {
-  kTextDecorationStyleSolid,
-  kTextDecorationStyleDouble,
-  kTextDecorationStyleDotted,
-  kTextDecorationStyleDashed,
-  kTextDecorationStyleWavy
-};
+enum class ETextDecorationStyle { kSolid, kDouble, kDotted, kDashed, kWavy };
 
 static const size_t kTextDecorationSkipBits = 3;
 enum class TextDecorationSkip { kNone = 0x0, kObjects = 0x1, kInk = 0x2 };
diff --git a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
index f2a4b73..6804885 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
@@ -62,8 +62,8 @@
 namespace {
 
 void NotifyFinishObservers(
-    HeapHashSet<WeakMember<ResourceFinishObserver>> observers) {
-  for (const auto& observer : observers)
+    HeapHashSet<WeakMember<ResourceFinishObserver>>* observers) {
+  for (const auto& observer : *observers)
     observer->NotifyFinished();
 }
 
@@ -371,14 +371,20 @@
 }
 
 void Resource::TriggerNotificationForFinishObservers() {
+  if (finish_observers_.IsEmpty())
+    return;
+
+  auto new_collections = new HeapHashSet<WeakMember<ResourceFinishObserver>>(
+      std::move(finish_observers_));
+  finish_observers_.clear();
+
   Platform::Current()
       ->CurrentThread()
       ->Scheduler()
       ->LoadingTaskRunner()
       ->PostTask(BLINK_FROM_HERE, WTF::Bind(&NotifyFinishObservers,
-                                            std::move(finish_observers_)));
+                                            WrapPersistent(new_collections)));
 
-  finish_observers_.clear();
   DidRemoveClientOrObserver();
 }
 
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index a14da973..8945d5eb 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -27,7 +27,7 @@
 # Do NOT CHANGE this if you don't know what you're doing -- see
 # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md
 # Reverting problematic clang rolls is safe, though.
-CLANG_REVISION = '305462'
+CLANG_REVISION = '305489'
 
 use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ
 if use_head_revision:
diff --git a/tools/gn/action_target_generator.cc b/tools/gn/action_target_generator.cc
index 5c7cbf67..b7efa43 100644
--- a/tools/gn/action_target_generator.cc
+++ b/tools/gn/action_target_generator.cc
@@ -4,6 +4,7 @@
 
 #include "tools/gn/action_target_generator.h"
 
+#include "base/stl_util.h"
 #include "tools/gn/build_settings.h"
 #include "tools/gn/err.h"
 #include "tools/gn/filesystem_utils.h"
@@ -73,10 +74,8 @@
   // together.
   const auto& required_args_substitutions =
       target_->action_values().args().required_types();
-  bool has_rsp_file_name = std::find(required_args_substitutions.begin(),
-                                     required_args_substitutions.end(),
-                                     SUBSTITUTION_RSP_FILE_NAME) !=
-      required_args_substitutions.end();
+  bool has_rsp_file_name = base::ContainsValue(required_args_substitutions,
+                                               SUBSTITUTION_RSP_FILE_NAME);
   if (target_->action_values().uses_rsp_file() && !has_rsp_file_name) {
     *err_ = Err(function_call_, "Missing {{response_file_name}} in args.",
         "This target defines response_file_contents but doesn't use\n"
diff --git a/tools/gn/function_process_file_template.cc b/tools/gn/function_process_file_template.cc
index 28e3e46..47de640 100644
--- a/tools/gn/function_process_file_template.cc
+++ b/tools/gn/function_process_file_template.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/stl_util.h"
 #include "tools/gn/functions.h"
 #include "tools/gn/parse_tree.h"
 #include "tools/gn/scope.h"
@@ -94,8 +95,7 @@
   }
 
   auto& types = subst.required_types();
-  if (std::find(types.begin(), types.end(),
-                SUBSTITUTION_SOURCE_TARGET_RELATIVE) != types.end()) {
+  if (base::ContainsValue(types, SUBSTITUTION_SOURCE_TARGET_RELATIVE)) {
     *err = Err(template_arg, "Not a valid substitution type for the function.");
     return Value();
   }
diff --git a/tools/gn/runtime_deps_unittest.cc b/tools/gn/runtime_deps_unittest.cc
index d0658f44..7de91fc1 100644
--- a/tools/gn/runtime_deps_unittest.cc
+++ b/tools/gn/runtime_deps_unittest.cc
@@ -4,8 +4,7 @@
 
 #include <stddef.h>
 
-#include <algorithm>
-
+#include "base/stl_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "tools/gn/runtime_deps.h"
 #include "tools/gn/scheduler.h"
@@ -91,29 +90,25 @@
   EXPECT_TRUE(MakePair("./main", &main) == result[0]);
 
   // The rest of the ordering is undefined. First the data files.
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../stat.dat", &stat)) !=
-              result.end()) << GetVectorDescription(result);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../shared.dat", &shared)) !=
-              result.end()) << GetVectorDescription(result);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../loadable.dat", &loadable)) !=
-              result.end()) << GetVectorDescription(result);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../set.dat", &set)) !=
-              result.end()) << GetVectorDescription(result);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../main.dat", &main)) !=
-              result.end()) << GetVectorDescription(result);
+  EXPECT_TRUE(base::ContainsValue(result, MakePair("../../stat.dat", &stat)))
+      << GetVectorDescription(result);
+  EXPECT_TRUE(
+      base::ContainsValue(result, MakePair("../../shared.dat", &shared)))
+      << GetVectorDescription(result);
+  EXPECT_TRUE(
+      base::ContainsValue(result, MakePair("../../loadable.dat", &loadable)))
+      << GetVectorDescription(result);
+  EXPECT_TRUE(base::ContainsValue(result, MakePair("../../set.dat", &set)))
+      << GetVectorDescription(result);
+  EXPECT_TRUE(base::ContainsValue(result, MakePair("../../main.dat", &main)))
+      << GetVectorDescription(result);
 
   // Check the static library and loadable module.
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("./libshared.so", &shared)) !=
-              result.end()) << GetVectorDescription(result);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("./libloadable.so", &loadable)) !=
-              result.end()) << GetVectorDescription(result);
+  EXPECT_TRUE(base::ContainsValue(result, MakePair("./libshared.so", &shared)))
+      << GetVectorDescription(result);
+  EXPECT_TRUE(
+      base::ContainsValue(result, MakePair("./libloadable.so", &loadable)))
+      << GetVectorDescription(result);
 }
 
 // Tests that executables that aren't listed as data deps aren't included in
@@ -163,12 +158,11 @@
   EXPECT_TRUE(MakePair("./main", &main) == result[0]);
 
   // The rest of the ordering is undefined.
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("./datadep", &datadep)) !=
-              result.end()) << GetVectorDescription(result);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../final_in.dat", &final_in)) !=
-              result.end()) << GetVectorDescription(result);
+  EXPECT_TRUE(base::ContainsValue(result, MakePair("./datadep", &datadep)))
+      << GetVectorDescription(result);
+  EXPECT_TRUE(
+      base::ContainsValue(result, MakePair("../../final_in.dat", &final_in)))
+      << GetVectorDescription(result);
 }
 
 // Tests that action and copy outputs are considered if they're data deps, but
@@ -232,24 +226,23 @@
   EXPECT_TRUE(MakePair("./main", &main) == result[0]);
 
   // The rest of the ordering is undefined.
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../datadep.data", &datadep)) !=
-              result.end()) << GetVectorDescription(result);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../datadep_copy.data", &datadep_copy)) !=
-              result.end()) << GetVectorDescription(result);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../datadep.output", &datadep)) !=
-              result.end()) << GetVectorDescription(result);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../datadep_copy.output", &datadep_copy)) !=
-              result.end()) << GetVectorDescription(result);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../dep.data", &dep)) !=
-              result.end()) << GetVectorDescription(result);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../dep_copy/data/", &dep_copy)) !=
-              result.end()) << GetVectorDescription(result);
+  EXPECT_TRUE(
+      base::ContainsValue(result, MakePair("../../datadep.data", &datadep)))
+      << GetVectorDescription(result);
+  EXPECT_TRUE(base::ContainsValue(
+      result, MakePair("../../datadep_copy.data", &datadep_copy)))
+      << GetVectorDescription(result);
+  EXPECT_TRUE(
+      base::ContainsValue(result, MakePair("../../datadep.output", &datadep)))
+      << GetVectorDescription(result);
+  EXPECT_TRUE(base::ContainsValue(
+      result, MakePair("../../datadep_copy.output", &datadep_copy)))
+      << GetVectorDescription(result);
+  EXPECT_TRUE(base::ContainsValue(result, MakePair("../../dep.data", &dep)))
+      << GetVectorDescription(result);
+  EXPECT_TRUE(
+      base::ContainsValue(result, MakePair("../../dep_copy/data/", &dep_copy)))
+      << GetVectorDescription(result);
 
   // Explicitly asking for the runtime deps of an action target only includes
   // the data and not all outputs.
@@ -344,19 +337,16 @@
   // The rest of the ordering is undefined.
 
   // The framework bundle's internal dependencies should not be incldued.
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("Bundle.framework/", &bundle)) !=
-              result.end()) << GetVectorDescription(result);
+  EXPECT_TRUE(
+      base::ContainsValue(result, MakePair("Bundle.framework/", &bundle)))
+      << GetVectorDescription(result);
   // But direct data and data dependencies should be.
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("./datadep", &data_dep)) !=
-              result.end()) << GetVectorDescription(result);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../dd.data", &data_dep)) !=
-              result.end()) << GetVectorDescription(result);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../b.data", &bundle)) !=
-              result.end()) << GetVectorDescription(result);
+  EXPECT_TRUE(base::ContainsValue(result, MakePair("./datadep", &data_dep)))
+      << GetVectorDescription(result);
+  EXPECT_TRUE(base::ContainsValue(result, MakePair("../../dd.data", &data_dep)))
+      << GetVectorDescription(result);
+  EXPECT_TRUE(base::ContainsValue(result, MakePair("../../b.data", &bundle)))
+      << GetVectorDescription(result);
 }
 
 // Tests that a dependency duplicated in regular and data deps is processed
@@ -380,9 +370,9 @@
   // The results should be the executable and the copy output.
   std::vector<std::pair<OutputFile, const Target*>> result =
       ComputeRuntimeDeps(&target);
-  EXPECT_TRUE(std::find(result.begin(), result.end(),
-                        MakePair("../../action.output", &action)) !=
-              result.end()) << GetVectorDescription(result);
+  EXPECT_TRUE(
+      base::ContainsValue(result, MakePair("../../action.output", &action)))
+      << GetVectorDescription(result);
 }
 
 // Tests that actions can't have output substitutions.
diff --git a/tools/gn/target.cc b/tools/gn/target.cc
index 759d7bf..f8af715 100644
--- a/tools/gn/target.cc
+++ b/tools/gn/target.cc
@@ -6,9 +6,8 @@
 
 #include <stddef.h>
 
-#include <algorithm>
-
 #include "base/bind.h"
+#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "tools/gn/config_values_extractors.h"
@@ -95,8 +94,7 @@
       Toolchain::ToolType tool_type;
       if (!target->GetOutputFilesForSource(source, &tool_type, &source_outputs))
         continue;
-      if (std::find(source_outputs.begin(), source_outputs.end(), file) !=
-          source_outputs.end())
+      if (base::ContainsValue(source_outputs, file))
         return true;
     }
   }
diff --git a/ui/gfx/codec/png_codec.cc b/ui/gfx/codec/png_codec.cc
index 69a00c1..fe40205 100644
--- a/ui/gfx/codec/png_codec.cc
+++ b/ui/gfx/codec/png_codec.cc
@@ -206,9 +206,6 @@
   // Pick our row format converter necessary for this data.
   if (!input_has_alpha) {
     switch (state->output_format) {
-      case PNGCodec::FORMAT_RGB:
-        state->output_channels = 3;
-        break;
       case PNGCodec::FORMAT_RGBA:
         state->output_channels = 4;
         png_set_add_alpha(png_ptr, 0xFF, PNG_FILLER_AFTER);
@@ -225,10 +222,6 @@
     }
   } else {
     switch (state->output_format) {
-      case PNGCodec::FORMAT_RGB:
-        state->output_channels = 3;
-        png_set_strip_alpha(png_ptr);
-        break;
       case PNGCodec::FORMAT_RGBA:
         state->output_channels = 4;
         break;
@@ -634,12 +627,6 @@
   int input_color_components, output_color_components;
   int png_output_color_type;
   switch (format) {
-    case PNGCodec::FORMAT_RGB:
-      input_color_components = 3;
-      output_color_components = 3;
-      png_output_color_type = PNG_COLOR_TYPE_RGB;
-      break;
-
     case PNGCodec::FORMAT_RGBA:
       input_color_components = 4;
       if (discard_transparency) {
diff --git a/ui/gfx/codec/png_codec.h b/ui/gfx/codec/png_codec.h
index 0ae9a81d..335b58a 100644
--- a/ui/gfx/codec/png_codec.h
+++ b/ui/gfx/codec/png_codec.h
@@ -28,10 +28,6 @@
 class CODEC_EXPORT PNGCodec {
  public:
   enum ColorFormat {
-    // 3 bytes per pixel (packed), in RGB order regardless of endianness.
-    // This is the native JPEG format.
-    FORMAT_RGB,
-
     // 4 bytes per pixel, in RGBA order in memory regardless of endianness.
     FORMAT_RGBA,
 
diff --git a/ui/gfx/codec/png_codec_unittest.cc b/ui/gfx/codec/png_codec_unittest.cc
index b0d1e3d..faf665d 100644
--- a/ui/gfx/codec/png_codec_unittest.cc
+++ b/ui/gfx/codec/png_codec_unittest.cc
@@ -276,34 +276,6 @@
     src_data[i] = i % 255;
 }
 
-TEST(PNGCodec, EncodeDecodeRGB) {
-  const int w = 20, h = 20;
-
-  // create an image with known values
-  std::vector<unsigned char> original;
-  MakeRGBImage(w, h, &original);
-
-  // encode
-  std::vector<unsigned char> encoded;
-  ASSERT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB,
-                               Size(w, h), w * 3, false,
-                               std::vector<PNGCodec::Comment>(),
-                               &encoded));
-
-  // decode, it should have the same size as the original
-  std::vector<unsigned char> decoded;
-  int outw, outh;
-  ASSERT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
-                               PNGCodec::FORMAT_RGB, &decoded,
-                               &outw, &outh));
-  ASSERT_EQ(w, outw);
-  ASSERT_EQ(h, outh);
-  ASSERT_EQ(original.size(), decoded.size());
-
-  // Images must be equal
-  ASSERT_TRUE(original == decoded);
-}
-
 TEST(PNGCodec, EncodeDecodeRGBA) {
   const int w = 20, h = 20;
 
@@ -407,49 +379,6 @@
   }
 }
 
-TEST(PNGCodec, DecodePaletteDiscardAlpha) {
-  const int w = 20, h = 20;
-
-  // create an image with known values
-  std::vector<unsigned char> original;
-  std::vector<png_color> original_palette;
-  std::vector<unsigned char> original_trans_chunk;
-  MakePaletteImage(w, h, &original, &original_palette, &original_trans_chunk);
-
-  // encode
-  std::vector<unsigned char> encoded;
-  ASSERT_TRUE(EncodeImage(original,
-                          w, h,
-                          COLOR_TYPE_PALETTE,
-                          &encoded,
-                          PNG_INTERLACE_NONE,
-                          &original_palette,
-                          &original_trans_chunk));
-
-  // decode
-  std::vector<unsigned char> decoded;
-  int outw, outh;
-  ASSERT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
-                               PNGCodec::FORMAT_RGB, &decoded,
-                               &outw, &outh));
-  ASSERT_EQ(w, outw);
-  ASSERT_EQ(h, outh);
-  ASSERT_EQ(decoded.size(), w * h * 3U);
-
-  // Images must be equal
-  for (int y = 0; y < h; ++y) {
-    for (int x = 0; x < w; ++x) {
-      unsigned char palette_pixel = original[y * w + x];
-      png_color& palette_color = original_palette[palette_pixel];
-      unsigned char* rgba_pixel = &decoded[(y * w + x) * 3];
-
-      EXPECT_EQ(palette_color.red, rgba_pixel[0]);
-      EXPECT_EQ(palette_color.green, rgba_pixel[1]);
-      EXPECT_EQ(palette_color.blue, rgba_pixel[2]);
-    }
-  }
-}
-
 TEST(PNGCodec, DecodeInterlacedPalette) {
   const int w = 20, h = 20;
 
@@ -510,20 +439,20 @@
   std::vector<unsigned char> decoded;
   int outw, outh;
   ASSERT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
-                               PNGCodec::FORMAT_RGB, &decoded,
-                               &outw, &outh));
+                               PNGCodec::FORMAT_RGBA, &decoded, &outw, &outh));
   ASSERT_EQ(w, outw);
   ASSERT_EQ(h, outh);
-  ASSERT_EQ(decoded.size(), original.size() * 3);
+  ASSERT_EQ(decoded.size(), original.size() * 4);
 
   // Images must be equal
   for (int y = 0; y < h; ++y) {
     for (int x = 0; x < w; ++x) {
       unsigned char gray_pixel = original[(y * w + x)];
-      unsigned char* rgba_pixel = &decoded[(y * w + x) * 3];
+      unsigned char* rgba_pixel = &decoded[(y * w + x) * 4];
       EXPECT_EQ(rgba_pixel[0], gray_pixel);
       EXPECT_EQ(rgba_pixel[1], gray_pixel);
       EXPECT_EQ(rgba_pixel[2], gray_pixel);
+      EXPECT_EQ(rgba_pixel[3], 0xff);
     }
   }
 }
@@ -565,42 +494,6 @@
   }
 }
 
-TEST(PNGCodec, DecodeGrayscaleWithAlphaDiscardAlpha) {
-  const int w = 20, h = 20;
-
-  // create an image with known values
-  std::vector<unsigned char> original;
-  MakeGrayscaleAlphaImage(w, h, &original);
-
-  // encode
-  std::vector<unsigned char> encoded;
-  ASSERT_TRUE(EncodeImage(original,
-                          w, h,
-                          COLOR_TYPE_GRAY_ALPHA,
-                          &encoded));
-
-  // decode
-  std::vector<unsigned char> decoded;
-  int outw, outh;
-  ASSERT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
-                               PNGCodec::FORMAT_RGB, &decoded,
-                               &outw, &outh));
-  ASSERT_EQ(w, outw);
-  ASSERT_EQ(h, outh);
-  ASSERT_EQ(decoded.size(), w * h * 3U);
-
-  // Images must be equal
-  for (int y = 0; y < h; ++y) {
-    for (int x = 0; x < w; ++x) {
-      unsigned char* gray_pixel = &original[(y * w + x) * 2];
-      unsigned char* rgba_pixel = &decoded[(y * w + x) * 3];
-      EXPECT_EQ(rgba_pixel[0], gray_pixel[0]);
-      EXPECT_EQ(rgba_pixel[1], gray_pixel[0]);
-      EXPECT_EQ(rgba_pixel[2], gray_pixel[0]);
-    }
-  }
-}
-
 TEST(PNGCodec, DecodeInterlacedGrayscale) {
   const int w = 20, h = 20;
 
@@ -677,35 +570,6 @@
   }
 }
 
-TEST(PNGCodec, DecodeInterlacedRGB) {
-  const int w = 20, h = 20;
-
-  // create an image with known values
-  std::vector<unsigned char> original;
-  MakeRGBImage(w, h, &original);
-
-  // encode
-  std::vector<unsigned char> encoded;
-  ASSERT_TRUE(EncodeImage(original,
-                          w, h,
-                          COLOR_TYPE_RGB,
-                          &encoded,
-                          PNG_INTERLACE_ADAM7));
-
-  // decode, it should have the same size as the original
-  std::vector<unsigned char> decoded;
-  int outw, outh;
-  ASSERT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
-                               PNGCodec::FORMAT_RGB, &decoded,
-                               &outw, &outh));
-  ASSERT_EQ(w, outw);
-  ASSERT_EQ(h, outh);
-  ASSERT_EQ(original.size(), decoded.size());
-
-  // Images must be equal
-  ASSERT_EQ(original, decoded);
-}
-
 TEST(PNGCodec, DecodeInterlacedRGBA) {
   const int w = 20, h = 20;
 
@@ -735,43 +599,6 @@
   ASSERT_EQ(original, decoded);
 }
 
-TEST(PNGCodec, DecodeInterlacedRGBADiscardAlpha) {
-  const int w = 20, h = 20;
-
-  // create an image with known values
-  std::vector<unsigned char> original;
-  MakeRGBAImage(w, h, false, &original);
-
-  // encode
-  std::vector<unsigned char> encoded;
-  ASSERT_TRUE(EncodeImage(original,
-                          w, h,
-                          COLOR_TYPE_RGBA,
-                          &encoded,
-                          PNG_INTERLACE_ADAM7));
-
-  // decode
-  std::vector<unsigned char> decoded;
-  int outw, outh;
-  ASSERT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
-                               PNGCodec::FORMAT_RGB, &decoded,
-                               &outw, &outh));
-  ASSERT_EQ(w, outw);
-  ASSERT_EQ(h, outh);
-  ASSERT_EQ(decoded.size(), w * h * 3U);
-
-  // Images must be equal
-  for (int x = 0; x < w; x++) {
-    for (int y = 0; y < h; y++) {
-      unsigned char* orig_px = &original[(y * w + x) * 4];
-      unsigned char* dec_px = &decoded[(y * w + x) * 3];
-      EXPECT_EQ(dec_px[0], orig_px[0]);
-      EXPECT_EQ(dec_px[1], orig_px[1]);
-      EXPECT_EQ(dec_px[2], orig_px[2]);
-    }
-  }
-}
-
 TEST(PNGCodec, DecodeInterlacedBGR) {
   const int w = 20, h = 20;
 
@@ -912,80 +739,29 @@
 
   // Make some random data (an uncompressed image).
   std::vector<unsigned char> original;
-  MakeRGBImage(w, h, &original);
+  MakeRGBAImage(w, h, false, &original);
 
-  // It should fail when given non-JPEG compressed data.
+  // It should fail when given non-PNG compressed data.
   std::vector<unsigned char> output;
   int outw, outh;
   EXPECT_FALSE(PNGCodec::Decode(&original[0], original.size(),
-                                PNGCodec::FORMAT_RGB, &output,
-                                &outw, &outh));
+                                PNGCodec::FORMAT_RGBA, &output, &outw, &outh));
 
   // Make some compressed data.
   std::vector<unsigned char> compressed;
-  ASSERT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB,
-                               Size(w, h), w * 3, false,
-                               std::vector<PNGCodec::Comment>(),
+  ASSERT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGBA, Size(w, h),
+                               w * 4, false, std::vector<PNGCodec::Comment>(),
                                &compressed));
 
   // Try decompressing a truncated version.
   EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size() / 2,
-                                PNGCodec::FORMAT_RGB, &output,
-                                &outw, &outh));
+                                PNGCodec::FORMAT_RGBA, &output, &outw, &outh));
 
   // Corrupt it and try decompressing that.
   for (int i = 10; i < 30; i++)
     compressed[i] = i;
   EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size(),
-                                PNGCodec::FORMAT_RGB, &output,
-                                &outw, &outh));
-}
-
-TEST(PNGCodec, StripAddAlpha) {
-  const int w = 20, h = 20;
-
-  // These should be the same except one has a 0xff alpha channel.
-  std::vector<unsigned char> original_rgb;
-  MakeRGBImage(w, h, &original_rgb);
-  std::vector<unsigned char> original_rgba;
-  MakeRGBAImage(w, h, false, &original_rgba);
-
-  // Encode RGBA data as RGB.
-  std::vector<unsigned char> encoded;
-  EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], PNGCodec::FORMAT_RGBA,
-                               Size(w, h), w * 4, true,
-                               std::vector<PNGCodec::Comment>(),
-                               &encoded));
-
-  // Decode the RGB to RGBA.
-  std::vector<unsigned char> decoded;
-  int outw, outh;
-  EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
-                               PNGCodec::FORMAT_RGBA, &decoded,
-                               &outw, &outh));
-
-  // Decoded and reference should be the same (opaque alpha).
-  ASSERT_EQ(w, outw);
-  ASSERT_EQ(h, outh);
-  ASSERT_EQ(original_rgba.size(), decoded.size());
-  ASSERT_EQ(original_rgba, decoded);
-
-  // Encode RGBA to RGBA.
-  EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], PNGCodec::FORMAT_RGBA,
-                               Size(w, h), w * 4, false,
-                               std::vector<PNGCodec::Comment>(),
-                               &encoded));
-
-  // Decode the RGBA to RGB.
-  EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
-                               PNGCodec::FORMAT_RGB, &decoded,
-                               &outw, &outh));
-
-  // It should be the same as our non-alpha-channel reference.
-  ASSERT_EQ(w, outw);
-  ASSERT_EQ(h, outh);
-  ASSERT_EQ(original_rgb.size(), decoded.size());
-  ASSERT_EQ(original_rgb, decoded);
+                                PNGCodec::FORMAT_RGBA, &output, &outw, &outh));
 }
 
 TEST(PNGCodec, EncodeBGRASkBitmapStridePadded) {
@@ -1125,15 +901,15 @@
   const int w = 10, h = 10;
 
   std::vector<unsigned char> original;
-  MakeRGBImage(w, h, &original);
+  MakeRGBAImage(w, h, true, &original);
 
   std::vector<unsigned char> encoded;
   std::vector<PNGCodec::Comment> comments;
   comments.push_back(PNGCodec::Comment("key", "text"));
   comments.push_back(PNGCodec::Comment("test", "something"));
   comments.push_back(PNGCodec::Comment("have some", "spaces in both"));
-  EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB,
-                               Size(w, h), w * 3, false, comments, &encoded));
+  EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGBA, Size(w, h),
+                               w * 4, false, comments, &encoded));
 
   // Each chunk is of the form length (4 bytes), chunk type (tEXt), data,
   // checksum (4 bytes).  Make sure we find all of them in the encoded