diff --git a/DEPS b/DEPS
index f5fbf56..4cb279e 100644
--- a/DEPS
+++ b/DEPS
@@ -129,7 +129,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '76e626d9bb555d2a831b1f91b37e93649bfbd71d',
+  'skia_revision': '25e371f7ee5a770ba0d7fe5b8b51887c616cc52b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -141,11 +141,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': 'e6b23e45b380bee1a2dfda06e4728d24d4d4ad8b',
+  'angle_revision': 'd581f918e90dd5a1e827ddc15abf83a17656262c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '5d64ec4c2dcd5dbeac89a1f5e50bb3d6619081cd',
+  'swiftshader_revision': 'f41ca6b57107978252fdd14deaefe9fbc396c86c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -196,7 +196,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'd27288f5266a4ebf69de7cc91dc865707425736b',
+  'catapult_revision': '50b06f012a60d306c1edafb6544fb9e36f07e645',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -260,15 +260,15 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'spirv_cross_revision': '69b034f26e28a76a6f4e5d9521123072b24d7ea2',
+  'spirv_cross_revision': 'f07a4e16a60e1d0231dda5d3883550761bd70a47',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'shaderc_revision': '6ff17fe32fd2e0b6bc1890befaf036d526b24540',
+  'shaderc_revision': 'ff9ae40e3734a264a56bba02191f5ae18c7e5e03',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '51fd66e3dd35d4ed80dc64244a6dd132e2321fa7',
+  'dawn_revision': '9a9b837519953393aa8c76dd4f6df6090fba08c7',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -805,7 +805,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'f21ce663029c3172c162dae0a199f5be5a0c9991',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'f5a6b40dd0b3dc5181f6898236e04622ff2a640d',
       'condition': 'checkout_linux',
   },
 
@@ -830,7 +830,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6379cd39a3336ab8716c77b1c68ab37ff406d060',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a67950d67088163e315e3bc4c6d66fb1968f2724',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -1172,7 +1172,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  'de4e8874ae8261e916af8c5e1926149f8b8540d9',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '2072d9bde71d3bfeef6d03b1bf165e2eaa06d183',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
@@ -1343,7 +1343,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '688fbfe33779392aa210d67d4aa12cb012f112c2',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '7ddef1af885921e74076b1c2f6695231b48e5ace',
+    Var('webrtc_git') + '/src.git' + '@' + '21d42d27103eedfa24696e4168a44bd1cbade2ee',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1384,7 +1384,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3ec1a396fb7932f2fa19253833dd2229394056b4',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c1ad291dcb9c9d1b97ca42d16739693531f1af52',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/WATCHLISTS b/WATCHLISTS
index 4d7f817..d12491a47 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -728,6 +728,9 @@
                   'chromeos/services/cellular_setup/|'\
                   'ui/webui/resources/cr_components/chromeos/cellular_setup/',
     },
+    'chromeos_device_policy': {
+      'filepath': 'components/policy/proto/chrome_device_policy.proto'
+    },
     'chromeos_geolocation': {
       'filepath': 'chromeos/geolocation/',
     },
@@ -2137,6 +2140,7 @@
     'chromeos_calculator': ['dharcourt@chromium.org'],
     'chromeos_cellular': ['azeemarshad+watch-cellular@chromium.org',
                           'khorimoto+watch-cellular@chromium.org'],
+    'chromeos_device_policy': ['ljusten+watch@chromium.org'],
     'chromeos_geolocation': ['alemate+watch@chromium.org'],
     'chromeos_lkgm': ['achuith+watch@chromium.org',
                       'bpastene+watch@chromium.org',
diff --git a/android_webview/browser/gfx/aw_draw_fn_impl.cc b/android_webview/browser/gfx/aw_draw_fn_impl.cc
index 4299b44..245a3b1 100644
--- a/android_webview/browser/gfx/aw_draw_fn_impl.cc
+++ b/android_webview/browser/gfx/aw_draw_fn_impl.cc
@@ -16,6 +16,7 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "gpu/ipc/common/android/android_image_reader_utils.h"
+#include "gpu/vulkan/vulkan_fence_helper.h"
 #include "gpu/vulkan/vulkan_function_pointers.h"
 #include "gpu/vulkan/vulkan_implementation.h"
 #include "jni/AwDrawFnImpl_jni.h"
@@ -38,6 +39,18 @@
 
 namespace {
 GLNonOwnedCompatibilityContext* g_gl_context = nullptr;
+
+void CleanupInFlightDraw(sk_sp<GrVkSecondaryCBDrawContext> draw_context,
+                         VkSemaphore post_draw_semaphore,
+                         gpu::VulkanDeviceQueue* device_queue,
+                         bool /* context_lost */) {
+  VkDevice device = device_queue->GetVulkanDevice();
+  // We do the same thing whether or not context is lost.
+  draw_context->releaseResources();
+  draw_context.reset();
+  if (post_draw_semaphore != VK_NULL_HANDLE)
+    vkDestroySemaphore(device, post_draw_semaphore, nullptr);
+}
 }
 
 class GLNonOwnedCompatibilityContext : public gl::GLContextEGL {
@@ -177,33 +190,6 @@
   return SkColorSpace::MakeRGB(transfer_fn, to_xyz);
 }
 
-// Create a VkFence and submit it to the queue.
-VkFence CreateAndSubmitFence(VkDevice device, VkQueue queue) {
-  VkFence fence = VK_NULL_HANDLE;
-  VkFenceCreateInfo create_info{
-      .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
-      .pNext = nullptr,
-      .flags = 0,
-  };
-
-  auto result =
-      vkCreateFence(device, &create_info, nullptr /* pAllocator */, &fence);
-  if (result != VK_SUCCESS) {
-    LOG(ERROR) << "Could not create VkFence.";
-    return VK_NULL_HANDLE;
-  }
-
-  result =
-      vkQueueSubmit(queue, 0 /* submitCount */, nullptr /* pSubmits */, fence);
-  if (result != VK_SUCCESS) {
-    LOG(ERROR) << "Could not create VkFence.";
-    vkDestroyFence(device, fence, nullptr /* pAllocator */);
-    return VK_NULL_HANDLE;
-  }
-
-  return fence;
-}
-
 }  // namespace
 
 static void JNI_AwDrawFnImpl_SetDrawFnFunctionTable(JNIEnv* env,
@@ -277,31 +263,8 @@
         false /* save_restore */);
   }
 
-  if (!in_flight_draws_.empty()) {
-    DCHECK(!is_interop_mode_);
-    // Make sure the last pending draw is finished, and then we can destroy all
-    // pending draws safely.
-    VkFence last_fence = in_flight_draws_.back().fence;
-    VkDevice device =
-        vulkan_context_provider_->GetDeviceQueue()->GetVulkanDevice();
-    VkResult result =
-        vkWaitForFences(device, 1, &last_fence, VK_TRUE,
-                        base::TimeDelta::FromSeconds(60).InNanoseconds());
-    DCHECK_EQ(result, VK_SUCCESS);
-    while (!in_flight_draws_.empty()) {
-      auto& draw = in_flight_draws_.front();
-      vkDestroyFence(device, draw.fence, nullptr /* pAllocator */);
-      draw.draw_context->releaseResources();
-      draw.draw_context = nullptr;
-      in_flight_draws_.pop();
-    }
-  }
-
-  while (!in_flight_interop_draws_.empty()) {
-    DCHECK(is_interop_mode_);
-    // Let returned InFlightInteropDraw go out of scope.
-    TakeInFlightInteropDrawForReUse();
-  }
+  // Clear the queue.
+  { auto queue = std::move(in_flight_interop_draws_); }
 
   vulkan_context_provider_.reset();
   gl_context_.reset();
@@ -366,31 +329,16 @@
   if (!vulkan_context_provider_)
     return;
 
-  DCHECK(draw_context_);
-  VkDevice device =
-      vulkan_context_provider_->GetDeviceQueue()->GetVulkanDevice();
-  VkQueue queue = vulkan_context_provider_->GetDeviceQueue()->GetVulkanQueue();
-  VkFence fence = CreateAndSubmitFence(device, queue);
-  DCHECK(fence != VK_NULL_HANDLE);
-  in_flight_draws_.emplace(fence, std::move(draw_context_));
+  gpu::VulkanFenceHelper* fence_helper =
+      vulkan_context_provider_->GetDeviceQueue()->GetFenceHelper();
 
-  // Cleanup completed draws.
-  while (!in_flight_draws_.empty()) {
-    auto& draw = in_flight_draws_.front();
-    VkResult result = vkGetFenceStatus(device, draw.fence);
-    if (result == VK_NOT_READY)
-      break;
-    if (result == VK_SUCCESS) {
-      vkDestroyFence(device, draw.fence, nullptr /* pAllocator */);
-      draw.draw_context->releaseResources();
-      draw.draw_context = nullptr;
-      in_flight_draws_.pop();
-      continue;
-    }
-    // Handle context lost.
-    NOTREACHED();
-  }
-  DCHECK_LE(in_flight_draws_.size(), 2u);
+  fence_helper->EnqueueCleanupTaskForSubmittedWork(
+      base::BindOnce(&CleanupInFlightDraw, std::move(draw_context_),
+                     static_cast<VkSemaphore>(VK_NULL_HANDLE)));
+
+  // Process cleanup tasks and generate fences at the end of each PostDrawVk.
+  fence_helper->GenerateCleanupFence();
+  fence_helper->ProcessCleanupTasks();
 }
 
 void AwDrawFnImpl::DrawVkInterop(AwDrawFn_DrawVkParams* params) {
@@ -411,7 +359,8 @@
   // If we've exhausted our buffers, re-use an existing one.
   // TODO(ericrk): Benchmark using more than 1 buffer.
   if (in_flight_interop_draws_.size() >= 1 /* single buffering */) {
-    pending_draw = TakeInFlightInteropDrawForReUse();
+    pending_draw = std::move(in_flight_interop_draws_.front());
+    in_flight_interop_draws_.pop();
   }
 
   // If prev buffer is wrong size, just re-allocate.
@@ -636,20 +585,22 @@
   }
   pending_draw->sync_fd = semaphore_handle.TakeHandle();
 
-  DCHECK(VK_NULL_HANDLE == pending_draw->post_draw_fence);
+  gpu::VulkanFenceHelper* fence_helper =
+      vulkan_context_provider_->GetDeviceQueue()->GetFenceHelper();
 
-  VkDevice device =
-      vulkan_context_provider_->GetDeviceQueue()->GetVulkanDevice();
-  VkQueue queue = vulkan_context_provider_->GetDeviceQueue()->GetVulkanQueue();
-  VkFence fence = CreateAndSubmitFence(device, queue);
-  if (fence == VK_NULL_HANDLE) {
-    LOG(ERROR) << "Could not create fence.";
-    return;
-  }
-  pending_draw->post_draw_fence = fence;
+  fence_helper->EnqueueCleanupTaskForSubmittedWork(base::BindOnce(
+      &CleanupInFlightDraw, std::move(pending_draw->draw_context),
+      pending_draw->post_draw_semaphore));
+  pending_draw->post_draw_semaphore = VK_NULL_HANDLE;
 
   // Add the |pending_draw| to |in_flight_interop_draws_|.
   in_flight_interop_draws_.push(std::move(pending_draw));
+
+  // Process cleanup tasks and generate fences at the end of each PostDrawVk.
+  // TODO(ericrk): We'd ideally combine this with the flushAndSignalSemaphores
+  // above.
+  fence_helper->GenerateCleanupFence();
+  fence_helper->ProcessCleanupTasks();
 }
 
 template <typename T>
@@ -673,43 +624,6 @@
   render_thread_manager_.DrawOnRT(false /* save_restore */, &hr_params);
 }
 
-std::unique_ptr<AwDrawFnImpl::InFlightInteropDraw>
-AwDrawFnImpl::TakeInFlightInteropDrawForReUse() {
-  DCHECK(vulkan_context_provider_);
-  DCHECK(!in_flight_interop_draws_.empty());
-  std::unique_ptr<InFlightInteropDraw> draw =
-      std::move(in_flight_interop_draws_.front());
-  in_flight_interop_draws_.pop();
-
-  // Wait for our draw's |post_draw_fence| to pass.
-  DCHECK(draw->post_draw_fence != VK_NULL_HANDLE);
-  VkResult wait_result = vkWaitForFences(
-      vulkan_context_provider_->device(), 1, &draw->post_draw_fence, VK_TRUE,
-      base::TimeDelta::FromSeconds(60).InNanoseconds());
-  if (wait_result != VK_SUCCESS) {
-    LOG(ERROR) << "Fence did not pass in the expected timeframe.";
-    return nullptr;
-  }
-
-  draw->draw_context->releaseResources();
-  draw->draw_context.reset();
-  vkDestroyFence(vulkan_context_provider_->device(), draw->post_draw_fence,
-                 nullptr);
-  draw->post_draw_fence = VK_NULL_HANDLE;
-  vkDestroySemaphore(vulkan_context_provider_->device(),
-                     draw->post_draw_semaphore, nullptr);
-  draw->post_draw_semaphore = VK_NULL_HANDLE;
-  return draw;
-}
-
-AwDrawFnImpl::InFlightDraw::InFlightDraw(
-    VkFence fence,
-    sk_sp<GrVkSecondaryCBDrawContext> draw_context)
-    : fence(fence), draw_context(std::move(draw_context)) {}
-
-AwDrawFnImpl::InFlightDraw::InFlightDraw(InFlightDraw&& other) = default;
-AwDrawFnImpl::InFlightDraw::~InFlightDraw() = default;
-
 AwDrawFnImpl::InFlightInteropDraw::InFlightInteropDraw(
     AwVulkanContextProvider* vk_context_provider)
     : vk_context_provider(vk_context_provider) {}
@@ -734,10 +648,6 @@
       draw_context->releaseResources();
       draw_context.reset();
     }
-    if (post_draw_fence != VK_NULL_HANDLE) {
-      vkDestroyFence(vk_context_provider->device(), post_draw_fence, nullptr);
-      post_draw_fence = VK_NULL_HANDLE;
-    }
     if (post_draw_semaphore != VK_NULL_HANDLE) {
       vkDestroySemaphore(vk_context_provider->device(), post_draw_semaphore,
                          nullptr);
@@ -746,7 +656,6 @@
   }
   DCHECK(!draw_context);
   DCHECK(!ahb_skimage);
-  DCHECK(post_draw_fence == VK_NULL_HANDLE);
   DCHECK(post_draw_semaphore == VK_NULL_HANDLE);
 
   // Clean up re-usable components that are expected to still be alive.
@@ -755,9 +664,10 @@
   if (framebuffer_id)
     glDeleteFramebuffersEXT(1, &framebuffer_id);
   if (image_info.fImage != VK_NULL_HANDLE) {
-    vkDestroyImage(vk_context_provider->device(), image_info.fImage, nullptr);
-    vkFreeMemory(vk_context_provider->device(), image_info.fAlloc.fMemory,
-                 nullptr);
+    vk_context_provider->GetDeviceQueue()
+        ->GetFenceHelper()
+        ->EnqueueImageCleanupForSubmittedWork(image_info.fImage,
+                                              image_info.fAlloc.fMemory);
   }
 }
 
diff --git a/android_webview/browser/gfx/aw_draw_fn_impl.h b/android_webview/browser/gfx/aw_draw_fn_impl.h
index 80d89d1..a75362c2 100644
--- a/android_webview/browser/gfx/aw_draw_fn_impl.h
+++ b/android_webview/browser/gfx/aw_draw_fn_impl.h
@@ -82,8 +82,6 @@
     return &render_thread_manager_;
   }
 
-  std::unique_ptr<InFlightInteropDraw> TakeInFlightInteropDrawForReUse();
-
   const bool is_interop_mode_;
 
   int functor_handle_;
@@ -96,17 +94,6 @@
   // The draw context for the current frame. It is for direct mode only.
   sk_sp<GrVkSecondaryCBDrawContext> draw_context_;
 
-  struct InFlightDraw {
-    InFlightDraw(VkFence fence, sk_sp<GrVkSecondaryCBDrawContext> draw_context);
-    InFlightDraw(InFlightDraw&& other);
-    ~InFlightDraw();
-
-    // The fence for cleanup the |draw_context|.
-    VkFence fence = VK_NULL_HANDLE;
-    sk_sp<GrVkSecondaryCBDrawContext> draw_context;
-  };
-  base::queue<InFlightDraw> in_flight_draws_;
-
   // GL context used to draw via GL in Vk interop path.
   scoped_refptr<GLNonOwnedCompatibilityContext> gl_context_;
 
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java
index 4198eb1..693fff2 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java
@@ -4,8 +4,6 @@
 
 package org.chromium.android_webview.test;
 
-import static org.junit.Assert.assertNotEquals;
-
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.view.View;
@@ -22,11 +20,14 @@
 import org.chromium.android_webview.AwLayoutSizer;
 import org.chromium.android_webview.test.util.CommonResources;
 import org.chromium.android_webview.test.util.GraphicsTestUtils;
+import org.chromium.base.Log;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.Feature;
 
 import java.util.concurrent.atomic.AtomicReference;
 
+import javax.annotation.concurrent.GuardedBy;
+
 /**
  * Tests for certain edge cases related to integrating with the Android view system.
  */
@@ -46,25 +47,37 @@
                 }
             };
 
+    private static final String TAG = "AndroidViewTest"; // 20 max characters
+    // TODO(crbug.com/949391): turn this off once we can get some details about flakes.
+    private static final boolean DEBUG = true;
     private static final int CONTENT_SIZE_CHANGE_STABILITY_TIMEOUT_MS = 1000;
 
     private static class OnContentSizeChangedHelper extends CallbackHelper {
+        final private Object mLock = new Object();
+        @GuardedBy("mLock")
         private int mWidth;
+        @GuardedBy("mLock")
         private int mHeight;
 
         public int getWidth() {
             assert getCallCount() > 0;
-            return mWidth;
+            synchronized (mLock) {
+                return mWidth;
+            }
         }
 
         public int getHeight() {
             assert getCallCount() > 0;
-            return mHeight;
+            synchronized (mLock) {
+                return mHeight;
+            }
         }
 
         public void onContentSizeChanged(int widthCss, int heightCss) {
-            mWidth = widthCss;
-            mHeight = heightCss;
+            synchronized (mLock) {
+                mWidth = widthCss;
+                mHeight = heightCss;
+            }
             notifyCalled();
         }
     }
@@ -223,16 +236,19 @@
     private void waitForContentSizeToChangeTo(OnContentSizeChangedHelper helper, int callCount,
             int widthCss, int heightCss) throws Exception {
         final int maxSizeChangeNotificationsToWaitFor = 5;
-        for (int i = 1; i <= maxSizeChangeNotificationsToWaitFor; i++) {
-            helper.waitForCallback(callCount, i);
+        for (int i = 0; i < maxSizeChangeNotificationsToWaitFor; i++) {
+            helper.waitForCallback(callCount + i);
+            if (DEBUG) {
+                Log.i(TAG,
+                        "i: " + i + ", height: " + helper.getHeight()
+                                + ", width: " + helper.getWidth());
+            }
             if ((heightCss == -1 || helper.getHeight() == heightCss)
                     && (widthCss == -1 || helper.getWidth() == widthCss)) {
-                break;
+                return;
             }
-            // This means that we hit the max number of iterations but the expected contents size
-            // wasn't reached.
-            assertNotEquals(i, maxSizeChangeNotificationsToWaitFor);
         }
+        Assert.fail("The expected contents size was not reached in max # of trials.");
     }
 
     private void loadPageOfSizeAndWaitForSizeChange(AwContents awContents,
@@ -294,6 +310,7 @@
                 + "</style>", "<div>a</div>");
 
         final int contentSizeChangeCallCount = mOnContentSizeChangedHelper.getCallCount();
+        Assert.assertEquals(0, contentSizeChangeCallCount);
         mActivityTestRule.loadDataAsync(
                 testContainerView.getAwContents(), htmlData, "text/html", false);
 
diff --git a/android_webview/tools/OWNERS b/android_webview/tools/OWNERS
new file mode 100644
index 0000000..57537f1
--- /dev/null
+++ b/android_webview/tools/OWNERS
@@ -0,0 +1,3 @@
+ntfschr@chromium.org
+
+# COMPONENT: Mobile>WebView
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java
index a80822a..93602b0 100644
--- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java
+++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java
@@ -509,12 +509,17 @@
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         getMenuInflater().inflate(R.menu.main_menu, menu);
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
+            menu.findItem(R.id.menu_enable_tracing).setEnabled(false);
+        }
         return true;
     }
 
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
-        menu.findItem(R.id.menu_enable_tracing).setChecked(mEnableTracing);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+            menu.findItem(R.id.menu_enable_tracing).setChecked(mEnableTracing);
+        }
         return true;
     }
 
@@ -539,6 +544,8 @@
             case R.id.menu_enable_tracing:
                 mEnableTracing = !mEnableTracing;
                 item.setChecked(mEnableTracing);
+
+                // TODO(laisminchillo): replace this with AndroidX's TracingController
                 TracingController tracingController = TracingController.getInstance();
                 if (mEnableTracing) {
                     tracingController.start(
diff --git a/ash/assistant/ui/assistant_web_view.cc b/ash/assistant/ui/assistant_web_view.cc
index a5fba4c..99bfd4c9 100644
--- a/ash/assistant/ui/assistant_web_view.cc
+++ b/ash/assistant/ui/assistant_web_view.cc
@@ -22,7 +22,6 @@
 #include "ui/display/screen.h"
 #include "ui/gfx/canvas.h"
 #include "ui/views/layout/box_layout.h"
-#include "ui/views/painter.h"
 #include "ui/views/widget/widget.h"
 
 namespace ash {
@@ -35,37 +34,6 @@
              : kMaxHeightDip;
 }
 
-// ContentsMaskPainter ---------------------------------------------------------
-
-class ContentsMaskPainter : public views::Painter {
- public:
-  ContentsMaskPainter() = default;
-  ~ContentsMaskPainter() override = default;
-
-  // views::Painter:
-  gfx::Size GetMinimumSize() const override { return gfx::Size(); }
-
-  void Paint(gfx::Canvas* canvas, const gfx::Size& size) override {
-    cc::PaintFlags flags;
-    flags.setAntiAlias(true);
-    flags.setColor(SK_ColorBLACK);
-
-    SkRRect rect;
-    rect.setRectRadii(
-        SkRect::MakeWH(size.width(), size.height()),
-        (const SkVector[]){
-            /*upper_left=*/SkVector::Make(0, 0),
-            /*upper_right=*/SkVector::Make(0, 0),
-            /*lower_right=*/SkVector::Make(kCornerRadiusDip, kCornerRadiusDip),
-            /*lower_left=*/SkVector::Make(kCornerRadiusDip, kCornerRadiusDip)});
-
-    canvas->sk_canvas()->drawRRect(rect, flags);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ContentsMaskPainter);
-};
-
 }  // namespace
 
 // AssistantWebView ------------------------------------------------------------
@@ -120,21 +88,6 @@
     contents_->FocusThroughTabTraversal(reverse);
 }
 
-void AssistantWebView::OnWindowBoundsChanged(aura::Window* window,
-                                             const gfx::Rect& old_bounds,
-                                             const gfx::Rect& new_bounds,
-                                             ui::PropertyChangeReason reason) {
-  // The mask layer should always match the bounds of the contents' native view.
-  contents_mask_->layer()->SetBounds(gfx::Rect(new_bounds.size()));
-}
-
-void AssistantWebView::OnWindowDestroying(aura::Window* window) {
-  // It's possible for |window| to be deleted before AssistantWebView. When this
-  // happens, we need to perform clean up on |window| before it is destroyed.
-  window->RemoveObserver(this);
-  window->layer()->SetMaskLayer(nullptr);
-}
-
 void AssistantWebView::InitLayout() {
   SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::Orientation::kVertical));
@@ -146,12 +99,6 @@
   if (app_list_features::IsEmbeddedAssistantUIEnabled())
     caption_bar_->SetButtonVisible(AssistantButtonId::kClose, false);
   AddChildView(caption_bar_);
-
-  // Contents mask.
-  // This is used to enforce corner radius on the contents' native view layer.
-  contents_mask_ = views::Painter::CreatePaintedLayer(
-      std::make_unique<ContentsMaskPainter>());
-  contents_mask_->layer()->SetFillsBoundsOpaquely(false);
 }
 
 bool AssistantWebView::OnCaptionButtonPressed(AssistantButtonId id) {
@@ -224,18 +171,10 @@
   AddChildView(contents_->GetView()->view());
   SetFocusBehavior(FocusBehavior::ALWAYS);
 
-  gfx::NativeView native_view = contents_->GetView()->native_view();
-
-  // We apply a layer mask to the contents' native view to enforce our desired
-  // corner radius. We need to sync the bounds of mask layer with the bounds
-  // of the native view prior to application to prevent DCHECK failure.
-  contents_mask_->layer()->SetBounds(
-      gfx::Rect(native_view->GetBoundsInScreen().size()));
-  native_view->layer()->SetMaskLayer(contents_mask_->layer());
-
-  // We observe |native_view| to ensure we keep the mask layer bounds in sync
-  // with the native view layer's bounds across size changes.
-  native_view->AddObserver(this);
+  // We need to clip the corners of our web contents to match our container.
+  contents_->GetView()->native_view()->layer()->SetRoundedCornerRadius(
+      {/*top_left=*/0, /*top_right=*/0, /*bottom_right=*/kCornerRadiusDip,
+       /*bottom_left=*/kCornerRadiusDip});
 }
 
 void AssistantWebView::DidSuppressNavigation(const GURL& url,
@@ -273,12 +212,6 @@
   if (!contents_)
     return;
 
-  gfx::NativeView native_view = contents_->GetView()->native_view();
-  if (native_view) {
-    native_view->RemoveObserver(this);
-    native_view->layer()->SetMaskLayer(nullptr);
-  }
-
   views::View* view = contents_->GetView()->view();
   if (view)
     RemoveChildView(view);
diff --git a/ash/assistant/ui/assistant_web_view.h b/ash/assistant/ui/assistant_web_view.h
index 1f0b466..37e14a41e 100644
--- a/ash/assistant/ui/assistant_web_view.h
+++ b/ash/assistant/ui/assistant_web_view.h
@@ -17,7 +17,6 @@
 #include "base/optional.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/content/public/cpp/navigable_contents.h"
-#include "ui/aura/window_observer.h"
 #include "ui/views/view.h"
 
 namespace ash {
@@ -31,7 +30,6 @@
 // Service.
 class COMPONENT_EXPORT(ASSISTANT_UI) AssistantWebView
     : public views::View,
-      public aura::WindowObserver,
       public AssistantViewDelegateObserver,
       public CaptionBarDelegate,
       public content::NavigableContentsObserver,
@@ -48,13 +46,6 @@
   void OnFocus() override;
   void AboutToRequestFocusFromTabTraversal(bool reverse) override;
 
-  // views::WindowObserver:
-  void OnWindowBoundsChanged(aura::Window* window,
-                             const gfx::Rect& old_bounds,
-                             const gfx::Rect& new_bounds,
-                             ui::PropertyChangeReason reason) override;
-  void OnWindowDestroying(aura::Window* window) override;
-
   // CaptionBarDelegate:
   bool OnCaptionButtonPressed(AssistantButtonId id) override;
 
@@ -88,12 +79,6 @@
   mojo::Remote<content::mojom::NavigableContentsFactory> contents_factory_;
   std::unique_ptr<content::NavigableContents> contents_;
 
-  // Our contents are drawn to a layer that is not masked by our widget's layer.
-  // This causes our contents to ignore the corner radius that we have set on
-  // the widget. To address this, we apply a separate layer mask to the
-  // contents' native view layer enforcing our desired corner radius.
-  std::unique_ptr<ui::LayerOwner> contents_mask_;
-
   base::WeakPtrFactory<AssistantWebView> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(AssistantWebView);
diff --git a/ash/public/cpp/ash_switches.cc b/ash/public/cpp/ash_switches.cc
index afcf31f7..6b95b9e 100644
--- a/ash/public/cpp/ash_switches.cc
+++ b/ash/public/cpp/ash_switches.cc
@@ -81,15 +81,6 @@
 const char kAshHideNotificationsForFactory[] =
     "ash-hide-notifications-for-factory";
 
-// The color scheme to be used.
-const char kAshShelfColorScheme[] = "ash-shelf-color-scheme";
-const char kAshShelfColorSchemeLightMuted[] = "light_muted";
-const char kAshShelfColorSchemeLightVibrant[] = "light_vibrant";
-const char kAshShelfColorSchemeNormalMuted[] = "normal_muted";
-const char kAshShelfColorSchemeNormalVibrant[] = "normal_vibrant";
-const char kAshShelfColorSchemeDarkMuted[] = "dark_muted";
-const char kAshShelfColorSchemeDarkVibrant[] = "dark_vibrant";
-
 // Enables the heads-up display for tracking touch points.
 const char kAshTouchHud[] = "ash-touch-hud";
 
diff --git a/ash/shelf/shelf_background_animator.cc b/ash/shelf/shelf_background_animator.cc
index 46c7599..68b18e2 100644
--- a/ash/shelf/shelf_background_animator.cc
+++ b/ash/shelf/shelf_background_animator.cc
@@ -30,28 +30,9 @@
 
 namespace {
 
-// Returns color profile used for shelf based on the kAshShelfColorScheme
-// command line arg.
+// Returns the color profile used for the shelf.
 ColorProfile GetShelfColorProfile() {
-  const std::string switch_value =
-      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-          switches::kAshShelfColorScheme);
-
-  ColorProfile color_profile(LumaRange::DARK, SaturationRange::MUTED);
-
-  if (switch_value.find("light") != std::string::npos)
-    color_profile.luma = LumaRange::LIGHT;
-  else if (switch_value.find("normal") != std::string::npos)
-    color_profile.luma = LumaRange::NORMAL;
-  else if (switch_value.find("dark") != std::string::npos)
-    color_profile.luma = LumaRange::DARK;
-
-  if (switch_value.find("vibrant") != std::string::npos)
-    color_profile.saturation = SaturationRange::VIBRANT;
-  else if (switch_value.find("muted") != std::string::npos)
-    color_profile.saturation = SaturationRange::MUTED;
-
-  return color_profile;
+  return ColorProfile(LumaRange::DARK, SaturationRange::MUTED);
 }
 
 }  // namespace
diff --git a/ash/system/unified/feature_pod_button.cc b/ash/system/unified/feature_pod_button.cc
index 4d072b6..64e30584 100644
--- a/ash/system/unified/feature_pod_button.cc
+++ b/ash/system/unified/feature_pod_button.cc
@@ -21,6 +21,7 @@
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/box_layout.h"
+#include "ui/views/view_class_properties.h"
 
 namespace ash {
 
@@ -40,6 +41,10 @@
   SetBorder(views::CreateEmptyBorder(kUnifiedFeaturePodIconPadding));
   SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
   TrayPopupUtils::ConfigureTrayPopupButton(this);
+
+  auto path = std::make_unique<SkPath>();
+  path->addOval(gfx::RectToSkRect(gfx::Rect(kUnifiedFeaturePodIconSize)));
+  SetProperty(views::kHighlightPathKey, path.release());
 }
 
 FeaturePodIconButton::~FeaturePodIconButton() = default;
@@ -130,6 +135,8 @@
 FeaturePodLabelButton::~FeaturePodLabelButton() = default;
 
 void FeaturePodLabelButton::Layout() {
+  DCHECK(focus_ring());
+  focus_ring()->Layout();
   LayoutInCenter(label_, GetContentsBounds().y());
   LayoutInCenter(sub_label_, GetContentsBounds().CenterPoint().y());
 
diff --git a/build/android/gyp/desugar.py b/build/android/gyp/desugar.py
index 656e4b3..b9d04059 100755
--- a/build/android/gyp/desugar.py
+++ b/build/android/gyp/desugar.py
@@ -14,6 +14,7 @@
 def main():
   args = build_utils.ExpandFileArgs(sys.argv[1:])
   parser = argparse.ArgumentParser()
+  build_utils.AddDepfileOption(parser)
   parser.add_argument('--desugar-jar', required=True,
                       help='Path to Desugar.jar.')
   parser.add_argument('--input-jar', required=True,
@@ -47,6 +48,13 @@
     cmd += ['--classpath_entry', path]
   build_utils.CheckOutput(cmd, print_stdout=False)
 
+  if options.depfile:
+    build_utils.WriteDepfile(
+        options.depfile,
+        options.output_jar,
+        inputs=options.bootclasspath + options.classpath,
+        add_pydeps=False)
+
 
 if __name__ == '__main__':
   sys.exit(main())
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index d591271d..9c9031c 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -1649,6 +1649,7 @@
       action_with_pydeps(_desugar_target) {
         script = "//build/android/gyp/desugar.py"
         deps = _deps
+        depfile = "$target_gen_dir/$target_name.d"
         if (defined(invoker.deps)) {
           deps += invoker.deps
         }
@@ -1674,6 +1675,8 @@
           # is implemented, see http://crbug.com/885273
           "--classpath=@FileArg($_rebased_build_config:deps_info:javac_full_interface_classpath)",
           "--bootclasspath=@FileArg($_rebased_build_config:android:sdk_interface_jars)",
+          "--depfile",
+          rebase_path(depfile, root_build_dir),
         ]
       }
 
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index aab9de73..83108887 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -961,6 +961,7 @@
   "java/src/org/chromium/chrome/browser/notifications/ChromeNotification.java",
   "java/src/org/chromium/chrome/browser/notifications/ChromeNotificationBuilder.java",
   "java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java",
+  "java/src/org/chromium/chrome/browser/notifications/ForegroundServiceUtils.java",
   "java/src/org/chromium/chrome/browser/notifications/NotificationBuilder.java",
   "java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java",
   "java/src/org/chromium/chrome/browser/notifications/NotificationBuilderFactory.java",
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
index 402ee196..d202496 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.tasks.tab_management;
 
 import android.content.Context;
+import android.content.res.Configuration;
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
@@ -104,8 +105,11 @@
         mRecyclerView.setAdapter(adapter);
 
         if (mMode == TabListMode.GRID) {
-            mRecyclerView.setLayoutManager(
-                    new GridLayoutManager(context, GRID_LAYOUT_SPAN_COUNT_PORTRAIT));
+            mRecyclerView.setLayoutManager(new GridLayoutManager(context,
+                    context.getResources().getConfiguration().orientation
+                                    == Configuration.ORIENTATION_PORTRAIT
+                            ? GRID_LAYOUT_SPAN_COUNT_PORTRAIT
+                            : GRID_LAYOUT_SPAN_COUNT_LANDSCAPE));
         } else if (mMode == TabListMode.STRIP) {
             mRecyclerView.setLayoutManager(
                     new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
diff --git a/chrome/android/java/res/layout/permission_dialog.xml b/chrome/android/java/res/layout/permission_dialog.xml
index cd44504..51189b5 100644
--- a/chrome/android/java/res/layout/permission_dialog.xml
+++ b/chrome/android/java/res/layout/permission_dialog.xml
@@ -4,17 +4,19 @@
      found in the LICENSE file.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:orientation="vertical"
     android:gravity="start"
-    style="@style/AlertDialogContent" >
+    style="@style/AlertDialogContent">
 
-    <TextView
+    <org.chromium.chrome.browser.widget.TextViewWithCompoundDrawables
         android:id="@+id/text"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:gravity="center_vertical"
         android:textDirection="locale"
-        android:textSize="@dimen/dialog_text_size"
         android:paddingBottom="24dp"
-        android:drawablePadding="8dp" />
+        android:drawablePadding="8dp"
+        android:textAppearance="@style/TextAppearance.BlackBody"
+        app:chromeDrawableTint="@color/default_icon_color_blue" />
 </LinearLayout>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index b5db1203..ef4a8765 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -497,7 +497,6 @@
          https://www.google.com/design/spec/components/dialogs.html#dialogs-simple-dialogs -->
     <dimen name="dialog_width_unit">56dp</dimen>  <!-- MD dialog widths are multiples of this. -->
     <dimen name="dialog_header_margin">14dp</dimen>
-    <dimen name="dialog_text_size">14sp</dimen>
     <dimen name="separator_height">1dp</dimen>
 
     <!-- Modern List Item dimensions -->
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
index 7a73854..fbe14aa 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
@@ -11,7 +11,6 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.support.annotation.Nullable;
-import android.support.v4.content.ContextCompat;
 import android.view.View;
 
 import com.google.android.gms.common.ConnectionResult;
@@ -284,18 +283,8 @@
     }
 
     /**
-     * Starts a service from {@code intent} with the expectation that it will make itself a
-     * foreground service with {@link android.app.Service#startForeground(int, Notification)}.
-     *
-     * @param intent The {@link Intent} to fire to start the service.
-     */
-    public void startForegroundService(Intent intent) {
-        ContextCompat.startForegroundService(ContextUtils.getApplicationContext(), intent);
-    }
-
-    /**
      * Upgrades a service from background to foreground after calling
-     * {@link #startForegroundService(Intent)}.
+     * {@link Service#startForegroundService(Intent)}.
      * @param service The service to be foreground.
      * @param id The notification id.
      * @param notification The notification attached to the foreground service.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsService.java b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsService.java
index aa04dfe..c8cbe8b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsService.java
@@ -20,12 +20,12 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.AppHooks;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.notifications.ChromeNotification;
 import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder;
+import org.chromium.chrome.browser.notifications.ForegroundServiceUtils;
 import org.chromium.chrome.browser.notifications.NotificationBuilderFactory;
 import org.chromium.chrome.browser.notifications.NotificationConstants;
 import org.chromium.chrome.browser.notifications.NotificationMetadata;
@@ -234,7 +234,7 @@
         ChromeNotification notification =
                 createNotificationBuilder(isUpdate, tabId).buildChromeNotification();
 
-        AppHooks.get().startForeground(this, notification.getMetadata().id,
+        ForegroundServiceUtils.getInstance().startForeground(this, notification.getMetadata().id,
                 notification.getNotification(), 0 /* foregroundServiceType */);
 
         if (!isUpdate) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java
index d1599e3a..b6ed513 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java
@@ -384,8 +384,7 @@
      * @return The visibility percentage for the divider line ranging from 0.f to 1.f.
      */
     public float getDividerLineVisibilityPercentage() {
-        return mContextualSearchPanel.useGenericSheetUx() ? DIVIDER_LINE_OPACITY_GENERIC
-                                                          : mDividerLineVisibilityPercentage;
+        return mDividerLineVisibilityPercentage;
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
index bb50c39..c50cd5da 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -62,13 +62,6 @@
     private ContextualSearchSceneLayer mSceneLayer;
 
     /**
-     * Whether to use the Generic Sheet UX.
-     * This activates the closebox in the peeking Bar, and may someday do more,
-     * e.g. swipe-closed behavior.  See crbug.com/831783 for details.
-     */
-    private boolean mUseGenericSheetUx;
-
-    /**
      * A ScrimView for adjusting the Status Bar's brightness when a scrim is present (when the panel
      * is open).
      */
@@ -105,12 +98,6 @@
     }
 
     @Override
-    protected void initializeUiState() {
-        mUseGenericSheetUx = false;
-        // TODO(crbug.com/831783): Clean up this code.
-    }
-
-    @Override
     public OverlayPanelContent createNewOverlayPanelContent() {
         return new OverlayPanelContent(mManagementDelegate.getOverlayContentDelegate(),
                 new PanelProgressObserver(), mActivity, /* isIncognito= */ false, getBarHeight());
@@ -277,9 +264,7 @@
         getSearchBarControl().onSearchBarClick(x);
 
         if (isPeeking()) {
-            if (useGenericSheetUx() && isCoordinateInsideCloseButton(x)) {
-                closePanel(StateChangeReason.CLOSE_BUTTON, true);
-            } else if (getSearchBarControl().getQuickActionControl().hasQuickAction()
+            if (getSearchBarControl().getQuickActionControl().hasQuickAction()
                     && isCoordinateInsideActionTarget(x)) {
                 mPanelMetrics.setWasQuickActionClicked();
                 getSearchBarControl().getQuickActionControl().sendIntent(
@@ -723,33 +708,6 @@
         }
     }
 
-    @Override
-    public float getArrowIconOpacity() {
-        if (useGenericSheetUx()) {
-            return ARROW_ICON_OPACITY_GENERIC_UX;
-        } else {
-            return super.getArrowIconOpacity();
-        }
-    }
-
-    @Override
-    public float getCloseIconOpacity() {
-        if (useGenericSheetUx()) {
-            return CLOSE_ICON_OPACITY_GENERIC_UX;
-        } else {
-            return super.getCloseIconOpacity();
-        }
-    }
-
-    /**
-     * Whether the UX should match the generic sheet UX used by the generic assistive surface.
-     * TODO(crbug.com/831783) remove when the generic sheet UX is the default.
-     * @return Whether to apply the generic UX, rather than the legacy Contextual Search UX.
-     */
-    boolean useGenericSheetUx() {
-        return mUseGenericSheetUx;
-    }
-
     // ============================================================================================
     // Selection position
     // ============================================================================================
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundService.java
index c4cc5f75..e6f03a4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundService.java
@@ -21,7 +21,7 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.base.VisibleForTesting;
-import org.chromium.chrome.browser.AppHooks;
+import org.chromium.chrome.browser.notifications.ForegroundServiceUtils;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -60,7 +60,8 @@
      */
     public static void startDownloadForegroundService(Context context) {
         // TODO(crbug.com/770389): Grab a WakeLock here until the service has started.
-        AppHooks.get().startForegroundService(new Intent(context, DownloadForegroundService.class));
+        ForegroundServiceUtils.getInstance().startForegroundService(
+                new Intent(context, DownloadForegroundService.class));
     }
 
     /**
@@ -241,7 +242,7 @@
     @VisibleForTesting
     void startForegroundInternal(int notificationId, Notification notification) {
         Log.w(TAG, "startForegroundInternal id: " + notificationId);
-        AppHooks.get().startForeground(
+        ForegroundServiceUtils.getInstance().startForeground(
                 this, notificationId, notification, 0 /* foregroundServiceType */);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
index a299ea4..385dd58 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
@@ -8,7 +8,6 @@
 import static org.chromium.chrome.browser.download.DownloadSnackbarController.INVALID_NOTIFICATION_ID;
 
 import android.app.Notification;
-import android.app.NotificationManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -29,6 +28,8 @@
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.library_loader.LibraryProcessType;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.notifications.NotificationManagerProxy;
+import org.chromium.chrome.browser.notifications.NotificationManagerProxyImpl;
 import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.util.FeatureUtilities;
@@ -94,7 +95,7 @@
     @VisibleForTesting
     final List<ContentId> mDownloadsInProgress = new ArrayList<ContentId>();
 
-    private NotificationManager mNotificationManager;
+    private NotificationManagerProxy mNotificationManager;
     private Bitmap mDownloadSuccessLargeIcon;
     private DownloadSharedPreferenceHelper mDownloadSharedPreferenceHelper;
     private DownloadForegroundServiceManager mDownloadForegroundServiceManager;
@@ -114,8 +115,7 @@
     @VisibleForTesting
     DownloadNotificationService() {
         mNotificationManager =
-                (NotificationManager) ContextUtils.getApplicationContext().getSystemService(
-                        Context.NOTIFICATION_SERVICE);
+                new NotificationManagerProxyImpl(ContextUtils.getApplicationContext());
         mDownloadSharedPreferenceHelper = DownloadSharedPreferenceHelper.getInstance();
         mDownloadForegroundServiceManager = new DownloadForegroundServiceManager();
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java
index fef3686..7d8c981 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java
@@ -338,7 +338,7 @@
     }
 
     private void onRenameItem(OfflineItem item) {
-        // TODO(hesen): Add uma stats.
+        UmaUtils.recordItemAction(ViewAction.MENU_RENAME);
         mRenameController.rename(item.title, (newName, renameCallback) -> {
             mProvider.renameItem(item, newName, renameCallback);
         });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java
index 37a5c6a..f17ced2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java
@@ -40,7 +40,7 @@
     // Please treat this list as append only and keep it in sync with
     // Android.DownloadManager.List.View.Actions in enums.xml.
     @IntDef({ViewAction.OPEN, ViewAction.RESUME, ViewAction.PAUSE, ViewAction.CANCEL,
-            ViewAction.MENU_SHARE, ViewAction.MENU_DELETE, ViewAction.RETRY})
+            ViewAction.MENU_SHARE, ViewAction.MENU_DELETE, ViewAction.RETRY, ViewAction.MENU_RENAME})
     @Retention(RetentionPolicy.SOURCE)
     public @interface ViewAction {
         int OPEN = 0;
@@ -50,7 +50,8 @@
         int MENU_SHARE = 4;
         int MENU_DELETE = 5;
         int RETRY = 6;
-        int NUM_ENTRIES = 7;
+        int MENU_RENAME = 7;
+        int NUM_ENTRIES = 8;
     }
 
     // Please treat this list as append only and keep it in sync with
@@ -121,6 +122,9 @@
             case ViewAction.RETRY:
                 userActionSuffix = "Retry";
                 break;
+            case ViewAction.MENU_RENAME:
+                userActionSuffix = "MenuRename";
+                break;
             default:
                 assert false : "Unexpected action " + action + " passed to recordItemAction.";
                 return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java
index d2a085ad..437468f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java
@@ -10,7 +10,7 @@
 import android.view.KeyEvent;
 
 import org.chromium.base.Log;
-import org.chromium.chrome.browser.AppHooks;
+import org.chromium.chrome.browser.notifications.ForegroundServiceUtils;
 
 /**
  * MediaButtonReceiver is a basic BroadcastReceiver class that receives
@@ -40,6 +40,6 @@
         }
 
         intent.setClass(context, getServiceClass());
-        AppHooks.get().startForegroundService(intent);
+        ForegroundServiceUtils.getInstance().startForegroundService(intent);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
index ea13439..6202f28 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
@@ -40,10 +40,10 @@
 import org.chromium.base.SysUtils;
 import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.AppHooks;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.notifications.ChromeNotification;
 import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder;
+import org.chromium.chrome.browser.notifications.ForegroundServiceUtils;
 import org.chromium.chrome.browser.notifications.NotificationBuilderFactory;
 import org.chromium.chrome.browser.notifications.NotificationConstants;
 import org.chromium.chrome.browser.notifications.NotificationManagerProxy;
@@ -293,7 +293,7 @@
                 NotificationBuilderFactory.createChromeNotificationBuilder(true /* preferCompat */,
                         ChannelDefinitions.ChannelId.MEDIA, null /* remoteAppPackageName */,
                         metadata);
-        AppHooks.get().startForeground(s, s.getNotificationId(),
+        ForegroundServiceUtils.getInstance().startForeground(s, s.getNotificationId(),
                 builder.buildChromeNotification().getNotification(), 0 /* foregroundServiceType */);
     }
 
@@ -851,7 +851,7 @@
         if (mService == null) {
             updateMediaSession();
             updateNotificationBuilder();
-            AppHooks.get().startForegroundService(createIntent());
+            ForegroundServiceUtils.getInstance().startForegroundService(createIntent());
         } else {
             updateNotification(false, false);
         }
@@ -939,7 +939,9 @@
         // crash Chrome.
         boolean foregroundedService = false;
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && serviceStarting) {
-            mService.startForeground(mMediaNotificationInfo.id, notification.getNotification());
+            ForegroundServiceUtils.getInstance().startForeground(mService,
+                    mMediaNotificationInfo.id, notification.getNotification(),
+                    0 /*foregroundServiceType*/);
             foregroundedService = true;
         }
 
@@ -953,7 +955,9 @@
             NotificationManagerProxy manager = new NotificationManagerProxyImpl(getContext());
             manager.notify(notification);
         } else if (!foregroundedService) {
-            mService.startForeground(mMediaNotificationInfo.id, notification.getNotification());
+            ForegroundServiceUtils.getInstance().startForeground(mService,
+                    mMediaNotificationInfo.id, notification.getNotification(),
+                    0 /*foregroundServiceType*/);
         }
         if (shouldLogNotification) {
             mNotificationUmaTracker.onNotificationShown(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/ForegroundServiceUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/ForegroundServiceUtils.java
new file mode 100644
index 0000000..666ac36
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/ForegroundServiceUtils.java
@@ -0,0 +1,70 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.notifications;
+
+import android.app.Notification;
+import android.app.Service;
+import android.content.Intent;
+import android.support.v4.content.ContextCompat;
+
+import org.chromium.base.ContextUtils;
+import org.chromium.base.VisibleForTesting;
+import org.chromium.chrome.browser.AppHooks;
+
+/**
+ * Utility functions that call into Android foreground service related API, and provides
+ * compatibility for older Android versions and work around for Android API bugs.
+ */
+public class ForegroundServiceUtils {
+    private ForegroundServiceUtils() {}
+
+    /**
+     * Gets the singleton instance of ForegroundServiceUtils.
+     */
+    public static ForegroundServiceUtils getInstance() {
+        return ForegroundServiceUtils.LazyHolder.sInstance;
+    }
+
+    /**
+     * Sets a mocked instance for testing.
+     */
+    @VisibleForTesting
+    public static void setInstanceForTesting(ForegroundServiceUtils instance) {
+        ForegroundServiceUtils.LazyHolder.sInstance = instance;
+    }
+
+    private static class LazyHolder {
+        private static ForegroundServiceUtils sInstance = new ForegroundServiceUtils();
+    }
+
+    /**
+     * Starts a service from {@code intent} with the expectation that it will make itself a
+     * foreground service with {@link android.app.Service#startForeground(int, Notification)}.
+     *
+     * @param intent The {@link Intent} to fire to start the service.
+     */
+    public void startForegroundService(Intent intent) {
+        ContextCompat.startForegroundService(ContextUtils.getApplicationContext(), intent);
+    }
+
+    /**
+     * Upgrades a service from background to foreground after calling
+     * {@link #startForegroundService(Intent)}.
+     * @param service The service to be foreground.
+     * @param id The notification id.
+     * @param notification The notification attached to the foreground service.
+     * @param foregroundServiceType The type of foreground service. Must be a subset of the
+     *                              foreground service types defined in AndroidManifest.xml.
+     *                              Use 0 if no foregroundServiceType attribute is defined.
+     */
+    public void startForeground(
+            Service service, int id, Notification notification, int foregroundServiceType) {
+        // If android fail to build the notification, do nothing.
+        if (notification == null) return;
+
+        // TODO(xingliu): Remove startForeground call from AppHooks when Q sdk is available.
+        AppHooks.get().startForeground(service, id, notification, foregroundServiceType);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
index 7335918..b670f3a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -1036,7 +1036,8 @@
         }
 
         mStatusViewCoordinator.setUseDarkColors(useDarkColors);
-        mAutocompleteCoordinator.updateVisualsForState(useDarkColors);
+        mAutocompleteCoordinator.updateVisualsForState(
+                useDarkColors, mToolbarDataProvider.isIncognito());
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
index 50828d44..a77cf3d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
@@ -339,9 +339,10 @@
     /**
      * Update the visuals of the autocomplete UI.
      * @param useDarkColors Whether dark colors should be applied to the UI.
+     * @param isIncognito Whether the UI is for incognito mode or not.
      */
-    public void updateVisualsForState(boolean useDarkColors) {
-        mMediator.setUseDarkColors(useDarkColors);
+    public void updateVisualsForState(boolean useDarkColors, boolean isIncognito) {
+        mMediator.updateVisualsForState(useDarkColors, isIncognito);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
index 3a52b13..3b9f00f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -266,10 +266,11 @@
     /**
      * Specifies the visual state to be used by the suggestions.
      * @param useDarkColors Whether dark colors should be used for fonts and icons.
+     * @param isIncognito Whether the UI is for incognito mode or not.
      */
-    void setUseDarkColors(boolean useDarkColors) {
+    void updateVisualsForState(boolean useDarkColors, boolean isIncognito) {
         mUseDarkColors = useDarkColors;
-        mListPropertyModel.set(SuggestionListProperties.USE_DARK_BACKGROUND, !useDarkColors);
+        mListPropertyModel.set(SuggestionListProperties.IS_INCOGNITO, isIncognito);
         for (int i = 0; i < mCurrentModels.size(); i++) {
             PropertyModel model = mCurrentModels.get(i).model;
             model.set(SuggestionCommonProperties.USE_DARK_COLORS, useDarkColors);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsList.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsList.java
index 71f4014..0cc8da64 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsList.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsList.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.omnibox.suggestions;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
@@ -20,6 +21,7 @@
 import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.WindowDelegate;
+import org.chromium.chrome.browser.util.ColorUtils;
 import org.chromium.chrome.browser.util.KeyNavigationUtil;
 import org.chromium.chrome.browser.util.ViewUtils;
 
@@ -30,11 +32,10 @@
  */
 @VisibleForTesting
 public class OmniboxSuggestionsList extends ListView {
-    private static final int LIGHT_BG_COLOR = 0xFFFFFFFF;
-    private static final int DARK_BG_COLOR = 0xFF3C4043;
-
     private final int[] mTempPosition = new int[2];
     private final Rect mTempRect = new Rect();
+    private final int mStandardBgColor;
+    private final int mIncognitoBgColor;
 
     private OmniboxSuggestionListEmbedder mEmbedder;
     private View mAnchorView;
@@ -74,8 +75,11 @@
         setFocusable(true);
         setFocusableInTouchMode(true);
 
-        int paddingBottom = context.getResources().getDimensionPixelOffset(
-                R.dimen.omnibox_suggestion_list_padding_bottom);
+        final Resources resources = context.getResources();
+        mStandardBgColor = ColorUtils.getDefaultThemeColor(resources, false);
+        mIncognitoBgColor = ColorUtils.getDefaultThemeColor(resources, true);
+        int paddingBottom =
+                resources.getDimensionPixelOffset(R.dimen.omnibox_suggestion_list_padding_bottom);
         ViewCompat.setPaddingRelative(this, 0, 0, 0, paddingBottom);
     }
 
@@ -143,8 +147,8 @@
     /**
      * Update the suggestion popup background to reflect the current state.
      */
-    void refreshPopupBackground(boolean useDarkBackground) {
-        int color = useDarkBackground ? DARK_BG_COLOR : LIGHT_BG_COLOR;
+    void refreshPopupBackground(boolean isIncognito) {
+        int color = isIncognito ? mIncognitoBgColor : mStandardBgColor;
         if (!isHardwareAccelerated()) {
             // When HW acceleration is disabled, changing mSuggestionList' items somehow erases
             // mOmniboxResultsContainer' background from the area not covered by mSuggestionList.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java
index ca80a402..e6f7b9f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java
@@ -30,9 +30,8 @@
             SUGGESTION_MODELS = new WritableObjectPropertyKey<>(true);
 
     /** Whether the suggestion list should have a dark background. */
-    public static final WritableBooleanPropertyKey USE_DARK_BACKGROUND =
-            new WritableBooleanPropertyKey();
+    public static final WritableBooleanPropertyKey IS_INCOGNITO = new WritableBooleanPropertyKey();
 
     public static final PropertyKey[] ALL_KEYS =
-            new PropertyKey[] {VISIBLE, EMBEDDER, SUGGESTION_MODELS, USE_DARK_BACKGROUND};
+            new PropertyKey[] {VISIBLE, EMBEDDER, SUGGESTION_MODELS, IS_INCOGNITO};
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java
index 1405cb2..7fa3738 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java
@@ -55,9 +55,8 @@
         } else if (SuggestionListProperties.SUGGESTION_MODELS.equals(propertyKey)) {
             view.adapter.updateModels(model.get(SuggestionListProperties.SUGGESTION_MODELS));
             view.listView.setSelection(0);
-        } else if (SuggestionListProperties.USE_DARK_BACKGROUND.equals(propertyKey)) {
-            view.listView.refreshPopupBackground(
-                    model.get(SuggestionListProperties.USE_DARK_BACKGROUND));
+        } else if (SuggestionListProperties.IS_INCOGNITO.equals(propertyKey)) {
+            view.listView.refreshPopupBackground(model.get(SuggestionListProperties.IS_INCOGNITO));
         }
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webshare/BlobReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/webshare/BlobReceiver.java
index a8c6c6c8..2e8bbf7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webshare/BlobReceiver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webshare/BlobReceiver.java
@@ -76,7 +76,7 @@
     @Override
     public void onConnectionError(MojoException e) {
         if (mCallback == null) return;
-        reportError(MojoResult.INTERNAL, "Connection error detected.");
+        reportError(e.getMojoResult(), "Connection error detected.");
     }
 
     // BlobReaderClient
@@ -109,7 +109,10 @@
 
     // BlobReaderClient
     @Override
-    public void onComplete(int status, long dataLength) {}
+    public void onComplete(int status, long dataLength) {
+        if (mCallback == null) return;
+        read();
+    }
 
     private void read() {
         try {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationActionsUpdatedTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationActionsUpdatedTest.java
index 21c8fc0..47ef65b 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationActionsUpdatedTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationActionsUpdatedTest.java
@@ -48,7 +48,9 @@
 
         getManager().mThrottler.mManager = getManager();
         doCallRealMethod().when(getManager()).onServiceStarted(any(ListenerService.class));
-        doCallRealMethod().when(mMockAppHooks).startForegroundService(any(Intent.class));
+        doCallRealMethod()
+                .when(mMockForegroundServiceUtils)
+                .startForegroundService(any(Intent.class));
         mTabHolder = new MediaNotificationTestTabHolder(TAB_ID_1, "about:blank", "title1");
     }
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationFaviconTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationFaviconTest.java
index d8a0b74..98210ef 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationFaviconTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationFaviconTest.java
@@ -76,7 +76,9 @@
 
         getManager().mThrottler.mManager = getManager();
         doCallRealMethod().when(getManager()).onServiceStarted(any(ListenerService.class));
-        doCallRealMethod().when(mMockAppHooks).startForegroundService(any(Intent.class));
+        doCallRealMethod()
+                .when(mMockForegroundServiceUtils)
+                .startForegroundService(any(Intent.class));
         mTabHolder = new MediaNotificationTestTabHolder(TAB_ID_1, "about:blank", "title1");
     }
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerServiceLifecycleTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerServiceLifecycleTest.java
index 18fee49..f7118fb 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerServiceLifecycleTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerServiceLifecycleTest.java
@@ -110,7 +110,7 @@
 
         verify(getManager()).showNotification(newInfo);
         verifyNoMoreInteractions(getManager());
-        verify(mMockAppHooks, never()).startForegroundService(any(Intent.class));
+        verify(mMockForegroundServiceUtils, never()).startForegroundService(any(Intent.class));
         verify(mMockContext, never()).startService(any(Intent.class));
         verify(mMockUmaTracker, never()).onNotificationShown(anyInt(), any(Notification.class));
     }
@@ -127,7 +127,7 @@
 
         verify(getManager()).showNotification(newInfo);
         verifyNoMoreInteractions(getManager());
-        verify(mMockAppHooks, never()).startForegroundService(any(Intent.class));
+        verify(mMockForegroundServiceUtils, never()).startForegroundService(any(Intent.class));
         verify(mMockContext, never()).startService(any(Intent.class));
         verify(mMockUmaTracker, never()).onNotificationShown(anyInt(), any(Notification.class));
     }
@@ -140,7 +140,7 @@
         verify(getManager(), times(1)).updateMediaSession();
         verify(getManager(), times(1)).updateNotificationBuilder();
         verify(mMockContext, never()).startService(any(Intent.class));
-        verify(mMockAppHooks, times(1)).startForegroundService(any(Intent.class));
+        verify(mMockForegroundServiceUtils, times(1)).startForegroundService(any(Intent.class));
         verify(getManager(), never()).updateNotification(anyBoolean(), eq(false));
     }
 
@@ -154,7 +154,7 @@
         getManager().showNotification(newInfo);
 
         verify(getManager()).showNotification(newInfo);
-        verify(mMockAppHooks, never()).startForegroundService(any(Intent.class));
+        verify(mMockForegroundServiceUtils, never()).startForegroundService(any(Intent.class));
         verify(mMockContext, never()).startService(any(Intent.class));
         verify(getManager()).updateNotification(anyBoolean(), eq(false));
         verify(mMockUmaTracker, never()).onNotificationShown(anyInt(), any(Notification.class));
@@ -169,12 +169,13 @@
         MediaNotificationInfo oldInfo = mMediaNotificationInfoBuilder.build();
         getManager().showNotification(oldInfo);
 
-        InOrder order = inOrder(getManager(), mMockAppHooks);
+        InOrder order = inOrder(getManager(), mMockForegroundServiceUtils);
 
         assertEquals(oldInfo, getManager().mMediaNotificationInfo);
         order.verify(getManager(), times(1)).updateMediaSession();
         order.verify(getManager(), times(1)).updateNotificationBuilder();
-        order.verify(mMockAppHooks, times(1)).startForegroundService(any(Intent.class));
+        order.verify(mMockForegroundServiceUtils, times(1))
+                .startForegroundService(any(Intent.class));
         order.verify(getManager(), never()).updateNotification(anyBoolean(), eq(false));
 
         // The second call to |showNotification()| should only update the notification info.
@@ -185,7 +186,8 @@
         assertEquals(newInfo, getManager().mMediaNotificationInfo);
         order.verify(getManager(), times(1)).updateMediaSession();
         order.verify(getManager(), times(1)).updateNotificationBuilder();
-        order.verify(mMockAppHooks, times(1)).startForegroundService(any(Intent.class));
+        order.verify(mMockForegroundServiceUtils, times(1))
+                .startForegroundService(any(Intent.class));
         order.verify(getManager(), never()).updateNotification(anyBoolean(), eq(false));
 
         verify(getManager(), never()).onServiceStarted(any(ListenerService.class));
@@ -244,7 +246,9 @@
         getManager().mMediaNotificationInfo = mMediaNotificationInfoBuilder.build();
         getManager().updateNotification(false, false);
 
-        verify(mService).startForeground(eq(getNotificationId()), any(Notification.class));
+        verify(mMockForegroundServiceUtils)
+                .startForeground(
+                        eq(mService), eq(getNotificationId()), any(Notification.class), eq(0));
     }
 
     @Test
@@ -255,7 +259,9 @@
         getManager().mMediaNotificationInfo = mMediaNotificationInfoBuilder.build();
         getManager().updateNotification(false, false);
 
-        verify(mService).startForeground(eq(getNotificationId()), any(Notification.class));
+        verify(mMockForegroundServiceUtils)
+                .startForeground(
+                        eq(mService), eq(getNotificationId()), any(Notification.class), eq(0));
     }
 
     private ShadowNotificationManager getShadowNotificationManager() {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerTestBase.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerTestBase.java
index 02564ce..5ea143d 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerTestBase.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerTestBase.java
@@ -34,9 +34,9 @@
 import org.chromium.base.CommandLine;
 import org.chromium.base.ContextUtils;
 import org.chromium.chrome.browser.AppHooks;
-import org.chromium.chrome.browser.AppHooksImpl;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.media.ui.MediaNotificationManager.ListenerService;
+import org.chromium.chrome.browser.notifications.ForegroundServiceUtils;
 import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
 import org.chromium.services.media_session.MediaMetadata;
 
@@ -53,7 +53,7 @@
     Context mMockContext;
     MockListenerService mService;
     MediaNotificationListener mListener;
-    AppHooksImpl mMockAppHooks;
+    ForegroundServiceUtils mMockForegroundServiceUtils;
     NotificationUmaTracker mMockUmaTracker;
 
     MediaNotificationInfo.Builder mMediaNotificationInfoBuilder;
@@ -135,8 +135,8 @@
                 .when(mMockContext)
                 .startService(any(Intent.class));
 
-        mMockAppHooks = mock(AppHooksImpl.class);
-        AppHooks.setInstanceForTesting(mMockAppHooks);
+        mMockForegroundServiceUtils = mock(ForegroundServiceUtils.class);
+        ForegroundServiceUtils.setInstanceForTesting(mMockForegroundServiceUtils);
 
         // Init the command line to avoid assertion failure in |SysUtils#isLowEndDevice()|.
         CommandLine.init(null);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationTitleUpdatedTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationTitleUpdatedTest.java
index 888e5c4..9021c7a 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationTitleUpdatedTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationTitleUpdatedTest.java
@@ -51,7 +51,9 @@
 
         getManager().mThrottler.mManager = getManager();
         doCallRealMethod().when(getManager()).onServiceStarted(any(ListenerService.class));
-        doCallRealMethod().when(mMockAppHooks).startForegroundService(any(Intent.class));
+        doCallRealMethod()
+                .when(mMockForegroundServiceUtils)
+                .startForegroundService(any(Intent.class));
         mTabHolder = new MediaNotificationTestTabHolder(TAB_ID_1, "about:blank", "title1");
     }
 
diff --git a/chrome/android/touchless/java/res/drawable/suggestion_tile.xml b/chrome/android/touchless/java/res/drawable/suggestion_tile.xml
new file mode 100644
index 0000000..9ae6fed
--- /dev/null
+++ b/chrome/android/touchless/java/res/drawable/suggestion_tile.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/tile_view_icon_focused" android:state_focused="true"/>
+</selector>
\ No newline at end of file
diff --git a/chrome/android/touchless/java/res/drawable/tile_view_icon_focused.xml b/chrome/android/touchless/java/res/drawable/tile_view_icon_focused.xml
new file mode 100644
index 0000000..a19a724
--- /dev/null
+++ b/chrome/android/touchless/java/res/drawable/tile_view_icon_focused.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <stroke android:width="@dimen/most_likely_tile_focus_stroke_width" android:color="@color/light_active_color"/>
+</shape>
\ No newline at end of file
diff --git a/chrome/android/touchless/java/res/layout/most_likely_touchless.xml b/chrome/android/touchless/java/res/layout/most_likely_touchless.xml
index 8ab76e7..18409af 100644
--- a/chrome/android/touchless/java/res/layout/most_likely_touchless.xml
+++ b/chrome/android/touchless/java/res/layout/most_likely_touchless.xml
@@ -7,7 +7,7 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:layout_marginVertical="@dimen/most_likely_carousel_vertical_spacer"
+    android:paddingVertical="@dimen/most_likely_carousel_edge_spacer"
     android:gravity="center_horizontal">
 
     <android.support.v7.widget.RecyclerView
@@ -16,7 +16,6 @@
         android:scrollbars="none"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginBottom="@dimen/most_likely_carousel_edge_spacer"
         android:orientation="horizontal" />
 
     <TextView
@@ -24,6 +23,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:gravity="center"
-        android:textAppearance="@style/TextAppearance.BlackTitle2" />
+        android:textAppearance="@style/TextAppearance.BlackTitle2"
+        android:maxLines="1"/>
 
 </LinearLayout>
\ No newline at end of file
diff --git a/chrome/android/touchless/java/res/layout/touchless_suggestions_tile_view.xml b/chrome/android/touchless/java/res/layout/touchless_suggestions_tile_view.xml
index 0255d23b..cf50acd 100644
--- a/chrome/android/touchless/java/res/layout/touchless_suggestions_tile_view.xml
+++ b/chrome/android/touchless/java/res/layout/touchless_suggestions_tile_view.xml
@@ -5,11 +5,41 @@
 
 <org.chromium.chrome.browser.touchless.SiteSuggestionsTileView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:paddingHorizontal="@dimen/most_likely_tile_horizontal_spacer">
-    <include
-        layout="@layout/tile_no_text_view_condensed"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" />
+    android:layout_gravity="center"
+    android:background="@drawable/suggestion_tile">
+    <!-- The icon background. -->
+    <View
+        android:id="@+id/tile_view_icon_background"
+        android:layout_width="@dimen/tile_view_icon_size"
+        android:layout_height="@dimen/tile_view_icon_size"
+        android:background="@drawable/tile_view_icon_background_modern" />
+
+    <!-- The main icon. -->
+    <ImageView
+        android:id="@+id/tile_view_icon"
+        android:layout_width="@dimen/tile_view_icon_size_modern"
+        android:layout_height="@dimen/tile_view_icon_size_modern"
+        android:layout_gravity="center"
+        android:importantForAccessibility="no" />
+
+    <!-- Focus highlight. -->
+    <View
+        android:layout_width="@dimen/tile_view_icon_size"
+        android:layout_height="@dimen/tile_view_icon_size"
+        android:background="@drawable/suggestion_tile"
+        android:duplicateParentState="true"/>
+
+    <!-- The offline badge. -->
+    <ImageView
+        android:id="@+id/offline_badge"
+        android:layout_width="@dimen/tile_view_offline_badge_size_modern"
+        android:layout_height="@dimen/tile_view_offline_badge_size_modern"
+        android:layout_gravity="top|end"
+        android:layout_marginEnd="@dimen/tile_view_offline_badge_margin_end_modern_condensed"
+        android:visibility="gone"
+        android:contentDescription="@string/accessibility_ntp_offline_badge"
+        app:srcCompat="@drawable/ic_offline_pin_blue_white" />
 </org.chromium.chrome.browser.touchless.SiteSuggestionsTileView>
diff --git a/chrome/android/touchless/java/res/values-v17/dimens.xml b/chrome/android/touchless/java/res/values-v17/dimens.xml
index baeac27..bfa5041b 100644
--- a/chrome/android/touchless/java/res/values-v17/dimens.xml
+++ b/chrome/android/touchless/java/res/values-v17/dimens.xml
@@ -26,7 +26,7 @@
     <dimen name="open_last_tab_primary_text_margin_left">8dp</dimen>
 
     <!-- Most likely carousel dimensions. -->
+    <dimen name="most_likely_tile_focus_stroke_width">2dp</dimen>
     <dimen name="most_likely_tile_horizontal_spacer">6dp</dimen>
     <dimen name="most_likely_carousel_edge_spacer">8dp</dimen>
-    <dimen name="most_likely_carousel_vertical_spacer">16dp</dimen>
 </resources>
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsCoordinator.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsCoordinator.java
index 5b6044e..3e2cb04 100644
--- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsCoordinator.java
+++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsCoordinator.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.touchless;
 
 import android.content.Context;
+import android.graphics.Rect;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
@@ -64,6 +65,22 @@
                 adapter = new RecyclerViewAdapter<>(
                         adapterDelegate, new SiteSuggestionsViewHolderFactory());
 
+        // Add spacing because tile margins get swallowed/overridden somehow.
+        // TODO(chili): use layout margin.
+        recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
+            @Override
+            public void getItemOffsets(
+                    Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
+                outRect.bottom = context.getResources().getDimensionPixelSize(
+                        R.dimen.most_likely_carousel_edge_spacer);
+                outRect.left = context.getResources().getDimensionPixelSize(
+                        R.dimen.most_likely_tile_horizontal_spacer);
+                outRect.right = context.getResources().getDimensionPixelSize(
+                        R.dimen.most_likely_tile_horizontal_spacer);
+                outRect.top = context.getResources().getDimensionPixelSize(
+                        R.dimen.most_likely_carousel_edge_spacer);
+            }
+        });
         recyclerView.setLayoutManager(layoutManager);
         recyclerView.setAdapter(adapter);
 
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsLayoutManager.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsLayoutManager.java
index 4b0d7ea..ade379c1 100644
--- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsLayoutManager.java
+++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsLayoutManager.java
@@ -27,7 +27,7 @@
             int position = getPosition(child);
             // Calculates the offset for the child's left edge such that the child would be
             // perfectly centered in the view.
-            int childHalfWidth = child.getWidth() / 2;
+            int childHalfWidth = child.getWidth() / 2 + getLeftDecorationWidth(child);
             int offset = parent.getWidth() / 2 - childHalfWidth;
             // Scroll to child with calculated offset.
             scrollToPositionWithOffset(position, offset);
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java
index 6e73ecd..a30cf13 100644
--- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java
+++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java
@@ -28,6 +28,7 @@
 import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate;
 import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegateImpl;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.widget.displaystyle.UiConfig;
 import org.chromium.chrome.touchless.R;
 import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
@@ -109,7 +110,7 @@
         SuggestionsSource suggestionsSource = depsFactory.createSuggestionSource(profile);
         SuggestionsEventReporter eventReporter = depsFactory.createEventReporter();
         SuggestionsNavigationDelegate navigationDelegate = new SuggestionsNavigationDelegate(
-                activity, profile, nativePageHost, mTab.getTabModelSelector());
+                activity, profile, nativePageHost, TabModelSelector.from(mTab));
         SuggestionsUiDelegate suggestionsUiDelegate = new SuggestionsUiDelegateImpl(
                 suggestionsSource, eventReporter, navigationDelegate, profile, nativePageHost,
                 activity.getChromeApplication().getReferencePool(), activity.getSnackbarManager());
diff --git a/chrome/app/OWNERS b/chrome/app/OWNERS
index 6693dae..a4f3eaa8 100644
--- a/chrome/app/OWNERS
+++ b/chrome/app/OWNERS
@@ -14,7 +14,7 @@
 per-file chromium_strings.grd=*
 per-file generated_resources.grd=*
 per-file google_chrome_strings.grd=*
-per-file md_extensions_strings.grdp=*
+per-file extensions_strings.grdp=*
 
 per-file app_management_strings.grdp=file://chrome/browser/ui/webui/app_management/OWNERS
 
diff --git a/chrome/app/md_extensions_strings.grdp b/chrome/app/extensions_strings.grdp
similarity index 100%
rename from chrome/app/md_extensions_strings.grdp
rename to chrome/app/extensions_strings.grdp
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 085dee6..8ee40fe 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -209,7 +209,7 @@
 
       <!-- MD Extensions specific strings -->
       <if expr="enable_extensions">
-        <part file="md_extensions_strings.grdp" />
+        <part file="extensions_strings.grdp" />
       </if>
 
       <!-- NUX Welcome onboarding experience strings -->
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 0eb15c8..2f69ec0d 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -466,28 +466,6 @@
      switches::kTopChromeTouchUiEnabled}};
 
 #if defined(OS_CHROMEOS)
-const FeatureEntry::Choice kAshShelfColorSchemeChoices[] = {
-    {flags_ui::kGenericExperimentChoiceDefault, "", ""},
-    {flag_descriptions::kAshShelfColorSchemeLightVibrant,
-     ash::switches::kAshShelfColorScheme,
-     ash::switches::kAshShelfColorSchemeLightVibrant},
-    {flag_descriptions::kAshShelfColorSchemeNormalVibrant,
-     ash::switches::kAshShelfColorScheme,
-     ash::switches::kAshShelfColorSchemeNormalVibrant},
-    {flag_descriptions::kAshShelfColorSchemeDarkVibrant,
-     ash::switches::kAshShelfColorScheme,
-     ash::switches::kAshShelfColorSchemeDarkVibrant},
-    {flag_descriptions::kAshShelfColorSchemeLightMuted,
-     ash::switches::kAshShelfColorScheme,
-     ash::switches::kAshShelfColorSchemeLightMuted},
-    {flag_descriptions::kAshShelfColorSchemeNormalMuted,
-     ash::switches::kAshShelfColorScheme,
-     ash::switches::kAshShelfColorSchemeNormalMuted},
-    {flag_descriptions::kAshShelfColorSchemeDarkMuted,
-     ash::switches::kAshShelfColorScheme,
-     ash::switches::kAshShelfColorSchemeDarkMuted},
-};
-
 const FeatureEntry::Choice kUiShowCompositedLayerBordersChoices[] = {
     {flags_ui::kGenericExperimentChoiceDefault, "", ""},
     {flag_descriptions::kUiShowCompositedLayerBordersRenderPass,
@@ -1389,9 +1367,6 @@
         kOsAll,
         SINGLE_VALUE_TYPE(ash::switches::kAshDebugShortcuts),
     },
-    {"ash-shelf-color-scheme", flag_descriptions::kAshShelfColorScheme,
-     flag_descriptions::kAshShelfColorSchemeDescription, kOsCrOS,
-     MULTI_VALUE_TYPE(kAshShelfColorSchemeChoices)},
     {"ui-slow-animations", flag_descriptions::kUiSlowAnimationsName,
      flag_descriptions::kUiSlowAnimationsDescription, kOsCrOS,
      SINGLE_VALUE_TYPE(switches::kUISlowAnimations)},
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index a7c05f9b..ef90d1fe 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -98,8 +98,8 @@
         <include name="IDR_ABOUT_NACL_JS" file="resources\about_nacl\about_nacl.js" type="BINDATA" />
       </if>
       <if expr="not is_android">
-        <include name="IDR_ABOUT_SYS_HTML" file="resources\about_sys\about_sys.html" compress="gzip" flattenhtml="true" type="BINDATA" />
-        <include name="IDR_ABOUT_SYS_CSS" file="resources\about_sys\about_sys.css" compress="gzip" type="BINDATA" />
+        <include name="IDR_ABOUT_SYS_HTML" file="resources\about_sys\about_sys.html" compress="gzip" type="BINDATA" />
+        <include name="IDR_ABOUT_SYS_CSS" file="resources\about_sys\about_sys.css" compress="gzip" flattenhtml="true" type="BINDATA" />
         <include name="IDR_ABOUT_SYS_JS" file="resources\about_sys\about_sys.js" compress="gzip" type="BINDATA" />
       </if>
       <include name="IDR_ACCESSIBILITY_HTML" file="resources\accessibility\accessibility.html" flattenhtml="true" allowexternalscript="true" compress="gzip" type="BINDATA" />
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index dfed891..d8cd1ae8 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -581,10 +581,12 @@
     "arc/screen_capture/arc_screen_capture_session.h",
     "arc/tracing/arc_cpu_event.cc",
     "arc/tracing/arc_cpu_event.h",
-    "arc/tracing/arc_cpu_model.cc",
-    "arc/tracing/arc_cpu_model.h",
     "arc/tracing/arc_graphics_jank_detector.cc",
     "arc/tracing/arc_graphics_jank_detector.h",
+    "arc/tracing/arc_system_model.cc",
+    "arc/tracing/arc_system_model.h",
+    "arc/tracing/arc_system_stat_collector.cc",
+    "arc/tracing/arc_system_stat_collector.h",
     "arc/tracing/arc_tracing_bridge.cc",
     "arc/tracing/arc_tracing_bridge.h",
     "arc/tracing/arc_tracing_event.cc",
@@ -595,6 +597,10 @@
     "arc/tracing/arc_tracing_graphics_model.h",
     "arc/tracing/arc_tracing_model.cc",
     "arc/tracing/arc_tracing_model.h",
+    "arc/tracing/arc_value_event.cc",
+    "arc/tracing/arc_value_event.h",
+    "arc/tracing/arc_value_event_trimmer.cc",
+    "arc/tracing/arc_value_event_trimmer.h",
     "arc/tts/arc_tts_service.cc",
     "arc/tts/arc_tts_service.h",
     "arc/user_session/arc_user_session_service.cc",
@@ -1995,6 +2001,8 @@
     "ui/request_pin_view.h",
     "ui/screen_capture_notification_ui_chromeos.cc",
     "ui/screen_capture_notification_ui_chromeos.h",
+    "ui/tpm_auto_update_notification.cc",
+    "ui/tpm_auto_update_notification.h",
     "usb/cros_usb_detector.cc",
     "usb/cros_usb_detector.h",
     "virtual_machines/virtual_machines_util.cc",
@@ -2263,7 +2271,9 @@
     "arc/process/arc_process_unittest.cc",
     "arc/tracing/arc_cpu_event_unittest.cc",
     "arc/tracing/arc_graphics_jank_detector_unittest.cc",
+    "arc/tracing/arc_system_stat_collector_unittest.cc",
     "arc/tracing/arc_tracing_model_unittest.cc",
+    "arc/tracing/arc_value_event_unittest.cc",
     "arc/tts/arc_tts_service_unittest.cc",
     "arc/voice_interaction/fake_voice_interaction_controller.cc",
     "arc/voice_interaction/voice_interaction_controller_client_unittest.cc",
diff --git a/chrome/browser/chromeos/arc/tracing/arc_cpu_event.cc b/chrome/browser/chromeos/arc/tracing/arc_cpu_event.cc
index c10f9fd..9d42620 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_cpu_event.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_cpu_event.cc
@@ -78,6 +78,8 @@
       break;
     case ArcCpuEvent::Type::kWakeUp:
       switch (type) {
+        case ArcCpuEvent::Type::kIdleIn:
+          break;
         case ArcCpuEvent::Type::kIdleOut:
           break;
         case ArcCpuEvent::Type::kWakeUp:
diff --git a/chrome/browser/chromeos/arc/tracing/arc_cpu_event_unittest.cc b/chrome/browser/chromeos/arc/tracing/arc_cpu_event_unittest.cc
index 2573dc27..c815fc5 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_cpu_event_unittest.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_cpu_event_unittest.cc
@@ -77,8 +77,7 @@
   EXPECT_TRUE(
       CheckTrasition(Type::kIdleOut, idle_tid, Type::kActive, real_tid));
 
-  EXPECT_FALSE(
-      CheckTrasition(Type::kWakeUp, real_tid, Type::kIdleIn, idle_tid));
+  EXPECT_TRUE(CheckTrasition(Type::kWakeUp, real_tid, Type::kIdleIn, idle_tid));
   EXPECT_TRUE(
       CheckTrasition(Type::kWakeUp, real_tid, Type::kIdleOut, idle_tid));
   EXPECT_TRUE(CheckTrasition(Type::kWakeUp, real_tid, Type::kWakeUp, real_tid));
diff --git a/chrome/browser/chromeos/arc/tracing/arc_cpu_model.cc b/chrome/browser/chromeos/arc/tracing/arc_cpu_model.cc
deleted file mode 100644
index 165e8e2..0000000
--- a/chrome/browser/chromeos/arc/tracing/arc_cpu_model.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/chromeos/arc/tracing/arc_cpu_model.h"
-
-#include <stdio.h>
-
-#include "base/strings/stringprintf.h"
-
-namespace arc {
-
-namespace {
-
-constexpr char kKeyEvents[] = "events";
-constexpr char kKeyName[] = "name";
-constexpr char kKeyPid[] = "pid";
-constexpr char kKeyThreads[] = "threads";
-
-bool LoadThreads(const base::Value* value,
-                 ArcCpuModel::ThreadMap* out_threads) {
-  if (!value || !value->is_dict())
-    return false;
-
-  for (const auto& it : value->DictItems()) {
-    int tid;
-    if (sscanf(it.first.c_str(), "%d", &tid) != 1)
-      return false;
-
-    if (!it.second.is_dict())
-      return false;
-
-    const base::Value* name = it.second.FindKey(kKeyName);
-    if (!name || !name->is_string())
-      return false;
-    const base::Value* pid = it.second.FindKey(kKeyPid);
-    if (!pid || !pid->is_int())
-      return false;
-
-    (*out_threads)[tid] =
-        ArcCpuModel::ThreadInfo(pid->GetInt(), name->GetString());
-  }
-
-  return true;
-}
-
-base::DictionaryValue SerializeThreads(const ArcCpuModel::ThreadMap& threads) {
-  base::DictionaryValue result;
-
-  for (auto& thread_info : threads) {
-    base::DictionaryValue entry;
-    entry.SetKey(kKeyPid, base::Value(thread_info.second.pid));
-    entry.SetKey(kKeyName, base::Value(thread_info.second.name));
-    result.SetKey(base::StringPrintf("%d", thread_info.first),
-                  std::move(entry));
-  }
-
-  return result;
-}
-
-}  // namespace
-
-ArcCpuModel::ThreadInfo::ThreadInfo() = default;
-
-ArcCpuModel::ThreadInfo::ThreadInfo(int pid, const std::string& name)
-    : pid(pid), name(name) {}
-
-bool ArcCpuModel::ThreadInfo::operator==(const ThreadInfo& other) const {
-  return pid == other.pid && name == other.name;
-}
-
-ArcCpuModel::ArcCpuModel() = default;
-
-ArcCpuModel::~ArcCpuModel() = default;
-
-void ArcCpuModel::Reset() {
-  thread_map_.clear();
-  all_cpu_events_.clear();
-}
-
-void ArcCpuModel::CopyFrom(const ArcCpuModel& other) {
-  thread_map_ = other.thread_map_;
-  all_cpu_events_ = other.all_cpu_events_;
-}
-
-base::DictionaryValue ArcCpuModel::Serialize() const {
-  base::DictionaryValue result;
-  result.SetKey(kKeyThreads, SerializeThreads(thread_map_));
-  result.SetKey(kKeyEvents, SerializeAllCpuEvents(all_cpu_events_));
-  return result;
-}
-
-bool ArcCpuModel::Load(const base::Value* root) {
-  if (!root || !root->is_dict())
-    return false;
-
-  if (!LoadThreads(root->FindKey(kKeyThreads), &thread_map_))
-    return false;
-
-  if (!LoadAllCpuEvents(root->FindKey(kKeyEvents), &all_cpu_events_))
-    return false;
-
-  return true;
-}
-
-bool ArcCpuModel::operator==(const ArcCpuModel& other) const {
-  return thread_map_ == other.thread_map_ &&
-         all_cpu_events_ == other.all_cpu_events_;
-}
-
-}  // namespace arc
diff --git a/chrome/browser/chromeos/arc/tracing/arc_system_model.cc b/chrome/browser/chromeos/arc/tracing/arc_system_model.cc
new file mode 100644
index 0000000..f5cb611
--- /dev/null
+++ b/chrome/browser/chromeos/arc/tracing/arc_system_model.cc
@@ -0,0 +1,120 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/arc/tracing/arc_system_model.h"
+
+#include <stdio.h>
+
+#include "base/strings/stringprintf.h"
+
+namespace arc {
+
+namespace {
+
+constexpr char kKeyCpu[] = "cpu";
+constexpr char kKeyMemory[] = "memory";
+constexpr char kKeyName[] = "name";
+constexpr char kKeyPid[] = "pid";
+constexpr char kKeyThreads[] = "threads";
+
+bool LoadThreads(const base::Value* value,
+                 ArcSystemModel::ThreadMap* out_threads) {
+  if (!value || !value->is_dict())
+    return false;
+
+  for (const auto& it : value->DictItems()) {
+    int tid;
+    if (sscanf(it.first.c_str(), "%d", &tid) != 1)
+      return false;
+
+    if (!it.second.is_dict())
+      return false;
+
+    const base::Value* name = it.second.FindKey(kKeyName);
+    if (!name || !name->is_string())
+      return false;
+    const base::Value* pid = it.second.FindKey(kKeyPid);
+    if (!pid || !pid->is_int())
+      return false;
+
+    (*out_threads)[tid] =
+        ArcSystemModel::ThreadInfo(pid->GetInt(), name->GetString());
+  }
+
+  return true;
+}
+
+base::DictionaryValue SerializeThreads(
+    const ArcSystemModel::ThreadMap& threads) {
+  base::DictionaryValue result;
+
+  for (auto& thread_info : threads) {
+    base::DictionaryValue entry;
+    entry.SetKey(kKeyPid, base::Value(thread_info.second.pid));
+    entry.SetKey(kKeyName, base::Value(thread_info.second.name));
+    result.SetKey(base::StringPrintf("%d", thread_info.first),
+                  std::move(entry));
+  }
+
+  return result;
+}
+
+}  // namespace
+
+ArcSystemModel::ThreadInfo::ThreadInfo() = default;
+
+ArcSystemModel::ThreadInfo::ThreadInfo(int pid, const std::string& name)
+    : pid(pid), name(name) {}
+
+bool ArcSystemModel::ThreadInfo::operator==(const ThreadInfo& other) const {
+  return pid == other.pid && name == other.name;
+}
+
+ArcSystemModel::ArcSystemModel() = default;
+
+ArcSystemModel::~ArcSystemModel() = default;
+
+void ArcSystemModel::Reset() {
+  thread_map_.clear();
+  all_cpu_events_.clear();
+  memory_events_.clear();
+}
+
+void ArcSystemModel::CopyFrom(const ArcSystemModel& other) {
+  thread_map_ = other.thread_map_;
+  all_cpu_events_ = other.all_cpu_events_;
+  memory_events_ = other.memory_events_;
+}
+
+base::DictionaryValue ArcSystemModel::Serialize() const {
+  base::DictionaryValue result;
+  result.SetKey(kKeyThreads, SerializeThreads(thread_map_));
+  result.SetKey(kKeyCpu, SerializeAllCpuEvents(all_cpu_events_));
+  result.SetKey(kKeyMemory, SerializeValueEvents(memory_events_));
+  return result;
+}
+
+bool ArcSystemModel::Load(const base::Value* root) {
+  if (!root || !root->is_dict())
+    return false;
+
+  if (!LoadThreads(root->FindKey(kKeyThreads), &thread_map_))
+    return false;
+
+  if (!LoadAllCpuEvents(root->FindKey(kKeyCpu), &all_cpu_events_))
+    return false;
+
+  if (!LoadValueEvents(root->FindKey(kKeyMemory), &memory_events_))
+    return false;
+
+  return true;
+}
+
+bool ArcSystemModel::operator==(const ArcSystemModel& other) const {
+  return thread_map_ == other.thread_map_ &&
+         all_cpu_events_ == other.all_cpu_events_ &&
+         memory_events_ == other.memory_events_;
+}
+
+}  // namespace arc
diff --git a/chrome/browser/chromeos/arc/tracing/arc_cpu_model.h b/chrome/browser/chromeos/arc/tracing/arc_system_model.h
similarity index 61%
rename from chrome/browser/chromeos/arc/tracing/arc_cpu_model.h
rename to chrome/browser/chromeos/arc/tracing/arc_system_model.h
index b3f82ec..94f6567 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_cpu_model.h
+++ b/chrome/browser/chromeos/arc/tracing/arc_system_model.h
@@ -2,19 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_CPU_MODEL_H_
-#define CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_CPU_MODEL_H_
+#ifndef CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_SYSTEM_MODEL_H_
+#define CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_SYSTEM_MODEL_H_
 
 #include <map>
 #include <string>
 
 #include "base/values.h"
 #include "chrome/browser/chromeos/arc/tracing/arc_cpu_event.h"
+#include "chrome/browser/chromeos/arc/tracing/arc_value_event.h"
 
 namespace arc {
 
-// Contains information about CPU activity events and involved threads.
-class ArcCpuModel {
+// Contains information about system activity and involved threads. System
+// activity includes CPU and memory events.
+class ArcSystemModel {
  public:
   static constexpr int kUnknownPid = -1;
 
@@ -32,16 +34,16 @@
 
   using ThreadMap = std::map<int, ThreadInfo>;
 
-  ArcCpuModel();
-  ~ArcCpuModel();
+  ArcSystemModel();
+  ~ArcSystemModel();
 
   void Reset();
 
-  void CopyFrom(const ArcCpuModel& other);
+  void CopyFrom(const ArcSystemModel& other);
   base::DictionaryValue Serialize() const;
   bool Load(const base::Value* root);
 
-  bool operator==(const ArcCpuModel& other) const;
+  bool operator==(const ArcSystemModel& other) const;
 
   ThreadMap& thread_map() { return thread_map_; }
   const ThreadMap& thread_map() const { return thread_map_; }
@@ -49,13 +51,17 @@
   AllCpuEvents& all_cpu_events() { return all_cpu_events_; }
   const AllCpuEvents& all_cpu_events() const { return all_cpu_events_; }
 
+  ValueEvents& memory_events() { return memory_events_; }
+  const ValueEvents& memory_events() const { return memory_events_; }
+
  private:
   ThreadMap thread_map_;
   AllCpuEvents all_cpu_events_;
+  ValueEvents memory_events_;
 
-  DISALLOW_COPY_AND_ASSIGN(ArcCpuModel);
+  DISALLOW_COPY_AND_ASSIGN(ArcSystemModel);
 };
 
 }  // namespace arc
 
-#endif  // CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_CPU_MODEL_H_
+#endif  // CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_SYSTEM_MODEL_H_
diff --git a/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.cc b/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.cc
new file mode 100644
index 0000000..c5660ca
--- /dev/null
+++ b/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.cc
@@ -0,0 +1,221 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.h"
+
+#include "base/bind.h"
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/task/post_task.h"
+#include "base/task_runner_util.h"
+#include "base/threading/thread_restrictions.h"
+#include "chrome/browser/chromeos/arc/tracing/arc_system_model.h"
+#include "chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.h"
+
+namespace arc {
+
+namespace {
+
+// Interval to update system stats.
+constexpr base::TimeDelta kSystemStatUpdateInterval =
+    base::TimeDelta::FromMilliseconds(10);
+
+bool IsWhitespace(char c) {
+  return c == ' ' || c == '\t' || c == '\n';
+}
+
+bool IsDigit(char c) {
+  return c >= '0' && c <= '9';
+}
+
+bool IsEnd(char c) {
+  return IsWhitespace(c) || c == 0;
+}
+
+}  // namespace
+
+struct ArcSystemStatCollector::Sample {
+  base::TimeTicks timestamp;
+  int swap_sectors_read = 0;
+  int swap_sectors_write = 0;
+  int swap_waiting_time_ms = 0;
+  int mem_total_kb = 0;
+  int mem_used_kb = 0;
+};
+
+// static
+constexpr int ArcSystemStatCollector::kZramStatColumns[];
+
+// static
+constexpr int ArcSystemStatCollector::kMemInfoColumns[];
+
+ArcSystemStatCollector::ArcSystemStatCollector() : weak_ptr_factory_(this) {}
+
+ArcSystemStatCollector::~ArcSystemStatCollector() = default;
+
+void ArcSystemStatCollector::Start(const base::TimeDelta& max_interval) {
+  const size_t sample_count =
+      1 + max_interval.InMicroseconds() /
+              kSystemStatUpdateInterval.InMicroseconds();
+  samples_.resize(sample_count);
+  write_index_ = 0;
+  // Maximum 10 warning per session.
+  missed_update_warning_left_ = 10;
+
+  background_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
+      {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
+  timer_.Start(
+      FROM_HERE, kSystemStatUpdateInterval,
+      base::BindRepeating(&ArcSystemStatCollector::ScheduleSystemStatUpdate,
+                          base::Unretained(this)));
+}
+
+void ArcSystemStatCollector::Stop() {
+  weak_ptr_factory_.InvalidateWeakPtrs();
+  background_task_runner_.reset();
+  timer_.Stop();
+  request_scheduled_ = false;
+}
+
+void ArcSystemStatCollector::Flush(const base::TimeTicks& min_timestamp,
+                                   const base::TimeTicks& max_timestamp,
+                                   ArcSystemModel* system_model) {
+  DCHECK(!timer_.IsRunning());
+  size_t sample_index =
+      write_index_ >= samples_.size() ? write_index_ - samples_.size() : 0;
+  ArcValueEventTrimmer mem_total(&system_model->memory_events(),
+                                 ArcValueEvent::Type::kMemTotal);
+  ArcValueEventTrimmer mem_used(&system_model->memory_events(),
+                                ArcValueEvent::Type::kMemUsed);
+  ArcValueEventTrimmer swap_read(&system_model->memory_events(),
+                                 ArcValueEvent::Type::kSwapRead);
+  ArcValueEventTrimmer swap_write(&system_model->memory_events(),
+                                  ArcValueEvent::Type::kSwapWrite);
+  ArcValueEventTrimmer swap_wait(&system_model->memory_events(),
+                                 ArcValueEvent::Type::kSwapWait);
+  while (sample_index < write_index_) {
+    const Sample& sample = samples_[sample_index % samples_.size()];
+    ++sample_index;
+    if (sample.timestamp > max_timestamp)
+      break;
+    if (sample.timestamp < min_timestamp)
+      continue;
+    const int64_t timestamp =
+        (sample.timestamp - base::TimeTicks()).InMicroseconds();
+    mem_total.MaybeAdd(timestamp, sample.mem_total_kb);
+    mem_used.MaybeAdd(timestamp, sample.mem_used_kb);
+    swap_read.MaybeAdd(timestamp, sample.swap_sectors_read);
+    swap_write.MaybeAdd(timestamp, sample.swap_sectors_write);
+    swap_wait.MaybeAdd(timestamp, sample.swap_waiting_time_ms);
+  }
+}
+
+void ArcSystemStatCollector::ScheduleSystemStatUpdate() {
+  if (request_scheduled_) {
+    if (missed_update_warning_left_-- > 0)
+      LOG(WARNING) << "Dropping update, already pending";
+    return;
+  }
+  base::TaskRunner* task_runner = background_task_runner_.get();
+  base::PostTaskAndReplyWithResult(
+      task_runner, FROM_HERE,
+      base::BindOnce(&ArcSystemStatCollector::ReadSystemStatOnBackgroundThread),
+      base::BindOnce(&ArcSystemStatCollector::UpdateSystemStatOnUiThread,
+                     weak_ptr_factory_.GetWeakPtr()));
+  request_scheduled_ = true;
+}
+
+// static
+ArcSystemStatCollector::RuntimeFrame
+ArcSystemStatCollector::ReadSystemStatOnBackgroundThread() {
+  const base::FilePath zram_stat_path(
+      FILE_PATH_LITERAL("/sys/block/zram0/stat"));
+  const base::FilePath mem_info_path(FILE_PATH_LITERAL("/proc/meminfo"));
+
+  ArcSystemStatCollector::RuntimeFrame current_frame;
+  if (!ParseStatFile(zram_stat_path, kZramStatColumns,
+                     current_frame.zram_stat)) {
+    memset(current_frame.zram_stat, 0, sizeof(current_frame.zram_stat));
+    static bool error_reported = false;
+    if (!error_reported) {
+      LOG(ERROR) << "Failed to read zram stat file: " << zram_stat_path.value();
+      error_reported = true;
+    }
+  }
+  if (!ParseStatFile(mem_info_path, kMemInfoColumns, current_frame.mem_info)) {
+    memset(current_frame.mem_info, 0, sizeof(current_frame.mem_info));
+    static bool error_reported = false;
+    if (!error_reported) {
+      LOG(ERROR) << "Failed to read mem info file: " << mem_info_path.value();
+      error_reported = true;
+    }
+  }
+  return current_frame;
+}
+
+void ArcSystemStatCollector::UpdateSystemStatOnUiThread(
+    RuntimeFrame current_frame) {
+  DCHECK(request_scheduled_);
+  request_scheduled_ = false;
+  DCHECK(!samples_.empty());
+  Sample& current_sample = samples_[write_index_ % samples_.size()];
+  current_sample.timestamp = base::TimeTicks::Now();
+  current_sample.mem_total_kb = current_frame.mem_info[0];
+  // Total - available.
+  current_sample.mem_used_kb =
+      current_frame.mem_info[0] - current_frame.mem_info[1];
+  // We calculate delta, so ignore first update.
+  if (write_index_) {
+    current_sample.swap_sectors_read =
+        current_frame.zram_stat[0] - previous_frame_.zram_stat[0];
+    current_sample.swap_sectors_write =
+        current_frame.zram_stat[1] - previous_frame_.zram_stat[1];
+    current_sample.swap_waiting_time_ms =
+        current_frame.zram_stat[2] - previous_frame_.zram_stat[2];
+  }
+  DCHECK_GE(current_sample.swap_sectors_read, 0);
+  DCHECK_GE(current_sample.swap_sectors_write, 0);
+  DCHECK_GE(current_sample.swap_waiting_time_ms, 0);
+  DCHECK_GE(current_sample.mem_total_kb, 0);
+  DCHECK_GE(current_sample.mem_used_kb, 0);
+  previous_frame_ = current_frame;
+  ++write_index_;
+}
+
+bool ParseStatFile(const base::FilePath& path,
+                   const int* columns,
+                   int64_t* output) {
+  char buffer[128];
+  const int read = base::ReadFile(path, buffer, sizeof(buffer) - 1);
+  if (read < 0)
+    return false;
+  buffer[read] = 0;
+  int column_index = 0;
+  const char* scan = buffer;
+  while (true) {
+    // Skip whitespace.
+    while (IsWhitespace(*scan))
+      ++scan;
+    if (*columns != column_index) {
+      // Just skip this entry. It may be digits or text.
+      while (!IsWhitespace(*scan))
+        ++scan;
+    } else {
+      int64_t value = 0;
+      while (IsDigit(*scan)) {
+        value = 10 * value + *scan - '0';
+        ++scan;
+      }
+      *output++ = value;
+      ++columns;
+      if (*columns < 0)
+        return IsEnd(*scan);  // All columns are read.
+    }
+    if (!IsWhitespace(*scan))
+      return false;
+    ++column_index;
+  }
+}
+
+}  // namespace arc
diff --git a/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.h b/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.h
new file mode 100644
index 0000000..4cc2c2f
--- /dev/null
+++ b/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.h
@@ -0,0 +1,116 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_SYSTEM_STAT_COLLECTOR_H_
+#define CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_SYSTEM_STAT_COLLECTOR_H_
+
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/timer/timer.h"
+
+namespace base {
+class FilePath;
+class TimeDelta;
+class SequencedTaskRunner;
+}  // namespace base
+
+namespace arc {
+
+class ArcSystemModel;
+
+// Collects various system statistics and appends results to the
+// |ArcSystemModel|.
+class ArcSystemStatCollector {
+ public:
+  // Indices of fields to parse zram info, see
+  // https://www.kernel.org/doc/Documentation/block/stat.txt
+  static constexpr int kZramStatColumns[] = {
+      2,   // number of sectors read
+      6,   // number of sectors written
+      10,  // total wait time for all requests (milliseconds)
+      -1,  // End of sequence
+  };
+
+  // Indices of fields to parse /proc/meminfo
+  // As an example:
+  // MemTotal:        8058940 kB
+  // MemFree:          314184 kB
+  // MemAvailable:    2714260 kB
+  // ...
+  static constexpr int kMemInfoColumns[] = {
+      1,   // MemTotal in kb.
+      7,   // MemAvailable in kb.
+      -1,  // End of sequence
+  };
+
+  ArcSystemStatCollector();
+  ~ArcSystemStatCollector();
+
+  // Starts sample collection, |max_interval| defines the maximum interval and
+  // it is used for circle buffer size calculation.
+  void Start(const base::TimeDelta& max_interval);
+  // Stops sample collection.
+  void Stop();
+  // Appends collected samples to |system_model|.|min_timestamp| and
+  // |max_timestamp| specify the minimum and maximum timestamps respectively to
+  // add to |system_model|.
+  void Flush(const base::TimeTicks& min_timestamp,
+             const base::TimeTicks& max_timestamp,
+             ArcSystemModel* system_model);
+
+ private:
+  struct Sample;
+
+  struct RuntimeFrame {
+    // read, written sectors and total time in milliseconds.
+    int64_t zram_stat[base::size(kZramStatColumns) - 1] = {0};
+    // total, available.
+    int64_t mem_info[base::size(kMemInfoColumns) - 1] = {0};
+  };
+
+  // Schedule reading System stat files in |ReadSystemStatOnBackgroundThread| on
+  // background thread. Once ready result is passed to
+  // |UpdateSystemStatOnUiThread|
+  void ScheduleSystemStatUpdate();
+  static RuntimeFrame ReadSystemStatOnBackgroundThread();
+  void UpdateSystemStatOnUiThread(RuntimeFrame current_frame);
+
+  // To schedule updates of system stat.
+  base::RepeatingTimer timer_;
+  // Performs reading kernel stat files on backgrond thread.
+  scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
+  // Use to prevent double scheduling.
+  bool request_scheduled_ = false;
+  // Used to limit the number of warnings printed in case System stat update is
+  // dropped due to previous update is in progress.
+  int missed_update_warning_left_ = 0;
+
+  // Samples are implemented as a circle buffer.
+  std::vector<Sample> samples_;
+  size_t write_index_ = 0;
+
+  // Used to calculate delta.
+  RuntimeFrame previous_frame_;
+
+  base::WeakPtrFactory<ArcSystemStatCollector> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ArcSystemStatCollector);
+};
+
+// Helper that reads and parses stat file containing decimal number separated by
+// whitespace and text fields. It does not have any dynamic memory allocation.
+// |path| specifies the file to read and parse. |columns| contains index of
+// column to parse, end of sequence is specified by terminator -1. |output|
+// receives parsed value. Must be the size as |columns| size - 1.
+bool ParseStatFile(const base::FilePath& path,
+                   const int* columns,
+                   int64_t* output);
+
+}  // namespace arc
+
+#endif  // CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_SYSTEM_STAT_COLLECTOR_H_
diff --git a/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector_unittest.cc b/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector_unittest.cc
new file mode 100644
index 0000000..1e0a5b7
--- /dev/null
+++ b/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector_unittest.cc
@@ -0,0 +1,43 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.h"
+
+#include "base/files/file_path.h"
+#include "base/path_service.h"
+#include "chrome/common/chrome_paths.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace arc {
+
+using ArcSystemStatCollectorTest = testing::Test;
+
+namespace {
+
+base::FilePath GetPath(const std::string& name) {
+  base::FilePath base_path;
+  base::PathService::Get(chrome::DIR_TEST_DATA, &base_path);
+  return base_path.Append("arc_graphics_tracing").Append(name);
+}
+
+}  // namespace
+
+TEST_F(ArcSystemStatCollectorTest, Parse) {
+  int64_t zram_values[3];
+  EXPECT_TRUE(ParseStatFile(GetPath("zram_stat"),
+                            ArcSystemStatCollector::kZramStatColumns,
+                            zram_values));
+  EXPECT_EQ(2384, zram_values[0]);
+  EXPECT_EQ(56696, zram_values[1]);
+  EXPECT_EQ(79, zram_values[2]);
+
+  int64_t mem_values[2];
+  EXPECT_TRUE(ParseStatFile(GetPath("proc_meminfo"),
+                            ArcSystemStatCollector::kMemInfoColumns,
+                            mem_values));
+  EXPECT_EQ(8058940, mem_values[0]);
+  EXPECT_EQ(2714260, mem_values[1]);
+}
+
+}  // namespace arc
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc
index 4375f338..9d728c3 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc
@@ -36,10 +36,10 @@
 constexpr char kKeyAndroid[] = "android";
 constexpr char kKeyBuffers[] = "buffers";
 constexpr char kKeyChrome[] = "chrome";
-constexpr char kKeyCpu[] = "cpu";
 constexpr char kKeyDuration[] = "duration";
 constexpr char kKeyGlobalEvents[] = "global_events";
 constexpr char kKeyViews[] = "views";
+constexpr char kKeySystem[] = "system";
 constexpr char kKeyTaskId[] = "task_id";
 
 constexpr char kAcquireBufferQuery[] =
@@ -980,7 +980,7 @@
     return false;
   }
 
-  cpu_model_.CopyFrom(common_model.cpu_model());
+  system_model_.CopyFrom(common_model.system_model());
 
   NormalizeTimestamps();
 
@@ -1012,13 +1012,18 @@
     }
   }
 
-  for (const auto& cpu_events : cpu_model_.all_cpu_events()) {
+  for (const auto& cpu_events : system_model_.all_cpu_events()) {
     if (!cpu_events.empty()) {
       min = std::min(min, cpu_events.front().timestamp);
       max = std::max(max, cpu_events.back().timestamp);
     }
   }
 
+  if (!system_model_.memory_events().empty()) {
+    min = std::min(min, system_model_.memory_events().front().timestamp);
+    max = std::max(max, system_model_.memory_events().back().timestamp);
+  }
+
   duration_ = max - min + 1;
 
   for (BufferEvents* buffer : all_buffers) {
@@ -1026,10 +1031,13 @@
       event.timestamp -= min;
   }
 
-  for (auto& cpu_events : cpu_model_.all_cpu_events()) {
+  for (auto& cpu_events : system_model_.all_cpu_events()) {
     for (auto& cpu_event : cpu_events)
       cpu_event.timestamp -= min;
   }
+
+  for (auto& memory_event : system_model_.memory_events())
+    memory_event.timestamp -= min;
 }
 
 void ArcTracingGraphicsModel::Reset() {
@@ -1037,7 +1045,7 @@
   android_top_level_.Reset();
   view_buffers_.clear();
   chrome_buffer_id_to_task_id_.clear();
-  cpu_model_.Reset();
+  system_model_.Reset();
   duration_ = 0;
 }
 
@@ -1070,8 +1078,8 @@
   // Chrome top events
   root->SetKey(kKeyChrome, SerializeEventsContainer(chrome_top_level_));
 
-  // CPU.
-  root->SetKey(kKeyCpu, cpu_model_.Serialize());
+  // System.
+  root->SetKey(kKeySystem, system_model_.Serialize());
 
   // Duration.
   root->SetKey(kKeyDuration, base::Value(static_cast<double>(duration_)));
@@ -1130,7 +1138,7 @@
   if (!LoadEventsContainer(root.FindKey(kKeyChrome), &chrome_top_level_))
     return false;
 
-  if (!cpu_model_.Load(root.FindKey(kKeyCpu)))
+  if (!system_model_.Load(root.FindKey(kKeySystem)))
     return false;
 
   const base::Value* duration = root.FindKey(kKeyDuration);
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h
index a62c407c..92aee932 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h
+++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h
@@ -12,7 +12,7 @@
 
 #include "base/macros.h"
 #include "base/values.h"
-#include "chrome/browser/chromeos/arc/tracing/arc_cpu_model.h"
+#include "chrome/browser/chromeos/arc/tracing/arc_system_model.h"
 
 namespace arc {
 
@@ -154,8 +154,8 @@
 
   const EventsContainer& chrome_top_level() const { return chrome_top_level_; }
 
-  ArcCpuModel& cpu_model() { return cpu_model_; }
-  const ArcCpuModel& cpu_model() const { return cpu_model_; }
+  ArcSystemModel& system_model() { return system_model_; }
+  const ArcSystemModel& system_model() const { return system_model_; }
 
  private:
   // Normalizes timestamp for all events by subtracting the timestamp of the
@@ -178,7 +178,7 @@
   // Map Chrome buffer id to task id.
   std::map<std::string, int> chrome_buffer_id_to_task_id_;
   // CPU event model.
-  ArcCpuModel cpu_model_;
+  ArcSystemModel system_model_;
 
   DISALLOW_COPY_AND_ASSIGN(ArcTracingGraphicsModel);
 };
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_model.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_model.cc
index 8968f308..2d94d3e3 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_tracing_model.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_model.cc
@@ -421,12 +421,13 @@
       return false;
     }
 
-    if (cpu_model_.thread_map().find(tid) == cpu_model_.thread_map().end()) {
+    if (system_model_.thread_map().find(tid) ==
+        system_model_.thread_map().end()) {
       int thread_name_start = 0;
       while (line[thread_name_start] == ' ')
         ++thread_name_start;
-      cpu_model_.thread_map()[tid] = ArcCpuModel::ThreadInfo(
-          ArcCpuModel::kUnknownPid,
+      system_model_.thread_map()[tid] = ArcSystemModel::ThreadInfo(
+          ArcSystemModel::kUnknownPid,
           line.substr(thread_name_start, 16 - thread_name_start));
     }
 
@@ -461,20 +462,20 @@
         return false;
       }
     } else if (!strncmp(&line[separator_position], kCpuIdle, kCpuIdleLength)) {
-      if (!HandleCpuIdle(&cpu_model_.all_cpu_events(), timestamp, cpu_id, tid,
-                         line, separator_position + kCpuIdleLength)) {
+      if (!HandleCpuIdle(&system_model_.all_cpu_events(), timestamp, cpu_id,
+                         tid, line, separator_position + kCpuIdleLength)) {
         return false;
       }
     } else if (!strncmp(&line[separator_position], kSchedWakeUp,
                         kSchedWakeUpLength)) {
-      if (!HandleSchedWakeUp(&cpu_model_.all_cpu_events(), timestamp, cpu_id,
+      if (!HandleSchedWakeUp(&system_model_.all_cpu_events(), timestamp, cpu_id,
                              tid, line,
                              separator_position + kSchedWakeUpLength)) {
         return false;
       }
     } else if (!strncmp(&line[separator_position], kSchedSwitch,
                         kSchedSwitchLength)) {
-      if (!HandleSchedSwitch(&cpu_model_.all_cpu_events(), timestamp, cpu_id,
+      if (!HandleSchedSwitch(&system_model_.all_cpu_events(), timestamp, cpu_id,
                              tid, line,
                              separator_position + kSchedSwitchLength)) {
         return false;
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_model.h b/chrome/browser/chromeos/arc/tracing/arc_tracing_model.h
index 716c5085..234f0b7 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_tracing_model.h
+++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_model.h
@@ -12,7 +12,7 @@
 
 #include "base/macros.h"
 #include "base/values.h"
-#include "chrome/browser/chromeos/arc/tracing/arc_cpu_model.h"
+#include "chrome/browser/chromeos/arc/tracing/arc_system_model.h"
 
 namespace arc {
 
@@ -57,7 +57,8 @@
   // Dumps this model to |stream|.
   void Dump(std::ostream& stream) const;
 
-  const ArcCpuModel& cpu_model() const { return cpu_model_; }
+  ArcSystemModel& system_model() { return system_model_; }
+  const ArcSystemModel& system_model() const { return system_model_; }
 
  private:
   // Processes list of events. Returns true in case all events were processed
@@ -77,7 +78,7 @@
   // tracing events.
   std::map<std::string, TracingEvents> group_events_;
 
-  ArcCpuModel cpu_model_;
+  ArcSystemModel system_model_;
 
   // Metadata events.
   TracingEvents metadata_events_;
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc
index 53ecc86..5e146e7f 100644
--- a/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc
+++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc
@@ -144,8 +144,8 @@
   ASSERT_TRUE(model.Build(tracing_data));
 
   // 4 CPU cores.
-  EXPECT_EQ(4U, model.cpu_model().all_cpu_events().size());
-  for (const auto& cpu_events : model.cpu_model().all_cpu_events())
+  EXPECT_EQ(4U, model.system_model().all_cpu_events().size());
+  for (const auto& cpu_events : model.system_model().all_cpu_events())
     EXPECT_TRUE(ValidateCpuEvents(cpu_events));
 
   // Perform several well-known queries.
@@ -212,14 +212,14 @@
 
   // Note, CPU events in |graphics_model| are normalized by timestamp. So they
   // are not equal and we cannot do direct comparison.
-  ASSERT_EQ(graphics_model.cpu_model().all_cpu_events().size(),
-            model.cpu_model().all_cpu_events().size());
-  EXPECT_EQ(graphics_model.cpu_model().thread_map(),
-            model.cpu_model().thread_map());
-  for (size_t i = 0; i < graphics_model.cpu_model().all_cpu_events().size();
+  ASSERT_EQ(graphics_model.system_model().all_cpu_events().size(),
+            model.system_model().all_cpu_events().size());
+  EXPECT_EQ(graphics_model.system_model().thread_map(),
+            model.system_model().thread_map());
+  for (size_t i = 0; i < graphics_model.system_model().all_cpu_events().size();
        ++i) {
-    EXPECT_EQ(graphics_model.cpu_model().all_cpu_events()[i].size(),
-              model.cpu_model().all_cpu_events()[i].size());
+    EXPECT_EQ(graphics_model.system_model().all_cpu_events()[i].size(),
+              model.system_model().all_cpu_events()[i].size());
   }
 
   EXPECT_GT(graphics_model.duration(), 0U);
@@ -238,7 +238,8 @@
             graphics_model_loaded.chrome_top_level());
   EXPECT_EQ(graphics_model.view_buffers(),
             graphics_model_loaded.view_buffers());
-  EXPECT_EQ(graphics_model.cpu_model(), graphics_model_loaded.cpu_model());
+  EXPECT_EQ(graphics_model.system_model(),
+            graphics_model_loaded.system_model());
   EXPECT_EQ(graphics_model.duration(), graphics_model_loaded.duration());
 }
 
diff --git a/chrome/browser/chromeos/arc/tracing/arc_value_event.cc b/chrome/browser/chromeos/arc/tracing/arc_value_event.cc
new file mode 100644
index 0000000..4f140c5
--- /dev/null
+++ b/chrome/browser/chromeos/arc/tracing/arc_value_event.cc
@@ -0,0 +1,73 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/arc/tracing/arc_value_event.h"
+
+namespace arc {
+
+ArcValueEvent::ArcValueEvent(int64_t timestamp, Type type, int value)
+    : timestamp(timestamp), type(type), value(value) {}
+
+bool ArcValueEvent::operator==(const ArcValueEvent& other) const {
+  return timestamp == other.timestamp && type == other.type &&
+         value == other.value;
+}
+
+base::ListValue SerializeValueEvents(const ValueEvents& value_events) {
+  base::ListValue list;
+  for (const auto& event : value_events) {
+    base::ListValue event_value;
+    event_value.GetList().push_back(base::Value(static_cast<int>(event.type)));
+    event_value.GetList().push_back(
+        base::Value(static_cast<double>(event.timestamp)));
+    event_value.GetList().push_back(base::Value(event.value));
+    list.GetList().emplace_back(std::move(event_value));
+  }
+  return list;
+}
+
+bool LoadValueEvents(const base::Value* value, ValueEvents* value_events) {
+  if (!value || !value->is_list())
+    return false;
+
+  int64_t previous_timestamp = 0;
+  for (const auto& entry : value->GetList()) {
+    if (!entry.is_list() || entry.GetList().size() != 3)
+      return false;
+    if (!entry.GetList()[0].is_int())
+      return false;
+    const ArcValueEvent::Type type =
+        static_cast<ArcValueEvent::Type>(entry.GetList()[0].GetInt());
+    switch (type) {
+      case ArcValueEvent::Type::kMemTotal:
+      case ArcValueEvent::Type::kMemUsed:
+      case ArcValueEvent::Type::kSwapRead:
+      case ArcValueEvent::Type::kSwapWrite:
+      case ArcValueEvent::Type::kSwapWait:
+        break;
+      default:
+        return false;
+    }
+    if (!entry.GetList()[1].is_double() && !entry.GetList()[1].is_int())
+      return false;
+    const int64_t timestamp = entry.GetList()[1].GetDouble();
+    if (timestamp < previous_timestamp)
+      return false;
+    if (!entry.GetList()[2].is_int())
+      return false;
+    const int value = entry.GetList()[2].GetInt();
+    value_events->emplace_back(timestamp, type, value);
+    previous_timestamp = timestamp;
+  }
+
+  return true;
+}
+
+std::ostream& operator<<(std::ostream& os, ArcValueEvent::Type event_type) {
+  return os << static_cast<
+             typename std::underlying_type<ArcValueEvent::Type>::type>(
+             event_type);
+}
+
+}  // namespace arc
diff --git a/chrome/browser/chromeos/arc/tracing/arc_value_event.h b/chrome/browser/chromeos/arc/tracing/arc_value_event.h
new file mode 100644
index 0000000..2876d3bc
--- /dev/null
+++ b/chrome/browser/chromeos/arc/tracing/arc_value_event.h
@@ -0,0 +1,54 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_VALUE_EVENT_H_
+#define CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_VALUE_EVENT_H_
+
+#include <ostream>
+#include <vector>
+
+#include "base/values.h"
+
+namespace arc {
+
+// Tracing event with a value.
+struct ArcValueEvent {
+  enum class Type {
+    kMemTotal,
+    kMemUsed,
+    kSwapRead,
+    kSwapWrite,
+    kSwapWait,
+  };
+
+  ArcValueEvent(int64_t timestamp, Type type, int value);
+
+  bool operator==(const ArcValueEvent& other) const;
+
+  int64_t timestamp;
+  Type type;
+  /**
+   * kMemTotal - kb.
+   * kMemUsed - kb.
+   * kSwapRead - number of sectors.
+   * kSwapWrite - number of sectors.
+   * kSwapWait - milliseconds.
+   */
+  int value;
+};
+
+using ValueEvents = std::vector<ArcValueEvent>;
+
+// Serializes value events into |base::ListValue|.
+base::ListValue SerializeValueEvents(const ValueEvents& value_events);
+
+// Loads value events from |base::ListValue|. Returns true in case value
+// events were loaded successfully.
+bool LoadValueEvents(const base::Value* value, ValueEvents* value_events);
+
+std::ostream& operator<<(std::ostream& os, ArcValueEvent::Type event_type);
+
+}  // namespace arc
+
+#endif  // CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_VALUE_EVENT_H_
diff --git a/chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.cc b/chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.cc
new file mode 100644
index 0000000..81360397
--- /dev/null
+++ b/chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.cc
@@ -0,0 +1,36 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.h"
+
+namespace arc {
+
+ArcValueEventTrimmer::ArcValueEventTrimmer(ValueEvents* events,
+                                           ArcValueEvent::Type type)
+    : events_(events), type_(type) {}
+
+ArcValueEventTrimmer::~ArcValueEventTrimmer() {
+  Flush();
+}
+
+void ArcValueEventTrimmer::MaybeAdd(int64_t timestamp, int value) {
+  if (!first_event_ && last_value_ == value) {
+    last_trimmed_timestamp_ = timestamp;
+    was_trimmed_ = true;
+    return;
+  }
+  Flush();
+  events_->emplace_back(timestamp, type_, value);
+  last_value_ = value;
+  first_event_ = false;
+  was_trimmed_ = false;
+}
+
+void ArcValueEventTrimmer::Flush() {
+  if (was_trimmed_)
+    events_->emplace_back(last_trimmed_timestamp_, type_, last_value_);
+  was_trimmed_ = false;
+}
+
+}  // namespace arc
diff --git a/chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.h b/chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.h
new file mode 100644
index 0000000..21dfbe96
--- /dev/null
+++ b/chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.h
@@ -0,0 +1,46 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_VALUE_EVENT_TRIMMER_H_
+#define CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_VALUE_EVENT_TRIMMER_H_
+
+#include "base/values.h"
+#include "chrome/browser/chromeos/arc/tracing/arc_value_event.h"
+
+namespace arc {
+
+// Helper that prevents adding events with the same value.
+// For example event values (value:timestamp)
+// 1:100 2:101 2:102 2:103 2:104 1:105 2:106
+// would be trimmed to
+// 1:100 2:101 2:104 1:105 2:106.
+class ArcValueEventTrimmer {
+ public:
+  ArcValueEventTrimmer(ValueEvents* events, ArcValueEvent::Type type);
+  ~ArcValueEventTrimmer();
+
+  // May be add the next event, in case it is not trimmed out.
+  void MaybeAdd(int64_t timestamp, int value);
+
+ private:
+  // In case value has changed, insert last trimmed value.
+  void Flush();
+
+  ValueEvents* const events_;
+  const ArcValueEvent::Type type_;
+  // Indicate if this is first event that would never be trimmed.
+  bool first_event_ = true;
+  // Set to true in case last event was trimmed.
+  bool was_trimmed_ = false;
+  // Timestamp of the last trimmed event.
+  int64_t last_trimmed_timestamp_;
+  // Value of the last event.
+  int last_value_ = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(ArcValueEventTrimmer);
+};
+
+}  // namespace arc
+
+#endif  // CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_VALUE_EVENT_TRIMMER_H_
diff --git a/chrome/browser/chromeos/arc/tracing/arc_value_event_unittest.cc b/chrome/browser/chromeos/arc/tracing/arc_value_event_unittest.cc
new file mode 100644
index 0000000..7ced142
--- /dev/null
+++ b/chrome/browser/chromeos/arc/tracing/arc_value_event_unittest.cc
@@ -0,0 +1,61 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/arc/tracing/arc_value_event.h"
+#include "chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace arc {
+
+using ArcValueEventTest = testing::Test;
+using Type = ArcValueEvent::Type;
+
+TEST_F(ArcValueEventTest, Trimmer) {
+  ValueEvents events;
+  {
+    ArcValueEventTrimmer trimmer(&events, ArcValueEvent::Type::kMemUsed);
+    trimmer.MaybeAdd(100 /* timestamp */, 1 /* value */);
+    ASSERT_EQ(1U, events.size());
+    EXPECT_EQ(ArcValueEvent(100, ArcValueEvent::Type::kMemUsed, 1), events[0]);
+    trimmer.MaybeAdd(101, 2);
+    ASSERT_EQ(2U, events.size());
+    EXPECT_EQ(ArcValueEvent(101, ArcValueEvent::Type::kMemUsed, 2), events[1]);
+    trimmer.MaybeAdd(102, 2);
+    EXPECT_EQ(2U, events.size());
+    trimmer.MaybeAdd(103, 2);
+    EXPECT_EQ(2U, events.size());
+    trimmer.MaybeAdd(104, 2);
+    EXPECT_EQ(2U, events.size());
+    trimmer.MaybeAdd(105, 1);
+    ASSERT_EQ(4U, events.size());
+    EXPECT_EQ(ArcValueEvent(104, ArcValueEvent::Type::kMemUsed, 2), events[2]);
+    EXPECT_EQ(ArcValueEvent(105, ArcValueEvent::Type::kMemUsed, 1), events[3]);
+    trimmer.MaybeAdd(106, 2);
+    ASSERT_EQ(5U, events.size());
+    EXPECT_EQ(ArcValueEvent(106, ArcValueEvent::Type::kMemUsed, 2), events[4]);
+    trimmer.MaybeAdd(107, 2);
+    EXPECT_EQ(5U, events.size());
+  }
+  // Check auto-close, last trimmed is added.
+  ASSERT_EQ(6U, events.size());
+  EXPECT_EQ(ArcValueEvent(107, ArcValueEvent::Type::kMemUsed, 2), events[5]);
+}
+
+TEST_F(ArcValueEventTest, Serialize) {
+  const ValueEvents events{
+      {100 /* timestamp */, ArcValueEvent::Type::kMemTotal, 10 /* value */},
+      {101 /* timestamp */, ArcValueEvent::Type::kMemUsed, 20 /* value */},
+      {102 /* timestamp */, ArcValueEvent::Type::kSwapRead, 30 /* value */},
+      {103 /* timestamp */, ArcValueEvent::Type::kSwapWrite, 40 /* value */},
+      {104 /* timestamp */, ArcValueEvent::Type::kSwapWait, 50 /* value */}};
+
+  const base::ListValue value = SerializeValueEvents(events);
+
+  ValueEvents loaded_events;
+  EXPECT_TRUE(LoadValueEvents(&value, &loaded_events));
+  EXPECT_EQ(events, loaded_events);
+}
+
+}  // namespace arc
diff --git a/chrome/browser/chromeos/kiosk_next_home/app_controller_service_unittest.cc b/chrome/browser/chromeos/kiosk_next_home/app_controller_service_unittest.cc
index 169c688..6fb8d54 100644
--- a/chrome/browser/chromeos/kiosk_next_home/app_controller_service_unittest.cc
+++ b/chrome/browser/chromeos/kiosk_next_home/app_controller_service_unittest.cc
@@ -23,10 +23,14 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/constants/chromeos_switches.h"
 #include "components/arc/test/fake_app_instance.h"
+#include "components/keyed_service/core/keyed_service.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/display/types/display_constants.h"
+#include "ui/events/event_constants.h"
 
 namespace chromeos {
 namespace kiosk_next_home {
@@ -61,13 +65,36 @@
   std::vector<mojom::AppPtr> app_updates_;
 };
 
+// Mock instance for the AppServiceProxy. It only overrides a subset of the
+// methods provided by the proxy since we expect that most tests can be written
+// with their real implementations (i.e. AppRegistryCache()).
+class MockAppServiceProxy : public KeyedService, public apps::AppServiceProxy {
+ public:
+  static MockAppServiceProxy* OverrideRealProxyForProfile(Profile* profile) {
+    return static_cast<MockAppServiceProxy*>(
+        apps::AppServiceProxyFactory::GetInstance()->SetTestingFactoryAndUse(
+            profile, base::BindRepeating([](content::BrowserContext* context) {
+              return static_cast<std::unique_ptr<KeyedService>>(
+                  std::make_unique<MockAppServiceProxy>());
+            })));
+  }
+
+  // apps::AppServiceProxy:
+  MOCK_METHOD4(Launch,
+               void(const std::string& app_id,
+                    int32_t event_flags,
+                    apps::mojom::LaunchSource launch_source,
+                    int64_t display_id));
+  MOCK_METHOD1(Uninstall, void(const std::string& app_id));
+};
+
 class AppControllerServiceTest : public testing::Test {
  protected:
   void SetUp() override {
     profile_ = std::make_unique<TestingProfile>();
 
     arc_test_.SetUp(profile());
-    proxy_ = apps::AppServiceProxyFactory::GetForProfile(profile());
+    proxy_ = MockAppServiceProxy::OverrideRealProxyForProfile(profile());
 
     app_controller_service_ = AppControllerService::Get(profile());
 
@@ -81,6 +108,8 @@
 
   Profile* profile() { return profile_.get(); }
 
+  MockAppServiceProxy* proxy() { return proxy_; }
+
   AppControllerService* service() { return app_controller_service_; }
 
   std::string GetAppIdFromAndroidPackage(const std::string& package) {
@@ -125,7 +154,7 @@
   // returns them in a map keyed by their |app_id|.
   AppMap GetAppsFromController() {
     AppMap apps;
-    app_controller_service_->GetApps(base::BindLambdaForTesting(
+    service()->GetApps(base::BindLambdaForTesting(
         [&apps](std::vector<mojom::AppPtr> app_list) {
           for (const auto& app : app_list) {
             apps[app->app_id] = app.Clone();
@@ -160,7 +189,7 @@
     bool returned_success;
     std::string returned_android_id;
 
-    app_controller_service_->GetArcAndroidId(base::BindLambdaForTesting(
+    service()->GetArcAndroidId(base::BindLambdaForTesting(
         [&returned_success, &returned_android_id](
             bool success, const std::string& android_id) {
           returned_success = success;
@@ -230,8 +259,8 @@
   content::TestBrowserThreadBundle test_browser_thread_bundle_;
   std::unique_ptr<TestingProfile> profile_;
   ArcAppTest arc_test_;
-  apps::AppServiceProxy* proxy_;
-  AppControllerService* app_controller_service_;
+  MockAppServiceProxy* proxy_ = nullptr;
+  AppControllerService* app_controller_service_ = nullptr;
   std::unique_ptr<FakeAppControllerClient> client_;
 
   void ExpectEqualApps(const mojom::App& expected_app,
@@ -651,5 +680,19 @@
   ExpectAppChangedUpdates({first_app_state});
 }
 
+TEST_F(AppControllerServiceTest, LaunchAppCallsAppServiceCorrectly) {
+  EXPECT_CALL(*proxy(), Launch("fake_app_id", ui::EventFlags::EF_NONE,
+                               apps::mojom::LaunchSource::kFromKioskNextHome,
+                               display::kDefaultDisplayId));
+
+  service()->LaunchApp("fake_app_id");
+}
+
+TEST_F(AppControllerServiceTest, UninstallAppCallsAppServiceCorrectly) {
+  EXPECT_CALL(*proxy(), Uninstall("fake_app_id"));
+
+  service()->UninstallApp("fake_app_id");
+}
+
 }  // namespace kiosk_next_home
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/session/chrome_session_manager.cc b/chrome/browser/chromeos/login/session/chrome_session_manager.cc
index f306d370..afc5a99 100644
--- a/chrome/browser/chromeos/login/session/chrome_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/chrome_session_manager.cc
@@ -31,6 +31,7 @@
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/chromeos/policy/app_install_event_log_manager_wrapper.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/tether/tether_service.h"
 #include "chrome/browser/chromeos/tpm_firmware_update_notification.h"
@@ -194,6 +195,11 @@
 
   UserSessionManager::GetInstance()->CheckEolStatus(user_profile);
   tpm_firmware_update::ShowNotificationIfNeeded(user_profile);
+  g_browser_process->platform_part()
+      ->browser_policy_connector_chromeos()
+      ->GetTPMAutoUpdateModePolicyHandler()
+      ->ShowTPMAutoUpdateNotificationIfNeeded();
+
   ArcTermsOfServiceScreen::MaybeLaunchArcSettings(user_profile);
   SyncConsentScreen::MaybeLaunchSyncConsentSettings(user_profile);
   UserSessionManager::GetInstance()->StartAccountManagerMigration(user_profile);
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index 0e02efe..ec87b0d 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -76,6 +76,7 @@
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/chromeos/policy/app_install_event_log_manager_wrapper.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/tether/tether_service.h"
@@ -2185,6 +2186,11 @@
   // and show the message accordingly.
   tpm_firmware_update::ShowNotificationIfNeeded(profile);
 
+  g_browser_process->platform_part()
+      ->browser_policy_connector_chromeos()
+      ->GetTPMAutoUpdateModePolicyHandler()
+      ->ShowTPMAutoUpdateNotificationIfNeeded();
+
   if (should_launch_browser_) {
     ArcTermsOfServiceScreen::MaybeLaunchArcSettings(profile);
     SyncConsentScreen::MaybeLaunchSyncConsentSettings(profile);
diff --git a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
index 545fe4e3..7d45d80 100644
--- a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
+++ b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
@@ -53,6 +53,7 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
+#include "content/public/browser/storage_partition.h"
 #include "content/public/test/browser_test_utils.h"
 #include "extensions/browser/extension_host.h"
 #include "extensions/browser/process_manager.h"
@@ -309,9 +310,9 @@
     test::OobeJS().ExpectTrue("!!document.querySelector('#account-picker')");
     test::OobeJS().ExpectTrue("!!document.querySelector('#pod-row')");
 
-    std::string account_id = PickAccountId(
-        ProfileManager::GetPrimaryUserProfile(), kTestGaiaId, kTestEmail);
-
+    // PickAccountId does not work at this point as the primary user profile has
+    // not yet been created.
+    const std::string account_id = kTestEmail;
     EXPECT_EQ(GetOAuthStatusFromLocalState(account_id),
               user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
 
@@ -320,6 +321,7 @@
         TryToLogin(AccountId::FromUserEmailGaiaId(kTestEmail, kTestGaiaId),
                    kTestAccountPassword));
     Profile* profile = ProfileManager::GetPrimaryUserProfile();
+    ASSERT_EQ(account_id, PickAccountId(profile, kTestGaiaId, kTestEmail));
 
     // Wait for the session merge to finish.
     WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_DONE);
@@ -483,54 +485,38 @@
   DISALLOW_COPY_AND_ASSIGN(OAuth2Test);
 };
 
-class CookieReader : public base::RefCountedThreadSafe<CookieReader> {
+class CookieReader {
  public:
-  CookieReader() {}
+  CookieReader() = default;
+  ~CookieReader() = default;
 
   void ReadCookies(Profile* profile) {
-    context_ = profile->GetRequestContext();
-    base::PostTaskWithTraits(
-        FROM_HERE, {content::BrowserThread::IO},
-        base::BindOnce(&CookieReader::ReadCookiesOnIOThread, this));
-    run_loop_ = std::make_unique<base::RunLoop>();
-    run_loop_->Run();
+    base::RunLoop run_loop;
+    content::BrowserContext::GetDefaultStoragePartition(profile)
+        ->GetCookieManagerForBrowserProcess()
+        ->GetAllCookies(base::BindOnce(&CookieReader::OnGotAllCookies,
+                                       base::Unretained(this),
+                                       run_loop.QuitClosure()));
+    run_loop.Run();
   }
 
   std::string GetCookieValue(const std::string& name) {
-    for (std::vector<net::CanonicalCookie>::const_iterator iter =
-             cookie_list_.begin();
-         iter != cookie_list_.end(); ++iter) {
-      if (iter->Name() == name) {
-        return iter->Value();
+    for (const auto& item : cookie_list_) {
+      if (item.Name() == name) {
+        return item.Value();
       }
     }
     return std::string();
   }
 
  private:
-  friend class base::RefCountedThreadSafe<CookieReader>;
-
-  virtual ~CookieReader() {}
-
-  void ReadCookiesOnIOThread() {
-    context_->GetURLRequestContext()->cookie_store()->GetAllCookiesAsync(
-        base::BindOnce(&CookieReader::OnGetAllCookiesOnUIThread, this));
-  }
-
-  void OnGetAllCookiesOnUIThread(
-      const net::CookieList& cookies,
-      const net::CookieStatusList& excluded_cookies) {
+  void OnGotAllCookies(base::OnceClosure callback,
+                       const net::CookieList& cookies) {
     cookie_list_ = cookies;
-    base::PostTaskWithTraits(
-        FROM_HERE, {content::BrowserThread::UI},
-        base::BindOnce(&CookieReader::OnCookiesReadyOnUIThread, this));
+    std::move(callback).Run();
   }
 
-  void OnCookiesReadyOnUIThread() { run_loop_->Quit(); }
-
-  scoped_refptr<net::URLRequestContextGetter> context_;
   net::CookieList cookie_list_;
-  std::unique_ptr<base::RunLoop> run_loop_;
 
   DISALLOW_COPY_AND_ASSIGN(CookieReader);
 };
@@ -547,10 +533,10 @@
 
   EXPECT_EQ(GetOAuthStatusFromLocalState(account_id),
             user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
-  scoped_refptr<CookieReader> cookie_reader(new CookieReader());
-  cookie_reader->ReadCookies(GetProfile());
-  EXPECT_EQ(cookie_reader->GetCookieValue("SID"), kTestSessionSIDCookie);
-  EXPECT_EQ(cookie_reader->GetCookieValue("LSID"), kTestSessionLSIDCookie);
+  CookieReader cookie_reader;
+  cookie_reader.ReadCookies(GetProfile());
+  EXPECT_EQ(cookie_reader.GetCookieValue("SID"), kTestSessionSIDCookie);
+  EXPECT_EQ(cookie_reader.GetCookieValue("LSID"), kTestSessionLSIDCookie);
 }
 
 // MergeSession test is running merge session process for an existing profile
@@ -561,35 +547,33 @@
   SetupGaiaServerForUnexpiredAccount();
   SimulateNetworkOnline();
   LoginAsExistingUser();
-  scoped_refptr<CookieReader> cookie_reader(new CookieReader());
-  cookie_reader->ReadCookies(GetProfile());
+  CookieReader cookie_reader;
+  cookie_reader.ReadCookies(GetProfile());
   // These are still cookie values from the initial session since
   // /ListAccounts
-  EXPECT_EQ(cookie_reader->GetCookieValue("SID"), kTestSessionSIDCookie);
-  EXPECT_EQ(cookie_reader->GetCookieValue("LSID"), kTestSessionLSIDCookie);
+  EXPECT_EQ(cookie_reader.GetCookieValue("SID"), kTestSessionSIDCookie);
+  EXPECT_EQ(cookie_reader.GetCookieValue("LSID"), kTestSessionLSIDCookie);
 }
 
 // MergeSession test is running merge session process for an existing profile
 // that was generated in PRE_PRE_MergeSession test.
-// Disabled due to flakiness: crbug.com/496832
-IN_PROC_BROWSER_TEST_F(OAuth2Test, DISABLED_PRE_MergeSession) {
+IN_PROC_BROWSER_TEST_F(OAuth2Test, PRE_MergeSession) {
   SetupGaiaServerForExpiredAccount();
   SimulateNetworkOnline();
   LoginAsExistingUser();
-  scoped_refptr<CookieReader> cookie_reader(new CookieReader());
-  cookie_reader->ReadCookies(GetProfile());
+  CookieReader cookie_reader;
+  cookie_reader.ReadCookies(GetProfile());
   // These should be cookie values that we generated by calling /MergeSession,
   // since /ListAccounts should have tell us that the initial session cookies
   // are stale.
-  EXPECT_EQ(cookie_reader->GetCookieValue("SID"), kTestSession2SIDCookie);
-  EXPECT_EQ(cookie_reader->GetCookieValue("LSID"), kTestSession2LSIDCookie);
+  EXPECT_EQ(cookie_reader.GetCookieValue("SID"), kTestSession2SIDCookie);
+  EXPECT_EQ(cookie_reader.GetCookieValue("LSID"), kTestSession2LSIDCookie);
 }
 
 // MergeSession test is attempting to merge session for an existing profile
 // that was generated in PRE_PRE_MergeSession test. This attempt should fail
 // since FakeGaia instance isn't configured to return relevant tokens/cookies.
-// Disabled due to flakiness: crbug.com/496832
-IN_PROC_BROWSER_TEST_F(OAuth2Test, DISABLED_MergeSession) {
+IN_PROC_BROWSER_TEST_F(OAuth2Test, MergeSession) {
   SimulateNetworkOnline();
 
   content::WindowedNotificationObserver(
@@ -600,7 +584,9 @@
   test::OobeJS().ExpectTrue("!!document.querySelector('#account-picker')");
   test::OobeJS().ExpectTrue("!!document.querySelector('#pod-row')");
 
-  std::string account_id = PickAccountId(GetProfile(), kTestGaiaId, kTestEmail);
+  // PickAccountId does not work at this point as the primary user profile has
+  // not yet been created.
+  const std::string account_id = kTestEmail;
   EXPECT_EQ(GetOAuthStatusFromLocalState(account_id),
             user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
 
@@ -608,6 +594,8 @@
       TryToLogin(AccountId::FromUserEmailGaiaId(kTestEmail, kTestGaiaId),
                  kTestAccountPassword));
 
+  ASSERT_EQ(account_id, PickAccountId(GetProfile(), kTestGaiaId, kTestEmail));
+
   // Wait for the session merge to finish.
   WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_FAILED);
 
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
index 31f17e1..134026c 100644
--- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
+++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -243,7 +243,7 @@
 
   tpm_auto_update_mode_policy_handler_ =
       std::make_unique<TPMAutoUpdateModePolicyHandler>(
-          chromeos::CrosSettings::Get());
+          chromeos::CrosSettings::Get(), local_state);
 }
 
 void BrowserPolicyConnectorChromeOS::PreShutdown() {
diff --git a/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.cc b/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.cc
index ee7af931..29c3b640 100644
--- a/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.cc
+++ b/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.cc
@@ -7,13 +7,20 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/tpm_firmware_update.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/common/pref_names.h"
 #include "chromeos/dbus/session_manager/session_manager_client.h"
 #include "chromeos/settings/cros_settings_names.h"
 #include "chromeos/settings/cros_settings_provider.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+#include "components/user_manager/user_manager.h"
 
 namespace {
 
@@ -21,6 +28,9 @@
 const base::TimeDelta kFirmwareAvailabilityCheckerTimeout =
     base::TimeDelta::FromSeconds(20);
 
+const base::TimeDelta kTPMUpdatePlannedNotificationWaitTime =
+    base::TimeDelta::FromDays(1);
+
 // Reads the value of the the device setting key
 // TPMFirmwareUpdateSettings.AutoUpdateMode from a trusted store. If the value
 // is temporarily untrusted |callback| will be invoked later when trusted values
@@ -71,8 +81,12 @@
 namespace policy {
 
 TPMAutoUpdateModePolicyHandler::TPMAutoUpdateModePolicyHandler(
-    chromeos::CrosSettings* cros_settings)
-    : cros_settings_(cros_settings), weak_factory_(this) {
+    chromeos::CrosSettings* cros_settings,
+    PrefService* local_state)
+    : cros_settings_(cros_settings),
+      local_state_(local_state),
+      weak_factory_(this) {
+  DCHECK(local_state_);
   policy_subscription_ = cros_settings_->AddSettingsObserver(
       chromeos::kTPMFirmwareUpdateSettings,
       base::BindRepeating(&TPMAutoUpdateModePolicyHandler::OnPolicyChanged,
@@ -81,6 +95,12 @@
   update_checker_callback_ =
       base::BindRepeating(&TPMAutoUpdateModePolicyHandler::CheckForUpdate,
                           weak_factory_.GetWeakPtr());
+
+  show_notfication_callback_ =
+      base::BindRepeating(&chromeos::ShowAutoUpdateNotification);
+
+  notification_timer_ = std::make_unique<base::OneShotTimer>();
+
   // Fire it once so we're sure we get an invocation on startup.
   OnPolicyChanged();
 }
@@ -95,11 +115,20 @@
 
   if (auto_update_mode == AutoUpdateMode::kNever ||
       auto_update_mode == AutoUpdateMode::kEnrollment) {
+    if (notification_timer_->IsRunning())
+      notification_timer_->Stop();
     return;
   }
 
-  if (auto_update_mode == AutoUpdateMode::kWithoutAcknowledgment)
-    update_checker_callback_.Run(base::BindOnce(&OnUpdateAvailableCheckResult));
+  if (auto_update_mode == AutoUpdateMode::kUserAcknowledgment) {
+    if (!WasTPMUpdateOnNextRebootNotificationShown()) {
+      update_checker_callback_.Run(base::BindOnce(
+          &TPMAutoUpdateModePolicyHandler::ShowTPMAutoUpdateNotification,
+          weak_factory_.GetWeakPtr()));
+      return;
+    }
+  }
+  update_checker_callback_.Run(base::BindOnce(&OnUpdateAvailableCheckResult));
 }
 
 void TPMAutoUpdateModePolicyHandler::CheckForUpdate(
@@ -123,6 +152,11 @@
   update_checker_callback_ = callback;
 }
 
+void TPMAutoUpdateModePolicyHandler::SetShowNotificationCallbackForTesting(
+    const ShowNotificationCallback& callback) {
+  show_notfication_callback_ = callback;
+}
+
 void TPMAutoUpdateModePolicyHandler::UpdateOnEnrollmentIfNeeded() {
   AutoUpdateMode auto_update_mode = GetTPMAutoUpdateModeSetting(
       cros_settings_,
@@ -140,4 +174,98 @@
   }
 }
 
+void TPMAutoUpdateModePolicyHandler::ShowTPMAutoUpdateNotificationIfNeeded() {
+  AutoUpdateMode auto_update_mode = GetTPMAutoUpdateModeSetting(
+      cros_settings_,
+      base::BindRepeating(&TPMAutoUpdateModePolicyHandler::OnPolicyChanged,
+                          weak_factory_.GetWeakPtr()));
+
+  if (auto_update_mode != AutoUpdateMode::kUserAcknowledgment)
+    return;
+
+  update_checker_callback_.Run(base::BindOnce(
+      &TPMAutoUpdateModePolicyHandler::ShowTPMAutoUpdateNotification,
+      weak_factory_.GetWeakPtr()));
+}
+
+void TPMAutoUpdateModePolicyHandler::ShowTPMAutoUpdateNotification(
+    bool update_available) {
+  if (!update_available)
+    return;
+
+  if (!user_manager::UserManager::IsInitialized())
+    return;
+
+  const user_manager::UserManager* user_manager =
+      user_manager::UserManager::Get();
+  if (!user_manager->IsUserLoggedIn() || user_manager->IsLoggedInAsKioskApp())
+    return;
+
+  Profile* profile = ProfileManager::GetActiveUserProfile();
+  if (!profile)
+    return;
+
+  base::Time notification_shown =
+      local_state_->GetTime(prefs::kTPMUpdatePlannedNotificationShownTime);
+
+  if (notification_shown == base::Time::Min()) {
+    notification_shown = base::Time::Now();
+    local_state_->SetTime(prefs::kTPMUpdatePlannedNotificationShownTime,
+                          notification_shown);
+    show_notfication_callback_.Run(
+        chromeos::TpmAutoUpdateUserNotification::kPlanned, profile);
+  }
+
+  // Show update on next reboot notification after
+  // |kTPMUpdatePlannedNotificationWaitTime|.
+  base::Time show_reboot_notification_time =
+      notification_shown + kTPMUpdatePlannedNotificationWaitTime;
+
+  if (show_reboot_notification_time <= base::Time::Now()) {
+    if (notification_timer_->IsRunning())
+      notification_timer_->Stop();
+    ShowTPMUpdateOnNextRebootNotification();
+    return;
+  }
+
+  // Set a timer that will display the update on next reboot notification after
+  // 24 hours.
+  if (notification_timer_->IsRunning())
+    return;
+  notification_timer_->Start(
+      FROM_HERE, show_reboot_notification_time - base::Time::Now(), this,
+      &TPMAutoUpdateModePolicyHandler::ShowTPMUpdateOnNextRebootNotification);
+}
+
+bool TPMAutoUpdateModePolicyHandler::
+    WasTPMUpdateOnNextRebootNotificationShown() {
+  return local_state_->GetBoolean(
+      prefs::kTPMUpdateOnNextRebootNotificationShown);
+}
+
+// static
+void TPMAutoUpdateModePolicyHandler::RegisterPrefs(
+    PrefRegistrySimple* registry) {
+  registry->RegisterTimePref(prefs::kTPMUpdatePlannedNotificationShownTime,
+                             base::Time::Min());
+  registry->RegisterBooleanPref(prefs::kTPMUpdateOnNextRebootNotificationShown,
+                                false);
+}
+
+void TPMAutoUpdateModePolicyHandler::ShowTPMUpdateOnNextRebootNotification() {
+  Profile* profile = ProfileManager::GetActiveUserProfile();
+  if (!profile)
+    return;
+  local_state_->SetBoolean(prefs::kTPMUpdateOnNextRebootNotificationShown,
+                           true);
+
+  show_notfication_callback_.Run(
+      chromeos::TpmAutoUpdateUserNotification::kOnNextReboot, profile);
+}
+
+void TPMAutoUpdateModePolicyHandler::SetNotificationTimerForTesting(
+    std::unique_ptr<base::OneShotTimer> timer) {
+  notification_timer_ = std::move(timer);
+}
+
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h b/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h
index 467625ea..e53921e5 100644
--- a/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h
+++ b/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h
@@ -11,6 +11,15 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/chromeos/ui/tpm_auto_update_notification.h"
+
+class PrefRegistrySimple;
+class PrefService;
+class Profile;
+
+namespace base {
+class OneShotTimer;
+}
 
 namespace policy {
 
@@ -38,34 +47,70 @@
   using UpdateCheckerCallback =
       base::RepeatingCallback<void(base::OnceCallback<void(bool)> callback)>;
 
-  explicit TPMAutoUpdateModePolicyHandler(
-      chromeos::CrosSettings* cros_settings);
+  // Will be invoked by TPMAutoUpdateModePolicyHandler to display a notification
+  // informing the user that a TPM update which will clear user data is planned
+  // in 24 hours or at next reboot, depending on |notification_type|.
+  using ShowNotificationCallback = base::RepeatingCallback<void(
+      chromeos::TpmAutoUpdateUserNotification notification_type,
+      Profile* profile)>;
+
+  TPMAutoUpdateModePolicyHandler(chromeos::CrosSettings* cros_settings,
+                                 PrefService* local_state);
   ~TPMAutoUpdateModePolicyHandler();
 
   // Sets a UpdateCheckerCallback for testing.
   void SetUpdateCheckerCallbackForTesting(
       const UpdateCheckerCallback& callback);
 
+  void SetShowNotificationCallbackForTesting(
+      const ShowNotificationCallback& callback);
+
+  void SetNotificationTimerForTesting(
+      std::unique_ptr<base::OneShotTimer> timer);
+
   // Updates the TPM firmware if the device is set to update at enrollment via
   // device policy option TPMFirmwareUpdateSettings.AutoUpdateMode. If the TPM
   // firmware is not vulnerable the method will return without updating.
   void UpdateOnEnrollmentIfNeeded();
 
+  // Shows notifications informing the user about a planned auto-update that
+  // will clear user data. Notifications are shown only if the TPM firmware
+  // needs to be updated and the device policy
+  // TPMFirmwareUpdateSettings.AutoUpdateMode is set to |UserAcknowledgment|.
+  void ShowTPMAutoUpdateNotificationIfNeeded();
+
+  static void RegisterPrefs(PrefRegistrySimple* registry);
+
  private:
   void OnPolicyChanged();
 
+  // Called by the TPM firmware update availability checker via
+  // |UpdateCheckerCallback|. Shows TPM auto-update notifications if
+  // |update_available| is true.
+  void ShowTPMAutoUpdateNotification(bool update_available);
+
   static void OnUpdateAvailableCheckResult(bool update_available);
 
   // Check if a TPM firmware update is available.
   void CheckForUpdate(base::OnceCallback<void(bool)> callback);
 
+  bool WasTPMUpdateOnNextRebootNotificationShown();
+
+  void ShowTPMUpdateOnNextRebootNotification();
+
   chromeos::CrosSettings* cros_settings_;
 
+  PrefService* local_state_;
+
+  std::unique_ptr<base::OneShotTimer> notification_timer_;
+
   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
       policy_subscription_;
 
   UpdateCheckerCallback update_checker_callback_;
 
+  ShowNotificationCallback show_notfication_callback_;
+
   base::WeakPtrFactory<TPMAutoUpdateModePolicyHandler> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(TPMAutoUpdateModePolicyHandler);
diff --git a/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler_unittest.cc b/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler_unittest.cc
index 55a47e8..5320ced 100644
--- a/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler_unittest.cc
+++ b/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler_unittest.cc
@@ -9,21 +9,43 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/run_loop.h"
+#include "base/timer/mock_timer.h"
+#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/chromeos/settings/scoped_testing_cros_settings.h"
 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
 #include "chrome/browser/chromeos/tpm_firmware_update.h"
+#include "chrome/browser/prefs/browser_prefs.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/testing_profile_manager.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/session_manager/fake_session_manager_client.h"
 #include "chromeos/settings/cros_settings_names.h"
 #include "chromeos/tpm/stub_install_attributes.h"
+#include "components/account_id/account_id.h"
+#include "components/prefs/pref_service.h"
+#include "components/prefs/testing_pref_service.h"
+#include "components/user_manager/fake_user_manager.h"
+#include "components/user_manager/scoped_user_manager.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+namespace {
+constexpr char kFakeUserName[] = "test@example.com";
+constexpr char kFakeGaiaId[] = "1234567890";
+}  // namespace
+
 namespace policy {
 
 class TPMAutoUpdateModePolicyHandlerTest : public testing::Test {
  public:
-  TPMAutoUpdateModePolicyHandlerTest() {
+  TPMAutoUpdateModePolicyHandlerTest()
+      : local_state_(TestingBrowserProcess::GetGlobal()),
+        user_manager_(new chromeos::FakeChromeUserManager()),
+        user_manager_enabler_(base::WrapUnique(user_manager_)),
+        profile_manager_(TestingBrowserProcess::GetGlobal(), &local_state_) {
+    CHECK(profile_manager_.SetUp());
     chromeos::SessionManagerClient::InitializeFakeInMemory();
   }
 
@@ -44,10 +66,23 @@
     std::move(callback).Run(update_available_);
   }
 
+  void ShowNotification(
+      chromeos::TpmAutoUpdateUserNotification notification_type,
+      Profile* profile) {
+    last_shown_notification_ = notification_type;
+  }
+
  protected:
   bool update_available_ = false;
+  chromeos::TpmAutoUpdateUserNotification last_shown_notification_ =
+      chromeos::TpmAutoUpdateUserNotification::kNone;
 
   content::TestBrowserThreadBundle thread_bundle_;
+  ScopedTestingLocalState local_state_;
+  chromeos::FakeChromeUserManager* user_manager_;
+  user_manager::ScopedUserManager user_manager_enabler_;
+  TestingProfileManager profile_manager_;
+
   // Set up fake install attributes to pretend the machine is enrolled.
   chromeos::ScopedStubInstallAttributes test_install_attributes_{
       chromeos::StubInstallAttributes::CreateCloudManaged("example.com",
@@ -61,7 +96,7 @@
 // policy option TPMFirmwareUpdateSettings.AutoUpdateMode.
 TEST_F(TPMAutoUpdateModePolicyHandlerTest, PolicyUpdatesTriggered) {
   TPMAutoUpdateModePolicyHandler tpm_update_policy_handler(
-      chromeos::CrosSettings::Get());
+      chromeos::CrosSettings::Get(), local_state_.Get());
   tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting(
       base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate,
                           weak_factory_.GetWeakPtr()));
@@ -99,7 +134,7 @@
 // state preserving update is not available.
 TEST_F(TPMAutoUpdateModePolicyHandlerTest, NoUpdatesAvailable) {
   TPMAutoUpdateModePolicyHandler tpm_update_policy_handler(
-      chromeos::CrosSettings::Get());
+      chromeos::CrosSettings::Get(), local_state_.Get());
   tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting(
       base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate,
                           weak_factory_.GetWeakPtr()));
@@ -112,4 +147,141 @@
                    ->start_tpm_firmware_update_call_count());
 }
 
+// Verify that the notification informing the user that an update is planned
+// after 24 hours is shown.
+TEST_F(TPMAutoUpdateModePolicyHandlerTest, ShowPlannedUpdateNotification) {
+  TPMAutoUpdateModePolicyHandler tpm_update_policy_handler(
+      chromeos::CrosSettings::Get(), local_state_.Get());
+  tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting(
+      base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate,
+                          weak_factory_.GetWeakPtr()));
+  tpm_update_policy_handler.SetShowNotificationCallbackForTesting(
+      base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::ShowNotification,
+                          base::Unretained(this)));
+
+  const AccountId account_id(
+      AccountId::FromUserEmailGaiaId(kFakeUserName, kFakeGaiaId));
+  user_manager_->AddUser(account_id);
+  user_manager_->LoginUser(account_id);
+
+  update_available_ = true;
+
+  EXPECT_EQ(last_shown_notification_,
+            chromeos::TpmAutoUpdateUserNotification::kNone);
+
+  SetAutoUpdateMode(AutoUpdateMode::kUserAcknowledgment);
+  base::RunLoop().RunUntilIdle();
+
+  // TPM update is not triggered.
+  EXPECT_EQ(0, chromeos::FakeSessionManagerClient::Get()
+                   ->start_tpm_firmware_update_call_count());
+
+  EXPECT_EQ(last_shown_notification_,
+            chromeos::TpmAutoUpdateUserNotification::kPlanned);
+}
+
+// Verify that the notification informing the user that an update will happen at
+// the next reboot is shown.
+TEST_F(TPMAutoUpdateModePolicyHandlerTest,
+       ShowUpdateOnRebootNotificationNoTimer) {
+  TPMAutoUpdateModePolicyHandler tpm_update_policy_handler(
+      chromeos::CrosSettings::Get(), local_state_.Get());
+  tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting(
+      base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate,
+                          weak_factory_.GetWeakPtr()));
+  tpm_update_policy_handler.SetShowNotificationCallbackForTesting(
+      base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::ShowNotification,
+                          base::Unretained(this)));
+
+  const AccountId account_id(
+      AccountId::FromUserEmailGaiaId(kFakeUserName, kFakeGaiaId));
+  user_manager_->AddUser(account_id);
+  user_manager_->LoginUser(account_id);
+
+  update_available_ = true;
+
+  // First notification was shwed more than 24 hours ago.
+  base::Time yesterday = base::Time::Now() - base::TimeDelta::FromHours(25);
+  local_state_.Get()->SetInt64(
+      prefs::kTPMUpdatePlannedNotificationShownTime,
+      yesterday.ToDeltaSinceWindowsEpoch().InSeconds());
+
+  SetAutoUpdateMode(AutoUpdateMode::kUserAcknowledgment);
+  base::RunLoop().RunUntilIdle();
+
+  // TPM update is not triggered.
+  EXPECT_EQ(0, chromeos::FakeSessionManagerClient::Get()
+                   ->start_tpm_firmware_update_call_count());
+
+  // Show planned update notification.
+  EXPECT_EQ(last_shown_notification_,
+            chromeos::TpmAutoUpdateUserNotification::kOnNextReboot);
+}
+
+// Verify that the notification informing the user that an update will happen at
+// the next reboot is triggered by the timer.
+TEST_F(TPMAutoUpdateModePolicyHandlerTest,
+       ShowUpdateOnRebootNotificationTimer) {
+  TPMAutoUpdateModePolicyHandler tpm_update_policy_handler(
+      chromeos::CrosSettings::Get(), local_state_.Get());
+  tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting(
+      base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate,
+                          weak_factory_.GetWeakPtr()));
+  tpm_update_policy_handler.SetShowNotificationCallbackForTesting(
+      base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::ShowNotification,
+                          base::Unretained(this)));
+
+  auto mock_timer = std::make_unique<base::MockOneShotTimer>();
+  auto* mock_timer_ptr = mock_timer.get();
+
+  tpm_update_policy_handler.SetNotificationTimerForTesting(
+      std::move(mock_timer));
+
+  const AccountId account_id(
+      AccountId::FromUserEmailGaiaId(kFakeUserName, kFakeGaiaId));
+  user_manager_->AddUser(account_id);
+  user_manager_->LoginUser(account_id);
+
+  update_available_ = true;
+
+  SetAutoUpdateMode(AutoUpdateMode::kUserAcknowledgment);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(0, chromeos::FakeSessionManagerClient::Get()
+                   ->start_tpm_firmware_update_call_count());
+
+  // Show planned update notification.
+  EXPECT_EQ(last_shown_notification_,
+            chromeos::TpmAutoUpdateUserNotification::kPlanned);
+
+  mock_timer_ptr->Fire();
+
+  // Show update at reboot notification.
+  EXPECT_EQ(last_shown_notification_,
+            chromeos::TpmAutoUpdateUserNotification::kOnNextReboot);
+}
+
+// TPM update with user acknowlegment triggered.
+TEST_F(TPMAutoUpdateModePolicyHandlerTest, UpdateWithUserAcknowlegment) {
+  TPMAutoUpdateModePolicyHandler tpm_update_policy_handler(
+      chromeos::CrosSettings::Get(), local_state_.Get());
+  tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting(
+      base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate,
+                          weak_factory_.GetWeakPtr()));
+  tpm_update_policy_handler.SetShowNotificationCallbackForTesting(
+      base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::ShowNotification,
+                          base::Unretained(this)));
+
+  update_available_ = true;
+
+  // Update at next reboot notification already shown.
+  local_state_.Get()->SetBoolean(prefs::kTPMUpdateOnNextRebootNotificationShown,
+                                 true);
+  SetAutoUpdateMode(AutoUpdateMode::kUserAcknowledgment);
+  base::RunLoop().RunUntilIdle();
+
+  // Update is triggered.
+  EXPECT_EQ(1, chromeos::FakeSessionManagerClient::Get()
+                   ->start_tpm_firmware_update_call_count());
+}
+
 }  // namespace policy
diff --git a/chrome/browser/chromeos/ui/tpm_auto_update_notification.cc b/chrome/browser/chromeos/ui/tpm_auto_update_notification.cc
new file mode 100644
index 0000000..8aa1cca
--- /dev/null
+++ b/chrome/browser/chromeos/ui/tpm_auto_update_notification.cc
@@ -0,0 +1,69 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/ui/tpm_auto_update_notification.h"
+
+#include "ash/public/cpp/notification_utils.h"
+#include "base/bind.h"
+#include "base/strings/string16.h"
+#include "chrome/browser/notifications/notification_display_service.h"
+#include "chrome/browser/notifications/notification_display_service_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/grit/generated_resources.h"
+#include "components/prefs/pref_service.h"
+#include "components/vector_icons/vector_icons.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace chromeos {
+
+constexpr char kTPMPlannedAutoUpdateNotificationId[] =
+    "chrome://tpm_planned_firmware_auto_update";
+constexpr char kTPMAutoUpdateOnRebootNotificationId[] =
+    "chrome://tpm_firmware_auto_update_on_reboot";
+
+void ShowAutoUpdateNotification(TpmAutoUpdateUserNotification notification_type,
+                                Profile* profile) {
+  base::string16 title, text;
+  std::string notification_id;
+  bool pinned = false;
+
+  switch (notification_type) {
+    case TpmAutoUpdateUserNotification::kPlanned:
+      title = l10n_util::GetStringUTF16(
+          IDS_TPM_AUTO_UPDATE_PLANNED_NOTIFICATION_TITLE);
+      text = l10n_util::GetStringUTF16(
+          IDS_TPM_AUTO_UPDATE_PLANNED_NOTIFICATION_MESSAGE);
+      notification_id = kTPMPlannedAutoUpdateNotificationId;
+      break;
+    case TpmAutoUpdateUserNotification::kOnNextReboot:
+      title = l10n_util::GetStringUTF16(
+          IDS_TPM_AUTO_UPDATE_REBOOT_NOTIFICATION_TITLE);
+      text = l10n_util::GetStringUTF16(
+          IDS_TPM_AUTO_UPDATE_REBOOT_NOTIFICATION_MESSAGE);
+      notification_id = kTPMAutoUpdateOnRebootNotificationId;
+      pinned = true;
+      break;
+    default:
+      return;
+  }
+
+  std::unique_ptr<message_center::Notification> notification =
+      ash::CreateSystemNotification(
+          message_center::NOTIFICATION_TYPE_SIMPLE, notification_id, title,
+          text, base::string16() /*display_source*/, GURL(),
+          message_center::NotifierId(
+              message_center::NotifierType::SYSTEM_COMPONENT, notification_id),
+          message_center::RichNotificationData(),
+          new message_center::NotificationDelegate(),
+          vector_icons::kBusinessIcon,
+          message_center::SystemNotificationWarningLevel::NORMAL);
+  notification->set_priority(message_center::SYSTEM_PRIORITY);
+  notification->set_pinned(pinned);
+
+  NotificationDisplayServiceFactory::GetForProfile(profile)->Display(
+      NotificationHandler::Type::TRANSIENT, *notification,
+      nullptr /*metadata*/);
+}
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/ui/tpm_auto_update_notification.h b/chrome/browser/chromeos/ui/tpm_auto_update_notification.h
new file mode 100644
index 0000000..9d271bb
--- /dev/null
+++ b/chrome/browser/chromeos/ui/tpm_auto_update_notification.h
@@ -0,0 +1,31 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_UI_TPM_AUTO_UPDATE_NOTIFICATION_H_
+#define CHROME_BROWSER_CHROMEOS_UI_TPM_AUTO_UPDATE_NOTIFICATION_H_
+
+class Profile;
+
+namespace chromeos {
+
+// For the TPM firmware auto-update flow with user acknowledgment users will be
+// shown two notifications, one informing that an auto-update will be performed
+// at the first reboot after 24 hours and one displayed after at least 24 hours
+// informing that an update will happen at the next reboot.
+enum class TpmAutoUpdateUserNotification {
+  kNone = 0,
+  // Corresponds to the notification informing the user that an update that will
+  // clear user data will be performed at the first reboot after 24 hours.
+  kPlanned = 1,
+  // Corresponds to the notification informing the user that an update that will
+  // clear user data will be performed after the next reboot.
+  kOnNextReboot = 2
+};
+
+void ShowAutoUpdateNotification(TpmAutoUpdateUserNotification notification_type,
+                                Profile* profile);
+
+}  // namespace chromeos
+
+#endif  //  CHROME_BROWSER_CHROMEOS_UI_TPM_AUTO_UPDATE_NOTIFICATION_H_
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 83195747..a36cd56 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -168,11 +168,6 @@
     "expiry_milestone": 75
   },
   {
-    "name": "ash-shelf-color-scheme",
-    "owners": [ "manucornet" ],
-    "expiry_milestone": 76
-  },
-  {
     "name": "auto-fetch-on-net-error-page",
     "owners": [ "harringtond", "offline-dev" ],
     "expiry_milestone": 82
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 4669071b..0a291df 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -3005,17 +3005,6 @@
     "Enable unified desktop mode which allows a window to span multiple "
     "displays.";
 
-const char kAshShelfColorScheme[] = "Shelf color scheme in Chrome OS System UI";
-const char kAshShelfColorSchemeDescription[] =
-    "Specify how the color is derived from the wallpaper. This flag is only "
-    "used when the --ash-shelf-color flag is enabled. Defaults to Dark & Muted";
-const char kAshShelfColorSchemeLightVibrant[] = "Light & Vibrant";
-const char kAshShelfColorSchemeNormalVibrant[] = "Normal & Vibrant";
-const char kAshShelfColorSchemeDarkVibrant[] = "Dark & Vibrant";
-const char kAshShelfColorSchemeLightMuted[] = "Light & Muted";
-const char kAshShelfColorSchemeNormalMuted[] = "Normal & Muted";
-const char kAshShelfColorSchemeDarkMuted[] = "Dark & Muted";
-
 const char kBulkPrintersName[] = "Bulk Printers Policy";
 const char kBulkPrintersDescription[] = "Enables the new bulk printers policy";
 
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 38d717f..662fd77d 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1806,18 +1806,6 @@
 extern const char kAshEnableUnifiedDesktopName[];
 extern const char kAshEnableUnifiedDesktopDescription[];
 
-extern const char kAshShelfColorName[];
-extern const char kAshShelfColorDescription[];
-
-extern const char kAshShelfColorScheme[];
-extern const char kAshShelfColorSchemeDescription[];
-extern const char kAshShelfColorSchemeLightVibrant[];
-extern const char kAshShelfColorSchemeNormalVibrant[];
-extern const char kAshShelfColorSchemeDarkVibrant[];
-extern const char kAshShelfColorSchemeLightMuted[];
-extern const char kAshShelfColorSchemeNormalMuted[];
-extern const char kAshShelfColorSchemeDarkMuted[];
-
 extern const char kBulkPrintersName[];
 extern const char kBulkPrintersDescription[];
 
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 75917ffe..cbaf6a0c 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -740,6 +740,9 @@
   { key::kDeviceBootOnAcEnabled,
     ash::prefs::kDeviceBootOnAcEnabled,
     base::Value::Type::BOOLEAN },
+  { key::kSamlInSessionPasswordChangeEnabled,
+    prefs::kSamlInSessionPasswordChangeEnabled,
+    base::Value::Type::BOOLEAN },
 #endif  // defined(OS_CHROMEOS)
 
 // Metrics reporting is controlled by a platform specific policy for ChromeOS
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index b2d101462..8169d37c 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/accessibility/invert_bubble_prefs.h"
 #include "chrome/browser/browser_process_impl.h"
 #include "chrome/browser/chrome_content_browser_client.h"
+#include "chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h"
 #include "chrome/browser/chromeos/scheduler_configuration_manager.h"
 #include "chrome/browser/component_updater/component_updater_prefs.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
@@ -583,6 +584,7 @@
   policy::DeviceWallpaperImageHandler::RegisterPrefs(registry);
   policy::DMTokenStorage::RegisterPrefs(registry);
   policy::PolicyCertServiceFactory::RegisterPrefs(registry);
+  policy::TPMAutoUpdateModePolicyHandler::RegisterPrefs(registry);
   quirks::QuirksManager::RegisterPrefs(registry);
 #endif
 
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index d6143f9e..83d3ee6 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -65,6 +65,7 @@
 #include "chrome/browser/search_engines/template_url_fetcher_factory.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
 #include "chrome/browser/send_tab_to_self/send_tab_to_self_client_service_factory.h"
+#include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h"
 #include "chrome/browser/sessions/session_service_factory.h"
 #include "chrome/browser/sessions/tab_restore_service_factory.h"
 #include "chrome/browser/signin/about_signin_internals_factory.h"
@@ -377,7 +378,9 @@
 #if defined(OS_ANDROID)
   SearchPermissionsService::Factory::GetInstance();
 #endif
-  send_tab_to_self::SendTabToSelfClientServiceFactory::GetInstance();
+  if (send_tab_to_self::IsReceivingEnabled()) {
+    send_tab_to_self::SendTabToSelfClientServiceFactory::GetInstance();
+  }
 #if BUILDFLAG(ENABLE_SESSION_SERVICE)
   SessionServiceFactory::GetInstance();
 #endif
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc
index 70a64a5..7caa218 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -224,14 +224,13 @@
   GetDefaultStoragePartition(this)->GetNetworkContext()->ClearHostCache(
       nullptr, network::mojom::NetworkContext::ClearHostCacheCallback());
 
-  BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
-      this);
-  // The SimpleDependencyManager should always be called after the
+  // The SimpleDependencyManager should always be passed after the
   // BrowserContextDependencyManager. This is because the KeyedService instances
   // in the BrowserContextDependencyManager's dependency graph can depend on the
   // ones in the SimpleDependencyManager's graph.
-  SimpleDependencyManager::GetInstance()->DestroyKeyedServices(
-      GetSimpleFactoryKey());
+  DependencyManager::PerformInterlockedTwoPhaseShutdown(
+      BrowserContextDependencyManager::GetInstance(), this,
+      SimpleDependencyManager::GetInstance(), GetSimpleFactoryKey());
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   base::PostTaskWithTraits(
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 6ee37bc..8ff2f79 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -799,14 +799,13 @@
 
   FullBrowserTransitionManager::Get()->OnProfileDestroyed(this);
 
-  BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
-      this);
-  // The SimpleDependencyManager should always be called after the
+  // The SimpleDependencyManager should always be passed after the
   // BrowserContextDependencyManager. This is because the KeyedService instances
   // in the BrowserContextDependencyManager's dependency graph can depend on the
   // ones in the SimpleDependencyManager's graph.
-  SimpleDependencyManager::GetInstance()->DestroyKeyedServices(
-      GetSimpleFactoryKey());
+  DependencyManager::PerformInterlockedTwoPhaseShutdown(
+      BrowserContextDependencyManager::GetInstance(), this,
+      SimpleDependencyManager::GetInstance(), GetSimpleFactoryKey());
 
   // This causes the Preferences file to be written to disk.
   if (prefs_loaded)
diff --git a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
index 5c31a1a..b80baec1 100644
--- a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
@@ -1562,7 +1562,13 @@
   EXPECT_TRUE(IsTabDiscarded(browser4->tab_strip_model()->GetWebContentsAt(1)));
 }
 
-IN_PROC_BROWSER_TEST_F(TabManagerTest, UnfreezeTabOnNavigationEvent) {
+#if defined(OS_WIN)
+// Flaky: https://crbug.com/918701
+#define MAYBE_UnfreezeTabOnNavigationEvent DISABLED_UnfreezeTabOnNavigationEvent
+#else
+#define MAYBE_UnfreezeTabOnNavigationEvent UnfreezeTabOnNavigationEvent
+#endif
+IN_PROC_BROWSER_TEST_F(TabManagerTest, MAYBE_UnfreezeTabOnNavigationEvent) {
   TestTransitionFromActiveToPendingFreeze();
 
   browser()->tab_strip_model()->GetWebContentsAt(1)->GetController().Reload(
diff --git a/chrome/browser/resources/about_sys/about_sys.css b/chrome/browser/resources/about_sys/about_sys.css
index 8b626b540..6048d803 100644
--- a/chrome/browser/resources/about_sys/about_sys.css
+++ b/chrome/browser/resources/about_sys/about_sys.css
@@ -132,16 +132,11 @@
 
 .number-expanded,
 .number-collapsed  {
-  text-align: left;
+  text-align: start;
   text-overflow: ellipsis;
   width: 80%;
 }
 
-html[dir='rtl'] .number-expanded,
-html[dir='rtl'] .number-collapsed  {
-  text-align: right;
-}
-
 tr > *:nth-child(1),
 tr > *:nth-child(2) {
   border-inline-end: 1px solid rgb(181, 198, 222);
@@ -171,7 +166,7 @@
 }
 
 .spinner {
-  -webkit-animation: rotate 2s linear infinite;
+  animation: rotate 2s linear infinite;
   border: 4px solid rgb(239, 243, 255);
   border-radius: 50%;
   border-top: 4px solid rgb(82, 150, 222);
@@ -179,7 +174,7 @@
   width: 20px;
 }
 
-@-webkit-keyframes rotate {
+@keyframes rotate {
   0% { transform: rotate(0deg); }
   100% { transform: rotate(360deg); }
 }
diff --git a/chrome/browser/resources/about_sys/about_sys.html b/chrome/browser/resources/about_sys/about_sys.html
index d9cfd51..2c364771 100644
--- a/chrome/browser/resources/about_sys/about_sys.html
+++ b/chrome/browser/resources/about_sys/about_sys.html
@@ -4,12 +4,11 @@
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
     <title>$i18n{title}</title>
     <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-    <link rel="stylesheet" href="chrome://system/about_sys.css">
+    <link rel="stylesheet" href="about_sys.css">
     <script src="chrome://resources/js/util.js"></script>
-    <script src="chrome://resources/js/jstemplate_compiled.js"></script>
     <script src="chrome://resources/js/load_time_data.js"></script>
-    <script src="chrome://system/about_sys.js"></script>
-    <script src="chrome://system/strings.js"></script>
+    <script src="about_sys.js"></script>
+    <script src="strings.js"></script>
   </head>
   <body>
     <div id="header">
diff --git a/chrome/browser/resources/about_sys/about_sys.js b/chrome/browser/resources/about_sys/about_sys.js
index 097abdb..ec28d40 100644
--- a/chrome/browser/resources/about_sys/about_sys.js
+++ b/chrome/browser/resources/about_sys/about_sys.js
@@ -174,7 +174,7 @@
   updateLogEntries(systemInfo);
   const spinner = $('loadingIndicator');
   spinner.style.display = 'none';
-  spinner.style.webkitAnimationPlayState = 'paused';
+  spinner.style.animationPlayState = 'paused';
 }
 
 /**
diff --git a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js
index ab4af53f1..2c84504 100644
--- a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js
+++ b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js
@@ -683,9 +683,9 @@
     // Construct sub-model of active/idle events per each thread, active within
     // this interval.
     var eventsPerTid = {};
-    for (var cpuId = 0; cpuId < overviewBand.model.cpu.events.length; cpuId++) {
+    for (var cpuId = 0; cpuId < overviewBand.model.system.cpu.length; cpuId++) {
       var activeEvents = new Events(
-          overviewBand.model.cpu.events[cpuId], 3 /* kActive */,
+          overviewBand.model.system.cpu[cpuId], 3 /* kActive */,
           3 /* kActive */);
       var activeTid = 0;
       var index = activeEvents.getFirstAfter(minTimestamp);
@@ -715,7 +715,7 @@
     var totalTime = 0;
     for (var tid in eventsPerTid) {
       var thread = eventsPerTid[tid];
-      var pid = overviewBand.model.cpu.threads[tid].pid;
+      var pid = overviewBand.model.system.threads[tid].pid;
       if (!(pid in threadsPerPid)) {
         pids.push(pid);
         threadsPerPid[pid] = {};
@@ -750,8 +750,8 @@
       var pid = pids[i];
       var threads = threadsPerPid[pid].threads;
       var processName;
-      if (pid in overviewBand.model.cpu.threads) {
-        processName = overviewBand.model.cpu.threads[pid].name;
+      if (pid in overviewBand.model.system.threads) {
+        processName = overviewBand.model.system.threads[pid].name;
       } else {
         processName = 'Others';
       }
@@ -773,7 +773,7 @@
         var tid = threads[j].tid;
         bands.addBand(
             new Events(eventsPerTid[tid].events, 0, 1), cpuBandHeight, padding);
-        var threadName = overviewBand.model.cpu.threads[tid].name;
+        var threadName = overviewBand.model.system.threads[tid].name;
         var threadCpuUsage = 100.0 * threads[j].totalTime / duration;
         var threadInfo = threadName + ' ' + threadCpuUsage.toFixed(2) + '%';
         SVG.addText(
@@ -849,9 +849,9 @@
     this.model = model;
     var bandHeight = 6;
     var padding = 2;
-    for (var cpuId = 0; cpuId < this.model.cpu.events.length; cpuId++) {
+    for (var cpuId = 0; cpuId < this.model.system.cpu.length; cpuId++) {
       this.addBand(
-          new Events(this.model.cpu.events[cpuId], 0, 1), bandHeight, padding);
+          new Events(this.model.system.cpu[cpuId], 0, 1), bandHeight, padding);
     }
   }
 
diff --git a/chrome/browser/resources/local_ntp/animations.css b/chrome/browser/resources/local_ntp/animations.css
index cb2efa4..465d029a 100644
--- a/chrome/browser/resources/local_ntp/animations.css
+++ b/chrome/browser/resources/local_ntp/animations.css
@@ -49,7 +49,8 @@
   border-radius: 4px;
   font-size: 12px;
   font-weight: 500;
-  height: 32px;
+  line-height: 1.6;
+  min-height: 32px;
   padding: 0 16px;
   position: relative;
   transition-duration: 200ms;
diff --git a/chrome/browser/resources/local_ntp/custom_backgrounds.css b/chrome/browser/resources/local_ntp/custom_backgrounds.css
index 57b25e42..bc03c5e 100644
--- a/chrome/browser/resources/local_ntp/custom_backgrounds.css
+++ b/chrome/browser/resources/local_ntp/custom_backgrounds.css
@@ -581,9 +581,10 @@
   color: #FFF;
   display: inline-block;
   font-size: 13px;
-  height: 32px;
+  line-height: 1.6;
+  min-height: 32px;
   overflow: hidden;
-  padding: 8px 16px 0 16px;
+  padding: 0 16px;
   position: absolute;
   text-overflow: ellipsis;
   user-select: none;
diff --git a/chrome/browser/resources/local_ntp/custom_links_edit.css b/chrome/browser/resources/local_ntp/custom_links_edit.css
index d4c2cad..88fabe70 100644
--- a/chrome/browser/resources/local_ntp/custom_links_edit.css
+++ b/chrome/browser/resources/local_ntp/custom_links_edit.css
@@ -75,8 +75,8 @@
   caret-color: rgb(var(--GB600-rgb));
   color: rgb(var(--GG900-rgb));
   font-size: 13px;
-  height: 32px;
-  line-height: 24px;
+  line-height: 1.6;
+  min-height: 32px;
   outline: none;
   padding-inline-end: 8px;
   padding-inline-start: 8px;
diff --git a/chrome/browser/resources/settings/about_page/about_page.html b/chrome/browser/resources/settings/about_page/about_page.html
index d0c98a66..2228620 100644
--- a/chrome/browser/resources/settings/about_page/about_page.html
+++ b/chrome/browser/resources/settings/about_page/about_page.html
@@ -57,9 +57,10 @@
         margin-inline-end: var(--about-page-image-space);
       }
 
-      iron-icon {
+      .icon-container {
         margin-inline-end: var(--about-page-image-space);
         min-width: 32px;  /* The width of the product-logo img. */
+        text-align: center;
       }
 
       iron-icon[icon='settings:check-circle'] {
@@ -105,19 +106,21 @@
               src URL -->
             <!-- Set the icon from the iconset (when it's obsolete/EOL and
               when update is done) or set the src (when it's updating). -->
-            <iron-icon
-                hidden="[[!shouldShowIcons_(showUpdateStatus_)]]"
+            <div class="icon-container"
+                hidden="[[!shouldShowIcons_(showUpdateStatus_)]]">
+              <iron-icon
 <if expr="not chromeos">
-                icon$="[[getUpdateStatusIcon_(
-                    obsoleteSystemInfo_, currentUpdateStatusEvent_)]]"
-                src="[[getThrobberSrcIfUpdating_(obsoleteSystemInfo_, currentUpdateStatusEvent_)]]">
+                  icon$="[[getUpdateStatusIcon_(
+                      obsoleteSystemInfo_, currentUpdateStatusEvent_)]]"
+                  src="[[getThrobberSrcIfUpdating_(obsoleteSystemInfo_, currentUpdateStatusEvent_)]]">
 </if>
 <if expr="chromeos">
-                icon$="[[getUpdateStatusIcon_(
-                    hasEndOfLife_, currentUpdateStatusEvent_)]]"
-                src="[[getThrobberSrcIfUpdating_(hasEndOfLife_, currentUpdateStatusEvent_)]]">
+                  icon$="[[getUpdateStatusIcon_(
+                      hasEndOfLife_, currentUpdateStatusEvent_)]]"
+                  src="[[getThrobberSrcIfUpdating_(hasEndOfLife_, currentUpdateStatusEvent_)]]">
 </if>
-            </iron-icon>
+              </iron-icon>
+            </div>
             <div class="start padded">
               <div id="updateStatusMessage" hidden="[[!showUpdateStatus_]]">
                 <div
diff --git a/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc b/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc
index 7d7ba77f..e451244 100644
--- a/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc
+++ b/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc
@@ -8,6 +8,7 @@
 #include "base/memory/singleton.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h"
 #include "chrome/browser/sync/model_type_store_service_factory.h"
 #include "chrome/common/channel_info.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
@@ -39,6 +40,8 @@
 
 KeyedService* SendTabToSelfSyncServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
+  DCHECK(send_tab_to_self::IsReceivingEnabled());
+
   Profile* profile = Profile::FromBrowserContext(context);
 
   syncer::OnceModelTypeStoreFactory store_factory =
diff --git a/chrome/browser/ui/accelerator_utils.h b/chrome/browser/ui/accelerator_utils.h
index 3c274f7b..9c76d66 100644
--- a/chrome/browser/ui/accelerator_utils.h
+++ b/chrome/browser/ui/accelerator_utils.h
@@ -15,8 +15,7 @@
 
 // Returns true if the given |accelerator| is currently registered by
 // Chrome.
-bool IsChromeAccelerator(const ui::Accelerator& accelerator,
-                         Profile* profile);
+bool IsChromeAccelerator(const ui::Accelerator& accelerator, Profile* profile);
 
 ui::Accelerator GetPrimaryChromeAcceleratorForBookmarkPage();
 
diff --git a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
index 12f080d..228ddd0 100644
--- a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
@@ -19,6 +19,7 @@
 #include "components/autofill/core/common/autofill_util.h"
 #include "components/grit/components_scaled_resources.h"
 #include "components/strings/grit/components_strings.h"
+#include "components/vector_icons/vector_icons.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/color_palette.h"
@@ -230,10 +231,12 @@
     return gfx::CreateVectorIcon(omnibox::kHttpsInvalidIcon, kIconSize,
                                  gfx::kGoogleRed700);
   }
-  if (icon_str == "keyIcon")
+  if (icon_str == "keyIcon") {
     return gfx::CreateVectorIcon(kKeyIcon, kIconSize, gfx::kChromeIconGrey);
-  if (icon_str == "globeIcon")
+  }
+  if (icon_str == "globeIcon") {
     return gfx::CreateVectorIcon(kGlobeIcon, kIconSize, gfx::kChromeIconGrey);
+  }
   if (icon_str == "google") {
 #if defined(GOOGLE_CHROME_BUILD)
     return gfx::CreateVectorIcon(kGoogleGLogoIcon, kIconSize,
@@ -243,6 +246,15 @@
 #endif
   }
 
+  if (icon_str == "locationOnIcon") {
+    return gfx::CreateVectorIcon(vector_icons::kLocationOnIcon, kIconSize,
+                                 gfx::kChromeIconGrey);
+  }
+  if (icon_str == "userAccountAvatarIcon") {
+    return gfx::CreateVectorIcon(kUserAccountAvatarIcon, kIconSize,
+                                 gfx::kChromeIconGrey);
+  }
+
   // For other suggestion entries, get icon from PNG files.
   int icon_id = GetIconResourceID(icon_str);
   DCHECK_NE(kResourceNotFoundId, icon_id);
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index f8250a3..84e0e2f 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -223,6 +223,7 @@
 #if defined(OS_WIN)
 #include <shellapi.h>
 #include <windows.h>
+
 #include "chrome/browser/ui/view_ids.h"
 #include "components/autofill/core/browser/autofill_ie_toolbar_import_win.h"
 #include "ui/base/win/shell.h"
@@ -370,9 +371,7 @@
 class Browser::InterstitialObserver : public content::WebContentsObserver {
  public:
   InterstitialObserver(Browser* browser, content::WebContents* web_contents)
-      : WebContentsObserver(web_contents),
-        browser_(browser) {
-  }
+      : WebContentsObserver(web_contents), browser_(browser) {}
 
   void DidAttachInterstitialPage() override {
     browser_->UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
@@ -446,10 +445,9 @@
   extension_registry_observer_.Add(
       extensions::ExtensionRegistry::Get(profile_));
 #if !defined(OS_ANDROID)
-  registrar_.Add(
-      this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
-      content::Source<ThemeService>(
-          ThemeServiceFactory::GetForProfile(profile_)));
+  registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
+                 content::Source<ThemeService>(
+                     ThemeServiceFactory::GetForProfile(profile_)));
 #endif
   registrar_.Add(this, chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
                  content::NotificationService::AllSources());
@@ -699,9 +697,10 @@
 
   // Include the app name in window titles for tabbed browser windows when
   // requested with |include_app_name|.
-  return (!is_app() && include_app_name) ?
-      l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT, title):
-      title;
+  return (!is_app() && include_app_name)
+             ? l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT,
+                                          title)
+             : title;
 }
 
 // static
@@ -830,7 +829,7 @@
   int total_download_count =
       DownloadCoreService::NonMaliciousDownloadCountAllProfiles();
   if (total_download_count == 0)
-    return DOWNLOAD_CLOSE_OK;   // No downloads; can definitely close.
+    return DOWNLOAD_CLOSE_OK;  // No downloads; can definitely close.
 
   // Figure out how many windows are open total, and associated with this
   // profile, that are relevant for the ok-to-close decision.
@@ -925,14 +924,9 @@
   ui::SelectFileDialog::FileTypeInfo file_types;
   file_types.allowed_paths =
       ui::SelectFileDialog::FileTypeInfo::ANY_PATH_OR_URL;
-  select_file_dialog_->SelectFile(ui::SelectFileDialog::SELECT_OPEN_FILE,
-                                  base::string16(),
-                                  directory,
-                                  &file_types,
-                                  0,
-                                  base::FilePath::StringType(),
-                                  parent_window,
-                                  NULL);
+  select_file_dialog_->SelectFile(
+      ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(), directory,
+      &file_types, 0, base::FilePath::StringType(), parent_window, NULL);
 }
 
 void Browser::UpdateDownloadShelfVisibility(bool visible) {
@@ -1381,9 +1375,9 @@
   // navigation, so we don't have to worry about flickering. We do, however,
   // need to update the command state early on load to always present usable
   // actions in the face of slow-to-commit pages.
-  if (changed_flags & (content::INVALIDATE_TYPE_URL |
-                       content::INVALIDATE_TYPE_LOAD |
-                       content::INVALIDATE_TYPE_TAB))
+  if (changed_flags &
+      (content::INVALIDATE_TYPE_URL | content::INVALIDATE_TYPE_LOAD |
+       content::INVALIDATE_TYPE_TAB))
     command_controller_->TabStateChanged();
 
   if (web_app_controller_)
@@ -1479,8 +1473,7 @@
   chrome::ExecuteCommand(this, zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
 }
 
-bool Browser::TakeFocus(content::WebContents* source,
-                        bool reverse) {
+bool Browser::TakeFocus(content::WebContents* source, bool reverse) {
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER,
       content::Source<Browser>(this),
@@ -1491,8 +1484,8 @@
 void Browser::BeforeUnloadFired(WebContents* web_contents,
                                 bool proceed,
                                 bool* proceed_to_fire_unload) {
-  if (is_devtools() && DevToolsWindow::HandleBeforeUnload(web_contents,
-        proceed, proceed_to_fire_unload))
+  if (is_devtools() && DevToolsWindow::HandleBeforeUnload(
+                           web_contents, proceed, proceed_to_fire_unload))
     return;
 
   *proceed_to_fire_unload =
@@ -1706,8 +1699,8 @@
       PermissionRequestManager::FromWebContents(web_contents);
   if (permission_request_manager) {
     permission_request_manager->AddRequest(
-        new RegisterProtocolHandlerPermissionRequest(registry, handler,
-                                                     url, user_gesture));
+        new RegisterProtocolHandlerPermissionRequest(registry, handler, url,
+                                                     user_gesture));
   }
 }
 
@@ -1739,10 +1732,8 @@
   if (!find_tab_helper)
     return;
 
-  find_tab_helper->HandleFindReply(request_id,
-                                   number_of_matches,
-                                   selection_rect,
-                                   active_match_ordinal,
+  find_tab_helper->HandleFindReply(request_id, number_of_matches,
+                                   selection_rect, active_match_ordinal,
                                    final_update);
 }
 
@@ -1929,7 +1920,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 // Browser, ui::SelectFileDialog::Listener implementation:
 
-void Browser::FileSelected(const base::FilePath& path, int index,
+void Browser::FileSelected(const base::FilePath& path,
+                           int index,
                            void* params) {
   FileSelectedWithExtraInfo(ui::SelectedFileInfo(path, path), index, params);
 }
@@ -2034,8 +2026,9 @@
   DCHECK(source);
   if (tab_strip_model_->GetActiveWebContents() == source) {
     window_->SetTranslateIconToggled(
-        ChromeTranslateClient::FromWebContents(
-            source)->GetLanguageState().IsPageTranslated());
+        ChromeTranslateClient::FromWebContents(source)
+            ->GetLanguageState()
+            .IsPageTranslated());
   }
 }
 
@@ -2261,12 +2254,11 @@
 
 void Browser::UpdateToolbar(bool should_restore_state) {
   TRACE_EVENT0("ui", "Browser::UpdateToolbar");
-  window_->UpdateToolbar(should_restore_state ?
-      tab_strip_model_->GetActiveWebContents() : NULL);
+  window_->UpdateToolbar(
+      should_restore_state ? tab_strip_model_->GetActiveWebContents() : NULL);
 }
 
-void Browser::ScheduleUIUpdate(WebContents* source,
-                               unsigned changed_flags) {
+void Browser::ScheduleUIUpdate(WebContents* source, unsigned changed_flags) {
   DCHECK(source);
   int index = tab_strip_model_->GetIndexOfWebContents(source);
   DCHECK_NE(TabStripModel::kNoTab, index);
@@ -2347,12 +2339,14 @@
 
       // Updating the URL happens synchronously in ScheduleUIUpdate.
       if (flags & content::INVALIDATE_TYPE_LOAD && GetStatusBubble()) {
-        GetStatusBubble()->SetStatus(CoreTabHelper::FromWebContents(
-            tab_strip_model_->GetActiveWebContents())->GetStatusText());
+        GetStatusBubble()->SetStatus(
+            CoreTabHelper::FromWebContents(
+                tab_strip_model_->GetActiveWebContents())
+                ->GetStatusText());
       }
 
-      if (flags & (content::INVALIDATE_TYPE_TAB |
-                   content::INVALIDATE_TYPE_TITLE)) {
+      if (flags &
+          (content::INVALIDATE_TYPE_TAB | content::INVALIDATE_TYPE_TITLE)) {
         window_->UpdateTitleBar();
       }
     }
@@ -2410,10 +2404,9 @@
             SessionTabHelper::FromWebContents(web_contents);
         session_service->SetTabIndexInWindow(
             session_id(), session_tab_helper->session_id(), i);
-        session_service->SetPinnedState(
-            session_id(),
-            session_tab_helper->session_id(),
-            tab_strip_model_->IsTabPinned(i));
+        session_service->SetPinnedState(session_id(),
+                                        session_tab_helper->session_id(),
+                                        tab_strip_model_->IsTabPinned(i));
       }
     }
   }
@@ -2438,9 +2431,7 @@
   // that's ok.
   cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
   window_->ConfirmBrowserCloseWithPendingDownloads(
-      num_downloads_blocking,
-      dialog_type,
-      false,
+      num_downloads_blocking, dialog_type, false,
       base::Bind(&Browser::InProgressDownloadResponse,
                  weak_factory_.GetWeakPtr()));
 
@@ -2491,8 +2482,8 @@
   web_contents->SetDelegate(delegate);
 
   // ...and all the helpers.
-  WebContentsModalDialogManager::FromWebContents(web_contents)->
-      SetDelegate(delegate);
+  WebContentsModalDialogManager::FromWebContents(web_contents)
+      ->SetDelegate(delegate);
   translate::ContentTranslateDriver& content_translate_driver =
       ChromeTranslateClient::FromWebContents(web_contents)->translate_driver();
   if (delegate) {
@@ -2637,9 +2628,9 @@
   }
 
   bool should_animate = reason == BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE;
-  window_->BookmarkBarStateChanged(should_animate ?
-      BookmarkBar::ANIMATE_STATE_CHANGE :
-      BookmarkBar::DONT_ANIMATE_STATE_CHANGE);
+  window_->BookmarkBarStateChanged(
+      should_animate ? BookmarkBar::ANIMATE_STATE_CHANGE
+                     : BookmarkBar::DONT_ANIMATE_STATE_CHANGE);
 }
 
 bool Browser::ShouldShowBookmarkBar() const {
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index ce0922d..a2364d0 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -90,7 +90,7 @@
 
 class Extension;
 class ExtensionRegistry;
-}
+}  // namespace extensions
 
 namespace gfx {
 class Image;
@@ -269,18 +269,14 @@
     initial_show_state_ = initial_show_state;
   }
   // Return true if the initial window bounds have been overridden.
-  bool bounds_overridden() const {
-    return !override_bounds_.IsEmpty();
-  }
+  bool bounds_overridden() const { return !override_bounds_.IsEmpty(); }
   // Set indicator that this browser is being created via session restore.
   // This is used on the Mac (only) to determine animation style when the
   // browser window is shown.
   void set_is_session_restore(bool is_session_restore) {
     is_session_restore_ = is_session_restore;
   }
-  bool is_session_restore() const {
-    return is_session_restore_;
-  }
+  bool is_session_restore() const { return is_session_restore_; }
 
   bool is_focus_mode() const { return is_focus_mode_; }
 
@@ -315,7 +311,7 @@
   }
   const SessionID& session_id() const { return session_id_; }
   BrowserContentSettingBubbleModelDelegate*
-      content_setting_bubble_model_delegate() {
+  content_setting_bubble_model_delegate() {
     return content_setting_bubble_model_delegate_.get();
   }
   BrowserLiveTabContext* live_tab_context() { return live_tab_context_.get(); }
@@ -853,8 +849,7 @@
   //   updates), then scheduled_updates_ is updated for the |source| and update
   //   pair and a task is scheduled (assuming it isn't running already)
   //   that invokes ProcessPendingUIUpdates.
-  void ScheduleUIUpdate(content::WebContents* source,
-                        unsigned changed_flags);
+  void ScheduleUIUpdate(content::WebContents* source, unsigned changed_flags);
 
   // Processes all pending updates to the UI that have been scheduled by
   // ScheduleUIUpdate in scheduled_updates_.
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index 768ef11..f71ff05 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -130,8 +130,8 @@
 using app_modal::AppModalDialogQueue;
 using app_modal::JavaScriptAppModalDialog;
 using base::ASCIIToUTF16;
-using content::InterstitialPage;
 using content::HostZoomMap;
+using content::InterstitialPage;
 using content::NavigationController;
 using content::NavigationEntry;
 using content::OpenURLParams;
@@ -173,7 +173,7 @@
 int CountRenderProcessHosts() {
   int result = 0;
   for (content::RenderProcessHost::iterator i(
-          content::RenderProcessHost::AllHostsIterator());
+           content::RenderProcessHost::AllHostsIterator());
        !i.IsAtEnd(); i.Advance())
     ++result;
   return result;
@@ -224,17 +224,13 @@
 class TestInterstitialPage : public content::InterstitialPageDelegate {
  public:
   TestInterstitialPage(WebContents* tab, bool new_navigation, const GURL& url) {
-    interstitial_page_ = InterstitialPage::Create(
-        tab, new_navigation, url , this);
+    interstitial_page_ =
+        InterstitialPage::Create(tab, new_navigation, url, this);
     interstitial_page_->Show();
   }
   ~TestInterstitialPage() override {}
-  void Proceed() {
-    interstitial_page_->Proceed();
-  }
-  void DontProceed() {
-    interstitial_page_->DontProceed();
-  }
+  void Proceed() { interstitial_page_->Proceed(); }
+  void DontProceed() { interstitial_page_->DontProceed(); }
 
   std::string GetHTMLContents() override { return "<h1>INTERSTITIAL</h1>"; }
 
@@ -246,15 +242,12 @@
  public:
   RenderViewSizeObserver(content::WebContents* web_contents,
                          BrowserWindow* browser_window)
-      : WebContentsObserver(web_contents),
-        browser_window_(browser_window) {
-  }
+      : WebContentsObserver(web_contents), browser_window_(browser_window) {}
 
-  void GetSizeForRenderViewHost(
-      content::RenderViewHost* render_view_host,
-      gfx::Size* rwhv_create_size,
-      gfx::Size* rwhv_commit_size,
-      gfx::Size* wcv_commit_size) {
+  void GetSizeForRenderViewHost(content::RenderViewHost* render_view_host,
+                                gfx::Size* rwhv_create_size,
+                                gfx::Size* rwhv_commit_size,
+                                gfx::Size* wcv_commit_size) {
     RenderViewSizes::const_iterator result = render_view_sizes_.end();
     result = render_view_sizes_.find(render_view_host);
     if (result != render_view_sizes_.end()) {
@@ -386,9 +379,9 @@
       browser(), ui_test_utils::GetTestUrl(
                      base::FilePath(base::FilePath::kCurrentDirectory),
                      base::FilePath(kTitle1File)));
-  EXPECT_EQ(LocaleWindowCaptionFromPageTitle(ASCIIToUTF16("title1.html")),
-            browser()->GetWindowTitleForCurrentTab(
-                true /* include_app_name */));
+  EXPECT_EQ(
+      LocaleWindowCaptionFromPageTitle(ASCIIToUTF16("title1.html")),
+      browser()->GetWindowTitleForCurrentTab(true /* include_app_name */));
   base::string16 tab_title;
   ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title));
   EXPECT_EQ(ASCIIToUTF16("title1.html"), tab_title);
@@ -446,9 +439,9 @@
                      base::FilePath(base::FilePath::kCurrentDirectory),
                      base::FilePath(kTitle2File)));
   const base::string16 test_title(ASCIIToUTF16("Title Of Awesomeness"));
-  EXPECT_EQ(LocaleWindowCaptionFromPageTitle(test_title),
-            browser()->GetWindowTitleForCurrentTab(
-                true /* include_app_name */));
+  EXPECT_EQ(
+      LocaleWindowCaptionFromPageTitle(test_title),
+      browser()->GetWindowTitleForCurrentTab(true /* include_app_name */));
   base::string16 tab_title;
   ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title));
   EXPECT_EQ(test_title, tab_title);
@@ -482,8 +475,9 @@
 
 IN_PROC_BROWSER_TEST_F(BrowserTest, NoJavaScriptDialogsActivateTab) {
   // Set up two tabs, with the tab at index 0 active.
-  GURL url(ui_test_utils::GetTestUrl(base::FilePath(
-      base::FilePath::kCurrentDirectory), base::FilePath(kTitle1File)));
+  GURL url(ui_test_utils::GetTestUrl(
+      base::FilePath(base::FilePath::kCurrentDirectory),
+      base::FilePath(kTitle1File)));
   ui_test_utils::NavigateToURL(browser(), url);
   AddTabAtIndex(0, url, ui::PAGE_TRANSITION_TYPED);
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
@@ -537,14 +531,14 @@
 // Warning: this test can take >30 seconds when running on a slow (low
 // memory?) Mac builder.
 IN_PROC_BROWSER_TEST_F(BrowserTest, ThirtyFourTabs) {
-  GURL url(ui_test_utils::GetTestUrl(base::FilePath(
-      base::FilePath::kCurrentDirectory), base::FilePath(kTitle2File)));
+  GURL url(ui_test_utils::GetTestUrl(
+      base::FilePath(base::FilePath::kCurrentDirectory),
+      base::FilePath(kTitle2File)));
 
   // There is one initial tab.
   const int kTabCount = 34;
   for (int ix = 0; ix != (kTabCount - 1); ++ix) {
-    chrome::AddSelectedTabWithURL(browser(), url,
-                                  ui::PAGE_TRANSITION_TYPED);
+    chrome::AddSelectedTabWithURL(browser(), url, ui::PAGE_TRANSITION_TYPED);
   }
   EXPECT_EQ(kTabCount, browser()->tab_strip_model()->count());
 
@@ -579,8 +573,7 @@
   {
     content::WindowedNotificationObserver stop_observer(
         content::NOTIFICATION_LOAD_STOP,
-        content::Source<NavigationController>(
-            &web_contents->GetController()));
+        content::Source<NavigationController>(&web_contents->GetController()));
     browser()->OpenURL(OpenURLParams(abort_url, Referrer(),
                                      WindowOpenDisposition::CURRENT_TAB,
                                      ui::PAGE_TRANSITION_TYPED, false));
@@ -598,8 +591,7 @@
   {
     content::WindowedNotificationObserver stop_observer(
         content::NOTIFICATION_LOAD_STOP,
-        content::Source<NavigationController>(
-            &web_contents->GetController()));
+        content::Source<NavigationController>(&web_contents->GetController()));
     browser()->OpenURL(OpenURLParams(abort_url, Referrer(),
                                      WindowOpenDisposition::CURRENT_TAB,
                                      ui::PAGE_TRANSITION_TYPED, false));
@@ -660,8 +652,7 @@
   content::RenderProcessHost* child_process =
       contents->GetMainFrame()->GetProcess();
   content::RenderProcessHostWatcher crash_observer(
-      child_process,
-      content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+      child_process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
   child_process->Shutdown(0);
   crash_observer.Wait();
   EXPECT_FALSE(dialog_queue->HasActiveDialog());
@@ -695,8 +686,7 @@
   content::RenderProcessHost* child_process =
       contents->GetMainFrame()->GetProcess();
   content::RenderProcessHostWatcher crash_observer(
-      child_process,
-      content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+      child_process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
   child_process->Shutdown(0);
   crash_observer.Wait();
   EXPECT_FALSE(js_helper->IsShowingDialogForTesting());
@@ -955,8 +945,8 @@
   content::WindowedNotificationObserver nav_observer(
       content::NOTIFICATION_NAV_ENTRY_COMMITTED,
       content::NotificationService::AllSources());
-  oldtab->GetMainFrame()->
-      ExecuteJavaScriptWithUserGestureForTests(ASCIIToUTF16(redirect_popup));
+  oldtab->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
+      ASCIIToUTF16(redirect_popup));
 
   // Wait for popup window to appear and finish navigating.
   popup_observer.Wait();
@@ -989,8 +979,8 @@
   content::WindowedNotificationObserver nav_observer2(
       content::NOTIFICATION_NAV_ENTRY_COMMITTED,
       content::NotificationService::AllSources());
-  oldtab->GetMainFrame()->
-      ExecuteJavaScriptWithUserGestureForTests(ASCIIToUTF16(refresh_popup));
+  oldtab->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
+      ASCIIToUTF16(refresh_popup));
 
   // Wait for popup window to appear and finish navigating.
   popup_observer2.Wait();
@@ -1042,8 +1032,8 @@
   content::WindowedNotificationObserver nav_observer(
       content::NOTIFICATION_NAV_ENTRY_COMMITTED,
       content::NotificationService::AllSources());
-  oldtab->GetMainFrame()->
-      ExecuteJavaScriptWithUserGestureForTests(ASCIIToUTF16(dont_fork_popup));
+  oldtab->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
+      ASCIIToUTF16(dont_fork_popup));
 
   // Wait for popup window to appear and finish navigating.
   popup_observer.Wait();
@@ -1071,8 +1061,8 @@
   navigate_str += "\";";
 
   content::WindowedNotificationObserver nav_observer2(
-        content::NOTIFICATION_NAV_ENTRY_COMMITTED,
-        content::NotificationService::AllSources());
+      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
+      content::NotificationService::AllSources());
   oldtab->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
       ASCIIToUTF16(navigate_str));
   nav_observer2.Wait();
@@ -1122,12 +1112,15 @@
 
   ui_test_utils::NavigateToURL(browser(), url);
 
-  NavigationEntry* entry = browser()->tab_strip_model()->
-      GetActiveWebContents()->GetController().GetLastCommittedEntry();
+  NavigationEntry* entry = browser()
+                               ->tab_strip_model()
+                               ->GetActiveWebContents()
+                               ->GetController()
+                               .GetLastCommittedEntry();
   EXPECT_EQ(expected_favicon_url.spec(), entry->GetFavicon().url.spec());
 }
 
-#if defined(OS_MACOSX) || defined(OS_LINUX) || defined (OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_WIN)
 // http://crbug.com/83828. On Mac 10.6, the failure rate is 14%
 #define MAYBE_FaviconChange DISABLED_FaviconChange
 #else
@@ -1140,17 +1133,21 @@
 IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_FaviconChange) {
   static const base::FilePath::CharType* kFile =
       FILE_PATH_LITERAL("onload_change_favicon.html");
-  GURL file_url(ui_test_utils::GetTestUrl(base::FilePath(
-      base::FilePath::kCurrentDirectory), base::FilePath(kFile)));
+  GURL file_url(ui_test_utils::GetTestUrl(
+      base::FilePath(base::FilePath::kCurrentDirectory),
+      base::FilePath(kFile)));
   ASSERT_TRUE(file_url.SchemeIs(url::kFileScheme));
   ui_test_utils::NavigateToURL(browser(), file_url);
 
-  NavigationEntry* entry = browser()->tab_strip_model()->
-      GetActiveWebContents()->GetController().GetLastCommittedEntry();
-  static const base::FilePath::CharType* kIcon =
-      FILE_PATH_LITERAL("test1.png");
-  GURL expected_favicon_url(ui_test_utils::GetTestUrl(base::FilePath(
-      base::FilePath::kCurrentDirectory), base::FilePath(kIcon)));
+  NavigationEntry* entry = browser()
+                               ->tab_strip_model()
+                               ->GetActiveWebContents()
+                               ->GetController()
+                               .GetLastCommittedEntry();
+  static const base::FilePath::CharType* kIcon = FILE_PATH_LITERAL("test1.png");
+  GURL expected_favicon_url(ui_test_utils::GetTestUrl(
+      base::FilePath(base::FilePath::kCurrentDirectory),
+      base::FilePath(kIcon)));
   EXPECT_EQ(expected_favicon_url.spec(), entry->GetFavicon().url.spec());
 }
 
@@ -1187,8 +1184,7 @@
       extensions::ExtensionSystem::Get(browser()->profile())
           ->extension_service();
   service->UninstallExtension(GetExtension()->id(),
-                              extensions::UNINSTALL_REASON_FOR_TESTING,
-                              NULL);
+                              extensions::UNINSTALL_REASON_FOR_TESTING, NULL);
   EXPECT_EQ(1, observer.closing_count());
 
   model->RemoveObserver(&observer);
@@ -1211,8 +1207,9 @@
   base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
   command_line.AppendSwitchASCII(switches::kAppId, extension_app->id());
 
-  chrome::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ?
-      chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN;
+  chrome::startup::IsFirstRun first_run =
+      first_run::IsChromeFirstRun() ? chrome::startup::IS_FIRST_RUN
+                                    : chrome::startup::IS_NOT_FIRST_RUN;
   StartupBrowserCreatorImpl launch(base::FilePath(), command_line, first_run);
 
   // The app should open as a tab.
@@ -1270,8 +1267,7 @@
 
   // App windows can show location bars, for example when they navigate away
   // from their starting origin.
-  EXPECT_TRUE(
-      app_browser->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR));
+  EXPECT_TRUE(app_browser->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR));
 
   DevToolsWindowTesting::CloseDevToolsWindowSync(devtools_window);
 }
@@ -1356,8 +1352,9 @@
 
   // Launch again with the same profile.
   base::CommandLine dummy(base::CommandLine::NO_PROGRAM);
-  chrome::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ?
-      chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN;
+  chrome::startup::IsFirstRun first_run =
+      first_run::IsChromeFirstRun() ? chrome::startup::IS_FIRST_RUN
+                                    : chrome::startup::IS_NOT_FIRST_RUN;
   StartupBrowserCreatorImpl launch(base::FilePath(), dummy, first_run);
   launch.Launch(browser()->profile(), std::vector<GURL>(), false);
 
@@ -1434,14 +1431,14 @@
   // The browser's app name should include the extension's id.
   std::string app_name = new_browser->app_name_;
   EXPECT_NE(app_name.find(extension_app->id()), std::string::npos)
-      << "Name " << app_name << " should contain id "<< extension_app->id();
+      << "Name " << app_name << " should contain id " << extension_app->id();
 }
 #endif  // !defined(OS_MACOSX)
 
 // Makes sure the browser doesn't crash when
 // set_show_state(ui::SHOW_STATE_MAXIMIZED) has been invoked.
 IN_PROC_BROWSER_TEST_F(BrowserTest, StartMaximized) {
-  Browser::Type types[] = { Browser::TYPE_TABBED, Browser::TYPE_POPUP };
+  Browser::Type types[] = {Browser::TYPE_TABBED, Browser::TYPE_POPUP};
   for (size_t i = 0; i < base::size(types); ++i) {
     Browser::CreateParams params(types[i], browser()->profile(), true);
     params.initial_show_state = ui::SHOW_STATE_MAXIMIZED;
@@ -1452,7 +1449,7 @@
 // Makes sure the browser doesn't crash when
 // set_show_state(ui::SHOW_STATE_MINIMIZED) has been invoked.
 IN_PROC_BROWSER_TEST_F(BrowserTest, StartMinimized) {
-  Browser::Type types[] = { Browser::TYPE_TABBED, Browser::TYPE_POPUP };
+  Browser::Type types[] = {Browser::TYPE_TABBED, Browser::TYPE_POPUP};
   for (size_t i = 0; i < base::size(types); ++i) {
     Browser::CreateParams params(types[i], browser()->profile(), true);
     params.initial_show_state = ui::SHOW_STATE_MINIMIZED;
@@ -1473,9 +1470,10 @@
 
   content::WindowedNotificationObserver back_nav_load_observer(
       content::NOTIFICATION_LOAD_STOP,
-      content::Source<NavigationController>(
-          &browser()->tab_strip_model()->GetActiveWebContents()->
-              GetController()));
+      content::Source<NavigationController>(&browser()
+                                                 ->tab_strip_model()
+                                                 ->GetActiveWebContents()
+                                                 ->GetController()));
   chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
   back_nav_load_observer.Wait();
   CommandUpdater* command_updater = browser()->command_controller();
@@ -1483,9 +1481,10 @@
 
   content::WindowedNotificationObserver forward_nav_load_observer(
       content::NOTIFICATION_LOAD_STOP,
-      content::Source<NavigationController>(
-          &browser()->tab_strip_model()->GetActiveWebContents()->
-              GetController()));
+      content::Source<NavigationController>(&browser()
+                                                 ->tab_strip_model()
+                                                 ->GetActiveWebContents()
+                                                 ->GetController()));
   chrome::GoForward(browser(), WindowOpenDisposition::CURRENT_TAB);
   // This check will happen before the navigation completes, since the browser
   // won't process the renderer's response until the Wait() call below.
@@ -1522,8 +1521,8 @@
   CommandUpdater* new_command_updater = new_browser->command_controller();
   // It should have Bookmarks & Settings commands disabled by default.
   EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_NEW_WINDOW));
-  EXPECT_FALSE(new_command_updater->IsCommandEnabled(
-      IDC_SHOW_BOOKMARK_MANAGER));
+  EXPECT_FALSE(
+      new_command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER));
   EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS));
   EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS));
   EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_OPTIONS));
@@ -1595,8 +1594,8 @@
   CommandUpdater* popup_command_updater = popup_browser->command_controller();
   EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS));
   EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_OPTIONS));
-  EXPECT_TRUE(popup_command_updater->IsCommandEnabled(
-      IDC_SHOW_BOOKMARK_MANAGER));
+  EXPECT_TRUE(
+      popup_command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER));
   EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS));
 }
 
@@ -1775,7 +1774,6 @@
   EXPECT_FALSE(contents->GetMainFrame()->GetProcess()->IsBlocked());
 }
 
-
 IN_PROC_BROWSER_TEST_F(BrowserTest, InterstitialCloseTab) {
   WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
 
@@ -2010,8 +2008,9 @@
   ASSERT_TRUE(browser()->profile());
   // Verify that the profile has been added correctly to the
   // ProfileAttributesStorage.
-  ASSERT_EQ(1u, g_browser_process->profile_manager()->
-      GetProfileAttributesStorage().GetNumberOfProfiles());
+  ASSERT_EQ(1u, g_browser_process->profile_manager()
+                    ->GetProfileAttributesStorage()
+                    .GetNumberOfProfiles());
 }
 #endif  // defined(OS_WIN)
 
@@ -2041,8 +2040,9 @@
   ASSERT_TRUE(browser()->profile());
   // Verify that the profile has been added correctly to the
   // ProfileAttributesStorage.
-  ASSERT_EQ(1u, g_browser_process->profile_manager()->
-      GetProfileAttributesStorage().GetNumberOfProfiles());
+  ASSERT_EQ(1u, g_browser_process->profile_manager()
+                    ->GetProfileAttributesStorage()
+                    .GetNumberOfProfiles());
 }
 #endif  // defined(OS_WIN)
 
@@ -2133,7 +2133,7 @@
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
     GURL url = ui_test_utils::GetTestUrl(
-       base::FilePath(), base::FilePath().AppendASCII("title1.html"));
+        base::FilePath(), base::FilePath().AppendASCII("title1.html"));
     command_line->AppendSwitchASCII(switches::kApp, url.spec());
   }
 };
@@ -2152,14 +2152,14 @@
   ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("WebKit"), true, true,
                                       NULL, NULL),
             0);
-  ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("OS"), true, true,
-                                      NULL, NULL),
+  ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("OS"), true, true, NULL,
+                                      NULL),
             0);
   ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("JavaScript"), true,
                                       true, NULL, NULL),
             0);
-  ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("Flash"), true,
-                                      true, NULL, NULL),
+  ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("Flash"), true, true,
+                                      NULL, NULL),
             0);
 }
 
@@ -2170,31 +2170,26 @@
 
 class ClickModifierTest : public InProcessBrowserTest {
  public:
-  ClickModifierTest() {
-  }
+  ClickModifierTest() {}
 
   // Returns a url that opens a new window or tab when clicked, via javascript.
   GURL GetWindowOpenURL() {
     return ui_test_utils::GetTestUrl(
-      base::FilePath(kTestDir),
-      base::FilePath(FILE_PATH_LITERAL("window_open.html")));
+        base::FilePath(kTestDir),
+        base::FilePath(FILE_PATH_LITERAL("window_open.html")));
   }
 
   // Returns a url that follows a simple link when clicked, unless affected by
   // modifiers.
   GURL GetHrefURL() {
     return ui_test_utils::GetTestUrl(
-      base::FilePath(kTestDir),
-      base::FilePath(FILE_PATH_LITERAL("href.html")));
+        base::FilePath(kTestDir),
+        base::FilePath(FILE_PATH_LITERAL("href.html")));
   }
 
-  base::string16 GetFirstPageTitle() {
-    return ASCIIToUTF16(kFirstPageTitle);
-  }
+  base::string16 GetFirstPageTitle() { return ASCIIToUTF16(kFirstPageTitle); }
 
-  base::string16 GetSecondPageTitle() {
-    return ASCIIToUTF16(kSecondPageTitle);
-  }
+  base::string16 GetSecondPageTitle() { return ASCIIToUTF16(kSecondPageTitle); }
 
   // Loads our test page and simulates a single click using the supplied button
   // and modifiers.  The click will cause either a navigation or the creation of
@@ -2387,8 +2382,7 @@
   WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::RenderViewHost* prev_rvh = web_contents->GetRenderViewHost();
-  const gfx::Size initial_wcv_size =
-      web_contents->GetContainerBounds().size();
+  const gfx::Size initial_wcv_size = web_contents->GetContainerBounds().size();
   RenderViewSizeObserver observer(web_contents, browser()->window());
 
   // Navigate to a non-NTP page, without resizing WebContentsView.
@@ -2400,8 +2394,7 @@
   prev_rvh = web_contents->GetRenderViewHost();
   gfx::Size rwhv_create_size0, rwhv_commit_size0, wcv_commit_size0;
   observer.GetSizeForRenderViewHost(web_contents->GetRenderViewHost(),
-                                    &rwhv_create_size0,
-                                    &rwhv_commit_size0,
+                                    &rwhv_create_size0, &rwhv_commit_size0,
                                     &wcv_commit_size0);
   EXPECT_EQ(gfx::Size(initial_wcv_size.width(), initial_wcv_size.height()),
             rwhv_create_size0);
@@ -2434,8 +2427,7 @@
   EXPECT_NE(prev_rvh, web_contents->GetRenderViewHost());
   gfx::Size rwhv_create_size1, rwhv_commit_size1, wcv_commit_size1;
   observer.GetSizeForRenderViewHost(web_contents->GetRenderViewHost(),
-                                    &rwhv_create_size1,
-                                    &rwhv_commit_size1,
+                                    &rwhv_create_size1, &rwhv_commit_size1,
                                     &wcv_commit_size1);
   EXPECT_EQ(rwhv_create_size1, rwhv_commit_size1);
   EXPECT_EQ(rwhv_commit_size1,
@@ -2452,8 +2444,7 @@
   ASSERT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
   gfx::Size rwhv_create_size2, rwhv_commit_size2, wcv_commit_size2;
   observer.GetSizeForRenderViewHost(web_contents->GetRenderViewHost(),
-                                    &rwhv_create_size2,
-                                    &rwhv_commit_size2,
+                                    &rwhv_create_size2, &rwhv_commit_size2,
                                     &wcv_commit_size2);
 
   // The behavior on OSX and Views is incorrect in this edge case, but they are
@@ -2589,9 +2580,8 @@
 
 // flaky new test: http://crbug.com/471703
 IN_PROC_BROWSER_TEST_F(BrowserTest, DISABLED_ChangeDisplayMode) {
-  CheckDisplayModeMQ(
-      ASCIIToUTF16("browser"),
-      browser()->tab_strip_model()->GetActiveWebContents());
+  CheckDisplayModeMQ(ASCIIToUTF16("browser"),
+                     browser()->tab_strip_model()->GetActiveWebContents());
 
   Profile* profile = ProfileManager::GetActiveUserProfile();
   ui_test_utils::BrowserAddedObserver browser_added_observer;
diff --git a/chrome/browser/ui/browser_close_unittest.cc b/chrome/browser/ui/browser_close_unittest.cc
index 1f184d8..68f30a3 100644
--- a/chrome/browser/ui/browser_close_unittest.cc
+++ b/chrome/browser/ui/browser_close_unittest.cc
@@ -66,9 +66,7 @@
     ADD_FAILURE();
   }
 
-  bool IsShelfEnabled() override {
-    return true;
-  }
+  bool IsShelfEnabled() override { return true; }
 
   // KeyedService
   void Shutdown() override {}
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index 9143298..085a070 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -97,8 +97,8 @@
 #include "ui/ozone/public/ozone_platform.h"
 #endif
 
-using content::NavigationEntry;
 using content::NavigationController;
+using content::NavigationEntry;
 using content::WebContents;
 
 namespace chrome {
@@ -107,8 +107,7 @@
 // BrowserCommandController, public:
 
 BrowserCommandController::BrowserCommandController(Browser* browser)
-    : browser_(browser),
-      command_updater_(nullptr) {
+    : browser_(browser), command_updater_(nullptr) {
   browser_->tab_strip_model()->AddObserver(this);
   PrefService* local_state = g_browser_process->local_state();
   if (local_state) {
@@ -149,8 +148,7 @@
                  base::Unretained(this)));
 #endif
   pref_signin_allowed_.Init(
-      prefs::kSigninAllowed,
-      profile()->GetOriginalProfile()->GetPrefs(),
+      prefs::kSigninAllowed, profile()->GetOriginalProfile()->GetPrefs(),
       base::Bind(&BrowserCommandController::OnSigninAllowedPrefChange,
                  base::Unretained(this)));
 
@@ -229,15 +227,11 @@
     return false;
 #endif
 
-  return command_id == IDC_CLOSE_TAB ||
-         command_id == IDC_CLOSE_WINDOW ||
-         command_id == IDC_NEW_INCOGNITO_WINDOW ||
-         command_id == IDC_NEW_TAB ||
-         command_id == IDC_NEW_WINDOW ||
-         command_id == IDC_RESTORE_TAB ||
+  return command_id == IDC_CLOSE_TAB || command_id == IDC_CLOSE_WINDOW ||
+         command_id == IDC_NEW_INCOGNITO_WINDOW || command_id == IDC_NEW_TAB ||
+         command_id == IDC_NEW_WINDOW || command_id == IDC_RESTORE_TAB ||
          command_id == IDC_SELECT_NEXT_TAB ||
-         command_id == IDC_SELECT_PREVIOUS_TAB ||
-         command_id == IDC_EXIT;
+         command_id == IDC_SELECT_PREVIOUS_TAB || command_id == IDC_EXIT;
 }
 
 void BrowserCommandController::TabStateChanged() {
@@ -315,8 +309,8 @@
   if (browser_->tab_strip_model()->active_index() == TabStripModel::kNoTab)
     return true;
 
-  DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command "
-                                                << id;
+  DCHECK(command_updater_.IsCommandEnabled(id))
+      << "Invalid/disabled command " << id;
 
   // The order of commands in this switch statement must match the function
   // declaration order in browser.h!
@@ -347,7 +341,7 @@
       Stop(browser_);
       break;
 
-     // Window management commands
+      // Window management commands
     case IDC_NEW_WINDOW:
       NewWindow(browser_);
       break;
@@ -733,7 +727,8 @@
 }
 
 void BrowserCommandController::RemoveCommandObserver(
-    int id, CommandObserver* observer) {
+    int id,
+    CommandObserver* observer) {
   command_updater_.RemoveCommandObserver(id, observer);
 }
 
@@ -824,9 +819,7 @@
  public:
   InterstitialObserver(BrowserCommandController* controller,
                        content::WebContents* web_contents)
-      : WebContentsObserver(web_contents),
-        controller_(controller) {
-  }
+      : WebContentsObserver(web_contents), controller_(controller) {}
 
   void DidAttachInterstitialPage() override {
     controller_->UpdateCommandsForTabState();
@@ -902,8 +895,8 @@
   command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
 
   // Show various bits of UI
-  const bool guest_session = profile()->IsGuestSession() ||
-                             profile()->IsSystemProfile();
+  const bool guest_session =
+      profile()->IsGuestSession() || profile()->IsSystemProfile();
   DCHECK(!profile()->IsSystemProfile())
       << "Ought to never have browser for the system profile.";
   const bool normal_window = browser_->is_type_tabbed();
@@ -917,9 +910,8 @@
   command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_MENU, true);
   command_updater_.UpdateCommandEnabled(IDC_SHOW_BETA_FORUM, true);
   command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, !guest_session);
-  command_updater_.UpdateCommandEnabled(IDC_RECENT_TABS_MENU,
-                                        !guest_session &&
-                                        !profile()->IsOffTheRecord());
+  command_updater_.UpdateCommandEnabled(
+      IDC_RECENT_TABS_MENU, !guest_session && !profile()->IsOffTheRecord());
   command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA,
                                         !guest_session);
 #if defined(OS_CHROMEOS)
@@ -951,8 +943,7 @@
 
   // Window management commands
   command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
-  command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
-                                        normal_window);
+  command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB, normal_window);
   command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window);
   command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window);
   command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window);
@@ -992,8 +983,7 @@
   IncognitoModePrefs::Availability incognito_availability =
       IncognitoModePrefs::GetAvailability(profile->GetPrefs());
   command_updater->UpdateCommandEnabled(
-      IDC_NEW_WINDOW,
-      incognito_availability != IncognitoModePrefs::FORCED);
+      IDC_NEW_WINDOW, incognito_availability != IncognitoModePrefs::FORCED);
   command_updater->UpdateCommandEnabled(
       IDC_NEW_INCOGNITO_WINDOW,
       incognito_availability != IncognitoModePrefs::DISABLED && !guest_session);
@@ -1051,8 +1041,8 @@
                                         CanReload(browser_));
 
   // Window management commands
-  command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
-      !browser_->is_app() && CanDuplicateTab(browser_));
+  command_updater_.UpdateCommandEnabled(
+      IDC_DUPLICATE_TAB, !browser_->is_app() && CanDuplicateTab(browser_));
   command_updater_.UpdateCommandEnabled(IDC_WINDOW_MUTE_SITE,
                                         !browser_->is_app());
   command_updater_.UpdateCommandEnabled(IDC_WINDOW_PIN_TAB,
@@ -1090,16 +1080,13 @@
 }
 
 void BrowserCommandController::UpdateCommandsForZoomState() {
-  WebContents* contents =
-      browser_->tab_strip_model()->GetActiveWebContents();
+  WebContents* contents = browser_->tab_strip_model()->GetActiveWebContents();
   if (!contents)
     return;
-  command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS,
-                                        CanZoomIn(contents));
+  command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, CanZoomIn(contents));
   command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL,
                                         CanResetZoom(contents));
-  command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS,
-                                        CanZoomOut(contents));
+  command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, CanZoomOut(contents));
 }
 
 void BrowserCommandController::UpdateCommandsForContentRestrictionState() {
@@ -1121,8 +1108,7 @@
 
   bool dev_tools_enabled = DevToolsWindow::AllowDevToolsFor(
       profile(), browser_->tab_strip_model()->GetActiveWebContents());
-  command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS,
-                                        dev_tools_enabled);
+  command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS, dev_tools_enabled);
   command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE,
                                         dev_tools_enabled);
   command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_DEVICES,
@@ -1155,12 +1141,12 @@
     return;
 
   command_updater_.UpdateCommandEnabled(
-      IDC_SHOW_BOOKMARK_BAR,
-      browser_defaults::bookmarks_enabled && !profile()->IsGuestSession() &&
-          !profile()->IsSystemProfile() &&
-          !profile()->GetPrefs()->IsManagedPreference(
-              bookmarks::prefs::kShowBookmarkBar) &&
-          IsShowingMainUI());
+      IDC_SHOW_BOOKMARK_BAR, browser_defaults::bookmarks_enabled &&
+                                 !profile()->IsGuestSession() &&
+                                 !profile()->IsSystemProfile() &&
+                                 !profile()->GetPrefs()->IsManagedPreference(
+                                     bookmarks::prefs::kShowBookmarkBar) &&
+                                 IsShowingMainUI());
 }
 
 void BrowserCommandController::UpdateCommandsForFileSelectionDialogs() {
@@ -1186,21 +1172,20 @@
 
   // Window management commands
   command_updater_.UpdateCommandEnabled(
-      IDC_SHOW_AS_TAB,
-      !browser_->is_type_tabbed() && !is_fullscreen);
+      IDC_SHOW_AS_TAB, !browser_->is_type_tabbed() && !is_fullscreen);
 
   // Focus various bits of UI
   command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
   command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_location_bar);
   command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
-  command_updater_.UpdateCommandEnabled(
-      IDC_FOCUS_MENU_BAR, main_not_fullscreen);
-  command_updater_.UpdateCommandEnabled(
-      IDC_FOCUS_NEXT_PANE, main_not_fullscreen);
-  command_updater_.UpdateCommandEnabled(
-      IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen);
-  command_updater_.UpdateCommandEnabled(
-      IDC_FOCUS_BOOKMARKS, main_not_fullscreen);
+  command_updater_.UpdateCommandEnabled(IDC_FOCUS_MENU_BAR,
+                                        main_not_fullscreen);
+  command_updater_.UpdateCommandEnabled(IDC_FOCUS_NEXT_PANE,
+                                        main_not_fullscreen);
+  command_updater_.UpdateCommandEnabled(IDC_FOCUS_PREVIOUS_PANE,
+                                        main_not_fullscreen);
+  command_updater_.UpdateCommandEnabled(IDC_FOCUS_BOOKMARKS,
+                                        main_not_fullscreen);
   command_updater_.UpdateCommandEnabled(
       IDC_FOCUS_INACTIVE_POPUP_FOR_ACCESSIBILITY, main_not_fullscreen);
 
@@ -1224,7 +1209,8 @@
 
 #if !defined(OS_MACOSX)
   // Disable toggling into fullscreen mode if disallowed by pref.
-  const bool fullscreen_enabled = is_fullscreen ||
+  const bool fullscreen_enabled =
+      is_fullscreen ||
       profile()->GetPrefs()->GetBoolean(prefs::kFullscreenAllowed);
 #else
   const bool fullscreen_enabled = true;
@@ -1358,14 +1344,14 @@
   command_updater_.UpdateCommandEnabled(
       IDC_RESTORE_TAB,
       tab_restore_service &&
-      (!tab_restore_service->IsLoaded() ||
-       GetRestoreTabType(browser_) != TabStripModelDelegate::RESTORE_NONE));
+          (!tab_restore_service->IsLoaded() ||
+           GetRestoreTabType(browser_) != TabStripModelDelegate::RESTORE_NONE));
 }
 
 void BrowserCommandController::UpdateCommandsForFind() {
   TabStripModel* model = browser_->tab_strip_model();
-  bool enabled = !model->IsTabBlocked(model->active_index()) &&
-                 !browser_->is_devtools();
+  bool enabled =
+      !model->IsTabBlocked(model->active_index()) && !browser_->is_devtools();
 
   command_updater_.UpdateCommandEnabled(IDC_FIND, enabled);
   command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, enabled);
diff --git a/chrome/browser/ui/browser_command_controller_browsertest.cc b/chrome/browser/ui/browser_command_controller_browsertest.cc
index 6e85720..7978ad48 100644
--- a/chrome/browser/ui/browser_command_controller_browsertest.cc
+++ b/chrome/browser/ui/browser_command_controller_browsertest.cc
@@ -43,7 +43,7 @@
 
 namespace chrome {
 
-class BrowserCommandControllerBrowserTest: public InProcessBrowserTest {
+class BrowserCommandControllerBrowserTest : public InProcessBrowserTest {
  public:
   BrowserCommandControllerBrowserTest() {}
   ~BrowserCommandControllerBrowserTest() override {}
@@ -117,12 +117,12 @@
   TemplateURLServiceFactory::GetForProfile(guest)->set_loaded(true);
 
   const CommandUpdater* command_updater = browser->command_controller();
-  #if defined(OS_CHROMEOS)
-    // Chrome OS uses system tray menu to handle multi-profiles.
-    EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_SHOW_AVATAR_MENU));
-  #else
-    EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_AVATAR_MENU));
-  #endif
+#if defined(OS_CHROMEOS)
+  // Chrome OS uses system tray menu to handle multi-profiles.
+  EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_SHOW_AVATAR_MENU));
+#else
+  EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_AVATAR_MENU));
+#endif
 }
 
 #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/browser_command_controller_interactive_browsertest.cc b/chrome/browser/ui/browser_command_controller_interactive_browsertest.cc
index 80998ce..de54f379 100644
--- a/chrome/browser/ui/browser_command_controller_interactive_browsertest.cc
+++ b/chrome/browser/ui/browser_command_controller_interactive_browsertest.cc
@@ -100,10 +100,10 @@
 #if defined(OS_MACOSX)
 // Triggers a DCHECK in MacViews: http://crbug.com/823478
 #define MAYBE_KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11 \
-    DISABLED_KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11
+  DISABLED_KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11
 #else
 #define MAYBE_KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11 \
-    KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11
+  KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11
 #endif
 IN_PROC_BROWSER_TEST_F(
     BrowserCommandControllerInteractiveTest,
@@ -135,10 +135,10 @@
 // TODO(zijiehe): Figure out why this test crashes on Mac OSX. The suspicious
 // command is "SendFullscreenShortcutAndWait()". See, http://crbug.com/738949.
 #define MAYBE_ShortcutsShouldTakeEffectInBrowserFullscreen \
-        DISABLED_ShortcutsShouldTakeEffectInBrowserFullscreen
+  DISABLED_ShortcutsShouldTakeEffectInBrowserFullscreen
 #else
 #define MAYBE_ShortcutsShouldTakeEffectInBrowserFullscreen \
-        ShortcutsShouldTakeEffectInBrowserFullscreen
+  ShortcutsShouldTakeEffectInBrowserFullscreen
 #endif
 IN_PROC_BROWSER_TEST_F(BrowserCommandControllerInteractiveTest,
                        MAYBE_ShortcutsShouldTakeEffectInBrowserFullscreen) {
@@ -165,10 +165,10 @@
 #if defined(OS_CHROMEOS)
 // This test is flaky on ChromeOS, see http://crbug.com/754878.
 #define MAYBE_ShortcutsShouldTakeEffectInJsFullscreen \
-        DISABLED_ShortcutsShouldTakeEffectInJsFullscreen
+  DISABLED_ShortcutsShouldTakeEffectInJsFullscreen
 #else
 #define MAYBE_ShortcutsShouldTakeEffectInJsFullscreen \
-        ShortcutsShouldTakeEffectInJsFullscreen
+  ShortcutsShouldTakeEffectInJsFullscreen
 #endif
 IN_PROC_BROWSER_TEST_F(BrowserCommandControllerInteractiveTest,
                        MAYBE_ShortcutsShouldTakeEffectInJsFullscreen) {
diff --git a/chrome/browser/ui/browser_command_controller_unittest.cc b/chrome/browser/ui/browser_command_controller_unittest.cc
index b61739c..899ace4c 100644
--- a/chrome/browser/ui/browser_command_controller_unittest.cc
+++ b/chrome/browser/ui/browser_command_controller_unittest.cc
@@ -161,8 +161,7 @@
   testprofile->SetGuestSession(true);
   chrome::BrowserCommandController ::
       UpdateSharedCommandsForIncognitoAvailability(
-          browser()->command_controller(),
-          testprofile);
+          browser()->command_controller(), testprofile);
   EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_OPTIONS));
   EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_IMPORT_SETTINGS));
   EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_SHOW_SIGNIN));
@@ -172,8 +171,7 @@
                                       IncognitoModePrefs::FORCED);
   chrome::BrowserCommandController ::
       UpdateSharedCommandsForIncognitoAvailability(
-          browser()->command_controller(),
-          testprofile);
+          browser()->command_controller(), testprofile);
   EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_OPTIONS));
   EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_IMPORT_SETTINGS));
   EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_SHOW_SIGNIN));
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index 3e4ebd9..0c29520 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -176,11 +176,11 @@
   BookmarkModel* model =
       BookmarkModelFactory::GetForBrowserContext(browser->profile());
   return browser_defaults::bookmarks_enabled &&
-      browser->profile()->GetPrefs()->GetBoolean(
-          bookmarks::prefs::kEditBookmarksEnabled) &&
-      model && model->loaded() && browser->is_type_tabbed() &&
-      (!check_remove_bookmark_ui ||
-           !chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
+         browser->profile()->GetPrefs()->GetBoolean(
+             bookmarks::prefs::kEditBookmarksEnabled) &&
+         model && model->loaded() && browser->is_type_tabbed() &&
+         (!check_remove_bookmark_ui ||
+          !chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
 }
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -207,8 +207,7 @@
   const extensions::ExtensionSet& extension_set =
       extensions::ExtensionRegistry::Get(profile)->enabled_extensions();
   for (extensions::ExtensionSet::const_iterator i = extension_set.begin();
-       i != extension_set.end();
-       ++i) {
+       i != extension_set.end(); ++i) {
     extensions::Command prospective_command;
     if (command_service->GetSuggestedExtensionCommand(
             (*i)->id(), bookmark_page_accelerator, &prospective_command)) {
@@ -393,7 +392,7 @@
   PrefService* prefs = profile->GetPrefs();
   if (incognito) {
     if (IncognitoModePrefs::GetAvailability(prefs) ==
-          IncognitoModePrefs::DISABLED) {
+        IncognitoModePrefs::DISABLED) {
       incognito = false;
     }
   } else if (profile->IsGuestSession() ||
@@ -433,16 +432,16 @@
     service->RestoreMostRecentEntry(nullptr);
 }
 
-void OpenURLOffTheRecord(Profile* profile,
-                         const GURL& url) {
+void OpenURLOffTheRecord(Profile* profile, const GURL& url) {
   ScopedTabbedBrowserDisplayer displayer(profile->GetOffTheRecordProfile());
-  AddSelectedTabWithURL(displayer.browser(), url,
-      ui::PAGE_TRANSITION_LINK);
+  AddSelectedTabWithURL(displayer.browser(), url, ui::PAGE_TRANSITION_LINK);
 }
 
 bool CanGoBack(const Browser* browser) {
-  return browser->tab_strip_model()->GetActiveWebContents()->
-      GetController().CanGoBack();
+  return browser->tab_strip_model()
+      ->GetActiveWebContents()
+      ->GetController()
+      .CanGoBack();
 }
 
 void GoBack(Browser* browser, WindowOpenDisposition disposition) {
@@ -460,15 +459,18 @@
 }
 
 bool CanGoForward(const Browser* browser) {
-  return browser->tab_strip_model()->GetActiveWebContents()->
-      GetController().CanGoForward();
+  return browser->tab_strip_model()
+      ->GetActiveWebContents()
+      ->GetController()
+      .CanGoForward();
 }
 
 void GoForward(Browser* browser, WindowOpenDisposition disposition) {
   base::RecordAction(UserMetricsAction("Forward"));
   if (CanGoForward(browser)) {
-    GetTabAndRevertIfNecessary(browser, disposition)->
-        GetController().GoForward();
+    GetTabAndRevertIfNecessary(browser, disposition)
+        ->GetController()
+        .GoForward();
   }
 }
 
@@ -506,7 +508,7 @@
   PrefService* pref_service = browser->profile()->GetPrefs();
   if (pref_service) {
     if (google_util::IsGoogleHomePageUrl(
-        GURL(pref_service->GetString(prefs::kHomePage)))) {
+            GURL(pref_service->GetString(prefs::kHomePage)))) {
       extra_headers = rlz::RLZTracker::GetAccessPointHttpHeader(
           rlz::RLZTracker::ChromeHomePage());
     }
@@ -532,9 +534,8 @@
 
   OpenURLParams params(
       url, Referrer(), disposition,
-      ui::PageTransitionFromInt(
-          ui::PAGE_TRANSITION_AUTO_BOOKMARK |
-          ui::PAGE_TRANSITION_HOME_PAGE),
+      ui::PageTransitionFromInt(ui::PAGE_TRANSITION_AUTO_BOOKMARK |
+                                ui::PAGE_TRANSITION_HOME_PAGE),
       false);
   params.extra_headers = extra_headers;
   browser->OpenURL(params);
@@ -560,11 +561,12 @@
   Navigate(&params);
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
-  DCHECK(extensions::ExtensionSystem::Get(
-      browser->profile())->extension_service());
+  DCHECK(extensions::ExtensionSystem::Get(browser->profile())
+             ->extension_service());
   const extensions::Extension* extension =
       extensions::ExtensionRegistry::Get(browser->profile())
-          ->enabled_extensions().GetAppByURL(url);
+          ->enabled_extensions()
+          .GetAppByURL(url);
   if (extension) {
     extensions::RecordAppLaunchType(extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
                                     extension->GetType());
@@ -750,8 +752,9 @@
     // Preserve the size of the original window. The new window has already
     // been given an offset by the OS, so we shouldn't copy the old bounds.
     BrowserWindow* new_window = new_browser->window();
-    new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
-                          browser->window()->GetRestoredBounds().size()));
+    new_window->SetBounds(
+        gfx::Rect(new_window->GetRestoredBounds().origin(),
+                  browser->window()->GetRestoredBounds().size()));
 
     // We need to show the browser now.  Otherwise ContainerWin assumes the
     // WebContents is invisible and won't size it.
@@ -858,8 +861,8 @@
       case extensions::Command::Type::kPageAction:
         // BookmarkCurrentPage is called through a user gesture, so it is safe
         // to grant the active tab permission.
-        extensions::ExtensionActionAPI::Get(browser->profile())->
-            ShowExtensionActionPopup(extension, browser, true);
+        extensions::ExtensionActionAPI::Get(browser->profile())
+            ->ShowExtensionActionPopup(extension, browser, true);
         break;
     }
     return;
@@ -879,8 +882,8 @@
 
 bool CanBookmarkAllTabs(const Browser* browser) {
   return browser->tab_strip_model()->count() > 1 &&
-             !chrome::ShouldRemoveBookmarkOpenPagesUI(browser->profile()) &&
-             CanBookmarkCurrentPageInternal(browser, false);
+         !chrome::ShouldRemoveBookmarkOpenPagesUI(browser->profile()) &&
+         CanBookmarkCurrentPageInternal(browser, false);
 }
 
 void SaveCreditCard(Browser* browser) {
@@ -935,8 +938,8 @@
       browser->tab_strip_model()->GetActiveWebContents();
   ManagePasswordsUIController* controller =
       ManagePasswordsUIController::FromWebContents(web_contents);
-  TabDialogs::FromWebContents(web_contents)->ShowManagePasswordsBubble(
-      !controller->IsAutomaticallyOpeningBubble());
+  TabDialogs::FromWebContents(web_contents)
+      ->ShowManagePasswordsBubble(!controller->IsAutomaticallyOpeningBubble());
 }
 
 void SavePage(Browser* browser) {
@@ -952,11 +955,11 @@
   // LocalState can be NULL in tests.
   if (g_browser_process->local_state() &&
       !g_browser_process->local_state()->GetBoolean(
-      prefs::kAllowFileSelectionDialogs)) {
+          prefs::kAllowFileSelectionDialogs)) {
     return false;
   }
   return !browser->is_devtools() &&
-      !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE);
+         !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE);
 }
 
 void ShowFindBar(Browser* browser) {
@@ -966,9 +969,10 @@
 void Print(Browser* browser) {
 #if BUILDFLAG(ENABLE_PRINTING)
   auto* web_contents = browser->tab_strip_model()->GetActiveWebContents();
-  printing::StartPrint(web_contents, browser->profile()->GetPrefs()->GetBoolean(
-                                         prefs::kPrintPreviewDisabled),
-                       false /* has_selection? */);
+  printing::StartPrint(
+      web_contents,
+      browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled),
+      false /* has_selection? */);
 #endif
 }
 
@@ -982,9 +986,9 @@
   // block it.
   WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
   return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
-      (current_tab && !current_tab->IsCrashed()) &&
-      !(IsShowingWebContentsModalDialog(browser) ||
-        GetContentRestrictions(browser) & CONTENT_RESTRICTION_PRINT);
+         (current_tab && !current_tab->IsCrashed()) &&
+         !(IsShowingWebContentsModalDialog(browser) ||
+           GetContentRestrictions(browser) & CONTENT_RESTRICTION_PRINT);
 }
 
 #if BUILDFLAG(ENABLE_PRINTING)
@@ -1028,11 +1032,11 @@
   WebContents* wc = browser->tab_strip_model()->GetActiveWebContents();
   DCHECK(wc);
 
-  std::string title = net::EscapeQueryParamValue(
-      base::UTF16ToUTF8(wc->GetTitle()), false);
+  std::string title =
+      net::EscapeQueryParamValue(base::UTF16ToUTF8(wc->GetTitle()), false);
   std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
-  std::string mailto = std::string("mailto:?subject=Fwd:%20") +
-      title + "&body=%0A%0A" + page_url;
+  std::string mailto = std::string("mailto:?subject=Fwd:%20") + title +
+                       "&body=%0A%0A" + page_url;
   platform_util::OpenExternal(browser->profile(), GURL(mailto));
 }
 
@@ -1199,7 +1203,7 @@
 
 bool CanRequestTabletSite(WebContents* current_tab) {
   return current_tab &&
-      current_tab->GetController().GetLastCommittedEntry() != NULL;
+         current_tab->GetController().GetLastCommittedEntry() != NULL;
 }
 
 bool IsRequestingTabletSite(Browser* browser) {
@@ -1251,8 +1255,8 @@
 
 bool IsDebuggerAttachedToCurrentTab(Browser* browser) {
   WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
-  return contents ?
-      content::DevToolsAgentHost::IsDebuggerAttached(contents) : false;
+  return contents ? content::DevToolsAgentHost::IsDebuggerAttached(contents)
+                  : false;
 }
 
 void CopyURL(Browser* browser) {
@@ -1283,9 +1287,10 @@
 }
 
 bool CanViewSource(const Browser* browser) {
-  return !browser->is_devtools() &&
-      browser->tab_strip_model()->GetActiveWebContents()->GetController().
-          CanViewSource();
+  return !browser->is_devtools() && browser->tab_strip_model()
+                                        ->GetActiveWebContents()
+                                        ->GetController()
+                                        .CanViewSource();
 }
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h
index 4aa0f36..6df3840 100644
--- a/chrome/browser/ui/browser_commands.h
+++ b/chrome/browser/ui/browser_commands.h
@@ -82,8 +82,7 @@
 bool CanZoomOut(content::WebContents* contents);
 bool CanResetZoom(content::WebContents* contents);
 void RestoreTab(Browser* browser);
-TabStripModelDelegate::RestoreTabType GetRestoreTabType(
-    const Browser* browser);
+TabStripModelDelegate::RestoreTabType GetRestoreTabType(const Browser* browser);
 void SelectNextTab(
     Browser* browser,
     TabStripModel::UserGestureDetails gesture_detail =
diff --git a/chrome/browser/ui/browser_content_setting_bubble_model_delegate.cc b/chrome/browser/ui/browser_content_setting_bubble_model_delegate.cc
index 88e1f37..a0ca506 100644
--- a/chrome/browser/ui/browser_content_setting_bubble_model_delegate.cc
+++ b/chrome/browser/ui/browser_content_setting_bubble_model_delegate.cc
@@ -19,12 +19,11 @@
     "https://support.google.com/chrome/?p=unauthenticated";
 
 BrowserContentSettingBubbleModelDelegate::
-BrowserContentSettingBubbleModelDelegate(Browser* browser) : browser_(browser) {
-}
+    BrowserContentSettingBubbleModelDelegate(Browser* browser)
+    : browser_(browser) {}
 
 BrowserContentSettingBubbleModelDelegate::
-~BrowserContentSettingBubbleModelDelegate() {
-}
+    ~BrowserContentSettingBubbleModelDelegate() {}
 
 void BrowserContentSettingBubbleModelDelegate::ShowCollectedCookiesDialog(
     content::WebContents* web_contents) {
@@ -34,8 +33,7 @@
 void BrowserContentSettingBubbleModelDelegate::ShowMediaSettingsPage() {
   // Microphone and camera settings appear in the content settings menu right
   // next to each other, the microphone section is first.
-  chrome::ShowContentSettings(
-          browser_, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
+  chrome::ShowContentSettings(browser_, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
 }
 
 void BrowserContentSettingBubbleModelDelegate::ShowContentSettingsPage(
diff --git a/chrome/browser/ui/browser_finder.cc b/chrome/browser/ui/browser_finder.cc
index 93a6940..441237597 100644
--- a/chrome/browser/ui/browser_finder.cc
+++ b/chrome/browser/ui/browser_finder.cc
@@ -28,15 +28,14 @@
 
 namespace {
 
-
 // Type used to indicate to match anything.
-const int kMatchAny                     = 0;
+const int kMatchAny = 0;
 
 // See BrowserMatches for details.
-const int kMatchOriginalProfile         = 1 << 0;
+const int kMatchOriginalProfile = 1 << 0;
 const int kMatchCanSupportWindowFeature = 1 << 1;
-const int kMatchTabbed                  = 1 << 2;
-const int kMatchDisplayId               = 1 << 3;
+const int kMatchTabbed = 1 << 2;
+const int kMatchDisplayId = 1 << 3;
 
 // Returns true if the specified |browser| matches the specified arguments.
 // |match_types| is a bitmask dictating what parameters to match:
@@ -173,10 +172,8 @@
                                         display_id);
 }
 
-Browser* FindAnyBrowser(Profile* profile,
-                        bool match_original_profiles) {
-  return FindBrowserWithTabbedOrAnyType(profile,
-                                        false,
+Browser* FindAnyBrowser(Profile* profile, bool match_original_profiles) {
+  return FindBrowserWithTabbedOrAnyType(profile, false,
                                         match_original_profiles);
 }
 
diff --git a/chrome/browser/ui/browser_finder.h b/chrome/browser/ui/browser_finder.h
index 7b9ca16..45ecde7 100644
--- a/chrome/browser/ui/browser_finder.h
+++ b/chrome/browser/ui/browser_finder.h
@@ -37,8 +37,7 @@
                            int64_t display_id = display::kInvalidDisplayId);
 
 // Finds an existing browser window of any kind.
-Browser* FindAnyBrowser(Profile* profile,
-                        bool match_original_profiles);
+Browser* FindAnyBrowser(Profile* profile, bool match_original_profiles);
 
 // Find an existing browser window with the provided profile. Searches in the
 // order of last activation. Only browsers that have been active can be
diff --git a/chrome/browser/ui/browser_finder_chromeos_unittest.cc b/chrome/browser/ui/browser_finder_chromeos_unittest.cc
index fb60bf8..fa63cd7 100644
--- a/chrome/browser/ui/browser_finder_chromeos_unittest.cc
+++ b/chrome/browser/ui/browser_finder_chromeos_unittest.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/browser_finder.h"
-
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
@@ -11,6 +9,7 @@
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_client.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_client_impl.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_client_impl_test_helper.h"
+#include "chrome/browser/ui/browser_finder.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/test_browser_window_aura.h"
 #include "chrome/test/base/testing_profile_manager.h"
diff --git a/chrome/browser/ui/browser_focus_uitest.cc b/chrome/browser/ui/browser_focus_uitest.cc
index 785bc31..1ea385b 100644
--- a/chrome/browser/ui/browser_focus_uitest.cc
+++ b/chrome/browser/ui/browser_focus_uitest.cc
@@ -83,15 +83,13 @@
     return ui_test_utils::IsViewFocused(browser(), vid);
   }
 
-  void ClickOnView(ViewID vid) {
-    ui_test_utils::ClickOnView(browser(), vid);
-  }
+  void ClickOnView(ViewID vid) { ui_test_utils::ClickOnView(browser(), vid); }
 
   void TestFocusTraversal(RenderViewHost* render_view_host, bool reverse) {
     const char kGetFocusedElementJS[] =
         "window.domAutomationController.send(getFocusedElement());";
-    const char* kExpectedIDs[] = { "textEdit", "searchButton", "luckyButton",
-                                   "googleLink", "gmailLink", "gmapLink" };
+    const char* kExpectedIDs[] = {"textEdit",   "searchButton", "luckyButton",
+                                  "googleLink", "gmailLink",    "gmapLink"};
     SCOPED_TRACE(base::StringPrintf("TestFocusTraversal: reverse=%d", reverse));
     ui::KeyboardCode key = ui::VKEY_TAB;
 #if defined(OS_MACOSX)
@@ -109,12 +107,12 @@
       // are required to traverse the back/forward buttons and the tab strip.
 #if defined(OS_MACOSX)
       if (ui_controls::IsFullKeyboardAccessEnabled()) {
-        ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
-            browser(), key, false, reverse, false, false));
+        ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), key, false,
+                                                    reverse, false, false));
         if (reverse) {
           for (int j = 0; j < 3; ++j) {
-            ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
-                browser(), key, false, reverse, false, false));
+            ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), key, false,
+                                                        reverse, false, false));
           }
         }
       }
@@ -273,16 +271,13 @@
 
   // Create several tabs.
   for (int i = 0; i < 4; ++i) {
-    chrome::AddSelectedTabWithURL(browser(), url,
-                                  ui::PAGE_TRANSITION_TYPED);
+    chrome::AddSelectedTabWithURL(browser(), url, ui::PAGE_TRANSITION_TYPED);
   }
 
   // Alternate focus for the tab.
-  const bool kFocusPage[3][5] = {
-    { true, true, true, true, false },
-    { false, false, false, false, false },
-    { false, true, false, true, false }
-  };
+  const bool kFocusPage[3][5] = {{true, true, true, true, false},
+                                 {false, false, false, false, false},
+                                 {false, true, false, true, false}};
 
   for (int i = 0; i < 3; i++) {
     for (int j = 0; j < 5; j++) {
@@ -313,24 +308,24 @@
     // Try the above, but with ctrl+tab. Since tab normally changes focus,
     // this has regressed in the past. Loop through several times to be sure.
     for (int j = 0; j < 15; j++) {
-      ViewID vid = kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER :
-                                          VIEW_ID_OMNIBOX;
+      ViewID vid =
+          kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER : VIEW_ID_OMNIBOX;
       ASSERT_TRUE(IsViewFocused(vid));
 
-      ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
-          browser(), ui::VKEY_TAB, true, false, false, false));
+      ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_TAB, true,
+                                                  false, false, false));
     }
 
     // As above, but with ctrl+shift+tab.
     browser()->tab_strip_model()->ActivateTabAt(
         4, {TabStripModel::GestureType::kOther});
     for (int j = 14; j >= 0; --j) {
-      ViewID vid = kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER :
-                                          VIEW_ID_OMNIBOX;
+      ViewID vid =
+          kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER : VIEW_ID_OMNIBOX;
       ASSERT_TRUE(IsViewFocused(vid));
 
-      ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
-          browser(), ui::VKEY_TAB, true, true, false, false));
+      ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_TAB, true,
+                                                  true, false, false));
     }
   }
 }
@@ -425,8 +420,7 @@
   chrome::FocusLocationBar(browser());
 
   ASSERT_TRUE(content::ExecuteScript(
-      browser()->tab_strip_model()->GetActiveWebContents(),
-      "stealFocus();"));
+      browser()->tab_strip_model()->GetActiveWebContents(), "stealFocus();"));
 
   // Make sure the location bar is still focused.
   ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX));
@@ -547,8 +541,8 @@
   EXPECT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
 
   // Open about:blank, focus should be on the location bar.
-  chrome::AddSelectedTabWithURL(
-      browser(), GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_LINK);
+  chrome::AddSelectedTabWithURL(browser(), GURL(url::kAboutBlankURL),
+                                ui::PAGE_TRANSITION_LINK);
   ASSERT_NO_FATAL_FAILURE(content::WaitForLoadStop(
       browser()->tab_strip_model()->GetActiveWebContents()));
   EXPECT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX));
@@ -570,8 +564,10 @@
     content::WindowedNotificationObserver observer(
         content::NOTIFICATION_LOAD_STOP,
         content::Source<content::NavigationController>(
-            &browser()->tab_strip_model()->GetActiveWebContents()->
-                GetController()));
+            &browser()
+                 ->tab_strip_model()
+                 ->GetActiveWebContents()
+                 ->GetController()));
     chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
     observer.Wait();
   }
@@ -587,8 +583,10 @@
     content::WindowedNotificationObserver observer(
         content::NOTIFICATION_LOAD_STOP,
         content::Source<content::NavigationController>(
-            &browser()->tab_strip_model()->GetActiveWebContents()->
-                GetController()));
+            &browser()
+                 ->tab_strip_model()
+                 ->GetActiveWebContents()
+                 ->GetController()));
     chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
     observer.Wait();
   }
@@ -616,8 +614,10 @@
     content::WindowedNotificationObserver observer(
         content::NOTIFICATION_LOAD_STOP,
         content::Source<content::NavigationController>(
-            &browser()->tab_strip_model()->GetActiveWebContents()->
-                GetController()));
+            &browser()
+                 ->tab_strip_model()
+                 ->GetActiveWebContents()
+                 ->GetController()));
     chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
     observer.Wait();
   }
@@ -654,8 +654,12 @@
   // Focus the omnibox.
   chrome::FocusLocationBar(browser());
 
-  OmniboxEditController* controller = browser()->window()->GetLocationBar()->
-      GetOmniboxView()->model()->controller();
+  OmniboxEditController* controller = browser()
+                                          ->window()
+                                          ->GetLocationBar()
+                                          ->GetOmniboxView()
+                                          ->model()
+                                          ->controller();
 
   // Simulate an alt-enter.
   controller->OnAutocompleteAccept(
@@ -686,8 +690,9 @@
 
   // Navigate to another page.
   const base::FilePath::CharType* kEmptyFile = FILE_PATH_LITERAL("empty.html");
-  GURL file_url(ui_test_utils::GetTestUrl(base::FilePath(
-      base::FilePath::kCurrentDirectory), base::FilePath(kEmptyFile)));
+  GURL file_url(ui_test_utils::GetTestUrl(
+      base::FilePath(base::FilePath::kCurrentDirectory),
+      base::FilePath(kEmptyFile)));
   ui_test_utils::NavigateToURL(browser(), file_url);
 
   ClickOnView(VIEW_ID_TAB_CONTAINER);
@@ -731,7 +736,8 @@
   const GURL url2 = embedded_test_server()->GetURL("/title2.html");
   const std::string spoof =
       "var w = window.open('about:blank'); w.opener = null;"
-      "w.document.location = '" + url2.spec() + "';";
+      "w.document.location = '" +
+      url2.spec() + "';";
 
   ASSERT_TRUE(content::ExecuteScript(web_contents, spoof));
   EXPECT_EQ(url1, web_contents->GetVisibleURL());
diff --git a/chrome/browser/ui/browser_instant_controller_unittest.cc b/chrome/browser/ui/browser_instant_controller_unittest.cc
index 60c8139..14adffe4 100644
--- a/chrome/browser/ui/browser_instant_controller_unittest.cc
+++ b/chrome/browser/ui/browser_instant_controller_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/ui/browser_instant_controller.h"
+
 #include <stddef.h>
 
 #include <vector>
@@ -14,7 +16,6 @@
 #include "chrome/browser/search/instant_service.h"
 #include "chrome/browser/search/instant_unittest_base.h"
 #include "chrome/browser/search/search.h"
-#include "chrome/browser/ui/browser_instant_controller.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/navigation_handle.h"
@@ -76,20 +77,15 @@
 
   const GURL& current_url() const { return contents_->GetURL(); }
 
-  int num_reloads() const {
-    return num_reloads_;
-  }
+  int num_reloads() const { return num_reloads_; }
 
-  bool can_go_back() const {
-    return contents_->GetController().CanGoBack();
-  }
+  bool can_go_back() const { return contents_->GetController().CanGoBack(); }
 
  protected:
   friend class BrowserInstantControllerTest;
   FRIEND_TEST_ALL_PREFIXES(BrowserInstantControllerTest,
                            DefaultSearchProviderChanged);
-  FRIEND_TEST_ALL_PREFIXES(BrowserInstantControllerTest,
-                           GoogleBaseURLUpdated);
+  FRIEND_TEST_ALL_PREFIXES(BrowserInstantControllerTest, GoogleBaseURLUpdated);
 
  private:
   content::WebContents* contents_;
@@ -106,7 +102,7 @@
         kTabReloadTestCasesFinalProviderNotGoogle[i];
     AddTab(browser(), GURL(test.start_url));
     content::WebContents* contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
+        browser()->tab_strip_model()->GetActiveWebContents();
 
     // Validate initial instant state.
     EXPECT_EQ(test.start_in_instant_process,
@@ -137,7 +133,7 @@
     base::RunLoop loop;
     loop.RunUntilIdle();
     EXPECT_EQ(test.should_reload ? 1 : 0, observer->num_reloads())
-      << test.description;
+        << test.description;
 
     if (test.end_in_local_ntp) {
       EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), observer->current_url())
@@ -153,7 +149,7 @@
     const TabReloadTestCase& test = kTabReloadTestCasesFinalProviderGoogle[i];
     AddTab(browser(), GURL(test.start_url));
     content::WebContents* contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
+        browser()->tab_strip_model()->GetActiveWebContents();
 
     // Validate initial instant state.
     EXPECT_EQ(test.start_in_instant_process,
@@ -181,7 +177,7 @@
     base::RunLoop loop;
     loop.RunUntilIdle();
     EXPECT_EQ(test.should_reload ? 1 : 0, observer->num_reloads())
-      << test.description;
+        << test.description;
 
     if (test.end_in_local_ntp) {
       EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), observer->current_url())
diff --git a/chrome/browser/ui/browser_list.cc b/chrome/browser/ui/browser_list.cc
index 76f2d70a..ed1a235 100644
--- a/chrome/browser/ui/browser_list.cc
+++ b/chrome/browser/ui/browser_list.cc
@@ -82,8 +82,7 @@
   browser->RegisterKeepAlive();
 
   content::NotificationService::current()->Notify(
-      chrome::NOTIFICATION_BROWSER_OPENED,
-      content::Source<Browser>(browser),
+      chrome::NOTIFICATION_BROWSER_OPENED, content::Source<Browser>(browser),
       content::NotificationService::NoDetails());
 
   for (BrowserListObserver& observer : observers_.Get())
@@ -101,8 +100,7 @@
   browser_list->currently_closing_browsers_.erase(browser);
 
   content::NotificationService::current()->Notify(
-      chrome::NOTIFICATION_BROWSER_CLOSED,
-      content::Source<Browser>(browser),
+      chrome::NOTIFICATION_BROWSER_CLOSED, content::Source<Browser>(browser),
       content::NotificationService::NoDetails());
 
   RemoveBrowserFrom(browser, &browser_list->browsers_);
@@ -332,11 +330,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 // BrowserList, private:
 
-BrowserList::BrowserList() {
-}
+BrowserList::BrowserList() {}
 
-BrowserList::~BrowserList() {
-}
+BrowserList::~BrowserList() {}
 
 // static
 void BrowserList::RemoveBrowserFrom(Browser* browser,
diff --git a/chrome/browser/ui/browser_list_observer.h b/chrome/browser/ui/browser_list_observer.h
index d8ec51c..6879a58 100644
--- a/chrome/browser/ui/browser_list_observer.h
+++ b/chrome/browser/ui/browser_list_observer.h
@@ -8,7 +8,7 @@
 class Browser;
 
 class BrowserListObserver {
-  public:
+ public:
   // Called immediately after a browser is added to the list
   virtual void OnBrowserAdded(Browser* browser) {}
 
diff --git a/chrome/browser/ui/browser_navigator_browsertest.cc b/chrome/browser/ui/browser_navigator_browsertest.cc
index 91346dd..b146eb9 100644
--- a/chrome/browser/ui/browser_navigator_browsertest.cc
+++ b/chrome/browser/ui/browser_navigator_browsertest.cc
@@ -111,7 +111,9 @@
 }
 
 bool BrowserNavigatorTest::OpenPOSTURLInNewForegroundTabAndGetTitle(
-    const GURL& url, const std::string& post_data, bool is_browser_initiated,
+    const GURL& url,
+    const std::string& post_data,
+    bool is_browser_initiated,
     base::string16* title) {
   NavigateParams param(MakeNavigateParams());
   param.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
@@ -163,8 +165,7 @@
   WebContents* base_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   if (base_web_contents) {
-    create_params.initial_size =
-        base_web_contents->GetContainerBounds().size();
+    create_params.initial_size = base_web_contents->GetContainerBounds().size();
   }
   return WebContents::Create(create_params);
 }
@@ -323,8 +324,7 @@
   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
   EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
 
-  unsigned int previous_tab_contents_count =
-      created_tab_contents_count_ = 0;
+  unsigned int previous_tab_contents_count = created_tab_contents_count_ = 0;
 
   // Navigate to singleton_url1.
   NavigateParams params(MakeNavigateParams());
@@ -337,8 +337,7 @@
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
 
   // No tab contents should have been created
-  EXPECT_EQ(previous_tab_contents_count,
-            created_tab_contents_count_);
+  EXPECT_EQ(previous_tab_contents_count, created_tab_contents_count_);
 }
 
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
@@ -370,8 +369,7 @@
   NavigateParams params(MakeNavigateParams());
   params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
   Navigate(&params);
-  EXPECT_NE(old_contents,
-            browser()->tab_strip_model()->GetActiveWebContents());
+  EXPECT_NE(old_contents, browser()->tab_strip_model()->GetActiveWebContents());
   EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents(),
             params.navigated_or_inserted_contents);
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
@@ -400,8 +398,8 @@
                        Disposition_IncompatibleWindow_Existing) {
   // Open a foreground tab in a window that cannot open popups when there is an
   // existing compatible window somewhere else that they can be opened within.
-  Browser* popup = CreateEmptyBrowserForType(Browser::TYPE_POPUP,
-                                             browser()->profile());
+  Browser* popup =
+      CreateEmptyBrowserForType(Browser::TYPE_POPUP, browser()->profile());
   NavigateParams params(MakeNavigateParams(popup));
   params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
   Navigate(&params);
@@ -433,8 +431,7 @@
   // need a different profile, and creating a popup window with an incognito
   // profile is a quick and dirty way of achieving this.
   Browser* popup = CreateEmptyBrowserForType(
-      Browser::TYPE_POPUP,
-      browser()->profile()->GetOffTheRecordProfile());
+      Browser::TYPE_POPUP, browser()->profile()->GetOffTheRecordProfile());
   NavigateParams params(MakeNavigateParams(popup));
   params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
   Navigate(&params);
@@ -558,8 +555,7 @@
 
 // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP
 // from an app popup results in a new Browser also of TYPE_POPUP.
-IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
-                       Disposition_NewPopupFromAppPopup) {
+IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupFromAppPopup) {
   Browser* app_browser = CreateEmptyBrowserForApp(browser()->profile());
   // Open an app popup.
   NavigateParams params1(MakeNavigateParams(app_browser));
@@ -630,7 +626,6 @@
   EXPECT_TRUE(params.browser->is_trusted_source());
 }
 
-
 // This test verifies that navigating with WindowOpenDisposition = NEW_WINDOW
 // always opens a new window.
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewWindow) {
@@ -1026,9 +1021,8 @@
 // This test verifies that navigating with WindowOpenDisposition = INCOGNITO
 // reuses an existing incognito window when possible.
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_IncognitoRefocus) {
-  Browser* incognito_browser =
-      CreateEmptyBrowserForType(Browser::TYPE_TABBED,
-                                browser()->profile()->GetOffTheRecordProfile());
+  Browser* incognito_browser = CreateEmptyBrowserForType(
+      Browser::TYPE_TABBED, browser()->profile()->GetOffTheRecordProfile());
   NavigateParams params(MakeNavigateParams());
   params.disposition = WindowOpenDisposition::OFF_THE_RECORD;
   Navigate(&params);
@@ -1204,9 +1198,10 @@
   EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(3, browser()->tab_strip_model()->count());
   EXPECT_EQ(2, browser()->tab_strip_model()->active_index());
-  EXPECT_EQ(GetContentSettingsURL(),
-            ShortenUberURL(browser()->tab_strip_model()->
-                GetActiveWebContents()->GetURL()));
+  EXPECT_EQ(
+      GetContentSettingsURL(),
+      ShortenUberURL(
+          browser()->tab_strip_model()->GetActiveWebContents()->GetURL()));
 }
 
 // This test verifies that constructing params with disposition = SINGLETON_TAB
@@ -1238,9 +1233,10 @@
   EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(3, browser()->tab_strip_model()->count());
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
-  EXPECT_EQ(GetContentSettingsURL(),
-            ShortenUberURL(browser()->tab_strip_model()->
-                GetActiveWebContents()->GetURL()));
+  EXPECT_EQ(
+      GetContentSettingsURL(),
+      ShortenUberURL(
+          browser()->tab_strip_model()->GetActiveWebContents()->GetURL()));
 }
 
 // This test verifies that constructing params with disposition = SINGLETON_TAB
@@ -1272,9 +1268,10 @@
   EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(3, browser()->tab_strip_model()->count());
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
-  EXPECT_EQ(GetClearBrowsingDataURL(),
-            ShortenUberURL(browser()->tab_strip_model()->
-                GetActiveWebContents()->GetURL()));
+  EXPECT_EQ(
+      GetClearBrowsingDataURL(),
+      ShortenUberURL(
+          browser()->tab_strip_model()->GetActiveWebContents()->GetURL()));
 }
 
 // This test verifies that constructing params with disposition = SINGLETON_TAB
@@ -1304,9 +1301,10 @@
   EXPECT_EQ(browser(), params.browser);
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
   EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
-  EXPECT_EQ(singleton_url_target,
-            ShortenUberURL(browser()->tab_strip_model()->
-                GetActiveWebContents()->GetURL()));
+  EXPECT_EQ(
+      singleton_url_target,
+      ShortenUberURL(
+          browser()->tab_strip_model()->GetActiveWebContents()->GetURL()));
 }
 
 // This test verifies that constructing params with disposition = SINGLETON_TAB
@@ -1384,9 +1382,10 @@
   }
 
   EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
-  EXPECT_EQ(GetSettingsURL(),
-            ShortenUberURL(browser()->tab_strip_model()->
-                GetActiveWebContents()->GetURL()));
+  EXPECT_EQ(
+      GetSettingsURL(),
+      ShortenUberURL(
+          browser()->tab_strip_model()->GetActiveWebContents()->GetURL()));
 }
 
 // Settings page is expected to always open in normal mode regardless
@@ -1450,9 +1449,10 @@
     observer.Wait();
   }
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
-  EXPECT_EQ(GetSettingsURL(),
-            ShortenUberURL(browser()->tab_strip_model()->
-                GetActiveWebContents()->GetURL()));
+  EXPECT_EQ(
+      GetSettingsURL(),
+      ShortenUberURL(
+          browser()->tab_strip_model()->GetActiveWebContents()->GetURL()));
 }
 
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
@@ -1469,9 +1469,10 @@
     observer.Wait();
   }
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
-  EXPECT_EQ(GetSettingsURL(),
-            ShortenUberURL(browser()->tab_strip_model()->
-                GetActiveWebContents()->GetURL()));
+  EXPECT_EQ(
+      GetSettingsURL(),
+      ShortenUberURL(
+          browser()->tab_strip_model()->GetActiveWebContents()->GetURL()));
 }
 
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
@@ -1491,9 +1492,10 @@
     observer.Wait();
   }
   EXPECT_EQ(1, browser()->tab_strip_model()->count());
-  EXPECT_EQ(GetSettingsURL(),
-            ShortenUberURL(browser()->tab_strip_model()->
-                GetActiveWebContents()->GetURL()));
+  EXPECT_EQ(
+      GetSettingsURL(),
+      ShortenUberURL(
+          browser()->tab_strip_model()->GetActiveWebContents()->GetURL()));
 }
 
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
@@ -1513,9 +1515,10 @@
     observer.Wait();
   }
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
-  EXPECT_EQ(GetSettingsURL(),
-            ShortenUberURL(browser()->tab_strip_model()->
-                GetActiveWebContents()->GetURL()));
+  EXPECT_EQ(
+      GetSettingsURL(),
+      ShortenUberURL(
+          browser()->tab_strip_model()->GetActiveWebContents()->GetURL()));
 }
 
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
@@ -1540,9 +1543,10 @@
     observer.Wait();
   }
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
-  EXPECT_EQ(GetSettingsURL(),
-            ShortenUberURL(browser()->tab_strip_model()->
-                GetActiveWebContents()->GetURL()));
+  EXPECT_EQ(
+      GetSettingsURL(),
+      ShortenUberURL(
+          browser()->tab_strip_model()->GetActiveWebContents()->GetURL()));
 }
 
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
@@ -1597,9 +1601,10 @@
   ShowSettings(browser());
 
   EXPECT_EQ(2, browser()->tab_strip_model()->count());
-  EXPECT_EQ(GetSettingsURL(),
-            ShortenUberURL(browser()->tab_strip_model()->
-                GetActiveWebContents()->GetURL()));
+  EXPECT_EQ(
+      GetSettingsURL(),
+      ShortenUberURL(
+          browser()->tab_strip_model()->GetActiveWebContents()->GetURL()));
 }
 
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, CloseSingletonTab) {
@@ -1645,10 +1650,10 @@
 // TODO(linux_aura) http://crbug.com/163931
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
 #define MAYBE_NavigateFromDefaultToBookmarksInSameTab \
-    DISABLED_NavigateFromDefaultToBookmarksInSameTab
+  DISABLED_NavigateFromDefaultToBookmarksInSameTab
 #else
 #define MAYBE_NavigateFromDefaultToBookmarksInSameTab \
-    NavigateFromDefaultToBookmarksInSameTab
+  NavigateFromDefaultToBookmarksInSameTab
 #endif
 IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
                        MAYBE_NavigateFromDefaultToBookmarksInSameTab) {
@@ -1679,8 +1684,7 @@
             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
 }
 
-IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest,
-                       NavigateWithoutBrowser) {
+IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, NavigateWithoutBrowser) {
   // First navigate using the profile of the existing browser window, and
   // check that the window is reused.
   NavigateParams params(browser()->profile(), GetGoogleURL(),
diff --git a/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc b/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc
index 5052dc6..d545e09 100644
--- a/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc
+++ b/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/browser_navigator_browsertest.h"
-
 #include "ash/public/cpp/window_properties.h"
 #include "ash/public/interfaces/window_pin_type.mojom.h"
 #include "base/command_line.h"
@@ -13,6 +11,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_navigator.h"
+#include "chrome/browser/ui/browser_navigator_browsertest.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/settings_window_manager_chromeos.h"
@@ -106,17 +105,15 @@
 }
 
 // Subclass that tests navigation while in the Guest session.
-class BrowserGuestSessionNavigatorTest: public BrowserNavigatorTest {
+class BrowserGuestSessionNavigatorTest : public BrowserNavigatorTest {
  protected:
   void SetUpCommandLine(base::CommandLine* command_line) override {
     base::CommandLine command_line_copy = *command_line;
-    command_line_copy.AppendSwitchASCII(
-        chromeos::switches::kLoginProfile, "user");
+    command_line_copy.AppendSwitchASCII(chromeos::switches::kLoginProfile,
+                                        "user");
     command_line_copy.AppendSwitch(chromeos::switches::kGuestSession);
-    chromeos::GetOffTheRecordCommandLine(GetGoogleURL(),
-                                         true,
-                                         command_line_copy,
-                                         command_line);
+    chromeos::GetOffTheRecordCommandLine(GetGoogleURL(), true,
+                                         command_line_copy, command_line);
   }
 };
 
@@ -142,9 +139,9 @@
   EXPECT_NE(browser(), params.browser);
   EXPECT_EQ(incognito_browser, params.browser);
   EXPECT_EQ(2, incognito_browser->tab_strip_model()->count());
-  EXPECT_EQ(GURL("chrome://chrome/settings"),
-            incognito_browser->tab_strip_model()->GetActiveWebContents()->
-                GetURL());
+  EXPECT_EQ(
+      GURL("chrome://chrome/settings"),
+      incognito_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
 }
 
 // Test that in multi user environments a newly created browser gets created
diff --git a/chrome/browser/ui/browser_navigator_params.h b/chrome/browser/ui/browser_navigator_params.h
index 88dc7eeb..7e46721 100644
--- a/chrome/browser/ui/browser_navigator_params.h
+++ b/chrome/browser/ui/browser_navigator_params.h
@@ -31,7 +31,7 @@
 class RenderFrameHost;
 class WebContents;
 struct OpenURLParams;
-}
+}  // namespace content
 
 // Parameters that tell Navigate() what to do.
 //
diff --git a/chrome/browser/ui/browser_otr_state_android.cc b/chrome/browser/ui/browser_otr_state_android.cc
index 526f228..3a1eb86 100644
--- a/chrome/browser/ui/browser_otr_state_android.cc
+++ b/chrome/browser/ui/browser_otr_state_android.cc
@@ -2,9 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/browser_otr_state.h"
-
 #include "chrome/browser/ui/android/tab_model/tab_model_list.h"
+#include "chrome/browser/ui/browser_otr_state.h"
 
 namespace chrome {
 
diff --git a/chrome/browser/ui/browser_tab_strip_model_delegate.cc b/chrome/browser/ui/browser_tab_strip_model_delegate.cc
index 189a628f..fa4dccfa 100644
--- a/chrome/browser/ui/browser_tab_strip_model_delegate.cc
+++ b/chrome/browser/ui/browser_tab_strip_model_delegate.cc
@@ -34,12 +34,9 @@
 // BrowserTabStripModelDelegate, public:
 
 BrowserTabStripModelDelegate::BrowserTabStripModelDelegate(Browser* browser)
-    : browser_(browser),
-      weak_factory_(this) {
-}
+    : browser_(browser), weak_factory_(this) {}
 
-BrowserTabStripModelDelegate::~BrowserTabStripModelDelegate() {
-}
+BrowserTabStripModelDelegate::~BrowserTabStripModelDelegate() {}
 
 ////////////////////////////////////////////////////////////////////////////////
 // BrowserTabStripModelDelegate, TabStripModelDelegate implementation:
@@ -96,8 +93,9 @@
 
 int BrowserTabStripModelDelegate::GetDragActions() const {
   return TabStripModelDelegate::TAB_TEAROFF_ACTION |
-      (browser_->tab_strip_model()->count() > 1
-          ? TabStripModelDelegate::TAB_MOVE_ACTION : 0);
+         (browser_->tab_strip_model()->count() > 1
+              ? TabStripModelDelegate::TAB_MOVE_ACTION
+              : 0);
 }
 
 bool BrowserTabStripModelDelegate::CanDuplicateContentsAt(int index) {
diff --git a/chrome/browser/ui/browser_tabrestore.cc b/chrome/browser/ui/browser_tabrestore.cc
index eecb1eb..055965a 100644
--- a/chrome/browser/ui/browser_tabrestore.cc
+++ b/chrome/browser/ui/browser_tabrestore.cc
@@ -23,9 +23,9 @@
 #include "content/public/browser/session_storage_namespace.h"
 #include "content/public/browser/web_contents.h"
 
+using content::NavigationEntry;
 using content::RestoreType;
 using content::WebContents;
-using content::NavigationEntry;
 using sessions::ContentSerializedNavigationBuilder;
 using sessions::SerializedNavigationEntry;
 
@@ -70,8 +70,7 @@
   WebContents* base_web_contents =
       browser->tab_strip_model()->GetActiveWebContents();
   if (base_web_contents) {
-    create_params.initial_size =
-        base_web_contents->GetContainerBounds().size();
+    create_params.initial_size = base_web_contents->GetContainerBounds().size();
   }
   std::unique_ptr<WebContents> web_contents =
       WebContents::CreateWithSessionStorage(create_params,
@@ -113,8 +112,7 @@
       from_last_session, last_active_time, session_storage_namespace,
       user_agent_override, !select, from_session_restore);
 
-  int add_types = select ? TabStripModel::ADD_ACTIVE
-                         : TabStripModel::ADD_NONE;
+  int add_types = select ? TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE;
   if (pin) {
     tab_index = std::min(
         tab_index, browser->tab_strip_model()->IndexOfFirstNonPinnedTab());
diff --git a/chrome/browser/ui/browser_tabrestore.h b/chrome/browser/ui/browser_tabrestore.h
index 8311ed21..451ead1 100644
--- a/chrome/browser/ui/browser_tabrestore.h
+++ b/chrome/browser/ui/browser_tabrestore.h
@@ -15,7 +15,7 @@
 namespace content {
 class SessionStorageNamespace;
 class WebContents;
-}
+}  // namespace content
 
 namespace sessions {
 class SerializedNavigationEntry;
diff --git a/chrome/browser/ui/browser_tabrestore_browsertest.cc b/chrome/browser/ui/browser_tabrestore_browsertest.cc
index d5c2064..fb8846b8 100644
--- a/chrome/browser/ui/browser_tabrestore_browsertest.cc
+++ b/chrome/browser/ui/browser_tabrestore_browsertest.cc
@@ -32,7 +32,8 @@
   for (int i = 0; i < tab_strip_model->count(); ++i) {
     content::WebContents* contents = tab_strip_model->GetWebContentsAt(i);
     std::string document_visibility_state;
-    const char kGetStateJS[] = "window.domAutomationController.send("
+    const char kGetStateJS[] =
+        "window.domAutomationController.send("
         "window.document.visibilityState);";
     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
         contents, kGetStateJS, &document_visibility_state));
@@ -45,7 +46,8 @@
 }
 
 void CreateTestTabs(Browser* browser) {
-  GURL test_page(ui_test_utils::GetTestUrl(base::FilePath(),
+  GURL test_page(ui_test_utils::GetTestUrl(
+      base::FilePath(),
       base::FilePath(FILE_PATH_LITERAL("tab-restore-visibility.html"))));
   ui_test_utils::NavigateToURLWithDisposition(
       browser, test_page, WindowOpenDisposition::NEW_FOREGROUND_TAB,
@@ -75,8 +77,7 @@
   content::DOMMessageQueue queue;
   Browser* browser = active_browser_list->get(0);
   RecentTabsSubMenuModel menu(nullptr, browser);
-  menu.ExecuteCommand(
-      RecentTabsSubMenuModel::GetFirstRecentTabsCommandId(), 0);
+  menu.ExecuteCommand(RecentTabsSubMenuModel::GetFirstRecentTabsCommandId(), 0);
   AwaitTabsReady(&queue, 2);
 
   // There should be 3 restored tabs in the new browser.
diff --git a/chrome/browser/ui/browser_tabstrip.cc b/chrome/browser/ui/browser_tabstrip.cc
index 4aff3ef..43ffee3 100644
--- a/chrome/browser/ui/browser_tabstrip.cc
+++ b/chrome/browser/ui/browser_tabstrip.cc
@@ -41,10 +41,9 @@
   core_tab_helper->set_new_tab_start_time(new_tab_start_time);
 }
 
-content::WebContents* AddSelectedTabWithURL(
-    Browser* browser,
-    const GURL& url,
-    ui::PageTransition transition) {
+content::WebContents* AddSelectedTabWithURL(Browser* browser,
+                                            const GURL& url,
+                                            ui::PageTransition transition) {
   NavigateParams params(browser, url, transition);
   params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
   Navigate(&params);
@@ -83,9 +82,8 @@
   }
 
   browser->tab_strip_model()->CloseWebContentsAt(
-      index,
-      add_to_history ? TabStripModel::CLOSE_CREATE_HISTORICAL_TAB
-                     : TabStripModel::CLOSE_NONE);
+      index, add_to_history ? TabStripModel::CLOSE_CREATE_HISTORICAL_TAB
+                            : TabStripModel::CLOSE_NONE);
 }
 
 }  // namespace chrome
diff --git a/chrome/browser/ui/browser_ui_prefs.cc b/chrome/browser/ui/browser_ui_prefs.cc
index fd2e2a1b..41be29e 100644
--- a/chrome/browser/ui/browser_ui_prefs.cc
+++ b/chrome/browser/ui/browser_ui_prefs.cc
@@ -50,10 +50,8 @@
 }
 
 void RegisterBrowserUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
-  registry->RegisterBooleanPref(
-      prefs::kHomePageIsNewTabPage,
-      true,
-      GetHomeButtonAndHomePageIsNewTabPageFlags());
+  registry->RegisterBooleanPref(prefs::kHomePageIsNewTabPage, true,
+                                GetHomeButtonAndHomePageIsNewTabPageFlags());
   registry->RegisterBooleanPref(prefs::kShowHomeButton, false,
                                 GetHomeButtonAndHomePageIsNewTabPageFlags());
 
@@ -77,8 +75,7 @@
   registry->RegisterDictionaryPref(prefs::kBrowserWindowPlacementPopup);
   registry->RegisterDictionaryPref(prefs::kAppWindowPlacement);
   registry->RegisterBooleanPref(
-      prefs::kEnableDoNotTrack,
-      false,
+      prefs::kEnableDoNotTrack, false,
       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
   registry->RegisterBooleanPref(prefs::kPrintPreviewUseSystemDefaultPrinter,
@@ -115,8 +112,7 @@
   // that use this preference.
   registry->RegisterBooleanPref(prefs::kShowUpdatePromotionInfoBar, true);
   registry->RegisterBooleanPref(
-      prefs::kShowFullscreenToolbar,
-      true,
+      prefs::kShowFullscreenToolbar, true,
       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
   registry->RegisterBooleanPref(
       prefs::kAllowJavascriptAppleEvents, false,
diff --git a/chrome/browser/ui/browser_unittest.cc b/chrome/browser/ui/browser_unittest.cc
index 06802f6..61f33a3 100644
--- a/chrome/browser/ui/browser_unittest.cc
+++ b/chrome/browser/ui/browser_unittest.cc
@@ -135,8 +135,8 @@
   WebContentsTester::For(raw_contents)->NavigateAndCommit(GURL("about:blank"));
   zoom::ZoomController* zoom_controller =
       zoom::ZoomController::FromWebContents(raw_contents);
-  EXPECT_TRUE(zoom_controller->SetZoomLevel(zoom_controller->
-                                            GetDefaultZoomLevel()));
+  EXPECT_TRUE(
+      zoom_controller->SetZoomLevel(zoom_controller->GetDefaultZoomLevel()));
 
   CommandUpdater* command_updater = browser()->command_controller();
 
@@ -275,15 +275,15 @@
 
  protected:
   BookmarkBar::State window_bookmark_bar_state() const {
-    return static_cast<BookmarkBarStateTestBrowserWindow*>(
-        browser()->window())->bookmark_bar_state();
+    return static_cast<BookmarkBarStateTestBrowserWindow*>(browser()->window())
+        ->bookmark_bar_state();
   }
 
   // BrowserWithTestWindowTest:
   void SetUp() override {
     BrowserWithTestWindowTest::SetUp();
-    static_cast<BookmarkBarStateTestBrowserWindow*>(
-        browser()->window())->set_browser(browser());
+    static_cast<BookmarkBarStateTestBrowserWindow*>(browser()->window())
+        ->set_browser(browser());
   }
 
   BrowserWindow* CreateBrowserWindow() override {
@@ -294,8 +294,7 @@
   class BookmarkBarStateTestBrowserWindow : public TestBrowserWindow {
    public:
     BookmarkBarStateTestBrowserWindow()
-        : browser_(NULL),
-          bookmark_bar_state_(BookmarkBar::HIDDEN) {}
+        : browser_(NULL), bookmark_bar_state_(BookmarkBar::HIDDEN) {}
     ~BookmarkBarStateTestBrowserWindow() override {}
 
     void set_browser(Browser* browser) { browser_ = browser; }
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index 2773d42..c040125 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -50,18 +50,18 @@
 class LocalCardMigrationBubble;
 class SaveCardBubbleController;
 class SaveCardBubbleView;
-}
+}  // namespace autofill
 
 namespace content {
 class WebContents;
 struct NativeWebKeyboardEvent;
 enum class KeyboardEventProcessingResult;
-}
+}  // namespace content
 
 namespace extensions {
 class Command;
 class Extension;
-}
+}  // namespace extensions
 
 namespace gfx {
 class Size;
@@ -410,7 +410,7 @@
   // modal dialogs within the browser window. This can sometimes be NULL (for
   // instance during tab drag on Views/Win32).
   virtual web_modal::WebContentsModalDialogHost*
-      GetWebContentsModalDialogHost() = 0;
+  GetWebContentsModalDialogHost() = 0;
 
   // Construct a BrowserWindow implementation for the specified |browser|.
   static BrowserWindow* CreateBrowserWindow(std::unique_ptr<Browser> browser,
diff --git a/chrome/browser/ui/browser_window_state.cc b/chrome/browser/ui/browser_window_state.cc
index 175d95ae..d741811b 100644
--- a/chrome/browser/ui/browser_window_state.cc
+++ b/chrome/browser/ui/browser_window_state.cc
@@ -76,8 +76,8 @@
 
 std::string GetWindowName(const Browser* browser) {
   if (browser->app_name().empty()) {
-    return browser->is_type_popup() ?
-        prefs::kBrowserWindowPlacementPopup : prefs::kBrowserWindowPlacement;
+    return browser->is_type_popup() ? prefs::kBrowserWindowPlacementPopup
+                                    : prefs::kBrowserWindowPlacement;
   }
   return browser->app_name();
 }
@@ -114,7 +114,8 @@
   // Only save the window placement of popups if the window is from a trusted
   // source (v1 app, devtools, or system window).
   return (browser->type() == Browser::TYPE_TABBED) ||
-    ((browser->type() == Browser::TYPE_POPUP) && browser->is_trusted_source());
+         ((browser->type() == Browser::TYPE_POPUP) &&
+          browser->is_trusted_source());
 }
 
 bool SavedBoundsAreContentBounds(const Browser* browser) {
@@ -151,11 +152,8 @@
   DCHECK(bounds);
   DCHECK(show_state);
   *bounds = browser->override_bounds();
-  WindowSizer::GetBrowserWindowBoundsAndShowState(browser->app_name(),
-                                                  *bounds,
-                                                  browser,
-                                                  bounds,
-                                                  show_state);
+  WindowSizer::GetBrowserWindowBoundsAndShowState(browser->app_name(), *bounds,
+                                                  browser, bounds, show_state);
 
   const base::CommandLine& parsed_command_line =
       *base::CommandLine::ForCurrentProcess();
diff --git a/chrome/browser/ui/browser_window_state.h b/chrome/browser/ui/browser_window_state.h
index 49b4534..a4e782d 100644
--- a/chrome/browser/ui/browser_window_state.h
+++ b/chrome/browser/ui/browser_window_state.h
@@ -16,7 +16,7 @@
 namespace base {
 class CommandLine;
 class DictionaryValue;
-}
+}  // namespace base
 
 namespace gfx {
 class Rect;
diff --git a/chrome/browser/ui/certificate_dialogs.cc b/chrome/browser/ui/certificate_dialogs.cc
index 780867d..2f4d0fa0 100644
--- a/chrome/browser/ui/certificate_dialogs.cc
+++ b/chrome/browser/ui/certificate_dialogs.cc
@@ -42,12 +42,12 @@
 void WriterCallback(const base::FilePath& path, const std::string& data) {
   int bytes_written = base::WriteFile(path, data.data(), data.size());
   if (bytes_written != static_cast<ssize_t>(data.size())) {
-    LOG(ERROR) << "Writing " << path.value() << " ("
-               << data.size() << "B) returned " << bytes_written;
+    LOG(ERROR) << "Writing " << path.value() << " (" << data.size()
+               << "B) returned " << bytes_written;
   }
 }
 
-std::string WrapAt64(const std::string &str) {
+std::string WrapAt64(const std::string& str) {
   std::string result;
   for (size_t i = 0; i < str.size(); i += 64) {
     result.append(str, i, 64);  // Append clamps the len arg internally.
@@ -62,9 +62,8 @@
     return std::string();
   std::string base64;
   base::Base64Encode(der_cert, &base64);
-  return "-----BEGIN CERTIFICATE-----\r\n" +
-      WrapAt64(base64) +
-      "-----END CERTIFICATE-----\r\n";
+  return "-----BEGIN CERTIFICATE-----\r\n" + WrapAt64(base64) +
+         "-----END CERTIFICATE-----\r\n";
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -127,7 +126,8 @@
     select_file_dialog_->ListenerDestroyed();
 }
 
-void Exporter::FileSelected(const base::FilePath& path, int index,
+void Exporter::FileSelected(const base::FilePath& path,
+                            int index,
                             void* params) {
   std::string data;
   switch (index - 1) {
@@ -142,8 +142,8 @@
       data = x509_certificate_model::GetCMSString(cert_chain_list_, 0, 1);
       break;
     case kPkcs7Chain:
-      data = x509_certificate_model::GetCMSString(
-          cert_chain_list_, 0, cert_chain_list_.size());
+      data = x509_certificate_model::GetCMSString(cert_chain_list_, 0,
+                                                  cert_chain_list_.size());
       break;
     case kBase64:
     default:
@@ -191,11 +191,9 @@
       l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7_CHAIN));
   file_type_info.include_all_files = true;
   select_file_dialog->SelectFile(
-      type, base::string16(),
-      suggested_path, &file_type_info,
+      type, base::string16(), suggested_path, &file_type_info,
       1,  // 1-based index for |file_type_info.extensions| to specify default.
-      FILE_PATH_LITERAL("crt"),
-      parent, params);
+      FILE_PATH_LITERAL("crt"), parent, params);
 }
 
 void ShowCertExportDialog(content::WebContents* web_contents,
diff --git a/chrome/browser/ui/chrome_bubble_manager.cc b/chrome/browser/ui/chrome_bubble_manager.cc
index eb2ae5a..ae074c8b 100644
--- a/chrome/browser/ui/chrome_bubble_manager.cc
+++ b/chrome/browser/ui/chrome_bubble_manager.cc
@@ -154,7 +154,8 @@
 }
 
 void ChromeBubbleManager::DidToggleFullscreenModeForTab(
-    bool entered_fullscreen, bool will_cause_resize) {
+    bool entered_fullscreen,
+    bool will_cause_resize) {
   CloseAllBubbles(BUBBLE_CLOSE_FULLSCREEN_TOGGLED);
   // Any bubble that didn't close should update its anchor position.
   UpdateAllBubbleAnchors();
@@ -172,7 +173,8 @@
 }
 
 void ChromeBubbleManager::ChromeBubbleMetrics::OnBubbleClosed(
-    BubbleReference bubble, BubbleCloseReason reason) {
+    BubbleReference bubble,
+    BubbleCloseReason reason) {
   // Log the amount of time the bubble was visible.
   base::TimeDelta visible_time = bubble->GetVisibleTime();
   UMA_HISTOGRAM_LONG_TIMES("Bubbles.DisplayTime.All", visible_time);
diff --git a/chrome/browser/ui/chrome_pages.cc b/chrome/browser/ui/chrome_pages.cc
index d8c619d5..2e631b6 100644
--- a/chrome/browser/ui/chrome_pages.cc
+++ b/chrome/browser/ui/chrome_pages.cc
@@ -275,7 +275,6 @@
   return url.SchemeIs(scheme);
 }
 
-
 void ShowSettings(Browser* browser) {
   ShowSettingsSubPage(browser, std::string());
 }
diff --git a/chrome/browser/ui/chrome_select_file_policy.cc b/chrome/browser/ui/chrome_select_file_policy.cc
index b842531..b9bc0b80 100644
--- a/chrome/browser/ui/chrome_select_file_policy.cc
+++ b/chrome/browser/ui/chrome_select_file_policy.cc
@@ -18,8 +18,7 @@
 
 ChromeSelectFilePolicy::ChromeSelectFilePolicy(
     content::WebContents* source_contents)
-    : source_contents_(source_contents) {
-}
+    : source_contents_(source_contents) {}
 
 ChromeSelectFilePolicy::~ChromeSelectFilePolicy() {}
 
diff --git a/chrome/browser/ui/chrome_select_file_policy_unittest.cc b/chrome/browser/ui/chrome_select_file_policy_unittest.cc
index 3b32d13..8171d00 100644
--- a/chrome/browser/ui/chrome_select_file_policy_unittest.cc
+++ b/chrome/browser/ui/chrome_select_file_policy_unittest.cc
@@ -22,7 +22,8 @@
 
 #if defined(USE_AURA)
 // http://crbug.com/105200
-#define MAYBE_ExpectAsynchronousListenerCall DISABLED_ExpectAsynchronousListenerCall
+#define MAYBE_ExpectAsynchronousListenerCall \
+  DISABLED_ExpectAsynchronousListenerCall
 #else
 #define MAYBE_ExpectAsynchronousListenerCall ExpectAsynchronousListenerCall
 #endif
@@ -31,9 +32,7 @@
 
 class FileSelectionUser : public ui::SelectFileDialog::Listener {
  public:
-  FileSelectionUser()
-      : file_selection_initialisation_in_progress(false) {
-  }
+  FileSelectionUser() : file_selection_initialisation_in_progress(false) {}
 
   ~FileSelectionUser() override {
     if (select_file_dialog_.get())
@@ -50,13 +49,8 @@
 
     file_selection_initialisation_in_progress = true;
     select_file_dialog_->SelectFile(ui::SelectFileDialog::SELECT_OPEN_FILE,
-                                    title,
-                                    file_path,
-                                    NULL,
-                                    0,
-                                    base::FilePath::StringType(),
-                                    NULL,
-                                    NULL);
+                                    title, file_path, NULL, 0,
+                                    base::FilePath::StringType(), NULL, NULL);
     file_selection_initialisation_in_progress = false;
   }
 
@@ -89,8 +83,7 @@
 TEST_F(ChromeSelectFilePolicyTest, MAYBE_ExpectAsynchronousListenerCall) {
   content::TestBrowserThreadBundle test_browser_thread_bundle;
 
-  ScopedTestingLocalState local_state(
-      TestingBrowserProcess::GetGlobal());
+  ScopedTestingLocalState local_state(TestingBrowserProcess::GetGlobal());
 
   std::unique_ptr<FileSelectionUser> file_selection_user(
       new FileSelectionUser());
diff --git a/chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.cc b/chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.cc
index 33fd605..64d1639 100644
--- a/chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.cc
+++ b/chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.cc
@@ -7,11 +7,9 @@
 #include "chrome/browser/platform_util.h"
 #include "content/public/browser/web_contents.h"
 
-ChromeWebModalDialogManagerDelegate::ChromeWebModalDialogManagerDelegate() {
-}
+ChromeWebModalDialogManagerDelegate::ChromeWebModalDialogManagerDelegate() {}
 
-ChromeWebModalDialogManagerDelegate::~ChromeWebModalDialogManagerDelegate() {
-}
+ChromeWebModalDialogManagerDelegate::~ChromeWebModalDialogManagerDelegate() {}
 
 bool ChromeWebModalDialogManagerDelegate::IsWebContentsVisible(
     content::WebContents* web_contents) {
diff --git a/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.h b/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.h
index aab52b7..da3f60c 100644
--- a/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.h
+++ b/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.h
@@ -29,6 +29,12 @@
 // True if the current page is starred. Used by star touch bar button.
 @property(nonatomic, assign) BOOL isStarred;
 
+// True if the back button is enabled.
+@property(nonatomic, assign) BOOL canGoBack;
+
+// True if the forward button is enabled.
+@property(nonatomic, assign) BOOL canGoForward;
+
 // Designated initializer.
 - (instancetype)initWithBrowser:(Browser*)browser
                      controller:(BrowserWindowTouchBarController*)controller;
@@ -38,10 +44,6 @@
 
 - (void)updateWebContents:(content::WebContents*)contents;
 
-// Updates the back/forward button. Called when creating the touch bar or when
-// the back and forward commands have changed.
-- (void)updateBackForwardControl;
-
 - (BrowserWindowTouchBarController*)controller;
 
 @end
@@ -49,6 +51,11 @@
 // Private methods exposed for testing.
 @interface BrowserWindowDefaultTouchBar (ExposedForTesting)
 
+@property(readonly, class) NSString* reloadOrStopItemIdentifier;
+@property(readonly, class) NSString* backItemIdentifier;
+@property(readonly, class) NSString* forwardItemIdentifier;
+@property(readonly, class) NSString* fullscreenOriginItemIdentifier;
+
 // Updates the reload/stop button. Called when creating the touch bar or the
 // page load state has been updated.
 - (void)updateReloadStopButton;
@@ -56,10 +63,6 @@
 // Returns the reload/stop button on the touch bar. Creates it if it's null.
 - (NSButton*)reloadStopButton;
 
-// Returns the back/forward segmented control on the touch bar. Creates it if
-// it's null.
-- (NSSegmentedControl*)backForwardControl;
-
 // Returns the bridge object that BrowserWindowDefaultTouchBar uses to receive
 // notifications.
 - (BookmarkTabHelperObserver*)bookmarkTabObserver;
diff --git a/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.mm b/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.mm
index 84099212..d4f5f37 100644
--- a/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.mm
+++ b/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.mm
@@ -51,7 +51,8 @@
 NSString* const kTabFullscreenTouchBarId = @"tab-fullscreen";
 
 // Touch bar items identifiers.
-NSString* const kBackForwardTouchId = @"BACK-FWD";
+NSString* const kBackTouchId = @"BACK";
+NSString* const kForwardTouchId = @"FORWARD";
 NSString* const kReloadOrStopTouchId = @"RELOAD-STOP";
 NSString* const kHomeTouchId = @"HOME";
 NSString* const kSearchTouchId = @"SEARCH";
@@ -59,9 +60,11 @@
 NSString* const kNewTabTouchId = @"NEW-TAB";
 NSString* const kFullscreenOriginLabelTouchId = @"FULLSCREEN-ORIGIN-LABEL";
 
-// The button indexes in the back and forward segment control.
-const int kBackSegmentIndex = 0;
-const int kForwardSegmentIndex = 1;
+// This is a combined back and forward control which can no longer be selected
+// but may be in an existing customized Touch Bar. It now represents a group
+// containing the back and forward buttons, and adding the back or forward
+// buttons to the Touch Bar individually magically decomposes the group.
+NSString* const kBackForwardTouchId = @"BACK-FWD";
 
 // Touch bar icon colors values.
 const SkColor kTouchBarDefaultIconColor = SK_ColorWHITE;
@@ -95,7 +98,7 @@
                          target:owner
                          action:@selector(executeCommand:)];
   button.tag = command;
-  [button setAccessibilityLabel:l10n_util::GetNSString(tooltip_id)];
+  button.accessibilityTitle = l10n_util::GetNSString(tooltip_id);
   return button;
 }
 
@@ -176,7 +179,10 @@
   // CommandObserver:
   void EnabledStateChangedForCommand(int command, bool enabled) override {
     DCHECK(command == IDC_BACK || command == IDC_FORWARD);
-    [owner_ updateBackForwardControl];
+    if (command == IDC_BACK)
+      owner_.canGoBack = enabled;
+    else if (command == IDC_FORWARD)
+      owner_.canGoForward = enabled;
   }
 
   // WebContentsObserver:
@@ -203,10 +209,6 @@
   DISALLOW_COPY_AND_ASSIGN(TouchBarNotificationBridge);
 };
 
-id<NSAccessibility> ToNSAccessibility(id object) {
-  return [object conformsToProtocol:@protocol(NSAccessibility)] ? object : nil;
-}
-
 }  // namespace
 
 @interface BrowserWindowDefaultTouchBar () {
@@ -230,9 +232,6 @@
   // The stop/reload button in the touch bar.
   base::scoped_nsobject<NSButton> reloadStopButton_;
 
-  // The back/forward segmented control in the touch bar.
-  base::scoped_nsobject<NSSegmentedControl> backForwardControl_;
-
   // The starred button in the touch bar.
   base::scoped_nsobject<NSButton> starredButton_;
 }
@@ -240,9 +239,6 @@
 // Creates and returns a touch bar for tab fullscreen mode.
 - (NSTouchBar*)createTabFullscreenTouchBar;
 
-// Sets up the back and forward segmented control.
-- (void)setupBackForwardControl;
-
 // Updates the starred button in the touch bar.
 - (void)updateStarredButton;
 
@@ -255,6 +251,8 @@
 
 @synthesize isPageLoading = isPageLoading_;
 @synthesize isStarred = isStarred_;
+@synthesize canGoBack = canGoBack_;
+@synthesize canGoForward = canGoForward_;
 
 - (instancetype)initWithBrowser:(Browser*)browser
                      controller:(BrowserWindowTouchBarController*)controller {
@@ -266,8 +264,12 @@
     notificationBridge_.reset(new TouchBarNotificationBridge(self, browser));
 
     commandUpdater_ = browser->command_controller();
+
     commandUpdater_->AddCommandObserver(IDC_BACK, notificationBridge_.get());
+    self.canGoBack = commandUpdater_->IsCommandEnabled(IDC_BACK);
+
     commandUpdater_->AddCommandObserver(IDC_FORWARD, notificationBridge_.get());
+    self.canGoForward = commandUpdater_->IsCommandEnabled(IDC_FORWARD);
 
     PrefService* prefs = browser->profile()->GetPrefs();
     showHomeButton_.Init(
@@ -301,12 +303,12 @@
       setCustomizationIdentifier:ui::GetTouchBarId(kBrowserWindowTouchBarId)];
   [touchBar setDelegate:self];
 
-  NSMutableArray* customIdentifiers = [NSMutableArray arrayWithCapacity:7];
-  NSMutableArray* defaultIdentifiers = [NSMutableArray arrayWithCapacity:6];
+  NSMutableArray<NSString*>* customIdentifiers = [NSMutableArray array];
+  NSMutableArray<NSString*>* defaultIdentifiers = [NSMutableArray array];
 
-  NSArray* touchBarItems = @[
-    kBackForwardTouchId, kReloadOrStopTouchId, kHomeTouchId, kSearchTouchId,
-    kStarTouchId, kNewTabTouchId
+  NSArray<NSString*>* touchBarItems = @[
+    kBackTouchId, kForwardTouchId, kReloadOrStopTouchId, kHomeTouchId,
+    kSearchTouchId, kStarTouchId, kNewTabTouchId
   ];
 
   for (NSString* item in touchBarItems) {
@@ -332,14 +334,41 @@
   if (!touchBar)
     return nil;
 
+  if ([identifier hasSuffix:kBackForwardTouchId]) {
+    auto* items = @[
+      [touchBar itemForIdentifier:ui::GetTouchBarItemId(
+                                      kBrowserWindowTouchBarId, kBackTouchId)],
+      [touchBar
+          itemForIdentifier:ui::GetTouchBarItemId(kBrowserWindowTouchBarId,
+                                                  kForwardTouchId)],
+    ];
+    auto groupItem = [NSGroupTouchBarItem groupItemWithIdentifier:identifier
+                                                            items:items];
+    [groupItem setCustomizationLabel:
+                   l10n_util::GetNSString(
+                       IDS_TOUCH_BAR_BACK_FORWARD_CUSTOMIZATION_LABEL)];
+    return groupItem;
+  }
+
   base::scoped_nsobject<NSCustomTouchBarItem> touchBarItem(
       [[ui::NSCustomTouchBarItem() alloc] initWithIdentifier:identifier]);
-  if ([identifier hasSuffix:kBackForwardTouchId]) {
-    [self updateBackForwardControl];
-    [touchBarItem setView:backForwardControl_.get()];
-    [touchBarItem setCustomizationLabel:
-                      l10n_util::GetNSString(
-                          IDS_TOUCH_BAR_BACK_FORWARD_CUSTOMIZATION_LABEL)];
+  if ([identifier hasSuffix:kBackTouchId]) {
+    auto* button = CreateTouchBarButton(vector_icons::kBackArrowIcon, self,
+                                        IDC_BACK, IDS_ACCNAME_BACK);
+    [button bind:@"enabled" toObject:self withKeyPath:@"canGoBack" options:nil];
+    [touchBarItem setView:button];
+    [touchBarItem
+        setCustomizationLabel:l10n_util::GetNSString(IDS_ACCNAME_BACK)];
+  } else if ([identifier hasSuffix:kForwardTouchId]) {
+    auto* button = CreateTouchBarButton(vector_icons::kForwardArrowIcon, self,
+                                        IDC_FORWARD, IDS_ACCNAME_FORWARD);
+    [button bind:@"enabled"
+           toObject:self
+        withKeyPath:@"canGoForward"
+            options:nil];
+    [touchBarItem setView:button];
+    [touchBarItem
+        setCustomizationLabel:l10n_util::GetNSString(IDS_ACCNAME_FORWARD)];
   } else if ([identifier hasSuffix:kReloadOrStopTouchId]) {
     [self updateReloadStopButton];
     [touchBarItem setView:reloadStopButton_.get()];
@@ -398,6 +427,8 @@
 
     [touchBarItem
         setView:[NSTextField labelWithAttributedString:attributedString.get()]];
+  } else {
+    return nil;
   }
 
   return touchBarItem.autorelease();
@@ -412,63 +443,10 @@
   return touchBar.autorelease();
 }
 
-- (void)setupBackForwardControl {
-  NSMutableArray* images = [NSMutableArray arrayWithArray:@[
-    CreateNSImageFromIcon(vector_icons::kBackArrowIcon),
-    CreateNSImageFromIcon(vector_icons::kForwardArrowIcon)
-  ]];
-
-  // Offset the icons so that it matches the height of the other Touch Bar
-  // items.
-  const int kIconYOffset = 2;
-  for (NSUInteger i = 0; i < [images count]; i++) {
-    NSImage* image = [images objectAtIndex:i];
-    NSSize size = [image size];
-    size.height += kIconYOffset;
-
-    NSImage* offsettedImage = [[[NSImage alloc] initWithSize:size] autorelease];
-    [offsettedImage lockFocus];
-    [image drawInRect:NSMakeRect(0, 0, size.width, size.height - kIconYOffset)];
-    [offsettedImage unlockFocus];
-    [images replaceObjectAtIndex:i withObject:offsettedImage];
-  }
-
-  NSSegmentedControl* control = [NSSegmentedControl
-      segmentedControlWithImages:images
-                    trackingMode:NSSegmentSwitchTrackingMomentary
-                          target:self
-                          action:@selector(backOrForward:)];
-
-  // Use the accessibility protocol to get the children.
-  // Use NSAccessibilityUnignoredDescendant to be sure we start with
-  // the correct object.
-  id<NSAccessibility> segmentElement =
-      ToNSAccessibility(NSAccessibilityUnignoredDescendant(control));
-  DCHECK(segmentElement);
-  NSArray<id<NSAccessibility>>* segments = segmentElement.accessibilityChildren;
-  ToNSAccessibility(segments[0]).accessibilityTitle =
-      l10n_util::GetNSString(IDS_ACCNAME_BACK);
-  ToNSAccessibility(segments[1]).accessibilityTitle =
-      l10n_util::GetNSString(IDS_ACCNAME_FORWARD);
-
-  backForwardControl_.reset([control retain]);
-}
-
 - (void)updateWebContents:(content::WebContents*)contents {
   notificationBridge_->UpdateWebContents(contents);
 }
 
-- (void)updateBackForwardControl {
-  if (!backForwardControl_)
-    [self setupBackForwardControl];
-
-  [backForwardControl_ setSegmentStyle:NSSegmentStyleSeparated];
-  [backForwardControl_ setEnabled:commandUpdater_->IsCommandEnabled(IDC_BACK)
-                       forSegment:kBackSegmentIndex];
-  [backForwardControl_ setEnabled:commandUpdater_->IsCommandEnabled(IDC_FORWARD)
-                       forSegment:kForwardSegmentIndex];
-}
-
 - (void)updateStarredButton {
   const gfx::VectorIcon& icon =
       isStarred_ ? omnibox::kStarActiveIcon : omnibox::kStarIcon;
@@ -532,14 +510,6 @@
   return searchButton;
 }
 
-- (void)backOrForward:(id)sender {
-  NSSegmentedControl* control = sender;
-  int command =
-      [control selectedSegment] == kBackSegmentIndex ? IDC_BACK : IDC_FORWARD;
-  LogTouchBarUMA(TouchBarActionFromCommand(command));
-  commandUpdater_->ExecuteCommand(command);
-}
-
 - (void)executeCommand:(id)sender {
   int command = [sender tag];
   ui::LogTouchBarUMA(TouchBarActionFromCommand(command));
@@ -561,6 +531,23 @@
 // Private methods exposed for testing.
 @implementation BrowserWindowDefaultTouchBar (ExposedForTesting)
 
++ (NSString*)reloadOrStopItemIdentifier {
+  return ui::GetTouchBarItemId(kBrowserWindowTouchBarId, kReloadOrStopTouchId);
+}
+
++ (NSString*)backItemIdentifier {
+  return ui::GetTouchBarItemId(kBrowserWindowTouchBarId, kBackTouchId);
+}
+
++ (NSString*)forwardItemIdentifier {
+  return ui::GetTouchBarItemId(kBrowserWindowTouchBarId, kForwardTouchId);
+}
+
++ (NSString*)fullscreenOriginItemIdentifier {
+  return ui::GetTouchBarItemId(kTabFullscreenTouchBarId,
+                               kFullscreenOriginLabelTouchId);
+}
+
 - (void)updateReloadStopButton {
   const gfx::VectorIcon& icon =
       isPageLoading_ ? kNavigateStopIcon : vector_icons::kReloadIcon;
@@ -586,13 +573,6 @@
   return reloadStopButton_.get();
 }
 
-- (NSSegmentedControl*)backForwardControl {
-  if (!backForwardControl_)
-    [self updateBackForwardControl];
-
-  return backForwardControl_.get();
-}
-
 - (BookmarkTabHelperObserver*)bookmarkTabObserver {
   return notificationBridge_.get();
 }
diff --git a/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar_unittest.mm b/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar_unittest.mm
index ec36da0d..7f679ff 100644
--- a/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar_unittest.mm
+++ b/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar_unittest.mm
@@ -18,33 +18,14 @@
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "components/strings/grit/components_strings.h"
+#include "content/public/test/test_renderer_host.h"
+#include "content/public/test/web_contents_tester.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
 #import "third_party/ocmock/OCMock/OCMock.h"
 #import "ui/base/cocoa/touch_bar_util.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
-namespace {
-
-// Touch bar identifiers.
-NSString* const kBrowserWindowTouchBarId = @"browser-window";
-NSString* const kTabFullscreenTouchBarId = @"tab-fullscreen";
-
-// Touch bar items identifiers.
-NSString* const kBackForwardTouchId = @"BACK-FWD";
-NSString* const kReloadOrStopTouchId = @"RELOAD-STOP";
-NSString* const kHomeTouchId = @"HOME";
-NSString* const kSearchTouchId = @"SEARCH";
-NSString* const kStarTouchId = @"BOOKMARK";
-NSString* const kNewTabTouchId = @"NEW-TAB";
-NSString* const kFullscreenOriginLabelTouchId = @"FULLSCREEN-ORIGIN-LABEL";
-
-// The button indexes in the back and forward segment control.
-const int kBackSegmentIndex = 0;
-const int kForwardSegmentIndex = 1;
-
-}  // namespace
-
 class BrowserWindowDefaultTouchBarUnitTest : public CocoaProfileTest {
  public:
   void SetUp() override {
@@ -53,6 +34,10 @@
 
     command_updater_ = browser()->command_controller();
 
+    browser()->tab_strip_model()->AppendWebContents(
+        content::WebContentsTester::CreateTestWebContents(profile(), nullptr),
+        true);
+
     if (@available(macOS 10.12.2, *)) {
       touch_bar_.reset([[BrowserWindowDefaultTouchBar alloc]
           initWithBrowser:browser()
@@ -60,68 +45,107 @@
     }
   }
 
-  NSString* GetFullscreenTouchBarItemId(NSString* id) {
-    return ui::GetTouchBarItemId(kTabFullscreenTouchBarId, id);
-  }
-
-  NSString* GetBrowserTouchBarItemId(NSString* id) {
-    return ui::GetTouchBarItemId(kBrowserWindowTouchBarId, id);
-  }
-
   void UpdateCommandEnabled(int id, bool enabled) {
     command_updater_->UpdateCommandEnabled(id, enabled);
   }
 
   void TearDown() override {
-    if (@available(macOS 10.12.2, *))
+    if (@available(macOS 10.12.2, *)) {
+      [touch_bar_ updateWebContents:nullptr];
       touch_bar_.reset();
+    }
     CocoaProfileTest::TearDown();
   }
 
   CommandUpdater* command_updater_;  // Weak, owned by Browser.
+  content::RenderViewHostTestEnabler rvh_test_enabler_;
 
   API_AVAILABLE(macos(10.12.2))
   base::scoped_nsobject<BrowserWindowDefaultTouchBar> touch_bar_;
 };
 
-// Tests to check if the touch bar contains the correct items.
+// Test if any known identifiers no longer work. See the message in the test;
+// these identifiers may be written out to disk on users' computers if they
+// customize the Touch Bar, and the corresponding items will disappear if they
+// can no longer be created.
+TEST_F(BrowserWindowDefaultTouchBarUnitTest, HistoricTouchBarItems) {
+  if (@available(macOS 10.12.2, *)) {
+    NSTouchBar* touch_bar = [touch_bar_ makeTouchBar];
+    for (NSString* item_identifier : {
+             @"BACK-FWD",
+             @"BACK",
+             @"FORWARD",
+             @"RELOAD-STOP",
+             @"HOME",
+             @"SEARCH",
+             @"BOOKMARK",
+             @"NEW-TAB",
+         }) {
+      auto identifier =
+          ui::GetTouchBarItemId(@"browser-window", item_identifier);
+      EXPECT_NE(nil, [touch_bar itemForIdentifier:identifier])
+          << "BrowserWindowDefaultTouchBar didn't return a Touch Bar item for "
+             "an identifier that was once available ("
+          << identifier.UTF8String
+          << "). If a user's customized Touch Bar includes this item, it will "
+             "disappear! Do not update or remove entries in this list just to "
+             "make the test pass; keep supporting old identifiers when "
+             "possible, even if they're no longer part of the set of "
+             "default/customizable items.";
+    }
+  }
+}
+
+// Tests if BrowserWindowDefaultTouchBar can produce the items it says it can
+// and, for each kind of bar, also verify that the advertised/customizable lists
+// include some representative items (if not, the lists might be wrong.)
 TEST_F(BrowserWindowDefaultTouchBarUnitTest, TouchBarItems) {
   if (@available(macOS 10.12.2, *)) {
+    auto test_default_identifiers =
+        [&](NSSet* expected_identifiers) API_AVAILABLE(macos(10.12.2)) {
+          NSTouchBar* touch_bar = [touch_bar_ makeTouchBar];
+          NSMutableSet<NSString*>* advertised_identifiers = [NSMutableSet set];
+          [advertised_identifiers
+              addObjectsFromArray:touch_bar.defaultItemIdentifiers];
+          [advertised_identifiers
+              addObjectsFromArray:touch_bar
+                                      .customizationAllowedItemIdentifiers];
+          [advertised_identifiers
+              addObjectsFromArray:touch_bar
+                                      .customizationRequiredItemIdentifiers];
+          EXPECT_TRUE(
+              [expected_identifiers isSubsetOfSet:advertised_identifiers])
+              << "Didn't find the expected identifiers "
+              << expected_identifiers.description.UTF8String
+              << " in the set of advertised identifiers "
+              << advertised_identifiers.description.UTF8String << ".";
+          for (NSString* identifier in advertised_identifiers) {
+            EXPECT_NE(nil, [touch_bar itemForIdentifier:identifier])
+                << "Didn't get a touch bar item for " << identifier.UTF8String;
+          }
+        };
+
     // Set to tab fullscreen.
     FullscreenController* fullscreen_controller =
         browser()->exclusive_access_manager()->fullscreen_controller();
     fullscreen_controller->set_is_tab_fullscreen_for_testing(true);
     EXPECT_TRUE(fullscreen_controller->IsTabFullscreen());
 
-    // The touch bar should only contain an item that displays the origin of the
-    // tab content fullscreen.
-    NSTouchBar* touch_bar = [touch_bar_ makeTouchBar];
-    NSArray* touch_bar_items = [touch_bar itemIdentifiers];
-    EXPECT_TRUE(
-        [touch_bar_items containsObject:GetFullscreenTouchBarItemId(
-                                            kFullscreenOriginLabelTouchId)]);
-    EXPECT_EQ(1u, [touch_bar_items count]);
+    // The fullscreen Touch Bar should include *at least* these items.
+    test_default_identifiers([NSSet setWithArray:@[
+      BrowserWindowDefaultTouchBar.fullscreenOriginItemIdentifier,
+    ]]);
 
     // Exit fullscreen.
     fullscreen_controller->set_is_tab_fullscreen_for_testing(false);
     EXPECT_FALSE(fullscreen_controller->IsTabFullscreen());
 
-    PrefService* prefs = profile()->GetPrefs();
-    DCHECK(prefs);
-    prefs->SetBoolean(prefs::kShowHomeButton, true);
-    touch_bar_items = [[touch_bar_ makeTouchBar] itemIdentifiers];
-    EXPECT_TRUE([touch_bar_items
-        containsObject:GetBrowserTouchBarItemId(kBackForwardTouchId)]);
-    EXPECT_TRUE([touch_bar_items
-        containsObject:GetBrowserTouchBarItemId(kReloadOrStopTouchId)]);
-    EXPECT_TRUE([touch_bar_items
-        containsObject:GetBrowserTouchBarItemId(kHomeTouchId)]);
-    EXPECT_TRUE([touch_bar_items
-        containsObject:GetBrowserTouchBarItemId(kSearchTouchId)]);
-    EXPECT_TRUE([touch_bar_items
-        containsObject:GetBrowserTouchBarItemId(kStarTouchId)]);
-    EXPECT_TRUE([touch_bar_items
-        containsObject:GetBrowserTouchBarItemId(kNewTabTouchId)]);
+    // The default Touch Bar should include *at least* these items.
+    test_default_identifiers([NSSet setWithArray:@[
+      BrowserWindowDefaultTouchBar.backItemIdentifier,
+      BrowserWindowDefaultTouchBar.forwardItemIdentifier,
+      BrowserWindowDefaultTouchBar.reloadOrStopItemIdentifier,
+    ]]);
   }
 }
 
@@ -131,56 +155,69 @@
     NSTouchBar* touch_bar = [touch_bar_ makeTouchBar];
     [touch_bar_ setIsPageLoading:NO];
 
-    NSTouchBarItem* item = [touch_bar_
-                     touchBar:touch_bar
-        makeItemForIdentifier:GetBrowserTouchBarItemId(kReloadOrStopTouchId)];
+    NSTouchBarItem* item =
+        [touch_bar itemForIdentifier:BrowserWindowDefaultTouchBar
+                                         .reloadOrStopItemIdentifier];
     EXPECT_EQ(IDC_RELOAD, [[item view] tag]);
 
     [touch_bar_ setIsPageLoading:YES];
-    item = [touch_bar_ touchBar:touch_bar
-          makeItemForIdentifier:GetBrowserTouchBarItemId(kReloadOrStopTouchId)];
+    item = [touch_bar itemForIdentifier:BrowserWindowDefaultTouchBar
+                                            .reloadOrStopItemIdentifier];
     EXPECT_EQ(IDC_STOP, [[item view] tag]);
   }
 }
 
-// Tests to see if the back/forward items on the touch bar is in sync with the
-// back and forward commands.
-TEST_F(BrowserWindowDefaultTouchBarUnitTest, BackForwardCommandUpdate) {
+// Tests if the back button on the touch bar is in sync with the back command.
+TEST_F(BrowserWindowDefaultTouchBarUnitTest, BackCommandUpdate) {
   if (@available(macOS 10.12.2, *)) {
-    NSSegmentedControl* back_forward_control = [touch_bar_ backForwardControl];
+    NSTouchBar* touch_bar = [touch_bar_ makeTouchBar];
+    NSTouchBarItem* item = [touch_bar
+        itemForIdentifier:BrowserWindowDefaultTouchBar.backItemIdentifier];
+    NSButton* button = base::mac::ObjCCast<NSButton>(item.view);
 
     UpdateCommandEnabled(IDC_BACK, true);
-    UpdateCommandEnabled(IDC_FORWARD, true);
-    EXPECT_TRUE([back_forward_control isEnabledForSegment:kBackSegmentIndex]);
-    EXPECT_TRUE(
-        [back_forward_control isEnabledForSegment:kForwardSegmentIndex]);
-
+    EXPECT_TRUE(button.enabled);
     UpdateCommandEnabled(IDC_BACK, false);
-    EXPECT_FALSE([back_forward_control isEnabledForSegment:kBackSegmentIndex]);
-    EXPECT_TRUE(
-        [back_forward_control isEnabledForSegment:kForwardSegmentIndex]);
-
-    UpdateCommandEnabled(IDC_FORWARD, false);
-    EXPECT_FALSE([back_forward_control isEnabledForSegment:kBackSegmentIndex]);
-    EXPECT_FALSE(
-        [back_forward_control isEnabledForSegment:kForwardSegmentIndex]);
+    EXPECT_FALSE(button.enabled);
   }
 }
 
-TEST_F(BrowserWindowDefaultTouchBarUnitTest, BackForwardAccessibilityLabels) {
+// Tests if the forward button on the touch bar is in sync with the forward
+// command.
+TEST_F(BrowserWindowDefaultTouchBarUnitTest, ForwardCommandUpdate) {
   if (@available(macOS 10.12.2, *)) {
-    NSSegmentedControl* control = touch_bar_.get().backForwardControl;
-    id<NSAccessibility> cell = NSAccessibilityUnignoredDescendant(control);
-    ASSERT_TRUE([cell conformsToProtocol:@protocol(NSAccessibility)]);
+    NSTouchBar* touch_bar = [touch_bar_ makeTouchBar];
+    NSTouchBarItem* item = [touch_bar
+        itemForIdentifier:BrowserWindowDefaultTouchBar.forwardItemIdentifier];
+    NSButton* button = base::mac::ObjCCast<NSButton>(item.view);
 
-    id<NSAccessibility> back = cell.accessibilityChildren[0];
-    EXPECT_TRUE([back conformsToProtocol:@protocol(NSAccessibility)]);
-    EXPECT_NSEQ(back.accessibilityTitle,
+    UpdateCommandEnabled(IDC_FORWARD, true);
+    EXPECT_TRUE(button.enabled);
+    UpdateCommandEnabled(IDC_FORWARD, false);
+    EXPECT_FALSE(button.enabled);
+  }
+}
+
+TEST_F(BrowserWindowDefaultTouchBarUnitTest, BackAccessibilityLabel) {
+  if (@available(macOS 10.12.2, *)) {
+    NSTouchBar* touch_bar = [touch_bar_ makeTouchBar];
+    NSTouchBarItem* item = [touch_bar
+        itemForIdentifier:BrowserWindowDefaultTouchBar.backItemIdentifier];
+    id<NSAccessibility> view = item.view;
+    ASSERT_TRUE([view conformsToProtocol:@protocol(NSAccessibility)]);
+    EXPECT_NSEQ(view.accessibilityTitle,
                 l10n_util::GetNSString(IDS_ACCNAME_BACK));
+  }
+}
 
-    id<NSAccessibility> forward = cell.accessibilityChildren[1];
-    EXPECT_TRUE([forward conformsToProtocol:@protocol(NSAccessibility)]);
-    EXPECT_NSEQ(forward.accessibilityTitle,
+TEST_F(BrowserWindowDefaultTouchBarUnitTest, ForwardAccessibilityLabel) {
+  if (@available(macOS 10.12.2, *)) {
+    NSTouchBar* touch_bar = [touch_bar_ makeTouchBar];
+    NSTouchBarItem* item = [touch_bar
+        itemForIdentifier:BrowserWindowDefaultTouchBar.forwardItemIdentifier];
+    id<NSAccessibility> view = item.view;
+    ASSERT_TRUE([view conformsToProtocol:@protocol(NSAccessibility)]);
+    EXPECT_NSEQ(view.accessibilityTitle,
                 l10n_util::GetNSString(IDS_ACCNAME_FORWARD));
   }
 }
diff --git a/chrome/browser/ui/collected_cookies_browsertest.cc b/chrome/browser/ui/collected_cookies_browsertest.cc
index 71e509f..8fc4ee63 100644
--- a/chrome/browser/ui/collected_cookies_browsertest.cc
+++ b/chrome/browser/ui/collected_cookies_browsertest.cc
@@ -66,6 +66,6 @@
   ShowUi(std::string());
 
   // Navigate to another page.
-  ui_test_utils::NavigateToURL(
-      browser(), embedded_test_server()->GetURL("/cookie2.html"));
+  ui_test_utils::NavigateToURL(browser(),
+                               embedded_test_server()->GetURL("/cookie2.html"));
 }
diff --git a/chrome/browser/ui/collected_cookies_infobar_delegate.cc b/chrome/browser/ui/collected_cookies_infobar_delegate.cc
index 0feb0af..0318da1 100644
--- a/chrome/browser/ui/collected_cookies_infobar_delegate.cc
+++ b/chrome/browser/ui/collected_cookies_infobar_delegate.cc
@@ -21,11 +21,9 @@
 }
 
 CollectedCookiesInfoBarDelegate::CollectedCookiesInfoBarDelegate()
-    : ConfirmInfoBarDelegate() {
-}
+    : ConfirmInfoBarDelegate() {}
 
-CollectedCookiesInfoBarDelegate::~CollectedCookiesInfoBarDelegate() {
-}
+CollectedCookiesInfoBarDelegate::~CollectedCookiesInfoBarDelegate() {}
 
 infobars::InfoBarDelegate::InfoBarIdentifier
 CollectedCookiesInfoBarDelegate::GetIdentifier() const {
diff --git a/chrome/browser/ui/color_chooser.h b/chrome/browser/ui/color_chooser.h
index 732e8af..4b9fa4d 100644
--- a/chrome/browser/ui/color_chooser.h
+++ b/chrome/browser/ui/color_chooser.h
@@ -10,7 +10,7 @@
 namespace content {
 class ColorChooser;
 class WebContents;
-}
+}  // namespace content
 
 namespace chrome {
 // Shows a color chooser that reports to the given WebContents.
diff --git a/chrome/browser/ui/confirm_bubble_model.cc b/chrome/browser/ui/confirm_bubble_model.cc
index e2b860e..1c6e44e 100644
--- a/chrome/browser/ui/confirm_bubble_model.cc
+++ b/chrome/browser/ui/confirm_bubble_model.cc
@@ -8,11 +8,9 @@
 #include "components/strings/grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 
-ConfirmBubbleModel::ConfirmBubbleModel() {
-}
+ConfirmBubbleModel::ConfirmBubbleModel() {}
 
-ConfirmBubbleModel::~ConfirmBubbleModel() {
-}
+ConfirmBubbleModel::~ConfirmBubbleModel() {}
 
 int ConfirmBubbleModel::GetButtons() const {
   return BUTTON_OK | BUTTON_CANCEL;
@@ -22,11 +20,9 @@
   return l10n_util::GetStringUTF16((button == BUTTON_OK) ? IDS_OK : IDS_CANCEL);
 }
 
-void ConfirmBubbleModel::Accept() {
-}
+void ConfirmBubbleModel::Accept() {}
 
-void ConfirmBubbleModel::Cancel() {
-}
+void ConfirmBubbleModel::Cancel() {}
 
 base::string16 ConfirmBubbleModel::GetLinkText() const {
   return base::string16();
diff --git a/chrome/browser/ui/confirm_bubble_model.h b/chrome/browser/ui/confirm_bubble_model.h
index 03a80c52..76c5bc8 100644
--- a/chrome/browser/ui/confirm_bubble_model.h
+++ b/chrome/browser/ui/confirm_bubble_model.h
@@ -16,8 +16,8 @@
 class ConfirmBubbleModel {
  public:
   enum BubbleButton {
-    BUTTON_NONE   = 0,
-    BUTTON_OK     = 1 << 0,
+    BUTTON_NONE = 0,
+    BUTTON_OK = 1 << 0,
     BUTTON_CANCEL = 1 << 1,
   };
 
diff --git a/chrome/browser/ui/crypto_module_delegate_nss.cc b/chrome/browser/ui/crypto_module_delegate_nss.cc
index 591dc6ba..88f1aef 100644
--- a/chrome/browser/ui/crypto_module_delegate_nss.cc
+++ b/chrome/browser/ui/crypto_module_delegate_nss.cc
@@ -33,11 +33,10 @@
 
   if (base::PostTaskWithTraits(
           FROM_HERE, {BrowserThread::UI},
-          base::BindOnce(
-              &ChromeNSSCryptoModuleDelegate::ShowDialog,
-              // This method blocks on |event_| until the task completes,
-              // so there's no need to ref-count.
-              base::Unretained(this), slot_name, retry))) {
+          base::BindOnce(&ChromeNSSCryptoModuleDelegate::ShowDialog,
+                         // This method blocks on |event_| until the task
+                         // completes, so there's no need to ref-count.
+                         base::Unretained(this), slot_name, retry))) {
     event_.Wait();
   }
   *cancelled = cancelled_;
@@ -48,10 +47,7 @@
                                                bool retry) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ShowCryptoModulePasswordDialog(
-      slot_name,
-      retry,
-      reason_,
-      server_.host(),
+      slot_name, retry, reason_, server_.host(),
       NULL,  // TODO(mattm): Supply parent window.
       base::Bind(&ChromeNSSCryptoModuleDelegate::GotPassword,
                  // RequestPassword is blocked on |event_| until GotPassword is
diff --git a/chrome/browser/ui/cryptuiapi_shim.h b/chrome/browser/ui/cryptuiapi_shim.h
index a6470d90..876753b 100644
--- a/chrome/browser/ui/cryptuiapi_shim.h
+++ b/chrome/browser/ui/cryptuiapi_shim.h
@@ -10,8 +10,8 @@
 // which undefines the OpenSSL macros which conflict. Any Chromium headers
 // which want to include cryptuiapi should instead include this header.
 
-#include <windows.h>
 #include <cryptuiapi.h>
+#include <windows.h>
 
 #include "base/win/wincrypt_shim.h"
 
diff --git a/chrome/browser/ui/external_protocol_dialog_delegate.cc b/chrome/browser/ui/external_protocol_dialog_delegate.cc
index 5fbb500..8f201e7 100644
--- a/chrome/browser/ui/external_protocol_dialog_delegate.cc
+++ b/chrome/browser/ui/external_protocol_dialog_delegate.cc
@@ -33,8 +33,7 @@
       render_view_routing_id_(render_view_routing_id),
       program_name_(shell_integration::GetApplicationNameForProtocol(url)) {}
 
-ExternalProtocolDialogDelegate::~ExternalProtocolDialogDelegate() {
-}
+ExternalProtocolDialogDelegate::~ExternalProtocolDialogDelegate() {}
 
 base::string16 ExternalProtocolDialogDelegate::GetDialogButtonLabel(
     ui::DialogButton button) const {
diff --git a/chrome/browser/ui/hung_plugin_tab_helper.cc b/chrome/browser/ui/hung_plugin_tab_helper.cc
index 047bb6e..25ccf39 100644
--- a/chrome/browser/ui/hung_plugin_tab_helper.cc
+++ b/chrome/browser/ui/hung_plugin_tab_helper.cc
@@ -52,7 +52,6 @@
 
 }  // namespace
 
-
 // HungPluginTabHelper::PluginState -------------------------------------------
 
 // Per-plugin state (since there could be more than one plugin hung).  The
@@ -96,17 +95,14 @@
       infobar(NULL),
       next_reshow_delay(base::TimeDelta::FromSeconds(kInitialReshowDelaySec)) {}
 
-HungPluginTabHelper::PluginState::~PluginState() {
-}
-
+HungPluginTabHelper::PluginState::~PluginState() {}
 
 // HungPluginTabHelper --------------------------------------------------------
 
 HungPluginTabHelper::HungPluginTabHelper(content::WebContents* contents)
     : content::WebContentsObserver(contents), infobar_observer_(this) {}
 
-HungPluginTabHelper::~HungPluginTabHelper() {
-}
+HungPluginTabHelper::~HungPluginTabHelper() {}
 
 void HungPluginTabHelper::PluginCrashed(const base::FilePath& plugin_path,
                                         base::ProcessId plugin_pid) {
@@ -171,9 +167,8 @@
       // Schedule the timer to re-show the infobar if the plugin continues to be
       // hung.
       state->timer.Start(FROM_HERE, state->next_reshow_delay,
-          base::Bind(&HungPluginTabHelper::OnReshowTimer,
-                     base::Unretained(this),
-                     i->first));
+                         base::BindOnce(&HungPluginTabHelper::OnReshowTimer,
+                                        base::Unretained(this), i->first));
 
       // Next time we do this, delay it twice as long to avoid being annoying.
       state->next_reshow_delay *= 2;
diff --git a/chrome/browser/ui/navigation_correction_tab_observer.cc b/chrome/browser/ui/navigation_correction_tab_observer.cc
index 70ca14ac..40256d42 100644
--- a/chrome/browser/ui/navigation_correction_tab_observer.cc
+++ b/chrome/browser/ui/navigation_correction_tab_observer.cc
@@ -50,14 +50,12 @@
   }
 }
 
-NavigationCorrectionTabObserver::~NavigationCorrectionTabObserver() {
-}
+NavigationCorrectionTabObserver::~NavigationCorrectionTabObserver() {}
 
 // static
 void NavigationCorrectionTabObserver::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* prefs) {
-  prefs->RegisterBooleanPref(prefs::kAlternateErrorPagesEnabled,
-                             true,
+  prefs->RegisterBooleanPref(prefs::kAlternateErrorPagesEnabled, true,
                              user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
 }
 
diff --git a/chrome/browser/ui/network_profile_bubble.cc b/chrome/browser/ui/network_profile_bubble.cc
index 155a8c1..0174a14 100644
--- a/chrome/browser/ui/network_profile_bubble.cc
+++ b/chrome/browser/ui/network_profile_bubble.cc
@@ -4,9 +4,8 @@
 
 #include "chrome/browser/ui/network_profile_bubble.h"
 
-#include <windows.h>
 #include <stdint.h>
-
+#include <windows.h>
 #include <wtsapi32.h>
 
 #include "base/bind.h"
@@ -113,8 +112,8 @@
   // Checking for RDP is cheaper than checking for a network drive so do this
   // one first.
   if (!::WTSQuerySessionInformation(WTS_CURRENT_SERVER, WTS_CURRENT_SESSION,
-                                    WTSClientProtocolType,
-                                    &buffer, &buffer_length)) {
+                                    WTSClientProtocolType, &buffer,
+                                    &buffer_length)) {
     RecordUmaEvent(METRIC_CHECK_FAILED);
     return;
   }
@@ -167,8 +166,7 @@
 
 // static
 void NetworkProfileBubble::RecordUmaEvent(MetricNetworkedProfileCheck event) {
-  UMA_HISTOGRAM_ENUMERATION(kMetricNetworkedProfileCheck,
-                            event,
+  UMA_HISTOGRAM_ENUMERATION(kMetricNetworkedProfileCheck, event,
                             METRIC_NETWORKED_PROFILE_CHECK_SIZE);
 }
 
diff --git a/chrome/browser/ui/network_profile_bubble.h b/chrome/browser/ui/network_profile_bubble.h
index d88e813..fac6a906 100644
--- a/chrome/browser/ui/network_profile_bubble.h
+++ b/chrome/browser/ui/network_profile_bubble.h
@@ -23,27 +23,27 @@
 class NetworkProfileBubble {
  public:
   enum MetricNetworkedProfileCheck {
-   // Check was suppressed by command line flag.
-   METRIC_CHECK_SUPPRESSED,
-   // WTSQuerySessionInformation call failed.
-   METRIC_CHECK_FAILED,
-   // File access in profile dir failed.
-   METRIC_CHECK_IO_FAILED,
+    // Check was suppressed by command line flag.
+    METRIC_CHECK_SUPPRESSED,
+    // WTSQuerySessionInformation call failed.
+    METRIC_CHECK_FAILED,
+    // File access in profile dir failed.
+    METRIC_CHECK_IO_FAILED,
 
-   // Profile on a network share detected.
-   METRIC_PROFILE_ON_NETWORK,
-   // Profile not on a network share detected.
-   METRIC_PROFILE_NOT_ON_NETWORK,
+    // Profile on a network share detected.
+    METRIC_PROFILE_ON_NETWORK,
+    // Profile not on a network share detected.
+    METRIC_PROFILE_NOT_ON_NETWORK,
 
-   // Check was suppressed because of remote session.
-   METRIC_REMOTE_SESSION,
+    // Check was suppressed because of remote session.
+    METRIC_REMOTE_SESSION,
 
-   // User has clicked learn more on the notification bubble.
-   METRIC_LEARN_MORE_CLICKED,
-   // User has clicked OK on the notification bubble.
-   METRIC_ACKNOWLEDGED,
+    // User has clicked learn more on the notification bubble.
+    METRIC_LEARN_MORE_CLICKED,
+    // User has clicked OK on the notification bubble.
+    METRIC_ACKNOWLEDGED,
 
-   METRIC_NETWORKED_PROFILE_CHECK_SIZE  // Must be the last.
+    METRIC_NETWORKED_PROFILE_CHECK_SIZE  // Must be the last.
   };
 
   // Returns true if the check for network located profile should be done. This
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
index 86ca5f5..3597fef 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -35,6 +35,7 @@
 #include "components/password_manager/core/browser/password_bubble_experiment.h"
 #include "components/password_manager/core/browser/password_form_manager_for_ui.h"
 #include "components/password_manager/core/browser/password_manager_constants.h"
+#include "components/password_manager/core/browser/password_ui_utils.h"
 #include "components/password_manager/core/browser/statistics_table.h"
 #include "components/password_manager/core/common/credential_manager_types.h"
 #include "content/public/browser/navigation_handle.h"
@@ -390,35 +391,9 @@
 
 void ManagePasswordsUIController::SavePassword(const base::string16& username,
                                                const base::string16& password) {
-  const auto& pending_credentials =
-      passwords_data_.form_manager()->GetPendingCredentials();
-  bool username_edited = pending_credentials.username_value != username;
-  bool password_changed = pending_credentials.password_value != password;
-  if (username_edited) {
-    passwords_data_.form_manager()->UpdateUsername(username);
-    if (GetPasswordFormMetricsRecorder()) {
-      GetPasswordFormMetricsRecorder()->RecordDetailedUserAction(
-          password_manager::PasswordFormMetricsRecorder::DetailedUserAction::
-              kEditedUsernameInBubble);
-    }
-  }
-  if (password_changed) {
-    passwords_data_.form_manager()->UpdatePasswordValue(password);
-    if (GetPasswordFormMetricsRecorder()) {
-      GetPasswordFormMetricsRecorder()->RecordDetailedUserAction(
-          password_manager::PasswordFormMetricsRecorder::DetailedUserAction::
-              kSelectedDifferentPasswordInBubble);
-    }
-  }
+  UpdatePasswordFormUsernameAndPassword(username, password,
+                                        passwords_data_.form_manager());
 
-  // Values of this histogram are a bit mask. Only the lower two bits are used:
-  // 0001 to indicate that the user has edited the username in the password
-  //      save bubble.
-  // 0010 to indicate that the user has changed the password in the password
-  //      save bubble.
-  // The maximum possible value is defined by OR-ing these values.
-  UMA_HISTOGRAM_ENUMERATION("PasswordManager.EditsInSaveBubble",
-                            username_edited + 2 * password_changed, 4);
   UMA_HISTOGRAM_BOOLEAN("PasswordManager.PasswordSavedWithManualFallback",
                         BubbleIsManualFallbackForSaving());
   if (GetPasswordFormMetricsRecorder() && BubbleIsManualFallbackForSaving()) {
diff --git a/chrome/browser/ui/platform_keys_certificate_selector_chromeos.h b/chrome/browser/ui/platform_keys_certificate_selector_chromeos.h
index cfee8bc..052ddb7f 100644
--- a/chrome/browser/ui/platform_keys_certificate_selector_chromeos.h
+++ b/chrome/browser/ui/platform_keys_certificate_selector_chromeos.h
@@ -18,7 +18,7 @@
 namespace net {
 class X509Certificate;
 typedef std::vector<scoped_refptr<X509Certificate>> CertificateList;
-}
+}  // namespace net
 
 namespace chromeos {
 
diff --git a/chrome/browser/ui/sad_tab.cc b/chrome/browser/ui/sad_tab.cc
index 2c24e97..567d7d09 100644
--- a/chrome/browser/ui/sad_tab.cc
+++ b/chrome/browser/ui/sad_tab.cc
@@ -266,8 +266,8 @@
       UMA_SAD_TAB_COUNTER("Tabs.SadTab.KillCreated.OOM");
       {
         const std::string spec = web_contents->GetURL().GetOrigin().spec();
-        memory::OomMemoryDetails::Log(
-            "Tab OOM-Killed Memory details: " + spec + ", ");
+        memory::OomMemoryDetails::Log("Tab OOM-Killed Memory details: " + spec +
+                                      ", ");
       }
       FALLTHROUGH;
 #endif
diff --git a/chrome/browser/ui/sad_tab_helper.cc b/chrome/browser/ui/sad_tab_helper.cc
index 52b80f6e..82496b4 100644
--- a/chrome/browser/ui/sad_tab_helper.cc
+++ b/chrome/browser/ui/sad_tab_helper.cc
@@ -30,12 +30,10 @@
 
 }  // namespace
 
-SadTabHelper::~SadTabHelper() {
-}
+SadTabHelper::~SadTabHelper() {}
 
 SadTabHelper::SadTabHelper(content::WebContents* web_contents)
-    : content::WebContentsObserver(web_contents) {
-}
+    : content::WebContentsObserver(web_contents) {}
 
 void SadTabHelper::ReinstallInWebView() {
   if (sad_tab_)
diff --git a/chrome/browser/ui/sad_tab_types.h b/chrome/browser/ui/sad_tab_types.h
index f889a4c..44f20a0 100644
--- a/chrome/browser/ui/sad_tab_types.h
+++ b/chrome/browser/ui/sad_tab_types.h
@@ -8,12 +8,12 @@
 #include "build/build_config.h"
 
 enum SadTabKind {
-  SAD_TAB_KIND_CRASHED,        // Tab crashed.
+  SAD_TAB_KIND_CRASHED,  // Tab crashed.
 #if defined(OS_CHROMEOS)
   SAD_TAB_KIND_KILLED_BY_OOM,  // Tab killed by oom killer.
 #endif
-  SAD_TAB_KIND_OOM,            // Tab ran out of memory.
-  SAD_TAB_KIND_KILLED          // Tab killed.
+  SAD_TAB_KIND_OOM,    // Tab ran out of memory.
+  SAD_TAB_KIND_KILLED  // Tab killed.
 };
 
 #endif  // CHROME_BROWSER_UI_SAD_TAB_TYPES_H_
diff --git a/chrome/browser/ui/scoped_tabbed_browser_displayer.h b/chrome/browser/ui/scoped_tabbed_browser_displayer.h
index bf6bc98..14fa037 100644
--- a/chrome/browser/ui/scoped_tabbed_browser_displayer.h
+++ b/chrome/browser/ui/scoped_tabbed_browser_displayer.h
@@ -21,9 +21,7 @@
   explicit ScopedTabbedBrowserDisplayer(Profile* profile);
   ~ScopedTabbedBrowserDisplayer();
 
-  Browser* browser() {
-    return browser_;
-  }
+  Browser* browser() { return browser_; }
 
  private:
   Browser* browser_;
diff --git a/chrome/browser/ui/screen_capture_notification_ui_stub.cc b/chrome/browser/ui/screen_capture_notification_ui_stub.cc
index fcef998..92ea27f 100644
--- a/chrome/browser/ui/screen_capture_notification_ui_stub.cc
+++ b/chrome/browser/ui/screen_capture_notification_ui_stub.cc
@@ -2,9 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/screen_capture_notification_ui.h"
-
 #include "base/logging.h"
+#include "chrome/browser/ui/screen_capture_notification_ui.h"
 
 // Stub implementation of the ScreenCaptureNotificationUI interface.
 class ScreenCaptureNotificationUIStub : public ScreenCaptureNotificationUI {
diff --git a/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc b/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc
index fddb40d..e3f58f2 100644
--- a/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc
+++ b/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/settings_window_manager_chromeos.h"
-
 #include <stddef.h>
 
 #include "base/bind.h"
@@ -20,6 +18,7 @@
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/settings_window_manager_chromeos.h"
 #include "chrome/browser/ui/settings_window_manager_observer_chromeos.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/signin_view_controller.h b/chrome/browser/ui/signin_view_controller.h
index 3dcd2a3..056192b 100644
--- a/chrome/browser/ui/signin_view_controller.h
+++ b/chrome/browser/ui/signin_view_controller.h
@@ -26,7 +26,7 @@
 enum class AccessPoint;
 enum class PromoAction;
 enum class Reason;
-}
+}  // namespace signin_metrics
 
 // Class responsible for showing and hiding all sign-in related UIs
 // (modal sign-in, DICE full-tab sign-in page, sync confirmation dialog, sign-in
@@ -81,7 +81,6 @@
   // Sets the height of the modal signin dialog.
   void SetModalSigninHeight(int height);
 
-
   // Notifies this object that it's |delegate_| member has become invalid.
   void ResetModalSigninDelegate();
 
diff --git a/chrome/browser/ui/simple_message_box.h b/chrome/browser/ui/simple_message_box.h
index 7077891..eb86ca9 100644
--- a/chrome/browser/ui/simple_message_box.h
+++ b/chrome/browser/ui/simple_message_box.h
@@ -26,8 +26,8 @@
 };
 
 enum MessageBoxType {
-  MESSAGE_BOX_TYPE_WARNING,      // Shows an OK button.
-  MESSAGE_BOX_TYPE_QUESTION,     // Shows YES and NO buttons.
+  MESSAGE_BOX_TYPE_WARNING,   // Shows an OK button.
+  MESSAGE_BOX_TYPE_QUESTION,  // Shows YES and NO buttons.
 };
 
 // Shows a dialog box with the given |title| and |message|. If |parent| is
diff --git a/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc b/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc
index de392c0..3333339a 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc
@@ -418,8 +418,9 @@
   return RemoveCreateDirectoryPermissionForUserDataDirectory();
 }
 
+// Flaky: https://crbug.com/951787
 IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorCorruptProfileTest,
-                       DeletedProfileFallbackToUserManager) {
+                       DISABLED_DeletedProfileFallbackToUserManager) {
   CheckBrowserWindows({});
   ExpectUserManagerToShow();
 }
diff --git a/chrome/browser/ui/tab_dialogs.cc b/chrome/browser/ui/tab_dialogs.cc
index 64c6569..90c1ccf 100644
--- a/chrome/browser/ui/tab_dialogs.cc
+++ b/chrome/browser/ui/tab_dialogs.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/ui/tab_dialogs.h"
+
 #include "content/public/browser/web_contents.h"
 
 namespace {
diff --git a/chrome/browser/ui/tab_dialogs.h b/chrome/browser/ui/tab_dialogs.h
index 5a53144c..c54feea 100644
--- a/chrome/browser/ui/tab_dialogs.h
+++ b/chrome/browser/ui/tab_dialogs.h
@@ -18,7 +18,7 @@
 namespace content {
 class RenderWidgetHost;
 class WebContents;
-}
+}  // namespace content
 
 namespace ui {
 class ProfileSigninConfirmationDelegate;
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
index 4a5e070d..a2c8e8f 100644
--- a/chrome/browser/ui/tab_helpers.cc
+++ b/chrome/browser/ui/tab_helpers.cc
@@ -320,12 +320,12 @@
   }
 #endif
 
-// --- Feature tab helpers behind flags ---
+  // --- Feature tab helpers behind flags ---
 
 #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
-offline_pages::OfflinePageTabHelper::CreateForWebContents(web_contents);
-offline_pages::RecentTabHelper::CreateForWebContents(web_contents);
-offline_pages::AutoFetchPageLoadWatcher::CreateForWebContents(web_contents);
+  offline_pages::OfflinePageTabHelper::CreateForWebContents(web_contents);
+  offline_pages::RecentTabHelper::CreateForWebContents(web_contents);
+  offline_pages::AutoFetchPageLoadWatcher::CreateForWebContents(web_contents);
 #endif
 
 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
diff --git a/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.cc b/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.cc
index 5e7902ac2..bb56ae9 100644
--- a/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.cc
+++ b/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.cc
@@ -22,12 +22,9 @@
 MockTabModalConfirmDialogDelegate::MockTabModalConfirmDialogDelegate(
     content::WebContents* web_contents,
     Delegate* delegate)
-    : TabModalConfirmDialogDelegate(web_contents),
-      delegate_(delegate) {
-}
+    : TabModalConfirmDialogDelegate(web_contents), delegate_(delegate) {}
 
-MockTabModalConfirmDialogDelegate::~MockTabModalConfirmDialogDelegate() {
-}
+MockTabModalConfirmDialogDelegate::~MockTabModalConfirmDialogDelegate() {}
 
 base::string16 MockTabModalConfirmDialogDelegate::GetTitle() {
   return base::string16();
@@ -57,8 +54,7 @@
       dialog_(NULL),
       accepted_count_(0),
       canceled_count_(0),
-      closed_count_(0) {
-}
+      closed_count_(0) {}
 
 void TabModalConfirmDialogTest::SetUpOnMainThread() {
   delegate_ = new MockTabModalConfirmDialogDelegate(
diff --git a/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h b/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h
index 3c111623..dd259cdb 100644
--- a/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h
+++ b/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h
@@ -18,6 +18,7 @@
     virtual void OnAccepted() = 0;
     virtual void OnCanceled() = 0;
     virtual void OnClosed() = 0;
+
    protected:
     virtual ~Delegate() {}
   };
diff --git a/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc b/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc
index b7f8591d..e032634 100644
--- a/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc
+++ b/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc
@@ -16,8 +16,7 @@
 
 TabModalConfirmDialogDelegate::TabModalConfirmDialogDelegate(
     WebContents* web_contents)
-    : close_delegate_(NULL),
-      closing_(false) {
+    : close_delegate_(NULL), closing_(false) {
   NavigationController* controller = &web_contents->GetController();
   registrar_.Add(this, content::NOTIFICATION_LOAD_START,
                  content::Source<NavigationController>(controller));
@@ -100,18 +99,14 @@
   return NULL;
 }
 
-void TabModalConfirmDialogDelegate::OnAccepted() {
-}
+void TabModalConfirmDialogDelegate::OnAccepted() {}
 
-void TabModalConfirmDialogDelegate::OnCanceled() {
-}
+void TabModalConfirmDialogDelegate::OnCanceled() {}
 
 void TabModalConfirmDialogDelegate::OnLinkClicked(
-    WindowOpenDisposition disposition) {
-}
+    WindowOpenDisposition disposition) {}
 
-void TabModalConfirmDialogDelegate::OnClosed() {
-}
+void TabModalConfirmDialogDelegate::OnClosed() {}
 
 void TabModalConfirmDialogDelegate::CloseDialog() {
   if (close_delegate_)
diff --git a/chrome/browser/ui/uma_browsing_activity_observer.cc b/chrome/browser/ui/uma_browsing_activity_observer.cc
index 0e526234..a2b94fc 100644
--- a/chrome/browser/ui/uma_browsing_activity_observer.cc
+++ b/chrome/browser/ui/uma_browsing_activity_observer.cc
@@ -38,13 +38,12 @@
 
 UMABrowsingActivityObserver::UMABrowsingActivityObserver() {
   registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
-                  content::NotificationService::AllSources());
+                 content::NotificationService::AllSources());
   registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
-                  content::NotificationService::AllSources());
+                 content::NotificationService::AllSources());
 }
 
-UMABrowsingActivityObserver::~UMABrowsingActivityObserver() {
-}
+UMABrowsingActivityObserver::~UMABrowsingActivityObserver() {}
 
 void UMABrowsingActivityObserver::Observe(
     int type,
@@ -55,7 +54,7 @@
         *content::Details<content::LoadCommittedDetails>(details).ptr();
 
     content::NavigationController* controller =
-      content::Source<content::NavigationController>(source).ptr();
+        content::Source<content::NavigationController>(source).ptr();
     // Track whether the page loaded is a search results page (SRP). Track
     // the non-SRP navigations as well so there is a control.
     base::RecordAction(base::UserMetricsAction("NavEntryCommitted"));
@@ -65,8 +64,8 @@
     // See http://crbug.com/291348.
     CHECK(load.entry);
     if (TemplateURLServiceFactory::GetForProfile(
-            Profile::FromBrowserContext(controller->GetBrowserContext()))->
-            IsSearchResultsPageFromDefaultSearchProvider(
+            Profile::FromBrowserContext(controller->GetBrowserContext()))
+            ->IsSearchResultsPageFromDefaultSearchProvider(
                 load.entry->GetURL())) {
       base::RecordAction(base::UserMetricsAction("NavEntryCommitted.SRP"));
     }
@@ -85,11 +84,10 @@
 void UMABrowsingActivityObserver::LogRenderProcessHostCount() const {
   int hosts_count = 0;
   for (content::RenderProcessHost::iterator i(
-          content::RenderProcessHost::AllHostsIterator());
-        !i.IsAtEnd(); i.Advance())
+           content::RenderProcessHost::AllHostsIterator());
+       !i.IsAtEnd(); i.Advance())
     ++hosts_count;
-  UMA_HISTOGRAM_CUSTOM_COUNTS("MPArch.RPHCountPerLoad", hosts_count,
-                              1, 50, 50);
+  UMA_HISTOGRAM_CUSTOM_COUNTS("MPArch.RPHCountPerLoad", hosts_count, 1, 50, 50);
 }
 
 void UMABrowsingActivityObserver::LogBrowserTabCount() const {
@@ -100,15 +98,15 @@
   for (auto* browser : *BrowserList::GetInstance()) {
     // Record how many tabs each window has open.
     UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerWindow",
-                                browser->tab_strip_model()->count(),
-                                1, 200, 50);
+                                browser->tab_strip_model()->count(), 1, 200,
+                                50);
     tab_count += browser->tab_strip_model()->count();
 
     if (browser->window()->IsActive()) {
       // Record how many tabs the active window has open.
       UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountActiveWindow",
-                                  browser->tab_strip_model()->count(),
-                                  1, 200, 50);
+                                  browser->tab_strip_model()->count(), 1, 200,
+                                  50);
     }
 
     if (browser->is_app())
diff --git a/chrome/browser/ui/unload_controller.cc b/chrome/browser/ui/unload_controller.cc
index 4fcc174..4e5fcfa3 100644
--- a/chrome/browser/ui/unload_controller.cc
+++ b/chrome/browser/ui/unload_controller.cc
@@ -45,7 +45,7 @@
   if (is_attempting_to_close_browser_)
     ClearUnloadState(contents, true);
   return !is_attempting_to_close_browser_ ||
-      is_calling_before_unload_handlers();
+         is_calling_before_unload_handlers();
 }
 
 bool UnloadController::ShouldRunUnloadEventsHelper(
@@ -194,7 +194,8 @@
     for (int i = 0; i < browser_->tab_strip_model()->count(); ++i) {
       content::WebContents* contents =
           browser_->tab_strip_model()->GetWebContentsAt(i);
-      bool should_fire_beforeunload = contents->NeedToFireBeforeUnload() ||
+      bool should_fire_beforeunload =
+          contents->NeedToFireBeforeUnload() ||
           DevToolsWindow::NeedsToInterceptBeforeUnload(contents);
       if (!ContainsKey(tabs_needing_unload_fired_, contents) &&
           should_fire_beforeunload) {
@@ -286,17 +287,14 @@
 void UnloadController::TabAttachedImpl(content::WebContents* contents) {
   // If the tab crashes in the beforeunload or unload handler, it won't be
   // able to ack. But we know we can close it.
-  registrar_.Add(
-      this,
-      content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
-      content::Source<content::WebContents>(contents));
+  registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
+                 content::Source<content::WebContents>(contents));
 }
 
 void UnloadController::TabDetachedImpl(content::WebContents* contents) {
   if (is_attempting_to_close_browser_)
     ClearUnloadState(contents, false);
-  registrar_.Remove(this,
-                    content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
+  registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
                     content::Source<content::WebContents>(contents));
 }
 
@@ -374,8 +372,8 @@
 
 bool UnloadController::HasCompletedUnloadProcessing() const {
   return is_attempting_to_close_browser_ &&
-      tabs_needing_before_unload_fired_.empty() &&
-      tabs_needing_unload_fired_.empty();
+         tabs_needing_before_unload_fired_.empty() &&
+         tabs_needing_unload_fired_.empty();
 }
 
 bool UnloadController::RemoveFromSet(UnloadListenerSet* set,
diff --git a/chrome/browser/ui/unload_controller.h b/chrome/browser/ui/unload_controller.h
index b100a1f..f067acc 100644
--- a/chrome/browser/ui/unload_controller.h
+++ b/chrome/browser/ui/unload_controller.h
@@ -22,7 +22,7 @@
 class NotificationSource;
 class NotificationDetails;
 class WebContents;
-}
+}  // namespace content
 
 class UnloadController : public content::NotificationObserver,
                          public TabStripModelObserver {
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
index 7bb98e17..135ba56 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -51,6 +51,7 @@
 #include "services/identity/public/cpp/primary_account_mutator.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/image/canvas_image_source.h"
 #include "ui/gfx/image/image_skia_operations.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/views/controls/button/label_button.h"
@@ -99,6 +100,27 @@
   Navigate(&params);
 }
 
+#if defined(GOOGLE_CHROME_BUILD)
+// Returns the Google G icon in grey and with a padding of 2. The padding is
+// needed to make the icon look smaller, otherwise it looks too big compared to
+// the other icons. See crbug.com/951751 for more information.
+gfx::ImageSkia GetGoogleIconForUserMenu(int icon_size) {
+  constexpr int kIconPadding = 2;
+  SkColor icon_color =
+      ui::NativeTheme::GetInstanceForNativeUi()->GetSystemColor(
+          ui::NativeTheme::kColorId_DefaultIconColor);
+  // |CreateVectorIcon()| doesn't override colors specified in the .icon file,
+  // therefore the image has to be colored manually with |CreateColorMask()|.
+  gfx::ImageSkia google_icon = gfx::CreateVectorIcon(
+      kGoogleGLogoIcon, icon_size - 2 * kIconPadding, gfx::kPlaceholderColor);
+  gfx::ImageSkia grey_google_icon =
+      gfx::ImageSkiaOperations::CreateColorMask(google_icon, icon_color);
+
+  return gfx::CanvasImageSource::CreatePadded(grey_google_icon,
+                                              gfx::Insets(kIconPadding));
+}
+#endif
+
 }  // namespace
 
 // ProfileChooserView ---------------------------------------------------------
@@ -894,24 +916,13 @@
 
 #if defined(GOOGLE_CHROME_BUILD)
 void ProfileChooserView::AddManageGoogleAccountButton() {
-  ProfileMenuViewBase::MenuItems menu_items;
-
-  SkColor icon_color =
-      ui::NativeTheme::GetInstanceForNativeUi()->GetSystemColor(
-          ui::NativeTheme::kColorId_DefaultIconColor);
-  // |CreateVectorIcon()| doesn't override colors specified in the .icon file,
-  // therefore the image has to be colored manually with |CreateColorMask()|.
-  gfx::ImageSkia google_logo = gfx::CreateVectorIcon(
-      kGoogleGLogoIcon, GetDefaultIconSize(), gfx::kPlaceholderColor);
-  gfx::ImageSkia grey_google_logo =
-      gfx::ImageSkiaOperations::CreateColorMask(google_logo, icon_color);
-
   std::unique_ptr<HoverButton> button = std::make_unique<HoverButton>(
-      this, grey_google_logo,
+      this, GetGoogleIconForUserMenu(GetDefaultIconSize()),
       l10n_util::GetStringUTF16(IDS_SETTINGS_MANAGE_GOOGLE_ACCOUNT));
   manage_google_account_button_ = button.get();
-  menu_items.push_back(std::move(button));
 
+  ProfileMenuViewBase::MenuItems menu_items;
+  menu_items.push_back(std::move(button));
   AddMenuItems(menu_items, /*new_group=*/false);
 }
 #endif
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
index 9580e58..444b883 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -2668,7 +2668,7 @@
 
   const int pinned_tab_count = GetPinnedTabCount();
   const int normal_count = tab_count() - pinned_tab_count;
-  if (normal_count <= 1 || normal_count == pinned_tab_count)
+  if (normal_count <= 1)
     return false;
 
   const int tab_overlap = TabStyle::GetTabOverlap();
diff --git a/chrome/browser/ui/web_app_browser_controller.cc b/chrome/browser/ui/web_app_browser_controller.cc
index f58fad2..1d80cb3c 100644
--- a/chrome/browser/ui/web_app_browser_controller.cc
+++ b/chrome/browser/ui/web_app_browser_controller.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/ui/web_app_browser_controller.h"
-#include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
 
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/extensions/extension_util.h"
@@ -12,6 +11,7 @@
 #include "chrome/browser/ssl/security_state_tab_helper.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
 #include "chrome/browser/ui/location_bar/location_bar.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
diff --git a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc
index eb22e97..e3026c0 100644
--- a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc
@@ -22,8 +22,9 @@
 #include "base/strings/stringprintf.h"
 #include "base/task/post_task.h"
 #include "base/values.h"
-#include "chrome/browser/chromeos/arc/tracing/arc_cpu_model.h"
 #include "chrome/browser/chromeos/arc/tracing/arc_graphics_jank_detector.h"
+#include "chrome/browser/chromeos/arc/tracing/arc_system_model.h"
+#include "chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.h"
 #include "chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h"
 #include "chrome/browser/chromeos/arc/tracing/arc_tracing_model.h"
 #include "chrome/browser/chromeos/file_manager/path_util.h"
@@ -120,7 +121,7 @@
 // Helper that clarifies thread and process names. Tracing events may not have
 // enough data for this. Also it determines the process pid the thread belongs
 // to.
-void UpdateThreads(arc::ArcCpuModel::ThreadMap* threads) {
+void UpdateThreads(arc::ArcSystemModel::ThreadMap* threads) {
   ProcessFilterPassAll filter_pass_all;
   base::ProcessIterator process_iterator(&filter_pass_all);
 
@@ -151,9 +152,12 @@
 std::pair<base::Value, std::string> BuildGraphicsModel(
     const std::string& data,
     base::DictionaryValue tasks_info,
+    std::unique_ptr<arc::ArcSystemStatCollector> system_stat_collector,
     const base::TimeTicks& time_min,
     const base::TimeTicks& time_max,
     const base::FilePath& last_model_path) {
+  DCHECK(system_stat_collector);
+
   arc::ArcTracingModel common_model;
   const base::TimeTicks time_min_clamped =
       std::max(time_min, time_max - kMaxIntervalToDisplay);
@@ -164,11 +168,14 @@
   if (!common_model.Build(data))
     return std::make_pair(base::Value(), "Failed to process tracing data");
 
+  system_stat_collector->Flush(time_min, time_max,
+                               &common_model.system_model());
+
   arc::ArcTracingGraphicsModel graphics_model;
   if (!graphics_model.Build(common_model))
     return std::make_pair(base::Value(), "Failed to build tracing model");
 
-  UpdateThreads(&graphics_model.cpu_model().thread_map());
+  UpdateThreads(&graphics_model.system_model().thread_map());
 
   std::unique_ptr<base::DictionaryValue> model = graphics_model.Serialize();
   model->SetKey(kKeyTasks, std::move(tasks_info));
@@ -337,6 +344,8 @@
   tracing_active_ = true;
   if (jank_detector_)
     jank_detector_->Reset();
+  system_stat_colletor_ = std::make_unique<arc::ArcSystemStatCollector>();
+  system_stat_colletor_->Start(kMaxIntervalToDisplay);
   content::TracingController::GetInstance()->StartTracing(
       config, base::BindOnce(&ArcGraphicsTracingHandler::OnTracingStarted,
                              weak_ptr_factory_.GetWeakPtr()));
@@ -349,6 +358,9 @@
 
   tracing_time_max_ = TRACE_TIME_TICKS_NOW();
 
+  if (system_stat_colletor_)
+    system_stat_colletor_->Stop();
+
   content::TracingController* const controller =
       content::TracingController::GetInstance();
 
@@ -378,12 +390,11 @@
     base::RefCountedString* trace_data) {
   std::string string_data;
   string_data.swap(trace_data->data());
-
   base::PostTaskWithTraitsAndReplyWithResult(
       FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
       base::BindOnce(&BuildGraphicsModel, std::move(string_data),
-                     std::move(tasks_info_), tracing_time_min_,
-                     tracing_time_max_,
+                     std::move(tasks_info_), std::move(system_stat_colletor_),
+                     tracing_time_min_, tracing_time_max_,
                      GetLastTracingModelPath(Profile::FromWebUI(web_ui()))),
       base::BindOnce(&ArcGraphicsTracingHandler::OnGraphicsModelReady,
                      weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.h b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.h
index c923a5b..b2b7ab2 100644
--- a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.h
+++ b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.h
@@ -18,6 +18,7 @@
 
 namespace arc {
 class ArcGraphicsJankDetector;
+class ArcSystemStatCollector;
 }  // namespace arc
 
 namespace base {
@@ -107,6 +108,9 @@
   // Used to detect janks for the currently active ARC++ window.
   std::unique_ptr<arc::ArcGraphicsJankDetector> jank_detector_;
 
+  // Collects system stat runtime.
+  std::unique_ptr<arc::ArcSystemStatCollector> system_stat_colletor_;
+
   // Information about tasks, title and icon.
   base::DictionaryValue tasks_info_;
 
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc
index 2defed7..9ac4079 100644
--- a/chrome/browser/ui/webui/extensions/extensions_ui.cc
+++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -128,7 +128,7 @@
     {"searchResultsPlural", IDS_SEARCH_RESULTS_PLURAL},
     {"searchResultsSingular", IDS_SEARCH_RESULTS_SINGULAR},
 
-    // Multi-use strings defined in md_extensions_strings.grdp.
+    // Multi-use strings defined in extensions_strings.grdp.
     {"remove", IDS_EXTENSIONS_REMOVE},
 
     // Add extension-specific strings.
diff --git a/chrome/common/mac/staging_watcher.h b/chrome/common/mac/staging_watcher.h
index 592c1c0..586ceecd 100644
--- a/chrome/common/mac/staging_watcher.h
+++ b/chrome/common/mac/staging_watcher.h
@@ -41,14 +41,11 @@
 @interface CrStagingKeyWatcher (TestingInterface)
 
 // The designated initializer. Allows a non-default NSUserDefaults to be
-// specified.
+// specified. Also allows the use of KVO to be disabled to allow the macOS 10.11
+// and earlier code path to be tested on 10.12 and later.
 - (instancetype)initWithUserDefaults:(NSUserDefaults*)defaults
-                         pollingTime:(NSTimeInterval)pollingTime;
-
-// KVO works for NSUserDefaults on 10.12 and later. This method turns off the
-// use of KVO to allow the macOS 10.11 and earlier code path to be tested on
-// 10.12 and later.
-- (void)disableKVOForTesting;
+                         pollingTime:(NSTimeInterval)pollingTime
+                disableKVOForTesting:(BOOL)disableKVOForTesting;
 
 // Returns whether the last call to -waitForStagingKeyToClear blocked or
 // returned immediately.
diff --git a/chrome/common/mac/staging_watcher.mm b/chrome/common/mac/staging_watcher.mm
index 0d58e93..cf81325 100644
--- a/chrome/common/mac/staging_watcher.mm
+++ b/chrome/common/mac/staging_watcher.mm
@@ -18,6 +18,14 @@
 // with that rewrite in 10.12. In macOS 10.11 and earlier, polling is the only
 // option. Note that NSUserDefaultsDidChangeNotification never notifies about
 // changes made by other programs, not even in 10.12 and later.
+//
+// On the other hand, KVO notification was broken in the NSUserDefaults rewrite
+// for 10.14; see:
+// - https://twitter.com/Catfish_Man/status/1116185288257105925
+// - rdar://49812220
+// The bug is that a change from "no value" to "value present" doesn't notify.
+// To work around that, a default is registered to ensure that there never is
+// a "no value" situation.
 
 namespace {
 
@@ -33,7 +41,6 @@
   base::mac::ScopedBlock<StagingKeyChangedObserver> callback_;
   BOOL lastStagingKeyValue_;
 
-  BOOL kvoDisabledForTesting_;
   BOOL lastWaitWasBlockedForTesting_;
 }
 
@@ -43,16 +50,19 @@
 
 - (instancetype)initWithPollingTime:(NSTimeInterval)pollingTime {
   return [self initWithUserDefaults:[NSUserDefaults standardUserDefaults]
-                        pollingTime:pollingTime];
+                        pollingTime:pollingTime
+               disableKVOForTesting:NO];
 }
 
 - (instancetype)initWithUserDefaults:(NSUserDefaults*)defaults
-                         pollingTime:(NSTimeInterval)pollingTime {
+                         pollingTime:(NSTimeInterval)pollingTime
+                disableKVOForTesting:(BOOL)disableKVOForTesting {
   if ((self = [super init])) {
     pollingTime_ = pollingTime;
     defaults_.reset(defaults, base::scoped_policy::RETAIN);
+    [defaults_ registerDefaults:@{kStagingKey : @[]}];
     lastStagingKeyValue_ = [self isStagingKeySet];
-    if (base::mac::IsAtLeastOS10_12() && !kvoDisabledForTesting_) {
+    if (base::mac::IsAtLeastOS10_12() && !disableKVOForTesting) {
       // If a change is made in another process (which is the use case here),
       // the prior value is never provided in the observation callback change
       // dictionary, whether or not NSKeyValueObservingOptionPrior is specified.
@@ -137,10 +147,6 @@
   [super dealloc];
 }
 
-- (void)disableKVOForTesting {
-  kvoDisabledForTesting_ = YES;
-}
-
 - (BOOL)lastWaitWasBlockedForTesting {
   return lastWaitWasBlockedForTesting_;
 }
diff --git a/chrome/common/mac/staging_watcher_unittest.mm b/chrome/common/mac/staging_watcher_unittest.mm
index ba0a18a..469494a 100644
--- a/chrome/common/mac/staging_watcher_unittest.mm
+++ b/chrome/common/mac/staging_watcher_unittest.mm
@@ -36,10 +36,10 @@
 
   base::scoped_nsobject<CrStagingKeyWatcher> CreateKeyWatcher() {
     base::scoped_nsobject<CrStagingKeyWatcher> keyWatcher(
-        [[CrStagingKeyWatcher alloc] initWithUserDefaults:defaults_
-                                              pollingTime:0.5]);
-    if (GetParam() == KVOOrNot::kDontUseKVO)
-      [keyWatcher disableKVOForTesting];
+        [[CrStagingKeyWatcher alloc]
+            initWithUserDefaults:defaults_
+                     pollingTime:0.5
+            disableKVOForTesting:(GetParam() == KVOOrNot::kDontUseKVO)]);
 
     return keyWatcher;
   }
@@ -133,16 +133,20 @@
   base::scoped_nsobject<CrStagingKeyWatcher> watcher = CreateKeyWatcher();
   NSRunLoop* runloop = [NSRunLoop currentRunLoop];
 
+  __block bool observerCalled = false;
   [watcher setStagingKeyChangedObserver:^(BOOL stagingKeySet) {
+    observerCalled = true;
     CFRunLoopStop([runloop getCFRunLoop]);
   }];
 
   SetDefaultsValueInSeparateProcess();
-  while (![watcher isStagingKeySet] &&
-         [runloop runMode:NSDefaultRunLoopMode
-               beforeDate:[NSDate distantFuture]]) {
+  ASSERT_FALSE([watcher isStagingKeySet]);
+  while (!observerCalled && [runloop runMode:NSDefaultRunLoopMode
+                                  beforeDate:[NSDate distantFuture]]) {
     /* run! */
   }
+
+  EXPECT_TRUE([watcher isStagingKeySet]);
 }
 
 TEST_P(StagingKeyWatcherTest, CallbackOnKeyUnset) {
@@ -152,14 +156,18 @@
   base::scoped_nsobject<CrStagingKeyWatcher> watcher = CreateKeyWatcher();
   NSRunLoop* runloop = [NSRunLoop currentRunLoop];
 
+  __block bool observerCalled = false;
   [watcher setStagingKeyChangedObserver:^(BOOL stagingKeySet) {
+    observerCalled = true;
     CFRunLoopStop([runloop getCFRunLoop]);
   }];
 
   ClearDefaultsValueInSeparateProcess();
-  while ([watcher isStagingKeySet] &&
-         [runloop runMode:NSDefaultRunLoopMode
-               beforeDate:[NSDate distantFuture]]) {
+  ASSERT_TRUE([watcher isStagingKeySet]);
+  while (!observerCalled && [runloop runMode:NSDefaultRunLoopMode
+                                  beforeDate:[NSDate distantFuture]]) {
     /* run! */
   }
+
+  EXPECT_FALSE([watcher isStagingKeySet]);
 }
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index ebb9105..0250b01 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -871,6 +871,18 @@
 const char kTPMFirmwareUpdateCleanupDismissed[] =
     "tpm_firmware_update.cleanup_dismissed";
 
+// Int64 pref indicating the time in microseconds since Windows epoch
+// (1601-01-01 00:00:00 UTC) when the notification informing the user about a
+// planned TPM update that will clear all user data was shown. If the
+// notification was not yet shown the pref holds the value Time::Min().
+const char kTPMUpdatePlannedNotificationShownTime[] =
+    "tpm_auto_update.planned_notification_shown_time";
+
+// Boolean pref indicating whether the notification informing the user that an
+// auto-update that will clear all the user data at next reboot was shown.
+const char kTPMUpdateOnNextRebootNotificationShown[] =
+    "tpm_auto_update.update_on_reboot_notification_shown";
+
 // Boolean pref indicating whether the NetBios Name Query Request Protocol is
 // used for discovering shares on the user's network by the Network File
 // Shares for Chrome OS feature.
@@ -1988,6 +2000,11 @@
 // set for child users only, and kept on the known user storage.
 const char kKnownUserParentAccessCodeConfig[] =
     "child_user.parent_access_code.config";
+
+// Enable chrome://password-change page for in-session change of SAML passwords.
+// Also enables SAML password expiry notifications, if we have that information.
+const char kSamlInSessionPasswordChangeEnabled[] =
+    "saml.in_session_password_change_enabled";
 #endif  // defined(OS_CHROMEOS)
 
 // Whether there is a Flash version installed that supports clearing LSO data.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index cba8345..7232152ad 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -281,6 +281,8 @@
 extern const char kNetworkFileSharesAllowed[];
 extern const char kManagedSessionEnabled[];
 extern const char kTPMFirmwareUpdateCleanupDismissed[];
+extern const char kTPMUpdatePlannedNotificationShownTime[];
+extern const char kTPMUpdateOnNextRebootNotificationShown[];
 extern const char kNetBiosShareDiscoveryEnabled[];
 extern const char kChildScreenTimeMilliseconds[];
 extern const char kLastChildScreenTimeSaved[];
@@ -657,6 +659,7 @@
 extern const char
     kAutoScreenBrightnessMetricsUnsupportedAlsUserAdjustmentCount[];
 extern const char kKnownUserParentAccessCodeConfig[];
+extern const char kSamlInSessionPasswordChangeEnabled[];
 #endif  // defined(OS_CHROMEOS)
 
 extern const char kClearPluginLSODataEnabled[];
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index 1ccb50f..de64448b 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -540,8 +540,13 @@
 
   FullBrowserTransitionManager::Get()->OnProfileDestroyed(this);
 
-  browser_context_dependency_manager_->DestroyBrowserContextServices(this);
-  simple_dependency_manager_->DestroyKeyedServices(GetSimpleFactoryKey());
+  // The SimpleDependencyManager should always be passed after the
+  // BrowserContextDependencyManager. This is because the KeyedService instances
+  // in the BrowserContextDependencyManager's dependency graph can depend on the
+  // ones in the SimpleDependencyManager's graph.
+  DependencyManager::PerformInterlockedTwoPhaseShutdown(
+      browser_context_dependency_manager_, this, simple_dependency_manager_,
+      GetSimpleFactoryKey());
 
   if (host_content_settings_map_.get())
     host_content_settings_map_->ShutdownOnUIThread();
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations
index df3845f5..c1477264 100644
--- a/chrome/test/chromedriver/test/test_expectations
+++ b/chrome/test/chromedriver/test/test_expectations
@@ -23,6 +23,33 @@
 
     # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2661
     'WindowTest.testSetsTheSizeOfTheCurrentWindowFromIframe',
+
+    # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2854
+    'ChromeOptionsFunctionalTest.canSetAcceptInsecureCerts',
+
+    # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2835
+    'CookieImplementationTest.deleteAllCookies',
+    'CookieImplementationTest.canHandleHttpOnlyCookie',
+
+    # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2858
+    'ElementFindingTest.testFindingMultipleElementsByInvalidClassNameShouldThrow',
+    'ElementFindingTest.testFindingMultipleElementsByCompoundClassNameShouldThrow',
+    'ElementFindingTest.testFindingMultipleElementsByEmptyIdShouldReturnEmptyList',
+    'FormHandlingTest.testShouldNotBeAbleToSubmitAFormThatDoesNotExist',
+    'PositionAndSizeTest.testShouldGetCoordinatesInViewPortOfAnElementInAFrame',
+    'PositionAndSizeTest.testShouldGetCoordinatesInViewPortOfAnElementInANestedFrame',
+    'BasicKeyboardInterfaceTest.testSelectionSelectBySymbol',
+    'BasicKeyboardInterfaceTest.testSelectionSelectByWord',
+    'BasicMouseInterfaceTest.testMovingMouseToRelativeElementOffset',
+    'BasicMouseInterfaceTest.testMovingMouseToRelativeZeroElementOffset',
+    'BasicMouseInterfaceTest.testCanMoveOverAndOutOfAnElement',
+    'BasicMouseInterfaceTest.testMoveMouseByOffsetOverAndOutOfAnElement',
+    'CombinedInputActionsTest.testClickAfterMoveToAnElementWithAnOffsetShouldUseLastMousePosition',
+    'CombinedInputActionsTest.testChordControlCutAndPaste',
+    'DragAndDropTest.testDragAndDropElementWithOffsetInScrolledDiv',
+    'DragAndDropTest.canDragAnElementNotVisibleInTheCurrentViewportDueToAParentOverflow',
+    'LocationContextTest.testShouldSetAndGetLatitude',
+    'LocationContextTest.testShouldSetAndGetLongitude',
 ]
 
 _READY_TO_RUN_FILTER = [
@@ -31,6 +58,12 @@
 
 _OS_NEGATIVE_FILTER = {}
 _OS_NEGATIVE_FILTER['win'] = [
+    # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2855
+    'WindowTest.canFullscreenTheWindow',
+    'WindowTest.canFullscreenTheWindowFromIframe',
+    'WindowTest.testCanMaximizeTheWindowFromIframe',
+    'WindowTest.testCanMaximizeTheWindow',
+    'BasicMouseInterfaceTest.testMovingMouseByRelativeOffset',
 ]
 _OS_NEGATIVE_FILTER['linux'] = [
 ]
@@ -42,7 +75,14 @@
     'WindowTest.canFullscreenTheWindowFromFrame',
     'WindowTest.canFullscreenTheWindowFromIframe',
     'WindowTest.testSetsTheSizeOfTheCurrentWindow',
+    'WindowTest.testCanMaximizeTheWindowFromFrame',
+    'WindowTest.testCanMaximizeTheWindowFromIframe',
+    'WindowTest.testCanMaximizeTheWindow',
     'BasicMouseInterfaceTest.testMovingMouseByRelativeOffset',
+
+    # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2856
+    'ClickScrollingTest.testShouldBeAbleToClickElementThatIsOutOfViewInANestedFrameThatIsOutOfView',
+    'ClickScrollingTest.testShouldBeAbleToClickElementThatIsOutOfViewInANestedFrame',
 ]
 
 _OS_NEGATIVE_FILTER['android:chrome'] = [
diff --git a/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_buffers.json b/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_buffers.json
index c22f730..f6e448e 100644
--- a/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_buffers.json
+++ b/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_buffers.json
@@ -4,7 +4,7 @@
                 "global_events": [ ] },
    "chrome": { "buffers": [ [ [ 500, 1667.0 ], [ 501, 1808.0 ] ] ],
                 "global_events": [ ]  },
-   "cpu": { "threads": {}, "events": []},
+   "system": { "threads": {}, "cpu": [], "memory": []},
    "duration": 1053800.0,
    "views": [ {
       "activity": "com.android.vending/com.android.vending.AssetBrowserActivity",
diff --git a/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_desc.json b/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_desc.json
index f9006a0..4e9382f 100644
--- a/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_desc.json
+++ b/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_desc.json
@@ -5,7 +5,7 @@
    "chrome": { "buffers": [ [ [ 500, 1667.0 ], [ 501, 1808.0 ] ] ],
                 "global_events": [ ]  },
    "duration": 1053800.0,
-   "cpu": { "threads": {}, "events": []},
+   "system": { "threads": {}, "cpu": [], "memory": []},
    "views": [ {
       "buffers": [ [ [ 200, 0.0 ], [ 201, 149.0 ] ], [ [ 300, 168.0 ], [ 202, 173.0 ] ] ],
       "global_events": [ ],
diff --git a/chrome/test/data/arc_graphics_tracing/gm_bad_wrong_timestamp.json b/chrome/test/data/arc_graphics_tracing/gm_bad_wrong_timestamp.json
index 36ba418..195ed0aa 100644
--- a/chrome/test/data/arc_graphics_tracing/gm_bad_wrong_timestamp.json
+++ b/chrome/test/data/arc_graphics_tracing/gm_bad_wrong_timestamp.json
@@ -4,7 +4,7 @@
                 "global_events": [ ] },
    "chrome": { "buffers": [ [ [ 500, 1667.0 ], [ 501, 1808.0 ] ] ],
                 "global_events": [ ]  },
-   "cpu": { "threads": {}, "events": []},
+   "system": { "threads": {}, "cpu": [], "memory": []},
    "duration": 1053800.0,
    "views": [ {
       "activity": "com.android.vending/com.android.vending.AssetBrowserActivity",
diff --git a/chrome/test/data/arc_graphics_tracing/gm_good.json b/chrome/test/data/arc_graphics_tracing/gm_good.json
index 93def21f..adeed59 100644
--- a/chrome/test/data/arc_graphics_tracing/gm_good.json
+++ b/chrome/test/data/arc_graphics_tracing/gm_good.json
@@ -4,7 +4,7 @@
                 "global_events": [ ] },
    "chrome": { "buffers": [ [ [ 500, 1667.0 ], [ 501, 1808.0 ] ] ],
                 "global_events": [ ]  },
-   "cpu": { "threads": {}, "events": []},
+   "system": { "threads": {}, "cpu": [], "memory": []},
    "duration": 1053800.0,
    "views": [ {
       "activity": "com.android.vending/com.android.vending.AssetBrowserActivity",
diff --git a/chrome/test/data/arc_graphics_tracing/proc_meminfo b/chrome/test/data/arc_graphics_tracing/proc_meminfo
new file mode 100644
index 0000000..aed7637
--- /dev/null
+++ b/chrome/test/data/arc_graphics_tracing/proc_meminfo
@@ -0,0 +1,38 @@
+MemTotal:        8058940 kB
+MemFree:          314184 kB
+MemAvailable:    2714260 kB
+Buffers:          701012 kB
+Cached:          4108044 kB
+SwapCached:            0 kB
+Active:          3734844 kB
+Inactive:        3288772 kB
+Active(anon):    2307120 kB
+Inactive(anon):  1971184 kB
+Active(file):    1427724 kB
+Inactive(file):  1317588 kB
+Unevictable:      119252 kB
+Mlocked:           30720 kB
+SwapTotal:      11805084 kB
+SwapFree:       11758420 kB
+Dirty:             57024 kB
+Writeback:             0 kB
+AnonPages:       2333820 kB
+Mapped:          1717224 kB
+Shmem:           2063760 kB
+Slab:             296624 kB
+SReclaimable:     131788 kB
+SUnreclaim:       164836 kB
+KernelStack:       30432 kB
+PageTables:        73772 kB
+NFS_Unstable:          0 kB
+Bounce:                0 kB
+WritebackTmp:          0 kB
+CommitLimit:    15834552 kB
+Committed_AS:   47032264 kB
+VmallocTotal:   34359738367 kB
+VmallocUsed:           0 kB
+VmallocChunk:          0 kB
+AnonHugePages:     30720 kB
+DirectMap4k:      378408 kB
+DirectMap2M:     7905280 kB
+DirectMap1G:           0 kB
diff --git a/chrome/test/data/arc_graphics_tracing/zram_stat b/chrome/test/data/arc_graphics_tracing/zram_stat
new file mode 100644
index 0000000..9d4a0e0
--- /dev/null
+++ b/chrome/test/data/arc_graphics_tracing/zram_stat
Binary files differ
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 1a8204ad..0e20df0 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -3521,6 +3521,14 @@
     "pref_mappings": [{ "pref": "web_package.signed_exchange.enabled" }]
   },
 
+  "SamlInSessionPasswordChangeEnabled": {
+    "os": [],
+    "test_policy": { "SamlInSessionPasswordChangeEnabled": true },
+    "pref_mappings": [
+      { "pref": "saml.in_session_password_change_enabled"}
+    ]
+  },
+
   "----- Chrome OS device policies ---------------------------------------": {},
 
   "DevicePolicyRefreshRate": {
diff --git a/components/autofill/core/browser/address_contact_form_label_formatter.cc b/components/autofill/core/browser/address_contact_form_label_formatter.cc
index 13036f9..ffcb115a 100644
--- a/components/autofill/core/browser/address_contact_form_label_formatter.cc
+++ b/components/autofill/core/browser/address_contact_form_label_formatter.cc
@@ -11,8 +11,9 @@
 AddressContactFormLabelFormatter::AddressContactFormLabelFormatter(
     const std::string& app_locale,
     ServerFieldType focused_field_type,
+    uint32_t groups,
     const std::vector<ServerFieldType>& field_types)
-    : LabelFormatter(app_locale, focused_field_type, field_types),
+    : LabelFormatter(app_locale, focused_field_type, groups, field_types),
       form_has_street_address_(HasStreetAddress(field_types_for_labels())) {}
 
 AddressContactFormLabelFormatter::~AddressContactFormLabelFormatter() {}
diff --git a/components/autofill/core/browser/address_contact_form_label_formatter.h b/components/autofill/core/browser/address_contact_form_label_formatter.h
index d2fc7e3..a34e8a7d 100644
--- a/components/autofill/core/browser/address_contact_form_label_formatter.h
+++ b/components/autofill/core/browser/address_contact_form_label_formatter.h
@@ -22,6 +22,7 @@
   AddressContactFormLabelFormatter(
       const std::string& app_locale,
       ServerFieldType focused_field_type,
+      uint32_t groups,
       const std::vector<ServerFieldType>& field_types);
 
   ~AddressContactFormLabelFormatter() override;
diff --git a/components/autofill/core/browser/address_email_form_label_formatter.cc b/components/autofill/core/browser/address_email_form_label_formatter.cc
index dcc46e2..675bf30 100644
--- a/components/autofill/core/browser/address_email_form_label_formatter.cc
+++ b/components/autofill/core/browser/address_email_form_label_formatter.cc
@@ -11,8 +11,9 @@
 AddressEmailFormLabelFormatter::AddressEmailFormLabelFormatter(
     const std::string& app_locale,
     ServerFieldType focused_field_type,
+    uint32_t groups,
     const std::vector<ServerFieldType>& field_types)
-    : LabelFormatter(app_locale, focused_field_type, field_types),
+    : LabelFormatter(app_locale, focused_field_type, groups, field_types),
       form_has_street_address_(HasStreetAddress(field_types_for_labels())) {}
 
 AddressEmailFormLabelFormatter::~AddressEmailFormLabelFormatter() {}
diff --git a/components/autofill/core/browser/address_email_form_label_formatter.h b/components/autofill/core/browser/address_email_form_label_formatter.h
index 606bf0a..5c44dba5 100644
--- a/components/autofill/core/browser/address_email_form_label_formatter.h
+++ b/components/autofill/core/browser/address_email_form_label_formatter.h
@@ -22,6 +22,7 @@
   AddressEmailFormLabelFormatter(
       const std::string& app_locale,
       ServerFieldType focused_field_type,
+      uint32_t groups,
       const std::vector<ServerFieldType>& field_types);
 
   ~AddressEmailFormLabelFormatter() override;
diff --git a/components/autofill/core/browser/address_form_label_formatter.cc b/components/autofill/core/browser/address_form_label_formatter.cc
index a3b9786..ec88eda 100644
--- a/components/autofill/core/browser/address_form_label_formatter.cc
+++ b/components/autofill/core/browser/address_form_label_formatter.cc
@@ -11,8 +11,9 @@
 AddressFormLabelFormatter::AddressFormLabelFormatter(
     const std::string& app_locale,
     ServerFieldType focused_field_type,
+    uint32_t groups,
     const std::vector<ServerFieldType>& field_types)
-    : LabelFormatter(app_locale, focused_field_type, field_types),
+    : LabelFormatter(app_locale, focused_field_type, groups, field_types),
       form_has_street_address_(HasStreetAddress(field_types_for_labels())) {}
 
 AddressFormLabelFormatter::~AddressFormLabelFormatter() {}
diff --git a/components/autofill/core/browser/address_form_label_formatter.h b/components/autofill/core/browser/address_form_label_formatter.h
index e477dfe..e4a97dcd 100644
--- a/components/autofill/core/browser/address_form_label_formatter.h
+++ b/components/autofill/core/browser/address_form_label_formatter.h
@@ -21,6 +21,7 @@
  public:
   AddressFormLabelFormatter(const std::string& app_locale,
                             ServerFieldType focused_field_type,
+                            uint32_t groups,
                             const std::vector<ServerFieldType>& field_types);
 
   ~AddressFormLabelFormatter() override;
diff --git a/components/autofill/core/browser/address_phone_form_label_formatter.cc b/components/autofill/core/browser/address_phone_form_label_formatter.cc
index 670f1e8..97e374b 100644
--- a/components/autofill/core/browser/address_phone_form_label_formatter.cc
+++ b/components/autofill/core/browser/address_phone_form_label_formatter.cc
@@ -11,8 +11,9 @@
 AddressPhoneFormLabelFormatter::AddressPhoneFormLabelFormatter(
     const std::string& app_locale,
     ServerFieldType focused_field_type,
+    uint32_t groups,
     const std::vector<ServerFieldType>& field_types)
-    : LabelFormatter(app_locale, focused_field_type, field_types),
+    : LabelFormatter(app_locale, focused_field_type, groups, field_types),
       form_has_street_address_(HasStreetAddress(field_types_for_labels())) {}
 
 AddressPhoneFormLabelFormatter::~AddressPhoneFormLabelFormatter() {}
diff --git a/components/autofill/core/browser/address_phone_form_label_formatter.h b/components/autofill/core/browser/address_phone_form_label_formatter.h
index 32f162a8..231ca9e 100644
--- a/components/autofill/core/browser/address_phone_form_label_formatter.h
+++ b/components/autofill/core/browser/address_phone_form_label_formatter.h
@@ -22,6 +22,7 @@
   AddressPhoneFormLabelFormatter(
       const std::string& app_locale,
       ServerFieldType focused_field_type,
+      uint32_t groups,
       const std::vector<ServerFieldType>& field_types);
 
   ~AddressPhoneFormLabelFormatter() override;
diff --git a/components/autofill/core/browser/contact_form_label_formatter.cc b/components/autofill/core/browser/contact_form_label_formatter.cc
index 05a7a0e..a375da5 100644
--- a/components/autofill/core/browser/contact_form_label_formatter.cc
+++ b/components/autofill/core/browser/contact_form_label_formatter.cc
@@ -13,8 +13,7 @@
     ServerFieldType focused_field_type,
     uint32_t groups,
     const std::vector<ServerFieldType>& field_types)
-    : LabelFormatter(app_locale, focused_field_type, field_types),
-      groups_(groups) {}
+    : LabelFormatter(app_locale, focused_field_type, groups, field_types) {}
 
 ContactFormLabelFormatter::~ContactFormLabelFormatter() {}
 
@@ -42,14 +41,14 @@
 
 base::string16 ContactFormLabelFormatter::MaybeGetEmail(
     const AutofillProfile& profile) const {
-  return ContainsEmail(groups_) ? GetLabelEmail(profile, app_locale())
-                                : base::string16();
+  return ContainsEmail(groups()) ? GetLabelEmail(profile, app_locale())
+                                 : base::string16();
 }
 
 base::string16 ContactFormLabelFormatter::MaybeGetPhone(
     const AutofillProfile& profile) const {
-  return ContainsPhone(groups_) ? GetLabelPhone(profile, app_locale())
-                                : base::string16();
+  return ContainsPhone(groups()) ? GetLabelPhone(profile, app_locale())
+                                 : base::string16();
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/contact_form_label_formatter.h b/components/autofill/core/browser/contact_form_label_formatter.h
index ca23a7fe..be4eb1ca 100644
--- a/components/autofill/core/browser/contact_form_label_formatter.h
+++ b/components/autofill/core/browser/contact_form_label_formatter.h
@@ -38,9 +38,6 @@
   // Returns |profile|'s phone number if |profile| has a phone number and if
   // this formatter's associated form has a phone field.
   base::string16 MaybeGetPhone(const AutofillProfile& profile) const;
-
-  // A bitmask indicating which fields the form contains.
-  uint32_t groups_;
 };
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/label_formatter.cc b/components/autofill/core/browser/label_formatter.cc
index 689e250..303fcdc9 100644
--- a/components/autofill/core/browser/label_formatter.cc
+++ b/components/autofill/core/browser/label_formatter.cc
@@ -24,25 +24,30 @@
 
 LabelFormatter::LabelFormatter(const std::string& app_locale,
                                ServerFieldType focused_field_type,
+                               uint32_t groups,
                                const std::vector<ServerFieldType>& field_types)
-    : app_locale_(app_locale), focused_field_type_(focused_field_type) {
+    : app_locale_(app_locale),
+      focused_field_type_(focused_field_type),
+      groups_(groups) {
   const FieldTypeGroup focused_group = GetFocusedNonBillingGroup();
-  std::set<FieldTypeGroup> groups{NAME, ADDRESS_HOME, EMAIL, PHONE_HOME};
+  std::set<FieldTypeGroup> groups_for_labels{NAME, ADDRESS_HOME, EMAIL,
+                                             PHONE_HOME};
 
   // If a user is focused on an address field, then parts of the address may be
   // shown in the label. For example, if the user is focusing on a street
   // address field, then it may be helpful to show the city in the label.
   // Otherwise, the focused field should not appear in the label.
   if (focused_group != ADDRESS_HOME) {
-    groups.erase(focused_group);
+    groups_for_labels.erase(focused_group);
   }
 
   // Countries are excluded to prevent them from appearing in labels with
   // national addresses.
-  auto can_be_shown_in_label = [&groups](ServerFieldType type) -> bool {
-    return groups.find(
+  auto can_be_shown_in_label =
+      [&groups_for_labels](ServerFieldType type) -> bool {
+    return groups_for_labels.find(
                AutofillType(AutofillType(type).GetStorableType()).group()) !=
-               groups.end() &&
+               groups_for_labels.end() &&
            type != ADDRESS_HOME_COUNTRY && type != ADDRESS_BILLING_COUNTRY;
   };
 
@@ -79,13 +84,13 @@
       return nullptr;
     case kName | kAddress | kPhone:
       return std::make_unique<AddressPhoneFormLabelFormatter>(
-          app_locale, focused_field_type, field_types);
+          app_locale, focused_field_type, groups, field_types);
     case kName | kAddress | kEmail:
       return std::make_unique<AddressEmailFormLabelFormatter>(
-          app_locale, focused_field_type, field_types);
+          app_locale, focused_field_type, groups, field_types);
     case kName | kAddress:
       return std::make_unique<AddressFormLabelFormatter>(
-          app_locale, focused_field_type, field_types);
+          app_locale, focused_field_type, groups, field_types);
     case kName | kEmail | kPhone:
     case kName | kEmail:
     case kName | kPhone:
diff --git a/components/autofill/core/browser/label_formatter.h b/components/autofill/core/browser/label_formatter.h
index 5879599..d2dd4bf 100644
--- a/components/autofill/core/browser/label_formatter.h
+++ b/components/autofill/core/browser/label_formatter.h
@@ -20,9 +20,14 @@
  public:
   LabelFormatter(const std::string& app_locale,
                  ServerFieldType focused_field_type,
+                 uint32_t groups,
                  const std::vector<ServerFieldType>& field_types);
   virtual ~LabelFormatter();
 
+  // Returns the bitmask indicating which FieldTypeGroups are represented in
+  // this formatter's associated form.
+  uint32_t groups() const { return groups_; }
+
   // Returns a collection of labels formed by extracting useful disambiguating
   // information from a collection of |profiles|.
   std::vector<base::string16> GetLabels(
@@ -69,6 +74,10 @@
   // The type of field on which the user is focused, e.g. NAME_FIRST.
   ServerFieldType focused_field_type_;
 
+  // The bitmask indicating which FieldTypeGroups are represented in this
+  // formatter's associated form.
+  uint32_t groups_;
+
   // A collection of field types that can be used to make labels. It includes
   // only types related to names, addresses, email addresses, and phone
   // numbers. It excludes types related to countries.
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 1d34ad6..8362c98 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -1168,12 +1168,15 @@
                                                  matched_profiles, suggestions,
                                                  &unique_matched_profiles);
 
-  std::unique_ptr<LabelFormatter> formatter =
-      base::FeatureList::IsEnabled(
-          autofill::features::kAutofillUseImprovedLabelDisambiguation)
-          ? LabelFormatter::Create(app_locale_, type.GetStorableType(),
-                                   field_types)
-          : nullptr;
+  std::unique_ptr<LabelFormatter> formatter;
+
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+  formatter = base::FeatureList::IsEnabled(
+                  autofill::features::kAutofillUseImprovedLabelDisambiguation)
+                  ? LabelFormatter::Create(app_locale_, type.GetStorableType(),
+                                           field_types)
+                  : nullptr;
+#endif
 
   // Generate disambiguating labels based on the list of matches.
   std::vector<base::string16> labels;
@@ -1184,7 +1187,10 @@
                                           type.GetStorableType(), 1,
                                           app_locale_, &labels);
   }
-  suggestion_selection::PrepareSuggestions(labels, &unique_suggestions);
+
+  suggestion_selection::PrepareSuggestions(
+      formatter && ContainsAddress(formatter->groups()), labels,
+      &unique_suggestions);
   return unique_suggestions;
 }
 
@@ -2491,12 +2497,16 @@
 }
 
 void PersonalDataManager::RemoveProfileFromDB(const std::string& guid) {
-  bool profile_exists = FindByGUID<AutofillProfile>(web_profiles_, guid);
+  auto profile_it = FindElementByGUID<AutofillProfile>(web_profiles_, guid);
+  bool profile_exists = profile_it != web_profiles_.end();
   if (!profile_exists && !ProfileChangesAreOngoing(guid)) {
     NotifyPersonalDataObserver();
     return;
   }
-  AutofillProfileDeepChange change(AutofillProfileChange::REMOVE, guid);
+  const AutofillProfile* profile =
+      profile_exists ? profile_it->get()
+                     : ongoing_profile_changes_[guid].back().profile();
+  AutofillProfileDeepChange change(AutofillProfileChange::REMOVE, *profile);
   if (!ProfileChangesAreOngoing(guid)) {
     database_helper_->GetLocalDatabase()->RemoveAutofillProfile(guid);
     change.set_is_ongoing_on_background();
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index 10deadda..e3c2ba2 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -2544,6 +2544,7 @@
   EXPECT_EQ(0U, personal_data_->GetProfiles().size());
 }
 
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
 TEST_F(PersonalDataManagerTest,
        GetProfileSuggestionsWithImprovedLabelDisambiguationForContactForm) {
   AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
@@ -2568,9 +2569,12 @@
               FormatExpectedLabel("(978) 674-4120", "hoa.pham@comcast.net")),
           testing::Field(
               &Suggestion::additional_label,
-              FormatExpectedLabel("(978) 674-4120", "hoa.pham@comcast.net")))));
+              FormatExpectedLabel("(978) 674-4120", "hoa.pham@comcast.net")),
+          testing::Field(&Suggestion::icon, "userAccountAvatarIcon"))));
 }
+#endif  // #if !defined(OS_ANDROID) && !defined(OS_IOS)
 
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
 TEST_F(PersonalDataManagerTest,
        GetProfileSuggestionsWithImprovedLabelDisambiguationForAddressForm) {
   AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
@@ -2593,11 +2597,14 @@
                   testing::Field(
                       &Suggestion::label,
                       base::ASCIIToUTF16("401 Merrimack St, Lowell, MA 01852")),
-                  testing::Field(&Suggestion::additional_label,
-                                 base::ASCIIToUTF16(
-                                     "401 Merrimack St, Lowell, MA 01852")))));
+                  testing::Field(
+                      &Suggestion::additional_label,
+                      base::ASCIIToUTF16("401 Merrimack St, Lowell, MA 01852")),
+                  testing::Field(&Suggestion::icon, "locationOnIcon"))));
 }
+#endif  // #if !defined(OS_ANDROID) && !defined(OS_IOS)
 
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
 TEST_F(
     PersonalDataManagerTest,
     GetProfileSuggestionsWithImprovedLabelDisambiguationForAddressPhoneForm) {
@@ -2617,15 +2624,17 @@
           AutofillType(NAME_FULL), base::string16(), false,
           std::vector<ServerFieldType>{NAME_FULL, ADDRESS_HOME_STREET_ADDRESS,
                                        PHONE_HOME_WHOLE_NUMBER}),
-      ElementsAre(AllOf(
-          testing::Field(
-              &Suggestion::label,
-              FormatExpectedLabel("(978) 674-4120", "401 Merrimack St")),
-          testing::Field(
-              &Suggestion::additional_label,
-              FormatExpectedLabel("(978) 674-4120", "401 Merrimack St")))));
+      ElementsAre(AllOf(testing::Field(&Suggestion::label,
+                                       FormatExpectedLabel("(978) 674-4120",
+                                                           "401 Merrimack St")),
+                        testing::Field(&Suggestion::additional_label,
+                                       FormatExpectedLabel("(978) 674-4120",
+                                                           "401 Merrimack St")),
+                        testing::Field(&Suggestion::icon, "locationOnIcon"))));
 }
+#endif  // #if !defined(OS_ANDROID) && !defined(OS_IOS)
 
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
 TEST_F(
     PersonalDataManagerTest,
     GetProfileSuggestionsWithImprovedLabelDisambiguationForAddressEmailForm) {
@@ -2640,19 +2649,20 @@
       /*enabled_features=*/{features::kAutofillUseImprovedLabelDisambiguation},
       /*disabled_features=*/{});
 
-  EXPECT_THAT(
-      personal_data_->GetProfileSuggestions(
-          AutofillType(NAME_FULL), base::string16(), false,
-          std::vector<ServerFieldType>{NAME_FULL, ADDRESS_HOME_STREET_ADDRESS,
-                                       EMAIL_ADDRESS}),
-      ElementsAre(AllOf(
-          testing::Field(
-              &Suggestion::label,
-              FormatExpectedLabel("401 Merrimack St", "hoa.pham@comcast.net")),
-          testing::Field(&Suggestion::additional_label,
-                         FormatExpectedLabel("401 Merrimack St",
-                                             "hoa.pham@comcast.net")))));
+  EXPECT_THAT(personal_data_->GetProfileSuggestions(
+                  AutofillType(NAME_FULL), base::string16(), false,
+                  std::vector<ServerFieldType>{
+                      NAME_FULL, ADDRESS_HOME_STREET_ADDRESS, EMAIL_ADDRESS}),
+              ElementsAre(AllOf(
+                  testing::Field(&Suggestion::label,
+                                 FormatExpectedLabel("401 Merrimack St",
+                                                     "hoa.pham@comcast.net")),
+                  testing::Field(&Suggestion::additional_label,
+                                 FormatExpectedLabel("401 Merrimack St",
+                                                     "hoa.pham@comcast.net")),
+                  testing::Field(&Suggestion::icon, "locationOnIcon"))));
 }
+#endif  // #if !defined(OS_ANDROID) && !defined(OS_IOS)
 
 TEST_F(PersonalDataManagerTest, IsKnownCard_MatchesMaskedServerCard) {
   // Add a masked server card.
diff --git a/components/autofill/core/browser/suggestion_selection.cc b/components/autofill/core/browser/suggestion_selection.cc
index 10d93bd..b8c2711 100644
--- a/components/autofill/core/browser/suggestion_selection.cc
+++ b/components/autofill/core/browser/suggestion_selection.cc
@@ -9,6 +9,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
+#include "build/build_config.h"
 #include "components/autofill/core/browser/address_i18n.h"
 #include "components/autofill/core/browser/autofill_data_util.h"
 #include "components/autofill/core/browser/autofill_metrics.h"
@@ -99,6 +100,7 @@
             /* is_masked_server_card= */ false, &prefix_matched_suggestion)) {
       matched_profiles->push_back(profile);
 
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
       // If the field with which the user is interacting is a phone number or
       // part of a phone number, then display it in the national format
       // corresponding to the profile's country. For example, (508) 488-0800
@@ -112,6 +114,7 @@
             base::UTF16ToUTF8(value), data_util::GetCountryCodeWithFallback(
                                           *profile, comparator.app_locale())));
       }
+#endif
 
       suggestions.push_back(Suggestion(value));
       suggestions.back().backend_id = profile->guid();
@@ -233,13 +236,22 @@
       num_profiles_supressed);
 }
 
-void PrepareSuggestions(const std::vector<base::string16>& labels,
+void PrepareSuggestions(bool contains_address,
+                        const std::vector<base::string16>& labels,
                         std::vector<Suggestion>* suggestions) {
   DCHECK_EQ(suggestions->size(), labels.size());
 
   for (size_t i = 0; i < labels.size(); ++i) {
     (*suggestions)[i].additional_label = base::string16(labels[i]);
     (*suggestions)[i].label = base::string16(labels[i]);
+
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+    if (base::FeatureList::IsEnabled(
+            autofill::features::kAutofillUseImprovedLabelDisambiguation)) {
+      (*suggestions)[i].icon =
+          contains_address ? "locationOnIcon" : "userAccountAvatarIcon";
+    }
+#endif
   }
 }
 
diff --git a/components/autofill/core/browser/suggestion_selection.h b/components/autofill/core/browser/suggestion_selection.h
index 067538b..817c0d20 100644
--- a/components/autofill/core/browser/suggestion_selection.h
+++ b/components/autofill/core/browser/suggestion_selection.h
@@ -62,7 +62,10 @@
 // Prepares a collection of Suggestions to show to the user. Adds |labels| to
 // their corresponding |suggestions|. A label corresponds to the suggestion with
 // the same index.
-void PrepareSuggestions(const std::vector<base::string16>& labels,
+// |contains_address| determines which icon to add to suggestions in the
+//  autofill-use-improved-label-disambiguation experiment.
+void PrepareSuggestions(bool contains_address,
+                        const std::vector<base::string16>& labels,
                         std::vector<Suggestion>* suggestions);
 
 }  // namespace suggestion_selection
diff --git a/components/autofill/core/browser/webdata/autofill_change.h b/components/autofill/core/browser/webdata/autofill_change.h
index 308ea62d..f23695ad 100644
--- a/components/autofill/core/browser/webdata/autofill_change.h
+++ b/components/autofill/core/browser/webdata/autofill_change.h
@@ -55,16 +55,12 @@
   // The |type| input specifies the change type.  The |key| input is the key
   // that identifies the |data_model|; it is the GUID of the entry for local
   // data and server_id of the entry for server data from GPay.
-  // When |type| == ADD, |data_model| should be non-NULL.
-  // When |type| == UPDATE, |data_model| should be non-NULL.
-  // When |type| == REMOVE, |data_model| should be NULL.
   AutofillDataModelChange(Type type,
                           const std::string& key,
                           const DataType* data_model)
       : GenericAutofillChange<std::string>(type, key), data_model_(data_model) {
-    DCHECK(type == REMOVE ? !data_model
-                          : data_model && (data_model->guid() == key ||
-                                           data_model->server_id() == key));
+    DCHECK(data_model &&
+           (data_model->guid() == key || data_model->server_id() == key));
   }
 
   ~AutofillDataModelChange() override {}
@@ -90,11 +86,6 @@
       : AutofillProfileChange(type, profile.guid(), &profile),
         profile_(profile) {}
 
-  AutofillProfileDeepChange(Type type, const std::string& guid)
-      : AutofillProfileChange(type, guid, nullptr), profile_(guid, "") {
-    DCHECK(type == GenericAutofillChange::REMOVE);
-  }
-
   ~AutofillProfileDeepChange() override {}
 
   const AutofillProfile* profile() const { return &profile_; }
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
index 961972e..fee7640 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
@@ -208,12 +208,8 @@
 
 void AutofillProfileSyncBridge::ActOnLocalChange(
     const AutofillProfileChange& change) {
-  DCHECK((change.type() == AutofillProfileChange::REMOVE) ==
-         (change.data_model() == nullptr));
-  if (!change_processor()->IsTrackingMetadata()) {
-    return;
-  }
-  if (change.data_model() &&
+  DCHECK(change.data_model());
+  if (!change_processor()->IsTrackingMetadata() ||
       change.data_model()->record_type() != AutofillProfile::LOCAL_PROFILE) {
     return;
   }
@@ -223,19 +219,10 @@
           GetAutofillTable(), syncer::AUTOFILL_PROFILE);
 
   // TODO(crbug.com/904390): Remove when the investigation is over.
-  bool is_converted_from_server = false;
-  if (change.type() == AutofillProfileChange::REMOVE) {
-    // The profile is not available any more so we cannot compare its value,
-    // instead we use a rougher test based on the id - whether it is a local
-    // GUID or a server id. As a result, it has a different semantics compared
-    // to AddOrUpdate.
-    is_converted_from_server = !base::IsValidGUID(change.key());
-  } else {
-    std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
-    GetAutofillTable()->GetServerProfiles(&server_profiles);
-    is_converted_from_server = IsLocalProfileEqualToServerProfile(
-        server_profiles, *change.data_model(), app_locale_);
-  }
+  std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
+  GetAutofillTable()->GetServerProfiles(&server_profiles);
+  bool is_converted_from_server = IsLocalProfileEqualToServerProfile(
+      server_profiles, *change.data_model(), app_locale_);
 
   switch (change.type()) {
     case AutofillProfileChange::ADD:
@@ -252,12 +239,6 @@
               : AutofillProfileSyncChangeOrigin::kTrulyLocal);
       break;
     case AutofillProfileChange::REMOVE:
-      // Removals have no data_model() so this change can still be for a
-      // SERVER_PROFILE. We have no simple way to rule it out. For the time
-      // being we rely on the processor ignoring deletions for storage keys it
-      // does not know.
-      // TODO(jkrcal): implement a hash map of known storage_keys and use it
-      // here.
       change_processor()->Delete(change.key(), metadata_change_list.get());
 
       // TODO(crbug.com/904390): Remove when the investigation is over.
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
index e2410d7..9da18603 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
@@ -453,7 +453,9 @@
 TEST_F(AutofillProfileSyncBridgeTest, AutofillProfileChanged_Deleted) {
   StartSyncing({});
 
-  AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuidB, nullptr);
+  AutofillProfile local(kGuidB, kHttpsOrigin);
+  local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
+  AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuidB, &local);
   EXPECT_CALL(mock_processor(), Delete(kGuidB, _));
   // The bridge does not need to commit when reacting to a notification about a
   // local change.
@@ -462,6 +464,20 @@
   bridge()->AutofillProfileChanged(change);
 }
 
+// Server profile updates should be ignored.
+TEST_F(AutofillProfileSyncBridgeTest,
+       AutofillProfileChanged_Deleted_IgnoreServerProfiles) {
+  StartSyncing({});
+
+  AutofillProfile server_profile(AutofillProfile::SERVER_PROFILE, "server-id");
+  AutofillProfileChange change(AutofillProfileChange::REMOVE,
+                               server_profile.guid(), &server_profile);
+
+  EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+  // Should not crash.
+  bridge()->AutofillProfileChanged(change);
+}
+
 TEST_F(AutofillProfileSyncBridgeTest, GetAllDataForDebugging) {
   AutofillProfile local1 = AutofillProfile(kGuidA, kHttpsOrigin);
   local1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
diff --git a/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc b/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
index c5853c0..1a6b461 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
@@ -608,33 +608,21 @@
 
 void AutofillProfileSyncableService::ActOnChange(
      const AutofillProfileChange& change) {
-  DCHECK(
-      (change.type() == AutofillProfileChange::REMOVE &&
-       !change.data_model()) ||
-      (change.type() != AutofillProfileChange::REMOVE && change.data_model()));
+  DCHECK(change.data_model());
   DCHECK(sync_processor_);
 
-  if (change.data_model() &&
-      change.data_model()->record_type() != AutofillProfile::LOCAL_PROFILE) {
+  if (change.data_model()->record_type() != AutofillProfile::LOCAL_PROFILE) {
     return;
   }
 
   // TODO(crbug.com/904390): Remove when the investigation is over.
   bool is_converted_from_server = false;
-  if (change.type() == AutofillProfileChange::REMOVE) {
-    // The profile is not available any more so we cannot compare its value,
-    // instead we use a rougher test based on the id - whether it is a local
-    // GUID or a server id. As a result, it has a different semantics compared
-    // to AddOrUpdate.
-    is_converted_from_server = !base::IsValidGUID(change.key());
-  } else {
-    // |webdata_backend_|, used by GetAutofillTable() may be null in unit-tests.
-    if (webdata_backend_ != nullptr) {
-      std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
-      GetAutofillTable()->GetServerProfiles(&server_profiles);
-      is_converted_from_server = IsLocalProfileEqualToServerProfile(
-          server_profiles, *change.data_model(), app_locale_);
-    }
+  // |webdata_backend_|, used by GetAutofillTable() may be null in unit-tests.
+  if (webdata_backend_ != nullptr) {
+    std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
+    GetAutofillTable()->GetServerProfiles(&server_profiles);
+    is_converted_from_server = IsLocalProfileEqualToServerProfile(
+        server_profiles, *change.data_model(), app_locale_);
   }
 
   syncer::SyncChangeList new_changes;
@@ -674,13 +662,10 @@
       break;
     }
     case AutofillProfileChange::REMOVE: {
-      // Removals have no data_model() so this change can still be for a
-      // SERVER_PROFILE. Rule it out by a lookup in profiles_map_.
       if (profiles_map_.find(change.key()) != profiles_map_.end()) {
-        AutofillProfile empty_profile(change.key(), std::string());
         new_changes.push_back(
             syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_DELETE,
-                               CreateData(empty_profile)));
+                               CreateData(*(change.data_model()))));
         profiles_map_.erase(change.key());
         // TODO(crbug.com/904390): Remove when the investigation is over.
         ReportAutofillProfileDeleteOrigin(
diff --git a/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc b/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
index 1b605e94..6291ce17 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
@@ -593,7 +593,8 @@
   AutofillProfileChange change1(AutofillProfileChange::ADD, kGuid1, &profile);
   autofill_syncable_service_.AutofillProfileChanged(change1);
 
-  AutofillProfileChange change2(AutofillProfileChange::REMOVE, kGuid1, nullptr);
+  AutofillProfileChange change2(AutofillProfileChange::REMOVE, kGuid1,
+                                &profile);
   autofill_syncable_service_.AutofillProfileChanged(change2);
 
   ASSERT_EQ(1U, sync_change_processor->changes().size());
@@ -611,7 +612,9 @@
   TestSyncChangeProcessor* sync_change_processor = new TestSyncChangeProcessor;
   autofill_syncable_service_.set_sync_processor(sync_change_processor);
 
-  AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuid2, nullptr);
+  AutofillProfile profile(kGuid2, kEmptyOrigin);
+  profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
+  AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuid2, &profile);
   autofill_syncable_service_.AutofillProfileChanged(change);
 
   ASSERT_EQ(0U, sync_change_processor->changes().size());
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc
index 0b1570d..c174b5a4 100644
--- a/components/autofill/core/browser/webdata/autofill_table.cc
+++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -1705,8 +1705,8 @@
 bool AutofillTable::RemoveAutofillDataModifiedBetween(
     const base::Time& delete_begin,
     const base::Time& delete_end,
-    std::vector<std::string>* profile_guids,
-    std::vector<std::string>* credit_card_guids) {
+    std::vector<std::unique_ptr<AutofillProfile>>* profiles,
+    std::vector<std::unique_ptr<CreditCard>>* credit_cards) {
   DCHECK(delete_end.is_null() || delete_begin < delete_end);
 
   time_t delete_begin_t = delete_begin.ToTimeT();
@@ -1719,17 +1719,20 @@
   s_profiles_get.BindInt64(0, delete_begin_t);
   s_profiles_get.BindInt64(1, delete_end_t);
 
-  profile_guids->clear();
+  profiles->clear();
   while (s_profiles_get.Step()) {
     std::string guid = s_profiles_get.ColumnString(0);
-    profile_guids->push_back(guid);
+    std::unique_ptr<AutofillProfile> profile = GetAutofillProfile(guid);
+    if (!profile)
+      return false;
+    profiles->push_back(std::move(profile));
   }
   if (!s_profiles_get.Succeeded())
     return false;
 
   // Remove the profile pieces.
-  for (const std::string& guid : *profile_guids) {
-    if (!RemoveAutofillProfilePieces(guid, db_))
+  for (const std::unique_ptr<AutofillProfile>& profile : *profiles) {
+    if (!RemoveAutofillProfilePieces(profile->guid(), db_))
       return false;
   }
 
@@ -1750,10 +1753,13 @@
   s_credit_cards_get.BindInt64(0, delete_begin_t);
   s_credit_cards_get.BindInt64(1, delete_end_t);
 
-  credit_card_guids->clear();
+  credit_cards->clear();
   while (s_credit_cards_get.Step()) {
     std::string guid = s_credit_cards_get.ColumnString(0);
-    credit_card_guids->push_back(guid);
+    std::unique_ptr<CreditCard> credit_card = GetCreditCard(guid);
+    if (!credit_card)
+      return false;
+    credit_cards->push_back(std::move(credit_card));
   }
   if (!s_credit_cards_get.Succeeded())
     return false;
diff --git a/components/autofill/core/browser/webdata/autofill_table.h b/components/autofill/core/browser/webdata/autofill_table.h
index ae7114f..4c57a95 100644
--- a/components/autofill/core/browser/webdata/autofill_table.h
+++ b/components/autofill/core/browser/webdata/autofill_table.h
@@ -452,8 +452,8 @@
   bool RemoveAutofillDataModifiedBetween(
       const base::Time& delete_begin,
       const base::Time& delete_end,
-      std::vector<std::string>* profile_guids,
-      std::vector<std::string>* credit_card_guids);
+      std::vector<std::unique_ptr<AutofillProfile>>* profiles,
+      std::vector<std::unique_ptr<CreditCard>>* credit_cards);
 
   // Removes origin URLs from the autofill_profiles and credit_cards tables if
   // they were written on or after |delete_begin| and strictly before
diff --git a/components/autofill/core/browser/webdata/autofill_table_unittest.cc b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
index dce60d15..b2f8812 100644
--- a/components/autofill/core/browser/webdata/autofill_table_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -1519,16 +1519,15 @@
       "VALUES('00000000-0000-0000-0000-000000000011', 67);"));
 
   // Remove all entries modified in the bounded time range [17,41).
-  std::vector<std::string> profile_guids;
-  std::vector<std::string> credit_card_guids;
+  std::vector<std::unique_ptr<AutofillProfile>> profiles;
+  std::vector<std::unique_ptr<CreditCard>> credit_cards;
   table_->RemoveAutofillDataModifiedBetween(
-      Time::FromTimeT(17), Time::FromTimeT(41),
-      &profile_guids, &credit_card_guids);
+      Time::FromTimeT(17), Time::FromTimeT(41), &profiles, &credit_cards);
 
   // Two profiles should have been removed.
-  ASSERT_EQ(2UL, profile_guids.size());
-  EXPECT_EQ("00000000-0000-0000-0000-000000000001", profile_guids[0]);
-  EXPECT_EQ("00000000-0000-0000-0000-000000000002", profile_guids[1]);
+  ASSERT_EQ(2UL, profiles.size());
+  EXPECT_EQ("00000000-0000-0000-0000-000000000001", profiles[0]->guid());
+  EXPECT_EQ("00000000-0000-0000-0000-000000000002", profiles[1]->guid());
 
   // Make sure that only the expected profiles are still present.
   sql::Statement s_autofill_profiles_bounded(
@@ -1595,10 +1594,10 @@
   EXPECT_FALSE(s_autofill_profile_phones_bounded.Step());
 
   // Three cards should have been removed.
-  ASSERT_EQ(3UL, credit_card_guids.size());
-  EXPECT_EQ("00000000-0000-0000-0000-000000000006", credit_card_guids[0]);
-  EXPECT_EQ("00000000-0000-0000-0000-000000000007", credit_card_guids[1]);
-  EXPECT_EQ("00000000-0000-0000-0000-000000000008", credit_card_guids[2]);
+  ASSERT_EQ(3UL, credit_cards.size());
+  EXPECT_EQ("00000000-0000-0000-0000-000000000006", credit_cards[0]->guid());
+  EXPECT_EQ("00000000-0000-0000-0000-000000000007", credit_cards[1]->guid());
+  EXPECT_EQ("00000000-0000-0000-0000-000000000008", credit_cards[2]->guid());
 
   // Make sure the expected profiles are still present.
   sql::Statement s_credit_cards_bounded(
@@ -1614,12 +1613,11 @@
   EXPECT_FALSE(s_credit_cards_bounded.Step());
 
   // Remove all entries modified on or after time 51 (unbounded range).
-  table_->RemoveAutofillDataModifiedBetween(
-      Time::FromTimeT(51), Time(),
-      &profile_guids, &credit_card_guids);
-  ASSERT_EQ(2UL, profile_guids.size());
-  EXPECT_EQ("00000000-0000-0000-0000-000000000004", profile_guids[0]);
-  EXPECT_EQ("00000000-0000-0000-0000-000000000005", profile_guids[1]);
+  table_->RemoveAutofillDataModifiedBetween(Time::FromTimeT(51), Time(),
+                                            &profiles, &credit_cards);
+  ASSERT_EQ(2UL, profiles.size());
+  EXPECT_EQ("00000000-0000-0000-0000-000000000004", profiles[0]->guid());
+  EXPECT_EQ("00000000-0000-0000-0000-000000000005", profiles[1]->guid());
 
   // Make sure that only the expected profile names are still present.
   sql::Statement s_autofill_profiles_unbounded(
@@ -1670,9 +1668,9 @@
   EXPECT_FALSE(s_autofill_profile_phones_unbounded.Step());
 
   // Two cards should have been removed.
-  ASSERT_EQ(2UL, credit_card_guids.size());
-  EXPECT_EQ("00000000-0000-0000-0000-000000000010", credit_card_guids[0]);
-  EXPECT_EQ("00000000-0000-0000-0000-000000000011", credit_card_guids[1]);
+  ASSERT_EQ(2UL, credit_cards.size());
+  EXPECT_EQ("00000000-0000-0000-0000-000000000010", credit_cards[0]->guid());
+  EXPECT_EQ("00000000-0000-0000-0000-000000000011", credit_cards[1]->guid());
 
   // Make sure the remaining card is the expected one.
   sql::Statement s_credit_cards_unbounded(
@@ -1684,14 +1682,13 @@
   EXPECT_FALSE(s_credit_cards_unbounded.Step());
 
   // Remove all remaining entries.
-  table_->RemoveAutofillDataModifiedBetween(
-      Time(), Time(),
-      &profile_guids, &credit_card_guids);
+  table_->RemoveAutofillDataModifiedBetween(Time(), Time(), &profiles,
+                                            &credit_cards);
 
   // Two profiles should have been removed.
-  ASSERT_EQ(2UL, profile_guids.size());
-  EXPECT_EQ("00000000-0000-0000-0000-000000000000", profile_guids[0]);
-  EXPECT_EQ("00000000-0000-0000-0000-000000000003", profile_guids[1]);
+  ASSERT_EQ(2UL, profiles.size());
+  EXPECT_EQ("00000000-0000-0000-0000-000000000000", profiles[0]->guid());
+  EXPECT_EQ("00000000-0000-0000-0000-000000000003", profiles[1]->guid());
 
   // Make sure there are no profiles remaining.
   sql::Statement s_autofill_profiles_empty(
@@ -1722,8 +1719,8 @@
   EXPECT_FALSE(s_autofill_profile_phones_empty.Step());
 
   // One credit card should have been deleted.
-  ASSERT_EQ(1UL, credit_card_guids.size());
-  EXPECT_EQ("00000000-0000-0000-0000-000000000009", credit_card_guids[0]);
+  ASSERT_EQ(1UL, credit_cards.size());
+  EXPECT_EQ("00000000-0000-0000-0000-000000000009", credit_cards[0]->guid());
 
   // There should be no cards left.
   sql::Statement s_credit_cards_empty(
@@ -2677,12 +2674,12 @@
   table_->UnmaskServerCreditCard(masked_card, full_number);
 
   // Delete data in a range a year in the future.
-  std::vector<std::string> profile_guids;
-  std::vector<std::string> credit_card_guids;
+  std::vector<std::unique_ptr<AutofillProfile>> profiles;
+  std::vector<std::unique_ptr<CreditCard>> credit_cards;
   ASSERT_TRUE(table_->RemoveAutofillDataModifiedBetween(
       unmasked_time + base::TimeDelta::FromDays(365),
-      unmasked_time + base::TimeDelta::FromDays(530),
-      &profile_guids, &credit_card_guids));
+      unmasked_time + base::TimeDelta::FromDays(530), &profiles,
+      &credit_cards));
 
   // This should not affect the unmasked card (should be unmasked).
   std::vector<std::unique_ptr<CreditCard>> outputs;
@@ -2697,8 +2694,7 @@
   // the database uses.
   base::Time now = base::Time::Now() + base::TimeDelta::FromSeconds(1);
   ASSERT_TRUE(table_->RemoveAutofillDataModifiedBetween(
-      now - base::TimeDelta::FromDays(1), now,
-      &profile_guids, &credit_card_guids));
+      now - base::TimeDelta::FromDays(1), now, &profiles, &credit_cards));
 
   // This should re-mask.
   ASSERT_TRUE(table_->GetServerCreditCards(&outputs));
@@ -2717,7 +2713,7 @@
 
   // Delete all data.
   ASSERT_TRUE(table_->RemoveAutofillDataModifiedBetween(
-      base::Time(), base::Time::Max(), &profile_guids, &credit_card_guids));
+      base::Time(), base::Time::Max(), &profiles, &credit_cards));
 
   // Should be masked again.
   ASSERT_TRUE(table_->GetServerCreditCards(&outputs));
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
index 2a0caec..a38a740 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
@@ -438,10 +438,8 @@
 
 void AutofillWalletMetadataSyncBridge::AutofillProfileChanged(
     const AutofillProfileChange& change) {
-  // Skip local profiles (if possible, i.e. if it is not a deletion where
-  // data_model() is not set).
-  if (change.data_model() &&
-      change.data_model()->record_type() != AutofillProfile::SERVER_PROFILE) {
+  // Skip local profiles.
+  if (change.data_model()->record_type() != AutofillProfile::SERVER_PROFILE) {
     return;
   }
   LocalMetadataChanged(WalletMetadataSpecifics::ADDRESS, change);
@@ -703,9 +701,7 @@
       if (RemoveServerMetadata(GetAutofillTable(), type, metadata_id)) {
         cache_.erase(storage_key);
         // Send up deletion only if we had this entry in the DB. It is not there
-        // if (i) it was previously deleted by a remote deletion or (ii) this is
-        // notification for a LOCAL_PROFILE (which have non-overlapping
-        // storage_keys).
+        // if it was previously deleted by a remote deletion.
         change_processor()->Delete(storage_key, metadata_change_list.get());
       }
       return;
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
index 237782d..f793b93 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
@@ -821,10 +821,11 @@
   EXPECT_CALL(*backend(), CommitChanges()).Times(0);
   EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
 
-  bridge()->AutofillProfileChanged(AutofillProfileChange(
-      AutofillProfileChange::REMOVE, existing_profile.server_id(), nullptr));
+  bridge()->AutofillProfileChanged(
+      AutofillProfileChange(AutofillProfileChange::REMOVE,
+                            existing_profile.server_id(), &existing_profile));
   bridge()->CreditCardChanged(CreditCardChange(
-      CreditCardChange::REMOVE, existing_card.server_id(), nullptr));
+      CreditCardChange::REMOVE, existing_card.server_id(), &existing_card));
 
   // Check that there is no metadata anymore.
   EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
@@ -850,10 +851,11 @@
   EXPECT_CALL(*backend(), CommitChanges()).Times(0);
   EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
 
-  bridge()->AutofillProfileChanged(AutofillProfileChange(
-      AutofillProfileChange::REMOVE, existing_profile.server_id(), nullptr));
+  bridge()->AutofillProfileChanged(
+      AutofillProfileChange(AutofillProfileChange::REMOVE,
+                            existing_profile.server_id(), &existing_profile));
   bridge()->CreditCardChanged(CreditCardChange(
-      CreditCardChange::REMOVE, existing_card.server_id(), nullptr));
+      CreditCardChange::REMOVE, existing_card.server_id(), &existing_card));
 
   // Check that there is also no metadata at the end.
   EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc b/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc
index 3ee7061..e801acb8 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc
@@ -563,19 +563,18 @@
 void AutofillWalletMetadataSyncableService::AutofillProfileChanged(
     const AutofillProfileChange& change) {
   DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(change.data_model());
   if (!track_wallet_data_) {
     return;
   }
 
-  if (sync_processor_ && change.data_model() &&
+  if (sync_processor_ && change.type() == AutofillProfileChange::UPDATE &&
       change.data_model()->record_type() != AutofillProfile::LOCAL_PROFILE) {
     std::string server_id = GetServerId(*change.data_model());
     auto it = FindServerIdAndTypeInCache(
         server_id, sync_pb::WalletMetadataSpecifics::ADDRESS, &cache_);
     if (it == cache_.end())
       return;
-    // Implicitly, we filter out ADD (not in cache) and REMOVE (!data_model()).
-    DCHECK(change.type() == AutofillProfileChange::UPDATE);
 
     const sync_pb::WalletMetadataSpecifics& remote =
         it->GetSpecifics().wallet_metadata();
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
index c76ea95..aa51b2f 100644
--- a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
+++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
@@ -533,7 +533,7 @@
     if (cmp < 0) {
       ++result.items_removed;
       result.changes.emplace_back(AutofillDataModelChange<Item>::REMOVE,
-                                  (*old_it)->server_id(), nullptr);
+                                  (*old_it)->server_id(), *old_it);
       ++old_it;
     } else if (cmp == 0) {
       ++old_it;
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
index 0725f77..1027a3d 100644
--- a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
+++ b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
@@ -306,15 +306,17 @@
   }
 
   // Send GUID-based notification.
-  AutofillProfileChange change(AutofillProfileChange::REMOVE, guid, nullptr);
+  AutofillProfileChange change(AutofillProfileChange::REMOVE, guid,
+                               profile.get());
   for (auto& db_observer : db_observer_list_)
     db_observer.AutofillProfileChanged(change);
 
   if (!on_autofill_profile_changed_cb_.is_null()) {
     ui_task_runner_->PostTask(
-        FROM_HERE, base::BindOnce(on_autofill_profile_changed_cb_,
-                                  AutofillProfileDeepChange(
-                                      AutofillProfileChange::REMOVE, guid)));
+        FROM_HERE,
+        base::BindOnce(on_autofill_profile_changed_cb_,
+                       AutofillProfileDeepChange(AutofillProfileChange::REMOVE,
+                                                 *profile.get())));
   }
 
   return WebDatabase::COMMIT_NEEDED;
@@ -413,6 +415,13 @@
 WebDatabase::State AutofillWebDataBackendImpl::RemoveCreditCard(
     const std::string& guid, WebDatabase* db) {
   DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
+  std::unique_ptr<CreditCard> card =
+      AutofillTable::FromWebDatabase(db)->GetCreditCard(guid);
+  if (!card) {
+    NOTREACHED();
+    return WebDatabase::COMMIT_NOT_NEEDED;
+  }
+
   if (!AutofillTable::FromWebDatabase(db)->RemoveCreditCard(guid)) {
     NOTREACHED();
     return WebDatabase::COMMIT_NOT_NEEDED;
@@ -420,7 +429,7 @@
 
   for (auto& db_observer : db_observer_list_) {
     db_observer.CreditCardChanged(
-        CreditCardChange(CreditCardChange::REMOVE, guid, nullptr));
+        CreditCardChange(CreditCardChange::REMOVE, guid, card.get()));
   }
   return WebDatabase::COMMIT_NEEDED;
 }
@@ -552,23 +561,20 @@
         const base::Time& delete_end,
         WebDatabase* db) {
   DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
-  std::vector<std::string> profile_guids;
-  std::vector<std::string> credit_card_guids;
+  std::vector<std::unique_ptr<AutofillProfile>> profiles;
+  std::vector<std::unique_ptr<CreditCard>> credit_cards;
   if (AutofillTable::FromWebDatabase(db)->RemoveAutofillDataModifiedBetween(
-          delete_begin,
-          delete_end,
-          &profile_guids,
-          &credit_card_guids)) {
-    for (const std::string& guid : profile_guids) {
+          delete_begin, delete_end, &profiles, &credit_cards)) {
+    for (const std::unique_ptr<AutofillProfile>& profile : profiles) {
       for (auto& db_observer : db_observer_list_) {
         db_observer.AutofillProfileChanged(AutofillProfileChange(
-            AutofillProfileChange::REMOVE, guid, nullptr));
+            AutofillProfileChange::REMOVE, profile->guid(), profile.get()));
       }
     }
-    for (const std::string& guid : credit_card_guids) {
+    for (const std::unique_ptr<CreditCard>& credit_card : credit_cards) {
       for (auto& db_observer : db_observer_list_) {
-        db_observer.CreditCardChanged(
-            CreditCardChange(CreditCardChange::REMOVE, guid, nullptr));
+        db_observer.CreditCardChanged(CreditCardChange(
+            CreditCardChange::REMOVE, credit_card->guid(), credit_card.get()));
       }
     }
     // Note: It is the caller's responsibility to post notifications for any
diff --git a/components/autofill/core/browser/webdata/web_data_service_unittest.cc b/components/autofill/core/browser/webdata/web_data_service_unittest.cc
index f1d6e76..5c2ff85c 100644
--- a/components/autofill/core/browser/webdata/web_data_service_unittest.cc
+++ b/components/autofill/core/browser/webdata/web_data_service_unittest.cc
@@ -313,7 +313,7 @@
 
   // Check that GUID-based notification was sent.
   const AutofillProfileChange expected_change(AutofillProfileChange::REMOVE,
-                                              profile.guid(), nullptr);
+                                              profile.guid(), &profile);
   EXPECT_CALL(observer_, AutofillProfileChanged(expected_change))
       .WillOnce(SignalEvent(&done_event_));
 
@@ -491,7 +491,7 @@
 
   // Check that GUID-based notification was sent for the profile.
   const AutofillProfileChange expected_profile_change(
-      AutofillProfileChange::REMOVE, profile.guid(), nullptr);
+      AutofillProfileChange::REMOVE, profile.guid(), &profile);
   EXPECT_CALL(observer_, AutofillProfileChanged(expected_profile_change))
       .WillOnce(SignalEvent(&done_event_));
 
diff --git a/components/browser_sync/profile_sync_service_autofill_unittest.cc b/components/browser_sync/profile_sync_service_autofill_unittest.cc
index b9651a6..3fef1b74 100644
--- a/components/browser_sync/profile_sync_service_autofill_unittest.cc
+++ b/components/browser_sync/profile_sync_service_autofill_unittest.cc
@@ -999,7 +999,7 @@
   ASSERT_TRUE(add_autofill.success());
 
   AutofillProfileChange change(AutofillProfileChange::REMOVE,
-                               sync_profile.guid(), nullptr);
+                               sync_profile.guid(), &sync_profile);
   web_data_service()->OnAutofillProfileChanged(change);
 
   std::vector<AutofillProfile> new_sync_profiles;
diff --git a/components/cbor/BUILD.gn b/components/cbor/BUILD.gn
index b0d8024..d2736ea 100644
--- a/components/cbor/BUILD.gn
+++ b/components/cbor/BUILD.gn
@@ -7,6 +7,8 @@
 component("cbor") {
   sources = [
     "constants.h",
+    "diagnostic_writer.cc",
+    "diagnostic_writer.h",
     "reader.cc",
     "reader.h",
     "values.cc",
@@ -25,6 +27,7 @@
 source_set("unit_tests") {
   testonly = true
   sources = [
+    "diagnostic_writer_unittest.cc",
     "reader_unittest.cc",
     "values_unittest.cc",
     "writer_unittest.cc",
diff --git a/components/cbor/diagnostic_writer.cc b/components/cbor/diagnostic_writer.cc
new file mode 100644
index 0000000..870f6ba
--- /dev/null
+++ b/components/cbor/diagnostic_writer.cc
@@ -0,0 +1,143 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/cbor/diagnostic_writer.h"
+
+#include <string>
+
+#include "base/json/string_escape.h"
+#include "base/logging.h"
+#include "base/numerics/clamped_math.h"
+#include "base/strings/string_number_conversions.h"
+#include "components/cbor/constants.h"
+#include "components/cbor/values.h"
+
+using base::ClampAdd;
+using base::ClampMul;
+
+namespace cbor {
+
+static bool Serialize(const Value& node,
+                      size_t rough_max_output_bytes,
+                      std::string* s) {
+  switch (node.type()) {
+    case Value::Type::UNSIGNED:
+      s->append(base::NumberToString(node.GetUnsigned()));
+      break;
+
+    case Value::Type::NEGATIVE:
+      s->append(base::NumberToString(node.GetNegative()));
+      break;
+
+    case Value::Type::BYTE_STRING: {
+      s->append("h'");
+
+      const std::vector<uint8_t>& bytes = node.GetBytestring();
+      if (ClampAdd(s->size(), ClampMul(2u, bytes.size())) >
+          rough_max_output_bytes) {
+        return false;
+      }
+      s->append(base::HexEncode(bytes.data(), bytes.size()));
+
+      s->push_back('\'');
+      break;
+    }
+
+    case Value::Type::STRING: {
+      std::string quoted_and_escaped;
+      base::EscapeJSONString(node.GetString(), /*put_in_quotes=*/true,
+                             &quoted_and_escaped);
+      if (ClampAdd(s->size(), quoted_and_escaped.size()) >
+          rough_max_output_bytes) {
+        return false;
+      }
+      s->append(quoted_and_escaped);
+      break;
+    }
+
+    case Value::Type::ARRAY: {
+      s->push_back('[');
+
+      const Value::ArrayValue& nodes = node.GetArray();
+      bool first = true;
+      for (const auto& subnode : nodes) {
+        if (!first) {
+          s->append(", ");
+        }
+        if (!Serialize(subnode, rough_max_output_bytes, s) ||
+            s->size() > rough_max_output_bytes) {
+          return false;
+        }
+        first = false;
+      }
+
+      s->push_back(']');
+      break;
+    }
+
+    case Value::Type::MAP: {
+      s->push_back('{');
+
+      const Value::MapValue& nodes = node.GetMap();
+      bool first = true;
+      for (const auto& pair : nodes) {
+        if (!first) {
+          s->append(", ");
+        }
+        if (!Serialize(pair.first, rough_max_output_bytes, s)) {
+          return false;
+        }
+        s->append(": ");
+        if (!Serialize(pair.second, rough_max_output_bytes, s) ||
+            s->size() > rough_max_output_bytes) {
+          return false;
+        }
+        first = false;
+      }
+
+      s->push_back('}');
+      break;
+    }
+
+    case Value::Type::SIMPLE_VALUE:
+      switch (node.GetSimpleValue()) {
+        case Value::SimpleValue::FALSE_VALUE:
+          s->append("false");
+          break;
+        case Value::SimpleValue::TRUE_VALUE:
+          s->append("true");
+          break;
+        case Value::SimpleValue::NULL_VALUE:
+          s->append("null");
+          break;
+        case Value::SimpleValue::UNDEFINED:
+          s->append("undefined");
+          break;
+        default:
+          NOTREACHED();
+          break;
+      }
+      break;
+
+    case Value::Type::NONE:
+      s->append("none");
+      break;
+
+    case Value::Type::TAG:
+      NOTREACHED();
+      break;
+  }
+
+  return true;
+}
+
+// static
+std::string DiagnosticWriter::Write(const Value& node,
+                                    size_t rough_max_output_bytes) {
+  std::string ret;
+  Serialize(node, rough_max_output_bytes, &ret);
+  return ret;
+}
+
+}  // namespace cbor
diff --git a/components/cbor/diagnostic_writer.h b/components/cbor/diagnostic_writer.h
new file mode 100644
index 0000000..3106ee3
--- /dev/null
+++ b/components/cbor/diagnostic_writer.h
@@ -0,0 +1,29 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_CBOR_DIAGNOSTIC_WRITER_H_
+#define COMPONENTS_CBOR_DIAGNOSTIC_WRITER_H_
+
+#include <string>
+
+#include "components/cbor/cbor_export.h"
+
+namespace cbor {
+
+class Value;
+
+class CBOR_EXPORT DiagnosticWriter {
+ public:
+  // Write converts the given CBOR value to a compact string, following the
+  // "Diagnostic Notation" format for CBOR
+  // (https://tools.ietf.org/html/rfc7049#section-6). |rough_max_output_bytes|
+  // provides a loose upper bound on the size of the result and the result may
+  // be truncated if it exceeds this size.
+  static std::string Write(const Value& node,
+                           size_t rough_max_output_bytes = 4096);
+};
+
+}  // namespace cbor
+
+#endif  // COMPONENTS_CBOR_DIAGNOSTIC_WRITER_H_
diff --git a/components/cbor/diagnostic_writer_unittest.cc b/components/cbor/diagnostic_writer_unittest.cc
new file mode 100644
index 0000000..c804ce0
--- /dev/null
+++ b/components/cbor/diagnostic_writer_unittest.cc
@@ -0,0 +1,61 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/cbor/diagnostic_writer.h"
+#include "components/cbor/values.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cbor {
+
+TEST(CBORDiagnosticWriterTest, Basic) {
+  Value::MapValue map;
+  map.emplace(1, 1);
+  map.emplace(2, -2);
+  map.emplace(3, "test");
+  std::vector<uint8_t> bytes = {1, 2, 3, 4};
+  map.emplace(4, std::move(bytes));
+
+  Value::MapValue submap;
+  submap.emplace(5, true);
+  submap.emplace(6, false);
+  map.emplace(5, cbor::Value(submap));
+
+  Value::ArrayValue array;
+  array.emplace_back(1);
+  array.emplace_back(2);
+  array.emplace_back(3);
+  array.emplace_back("foo");
+  map.emplace(6, cbor::Value(array));
+
+  map.emplace(7, "es\'cap\\in\ng");
+
+  EXPECT_EQ(
+      "{1: 1, 2: -2, 3: \"test\", 4: h'01020304', 5: {5: true, 6: false}, 6: "
+      "[1, 2, 3, \"foo\"], 7: \"es'cap\\\\in\\ng\"}",
+      DiagnosticWriter::Write(cbor::Value(map)));
+}
+
+TEST(CBORDiagnosticWriterTest, SizeLimit) {
+  Value::ArrayValue array;
+  array.emplace_back(1);
+  array.emplace_back(2);
+  array.emplace_back(3);
+  EXPECT_EQ("[1, 2, 3]", DiagnosticWriter::Write(cbor::Value(array)));
+  // A limit of zero is set, but it's only rough, so a few bytes might be
+  // produced.
+  EXPECT_LT(
+      DiagnosticWriter::Write(cbor::Value(array), /*rough_max_output_bytes=*/0)
+          .size(),
+      3u);
+
+  std::vector<uint8_t> bytes;
+  bytes.resize(100);
+  EXPECT_LT(
+      DiagnosticWriter::Write(cbor::Value(bytes), /*rough_max_output_bytes=*/0)
+          .size(),
+      3u);
+}
+
+}  // namespace cbor
diff --git a/components/certificate_transparency/log_dns_client.cc b/components/certificate_transparency/log_dns_client.cc
index 783b85d..695c096 100644
--- a/components/certificate_transparency/log_dns_client.cc
+++ b/components/certificate_transparency/log_dns_client.cc
@@ -483,14 +483,14 @@
   }
 
   last_dns_response_ = nullptr;
+  DCHECK(url_request_context_);
   current_dns_transaction_ = factory->CreateTransaction(
       qname, net::dns_protocol::kTypeTXT,
       base::BindOnce(&AuditProofQueryImpl::OnDnsTransactionComplete,
                      weak_ptr_factory_.GetWeakPtr()),
       net_log_,
-      lookup_securely_ ? net::SecureDnsMode::SECURE : net::SecureDnsMode::OFF);
-  DCHECK(url_request_context_);
-  current_dns_transaction_->SetRequestContext(url_request_context_);
+      lookup_securely_ ? net::SecureDnsMode::SECURE : net::SecureDnsMode::OFF,
+      url_request_context_);
 
   current_dns_transaction_->Start();
   return true;
diff --git a/components/crash/content/app/breakpad_win.cc b/components/crash/content/app/breakpad_win.cc
index 172cf5b..2231f14 100644
--- a/components/crash/content/app/breakpad_win.cc
+++ b/components/crash/content/app/breakpad_win.cc
@@ -372,9 +372,6 @@
 // Crashes the process after generating a dump for the provided exception. Note
 // that the crash reporter should be initialized before calling this function
 // for it to do anything.
-// NOTE: This function is used by SyzyASAN to invoke a crash. If you change the
-// the name or signature of this function you will break SyzyASAN instrumented
-// releases of Chrome. Please contact syzygy-team@chromium.org before doing so!
 extern "C" int __declspec(dllexport) CrashForException(
     EXCEPTION_POINTERS* info) {
   if (g_breakpad) {
diff --git a/components/cronet/native/cronet.idl b/components/cronet/native/cronet.idl
index c5615cd..ec9463b 100644
--- a/components/cronet/native/cronet.idl
+++ b/components/cronet/native/cronet.idl
@@ -859,6 +859,9 @@
    * Invoked when request is completed successfully. Once invoked, no other
    * UrlRequestCallback methods will be invoked.
    *
+   * Implementations of {@link #OnSucceeded} are allowed to call {@code
+   * Cronet_UrlRequest_Destroy(request)}.
+   *
    * @param request Request that succeeded.
    * @param info Response information.
    */
@@ -869,6 +872,9 @@
    * Once invoked, no other UrlRequestCallback methods will be invoked.
    * |error| provides information about the failure.
    *
+   * Implementations of {@link #OnFailed} are allowed to call {@code
+   * Cronet_UrlRequest_Destroy(request)}.
+   *
    * @param request Request that failed.
    * @param info Response information. May be null if no response was
    *         received.
@@ -880,6 +886,9 @@
    * Invoked if request was canceled via UrlRequest.cancel(). Once
    * invoked, no other UrlRequestCallback methods will be invoked.
    *
+   * Implementations of {@link #OnCanceled} are allowed to call {@code
+   * Cronet_UrlRequest_Destroy(request)}.
+   *
    * @param request Request that was canceled.
    * @param info Response information. May be null if no response was
    *         received.
diff --git a/components/cronet/native/url_request.cc b/components/cronet/native/url_request.cc
index 8c807c8d..a0ee45c8 100644
--- a/components/cronet/native/url_request.cc
+++ b/components/cronet/native/url_request.cc
@@ -546,6 +546,7 @@
   }
   InvokeAllStatusListeners();
   Cronet_UrlRequestCallback_OnSucceeded(callback_, this, response_info_.get());
+  // |this| may have been deleted here.
 }
 
 void Cronet_UrlRequestImpl::InvokeCallbackOnFailed() {
@@ -556,11 +557,13 @@
   InvokeAllStatusListeners();
   Cronet_UrlRequestCallback_OnFailed(callback_, this, response_info_.get(),
                                      error_.get());
+  // |this| may have been deleted here.
 }
 
 void Cronet_UrlRequestImpl::InvokeCallbackOnCanceled() {
   InvokeAllStatusListeners();
   Cronet_UrlRequestCallback_OnCanceled(callback_, this, response_info_.get());
+  // |this| may have been deleted here.
 }
 
 void Cronet_UrlRequestImpl::InvokeAllStatusListeners() {
diff --git a/components/gwp_asan/common/allocator_state.cc b/components/gwp_asan/common/allocator_state.cc
index 636979a..4a6812014 100644
--- a/components/gwp_asan/common/allocator_state.cc
+++ b/components/gwp_asan/common/allocator_state.cc
@@ -17,6 +17,7 @@
 // TODO: Delete out-of-line constexpr defininitons once C++17 is in use.
 constexpr size_t AllocatorState::kMaxMetadata;
 constexpr size_t AllocatorState::kMaxSlots;
+constexpr AllocatorState::MetadataIdx AllocatorState::kInvalidMetadataIdx;
 constexpr size_t AllocatorState::kMaxStackFrames;
 constexpr size_t AllocatorState::kMaxPackedTraceLength;
 
@@ -28,9 +29,7 @@
     const MetadataIdx* slot_to_metadata,
     MetadataIdx* metadata_idx) const {
   CHECK(IsValid());
-
-  if (!PointerIsMine(exception_address))
-    return GetMetadataReturnType::kUnrelatedCrash;
+  CHECK(PointerIsMine(exception_address));
 
   AllocatorState::SlotIdx slot_idx = GetNearestSlot(exception_address);
   if (slot_idx >= total_pages)
diff --git a/components/gwp_asan/common/allocator_state.h b/components/gwp_asan/common/allocator_state.h
index 64d69200..4e3d9240 100644
--- a/components/gwp_asan/common/allocator_state.h
+++ b/components/gwp_asan/common/allocator_state.h
@@ -27,6 +27,7 @@
 
 #include <atomic>
 #include <limits>
+#include <type_traits>
 
 #include "base/threading/platform_thread.h"
 
@@ -71,12 +72,11 @@
   };
 
   enum class GetMetadataReturnType {
-    kUnrelatedCrash = 0,
-    kGwpAsanCrash = 1,
-    kGwpAsanCrashWithMissingMetadata = 2,
-    kErrorBadSlot = 3,
-    kErrorBadMetadataIndex = 4,
-    kErrorOutdatedMetadataIndex = 5,
+    kGwpAsanCrash = 0,
+    kGwpAsanCrashWithMissingMetadata = 1,
+    kErrorBadSlot = 2,
+    kErrorBadMetadataIndex = 3,
+    kErrorOutdatedMetadataIndex = 4,
   };
 
   // Structure for storing data about a slot.
@@ -124,15 +124,12 @@
   bool IsValid() const;
 
   // This method is meant to be called from the crash handler with a validated
-  // AllocatorState object read from the crashed process. Given the metadata
-  // and slot to metadata arrays for the allocator and an exception address,
-  // this method determines if the exception is related to GWP-ASan or not and
-  // what the metadata for the relevant GWP-ASan allocation is if so.
-  //
-  // Returns an enum indicating an error, unrelated exception, or a GWP-ASan
-  // exception with or without metadata. If metadata is available, the
-  // metadata_idx parameter stores the index of the relevant metadata in the
-  // given array.
+  // AllocatorState object read from the crashed process and an exception
+  // address known to be in the GWP-ASan allocator region. Given the metadata
+  // and slot to metadata arrays for the allocator, this method returns an enum
+  // indicating an error or a GWP-ASan exception with or without metadata. If
+  // metadata is available, the metadata_idx parameter stores the index of the
+  // relevant metadata in the given array.
   GetMetadataReturnType GetMetadataForAddress(
       uintptr_t exception_address,
       const SlotMetadata* metadata_arr,
diff --git a/components/gwp_asan/common/allocator_state_unittest.cc b/components/gwp_asan/common/allocator_state_unittest.cc
index 4d81967..43246e5 100644
--- a/components/gwp_asan/common/allocator_state_unittest.cc
+++ b/components/gwp_asan/common/allocator_state_unittest.cc
@@ -150,9 +150,14 @@
   AllocatorState::MetadataIdx slot_to_metadata[kTestSlots];
 
   AllocatorState::MetadataIdx idx;
-  EXPECT_EQ(state_.GetMetadataForAddress(state_.pages_base_addr - 1, md,
-                                         slot_to_metadata, &idx),
-            GetMetadataReturnType::kUnrelatedCrash);
+#if defined(GTEST_HAS_DEATH_TEST)
+  EXPECT_DEATH(
+      {
+        state_.GetMetadataForAddress(state_.pages_base_addr - 1, md,
+                                     slot_to_metadata, &idx);
+      },
+      "");
+#endif
 
   slot_to_metadata[0] = AllocatorState::kInvalidMetadataIdx;
   EXPECT_EQ(state_.GetMetadataForAddress(state_.first_page_addr, md,
diff --git a/components/gwp_asan/crash_handler/crash_analyzer.cc b/components/gwp_asan/crash_handler/crash_analyzer.cc
index 26f77ad7..78f3213 100644
--- a/components/gwp_asan/crash_handler/crash_analyzer.cc
+++ b/components/gwp_asan/crash_handler/crash_analyzer.cc
@@ -111,8 +111,10 @@
   else if (valid_state.free_invalid_address)
     exception_addr = valid_state.free_invalid_address;
 
-  if (!exception_addr)
+  if (!exception_addr || !valid_state.PointerIsMine(exception_addr))
     return GwpAsanCrashAnalysisResult::kUnrelatedCrash;
+  // All errors that occur below happen for an exception known to be related to
+  // GWP-ASan.
 
   // Read the allocator's entire metadata array.
   auto metadata_arr = std::make_unique<AllocatorState::SlotMetadata[]>(
@@ -152,8 +154,6 @@
     DLOG(ERROR) << "Metadata index was outdated!";
     return GwpAsanCrashAnalysisResult::kErrorOutdatedMetadataIndex;
   }
-  if (ret == GetMetadataReturnType::kUnrelatedCrash)
-    return GwpAsanCrashAnalysisResult::kUnrelatedCrash;
 
   bool missing_metadata =
       (ret == GetMetadataReturnType::kGwpAsanCrashWithMissingMetadata);
diff --git a/components/gwp_asan/crash_handler/crash_handler_unittest.cc b/components/gwp_asan/crash_handler/crash_handler_unittest.cc
index 2d17694..56889d1 100644
--- a/components/gwp_asan/crash_handler/crash_handler_unittest.cc
+++ b/components/gwp_asan/crash_handler/crash_handler_unittest.cc
@@ -36,8 +36,6 @@
 
 namespace {
 
-class GwpAsanTest : public testing::Test {};
-
 constexpr size_t kAllocationSize = 902;
 constexpr int kSuccess = 0;
 constexpr size_t kTotalPages = AllocatorState::kMaxSlots;
diff --git a/components/keyed_service/core/dependency_manager.cc b/components/keyed_service/core/dependency_manager.cc
index 14b20f96..cb4ea9a 100644
--- a/components/keyed_service/core/dependency_manager.cc
+++ b/components/keyed_service/core/dependency_manager.cc
@@ -74,25 +74,64 @@
 }
 
 void DependencyManager::DestroyContextServices(void* context) {
-  std::vector<DependencyNode*> destruction_order;
-  if (!dependency_graph_.GetDestructionOrder(&destruction_order)) {
-    NOTREACHED();
-  }
+  std::vector<DependencyNode*> destruction_order = GetDestructionOrder();
 
 #ifndef NDEBUG
   DumpContextDependencies(context);
 #endif
 
-  for (auto* dependency_node : destruction_order) {
+  ShutdownFactoriesInOrder(context, destruction_order);
+  MarkContextDead(context);
+  DestroyFactoriesInOrder(context, destruction_order);
+}
+
+// static
+void DependencyManager::PerformInterlockedTwoPhaseShutdown(
+    DependencyManager* dependency_manager1,
+    void* context1,
+    DependencyManager* dependency_manager2,
+    void* context2) {
+  std::vector<DependencyNode*> destruction_order1 =
+      dependency_manager1->GetDestructionOrder();
+  std::vector<DependencyNode*> destruction_order2 =
+      dependency_manager2->GetDestructionOrder();
+
+#ifndef NDEBUG
+  dependency_manager1->DumpContextDependencies(context1);
+  dependency_manager2->DumpContextDependencies(context2);
+#endif
+
+  ShutdownFactoriesInOrder(context1, destruction_order1);
+  ShutdownFactoriesInOrder(context2, destruction_order2);
+
+  dependency_manager1->MarkContextDead(context1);
+  dependency_manager2->MarkContextDead(context2);
+
+  DestroyFactoriesInOrder(context1, destruction_order1);
+  DestroyFactoriesInOrder(context2, destruction_order2);
+}
+
+std::vector<DependencyNode*> DependencyManager::GetDestructionOrder() {
+  std::vector<DependencyNode*> destruction_order;
+  if (!dependency_graph_.GetDestructionOrder(&destruction_order))
+    NOTREACHED();
+  return destruction_order;
+}
+
+void DependencyManager::ShutdownFactoriesInOrder(
+    void* context,
+    std::vector<DependencyNode*>& order) {
+  for (auto* dependency_node : order) {
     KeyedServiceBaseFactory* factory =
         static_cast<KeyedServiceBaseFactory*>(dependency_node);
     factory->ContextShutdown(context);
   }
+}
 
-  // The context is now dead to the rest of the program.
-  dead_context_pointers_.insert(context);
-
-  for (auto* dependency_node : destruction_order) {
+void DependencyManager::DestroyFactoriesInOrder(
+    void* context,
+    std::vector<DependencyNode*>& order) {
+  for (auto* dependency_node : order) {
     KeyedServiceBaseFactory* factory =
         static_cast<KeyedServiceBaseFactory*>(dependency_node);
     factory->ContextDestroyed(context);
@@ -117,6 +156,10 @@
   dead_context_pointers_.erase(context);
 }
 
+void DependencyManager::MarkContextDead(void* context) {
+  dead_context_pointers_.insert(context);
+}
+
 #ifndef NDEBUG
 namespace {
 
diff --git a/components/keyed_service/core/dependency_manager.h b/components/keyed_service/core/dependency_manager.h
index 39ba693..1ee0b9dcf 100644
--- a/components/keyed_service/core/dependency_manager.h
+++ b/components/keyed_service/core/dependency_manager.h
@@ -26,6 +26,19 @@
 // broadcasting the context creation and destruction to each factory in
 // a safe order based on the stated dependencies.
 class KEYED_SERVICE_EXPORT DependencyManager {
+ public:
+  // Shuts down all keyed services managed by two
+  // DependencyManagers (DMs), then destroys them. The order of execution is:
+  // - Shutdown services in DM1
+  // - Shutdown services in DM2
+  // - Destroy services in DM1
+  // - Destroy services in DM2
+  static void PerformInterlockedTwoPhaseShutdown(
+      DependencyManager* dependency_manager1,
+      void* context1,
+      DependencyManager* dependency_manager2,
+      void* context2);
+
  protected:
   DependencyManager();
   virtual ~DependencyManager();
@@ -70,6 +83,11 @@
   // 0xWhatever).
   void MarkContextLive(void* context);
 
+  // Marks |context| as dead (i.e., stale). Calls passing |context| to
+  //|AssertContextWasntDestroyed()| will flag an error until that context is
+  // marked as live again with MarkContextLive().
+  void MarkContextDead(void* context);
+
 #ifndef NDEBUG
   // Dumps service dependency graph as a Graphviz dot file |dot_file| with a
   // title |top_level_name|. Helper for |DumpContextDependencies|.
@@ -85,6 +103,12 @@
   virtual void DumpContextDependencies(void* context) const = 0;
 #endif  // NDEBUG
 
+  std::vector<DependencyNode*> GetDestructionOrder();
+  static void ShutdownFactoriesInOrder(void* context,
+                                       std::vector<DependencyNode*>& order);
+  static void DestroyFactoriesInOrder(void* context,
+                                      std::vector<DependencyNode*>& order);
+
   DependencyGraph dependency_graph_;
 
   // A list of context objects that have gone through the Shutdown() phase.
diff --git a/components/omnibox/browser/document_provider.cc b/components/omnibox/browser/document_provider.cc
index a50c9f7..96f2d47 100644
--- a/components/omnibox/browser/document_provider.cc
+++ b/components/omnibox/browser/document_provider.cc
@@ -431,6 +431,9 @@
       omnibox::kDocumentProvider, "DocumentScoreResult2", 700);
   int score2 = base::GetFieldTrialParamByFeatureAsInt(
       omnibox::kDocumentProvider, "DocumentScoreResult3", 300);
+  // During development/quality iteration we may wish to defeat server scores.
+  bool use_server_scores = base::GetFieldTrialParamByFeatureAsBool(
+      omnibox::kDocumentProvider, "DocumentUseServerScore", true);
 
   // Some users may be in a counterfactual study arm in which we perform all
   // necessary work but do not forward the autocomplete matches.
@@ -473,7 +476,7 @@
         break;
     }
     int server_score;
-    if (result->GetInteger("score", &server_score)) {
+    if (use_server_scores && result->GetInteger("score", &server_score)) {
       if (previous_score >= 0 && server_score >= previous_score) {
         server_score = previous_score - 1;
       }
@@ -514,7 +517,7 @@
         match.description = GetProductDescriptionString(mimetype);
       }
       AutocompleteMatch::AddLastClassificationIfNecessary(
-          &match.description_class, 0, ACMatchClassification::NONE);
+          &match.description_class, 0, ACMatchClassification::DIM);
     }
     match.transition = ui::PAGE_TRANSITION_GENERATED;
     if (!in_counterfactual_group) {
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc
index 82482677c..f77ab0cd 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser.cc
+++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -253,11 +253,10 @@
   bool sign_in_username_first = true;
   // First username is stored in |result->username|.
   const FormFieldData* second_username = nullptr;
-  for (const auto& prediction : predictions) {
+  for (const PasswordFieldPrediction& prediction : predictions) {
     ProcessedField* processed_field = nullptr;
 
-    CredentialFieldType field_type =
-        DeriveFromServerFieldType(prediction.second.type);
+    CredentialFieldType field_type = DeriveFromServerFieldType(prediction.type);
     bool is_password_prediction = IsPasswordPrediction(field_type);
     if (mode == FormDataParser::Mode::kSaving && is_password_prediction) {
       // TODO(crbug.com/913965): Consider server predictions for password fields
@@ -267,14 +266,14 @@
     switch (field_type) {
       case CredentialFieldType::kUsername:
         if (!result->username) {
-          processed_field =
-              FindFieldWithUniqueRendererId(processed_fields, prediction.first);
+          processed_field = FindFieldWithUniqueRendererId(
+              processed_fields, prediction.renderer_id);
           if (processed_field) {
             result->username = processed_field->field;
           }
         } else if (!second_username) {
-          processed_field =
-              FindFieldWithUniqueRendererId(processed_fields, prediction.first);
+          processed_field = FindFieldWithUniqueRendererId(
+              processed_fields, prediction.renderer_id);
           if (processed_field) {
             second_username = processed_field->field;
           }
@@ -286,8 +285,8 @@
         if (result->password) {
           prevent_handling_two_usernames = true;
         } else {
-          processed_field =
-              FindFieldWithUniqueRendererId(processed_fields, prediction.first);
+          processed_field = FindFieldWithUniqueRendererId(
+              processed_fields, prediction.renderer_id);
           if (processed_field) {
             if (!processed_field->is_password)
               continue;
@@ -307,8 +306,8 @@
         // before the user has thought of and typed their new password
         // elsewhere. See https://crbug.com/902700 for more details.
         if (!result->new_password) {
-          processed_field =
-              FindFieldWithUniqueRendererId(processed_fields, prediction.first);
+          processed_field = FindFieldWithUniqueRendererId(
+              processed_fields, prediction.renderer_id);
           if (processed_field) {
             if (!processed_field->is_password)
               continue;
@@ -317,8 +316,8 @@
         }
         break;
       case CredentialFieldType::kConfirmationPassword:
-        processed_field =
-            FindFieldWithUniqueRendererId(processed_fields, prediction.first);
+        processed_field = FindFieldWithUniqueRendererId(processed_fields,
+                                                        prediction.renderer_id);
         if (processed_field) {
           if (!processed_field->is_password)
             continue;
@@ -355,11 +354,11 @@
 
   // For the use of basic heuristics, also mark CVC fields and NOT_PASSWORD
   // fields as such.
-  for (const auto& prediction : predictions) {
-    if (prediction.second.type == autofill::CREDIT_CARD_VERIFICATION_CODE ||
-        prediction.second.type == autofill::NOT_PASSWORD) {
-      ProcessedField* processed_field =
-          FindFieldWithUniqueRendererId(processed_fields, prediction.first);
+  for (const PasswordFieldPrediction& prediction : predictions) {
+    if (prediction.type == autofill::CREDIT_CARD_VERIFICATION_CODE ||
+        prediction.type == autofill::NOT_PASSWORD) {
+      ProcessedField* processed_field = FindFieldWithUniqueRendererId(
+          processed_fields, prediction.renderer_id);
       if (processed_field)
         processed_field->server_hints_not_password = true;
     }
@@ -868,10 +867,11 @@
     return false;
 
   uint32_t username_id = significant_fields.username->unique_renderer_id;
-  auto it = form_predictions->find(username_id);
-  if (it == form_predictions->end())
-    return false;
-  return it->second.may_use_prefilled_placeholder;
+  for (const PasswordFieldPrediction& prediction : *form_predictions) {
+    if (prediction.renderer_id == username_id)
+      return prediction.may_use_prefilled_placeholder;
+  }
+  return false;
 }
 
 // Puts together a PasswordForm, the result of the parsing, based on the
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
index 462b1af4..894dc06 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
+++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -174,8 +174,8 @@
   form_data.submission_event = test_case.submission_event;
   for (const FieldDataDescription& field_description : test_case.fields) {
     FormFieldData field;
-    const uint32_t unique_id = GetUniqueId();
-    field.unique_renderer_id = unique_id;
+    const uint32_t renderer_id = GetUniqueId();
+    field.unique_renderer_id = renderer_id;
     field.id_attribute = StampUniqueSuffix("html_id");
     if (field_description.name == kNonimportantValue) {
       field.name = StampUniqueSuffix("html_name");
@@ -199,16 +199,19 @@
       field.typed_value = ASCIIToUTF16(field_description.typed_value);
     form_data.fields.push_back(field);
     if (field_description.role == ElementRole::NONE) {
-      UpdateResultWithIdByRole(fill_result, unique_id,
+      UpdateResultWithIdByRole(fill_result, renderer_id,
                                field_description.role_filling);
-      UpdateResultWithIdByRole(save_result, unique_id,
+      UpdateResultWithIdByRole(save_result, renderer_id,
                                field_description.role_saving);
     } else {
-      UpdateResultWithIdByRole(fill_result, unique_id, field_description.role);
-      UpdateResultWithIdByRole(save_result, unique_id, field_description.role);
+      UpdateResultWithIdByRole(fill_result, renderer_id,
+                               field_description.role);
+      UpdateResultWithIdByRole(save_result, renderer_id,
+                               field_description.role);
     }
     if (field_description.prediction.type != autofill::MAX_VALID_FIELD_TYPE) {
-      (*predictions)[unique_id] = field_description.prediction;
+      predictions->push_back(field_description.prediction);
+      predictions->back().renderer_id = renderer_id;
     }
     if (field_description.predicted_username >= 0) {
       size_t index = static_cast<size_t>(field_description.predicted_username);
diff --git a/components/password_manager/core/browser/form_parsing/password_field_prediction.cc b/components/password_manager/core/browser/form_parsing/password_field_prediction.cc
index 53d62567..3cae5de 100644
--- a/components/password_manager/core/browser/form_parsing/password_field_prediction.cc
+++ b/components/password_manager/core/browser/form_parsing/password_field_prediction.cc
@@ -86,9 +86,10 @@
             predictions.may_use_prefilled_placeholder();
       }
 
-      result[field->unique_renderer_id] = PasswordFieldPrediction{
-          .type = server_type,
-          .may_use_prefilled_placeholder = may_use_prefilled_placeholder};
+      result.push_back(
+          {.renderer_id = field->unique_renderer_id,
+           .type = server_type,
+           .may_use_prefilled_placeholder = may_use_prefilled_placeholder});
     }
   }
 
diff --git a/components/password_manager/core/browser/form_parsing/password_field_prediction.h b/components/password_manager/core/browser/form_parsing/password_field_prediction.h
index c4bb30a..50adf03e 100644
--- a/components/password_manager/core/browser/form_parsing/password_field_prediction.h
+++ b/components/password_manager/core/browser/form_parsing/password_field_prediction.h
@@ -6,7 +6,7 @@
 #define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_FORM_PARSING_PASSWORD_FIELD_PREDICTION_H_
 
 #include <stdint.h>
-#include <map>
+#include <vector>
 
 #include "components/autofill/core/browser/field_types.h"
 
@@ -30,13 +30,14 @@
 
 // Contains server predictions for a field.
 struct PasswordFieldPrediction {
+  uint32_t renderer_id;
   autofill::ServerFieldType type;
   bool may_use_prefilled_placeholder = false;
 };
 
 // Contains server predictions for a form. Keys are unique renderer ids of
 // fields.
-using FormPredictions = std::map<uint32_t, PasswordFieldPrediction>;
+using FormPredictions = std::vector<PasswordFieldPrediction>;
 
 // Extracts all password related server predictions from |form_structure|.
 FormPredictions ConvertToFormPredictions(
diff --git a/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc b/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc
index 3c78258..a0265ee 100644
--- a/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc
+++ b/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc
@@ -36,6 +36,16 @@
 
 namespace {
 
+const PasswordFieldPrediction* FindFormPrediction(
+    const FormPredictions& predictions,
+    uint32_t renderer_id) {
+  for (const PasswordFieldPrediction& prediction : predictions) {
+    if (prediction.renderer_id == renderer_id)
+      return &prediction;
+  }
+  return nullptr;
+}
+
 TEST(FormPredictionsTest, ConvertToFormPredictions) {
   struct TestField {
     std::string name;
@@ -85,14 +95,15 @@
 
   for (size_t i = 0; i < base::size(test_fields); ++i) {
     uint32_t unique_renderer_id = form_data.fields[i].unique_renderer_id;
-    auto it = actual_predictions.find(unique_renderer_id);
+    const PasswordFieldPrediction* actual_prediction =
+        FindFormPrediction(actual_predictions, unique_renderer_id);
     if (test_fields[i].expected_type == UNKNOWN_TYPE) {
-      EXPECT_EQ(actual_predictions.end(), it);
+      EXPECT_FALSE(actual_prediction);
     } else {
-      ASSERT_NE(actual_predictions.end(), it);
-      EXPECT_EQ(test_fields[i].expected_type, it->second.type);
+      ASSERT_TRUE(actual_prediction);
+      EXPECT_EQ(test_fields[i].expected_type, actual_prediction->type);
       EXPECT_EQ(test_fields[i].may_use_prefilled_placeholder,
-                it->second.may_use_prefilled_placeholder);
+                actual_prediction->may_use_prefilled_placeholder);
     }
   }
 }
@@ -155,9 +166,10 @@
                    << ", input type=" << test_form[i].input_type
                    << ", expected type=" << test_form[i].expected_type
                    << ", synthesised FormFieldData=" << form_data.fields[i]);
-      auto it = actual_predictions.find(form_data.fields[i].unique_renderer_id);
-      ASSERT_NE(actual_predictions.end(), it);
-      EXPECT_EQ(test_form[i].expected_type, it->second.type);
+      const PasswordFieldPrediction* actual_prediction = FindFormPrediction(
+          actual_predictions, form_data.fields[i].unique_renderer_id);
+      ASSERT_TRUE(actual_prediction);
+      EXPECT_EQ(test_form[i].expected_type, actual_prediction->type);
     }
   }
 }
diff --git a/components/password_manager/core/browser/new_password_form_manager.cc b/components/password_manager/core/browser/new_password_form_manager.cc
index abe79c5..74e03072 100644
--- a/components/password_manager/core/browser/new_password_form_manager.cc
+++ b/components/password_manager/core/browser/new_password_form_manager.cc
@@ -1024,6 +1024,7 @@
     parsed_form->origin = form.origin;
     parsed_form->signon_realm = GetSignonRealm(form.origin);
   }
+  parsed_form->date_created = base::Time::Now();
 
   if (!HasGeneratedPassword()) {
     votes_uploader_.set_generated_password_changed(false);
diff --git a/components/password_manager/core/browser/new_password_form_manager_unittest.cc b/components/password_manager/core/browser/new_password_form_manager_unittest.cc
index acd6988..414e18d 100644
--- a/components/password_manager/core/browser/new_password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/new_password_form_manager_unittest.cc
@@ -175,7 +175,7 @@
     uint32_t renderer_id =
         form.fields[index_prediction.first].unique_renderer_id;
     ServerFieldType server_type = index_prediction.second;
-    predictions[renderer_id] = PasswordFieldPrediction{.type = server_type};
+    predictions.push_back({.renderer_id = renderer_id, .type = server_type});
   }
   FormSignature form_signature = CalculateFormSignature(form);
   return {{form_signature, predictions}};
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index ec2f994..3331be9 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -415,13 +415,14 @@
 
 void PasswordFormManager::PresaveGeneratedPassword(
     const autofill::PasswordForm& form) {
+  autofill::PasswordForm mutable_form(form);
+  mutable_form.date_created = base::Time::Now();
   if ((best_matches_.find(form.username_value) == best_matches_.end()) ||
       form.username_value.empty()) {
-    form_saver()->PresaveGeneratedPassword(form);
+    form_saver()->PresaveGeneratedPassword(mutable_form);
   } else {
-    autofill::PasswordForm form_without_username(form);
-    form_without_username.username_value.clear();
-    form_saver()->PresaveGeneratedPassword(form_without_username);
+    mutable_form.username_value.clear();
+    form_saver()->PresaveGeneratedPassword(mutable_form);
   }
 
   if (!has_generated_password_) {
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index 252e48b..e3f95227 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -3265,24 +3265,21 @@
   credentials.password_value = ASCIIToUTF16("password");
 
   // Simulate the user accepted a generated password.
-  EXPECT_CALL(MockFormSaver::Get(form_manager()),
-              PresaveGeneratedPassword(credentials));
+  EXPECT_CALL(MockFormSaver::Get(form_manager()), PresaveGeneratedPassword(_));
   form_manager()->PresaveGeneratedPassword(credentials);
   EXPECT_TRUE(form_manager()->HasGeneratedPassword());
   EXPECT_FALSE(form_manager()->generated_password_changed());
 
   // Simulate the user changed the presaved username.
   credentials.username_value = ASCIIToUTF16("new_username");
-  EXPECT_CALL(MockFormSaver::Get(form_manager()),
-              PresaveGeneratedPassword(credentials));
+  EXPECT_CALL(MockFormSaver::Get(form_manager()), PresaveGeneratedPassword(_));
   form_manager()->PresaveGeneratedPassword(credentials);
   EXPECT_TRUE(form_manager()->HasGeneratedPassword());
   EXPECT_FALSE(form_manager()->generated_password_changed());
 
   // Simulate the user changed the presaved password.
   credentials.password_value = ASCIIToUTF16("changed_password");
-  EXPECT_CALL(MockFormSaver::Get(form_manager()),
-              PresaveGeneratedPassword(credentials));
+  EXPECT_CALL(MockFormSaver::Get(form_manager()), PresaveGeneratedPassword(_));
   form_manager()->PresaveGeneratedPassword(credentials);
   EXPECT_TRUE(form_manager()->HasGeneratedPassword());
   EXPECT_TRUE(form_manager()->generated_password_changed());
@@ -4516,8 +4513,7 @@
   credentials.username_value = ASCIIToUTF16("new_user");
   credentials.password_value = ASCIIToUTF16("generatated_password");
 
-  EXPECT_CALL(MockFormSaver::Get(form_manager()),
-              PresaveGeneratedPassword(credentials));
+  EXPECT_CALL(MockFormSaver::Get(form_manager()), PresaveGeneratedPassword(_));
   form_manager()->PresaveGeneratedPassword(credentials);
 }
 
@@ -4534,9 +4530,12 @@
 
   PasswordForm credentials_without_username(credentials);
   credentials_without_username.username_value.clear();
-  EXPECT_CALL(MockFormSaver::Get(form_manager()),
-              PresaveGeneratedPassword(credentials_without_username));
+  PasswordForm actual;
+  EXPECT_CALL(MockFormSaver::Get(form_manager()), PresaveGeneratedPassword(_))
+      .WillOnce(SaveArg<0>(&actual));
   form_manager()->PresaveGeneratedPassword(credentials);
+  credentials_without_username.date_created = actual.date_created;
+  EXPECT_EQ(credentials_without_username, actual);
 }
 
 TEST_F(PasswordFormManagerTest, PresaveGeneratedPassword_EmptyUsername) {
@@ -4550,8 +4549,7 @@
   credentials.username_value.clear();
   credentials.password_value = ASCIIToUTF16("generatated_password");
 
-  EXPECT_CALL(MockFormSaver::Get(form_manager()),
-              PresaveGeneratedPassword(credentials));
+  EXPECT_CALL(MockFormSaver::Get(form_manager()), PresaveGeneratedPassword(_));
   form_manager()->PresaveGeneratedPassword(credentials);
 }
 
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc
index 7006db1..b02d694 100644
--- a/components/password_manager/core/browser/password_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -2178,18 +2178,23 @@
   PasswordForm sanitized_form(form);
   SanitizeFormData(&sanitized_form.form_data);
 
-  EXPECT_CALL(*store_, AddLogin(sanitized_form)).WillOnce(Return());
+  PasswordForm actual_form;
+  EXPECT_CALL(*store_, AddLogin(_)).WillOnce(SaveArg<0>(&actual_form));
   manager()->OnPresaveGeneratedPassword(&driver_, form);
+  EXPECT_NE(actual_form.date_created, base::Time());
+  sanitized_form.date_created = actual_form.date_created;
+  EXPECT_EQ(sanitized_form, actual_form);
 
   // The user updates the generated password.
   PasswordForm updated_form(form);
   updated_form.password_value = base::ASCIIToUTF16("password_12345");
   PasswordForm sanitized_updated_form(updated_form);
   SanitizeFormData(&sanitized_updated_form.form_data);
-  EXPECT_CALL(*store_,
-              UpdateLoginWithPrimaryKey(sanitized_updated_form, sanitized_form))
-      .WillOnce(Return());
+  EXPECT_CALL(*store_, UpdateLoginWithPrimaryKey(_, sanitized_form))
+      .WillOnce(SaveArg<0>(&actual_form));
   manager()->OnPresaveGeneratedPassword(&driver_, updated_form);
+  sanitized_updated_form.date_created = actual_form.date_created;
+  EXPECT_EQ(sanitized_updated_form, actual_form);
   histogram_tester.ExpectUniqueSample(
       "PasswordManager.GeneratedFormHasNoFormManager", false, 2);
 
@@ -2256,8 +2261,12 @@
     PasswordForm presaved_form(form);
     if (found_matched_logins_in_store)
       presaved_form.username_value.clear();
-    EXPECT_CALL(*store_, AddLogin(presaved_form)).WillOnce(Return());
+    PasswordForm actual_form;
+    EXPECT_CALL(*store_, AddLogin(_)).WillOnce(SaveArg<0>(&actual_form));
     manager()->OnPresaveGeneratedPassword(&driver_, form);
+    EXPECT_NE(actual_form.date_created, base::Time());
+    presaved_form.date_created = actual_form.date_created;
+    EXPECT_EQ(presaved_form, actual_form);
     ::testing::Mock::VerifyAndClearExpectations(store_.get());
 
     EXPECT_CALL(*store_, IsAbleToSavePasswords()).WillRepeatedly(Return(true));
diff --git a/components/password_manager/core/browser/password_ui_utils.cc b/components/password_manager/core/browser/password_ui_utils.cc
index 8e4cf6a..93b1993 100644
--- a/components/password_manager/core/browser/password_ui_utils.cc
+++ b/components/password_manager/core/browser/password_ui_utils.cc
@@ -8,11 +8,14 @@
 #include <string>
 #include <vector>
 
+#include "base/metrics/histogram_macros.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/common/password_form.h"
 #include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h"
+#include "components/password_manager/core/browser/password_form_manager_for_ui.h"
+#include "components/password_manager/core/browser/password_form_metrics_recorder.h"
 #include "components/url_formatter/elide_url.h"
 
 namespace password_manager {
@@ -71,4 +74,38 @@
                                                      : original;
 }
 
+void UpdatePasswordFormUsernameAndPassword(
+    const base::string16& username,
+    const base::string16& password,
+    PasswordFormManagerForUI* form_manager) {
+  const auto& pending_credentials = form_manager->GetPendingCredentials();
+  bool username_edited = pending_credentials.username_value != username;
+  bool password_changed = pending_credentials.password_value != password;
+  if (username_edited) {
+    form_manager->UpdateUsername(username);
+    if (form_manager->GetMetricsRecorder()) {
+      form_manager->GetMetricsRecorder()->RecordDetailedUserAction(
+          password_manager::PasswordFormMetricsRecorder::DetailedUserAction::
+              kEditedUsernameInBubble);
+    }
+  }
+  if (password_changed) {
+    form_manager->UpdatePasswordValue(password);
+    if (form_manager->GetMetricsRecorder()) {
+      form_manager->GetMetricsRecorder()->RecordDetailedUserAction(
+          password_manager::PasswordFormMetricsRecorder::DetailedUserAction::
+              kSelectedDifferentPasswordInBubble);
+    }
+  }
+
+  // Values of this histogram are a bit mask. Only the lower two bits are used:
+  // 0001 to indicate that the user has edited the username in the password save
+  // bubble.
+  // 0010 to indicate that the user has changed the password in the
+  // password save bubble.
+  // The maximum possible value is defined by OR-ing these values.
+  UMA_HISTOGRAM_ENUMERATION("PasswordManager.EditsInSaveBubble",
+                            username_edited + 2 * password_changed, 4);
+}
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_ui_utils.h b/components/password_manager/core/browser/password_ui_utils.h
index b4d98c8c..18a4fd7 100644
--- a/components/password_manager/core/browser/password_ui_utils.h
+++ b/components/password_manager/core/browser/password_ui_utils.h
@@ -20,6 +20,8 @@
 
 namespace password_manager {
 
+class PasswordFormManagerForUI;
+
 // Reverses order of labels in hostname.
 std::string SplitByDotAndReverse(base::StringPiece host);
 
@@ -41,6 +43,13 @@
 // |password_form|) and without prefixes "m.", "mobile." or "www.".
 std::string GetShownOrigin(const GURL& origin);
 
+// Updates the |form_manager| pending credentials with |username| and
+// |password|.
+void UpdatePasswordFormUsernameAndPassword(
+    const base::string16& username,
+    const base::string16& password,
+    PasswordFormManagerForUI* form_manager);
+
 }  // namespace password_manager
 
 #endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_UI_UTILS_H_
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index fcfb2c0..3ba1c52 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -15330,6 +15330,27 @@
 
       If this policy is not set, or if its value does not map to a Quick Fix Build, then the device won't be updated to a Quick Fix Build. If the device is already running a Quick Fix Build and the policy is not set anymore or its value does not map to a Quick Fix Build anymore, then the device will be updated to a regular build if the update is not blocked by another policy.''',
     },
+    {
+      'name': 'SamlInSessionPasswordChangeEnabled',
+      'type': 'main',
+      'schema': { 'type': 'boolean' },
+      'supported_on': ['chrome_os:76-'],
+      'future': True,
+      'tags': [],
+      'features': {
+        'dynamic_refresh': True,
+        'per_profile': False,
+      },
+      'example_value': True,
+      'id': 545,
+      'caption': '''Enables a page for in-session change of password for SAML users.''',
+      'desc': '''Enables a page at chrome://password-change that lets SAML users change their SAML passwords while in-session, which ensures that the SAML password and the device lockscreen password are kept in-sync.
+
+      This policy also enables notifications that warn SAML users if their SAML passwords are soon to expire so that they can deal with this immediately by doing an in-session password change.
+      But, these notifications will only be shown if password expiry information is sent to the device by the SAML identity provider during the SAML login flow.
+
+      If this policy is set, the user cannot change or override it.''',
+    },
   ],
 
   'messages': {
@@ -15495,5 +15516,5 @@
   },
   'placeholders': [],
   'deleted_policy_ids': [412],
-  'highest_id_currently_used':  544
+  'highest_id_currently_used':  545
 }
diff --git a/components/previews/content/BUILD.gn b/components/previews/content/BUILD.gn
index 70e8cc8..6c28495 100644
--- a/components/previews/content/BUILD.gn
+++ b/components/previews/content/BUILD.gn
@@ -8,6 +8,8 @@
     "hint_cache.h",
     "hint_cache_store.cc",
     "hint_cache_store.h",
+    "hint_update_data.cc",
+    "hint_update_data.h",
     "hints_fetcher.cc",
     "hints_fetcher.h",
     "previews_decider_impl.cc",
@@ -45,6 +47,7 @@
   sources = [
     "hint_cache_store_unittest.cc",
     "hint_cache_unittest.cc",
+    "hint_update_data_unittest.cc",
     "hints_fetcher_unittest.cc",
     "previews_decider_impl_unittest.cc",
     "previews_hints_unittest.cc",
diff --git a/components/previews/content/hint_cache_store.h b/components/previews/content/hint_cache_store.h
index b25b9cd..c5310dd5 100644
--- a/components/previews/content/hint_cache_store.h
+++ b/components/previews/content/hint_cache_store.h
@@ -139,6 +139,7 @@
 
  private:
   friend class HintCacheStoreTest;
+  friend class HintUpdateData;
 
   using EntryKeyPrefix = std::string;
   using EntryKeySet = std::unordered_set<EntryKey>;
diff --git a/components/previews/content/hint_update_data.cc b/components/previews/content/hint_update_data.cc
new file mode 100644
index 0000000..6375b14b
--- /dev/null
+++ b/components/previews/content/hint_update_data.cc
@@ -0,0 +1,84 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/previews/content/hint_update_data.h"
+
+#include "components/optimization_guide/proto/hints.pb.h"
+#include "components/previews/content/hint_cache_store.h"
+#include "components/previews/content/proto/hint_cache.pb.h"
+
+namespace previews {
+
+// static
+std::unique_ptr<HintUpdateData> HintUpdateData::CreateComponentHintUpdateData(
+    const base::Version& component_version) {
+  std::unique_ptr<HintUpdateData> update_data(
+      new HintUpdateData(base::Optional<base::Version>(component_version),
+                         base::Optional<base::Time>()));
+  return update_data;
+}
+
+// static
+std::unique_ptr<HintUpdateData> HintUpdateData::CreateFetchedHintUpdateData(
+    base::Time fetch_update_time) {
+  std::unique_ptr<HintUpdateData> update_data(
+      new HintUpdateData(base::Optional<base::Version>(),
+                         base::Optional<base::Time>(fetch_update_time)));
+  return update_data;
+}
+
+HintUpdateData::HintUpdateData(base::Optional<base::Version> component_version,
+                               base::Optional<base::Time> fetch_update_time)
+    : component_version_(component_version),
+      fetch_update_time_(fetch_update_time),
+      entries_to_save_(std::make_unique<EntryVector>()) {
+  DCHECK_NE(!component_version_, !fetch_update_time_);
+
+  if (component_version_.has_value()) {
+    hint_entry_key_prefix_ =
+        HintCacheStore::GetComponentHintEntryKeyPrefix(*component_version_);
+
+    // Add a component metadata entry for the component's version.
+    previews::proto::StoreEntry metadata_component_entry;
+    metadata_component_entry.set_version(component_version_->GetString());
+    entries_to_save_->emplace_back(
+        HintCacheStore::GetMetadataTypeEntryKey(
+            HintCacheStore::MetadataType::kComponent),
+        std::move(metadata_component_entry));
+  } else if (fetch_update_time_.has_value()) {
+    hint_entry_key_prefix_ =
+        // TODO(dougarnett): Merge in new call once landed:
+        // HintCacheStore::GetFetchedHintEntryKeyPrefix();
+        "3_";
+
+    // TODO(dougarnett): add metadata entry for Fetch update?
+  } else {
+    NOTREACHED();
+  }
+}
+
+HintUpdateData::~HintUpdateData() {}
+
+void HintUpdateData::MoveHintIntoUpdateData(
+    optimization_guide::proto::Hint&& hint) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(!hint_entry_key_prefix_.empty());
+
+  // To avoid any unnecessary copying, the hint is moved into proto::StoreEntry.
+  HintCacheStore::EntryKey hint_entry_key = hint_entry_key_prefix_ + hint.key();
+  previews::proto::StoreEntry entry_proto;
+  entry_proto.set_allocated_hint(
+      new optimization_guide::proto::Hint(std::move(hint)));
+  entries_to_save_->emplace_back(std::move(hint_entry_key),
+                                 std::move(entry_proto));
+}
+
+std::unique_ptr<EntryVector> HintUpdateData::TakeUpdateEntries() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(entries_to_save_);
+
+  return std::move(entries_to_save_);
+}
+
+}  // namespace previews
diff --git a/components/previews/content/hint_update_data.h b/components/previews/content/hint_update_data.h
new file mode 100644
index 0000000..7a6f153
--- /dev/null
+++ b/components/previews/content/hint_update_data.h
@@ -0,0 +1,85 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PREVIEWS_CONTENT_HINT_UPDATE_DATA_H_
+#define COMPONENTS_PREVIEWS_CONTENT_HINT_UPDATE_DATA_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/optional.h"
+#include "base/sequence_checker.h"
+#include "base/time/time.h"
+#include "base/version.h"
+#include "components/leveldb_proto/public/proto_database.h"
+
+namespace optimization_guide {
+namespace proto {
+class Hint;
+}  // namespace proto
+}  // namespace optimization_guide
+
+namespace previews {
+namespace proto {
+class StoreEntry;
+}  // namespace proto
+
+using EntryVector =
+    leveldb_proto::ProtoDatabase<previews::proto::StoreEntry>::KeyEntryVector;
+
+// Holds hint data for updating the HintCacheStore.
+class HintUpdateData {
+ public:
+  ~HintUpdateData();
+
+  // Creates an update data object for a component hint update.
+  static std::unique_ptr<HintUpdateData> CreateComponentHintUpdateData(
+      const base::Version& component_version);
+
+  // Creates an update data object for a fetched hint update.
+  static std::unique_ptr<HintUpdateData> CreateFetchedHintUpdateData(
+      base::Time fetch_update_time);
+
+  // Returns the component version of a component hint update.
+  const base::Optional<base::Version> component_version() const {
+    return component_version_;
+  }
+
+  // Returns the next update time for a fetched hint update.
+  const base::Optional<base::Time> fetch_update_time() const {
+    return fetch_update_time_;
+  }
+
+  // Moves |hint| into this update data. After MoveHintIntoUpdateData() is
+  // called, |hint| is no longer valid.
+  void MoveHintIntoUpdateData(optimization_guide::proto::Hint&& hint);
+
+  // Returns the store entry updates along with ownership to them.
+  std::unique_ptr<EntryVector> TakeUpdateEntries();
+
+ private:
+  HintUpdateData(base::Optional<base::Version> component_version,
+                 base::Optional<base::Time> fetch_update_time);
+
+  // The component version of the update data for a component update.
+  base::Optional<base::Version> component_version_;
+
+  // The time when hints in this update need to be updated for a fetch update.
+  base::Optional<base::Time> fetch_update_time_;
+
+  // The prefix to add to the key of every hint entry. It is set
+  // during construction for appropriate type of update.
+  std::string hint_entry_key_prefix_;
+
+  // The vector of entries to save.
+  std::unique_ptr<EntryVector> entries_to_save_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  DISALLOW_COPY_AND_ASSIGN(HintUpdateData);
+};
+
+}  // namespace previews
+
+#endif  // COMPONENTS_PREVIEWS_CONTENT_HINT_UPDATE_DATA_H_
diff --git a/components/previews/content/hint_update_data_unittest.cc b/components/previews/content/hint_update_data_unittest.cc
new file mode 100644
index 0000000..a177d1a
--- /dev/null
+++ b/components/previews/content/hint_update_data_unittest.cc
@@ -0,0 +1,70 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/previews/content/hint_update_data.h"
+
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "base/version.h"
+#include "components/optimization_guide/proto/hints.pb.h"
+#include "components/previews/content/proto/hint_cache.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace previews {
+
+namespace {
+
+TEST(HintUpdateDataTest, BuildComponentUpdateData) {
+  // Verify creating a Component Hint update package.
+  base::Version v1("1.2.3.4");
+  optimization_guide::proto::Hint hint1;
+  hint1.set_key("foo.org");
+  hint1.set_key_representation(optimization_guide::proto::HOST_SUFFIX);
+  optimization_guide::proto::PageHint* page_hint1 = hint1.add_page_hints();
+  page_hint1->set_page_pattern("slowpage");
+  optimization_guide::proto::Hint hint2;
+  hint2.set_key("bar.com");
+  hint2.set_key_representation(optimization_guide::proto::HOST_SUFFIX);
+  optimization_guide::proto::PageHint* page_hint2 = hint2.add_page_hints();
+  page_hint2->set_page_pattern("slowpagealso");
+
+  std::unique_ptr<HintUpdateData> component_update =
+      HintUpdateData::CreateComponentHintUpdateData(v1);
+  component_update->MoveHintIntoUpdateData(std::move(hint1));
+  component_update->MoveHintIntoUpdateData(std::move(hint2));
+  EXPECT_TRUE(component_update->component_version().has_value());
+  EXPECT_FALSE(component_update->fetch_update_time().has_value());
+  EXPECT_EQ(v1, *component_update->component_version());
+  // Verify there are 3 store entries: 1 for the metadata entry plus
+  // the 2 added hint entries.
+  EXPECT_EQ(3ul, component_update->TakeUpdateEntries()->size());
+}
+
+TEST(HintUpdateDataTest, BuildFetchUpdateData) {
+  // Verify creating a Fetched Hint update package.
+  base::Time update_time = base::Time::Now();
+  optimization_guide::proto::Hint hint1;
+  hint1.set_key("foo.org");
+  hint1.set_key_representation(optimization_guide::proto::HOST_SUFFIX);
+  optimization_guide::proto::PageHint* page_hint1 = hint1.add_page_hints();
+  page_hint1->set_page_pattern("slowpage");
+
+  std::unique_ptr<HintUpdateData> fetch_update =
+      HintUpdateData::CreateFetchedHintUpdateData(update_time);
+  fetch_update->MoveHintIntoUpdateData(std::move(hint1));
+  EXPECT_FALSE(fetch_update->component_version().has_value());
+  EXPECT_TRUE(fetch_update->fetch_update_time().has_value());
+  EXPECT_EQ(update_time, *fetch_update->fetch_update_time());
+  // Verify there are 2 store entries: 1 for the metadata entry plus
+  // the 1 added hint entries.
+  // TODO(dougarnett): Increase expected count once metadata support added.
+  EXPECT_EQ(1ul, fetch_update->TakeUpdateEntries()->size());
+}
+
+}  // namespace
+
+}  // namespace previews
diff --git a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css
index 59d5f17..f83991e 100644
--- a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css
+++ b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css
@@ -313,15 +313,6 @@
     transition: opacity 250ms cubic-bezier(0.4, 0, 0.2, 1);
   }
 
-  #details[hidden],
-  #information-container[hidden] {
-    display: block;
-    height: 0;
-    opacity: 0;
-    overflow: hidden;
-    transition: none;
-  }
-
   .details-button {
     padding-bottom: 16px;
     padding-top: 16px;
diff --git a/components/sync/base/DEPS b/components/sync/base/DEPS
index 1f826747..eca6939 100644
--- a/components/sync/base/DEPS
+++ b/components/sync/base/DEPS
@@ -10,5 +10,5 @@
   "+crypto",
   "+google/cacheinvalidation",
   "+third_party/zlib",  # For UniquePosition compression
-  "+net/base",
+  "+net",
 ]
diff --git a/components/sync/base/syncer_error.cc b/components/sync/base/syncer_error.cc
index 43496640..ede7462 100644
--- a/components/sync/base/syncer_error.cc
+++ b/components/sync/base/syncer_error.cc
@@ -5,7 +5,9 @@
 #include "components/sync/base/syncer_error.h"
 
 #include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
 #include "net/base/net_errors.h"
+#include "net/http/http_status_code.h"
 
 namespace syncer {
 
@@ -47,12 +49,38 @@
 
 }  // namespace
 
+SyncerError::SyncerError(Value value) : value_(value) {
+  // NETWORK_CONNECTION_UNAVAILABLE error must be created via the separate
+  // factory method NetworkConnectionUnavailable().
+  DCHECK_NE(value_, NETWORK_CONNECTION_UNAVAILABLE);
+  // SYNC_SERVER_ERROR and SYNC_AUTH_ERROR both correspond to HTTP errors, and
+  // must be created via HttpError().
+  DCHECK_NE(value_, SYNC_SERVER_ERROR);
+  DCHECK_NE(value_, SYNC_AUTH_ERROR);
+}
+
+// static
+SyncerError SyncerError::NetworkConnectionUnavailable(int net_error_code) {
+  return SyncerError(NETWORK_CONNECTION_UNAVAILABLE, net_error_code,
+                     /*http_status_code=*/0);
+}
+
+// static
+SyncerError SyncerError::HttpError(int http_status_code) {
+  return SyncerError((http_status_code == net::HTTP_UNAUTHORIZED)
+                         ? SYNC_AUTH_ERROR
+                         : SYNC_SERVER_ERROR,
+                     /*net_error_code=*/0, http_status_code);
+}
+
 std::string SyncerError::ToString() const {
-  if (value_ != NETWORK_CONNECTION_UNAVAILABLE) {
-    return GetSyncerErrorString(value_);
+  std::string result = GetSyncerErrorString(value_);
+  if (value_ == NETWORK_CONNECTION_UNAVAILABLE) {
+    result += " (" + net::ErrorToShortString(net_error_code_) + ")";
+  } else if (value_ == SYNC_SERVER_ERROR || value_ == SYNC_AUTH_ERROR) {
+    result += " (HTTP " + base::NumberToString(http_status_code_) + ")";
   }
-  return GetSyncerErrorString(value_) + " (" +
-         net::ErrorToShortString(net_error_code_) + ")";
+  return result;
 }
 
 bool SyncerError::IsActualError() const {
diff --git a/components/sync/base/syncer_error.h b/components/sync/base/syncer_error.h
index a6c9495..04edb6ed 100644
--- a/components/sync/base/syncer_error.h
+++ b/components/sync/base/syncer_error.h
@@ -25,6 +25,7 @@
     SYNC_AUTH_ERROR,                 // HTTP auth error.
 
     // Based on values returned by server.  Most are defined in sync.proto.
+    // TODO(crbug.com/951350): Unused, remove.
     SERVER_RETURN_INVALID_CREDENTIAL,
     SERVER_RETURN_UNKNOWN_ERROR,
     SERVER_RETURN_THROTTLED,
@@ -35,6 +36,7 @@
     SERVER_RETURN_CONFLICT,
     SERVER_RESPONSE_VALIDATION_FAILED,
     SERVER_RETURN_DISABLED_BY_ADMIN,
+    // TODO(crbug.com/951350): Unused, remove.
     SERVER_RETURN_USER_ROLLBACK,
     SERVER_RETURN_PARTIAL_FAILURE,
     SERVER_RETURN_CLIENT_DATA_OBSOLETE,
@@ -47,19 +49,14 @@
     SYNCER_OK
   };
 
-  constexpr SyncerError() : value_(UNSET), net_error_code_(0) {}
+  constexpr SyncerError() {}
+  // Note: NETWORK_CONNECTION_UNAVAILABLE, SYNC_SERVER_ERROR, and
+  // SYNC_AUTH_ERROR are *not* valid inputs for this constructor. These types
+  // of errors must be created via the factory functions below.
+  explicit SyncerError(Value value);
 
-  explicit constexpr SyncerError(Value value)
-      : value_(value), net_error_code_(0) {
-    // NETWORK_CONNECTION_UNAVAILABLE error must be created via the separate
-    // factory method NetworkConnectionUnavailable().
-    DCHECK_NE(value_, NETWORK_CONNECTION_UNAVAILABLE);
-  }
-
-  static constexpr SyncerError NetworkConnectionUnavailable(
-      int net_error_code) {
-    return SyncerError(NETWORK_CONNECTION_UNAVAILABLE, net_error_code);
-  }
+  static SyncerError NetworkConnectionUnavailable(int net_error_code);
+  static SyncerError HttpError(int http_status_code);
 
   Value value() const { return value_; }
 
@@ -70,11 +67,14 @@
   bool IsActualError() const;
 
  private:
-  constexpr SyncerError(Value value, int net_error_code)
-      : value_(value), net_error_code_(net_error_code) {}
+  constexpr SyncerError(Value value, int net_error_code, int http_status_code)
+      : value_(value),
+        net_error_code_(net_error_code),
+        http_status_code_(http_status_code) {}
 
-  Value value_;
-  int net_error_code_;
+  Value value_ = UNSET;
+  int net_error_code_ = 0;
+  int http_status_code_ = 0;
 };
 
 }  // namespace syncer
diff --git a/components/sync/engine_impl/backoff_delay_provider_unittest.cc b/components/sync/engine_impl/backoff_delay_provider_unittest.cc
index db5dff0..49104887 100644
--- a/components/sync/engine_impl/backoff_delay_provider_unittest.cc
+++ b/components/sync/engine_impl/backoff_delay_provider_unittest.cc
@@ -10,6 +10,7 @@
 #include "components/sync/engine/cycle/model_neutral_state.h"
 #include "components/sync/engine/polling_constants.h"
 #include "net/base/net_errors.h"
+#include "net/http/http_status_code.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using base::TimeDelta;
@@ -39,7 +40,8 @@
   std::unique_ptr<BackoffDelayProvider> delay(
       BackoffDelayProvider::FromDefaults());
   ModelNeutralState state;
-  state.last_get_key_result = SyncerError(SyncerError::SYNC_SERVER_ERROR);
+  state.last_get_key_result =
+      SyncerError::HttpError(net::HTTP_INTERNAL_SERVER_ERROR);
   EXPECT_EQ(kInitialBackoffRetrySeconds,
             delay->GetInitialDelay(state).InSeconds());
 
@@ -96,7 +98,8 @@
   std::unique_ptr<BackoffDelayProvider> delay(
       BackoffDelayProvider::WithShortInitialRetryOverride());
   ModelNeutralState state;
-  state.last_get_key_result = SyncerError(SyncerError::SYNC_SERVER_ERROR);
+  state.last_get_key_result =
+      SyncerError::HttpError(net::HTTP_INTERNAL_SERVER_ERROR);
   EXPECT_EQ(kInitialBackoffShortRetrySeconds,
             delay->GetInitialDelay(state).InSeconds());
 
diff --git a/components/sync/engine_impl/cycle/status_controller_unittest.cc b/components/sync/engine_impl/cycle/status_controller_unittest.cc
index 64b0da8..c90ca69 100644
--- a/components/sync/engine_impl/cycle/status_controller_unittest.cc
+++ b/components/sync/engine_impl/cycle/status_controller_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "components/sync/engine_impl/cycle/sync_cycle.h"
 #include "components/sync/test/engine/test_id_factory.h"
+#include "net/http/http_status_code.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace syncer {
@@ -20,7 +21,7 @@
   EXPECT_EQ(SyncerError::SYNCER_OK,
             status.model_neutral_state().last_download_updates_result.value());
 
-  status.set_commit_result(SyncerError(SyncerError::SYNC_AUTH_ERROR));
+  status.set_commit_result(SyncerError::HttpError(net::HTTP_UNAUTHORIZED));
   EXPECT_EQ(SyncerError::SYNC_AUTH_ERROR,
             status.model_neutral_state().commit_result.value());
 
diff --git a/components/sync/engine_impl/net/server_connection_manager.h b/components/sync/engine_impl/net/server_connection_manager.h
index aa41b48..cce4a3da 100644
--- a/components/sync/engine_impl/net/server_connection_manager.h
+++ b/components/sync/engine_impl/net/server_connection_manager.h
@@ -172,6 +172,11 @@
     return server_response_.net_error_code;
   }
 
+  inline int http_status_code() const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    return server_response_.http_status_code;
+  }
+
   const std::string client_id() const { return client_id_; }
 
   // Factory method to create an Connection object we can use for
@@ -194,7 +199,7 @@
  protected:
   inline std::string proto_sync_path() const { return proto_sync_path_; }
 
-  // Updates server_response_ and notifies listeners if the server status
+  // Updates |server_response_| and notifies listeners if the server status
   // changed.
   void SetServerResponse(const HttpResponse& server_response);
 
diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc
index 6649ffb..140f949 100644
--- a/components/sync/engine_impl/sync_manager_impl.cc
+++ b/components/sync/engine_impl/sync_manager_impl.cc
@@ -305,11 +305,6 @@
       std::move(backing_store), args->unrecoverable_error_handler,
       report_unrecoverable_error_function_, sync_encryption_handler_.get(),
       sync_encryption_handler_->GetCryptographerUnsafe());
-  share_.sync_credentials = args->credentials;
-
-  // UserShare is accessible to a lot of code that doesn't need access to the
-  // access token, so clear it from the UserShare.
-  share_.sync_credentials.access_token = "";
 
   DVLOG(1) << "Username: " << args->credentials.email;
   DVLOG(1) << "AccountId: " << args->credentials.account_id;
diff --git a/components/sync/engine_impl/syncer_proto_util.cc b/components/sync/engine_impl/syncer_proto_util.cc
index 2f090fc3..6706d02 100644
--- a/components/sync/engine_impl/syncer_proto_util.cc
+++ b/components/sync/engine_impl/syncer_proto_util.cc
@@ -104,7 +104,8 @@
 
 SyncerError ServerConnectionErrorAsSyncerError(
     const HttpResponse::ServerConnectionCode server_status,
-    int net_error_code) {
+    int net_error_code,
+    int http_status_code) {
   switch (server_status) {
     case HttpResponse::CONNECTION_UNAVAILABLE:
       return SyncerError::NetworkConnectionUnavailable(net_error_code);
@@ -112,10 +113,10 @@
       return SyncerError(SyncerError::NETWORK_IO_ERROR);
     case HttpResponse::SYNC_SERVER_ERROR:
       // This means the server returned a non-401 HTTP error.
-      return SyncerError(SyncerError::SYNC_SERVER_ERROR);
+      return SyncerError::HttpError(http_status_code);
     case HttpResponse::SYNC_AUTH_ERROR:
       // This means the server returned an HTTP 401 (unauthorized) error.
-      return SyncerError(SyncerError::SYNC_AUTH_ERROR);
+      return SyncerError::HttpError(http_status_code);
     case HttpResponse::SERVER_CONNECTION_OK:
     case HttpResponse::NONE:
     default:
@@ -467,8 +468,8 @@
     DCHECK_NE(server_status, HttpResponse::SERVER_CONNECTION_OK);
 
     return ServerConnectionErrorAsSyncerError(
-        server_status,
-        cycle->context()->connection_manager()->net_error_code());
+        server_status, cycle->context()->connection_manager()->net_error_code(),
+        cycle->context()->connection_manager()->http_status_code());
   }
   LogClientToServerResponse(*response);
 
diff --git a/components/sync/syncable/user_share.h b/components/sync/syncable/user_share.h
index 40e1975..ad010e66 100644
--- a/components/sync/syncable/user_share.h
+++ b/components/sync/syncable/user_share.h
@@ -6,9 +6,6 @@
 #define COMPONENTS_SYNC_SYNCABLE_USER_SHARE_H_
 
 #include <memory>
-#include <string>
-
-#include "components/sync/engine/sync_credentials.h"
 
 namespace syncer {
 
@@ -26,11 +23,6 @@
 
   // The Directory itself, which is the parent of Transactions.
   std::unique_ptr<syncable::Directory> directory;
-
-  // The credentials used by sync when talking to the sync server.
-  //
-  // Note: some or all of the sync_credentials fields may be empty.
-  SyncCredentials sync_credentials;
 };
 
 }  // namespace syncer
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
index 16e2e79..1fa6b8b3 100644
--- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
+++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-b40bf386e25ce91aafc019d40a661189a7a47843
\ No newline at end of file
+39fa511aadaac5698e0b3e5cbe5048c67a65a2eb
\ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
index a8129bb..2c45471 100644
--- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
+++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-ab606d4139fae91bf4f73f28b6a521ed3eec2a61
\ No newline at end of file
+eff215b2df47cdcde486b64911f874112476cedd
\ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
index 0724fbd47..80c59a3 100644
--- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
+++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-34a24dac8faed5c449b3cefa771251322048d5ae
\ No newline at end of file
+a83f38ff015b54d6c44c7b3469ecec711a771218
\ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
index 0e636c0..3f01627 100644
--- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
+++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-05c4244fd0044437c4b39dbf30ddedd9af27b72b
\ No newline at end of file
+4dfeebd17cd6bdc47bf5721a198b414a80081548
\ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-25.png.sha1
index b1127d8..266edb3 100644
--- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-25.png.sha1
+++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-1d39625008d14a1b6205b8163e9966b359863be6
\ No newline at end of file
+8c8b2ccdd9c67d3eeb58a2e8b5695bfb035c0173
\ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-26.png.sha1
index 4ef0b181..075bc11 100644
--- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-26.png.sha1
+++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-d4f9cbe2b0d12c55807fdafef90e7c4823563843
\ No newline at end of file
+a3a0894dcae57e0b619d3dfae4e2dcc244d03ad2
\ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-25.png.sha1
index 146dd944..1f6b55b8 100644
--- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-25.png.sha1
+++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-dba7354dd9ee806e6d147a11e6ac47c948c4cf4e
\ No newline at end of file
+8d5871d82eac0fd7cae759e1aa6232f75d508018
\ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-26.png.sha1
index cde34b2..8a8d5dc 100644
--- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-26.png.sha1
+++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-80d577d491ec4ff26236829dc864ec8d5e9dac33
\ No newline at end of file
+c6889ab587ebf97338206d4a2d496c1e587f096f
\ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
index 8d5d31e..23066645 100644
--- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
+++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-e64e29cd5895cdae8a876522ffa1e96887ee3a98
\ No newline at end of file
+97da7a119bb4434f7a67b82763d7cd5689748101
\ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
index acd6318..2fb9c11 100644
--- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
+++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-e663adf5c61e38ca5c28d8fc6d2bbd979e77245f
\ No newline at end of file
+6502add492f33d0e76660f6bd72999ef0eecc16f
\ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
index 73055c8..042e48f 100644
--- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
+++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-a7cf4544187917199e869ea4e0f6950d81ef0bf8
\ No newline at end of file
+7a4c548129116530661e27696a5e0dbae793bb9e
\ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
index 92d7ee75..24bc30a 100644
--- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
+++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-ae0c048df4c4179c85e13ce30c12543c9cea04bc
\ No newline at end of file
+2028868199c33d43de706c8607e3af64909784b7
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-25.png.sha1
index 8c837bc..e962bc35 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-25.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-578b0246815fdd37d5851dabae6aa84a4e4b4a23
\ No newline at end of file
+a07778983e1f124108e56837861fac2bd264dfe6
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-26.png.sha1
index 76888eb..052764e6 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-26.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-561610e9945cd3ff1b052f714189b474a4fa1e97
\ No newline at end of file
+aa638ae756981acc3f5100c64cab60ddddc8d73a
\ No newline at end of file
diff --git a/components/ukm/content/source_url_recorder_browsertest.cc b/components/ukm/content/source_url_recorder_browsertest.cc
index e61b3b2c..ff755a6 100644
--- a/components/ukm/content/source_url_recorder_browsertest.cc
+++ b/components/ukm/content/source_url_recorder_browsertest.cc
@@ -161,8 +161,9 @@
   EXPECT_NE(source->id(), ukm_entries[1]->source_id);
 }
 
+// Flaky on all OSes: https://crbug.com/951020
 IN_PROC_BROWSER_TEST_F(SourceUrlRecorderWebContentsObserverDownloadBrowserTest,
-                       IgnoreDownload) {
+                       DISABLED_IgnoreDownload) {
   GURL url(embedded_test_server()->GetURL("/download-test1.lib"));
   content::NavigationHandleObserver observer(shell()->web_contents(), url);
   content::NavigateToURL(shell(), url);
diff --git a/content/browser/fileapi/file_system_browsertest.cc b/content/browser/fileapi/file_system_browsertest.cc
index 3ff81a5a..863ac7c 100644
--- a/content/browser/fileapi/file_system_browsertest.cc
+++ b/content/browser/fileapi/file_system_browsertest.cc
@@ -11,6 +11,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
 #include "base/task/post_task.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/thread_test_helper.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/browser/browser_context.h"
@@ -22,6 +23,7 @@
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/shell/browser/shell.h"
+#include "storage/browser/fileapi/file_system_features.h"
 #include "storage/browser/quota/quota_manager.h"
 
 using storage::QuotaManager;
@@ -30,11 +32,16 @@
 
 // This browser test is aimed towards exercising the File System API bindings
 // and the actual implementation that lives in the browser side.
-class FileSystemBrowserTest : public ContentBrowserTest {
+class FileSystemBrowserTest : public ContentBrowserTest,
+                              public testing::WithParamInterface<bool> {
  public:
-  FileSystemBrowserTest() {}
+  FileSystemBrowserTest() {
+    feature_list_.InitAndEnableFeature(
+        storage::features::kEnableFilesystemInIncognito);
+  }
 
-  void SimpleTest(const GURL& test_url, bool incognito = false) {
+  void SimpleTest(const GURL& test_url) {
+    const bool incognito = GetParam();
     // The test page will perform tests on FileAPI, then navigate to either
     // a #pass or #fail ref.
     Shell* the_browser = incognito ? CreateOffTheRecordBrowser() : shell();
@@ -52,8 +59,13 @@
       FAIL() << "Failed: " << js_result;
     }
   }
+
+ protected:
+  base::test::ScopedFeatureList feature_list_;
 };
 
+INSTANTIATE_TEST_SUITE_P(, FileSystemBrowserTest, ::testing::Bool());
+
 class FileSystemBrowserTestWithLowQuota : public FileSystemBrowserTest {
  public:
   void SetUpOnMainThread() override {
@@ -81,15 +93,21 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(FileSystemBrowserTest, RequestTest) {
+// TODO(https://crbug.com/93417): Expand the test after updating quota
+// managenent for in-memory implementation.
+INSTANTIATE_TEST_SUITE_P(,
+                         FileSystemBrowserTestWithLowQuota,
+                         ::testing::Values(false));
+
+IN_PROC_BROWSER_TEST_P(FileSystemBrowserTest, RequestTest) {
   SimpleTest(GetTestUrl("fileapi", "request_test.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(FileSystemBrowserTest, CreateTest) {
+IN_PROC_BROWSER_TEST_P(FileSystemBrowserTest, CreateTest) {
   SimpleTest(GetTestUrl("fileapi", "create_test.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(FileSystemBrowserTestWithLowQuota, QuotaTest) {
+IN_PROC_BROWSER_TEST_P(FileSystemBrowserTestWithLowQuota, QuotaTest) {
   SimpleTest(GetTestUrl("fileapi", "quota_test.html"));
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 9cafebc..35f0356 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -410,41 +410,15 @@
                                            int32_t routing_id,
                                            mojom::WidgetPtr widget,
                                            bool hidden)
-    : renderer_initialized_(false),
-      destroyed_(false),
-      delegate_(delegate),
-      owner_delegate_(nullptr),
+    : delegate_(delegate),
       process_(process),
       routing_id_(routing_id),
       clock_(base::DefaultTickClock::GetInstance()),
-      is_loading_(false),
       is_hidden_(hidden),
-      visual_properties_ack_pending_(false),
-      auto_resize_enabled_(false),
-      page_scale_factor_(1.f),
-      is_pinch_gesture_active_(false),
-      waiting_for_screen_rects_ack_(false),
-      is_unresponsive_(false),
-      in_flight_event_count_(0),
-      in_get_backing_store_(false),
-      text_direction_updated_(false),
-      text_direction_(blink::kWebTextDirectionLeftToRight),
-      text_direction_canceled_(false),
-      suppress_events_until_keydown_(false),
-      pending_mouse_lock_request_(false),
-      allow_privileged_mouse_lock_(false),
-      is_last_unlocked_by_target_(false),
-      has_touch_handler_(false),
-      is_in_touchpad_gesture_fling_(false),
       latency_tracker_(delegate_),
-      next_browser_snapshot_id_(1),
-      owned_by_render_frame_host_(false),
-      is_focused_(false),
       hung_renderer_delay_(TimeDelta::FromMilliseconds(kHungRendererDelayMs)),
       new_content_rendering_delay_(
           TimeDelta::FromMilliseconds(kNewContentRenderingDelayMs)),
-      current_content_source_id_(0),
-      monitoring_composition_info_(false),
       compositor_frame_sink_binding_(this),
       frame_token_message_queue_(
           std::make_unique<FrameTokenMessageQueue>(this)),
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index e6d6317..0cd8ae71 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -964,17 +964,17 @@
   // true if a renderer has once been valid. We use this flag to display a sad
   // tab only when we lose our renderer and not if a paint occurs during
   // initialization.
-  bool renderer_initialized_;
+  bool renderer_initialized_ = false;
 
   // True if |Destroy()| has been called.
-  bool destroyed_;
+  bool destroyed_ = false;
 
   // Our delegate, which wants to know mainly about keyboard events.
   // It will remain non-NULL until DetachDelegate() is called.
   RenderWidgetHostDelegate* delegate_;
 
   // The delegate of the owner of this object.
-  RenderWidgetHostOwnerDelegate* owner_delegate_;
+  RenderWidgetHostOwnerDelegate* owner_delegate_ = nullptr;
 
   // Created during construction and guaranteed never to be NULL, but its
   // channel may be NULL if the renderer crashed, so one must always check that.
@@ -987,7 +987,7 @@
   const base::TickClock* clock_;
 
   // Indicates whether a page is loading or not.
-  bool is_loading_;
+  bool is_loading_ = false;
 
   // Indicates whether a page is hidden or not. Need to call
   // process_->UpdateClientPriority when this value changes.
@@ -1008,14 +1008,14 @@
 #endif
 
   // True when waiting for visual_properties_ack.
-  bool visual_properties_ack_pending_;
+  bool visual_properties_ack_pending_ = false;
 
   // Visual properties that were most recently sent to the renderer.
   std::unique_ptr<VisualProperties> old_visual_properties_;
 
   // True if the render widget host should track the render widget's size as
   // opposed to visa versa.
-  bool auto_resize_enabled_;
+  bool auto_resize_enabled_ = false;
 
   // The minimum size for the render widget if auto-resize is enabled.
   gfx::Size min_size_for_auto_resize_;
@@ -1024,11 +1024,12 @@
   gfx::Size max_size_for_auto_resize_;
 
   // The page-scale factor of the main-frame.
-  float page_scale_factor_;
-  // True when the renderer is currently undergoing a pinch-zoom gesture.
-  bool is_pinch_gesture_active_;
+  float page_scale_factor_ = 1.f;
 
-  bool waiting_for_screen_rects_ack_;
+  // True when the renderer is currently undergoing a pinch-zoom gesture.
+  bool is_pinch_gesture_active_ = false;
+
+  bool waiting_for_screen_rects_ack_ = false;
   gfx::Rect last_view_screen_rect_;
   gfx::Rect last_window_screen_rect_;
 
@@ -1046,27 +1047,27 @@
   base::ObserverList<RenderWidgetHostObserver>::Unchecked observers_;
 
   // This is true if the renderer is currently unresponsive.
-  bool is_unresponsive_;
+  bool is_unresponsive_ = false;
 
   // This value denotes the number of input events yet to be acknowledged
   // by the renderer.
-  int in_flight_event_count_;
+  int in_flight_event_count_ = 0;
 
   // Flag to detect recursive calls to GetBackingStore().
-  bool in_get_backing_store_;
+  bool in_get_backing_store_ = false;
 
   // Used for UMA histogram logging to measure the time for a repaint view
   // operation to finish.
   base::TimeTicks repaint_start_time_;
 
   // Set when we update the text direction of the selected input element.
-  bool text_direction_updated_;
-  blink::WebTextDirection text_direction_;
+  bool text_direction_updated_ = false;
+  blink::WebTextDirection text_direction_ = blink::kWebTextDirectionLeftToRight;
 
   // Set when we cancel updating the text direction.
   // This flag also ignores succeeding update requests until we call
   // NotifyTextDirection().
-  bool text_direction_canceled_;
+  bool text_direction_canceled_ = false;
 
   // Indicates if Char and KeyUp events should be suppressed or not. Usually all
   // events are sent to the renderer directly in sequence. However, if a
@@ -1079,10 +1080,10 @@
   // the Char event generated by alt-2 may also activate a HTML element if its
   // accesskey happens to be "2", then the user may get confused when switching
   // back to the original tab, because the content may already have changed.
-  bool suppress_events_until_keydown_;
+  bool suppress_events_until_keydown_ = false;
 
-  bool pending_mouse_lock_request_;
-  bool allow_privileged_mouse_lock_;
+  bool pending_mouse_lock_request_ = false;
+  bool allow_privileged_mouse_lock_ = false;
 
   // Stores the keyboard keys to lock while waiting for a pending lock request.
   base::Optional<base::flat_set<ui::DomCode>> keyboard_keys_to_lock_;
@@ -1092,18 +1093,18 @@
   // Used when locking to indicate when a target application has voluntarily
   // unlocked and desires to relock the mouse. If the mouse is unlocked due
   // to ESC being pressed by the user, this will be false.
-  bool is_last_unlocked_by_target_;
+  bool is_last_unlocked_by_target_ = false;
 
   // Keeps track of whether the webpage has any touch event handler. If it does,
   // then touch events are sent to the renderer. Otherwise, the touch events are
   // not sent to the renderer.
-  bool has_touch_handler_;
+  bool has_touch_handler_ = false;
 
   // TODO(wjmaclean) Remove the code for supporting resending gesture events
   // when WebView transitions to OOPIF and BrowserPlugin is removed.
   // http://crbug.com/533069
   bool is_in_gesture_scroll_[blink::kWebGestureDeviceCount] = {false};
-  bool is_in_touchpad_gesture_fling_;
+  bool is_in_touchpad_gesture_fling_ = false;
 
   std::unique_ptr<SyntheticGestureController> synthetic_gesture_controller_;
 
@@ -1120,20 +1121,20 @@
 
   RenderWidgetHostLatencyTracker latency_tracker_;
 
-  int next_browser_snapshot_id_;
+  int next_browser_snapshot_id_ = 1;
   using PendingSnapshotMap = std::map<int, GetSnapshotFromBrowserCallback>;
   PendingSnapshotMap pending_browser_snapshots_;
   PendingSnapshotMap pending_surface_browser_snapshots_;
 
   // Indicates whether a RenderFramehost has ownership, in which case this
   // object does not self destroy.
-  bool owned_by_render_frame_host_;
+  bool owned_by_render_frame_host_ = false;
 
   // Indicates whether this RenderWidgetHost thinks is focused. This is trying
   // to match what the renderer process knows. It is different from
   // RenderWidgetHostView::HasFocus in that in that the focus request may fail,
   // causing HasFocus to return false when is_focused_ is true.
-  bool is_focused_;
+  bool is_focused_ = false;
 
   // Whether the view should send begin frame messages to its render widget.
   // This is state that may arrive before the view has been set and that must be
@@ -1157,12 +1158,12 @@
   // a no-op for non-top-level RenderWidgets, as that should always be zero.
   // TODO(kenrb, fsamuel): We should use SurfaceIDs for this purpose when they
   // are available in the renderer process. See https://crbug.com/695579.
-  uint32_t current_content_source_id_;
+  uint32_t current_content_source_id_ = 0;
 
   // When true, the RenderWidget is regularly sending updates regarding
   // composition info. It should only be true when there is a focused editable
   // node.
-  bool monitoring_composition_info_;
+  bool monitoring_composition_info_ = false;
 
   // This is the content_source_id of the latest frame received. This value is
   // compared against current_content_source_id_ to determine whether the
diff --git a/content/browser/webauth/authenticator_common.cc b/content/browser/webauth/authenticator_common.cc
index 1dca48e..028b6d5 100644
--- a/content/browser/webauth/authenticator_common.cc
+++ b/content/browser/webauth/authenticator_common.cc
@@ -807,15 +807,13 @@
     return;
   }
 
-  if (options->allow_credentials.empty()) {
-    if (!base::FeatureList::IsEnabled(device::kWebAuthResidentKeys) ||
-        !request_delegate_->SupportsResidentKeys()) {
+  if (options->allow_credentials.empty() &&
+      (!base::FeatureList::IsEnabled(device::kWebAuthResidentKeys) ||
+        !request_delegate_->SupportsResidentKeys())) {
       InvokeCallbackAndCleanup(
           std::move(callback),
           blink::mojom::AuthenticatorStatus::RESIDENT_CREDENTIALS_UNSUPPORTED);
       return;
-    }
-    need_account_selection_ = true;
   }
 
   if (options->appid) {
@@ -1182,15 +1180,14 @@
         request_delegate_->UpdateLastTransportUsed(*transport_used);
       }
 
-      if (need_account_selection_) {
+      if (response_data->size() == 1) {
+        OnAccountSelected(std::move(response_data->at(0)));
+      } else {
         request_delegate_->SelectAccount(
             std::move(*response_data),
             base::BindOnce(&AuthenticatorCommon::OnAccountSelected,
                            weak_factory_.GetWeakPtr()));
-        return;
       }
-
-      OnAccountSelected(std::move(response_data.value()[0]));
       return;
   }
   NOTREACHED();
@@ -1335,7 +1332,6 @@
   client_data_json_.clear();
   app_id_.reset();
   attestation_requested_ = false;
-  need_account_selection_ = false;
   error_awaiting_user_acknowledgement_ =
       blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR;
 }
diff --git a/content/browser/webauth/authenticator_common.h b/content/browser/webauth/authenticator_common.h
index 488be50..ac7534c 100644
--- a/content/browser/webauth/authenticator_common.h
+++ b/content/browser/webauth/authenticator_common.h
@@ -200,10 +200,6 @@
   std::string relying_party_id_;
   std::unique_ptr<base::OneShotTimer> timer_;
   base::Optional<std::string> app_id_;
-  // need_account_selection_ indicates if an empty allow-list was used, thus
-  // implying that an account selection dialog needs to be displayed to the user
-  // before returning any assertions.
-  bool need_account_selection_ = false;
   // awaiting_attestation_response_ is true if the embedder has been queried
   // about an attestsation decision and the response is still pending.
   bool awaiting_attestation_response_ = false;
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc
index e1559646..d6337e6 100644
--- a/content/browser/webauth/authenticator_impl_unittest.cc
+++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -3367,8 +3367,8 @@
   TestServiceManagerContext smc;
   AuthenticatorPtr authenticator = ConnectToAuthenticator();
   TestGetAssertionCallback callback_receiver;
-  test_client_.expected_accounts = "01020304:test@example.com:Test User";
-  test_client_.selected_user_id = {1, 2, 3, 4};
+  // |SelectAccount| should not be called when there's only a single response.
+  test_client_.expected_accounts = "<invalid>";
   authenticator->GetAssertion(get_credential_options(),
                               callback_receiver.callback());
   callback_receiver.WaitForCallback();
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
index af810c9d..cc0c146a 100644
--- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -29,14 +29,10 @@
         ['win', 'mac', 'linux'])
     self.Skip('WebglExtension_WEBGL_compressed_texture_s3tc_srgb',
         ['win', 'mac', 'linux'])
-    self.Skip('WebglExtension_WEBGL_multiview',
-        ['mac', 'linux', 'android'], bug=864524)
-    # The multiview extension is only expected to be supported through ANGLE.
-    self.Skip('WebglExtension_WEBGL_multiview',
-        ['win', 'no_passthrough'], bug=864524)
-    # # ANGLE's OpenGL backend supports multiview only on NVIDIA.
-    self.Skip('WebglExtension_WEBGL_multiview',
-        ['win', 'passthrough', 'opengl', 'intel'], bug=864524)
+    # Disabling all multiview checks temporarily while ANGLE side changes
+    # get merged in.
+    self.Skip('WebglExtension_OVR_multiview2',
+        ['win', 'mac', 'linux', 'android'], bug=864524)
     self.Skip('WebglExtension_EXT_disjoint_timer_query_webgl2',
         ['android'], bug=808744)
     self.Skip('WebglExtension_KHR_parallel_shader_compile',
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
index f2b5ff1..089b43fa 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -344,6 +344,8 @@
         ['win', ('amd', 0x699f), 'opengl'], bug=950123)
     self.Skip('conformance/glsl/samplers/glsl-function-texture2dprojlod.html',
         ['win', ('amd', 0x699f), 'opengl'], bug=950123)
+    self.Fail('conformance/reading/read-pixels-test.html',
+        ['win', ('amd', 0x699f), 'opengl'], bug=951771)
     self.Skip('conformance/rendering/line-rendering-quality.html',
         ['win', ('amd', 0x699f), 'opengl'], bug=950123)
 
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
index bd14ab3..f838853 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
@@ -181,6 +181,7 @@
         'EXT_texture_filter_anisotropic',
         'KHR_parallel_shader_compile',
         'OES_texture_float_linear',
+        'OVR_multiview2',
         'WEBGL_compressed_texture_astc',
         'WEBGL_compressed_texture_etc',
         'WEBGL_compressed_texture_etc1',
@@ -192,7 +193,6 @@
         'WEBGL_lose_context',
         'WEBGL_multi_draw',
         'WEBGL_multi_draw_instanced',
-        'WEBGL_multiview',
         'WEBGL_video_texture',
       ]
 
diff --git a/device/fido/BUILD.gn b/device/fido/BUILD.gn
index e5dd860c..d98b319 100644
--- a/device/fido/BUILD.gn
+++ b/device/fido/BUILD.gn
@@ -237,6 +237,7 @@
     ":fido",
     "//base",
     "//components/apdu",
+    "//components/cbor",
     "//testing/gmock",
   ]
 }
@@ -270,6 +271,7 @@
     ":fido",
     "//base",
     "//base:i18n",
+    "//components/cbor",
   ]
   seed_corpus = "response_data_fuzzer_corpus/"
   libfuzzer_options = [ "max_len=65537" ]
diff --git a/device/fido/ctap2_device_operation.h b/device/fido/ctap2_device_operation.h
index 527e6af..cc194b6 100644
--- a/device/fido/ctap2_device_operation.h
+++ b/device/fido/ctap2_device_operation.h
@@ -16,6 +16,12 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/optional.h"
+#include "base/strings/string_number_conversions.h"
+#include "components/cbor/diagnostic_writer.h"
+#include "components/cbor/reader.h"
+#include "components/cbor/values.h"
+#include "components/cbor/writer.h"
+#include "components/device_event_log/device_event_log.h"
 #include "device/fido/device_operation.h"
 #include "device/fido/device_response_converter.h"
 #include "device/fido/fido_constants.h"
@@ -23,16 +29,25 @@
 
 namespace device {
 
-// Represents per device logic for CTAP2 authenticators. Ctap2DeviceOperation
-// is owned by FidoTask, and thus |request| outlives Ctap2DeviceOperation.
+// Ctap2DeviceOperation performs a single request--response operation on a CTAP2
+// device. The |Request| class must implement an |EncodeToCBOR| method that
+// returns a pair of |CtapRequestCommand| and an optional CBOR |Value|.
+// The response will be parsed to CBOR and then further parsed into a |Response|
+// using a provided callback.
 template <class Request, class Response>
 class Ctap2DeviceOperation : public DeviceOperation<Request, Response> {
  public:
+  // DeviceResponseCallback is either called with a |kSuccess| and a |Response|
+  // object, or else is called with a value other than |kSuccess| and
+  // |nullopt|.
   using DeviceResponseCallback =
       base::OnceCallback<void(CtapDeviceResponseCode,
                               base::Optional<Response>)>;
-  using DeviceResponseParser =
-      base::OnceCallback<base::Optional<Response>(base::span<const uint8_t>)>;
+  // DeviceResponseParser converts a generic CBOR structure into an
+  // operation-specific response. If the response didn't have a payload then the
+  // argument will be |nullopt|. The parser should return |nullopt| on error.
+  using DeviceResponseParser = base::OnceCallback<base::Optional<Response>(
+      const base::Optional<cbor::Value>&)>;
 
   Ctap2DeviceOperation(FidoDevice* device,
                        Request request,
@@ -47,8 +62,30 @@
   ~Ctap2DeviceOperation() override = default;
 
   void Start() override {
+    std::pair<CtapRequestCommand, base::Optional<cbor::Value>> request(
+        this->request().EncodeAsCBOR());
+    std::vector<uint8_t> request_bytes;
+
+    // TODO: it would be nice to see which device each request is going to, but
+    // that breaks every mock test because they aren't expecting a call to
+    // GetId().
+    if (request.second) {
+      FIDO_LOG(DEBUG) << "<- " << static_cast<int>(request.first) << " "
+                      << cbor::DiagnosticWriter::Write(*request.second);
+      base::Optional<std::vector<uint8_t>> cbor_bytes =
+          cbor::Writer::Write(*request.second);
+      DCHECK(cbor_bytes);
+      request_bytes = std::move(*cbor_bytes);
+    } else {
+      FIDO_LOG(DEBUG) << "<- " << static_cast<int>(request.first)
+                      << " (no payload)";
+    }
+
+    request_bytes.insert(request_bytes.begin(),
+                         static_cast<uint8_t>(request.first));
+
     this->token_ = this->device()->DeviceTransact(
-        this->request().EncodeAsCBOR(),
+        std::move(request_bytes),
         base::BindOnce(&Ctap2DeviceOperation::OnResponseReceived,
                        weak_factory_.GetWeakPtr()));
   }
@@ -57,16 +94,65 @@
       base::Optional<std::vector<uint8_t>> device_response) {
     this->token_.reset();
 
+    // TODO: it would be nice to see which device each response is coming from,
+    // but that breaks every mock test because they aren't expecting a call to
+    // GetId().
     if (!device_response) {
+      FIDO_LOG(ERROR) << "-> (error reading)";
       std::move(this->callback())
           .Run(CtapDeviceResponseCode::kCtap2ErrOther, base::nullopt);
       return;
     }
 
-    const auto response_code = GetResponseCode(*device_response);
-    std::move(this->callback())
-        .Run(response_code, std::move(device_response_parser_)
-                                .Run(std::move(*device_response)));
+    auto response_code = GetResponseCode(*device_response);
+    if (response_code != CtapDeviceResponseCode::kSuccess) {
+      FIDO_LOG(DEBUG) << "-> (CTAP2 error code "
+                      << static_cast<int>(response_code) << ")";
+      std::move(this->callback()).Run(response_code, base::nullopt);
+      return;
+    }
+    DCHECK(!device_response->empty());
+
+    base::Optional<cbor::Value> cbor;
+    base::Optional<Response> response;
+    base::span<const uint8_t> cbor_bytes(*device_response);
+    cbor_bytes = cbor_bytes.subspan(1);
+
+    if (!cbor_bytes.empty()) {
+      cbor::Reader::DecoderError error;
+      cbor = cbor::Reader::Read(cbor_bytes, &error);
+      if (!cbor) {
+        FIDO_LOG(ERROR) << "-> (CBOR parse error " << static_cast<int>(error)
+                        << " from "
+                        << base::HexEncode(device_response->data(),
+                                           device_response->size())
+                        << ")";
+        std::move(this->callback())
+            .Run(CtapDeviceResponseCode::kCtap2ErrInvalidCBOR, base::nullopt);
+        return;
+      }
+
+      response = std::move(std::move(device_response_parser_).Run(cbor));
+      if (response) {
+        FIDO_LOG(DEBUG) << "-> " << cbor::DiagnosticWriter::Write(*cbor);
+      } else {
+        FIDO_LOG(ERROR) << "-> (rejected CBOR structure) "
+                        << cbor::DiagnosticWriter::Write(*cbor);
+      }
+    } else {
+      response =
+          std::move(std::move(device_response_parser_).Run(base::nullopt));
+      if (response) {
+        FIDO_LOG(DEBUG) << "-> (empty payload)";
+      } else {
+        FIDO_LOG(ERROR) << "-> (rejected empty payload)";
+      }
+    }
+
+    if (!response) {
+      response_code = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
+    }
+    std::move(this->callback()).Run(response_code, std::move(response));
   }
 
  private:
diff --git a/device/fido/ctap_get_assertion_request.cc b/device/fido/ctap_get_assertion_request.cc
index afc89f9..32fb4ac7 100644
--- a/device/fido/ctap_get_assertion_request.cc
+++ b/device/fido/ctap_get_assertion_request.cc
@@ -36,7 +36,8 @@
 
 CtapGetAssertionRequest::~CtapGetAssertionRequest() = default;
 
-std::vector<uint8_t> CtapGetAssertionRequest::EncodeAsCBOR() const {
+std::pair<CtapRequestCommand, base::Optional<cbor::Value>>
+CtapGetAssertionRequest::EncodeAsCBOR() const {
   cbor::Value::MapValue cbor_map;
   cbor_map[cbor::Value(1)] = cbor::Value(rp_id_);
   cbor_map[cbor::Value(2)] = cbor::Value(client_data_hash_);
@@ -74,14 +75,8 @@
     cbor_map[cbor::Value(5)] = cbor::Value(std::move(option_map));
   }
 
-  auto serialized_param = cbor::Writer::Write(cbor::Value(std::move(cbor_map)));
-  DCHECK(serialized_param);
-
-  std::vector<uint8_t> cbor_request({base::strict_cast<uint8_t>(
-      CtapRequestCommand::kAuthenticatorGetAssertion)});
-  cbor_request.insert(cbor_request.end(), serialized_param->begin(),
-                      serialized_param->end());
-  return cbor_request;
+  return std::make_pair(CtapRequestCommand::kAuthenticatorGetAssertion,
+                        cbor::Value(std::move(cbor_map)));
 }
 
 CtapGetAssertionRequest& CtapGetAssertionRequest::SetUserVerification(
@@ -136,9 +131,10 @@
           response_rp_id_hash == *alternative_application_parameter());
 }
 
-std::vector<uint8_t> CtapGetNextAssertionRequest::EncodeAsCBOR() const {
-  return {
-      static_cast<uint8_t>(CtapRequestCommand::kAuthenticatorGetNextAssertion)};
+std::pair<CtapRequestCommand, base::Optional<cbor::Value>>
+CtapGetNextAssertionRequest::EncodeAsCBOR() const {
+  return std::make_pair(CtapRequestCommand::kAuthenticatorGetNextAssertion,
+                        base::nullopt);
 }
 
 }  // namespace device
diff --git a/device/fido/ctap_get_assertion_request.h b/device/fido/ctap_get_assertion_request.h
index 9191ea6..d6131e0 100644
--- a/device/fido/ctap_get_assertion_request.h
+++ b/device/fido/ctap_get_assertion_request.h
@@ -20,6 +20,10 @@
 #include "device/fido/fido_constants.h"
 #include "device/fido/public_key_credential_descriptor.h"
 
+namespace cbor {
+class Value;
+}
+
 namespace device {
 
 // Object that encapsulates request parameters for AuthenticatorGetAssertion as
@@ -39,7 +43,8 @@
   // Serializes GetAssertion request parameter into CBOR encoded map with
   // integer keys and CBOR encoded values as defined by the CTAP spec.
   // https://drafts.fidoalliance.org/fido-2/latest/fido-client-to-authenticator-protocol-v2.0-wd-20180305.html#authenticatorGetAssertion
-  std::vector<uint8_t> EncodeAsCBOR() const;
+  std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR()
+      const;
 
   CtapGetAssertionRequest& SetUserVerification(
       UserVerificationRequirement user_verfication);
@@ -114,7 +119,8 @@
 
 class CtapGetNextAssertionRequest {
  public:
-  std::vector<uint8_t> EncodeAsCBOR() const;
+  std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR()
+      const;
 };
 
 }  // namespace device
diff --git a/device/fido/ctap_make_credential_request.cc b/device/fido/ctap_make_credential_request.cc
index b01aff6f..549a2b8 100644
--- a/device/fido/ctap_make_credential_request.cc
+++ b/device/fido/ctap_make_credential_request.cc
@@ -9,7 +9,7 @@
 #include <utility>
 
 #include "base/numerics/safe_conversions.h"
-#include "components/cbor/writer.h"
+#include "components/cbor/values.h"
 #include "device/fido/fido_constants.h"
 #include "device/fido/fido_parsing_utils.h"
 
@@ -41,7 +41,8 @@
 
 CtapMakeCredentialRequest::~CtapMakeCredentialRequest() = default;
 
-std::vector<uint8_t> CtapMakeCredentialRequest::EncodeAsCBOR() const {
+std::pair<CtapRequestCommand, base::Optional<cbor::Value>>
+CtapMakeCredentialRequest::EncodeAsCBOR() const {
   cbor::Value::MapValue cbor_map;
   cbor_map[cbor::Value(1)] = cbor::Value(client_data_hash_);
   cbor_map[cbor::Value(2)] = rp_.ConvertToCBOR();
@@ -86,14 +87,8 @@
     cbor_map[cbor::Value(7)] = cbor::Value(std::move(option_map));
   }
 
-  auto serialized_param = cbor::Writer::Write(cbor::Value(std::move(cbor_map)));
-  DCHECK(serialized_param);
-
-  std::vector<uint8_t> cbor_request({base::strict_cast<uint8_t>(
-      CtapRequestCommand::kAuthenticatorMakeCredential)});
-  cbor_request.insert(cbor_request.end(), serialized_param->begin(),
-                      serialized_param->end());
-  return cbor_request;
+  return std::make_pair(CtapRequestCommand::kAuthenticatorMakeCredential,
+                        cbor::Value(std::move(cbor_map)));
 }
 
 CtapMakeCredentialRequest&
diff --git a/device/fido/ctap_make_credential_request.h b/device/fido/ctap_make_credential_request.h
index 2554344..e51050b4 100644
--- a/device/fido/ctap_make_credential_request.h
+++ b/device/fido/ctap_make_credential_request.h
@@ -21,6 +21,10 @@
 #include "device/fido/public_key_credential_rp_entity.h"
 #include "device/fido/public_key_credential_user_entity.h"
 
+namespace cbor {
+class Value;
+}
+
 namespace device {
 
 // Object containing request parameters for AuthenticatorMakeCredential command
@@ -44,7 +48,8 @@
   // Serializes MakeCredential request parameter into CBOR encoded map with
   // integer keys and CBOR encoded values as defined by the CTAP spec.
   // https://drafts.fidoalliance.org/fido-2/latest/fido-client-to-authenticator-protocol-v2.0-wd-20180305.html#authenticatorMakeCredential
-  std::vector<uint8_t> EncodeAsCBOR() const;
+  std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR()
+      const;
 
   CtapMakeCredentialRequest& SetAuthenticatorAttachment(
       AuthenticatorAttachment authenticator_attachment);
diff --git a/device/fido/ctap_request_unittest.cc b/device/fido/ctap_request_unittest.cc
index 83a0c13c..31cc2b2 100644
--- a/device/fido/ctap_request_unittest.cc
+++ b/device/fido/ctap_request_unittest.cc
@@ -8,6 +8,7 @@
 #include "device/fido/fido_constants.h"
 #include "device/fido/fido_parsing_utils.h"
 #include "device/fido/fido_test_data.h"
+#include "device/fido/mock_fido_device.h"
 #include "device/fido/virtual_ctap2_device.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -30,10 +31,10 @@
       test_data::kClientDataJson, std::move(rp), std::move(user),
       PublicKeyCredentialParams({{CredentialType::kPublicKey, 7},
                                  {CredentialType::kPublicKey, 257}}));
-  auto serialized_data =
+  auto serialized_data = MockFidoDevice::EncodeCBORRequest(
       make_credential_param.SetResidentKeyRequired(true)
           .SetUserVerification(UserVerificationRequirement::kRequired)
-          .EncodeAsCBOR();
+          .EncodeAsCBOR());
   EXPECT_THAT(serialized_data, ::testing::ElementsAreArray(
                                    test_data::kCtapMakeCredentialRequest));
 }
@@ -63,7 +64,8 @@
       .SetUserPresenceRequired(false)
       .SetUserVerification(UserVerificationRequirement::kRequired);
 
-  auto serialized_data = get_assertion_req.EncodeAsCBOR();
+  auto serialized_data =
+      MockFidoDevice::EncodeCBORRequest(get_assertion_req.EncodeAsCBOR());
   EXPECT_THAT(serialized_data,
               ::testing::ElementsAreArray(
                   test_data::kTestComplexCtapGetAssertionRequest));
diff --git a/device/fido/ctap_response_fuzzer.cc b/device/fido/ctap_response_fuzzer.cc
index c3abf10..4bec69e 100644
--- a/device/fido/ctap_response_fuzzer.cc
+++ b/device/fido/ctap_response_fuzzer.cc
@@ -9,6 +9,7 @@
 
 #include "base/at_exit.h"
 #include "base/i18n/icu_util.h"
+#include "components/cbor/reader.h"
 #include "device/fido/authenticator_get_assertion_response.h"
 #include "device/fido/authenticator_get_info_response.h"
 #include "device/fido/authenticator_make_credential_response.h"
@@ -31,9 +32,10 @@
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   std::vector<uint8_t> input(data, data + size);
+  base::Optional<cbor::Value> input_cbor = cbor::Reader::Read(input);
   std::array<uint8_t, 32> relying_party_id_hash = {};
   auto response = device::ReadCTAPMakeCredentialResponse(
-      FidoTransportProtocol::kUsbHumanInterfaceDevice, input);
+      FidoTransportProtocol::kUsbHumanInterfaceDevice, input_cbor);
   if (response)
     response->EraseAttestationStatement(AttestationObject::AAGUID::kErase);
 
@@ -44,7 +46,7 @@
   if (response)
     response->EraseAttestationStatement(AttestationObject::AAGUID::kErase);
 
-  device::ReadCTAPGetAssertionResponse(input);
+  device::ReadCTAPGetAssertionResponse(input_cbor);
   std::vector<uint8_t> u2f_response_data(data, data + size);
   std::vector<uint8_t> key_handle(data, data + size);
   device::AuthenticatorGetAssertionResponse::CreateFromU2fSignResponse(
diff --git a/device/fido/ctap_response_unittest.cc b/device/fido/ctap_response_unittest.cc
index 8b48791..87edc93 100644
--- a/device/fido/ctap_response_unittest.cc
+++ b/device/fido/ctap_response_unittest.cc
@@ -313,6 +313,13 @@
   return fido_parsing_utils::Materialize(test_data::kU2fSignKeyHandle);
 }
 
+// DecodeCBOR parses a CBOR structure, ignoring the first byte of |in|, which is
+// assumed to be a CTAP2 status byte.
+base::Optional<cbor::Value> DecodeCBOR(base::span<const uint8_t> in) {
+  CHECK(!in.empty());
+  return cbor::Reader::Read(in.subspan(1));
+}
+
 }  // namespace
 
 // Leveraging example 4 of section 6.1 of the spec https://fidoalliance.org
@@ -321,7 +328,7 @@
 TEST(CTAPResponseTest, TestReadMakeCredentialResponse) {
   auto make_credential_response = ReadCTAPMakeCredentialResponse(
       FidoTransportProtocol::kUsbHumanInterfaceDevice,
-      test_data::kTestMakeCredentialResponse);
+      DecodeCBOR(test_data::kTestMakeCredentialResponse));
   ASSERT_TRUE(make_credential_response);
   auto cbor_attestation_object = cbor::Reader::Read(
       make_credential_response->GetCBOREncodedAttestationObject());
@@ -376,7 +383,7 @@
 TEST(CTAPResponseTest, TestMakeCredentialNoneAttestationResponse) {
   auto make_credential_response = ReadCTAPMakeCredentialResponse(
       FidoTransportProtocol::kUsbHumanInterfaceDevice,
-      test_data::kTestMakeCredentialResponse);
+      DecodeCBOR(test_data::kTestMakeCredentialResponse));
   ASSERT_TRUE(make_credential_response);
   make_credential_response->EraseAttestationStatement(
       AttestationObject::AAGUID::kErase);
@@ -387,8 +394,8 @@
 // Leveraging example 5 of section 6.1 of the CTAP spec.
 // https://fidoalliance.org/specs/fido-v2.0-rd-20170927/fido-client-to-authenticator-protocol-v2.0-rd-20170927.html
 TEST(CTAPResponseTest, TestReadGetAssertionResponse) {
-  auto get_assertion_response =
-      ReadCTAPGetAssertionResponse(test_data::kDeviceGetAssertionResponse);
+  auto get_assertion_response = ReadCTAPGetAssertionResponse(
+      DecodeCBOR(test_data::kDeviceGetAssertionResponse));
   ASSERT_TRUE(get_assertion_response);
   ASSERT_TRUE(get_assertion_response->num_credentials());
   EXPECT_EQ(*get_assertion_response->num_credentials(), 1u);
diff --git a/device/fido/device_response_converter.cc b/device/fido/device_response_converter.cc
index 40e6e67..bff3fe5 100644
--- a/device/fido/device_response_converter.cc
+++ b/device/fido/device_response_converter.cc
@@ -12,6 +12,7 @@
 #include "base/numerics/safe_conversions.h"
 #include "base/optional.h"
 #include "base/stl_util.h"
+#include "components/cbor/diagnostic_writer.h"
 #include "components/cbor/reader.h"
 #include "components/cbor/writer.h"
 #include "components/device_event_log/device_event_log.h"
@@ -53,15 +54,11 @@
 // checks for correct encoding format.
 base::Optional<AuthenticatorMakeCredentialResponse>
 ReadCTAPMakeCredentialResponse(FidoTransportProtocol transport_used,
-                               base::span<const uint8_t> buffer) {
-  if (buffer.size() <= kResponseCodeLength)
+                               const base::Optional<cbor::Value>& cbor) {
+  if (!cbor || !cbor->is_map())
     return base::nullopt;
 
-  base::Optional<CBOR> decoded_response = cbor::Reader::Read(buffer.subspan(1));
-  if (!decoded_response || !decoded_response->is_map())
-    return base::nullopt;
-
-  const auto& decoded_map = decoded_response->GetMap();
+  const auto& decoded_map = cbor->GetMap();
   auto it = decoded_map.find(CBOR(1));
   if (it == decoded_map.end() || !it->second.is_string())
     return base::nullopt;
@@ -88,16 +85,11 @@
 }
 
 base::Optional<AuthenticatorGetAssertionResponse> ReadCTAPGetAssertionResponse(
-    base::span<const uint8_t> buffer) {
-  if (buffer.size() <= kResponseCodeLength)
+    const base::Optional<cbor::Value>& cbor) {
+  if (!cbor || !cbor->is_map())
     return base::nullopt;
 
-  base::Optional<CBOR> decoded_response = cbor::Reader::Read(buffer.subspan(1));
-
-  if (!decoded_response || !decoded_response->is_map())
-    return base::nullopt;
-
-  auto& response_map = decoded_response->GetMap();
+  auto& response_map = cbor->GetMap();
 
   auto it = response_map.find(CBOR(2));
   if (it == response_map.end() || !it->second.is_bytestring())
@@ -155,6 +147,7 @@
   if (!decoded_response || !decoded_response->is_map())
     return base::nullopt;
 
+  FIDO_LOG(DEBUG) << "-> " << cbor::DiagnosticWriter::Write(*decoded_response);
   const auto& response_map = decoded_response->GetMap();
 
   auto it = response_map.find(CBOR(1));
diff --git a/device/fido/device_response_converter.h b/device/fido/device_response_converter.h
index 201a42e..bfd7b26 100644
--- a/device/fido/device_response_converter.h
+++ b/device/fido/device_response_converter.h
@@ -27,21 +27,20 @@
 COMPONENT_EXPORT(DEVICE_FIDO)
 CtapDeviceResponseCode GetResponseCode(base::span<const uint8_t> buffer);
 
-// De-serializes CBOR encoded response, checks for valid CBOR map formatting,
-// and converts response to AuthenticatorMakeCredentialResponse object with
-// CBOR map keys that conform to format of attestation object defined by the
-// WebAuthN spec : https://w3c.github.io/webauthn/#fig-attStructs
+// Converts |cbor| to an |AuthenticatorMakeCredentialResponse| using map keys
+// that conform to format of attestation object defined by the Webauthn spec:
+// https://w3c.github.io/webauthn/#fig-attStructs
 COMPONENT_EXPORT(DEVICE_FIDO)
 base::Optional<AuthenticatorMakeCredentialResponse>
 ReadCTAPMakeCredentialResponse(FidoTransportProtocol transport_used,
-                               base::span<const uint8_t> buffer);
+                               const base::Optional<cbor::Value>& cbor);
 
-// De-serializes CBOR encoded response to AuthenticatorGetAssertion /
-// AuthenticatorGetNextAssertion request to AuthenticatorGetAssertionResponse
-// object.
+// Converts |cbor|, the response to an |AuthenticatorGetAssertion| /
+// |AuthenticatorGetNextAssertion| request, to an
+// |AuthenticatorGetAssertionResponse|.
 COMPONENT_EXPORT(DEVICE_FIDO)
 base::Optional<AuthenticatorGetAssertionResponse> ReadCTAPGetAssertionResponse(
-    base::span<const uint8_t> buffer);
+    const base::Optional<cbor::Value>& cbor);
 
 // De-serializes CBOR encoded response to AuthenticatorGetInfo request to
 // AuthenticatorGetInfoResponse object.
diff --git a/device/fido/get_assertion_handler_unittest.cc b/device/fido/get_assertion_handler_unittest.cc
index 91766cb..1a3d33b 100644
--- a/device/fido/get_assertion_handler_unittest.cc
+++ b/device/fido/get_assertion_handler_unittest.cc
@@ -278,7 +278,8 @@
   auto device = MockFidoDevice::MakeCtapWithGetInfoExpectation(
       test_data::kTestGetInfoResponseWithoutUvSupport);
   device->ExpectRequestAndRespondWith(
-      MakeCredentialTask::GetTouchRequest(device.get()).EncodeAsCBOR(),
+      MockFidoDevice::EncodeCBORRequest(
+          MakeCredentialTask::GetTouchRequest(device.get()).EncodeAsCBOR()),
       test_data::kTestMakeCredentialResponse);
 
   discovery()->AddDevice(std::move(device));
diff --git a/device/fido/get_assertion_request_handler.cc b/device/fido/get_assertion_request_handler.cc
index be9043b..4cb6003 100644
--- a/device/fido/get_assertion_request_handler.cc
+++ b/device/fido/get_assertion_request_handler.cc
@@ -370,10 +370,6 @@
   DCHECK_LT(0u, remaining_responses_);
 
   state_ = State::kFinished;
-  if (status == CtapDeviceResponseCode::kSuccess && !response) {
-    status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
-  }
-
   if (status != CtapDeviceResponseCode::kSuccess) {
     OnAuthenticatorResponse(authenticator, status, base::nullopt);
     return;
@@ -434,10 +430,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
   DCHECK_EQ(state_, State::kGettingRetries);
 
-  if (status == CtapDeviceResponseCode::kSuccess && !response) {
-    status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
-  }
-
   if (status != CtapDeviceResponseCode::kSuccess) {
     state_ = State::kFinished;
     FidoReturnCode ret = FidoReturnCode::kAuthenticatorResponseInvalid;
@@ -479,10 +471,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
   DCHECK_EQ(State::kGetEphemeralKey, state_);
 
-  if (status == CtapDeviceResponseCode::kSuccess && !response) {
-    status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
-  }
-
   if (status != CtapDeviceResponseCode::kSuccess) {
     state_ = State::kFinished;
     std::move(completion_callback_)
@@ -512,10 +500,6 @@
     return;
   }
 
-  if (status == CtapDeviceResponseCode::kSuccess && !response) {
-    status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
-  }
-
   if (status != CtapDeviceResponseCode::kSuccess) {
     state_ = State::kFinished;
     FidoReturnCode ret;
diff --git a/device/fido/make_credential_handler_unittest.cc b/device/fido/make_credential_handler_unittest.cc
index b906ecf1..dd9971b 100644
--- a/device/fido/make_credential_handler_unittest.cc
+++ b/device/fido/make_credential_handler_unittest.cc
@@ -242,7 +242,8 @@
   auto device = MockFidoDevice::MakeCtapWithGetInfoExpectation(
       test_data::kTestGetInfoResponseWithoutUvSupport);
   device->ExpectRequestAndRespondWith(
-      MakeCredentialTask::GetTouchRequest(device.get()).EncodeAsCBOR(),
+      MockFidoDevice::EncodeCBORRequest(
+          MakeCredentialTask::GetTouchRequest(device.get()).EncodeAsCBOR()),
       test_data::kTestMakeCredentialResponse);
   discovery()->AddDevice(std::move(device));
 
@@ -328,7 +329,8 @@
   auto device = MockFidoDevice::MakeCtapWithGetInfoExpectation(
       test_data::kTestGetInfoResponseWithoutResidentKeySupport);
   device->ExpectRequestAndRespondWith(
-      MakeCredentialTask::GetTouchRequest(device.get()).EncodeAsCBOR(),
+      MockFidoDevice::EncodeCBORRequest(
+          MakeCredentialTask::GetTouchRequest(device.get()).EncodeAsCBOR()),
       test_data::kTestMakeCredentialResponse);
 
   discovery()->AddDevice(std::move(device));
diff --git a/device/fido/make_credential_request_handler.cc b/device/fido/make_credential_request_handler.cc
index d9a0be9..1e20ec10 100644
--- a/device/fido/make_credential_request_handler.cc
+++ b/device/fido/make_credential_request_handler.cc
@@ -361,10 +361,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
   DCHECK_EQ(state_, State::kGettingRetries);
 
-  if (status == CtapDeviceResponseCode::kSuccess && !response) {
-    status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
-  }
-
   if (status != CtapDeviceResponseCode::kSuccess) {
     state_ = State::kFinished;
     FidoReturnCode ret = FidoReturnCode::kAuthenticatorResponseInvalid;
@@ -390,10 +386,6 @@
   DCHECK(state_ == State::kGetEphemeralKey ||
          state_ == State::kGetEphemeralKeyForNewPIN);
 
-  if (status == CtapDeviceResponseCode::kSuccess && !response) {
-    status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
-  }
-
   if (status != CtapDeviceResponseCode::kSuccess) {
     state_ = State::kFinished;
     std::move(completion_callback_)
@@ -448,10 +440,6 @@
     return;
   }
 
-  if (status == CtapDeviceResponseCode::kSuccess && !response) {
-    status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
-  }
-
   if (status != CtapDeviceResponseCode::kSuccess) {
     state_ = State::kFinished;
     FidoReturnCode ret;
diff --git a/device/fido/mock_fido_device.cc b/device/fido/mock_fido_device.cc
index 3185606..99af57b 100644
--- a/device/fido/mock_fido_device.cc
+++ b/device/fido/mock_fido_device.cc
@@ -11,6 +11,7 @@
 #include "base/strings/strcat.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/apdu/apdu_response.h"
+#include "components/cbor/writer.h"
 #include "device/fido/device_response_converter.h"
 #include "device/fido/fido_constants.h"
 #include "device/fido/fido_parsing_utils.h"
@@ -65,6 +66,21 @@
   return device;
 }
 
+std::vector<uint8_t> MockFidoDevice::EncodeCBORRequest(
+    std::pair<CtapRequestCommand, base::Optional<cbor::Value>> request) {
+  std::vector<uint8_t> request_bytes;
+
+  if (request.second) {
+    base::Optional<std::vector<uint8_t>> cbor_bytes =
+        cbor::Writer::Write(*request.second);
+    DCHECK(cbor_bytes);
+    request_bytes = std::move(*cbor_bytes);
+  }
+  request_bytes.insert(request_bytes.begin(),
+                       static_cast<uint8_t>(request.first));
+  return request_bytes;
+}
+
 // Matcher to compare the fist byte of the incoming requests.
 MATCHER_P(IsCtap2Command, expected_command, "") {
   return !arg.empty() && arg[0] == base::strict_cast<uint8_t>(expected_command);
diff --git a/device/fido/mock_fido_device.h b/device/fido/mock_fido_device.h
index dbecfa67..28c7a34 100644
--- a/device/fido/mock_fido_device.h
+++ b/device/fido/mock_fido_device.h
@@ -21,6 +21,10 @@
 #include "device/fido/fido_transport_protocol.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
+namespace cbor {
+class Value;
+}
+
 namespace device {
 
 class MockFidoDevice : public ::testing::StrictMock<FidoDevice> {
@@ -46,6 +50,10 @@
   static std::unique_ptr<MockFidoDevice> MakeCtapWithGetInfoExpectation(
       base::Optional<base::span<const uint8_t>> get_info_response =
           base::nullopt);
+  // EncodeCBORRequest is a helper function for use with the |Expect*|
+  // functions, below, that take a serialised request.
+  static std::vector<uint8_t> EncodeCBORRequest(
+      std::pair<CtapRequestCommand, base::Optional<cbor::Value>> request);
 
   MockFidoDevice();
   MockFidoDevice(ProtocolVersion protocol_version,
diff --git a/device/fido/pin.cc b/device/fido/pin.cc
index 2d12008..307add2 100644
--- a/device/fido/pin.cc
+++ b/device/fido/pin.cc
@@ -40,10 +40,11 @@
          HasAtLeastFourCodepoints(pin);
 }
 
-// EncodePINCommand returns a serialised CTAP2 PIN command for the operation
-// |subcommand|. Additional elements of the top-level CBOR map can be added with
-// the optional |add_additional| callback.
-static std::vector<uint8_t> EncodePINCommand(
+// EncodePINCommand returns a CTAP2 PIN command for the operation |subcommand|.
+// Additional elements of the top-level CBOR map can be added with the optional
+// |add_additional| callback.
+static std::pair<CtapRequestCommand, base::Optional<cbor::Value>>
+EncodePINCommand(
     Subcommand subcommand,
     std::function<void(cbor::Value::MapValue*)> add_additional = nullptr) {
   cbor::Value::MapValue map;
@@ -55,14 +56,12 @@
     add_additional(&map);
   }
 
-  auto serialized = cbor::Writer::Write(cbor::Value(map));
-  serialized->insert(
-      serialized->begin(),
-      static_cast<uint8_t>(CtapRequestCommand::kAuthenticatorClientPin));
-  return *serialized;
+  return std::make_pair(CtapRequestCommand::kAuthenticatorClientPin,
+                        cbor::Value(std::move(map)));
 }
 
-std::vector<uint8_t> RetriesRequest::EncodeAsCBOR() const {
+std::pair<CtapRequestCommand, base::Optional<cbor::Value>>
+RetriesRequest::EncodeAsCBOR() const {
   return EncodePINCommand(Subcommand::kGetRetries);
 }
 
@@ -70,19 +69,11 @@
 
 // static
 base::Optional<RetriesResponse> RetriesResponse::Parse(
-    base::span<const uint8_t> buffer) {
-  // The response status code (the first byte) has already been processed by
-  // this point.
-  if (buffer.empty()) {
+    const base::Optional<cbor::Value>& cbor) {
+  if (!cbor || !cbor->is_map()) {
     return base::nullopt;
   }
-
-  base::Optional<cbor::Value> decoded_response =
-      cbor::Reader::Read(buffer.subspan(1));
-  if (!decoded_response || !decoded_response->is_map()) {
-    return base::nullopt;
-  }
-  const auto& response_map = decoded_response->GetMap();
+  const auto& response_map = cbor->GetMap();
 
   auto it =
       response_map.find(cbor::Value(static_cast<int>(ResponseKey::kRetries)));
@@ -100,7 +91,8 @@
   return ret;
 }
 
-std::vector<uint8_t> KeyAgreementRequest::EncodeAsCBOR() const {
+std::pair<CtapRequestCommand, base::Optional<cbor::Value>>
+KeyAgreementRequest::EncodeAsCBOR() const {
   return EncodePINCommand(Subcommand::kGetKeyAgreement);
 }
 
@@ -134,19 +126,11 @@
 
 // static
 base::Optional<KeyAgreementResponse> KeyAgreementResponse::Parse(
-    base::span<const uint8_t> buffer) {
-  // The response status code (the first byte) has already been processed by
-  // this point.
-  if (buffer.empty()) {
+    const base::Optional<cbor::Value>& cbor) {
+  if (!cbor || !cbor->is_map()) {
     return base::nullopt;
   }
-
-  base::Optional<cbor::Value> decoded_response =
-      cbor::Reader::Read(buffer.subspan(1));
-  if (!decoded_response || !decoded_response->is_map()) {
-    return base::nullopt;
-  }
-  const auto& response_map = decoded_response->GetMap();
+  const auto& response_map = cbor->GetMap();
 
   // The ephemeral key is encoded as a COSE structure.
   auto it = response_map.find(
@@ -289,7 +273,8 @@
   EVP_CIPHER_CTX_cleanup(&aes_ctx);
 }
 
-std::vector<uint8_t> SetRequest::EncodeAsCBOR() const {
+std::pair<CtapRequestCommand, base::Optional<cbor::Value>>
+SetRequest::EncodeAsCBOR() const {
   // See
   // https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#settingNewPin
   uint8_t shared_key[SHA256_DIGEST_LENGTH];
@@ -335,10 +320,12 @@
 
 // static
 base::Optional<EmptyResponse> EmptyResponse::Parse(
-    base::span<const uint8_t> buffer) {
-  // The response status code (the first byte) has already been processed by
-  // this point.
-  if (buffer.size() != 1) {
+    const base::Optional<cbor::Value>& cbor) {
+  // Yubikeys can return just the status byte, and no CBOR bytes, for the empty
+  // response, which will end up here with |cbor| being |nullopt|. This seems
+  // wrong, but is handled. (The response should, instead, encode an empty CBOR
+  // map.)
+  if (cbor && (!cbor->is_map() || !cbor->GetMap().empty())) {
     return base::nullopt;
   }
 
@@ -346,7 +333,8 @@
   return ret;
 }
 
-std::vector<uint8_t> ChangeRequest::EncodeAsCBOR() const {
+std::pair<CtapRequestCommand, base::Optional<cbor::Value>>
+ChangeRequest::EncodeAsCBOR() const {
   // See
   // https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#changingExistingPin
   uint8_t shared_key[SHA256_DIGEST_LENGTH];
@@ -389,8 +377,9 @@
       });
 }
 
-std::vector<uint8_t> ResetRequest::EncodeAsCBOR() const {
-  return {static_cast<uint8_t>(CtapRequestCommand::kAuthenticatorReset)};
+std::pair<CtapRequestCommand, base::Optional<cbor::Value>>
+ResetRequest::EncodeAsCBOR() const {
+  return std::make_pair(CtapRequestCommand::kAuthenticatorReset, base::nullopt);
 }
 
 TokenRequest::TokenRequest(const std::string& pin,
@@ -410,7 +399,8 @@
   return shared_key_;
 }
 
-std::vector<uint8_t> TokenRequest::EncodeAsCBOR() const {
+std::pair<CtapRequestCommand, base::Optional<cbor::Value>>
+TokenRequest::EncodeAsCBOR() const {
   static_assert((sizeof(pin_hash_) % AES_BLOCK_SIZE) == 0,
                 "pin_hash_ is not a multiple of the AES block size");
   uint8_t encrypted_pin[sizeof(pin_hash_)];
@@ -451,19 +441,11 @@
 
 base::Optional<TokenResponse> TokenResponse::Parse(
     std::array<uint8_t, 32> shared_key,
-    base::span<const uint8_t> buffer) {
-  // The response status code (the first byte) has already been processed by
-  // this point.
-  if (buffer.empty()) {
+    const base::Optional<cbor::Value>& cbor) {
+  if (!cbor || !cbor->is_map()) {
     return base::nullopt;
   }
-
-  base::Optional<cbor::Value> decoded_response =
-      cbor::Reader::Read(buffer.subspan(1));
-  if (!decoded_response || !decoded_response->is_map()) {
-    return base::nullopt;
-  }
-  const auto& response_map = decoded_response->GetMap();
+  const auto& response_map = cbor->GetMap();
 
   auto it =
       response_map.find(cbor::Value(static_cast<int>(ResponseKey::kPINToken)));
diff --git a/device/fido/pin.h b/device/fido/pin.h
index 3a59518..4cd0fae 100644
--- a/device/fido/pin.h
+++ b/device/fido/pin.h
@@ -43,13 +43,14 @@
 // RetriesRequest asks an authenticator for the number of remaining PIN attempts
 // before the device is locked.
 struct RetriesRequest {
-  std::vector<uint8_t> EncodeAsCBOR() const;
+  std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR()
+      const;
 };
 
 // RetriesResponse reflects an authenticator's response to a |RetriesRequest|.
 struct RetriesResponse {
   static base::Optional<RetriesResponse> Parse(
-      base::span<const uint8_t> buffer);
+      const base::Optional<cbor::Value>& cbor);
 
   // retries is the number of PIN attempts remaining before the authenticator
   // locks.
@@ -62,7 +63,8 @@
 // KeyAgreementRequest asks an authenticator for an ephemeral ECDH key for
 // encrypting PIN material in future requests.
 struct KeyAgreementRequest {
-  std::vector<uint8_t> EncodeAsCBOR() const;
+  std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR()
+      const;
 };
 
 // KeyAgreementResponse reflects an authenticator's response to a
@@ -70,7 +72,7 @@
 // authenticator's ephemeral key.
 struct KeyAgreementResponse {
   static base::Optional<KeyAgreementResponse> Parse(
-      base::span<const uint8_t> buffer);
+      const base::Optional<cbor::Value>& cbor);
   static base::Optional<KeyAgreementResponse> ParseFromCOSE(
       const cbor::Value::MapValue& cose_key);
 
@@ -89,7 +91,8 @@
   // IsValid(pin) must be true.
   SetRequest(const std::string& pin, const KeyAgreementResponse& peer_key);
 
-  std::vector<uint8_t> EncodeAsCBOR() const;
+  std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR()
+      const;
 
  private:
   const KeyAgreementResponse peer_key_;
@@ -97,7 +100,8 @@
 };
 
 struct EmptyResponse {
-  static base::Optional<EmptyResponse> Parse(base::span<const uint8_t> buffer);
+  static base::Optional<EmptyResponse> Parse(
+      const base::Optional<cbor::Value>& cbor);
 };
 
 // ChangeRequest changes the PIN on an authenticator that already has a PIN set.
@@ -109,7 +113,8 @@
                 const std::string& new_pin,
                 const KeyAgreementResponse& peer_key);
 
-  std::vector<uint8_t> EncodeAsCBOR() const;
+  std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR()
+      const;
 
  private:
   const KeyAgreementResponse peer_key_;
@@ -122,7 +127,8 @@
 // PIN-related command, but is generally used to reset a PIN and so is
 // included here.
 struct ResetRequest {
-  std::vector<uint8_t> EncodeAsCBOR() const;
+  std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR()
+      const;
 };
 
 using ResetResponse = EmptyResponse;
@@ -141,7 +147,8 @@
   // This is needed to decrypt the response.
   const std::array<uint8_t, 32>& shared_key() const;
 
-  std::vector<uint8_t> EncodeAsCBOR() const;
+  std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR()
+      const;
 
  private:
   std::array<uint8_t, 32> shared_key_;
@@ -158,8 +165,9 @@
   ~TokenResponse();
   TokenResponse(const TokenResponse&);
 
-  static base::Optional<TokenResponse> Parse(std::array<uint8_t, 32> shared_key,
-                                             base::span<const uint8_t> buffer);
+  static base::Optional<TokenResponse> Parse(
+      std::array<uint8_t, 32> shared_key,
+      const base::Optional<cbor::Value>& cbor);
 
   // PinAuth returns a pinAuth parameter for a request that will use the given
   // client-data hash.
diff --git a/device/fido/reset_request_handler.cc b/device/fido/reset_request_handler.cc
index 95962060..aecad53f 100644
--- a/device/fido/reset_request_handler.cc
+++ b/device/fido/reset_request_handler.cc
@@ -65,10 +65,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
   DCHECK(processed_touch_);
 
-  if (status == CtapDeviceResponseCode::kSuccess && !response) {
-    status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
-  }
-
   std::move(finished_callback_).Run(status);
 }
 
diff --git a/device/fido/set_pin_request_handler.cc b/device/fido/set_pin_request_handler.cc
index 6b60b30f..dfe179f 100644
--- a/device/fido/set_pin_request_handler.cc
+++ b/device/fido/set_pin_request_handler.cc
@@ -108,10 +108,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
   DCHECK_EQ(state_, State::kGettingRetries);
 
-  if (status == CtapDeviceResponseCode::kSuccess && !response) {
-    status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
-  }
-
   if (status != CtapDeviceResponseCode::kSuccess) {
     state_ = State::kFinished;
     finished_callback_.Run(status);
@@ -130,10 +126,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_);
   DCHECK_EQ(state_, State::kGetEphemeralKey);
 
-  if (status == CtapDeviceResponseCode::kSuccess && !response) {
-    status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR;
-  }
-
   if (status != CtapDeviceResponseCode::kSuccess) {
     state_ = State::kFinished;
     finished_callback_.Run(status);
diff --git a/fuchsia/BUILD.gn b/fuchsia/BUILD.gn
index 04cf728..5c84563 100644
--- a/fuchsia/BUILD.gn
+++ b/fuchsia/BUILD.gn
@@ -41,6 +41,7 @@
 
   public_deps = [
     ":web_fidl",
+    "//third_party/fuchsia-sdk/sdk:web",
   ]
 }
 
diff --git a/fuchsia/fidl/cast/cast_channel.fidl b/fuchsia/fidl/cast/cast_channel.fidl
index f6274a6f..8fb702e 100644
--- a/fuchsia/fidl/cast/cast_channel.fidl
+++ b/fuchsia/fidl/cast/cast_channel.fidl
@@ -5,12 +5,16 @@
 library chromium.cast;
 
 using chromium.web;
+using fuchsia.web;
 
 [Discoverable]
 protocol CastChannel {
   /// Receives an opened Cast |channel| from the Cast application.
-  /// The return callback is invoked when the service is ready to accept a new
-  /// Cast Channel. OnOpened() should not be called again until this happens.
+  /// Open() must not be called again until the preceding call has returned.
+  [Transitional="Transitional method to migrate the fuchsia.web API."]
+  Open(fuchsia.web.MessagePort channel) -> ();
+
+  // TODO(crbug.com/946732): Remove this once callers have migrated to Open().
   OnOpened(chromium.web.MessagePort channel) -> ();
 };
 
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h
index 99c6893..052b441e 100644
--- a/gpu/GLES2/gl2chromium_autogen.h
+++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -413,8 +413,8 @@
 #define glDestroyGpuFenceCHROMIUM GLES2_GET_FUN(DestroyGpuFenceCHROMIUM)
 #define glInvalidateReadbackBufferShadowDataCHROMIUM \
   GLES2_GET_FUN(InvalidateReadbackBufferShadowDataCHROMIUM)
-#define glFramebufferTextureMultiviewLayeredANGLE \
-  GLES2_GET_FUN(FramebufferTextureMultiviewLayeredANGLE)
+#define glFramebufferTextureMultiviewOVR \
+  GLES2_GET_FUN(FramebufferTextureMultiviewOVR)
 #define glMaxShaderCompilerThreadsKHR GLES2_GET_FUN(MaxShaderCompilerThreadsKHR)
 #define glCreateAndTexStorage2DSharedImageCHROMIUM \
   GLES2_GET_FUN(CreateAndTexStorage2DSharedImageCHROMIUM)
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 61cf9c14..255f6eb5 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -4261,11 +4261,11 @@
     'extension': 'MESA_framebuffer_flip_y',
     'extension_flag': 'mesa_framebuffer_flip_y',
   },
-  'FramebufferTextureMultiviewLayeredANGLE': {
-    'decoder_func': 'DoFramebufferTextureMultiviewLayeredANGLE',
+  'FramebufferTextureMultiviewOVR': {
+    'decoder_func': 'DoFramebufferTextureMultiviewOVR',
     'unit_test': False,
-    'extension': 'ANGLE_multiview',
-    'extension_flag': 'angle_multiview',
+    'extension': 'OVR_multiview2',
+    'extension_flag': 'ovr_multiview2',
     'trace_level': 1,
     'es3': True
   },
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index 6a04d6c5..1772133b 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1900,14 +1900,13 @@
 GLES2InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) {
   gles2::GetGLContext()->InvalidateReadbackBufferShadowDataCHROMIUM(buffer_id);
 }
-void GL_APIENTRY
-GLES2FramebufferTextureMultiviewLayeredANGLE(GLenum target,
-                                             GLenum attachment,
-                                             GLuint texture,
-                                             GLint level,
-                                             GLint baseViewIndex,
-                                             GLsizei numViews) {
-  gles2::GetGLContext()->FramebufferTextureMultiviewLayeredANGLE(
+void GL_APIENTRY GLES2FramebufferTextureMultiviewOVR(GLenum target,
+                                                     GLenum attachment,
+                                                     GLuint texture,
+                                                     GLint level,
+                                                     GLint baseViewIndex,
+                                                     GLsizei numViews) {
+  gles2::GetGLContext()->FramebufferTextureMultiviewOVR(
       target, attachment, texture, level, baseViewIndex, numViews);
 }
 void GL_APIENTRY GLES2MaxShaderCompilerThreadsKHR(GLuint count) {
@@ -3410,9 +3409,9 @@
             glInvalidateReadbackBufferShadowDataCHROMIUM),
     },
     {
-        "glFramebufferTextureMultiviewLayeredANGLE",
+        "glFramebufferTextureMultiviewOVR",
         reinterpret_cast<GLES2FunctionPointer>(
-            glFramebufferTextureMultiviewLayeredANGLE),
+            glFramebufferTextureMultiviewOVR),
     },
     {
         "glMaxShaderCompilerThreadsKHR",
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index dc77c30b..dbe1d60 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -3524,14 +3524,14 @@
   }
 }
 
-void FramebufferTextureMultiviewLayeredANGLE(GLenum target,
-                                             GLenum attachment,
-                                             GLuint texture,
-                                             GLint level,
-                                             GLint baseViewIndex,
-                                             GLsizei numViews) {
-  gles2::cmds::FramebufferTextureMultiviewLayeredANGLE* c =
-      GetCmdSpace<gles2::cmds::FramebufferTextureMultiviewLayeredANGLE>();
+void FramebufferTextureMultiviewOVR(GLenum target,
+                                    GLenum attachment,
+                                    GLuint texture,
+                                    GLint level,
+                                    GLint baseViewIndex,
+                                    GLsizei numViews) {
+  gles2::cmds::FramebufferTextureMultiviewOVR* c =
+      GetCmdSpace<gles2::cmds::FramebufferTextureMultiviewOVR>();
   if (c) {
     c->Init(target, attachment, texture, level, baseViewIndex, numViews);
   }
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index adfb552..dd25fd000 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1339,12 +1339,12 @@
 
 void InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) override;
 
-void FramebufferTextureMultiviewLayeredANGLE(GLenum target,
-                                             GLenum attachment,
-                                             GLuint texture,
-                                             GLint level,
-                                             GLint baseViewIndex,
-                                             GLsizei numViews) override;
+void FramebufferTextureMultiviewOVR(GLenum target,
+                                    GLenum attachment,
+                                    GLuint texture,
+                                    GLint level,
+                                    GLint baseViewIndex,
+                                    GLsizei numViews) override;
 
 void MaxShaderCompilerThreadsKHR(GLuint count) override;
 
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
index 13b3676..123fcfe0 100644
--- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -3790,26 +3790,25 @@
   CheckGLError();
 }
 
-void GLES2Implementation::FramebufferTextureMultiviewLayeredANGLE(
-    GLenum target,
-    GLenum attachment,
-    GLuint texture,
-    GLint level,
-    GLint baseViewIndex,
-    GLsizei numViews) {
+void GLES2Implementation::FramebufferTextureMultiviewOVR(GLenum target,
+                                                         GLenum attachment,
+                                                         GLuint texture,
+                                                         GLint level,
+                                                         GLint baseViewIndex,
+                                                         GLsizei numViews) {
   GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG(
-      "[" << GetLogPrefix() << "] glFramebufferTextureMultiviewLayeredANGLE("
-          << GLES2Util::GetStringEnum(target) << ", "
-          << GLES2Util::GetStringEnum(attachment) << ", " << texture << ", "
-          << level << ", " << baseViewIndex << ", " << numViews << ")");
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFramebufferTextureMultiviewOVR("
+                     << GLES2Util::GetStringEnum(target) << ", "
+                     << GLES2Util::GetStringEnum(attachment) << ", " << texture
+                     << ", " << level << ", " << baseViewIndex << ", "
+                     << numViews << ")");
   if (numViews < 0) {
-    SetGLError(GL_INVALID_VALUE, "glFramebufferTextureMultiviewLayeredANGLE",
+    SetGLError(GL_INVALID_VALUE, "glFramebufferTextureMultiviewOVR",
                "numViews < 0");
     return;
   }
-  helper_->FramebufferTextureMultiviewLayeredANGLE(
-      target, attachment, texture, level, baseViewIndex, numViews);
+  helper_->FramebufferTextureMultiviewOVR(target, attachment, texture, level,
+                                          baseViewIndex, numViews);
   CheckGLError();
 }
 
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
index b14a3e39..bc43ccd 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -3227,14 +3227,14 @@
   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
 }
 
-TEST_F(GLES2ImplementationTest, FramebufferTextureMultiviewLayeredANGLE) {
+TEST_F(GLES2ImplementationTest, FramebufferTextureMultiviewOVR) {
   struct Cmds {
-    cmds::FramebufferTextureMultiviewLayeredANGLE cmd;
+    cmds::FramebufferTextureMultiviewOVR cmd;
   };
   Cmds expected;
   expected.cmd.Init(1, 2, 3, 4, 5, 6);
 
-  gl_->FramebufferTextureMultiviewLayeredANGLE(1, 2, 3, 4, 5, 6);
+  gl_->FramebufferTextureMultiviewOVR(1, 2, 3, 4, 5, 6);
   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
 }
 
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h
index addc988..dcf283b6 100644
--- a/gpu/command_buffer/client/gles2_interface_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -1007,12 +1007,12 @@
 virtual void WaitGpuFenceCHROMIUM(GLuint gpu_fence_id) = 0;
 virtual void DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) = 0;
 virtual void InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) = 0;
-virtual void FramebufferTextureMultiviewLayeredANGLE(GLenum target,
-                                                     GLenum attachment,
-                                                     GLuint texture,
-                                                     GLint level,
-                                                     GLint baseViewIndex,
-                                                     GLsizei numViews) = 0;
+virtual void FramebufferTextureMultiviewOVR(GLenum target,
+                                            GLenum attachment,
+                                            GLuint texture,
+                                            GLint level,
+                                            GLint baseViewIndex,
+                                            GLsizei numViews) = 0;
 virtual void MaxShaderCompilerThreadsKHR(GLuint count) = 0;
 virtual GLuint CreateAndTexStorage2DSharedImageCHROMIUM(
     const GLbyte* mailbox) = 0;
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
index ae86d59..bd728ed 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -977,12 +977,12 @@
 void WaitGpuFenceCHROMIUM(GLuint gpu_fence_id) override;
 void DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) override;
 void InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) override;
-void FramebufferTextureMultiviewLayeredANGLE(GLenum target,
-                                             GLenum attachment,
-                                             GLuint texture,
-                                             GLint level,
-                                             GLint baseViewIndex,
-                                             GLsizei numViews) override;
+void FramebufferTextureMultiviewOVR(GLenum target,
+                                    GLenum attachment,
+                                    GLuint texture,
+                                    GLint level,
+                                    GLint baseViewIndex,
+                                    GLsizei numViews) override;
 void MaxShaderCompilerThreadsKHR(GLuint count) override;
 GLuint CreateAndTexStorage2DSharedImageCHROMIUM(const GLbyte* mailbox) override;
 GLuint CreateAndTexStorage2DSharedImageWithInternalFormatCHROMIUM(
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
index 84434791..3057310 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1298,7 +1298,7 @@
 void GLES2InterfaceStub::DestroyGpuFenceCHROMIUM(GLuint /* gpu_fence_id */) {}
 void GLES2InterfaceStub::InvalidateReadbackBufferShadowDataCHROMIUM(
     GLuint /* buffer_id */) {}
-void GLES2InterfaceStub::FramebufferTextureMultiviewLayeredANGLE(
+void GLES2InterfaceStub::FramebufferTextureMultiviewOVR(
     GLenum /* target */,
     GLenum /* attachment */,
     GLuint /* texture */,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
index dc5f349..6f6b8dde 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -977,12 +977,12 @@
 void WaitGpuFenceCHROMIUM(GLuint gpu_fence_id) override;
 void DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) override;
 void InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) override;
-void FramebufferTextureMultiviewLayeredANGLE(GLenum target,
-                                             GLenum attachment,
-                                             GLuint texture,
-                                             GLint level,
-                                             GLint baseViewIndex,
-                                             GLsizei numViews) override;
+void FramebufferTextureMultiviewOVR(GLenum target,
+                                    GLenum attachment,
+                                    GLuint texture,
+                                    GLint level,
+                                    GLint baseViewIndex,
+                                    GLsizei numViews) override;
 void MaxShaderCompilerThreadsKHR(GLuint count) override;
 GLuint CreateAndTexStorage2DSharedImageCHROMIUM(const GLbyte* mailbox) override;
 GLuint CreateAndTexStorage2DSharedImageWithInternalFormatCHROMIUM(
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
index 1715ee82..4a0a5288 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2731,17 +2731,17 @@
   gl_->InvalidateReadbackBufferShadowDataCHROMIUM(buffer_id);
 }
 
-void GLES2TraceImplementation::FramebufferTextureMultiviewLayeredANGLE(
+void GLES2TraceImplementation::FramebufferTextureMultiviewOVR(
     GLenum target,
     GLenum attachment,
     GLuint texture,
     GLint level,
     GLint baseViewIndex,
     GLsizei numViews) {
-  TRACE_EVENT_BINARY_EFFICIENT0(
-      "gpu", "GLES2Trace::FramebufferTextureMultiviewLayeredANGLE");
-  gl_->FramebufferTextureMultiviewLayeredANGLE(target, attachment, texture,
-                                               level, baseViewIndex, numViews);
+  TRACE_EVENT_BINARY_EFFICIENT0("gpu",
+                                "GLES2Trace::FramebufferTextureMultiviewOVR");
+  gl_->FramebufferTextureMultiviewOVR(target, attachment, texture, level,
+                                      baseViewIndex, numViews);
 }
 
 void GLES2TraceImplementation::MaxShaderCompilerThreadsKHR(GLuint count) {
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index ebc1f78..cf009da4 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -17353,9 +17353,9 @@
     offsetof(SetReadbackBufferShadowAllocationINTERNAL, size) == 16,
     "offset of SetReadbackBufferShadowAllocationINTERNAL size should be 16");
 
-struct FramebufferTextureMultiviewLayeredANGLE {
-  typedef FramebufferTextureMultiviewLayeredANGLE ValueType;
-  static const CommandId kCmdId = kFramebufferTextureMultiviewLayeredANGLE;
+struct FramebufferTextureMultiviewOVR {
+  typedef FramebufferTextureMultiviewOVR ValueType;
+  static const CommandId kCmdId = kFramebufferTextureMultiviewOVR;
   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
   static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1);
 
@@ -17401,30 +17401,24 @@
   int32_t numViews;
 };
 
-static_assert(sizeof(FramebufferTextureMultiviewLayeredANGLE) == 28,
-              "size of FramebufferTextureMultiviewLayeredANGLE should be 28");
+static_assert(sizeof(FramebufferTextureMultiviewOVR) == 28,
+              "size of FramebufferTextureMultiviewOVR should be 28");
+static_assert(offsetof(FramebufferTextureMultiviewOVR, header) == 0,
+              "offset of FramebufferTextureMultiviewOVR header should be 0");
+static_assert(offsetof(FramebufferTextureMultiviewOVR, target) == 4,
+              "offset of FramebufferTextureMultiviewOVR target should be 4");
 static_assert(
-    offsetof(FramebufferTextureMultiviewLayeredANGLE, header) == 0,
-    "offset of FramebufferTextureMultiviewLayeredANGLE header should be 0");
+    offsetof(FramebufferTextureMultiviewOVR, attachment) == 8,
+    "offset of FramebufferTextureMultiviewOVR attachment should be 8");
+static_assert(offsetof(FramebufferTextureMultiviewOVR, texture) == 12,
+              "offset of FramebufferTextureMultiviewOVR texture should be 12");
+static_assert(offsetof(FramebufferTextureMultiviewOVR, level) == 16,
+              "offset of FramebufferTextureMultiviewOVR level should be 16");
 static_assert(
-    offsetof(FramebufferTextureMultiviewLayeredANGLE, target) == 4,
-    "offset of FramebufferTextureMultiviewLayeredANGLE target should be 4");
-static_assert(
-    offsetof(FramebufferTextureMultiviewLayeredANGLE, attachment) == 8,
-    "offset of FramebufferTextureMultiviewLayeredANGLE attachment should be 8");
-static_assert(
-    offsetof(FramebufferTextureMultiviewLayeredANGLE, texture) == 12,
-    "offset of FramebufferTextureMultiviewLayeredANGLE texture should be 12");
-static_assert(
-    offsetof(FramebufferTextureMultiviewLayeredANGLE, level) == 16,
-    "offset of FramebufferTextureMultiviewLayeredANGLE level should be 16");
-static_assert(offsetof(FramebufferTextureMultiviewLayeredANGLE,
-                       baseViewIndex) == 20,
-              "offset of FramebufferTextureMultiviewLayeredANGLE baseViewIndex "
-              "should be 20");
-static_assert(
-    offsetof(FramebufferTextureMultiviewLayeredANGLE, numViews) == 24,
-    "offset of FramebufferTextureMultiviewLayeredANGLE numViews should be 24");
+    offsetof(FramebufferTextureMultiviewOVR, baseViewIndex) == 20,
+    "offset of FramebufferTextureMultiviewOVR baseViewIndex should be 20");
+static_assert(offsetof(FramebufferTextureMultiviewOVR, numViews) == 24,
+              "offset of FramebufferTextureMultiviewOVR numViews should be 24");
 
 struct MaxShaderCompilerThreadsKHR {
   typedef MaxShaderCompilerThreadsKHR ValueType;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index fd913f8..ee423c7 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -5727,15 +5727,14 @@
   CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
 }
 
-TEST_F(GLES2FormatTest, FramebufferTextureMultiviewLayeredANGLE) {
-  cmds::FramebufferTextureMultiviewLayeredANGLE& cmd =
-      *GetBufferAs<cmds::FramebufferTextureMultiviewLayeredANGLE>();
+TEST_F(GLES2FormatTest, FramebufferTextureMultiviewOVR) {
+  cmds::FramebufferTextureMultiviewOVR& cmd =
+      *GetBufferAs<cmds::FramebufferTextureMultiviewOVR>();
   void* next_cmd =
       cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLenum>(12),
               static_cast<GLuint>(13), static_cast<GLint>(14),
               static_cast<GLint>(15), static_cast<GLsizei>(16));
-  EXPECT_EQ(static_cast<uint32_t>(
-                cmds::FramebufferTextureMultiviewLayeredANGLE::kCmdId),
+  EXPECT_EQ(static_cast<uint32_t>(cmds::FramebufferTextureMultiviewOVR::kCmdId),
             cmd.header.command);
   EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
   EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index 5fab1e6..3f3f1598 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -356,7 +356,7 @@
   OP(WaitGpuFenceCHROMIUM)                                 /* 597 */ \
   OP(DestroyGpuFenceCHROMIUM)                              /* 598 */ \
   OP(SetReadbackBufferShadowAllocationINTERNAL)            /* 599 */ \
-  OP(FramebufferTextureMultiviewLayeredANGLE)              /* 600 */ \
+  OP(FramebufferTextureMultiviewOVR)                       /* 600 */ \
   OP(MaxShaderCompilerThreadsKHR)                          /* 601 */ \
   OP(CreateAndTexStorage2DSharedImageINTERNALImmediate)    /* 602 */ \
   OP(BeginSharedImageAccessDirectCHROMIUM)                 /* 603 */ \
diff --git a/gpu/command_buffer/gles2_cmd_buffer_functions.txt b/gpu/command_buffer/gles2_cmd_buffer_functions.txt
index e56a66c..7c3d121 100644
--- a/gpu/command_buffer/gles2_cmd_buffer_functions.txt
+++ b/gpu/command_buffer/gles2_cmd_buffer_functions.txt
@@ -417,8 +417,8 @@
 // (used for CHROMIUM_nonblocking_readback implementation)
 GL_APICALL void         GL_APIENTRY glSetReadbackBufferShadowAllocationINTERNAL (GLidBuffer buffer_id, GLint shm_id, GLuint shm_offset, GLuint size);
 
-// Extension ANGLE_multiview
-GL_APICALL void         GL_APIENTRY glFramebufferTextureMultiviewLayeredANGLE (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
+// Extension OVR_multiview2
+GL_APICALL void         GL_APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
 
 // Extension KHR_parallel_shader_compile
 GL_APICALL void         GL_APIENTRY glMaxShaderCompilerThreadsKHR (GLuint count);
diff --git a/gpu/command_buffer/service/external_vk_image_skia_representation.cc b/gpu/command_buffer/service/external_vk_image_skia_representation.cc
index e5d11dc..d8b662fd 100644
--- a/gpu/command_buffer/service/external_vk_image_skia_representation.cc
+++ b/gpu/command_buffer/service/external_vk_image_skia_representation.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/trace_event/trace_event.h"
+#include "gpu/vulkan/vulkan_fence_helper.h"
 #include "gpu/vulkan/vulkan_function_pointers.h"
 #include "gpu/vulkan/vulkan_util.h"
 #include "third_party/skia/include/core/SkPromiseImageTexture.h"
@@ -20,27 +21,9 @@
     SharedImageBacking* backing,
     MemoryTypeTracker* tracker)
     : SharedImageRepresentationSkia(manager, backing, tracker) {
-  VkFenceCreateInfo create_info = {
-      .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
-      .pNext = nullptr,
-      .flags = 0,
-  };
-  VkResult result =
-      vkCreateFence(vk_device(), &create_info, nullptr /* pAllocator */,
-                    &begin_access_fence_);
-  DCHECK_EQ(result, VK_SUCCESS);
-  result = vkCreateFence(vk_device(), &create_info, nullptr /* pAllocator */,
-                         &end_access_fence_);
-  DCHECK_EQ(result, VK_SUCCESS);
 }
 
 ExternalVkImageSkiaRepresentation::~ExternalVkImageSkiaRepresentation() {
-  DestroySemaphores(std::move(begin_access_semaphores_), begin_access_fence_);
-  begin_access_semaphores_.clear();
-  DestroySemaphore(end_access_semaphore_, end_access_fence_);
-  end_access_semaphore_ = VK_NULL_HANDLE;
-  vkDestroyFence(vk_device(), begin_access_fence_, nullptr /* pAllocator */);
-  vkDestroyFence(vk_device(), end_access_fence_, nullptr /* pAllocator */);
 }
 
 sk_sp<SkSurface> ExternalVkImageSkiaRepresentation::BeginWriteAccess(
@@ -95,32 +78,33 @@
 sk_sp<SkPromiseImageTexture> ExternalVkImageSkiaRepresentation::BeginAccess(
     bool readonly) {
   DCHECK_EQ(access_mode_, kNone);
-  DestroySemaphores(std::move(begin_access_semaphores_), begin_access_fence_);
-  begin_access_semaphores_.clear();
 
   std::vector<SemaphoreHandle> handles;
   if (!backing_impl()->BeginAccess(readonly, &handles))
     return nullptr;
 
+  std::vector<VkSemaphore> begin_access_semaphores;
   for (auto& handle : handles) {
     VkSemaphore semaphore = vk_implementation()->ImportSemaphoreHandle(
         vk_device(), std::move(handle));
     if (semaphore != VK_NULL_HANDLE)
-      begin_access_semaphores_.push_back(semaphore);
+      begin_access_semaphores.push_back(semaphore);
   }
 
-  if (!begin_access_semaphores_.empty()) {
+  if (!begin_access_semaphores.empty()) {
     // Submit wait semaphore to the queue. Note that Skia uses the same queue
     // exposed by vk_queue(), so this will work due to Vulkan queue ordering.
-    if (!SubmitWaitVkSemaphores(vk_queue(), begin_access_semaphores_,
-                                begin_access_fence_)) {
+    if (!SubmitWaitVkSemaphores(vk_queue(), begin_access_semaphores)) {
       LOG(ERROR) << "Failed to wait on semaphore";
       // Since the semaphore was not actually sent to the queue, it is safe to
-      // destroy the |begin_access_semaphores_| here.
-      DestroySemaphores(std::move(begin_access_semaphores_));
-      begin_access_semaphores_.clear();
+      // destroy the |begin_access_semaphores| here.
+      DestroySemaphoresImmediate(std::move(begin_access_semaphores));
       return nullptr;
     }
+
+    // Enqueue delayed cleanup of the semaphores.
+    fence_helper()->EnqueueSemaphoresCleanupForSubmittedWork(
+        std::move(begin_access_semaphores));
   }
 
   // Create backend texture from the VkImage.
@@ -137,58 +121,59 @@
 
 void ExternalVkImageSkiaRepresentation::EndAccess(bool readonly) {
   DCHECK_NE(access_mode_, kNone);
-  // Cleanup resources for previous accessing.
-  DestroySemaphore(end_access_semaphore_, end_access_fence_);
 
-  end_access_semaphore_ =
+  VkSemaphore end_access_semaphore =
       vk_implementation()->CreateExternalSemaphore(backing_impl()->device());
-  // Submit wait semaphore to the queue. Note that Skia uses the same queue
-  // exposed by vk_queue(), so this will work due to Vulkan queue ordering.
-  if (!SubmitSignalVkSemaphore(vk_queue(), end_access_semaphore_,
-                               end_access_fence_)) {
-    LOG(ERROR) << "Failed to wait on semaphore";
-    // Since the semaphore was not actually sent to the queue, it is safe to
-    // destroy the |end_access_semaphore_| here.
-    DestroySemaphore(end_access_semaphore_);
-    end_access_semaphore_ = VK_NULL_HANDLE;
+  VkFence end_access_fence = VK_NULL_HANDLE;
+  if (end_access_semaphore != VK_NULL_HANDLE) {
+    if (VK_SUCCESS != fence_helper()->GetFence(&end_access_fence)) {
+      // Since the semaphore was not actually sent to the queue, it is safe to
+      // destroy the |end_access_semaphore| here.
+      DestroySemaphoreImmediate(end_access_semaphore);
+    }
+    // Submit wait semaphore to the queue. Note that Skia uses the same queue
+    // exposed by vk_queue(), so this will work due to Vulkan queue ordering.
+    if (!SubmitSignalVkSemaphore(vk_queue(), end_access_semaphore,
+                                 end_access_fence)) {
+      LOG(ERROR) << "Failed to wait on semaphore";
+      // Since the semaphore was not actually sent to the queue, it is safe to
+      // destroy the |end_access_semaphore| here.
+      DestroySemaphoreImmediate(end_access_semaphore);
+      // Same for the fence.
+      vkDestroyFence(vk_device(), end_access_fence, nullptr);
+      end_access_fence = VK_NULL_HANDLE;
+      end_access_semaphore = VK_NULL_HANDLE;
+    }
   }
 
   SemaphoreHandle handle;
-  if (end_access_semaphore_ != VK_NULL_HANDLE) {
+  if (end_access_semaphore != VK_NULL_HANDLE) {
     handle = vk_implementation()->GetSemaphoreHandle(vk_device(),
-                                                     end_access_semaphore_);
+                                                     end_access_semaphore);
     if (!handle.is_valid())
       LOG(FATAL) << "Failed to get handle from a semaphore.";
+
+    // We're done with the semaphore, enqueue deferred cleanup.
+    fence_helper()->EnqueueSemaphoreCleanupForSubmittedWork(
+        end_access_semaphore);
+    fence_helper()->EnqueueFence(end_access_fence);
   }
   backing_impl()->EndAccess(readonly, std::move(handle));
 }
 
-void ExternalVkImageSkiaRepresentation::DestroySemaphores(
-    std::vector<VkSemaphore> semaphores,
-    VkFence fence) {
+void ExternalVkImageSkiaRepresentation::DestroySemaphoresImmediate(
+    std::vector<VkSemaphore> semaphores) {
   if (semaphores.empty())
     return;
-  if (fence != VK_NULL_HANDLE)
-    WaitAndResetFence(fence);
   for (VkSemaphore semaphore : semaphores)
     vkDestroySemaphore(vk_device(), semaphore, nullptr /* pAllocator */);
 }
 
-void ExternalVkImageSkiaRepresentation::DestroySemaphore(VkSemaphore semaphore,
-                                                         VkFence fence) {
+void ExternalVkImageSkiaRepresentation::DestroySemaphoreImmediate(
+    VkSemaphore semaphore) {
   if (semaphore == VK_NULL_HANDLE)
     return;
-  if (fence != VK_NULL_HANDLE)
-    WaitAndResetFence(fence);
-  vkDestroySemaphore(vk_device(), semaphore, nullptr /* pAllocator */);
-}
-
-void ExternalVkImageSkiaRepresentation::WaitAndResetFence(VkFence fence) {
-  TRACE_EVENT0("gpu", "ExternalVkImageSkiaRepresentation::WaitAndResetFence");
-  VkResult result = vkWaitForFences(vk_device(), 1, &fence, VK_TRUE,
-                                    std::numeric_limits<uint64_t>::max());
-  LOG_IF(FATAL, result != VK_SUCCESS) << "vkWaitForFences failed.";
-  vkResetFences(vk_device(), 1, &fence);
+  return DestroySemaphoresImmediate({semaphore});
 }
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/external_vk_image_skia_representation.h b/gpu/command_buffer/service/external_vk_image_skia_representation.h
index 18adf54..516766f 100644
--- a/gpu/command_buffer/service/external_vk_image_skia_representation.h
+++ b/gpu/command_buffer/service/external_vk_image_skia_representation.h
@@ -55,18 +55,24 @@
         ->GetVulkanQueue();
   }
 
+  VulkanFenceHelper* fence_helper() {
+    return backing_impl()
+        ->context_state()
+        ->vk_context_provider()
+        ->GetDeviceQueue()
+        ->GetFenceHelper();
+  }
+
   ExternalVkImageBacking* backing_impl() {
     return static_cast<ExternalVkImageBacking*>(backing());
   }
 
   sk_sp<SkPromiseImageTexture> BeginAccess(bool readonly);
   void EndAccess(bool readonly);
-  void DestroySemaphores(std::vector<VkSemaphore> semaphores,
-                         VkFence fence = VK_NULL_HANDLE);
-  void DestroySemaphore(VkSemaphore semaphores, VkFence fence = VK_NULL_HANDLE);
-  void WaitAndResetFence(VkFence fence);
 
-  VkFence CreateFence();
+  // Functions used in error cases - immediately clean up semaphores.
+  void DestroySemaphoresImmediate(std::vector<VkSemaphore> semaphores);
+  void DestroySemaphoreImmediate(VkSemaphore semaphores);
 
   enum AccessMode {
     kNone = 0,
@@ -75,12 +81,6 @@
   };
   AccessMode access_mode_ = kNone;
   sk_sp<SkSurface> surface_;
-
-  std::vector<VkSemaphore> begin_access_semaphores_;
-  VkFence begin_access_fence_ = VK_NULL_HANDLE;
-
-  VkSemaphore end_access_semaphore_ = VK_NULL_HANDLE;
-  VkFence end_access_fence_ = VK_NULL_HANDLE;
 };
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 0716c4f..a2ed6be 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -1523,13 +1523,13 @@
     AddExtensionString("GL_MESA_framebuffer_flip_y");
   }
 
-  // Only supporting ANGLE_multiview in passthrough mode - not implemented in
+  // Only supporting OVR_multiview in passthrough mode - not implemented in
   // validating command decoder. The extension is only available in ANGLE and in
   // that case Chromium should be using passthrough by default.
   if (is_passthrough_cmd_decoder_ &&
-      gfx::HasExtension(extensions, "GL_ANGLE_multiview")) {
-    AddExtensionString("GL_ANGLE_multiview");
-    feature_flags_.angle_multiview = true;
+      gfx::HasExtension(extensions, "GL_OVR_multiview2")) {
+    AddExtensionString("GL_OVR_multiview2");
+    feature_flags_.ovr_multiview2 = true;
   }
 
   if (is_passthrough_cmd_decoder_ &&
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h
index c5ceec10f..9ad2b78 100644
--- a/gpu/command_buffer/service/feature_info.h
+++ b/gpu/command_buffer/service/feature_info.h
@@ -137,7 +137,7 @@
     bool unpremultiply_and_dither_copy = false;
     bool separate_stencil_ref_mask_writemask = false;
     bool mesa_framebuffer_flip_y = false;
-    bool angle_multiview = false;
+    bool ovr_multiview2 = false;
     bool khr_parallel_shader_compile = false;
     bool android_surface_control = false;
     bool khr_robust_buffer_access_behavior = false;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 9459fd0..881c4d0 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1759,12 +1759,12 @@
       GLint layer);
 
   // Wrapper for glFramebufferTextureLayer.
-  void DoFramebufferTextureMultiviewLayeredANGLE(GLenum target,
-                                                 GLenum attachment,
-                                                 GLuint texture,
-                                                 GLint level,
-                                                 GLint base_view_index,
-                                                 GLsizei num_views);
+  void DoFramebufferTextureMultiviewOVR(GLenum target,
+                                        GLenum attachment,
+                                        GLuint texture,
+                                        GLint level,
+                                        GLint base_view_index,
+                                        GLsizei num_views);
 
   // Wrapper for glGenerateMipmap
   void DoGenerateMipmap(GLenum target);
@@ -8622,7 +8622,7 @@
   }
 }
 
-void GLES2DecoderImpl::DoFramebufferTextureMultiviewLayeredANGLE(
+void GLES2DecoderImpl::DoFramebufferTextureMultiviewOVR(
     GLenum target,
     GLenum attachment,
     GLuint client_texture_id,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 8c4d715..d79dc20 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -5561,16 +5561,15 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleFramebufferTextureMultiviewLayeredANGLE(
+error::Error GLES2DecoderImpl::HandleFramebufferTextureMultiviewOVR(
     uint32_t immediate_data_size,
     const volatile void* cmd_data) {
   if (!feature_info_->IsWebGL2OrES3OrHigherContext())
     return error::kUnknownCommand;
-  const volatile gles2::cmds::FramebufferTextureMultiviewLayeredANGLE& c =
-      *static_cast<
-          const volatile gles2::cmds::FramebufferTextureMultiviewLayeredANGLE*>(
+  const volatile gles2::cmds::FramebufferTextureMultiviewOVR& c =
+      *static_cast<const volatile gles2::cmds::FramebufferTextureMultiviewOVR*>(
           cmd_data);
-  if (!features().angle_multiview) {
+  if (!features().ovr_multiview2) {
     return error::kUnknownCommand;
   }
 
@@ -5581,13 +5580,12 @@
   GLint baseViewIndex = static_cast<GLint>(c.baseViewIndex);
   GLsizei numViews = static_cast<GLsizei>(c.numViews);
   if (numViews < 0) {
-    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
-                       "glFramebufferTextureMultiviewLayeredANGLE",
+    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glFramebufferTextureMultiviewOVR",
                        "numViews < 0");
     return error::kNoError;
   }
-  DoFramebufferTextureMultiviewLayeredANGLE(target, attachment, texture, level,
-                                            baseViewIndex, numViews);
+  DoFramebufferTextureMultiviewOVR(target, attachment, texture, level,
+                                   baseViewIndex, numViews);
   return error::kNoError;
 }
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
index 6605a36..1fb7aa15 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
@@ -200,12 +200,12 @@
                                        GLuint texture,
                                        GLint level,
                                        GLint layer);
-error::Error DoFramebufferTextureMultiviewLayeredANGLE(GLenum target,
-                                                       GLenum attachment,
-                                                       GLuint texture,
-                                                       GLint level,
-                                                       GLint base_view_index,
-                                                       GLsizei num_views);
+error::Error DoFramebufferTextureMultiviewOVR(GLenum target,
+                                              GLenum attachment,
+                                              GLuint texture,
+                                              GLint level,
+                                              GLint base_view_index,
+                                              GLsizei num_views);
 error::Error DoFrontFace(GLenum mode);
 error::Error DoGenBuffers(GLsizei n, volatile GLuint* buffers);
 error::Error DoGenerateMipmap(GLenum target);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
index 3f1d15f..6c2d585fc 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -1299,8 +1299,7 @@
   return error::kNoError;
 }
 
-error::Error
-GLES2DecoderPassthroughImpl::DoFramebufferTextureMultiviewLayeredANGLE(
+error::Error GLES2DecoderPassthroughImpl::DoFramebufferTextureMultiviewOVR(
     GLenum target,
     GLenum attachment,
     GLuint texture,
@@ -1312,7 +1311,7 @@
                 "Cannot change the attachments of the default framebuffer.");
     return error::kNoError;
   }
-  api()->glFramebufferTextureMultiviewLayeredANGLEFn(
+  api()->glFramebufferTextureMultiviewOVRFn(
       target, attachment,
       GetTextureServiceID(api(), texture, resources_, false), level,
       base_view_index, num_views);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
index 3266134..0abeb0b 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
@@ -4835,17 +4835,15 @@
   return error::kNoError;
 }
 
-error::Error
-GLES2DecoderPassthroughImpl::HandleFramebufferTextureMultiviewLayeredANGLE(
+error::Error GLES2DecoderPassthroughImpl::HandleFramebufferTextureMultiviewOVR(
     uint32_t immediate_data_size,
     const volatile void* cmd_data) {
   if (!feature_info_->IsWebGL2OrES3OrHigherContext())
     return error::kUnknownCommand;
-  const volatile gles2::cmds::FramebufferTextureMultiviewLayeredANGLE& c =
-      *static_cast<
-          const volatile gles2::cmds::FramebufferTextureMultiviewLayeredANGLE*>(
+  const volatile gles2::cmds::FramebufferTextureMultiviewOVR& c =
+      *static_cast<const volatile gles2::cmds::FramebufferTextureMultiviewOVR*>(
           cmd_data);
-  if (!features().angle_multiview) {
+  if (!features().ovr_multiview2) {
     return error::kUnknownCommand;
   }
 
@@ -4855,7 +4853,7 @@
   GLint level = static_cast<GLint>(c.level);
   GLint baseViewIndex = static_cast<GLint>(c.baseViewIndex);
   GLsizei numViews = static_cast<GLsizei>(c.numViews);
-  error::Error error = DoFramebufferTextureMultiviewLayeredANGLE(
+  error::Error error = DoFramebufferTextureMultiviewOVR(
       target, attachment, texture, level, baseViewIndex, numViews);
   if (error != error::kNoError) {
     return error;
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
index a83edf30..0c9de256 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
@@ -33,6 +33,7 @@
 #include "gpu/command_buffer/service/texture_manager.h"
 #include "gpu/ipc/common/android/android_image_reader_utils.h"
 #include "gpu/vulkan/vulkan_device_queue.h"
+#include "gpu/vulkan/vulkan_fence_helper.h"
 #include "gpu/vulkan/vulkan_function_pointers.h"
 #include "gpu/vulkan/vulkan_implementation.h"
 #include "gpu/vulkan/vulkan_util.h"
@@ -72,71 +73,52 @@
   return os;
 }
 
-void DestroySemaphore(VkDevice vk_device,
-                      VkQueue vk_queue,
-                      VkSemaphore semaphore) {
-  if (semaphore == VK_NULL_HANDLE)
-    return;
+bool BeginVulkanAccess(viz::VulkanContextProvider* context_provider,
+                       base::ScopedFD begin_sync_fd) {
+  VkDevice vk_device = context_provider->GetDeviceQueue()->GetVulkanDevice();
+  VulkanImplementation* vk_implementation =
+      context_provider->GetVulkanImplementation();
+  VulkanFenceHelper* fence_helper =
+      context_provider->GetDeviceQueue()->GetFenceHelper();
+  VkQueue vk_queue = context_provider->GetDeviceQueue()->GetVulkanQueue();
 
-  // TODO(vikassoni): Need to do better semaphore cleanup management. Waiting
-  // on device to be idle to delete the semaphore is costly. Instead use a
-  // fence to get signal when semaphore submission is done.
-  VkResult result = vkQueueWaitIdle(vk_queue);
-  if (result != VK_SUCCESS) {
-    LOG(ERROR) << "vkQueueWaitIdle failed: " << result;
-    return;
+  // Wait on the provided |begin_sync_fd|.
+  VkSemaphore semaphore = VK_NULL_HANDLE;
+  if (begin_sync_fd.is_valid()) {
+    semaphore = vk_implementation->ImportSemaphoreHandle(
+        vk_device,
+        SemaphoreHandle(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
+                        std::move(begin_sync_fd)));
+    if (semaphore == VK_NULL_HANDLE) {
+      return false;
+    }
+
+    // Submit wait semaphore to the queue. Note that Skia uses the same queue
+    // exposed by vk_queue(), so this will work due to Vulkan queue ordering.
+    if (!SubmitWaitVkSemaphore(vk_queue, semaphore)) {
+      vkDestroySemaphore(vk_device, semaphore, nullptr);
+      return false;
+    }
+
+    // Enqueue destruction of the semaphore here.
+    // TODO(ericrk): Don't worry about generating a fence above, we will
+    // generate one in EndVulkanAccess. Refactoring will remove this path
+    // soon.
+    fence_helper->EnqueueSemaphoreCleanupForSubmittedWork(semaphore);
   }
 
-  vkDestroySemaphore(vk_device, semaphore, nullptr);
+  return true;
 }
 
-sk_sp<SkPromiseImageTexture> BeginVulkanAccess(
-    gpu::VulkanImplementation* vk_implementation,
-    VkDevice vk_device,
-    VkPhysicalDevice vk_physical_device,
-    VkQueue vk_queue,
-    base::android::ScopedHardwareBufferHandle ahb_handle,
-    gfx::Size size,
-    viz::ResourceFormat format,
-    VkSemaphore semaphore_to_clean) {
-  // Create a VkImage and import AHB.
-  VkImage vk_image;
-  VkImageCreateInfo vk_image_info;
-  VkDeviceMemory vk_device_memory;
-  VkDeviceSize mem_allocation_size;
-  if (!vk_implementation->CreateVkImageAndImportAHB(
-          vk_device, vk_physical_device, size, std::move(ahb_handle), &vk_image,
-          &vk_image_info, &vk_device_memory, &mem_allocation_size)) {
-    return nullptr;
-  }
-
-  // Create backend texture from the VkImage.
-  GrVkAlloc alloc = {vk_device_memory, 0, mem_allocation_size, 0};
-  GrVkImageInfo vk_info = {vk_image,
-                           alloc,
-                           vk_image_info.tiling,
-                           vk_image_info.initialLayout,
-                           vk_image_info.format,
-                           vk_image_info.mipLevels};
-  // TODO(bsalomon): Determine whether it makes sense to attempt to reuse this
-  // if the vk_info stays the same on subsequent calls.
-  auto promise_texture = SkPromiseImageTexture::Make(
-      GrBackendTexture(size.width(), size.height(), vk_info));
-  if (!promise_texture) {
-    vkDestroyImage(vk_device, vk_image, nullptr);
-    vkFreeMemory(vk_device, vk_device_memory, nullptr);
-    return nullptr;
-  }
-
-  DestroySemaphore(vk_device, vk_queue, semaphore_to_clean);
-
-  return promise_texture;
-}
-
-void EndVulkanAccess(gpu::VulkanImplementation* vk_implementation,
-                     VkDevice vk_device,
-                     VkQueue vk_queue,
+void EndVulkanAccess(viz::VulkanContextProvider* context_provider,
                      base::ScopedFD* sync_fd) {
+  VulkanImplementation* vk_implementation =
+      context_provider->GetVulkanImplementation();
+  VkDevice vk_device = context_provider->GetDeviceQueue()->GetVulkanDevice();
+  VkQueue vk_queue = context_provider->GetDeviceQueue()->GetVulkanQueue();
+  VulkanFenceHelper* fence_helper =
+      context_provider->GetDeviceQueue()->GetFenceHelper();
+
   // Create a vk semaphore which can be exported.
   VkExportSemaphoreCreateInfo export_info;
   export_info.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO;
@@ -155,8 +137,15 @@
     return;
   }
 
-  if (!SubmitSignalVkSemaphore(vk_queue, vk_semaphore,
-                               VK_NULL_HANDLE /* vk_fence */)) {
+  VkFence vk_fence;
+  result = fence_helper->GetFence(&vk_fence);
+  if (result != VK_SUCCESS) {
+    LOG(ERROR) << "Failed to create fence.";
+    vkDestroySemaphore(vk_device, vk_semaphore, nullptr);
+    return;
+  }
+
+  if (!SubmitSignalVkSemaphore(vk_queue, vk_semaphore, vk_fence)) {
     LOG(ERROR) << "Failed to wait on semaphore";
     vkDestroySemaphore(vk_device, vk_semaphore, nullptr);
     return;
@@ -167,18 +156,69 @@
       vk_implementation->GetSemaphoreHandle(vk_device, vk_semaphore);
   *sync_fd = semaphore_handle.TakeHandle();
 
-  // TODO(vikassoni): We need to wait for the queue submission to complete
-  // before we can destroy the semaphore. This will decrease the performance.
-  // Add a future patch to handle this in more efficient way. Keep semaphores
-  // in a STL queue instead of destroying it. Later use a fence to check if
-  // the batch that refers the semaphore has completed execution. Delete the
-  // semaphore once the fence is signalled.
-  result = vkQueueWaitIdle(vk_queue);
-  if (result != VK_SUCCESS) {
-    LOG(ERROR) << "vkQueueWaitIdle failed: " << result;
-    return;
+  // Enqueue cleanup of the semaphore based on the submission fence.
+  fence_helper->EnqueueSemaphoreCleanupForSubmittedWork(vk_semaphore);
+  fence_helper->EnqueueFence(vk_fence);
+}
+
+sk_sp<SkPromiseImageTexture> CreatePromiseTexture(
+    viz::VulkanContextProvider* context_provider,
+    base::android::ScopedHardwareBufferHandle ahb_handle,
+    gfx::Size size,
+    viz::ResourceFormat format) {
+  VulkanImplementation* vk_implementation =
+      context_provider->GetVulkanImplementation();
+  VkDevice vk_device = context_provider->GetDeviceQueue()->GetVulkanDevice();
+  VkPhysicalDevice vk_physical_device =
+      context_provider->GetDeviceQueue()->GetVulkanPhysicalDevice();
+
+  // Create a VkImage and import AHB.
+  VkImage vk_image;
+  VkImageCreateInfo vk_image_info;
+  VkDeviceMemory vk_device_memory;
+  VkDeviceSize mem_allocation_size;
+  if (!vk_implementation->CreateVkImageAndImportAHB(
+          vk_device, vk_physical_device, size, std::move(ahb_handle), &vk_image,
+          &vk_image_info, &vk_device_memory, &mem_allocation_size)) {
+    return nullptr;
   }
-  vkDestroySemaphore(vk_device, vk_semaphore, nullptr);
+
+  // Create backend texture from the VkImage.
+  GrVkAlloc alloc = {vk_device_memory, 0, mem_allocation_size, 0};
+  GrVkImageInfo vk_info = {vk_image,
+                           alloc,
+                           vk_image_info.tiling,
+                           vk_image_info.initialLayout,
+                           vk_image_info.format,
+                           vk_image_info.mipLevels,
+                           VK_QUEUE_FAMILY_EXTERNAL};
+  // TODO(bsalomon): Determine whether it makes sense to attempt to reuse this
+  // if the vk_info stays the same on subsequent calls.
+  auto promise_texture = SkPromiseImageTexture::Make(
+      GrBackendTexture(size.width(), size.height(), vk_info));
+  if (!promise_texture) {
+    vkDestroyImage(vk_device, vk_image, nullptr);
+    vkFreeMemory(vk_device, vk_device_memory, nullptr);
+    return nullptr;
+  }
+
+  return promise_texture;
+}
+
+void DestroyVkPromiseTexture(viz::VulkanContextProvider* context_provider,
+                             sk_sp<SkPromiseImageTexture> promise_texture) {
+  DCHECK(promise_texture);
+  DCHECK(promise_texture->unique());
+
+  GrVkImageInfo vk_image_info;
+  bool result =
+      promise_texture->backendTexture().getVkImageInfo(&vk_image_info);
+  DCHECK(result);
+
+  VulkanFenceHelper* fence_helper =
+      context_provider->GetDeviceQueue()->GetFenceHelper();
+  fence_helper->EnqueueImageCleanupForSubmittedWork(
+      vk_image_info.fImage, vk_image_info.fAlloc.fMemory);
 }
 
 }  // namespace
@@ -324,12 +364,12 @@
       SharedImageManager* manager,
       SharedImageBacking* backing,
       scoped_refptr<SharedContextState> context_state,
-      sk_sp<SkPromiseImageTexture> cached_promise_image_texture,
+      sk_sp<SkPromiseImageTexture> promise_texture,
       MemoryTypeTracker* tracker,
       gles2::Texture* texture)
       : SharedImageRepresentationSkia(manager, backing, tracker),
         context_state_(std::move(context_state)),
-        promise_texture_(cached_promise_image_texture),
+        promise_texture_(std::move(promise_texture)),
         texture_(std::move(texture)) {
 #if DCHECK_IS_ON()
     context_ = gl::GLContext::GetCurrent();
@@ -461,17 +501,19 @@
   SharedImageRepresentationSkiaVkAHB(
       SharedImageManager* manager,
       SharedImageBacking* backing,
-      scoped_refptr<SharedContextState> context_state)
+      scoped_refptr<SharedContextState> context_state,
+      sk_sp<SkPromiseImageTexture> promise_texture)
       : SharedImageRepresentationSkia(manager, backing, nullptr),
+        promise_texture_(std::move(promise_texture)),
         context_state_(std::move(context_state)) {
-    SharedImageBackingAHB* ahb_backing =
-        static_cast<SharedImageBackingAHB*>(backing);
-    DCHECK(ahb_backing);
+    DCHECK(promise_texture_);
     DCHECK(context_state_);
     DCHECK(context_state_->vk_context_provider());
   }
 
   ~SharedImageRepresentationSkiaVkAHB() override {
+    DestroyVkPromiseTexture(context_state_->vk_context_provider(),
+                            std::move(promise_texture_));
     DCHECK_EQ(mode_, RepresentationAccessMode::kNone);
     DCHECK(!surface_);
   }
@@ -487,29 +529,10 @@
     if (!ahb_backing()->BeginWrite(&sync_fd))
       return nullptr;
 
-    VkSemaphore semaphore = VK_NULL_HANDLE;
-    if (sync_fd.is_valid()) {
-      semaphore = vk_implementation()->ImportSemaphoreHandle(
-          vk_device(),
-          SemaphoreHandle(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
-                          std::move(sync_fd)));
-      if (semaphore == VK_NULL_HANDLE) {
-        return nullptr;
-      }
-
-      // Submit wait semaphore to the queue. Note that Skia uses the same queue
-      // exposed by vk_queue(), so this will work due to Vulkan queue ordering.
-      if (!SubmitWaitVkSemaphore(vk_queue(), semaphore)) {
-        DestroySemaphore(vk_device(), vk_queue(), semaphore);
-        return nullptr;
-      }
-    }
-
-    promise_texture_ = BeginVulkanAccess(
-        vk_implementation(), vk_device(), vk_phy_device(), vk_queue(),
-        ahb_backing()->GetAhbHandle(), size(), format(), semaphore);
-    if (!promise_texture_)
+    if (!BeginVulkanAccess(context_state_->vk_context_provider(),
+                           std::move(sync_fd))) {
       return nullptr;
+    }
 
     SkColorType sk_color_type = viz::ResourceFormatToClosestSkColorType(
         /*gpu_compositing=*/true, format());
@@ -543,32 +566,9 @@
     if (!ahb_backing()->BeginRead(this, &sync_fd))
       return nullptr;
 
-    VkSemaphore semaphore = VK_NULL_HANDLE;
-    // We need to wait only if there is a valid fd.
-    if (sync_fd.is_valid()) {
-      // Import the above sync fd into a semaphore.
-      semaphore = vk_implementation()->ImportSemaphoreHandle(
-          vk_device(),
-          SemaphoreHandle(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
-                          std::move(sync_fd)));
-      if (semaphore == VK_NULL_HANDLE)
-        return nullptr;
-
-      // Submit wait semaphore to the queue. Note that Skia uses the same queue
-      // exposed by vk_queue(), so this will work due to Vulkan queue ordering.
-      if (!SubmitWaitVkSemaphore(vk_queue(), semaphore)) {
-        vkDestroySemaphore(vk_device(), semaphore, nullptr);
-        return nullptr;
-      }
-    }
-
-    auto promise_texture = BeginVulkanAccess(
-        vk_implementation(), vk_device(), vk_phy_device(), vk_queue(),
-        ahb_backing()->GetAhbHandle(), size(), format(), std::move(semaphore));
-
     mode_ = RepresentationAccessMode::kRead;
 
-    return promise_texture;
+    return promise_texture_;
   }
 
   void EndReadAccess() override {
@@ -576,7 +576,7 @@
     DCHECK(!surface_);
 
     base::ScopedFD sync_fd;
-    EndVulkanAccess(vk_implementation(), vk_device(), vk_queue(), &sync_fd);
+    EndVulkanAccess(context_state_->vk_context_provider(), &sync_fd);
     // pass this sync fd to the backing.
     ahb_backing()->EndRead(this, std::move(sync_fd));
 
@@ -616,7 +616,7 @@
     DCHECK(surface_);
 
     base::ScopedFD sync_fd;
-    EndVulkanAccess(vk_implementation(), vk_device(), vk_queue(), &sync_fd);
+    EndVulkanAccess(context_state_->vk_context_provider(), &sync_fd);
     surface_ = nullptr;
     ahb_backing()->EndWrite(std::move(sync_fd));
 
@@ -726,8 +726,12 @@
   // Check whether we are in Vulkan mode OR GL mode and accordingly create
   // Skia representation.
   if (context_state->use_vulkan_gr_context()) {
+    sk_sp<SkPromiseImageTexture> promise_texture = CreatePromiseTexture(
+        context_state->vk_context_provider(), GetAhbHandle(), size(), format());
+    if (!promise_texture)
+      return nullptr;
     return std::make_unique<SharedImageRepresentationSkiaVkAHB>(
-        manager, this, std::move(context_state));
+        manager, this, std::move(context_state), std::move(promise_texture));
   }
 
   auto* texture = GenGLTexture();
@@ -741,8 +745,8 @@
   sk_sp<SkPromiseImageTexture> promise_texture =
       SkPromiseImageTexture::Make(backend_texture);
   return std::make_unique<SharedImageRepresentationSkiaGLAHB>(
-      manager, this, std::move(context_state), promise_texture, tracker,
-      std::move(texture));
+      manager, this, std::move(context_state), std::move(promise_texture),
+      tracker, std::move(texture));
 }
 
 bool SharedImageBackingAHB::BeginWrite(base::ScopedFD* fd_to_wait_on) {
diff --git a/gpu/command_buffer/service/webgpu_decoder.cc b/gpu/command_buffer/service/webgpu_decoder.cc
index f22232b..6291b7f 100644
--- a/gpu/command_buffer/service/webgpu_decoder.cc
+++ b/gpu/command_buffer/service/webgpu_decoder.cc
@@ -33,5 +33,14 @@
 
 WebGPUDecoder::~WebGPUDecoder() {}
 
+ContextResult WebGPUDecoder::Initialize(
+    const scoped_refptr<gl::GLSurface>& surface,
+    const scoped_refptr<gl::GLContext>& context,
+    bool offscreen,
+    const gles2::DisallowedFeatures& disallowed_features,
+    const ContextCreationAttribs& attrib_helper) {
+  return ContextResult::kSuccess;
+}
+
 }  // namespace webgpu
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/webgpu_decoder.h b/gpu/command_buffer/service/webgpu_decoder.h
index af9f52e..03b3137 100644
--- a/gpu/command_buffer/service/webgpu_decoder.h
+++ b/gpu/command_buffer/service/webgpu_decoder.h
@@ -29,6 +29,16 @@
 
   ~WebGPUDecoder() override;
 
+  // WebGPU-specific initialization that's different than DecoderContext's
+  // Initialize that is tied to GLES2 concepts and a noop for WebGPU decoders.
+  virtual ContextResult Initialize() = 0;
+
+  ContextResult Initialize(const scoped_refptr<gl::GLSurface>& surface,
+                           const scoped_refptr<gl::GLContext>& context,
+                           bool offscreen,
+                           const gles2::DisallowedFeatures& disallowed_features,
+                           const ContextCreationAttribs& attrib_helper) final;
+
  protected:
   WebGPUDecoder(DecoderClient* client,
                 CommandBufferServiceBase* command_buffer_service,
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc
index 6ae8475..9d73befd 100644
--- a/gpu/command_buffer/service/webgpu_decoder_impl.cc
+++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -92,19 +92,14 @@
                     gles2::Outputter* outputter);
   ~WebGPUDecoderImpl() override;
 
+  // WebGPUDecoder implementation
+  ContextResult Initialize() override;
+
   // DecoderContext implementation.
   base::WeakPtr<DecoderContext> AsWeakPtr() override {
     NOTIMPLEMENTED();
     return nullptr;
   }
-  ContextResult Initialize(
-      const scoped_refptr<gl::GLSurface>& surface,
-      const scoped_refptr<gl::GLContext>& context,
-      bool offscreen,
-      const gles2::DisallowedFeatures& disallowed_features,
-      const ContextCreationAttribs& attrib_helper) override {
-    return ContextResult::kSuccess;
-  }
   const gles2::ContextState* GetContextState() override {
     NOTREACHED();
     return nullptr;
@@ -350,11 +345,7 @@
     : WebGPUDecoder(client, command_buffer_service, outputter),
       wire_serializer_(new WireServerCommandSerializer(client)),
       dawn_instance_(new dawn_native::Instance()),
-      dawn_procs_(dawn_native::GetProcs()),
-      dawn_device_(CreateDefaultDevice()),
-      wire_server_(new dawn_wire::WireServer(dawn_device_,
-                                             dawn_procs_,
-                                             wire_serializer_.get())) {}
+      dawn_procs_(dawn_native::GetProcs()) {}
 
 WebGPUDecoderImpl::~WebGPUDecoderImpl() {
   // Reset the wire server first so all objects are destroyed before the device.
@@ -365,14 +356,28 @@
   }
 }
 
+ContextResult WebGPUDecoderImpl::Initialize() {
+  dawn_device_ = CreateDefaultDevice();
+  if (dawn_device_ == nullptr) {
+    return ContextResult::kFatalFailure;
+  }
+
+  wire_server_ = std::make_unique<dawn_wire::WireServer>(
+      dawn_device_, dawn_procs_, wire_serializer_.get());
+
+  return ContextResult::kSuccess;
+}
+
 DawnDevice WebGPUDecoderImpl::CreateDefaultDevice() {
   dawn_instance_->DiscoverDefaultAdapters();
   std::vector<dawn_native::Adapter> adapters = dawn_instance_->GetAdapters();
-  for (size_t i = 0; i < adapters.size(); ++i) {
-    return adapters[i].CreateDevice();
+  for (dawn_native::Adapter adapter : adapters) {
+    if (adapter.GetBackendType() != dawn_native::BackendType::Null &&
+        adapter.GetBackendType() != dawn_native::BackendType::OpenGL) {
+      return adapter.CreateDevice();
+    }
   }
-  NOTREACHED();
-  return {};
+  return nullptr;
 }
 
 const char* WebGPUDecoderImpl::GetCommandName(unsigned int command_id) const {
diff --git a/gpu/command_buffer/service/webgpu_decoder_unittest.cc b/gpu/command_buffer/service/webgpu_decoder_unittest.cc
index e9ff2f5..5b9a81b8 100644
--- a/gpu/command_buffer/service/webgpu_decoder_unittest.cc
+++ b/gpu/command_buffer/service/webgpu_decoder_unittest.cc
@@ -27,8 +27,13 @@
     command_buffer_service_.reset(new FakeCommandBufferServiceBase());
     decoder_.reset(WebGPUDecoder::Create(nullptr, command_buffer_service_.get(),
                                          &outputter_));
+    if (decoder_->Initialize() != ContextResult::kSuccess) {
+      decoder_ = nullptr;
+    }
   }
 
+  bool WebGPUSupported() const { return decoder_ != nullptr; }
+
   template <typename T>
   error::Error ExecuteCmd(const T& cmd) {
     static_assert(T::kArgFlags == cmd::kFixed,
@@ -47,6 +52,11 @@
 };
 
 TEST_F(WebGPUDecoderTest, Dummy) {
+  if (!WebGPUSupported()) {
+    LOG(ERROR) << "Test skipped because WebGPU isn't supported";
+    return;
+  }
+
   cmds::Dummy dummy;
   dummy.Init();
   EXPECT_EQ(error::kNoError, ExecuteCmd(dummy));
diff --git a/gpu/command_buffer/tests/webgpu_test.cc b/gpu/command_buffer/tests/webgpu_test.cc
index eacdd134..c3673f4e 100644
--- a/gpu/command_buffer/tests/webgpu_test.cc
+++ b/gpu/command_buffer/tests/webgpu_test.cc
@@ -22,9 +22,8 @@
 WebGPUTest::WebGPUTest() = default;
 WebGPUTest::~WebGPUTest() = default;
 
-bool WebGPUTest::WebGPUSupported() {
-  // crbug.com(941685): Vulkan driver crashes on Linux FYI Release (AMD R7 240).
-  return !GPUTestBotConfig::CurrentConfigMatches("Linux AMD");
+bool WebGPUTest::WebGPUSupported() const {
+  return context_ != nullptr;
 }
 
 void WebGPUTest::SetUp() {
@@ -37,9 +36,11 @@
 }
 
 void WebGPUTest::Initialize(const Options& options) {
-  if (!WebGPUSupported()) {
+  // crbug.com(941685): Vulkan driver crashes on Linux FYI Release (AMD R7 240).
+  if (GPUTestBotConfig::CurrentConfigMatches("Linux AMD")) {
     return;
   }
+
   ContextCreationAttribs attributes;
   attributes.bind_generates_resource = false;
   attributes.enable_gles2_interface = false;
@@ -53,7 +54,10 @@
       context_->Initialize(gpu_thread_holder_->GetTaskExecutor(), attributes,
                            options.shared_memory_limits, memory_buffer_manager,
                            image_factory, channel_manager);
-  DCHECK_EQ(result, ContextResult::kSuccess);
+  if (result != ContextResult::kSuccess) {
+    context_ = nullptr;
+    return;
+  }
 
   DawnProcTable procs = webgpu()->GetProcs();
   dawnSetProcs(&procs);
@@ -69,9 +73,10 @@
 
 TEST_F(WebGPUTest, Dummy) {
   if (!WebGPUSupported()) {
-    LOG(ERROR) << "Test skipped";
+    LOG(ERROR) << "Test skipped because WebGPU isn't supported";
     return;
   }
+
   Initialize(WebGPUTest::Options());
   webgpu()->Dummy();
 }
diff --git a/gpu/command_buffer/tests/webgpu_test.h b/gpu/command_buffer/tests/webgpu_test.h
index acd37899..45f4803 100644
--- a/gpu/command_buffer/tests/webgpu_test.h
+++ b/gpu/command_buffer/tests/webgpu_test.h
@@ -34,7 +34,7 @@
   WebGPUTest();
   ~WebGPUTest() override;
 
-  bool WebGPUSupported();
+  bool WebGPUSupported() const;
   void SetUp() override;
   void TearDown() override;
 
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc
index 8f25b70..4dd1f2d05 100644
--- a/gpu/ipc/in_process_command_buffer.cc
+++ b/gpu/ipc/in_process_command_buffer.cc
@@ -551,8 +551,16 @@
       DLOG(ERROR) << "ContextResult::kFatalFailure: WebGPU not enabled";
       return gpu::ContextResult::kFatalFailure;
     }
-    decoder_.reset(webgpu::WebGPUDecoder::Create(this, command_buffer_.get(),
-                                                 task_executor_->outputter()));
+    std::unique_ptr<webgpu::WebGPUDecoder> webgpu_decoder(
+        webgpu::WebGPUDecoder::Create(this, command_buffer_.get(),
+                                      task_executor_->outputter()));
+    gpu::ContextResult result = webgpu_decoder->Initialize();
+    if (result != gpu::ContextResult::kSuccess) {
+      DestroyOnGpuThread();
+      DLOG(ERROR) << "Failed to initializ WebGPUe decoder.";
+      return result;
+    }
+    decoder_ = std::move(webgpu_decoder);
   } else {
     // TODO(khushalsagar): A lot of this initialization code is duplicated in
     // GpuChannelManager. Pull it into a common util method.
diff --git a/gpu/ipc/service/webgpu_command_buffer_stub.cc b/gpu/ipc/service/webgpu_command_buffer_stub.cc
index 2241e15..a8c963d 100644
--- a/gpu/ipc/service/webgpu_command_buffer_stub.cc
+++ b/gpu/ipc/service/webgpu_command_buffer_stub.cc
@@ -112,10 +112,7 @@
       channel_->sync_point_manager()->CreateSyncPointClientState(
           CommandBufferNamespace::GPU_IO, command_buffer_id_, sequence_id_);
 
-  // Initialize the decoder with either the view or pbuffer GLContext.
-  ContextResult result = decoder->Initialize(
-      nullptr, nullptr, true /* offscreen */, gpu::gles2::DisallowedFeatures(),
-      init_params.attribs);
+  ContextResult result = decoder->Initialize();
   if (result != gpu::ContextResult::kSuccess) {
     DLOG(ERROR) << "Failed to initialize decoder.";
     return result;
diff --git a/gpu/vulkan/BUILD.gn b/gpu/vulkan/BUILD.gn
index 031c945..fd61fb4 100644
--- a/gpu/vulkan/BUILD.gn
+++ b/gpu/vulkan/BUILD.gn
@@ -37,6 +37,8 @@
       "vulkan_device_queue.cc",
       "vulkan_device_queue.h",
       "vulkan_export.h",
+      "vulkan_fence_helper.cc",
+      "vulkan_fence_helper.h",
       "vulkan_function_pointers.cc",
       "vulkan_function_pointers.h",
       "vulkan_implementation.cc",
@@ -100,13 +102,17 @@
         "tests/native_window.h",
         "tests/vulkan_test.cc",
         "tests/vulkan_tests_main.cc",
+        "vulkan_fence_helper_unittest.cc",
       ]
 
       deps = [
+        "//base:base",
         "//base/test:test_support",
+        "//components/viz/common:vulkan_context_provider",
         "//gpu/vulkan/init",
         "//testing/gmock",
         "//testing/gtest",
+        "//ui/gfx",
         "//ui/gfx:native_widget_types",
         "//ui/gfx/geometry",
       ]
diff --git a/gpu/vulkan/tests/vulkan_test.cc b/gpu/vulkan/tests/vulkan_test.cc
index 9f14628..bceeb2c 100644
--- a/gpu/vulkan/tests/vulkan_test.cc
+++ b/gpu/vulkan/tests/vulkan_test.cc
@@ -18,6 +18,7 @@
   EXPECT_TRUE(surface);
   EXPECT_TRUE(surface->Initialize(GetDeviceQueue(),
                                   VulkanSurface::DEFAULT_SURFACE_FORMAT));
+  EXPECT_TRUE(surface->SetSize(gfx::Size(100, 100)));
   surface->Destroy();
 }
 
@@ -26,6 +27,7 @@
   ASSERT_TRUE(surface);
   ASSERT_TRUE(surface->Initialize(GetDeviceQueue(),
                                   VulkanSurface::DEFAULT_SURFACE_FORMAT));
+  ASSERT_TRUE(surface->SetSize(gfx::Size(100, 100)));
 
   // First swap is a special case, call it first to get better errors.
   EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers());
diff --git a/gpu/vulkan/vulkan_command_buffer.cc b/gpu/vulkan/vulkan_command_buffer.cc
index d9c5a4d..b762400 100644
--- a/gpu/vulkan/vulkan_command_buffer.cc
+++ b/gpu/vulkan/vulkan_command_buffer.cc
@@ -21,8 +21,8 @@
 }
 
 VulkanCommandBuffer::~VulkanCommandBuffer() {
+  DCHECK(!submission_fence_.is_valid());
   DCHECK_EQ(static_cast<VkCommandBuffer>(VK_NULL_HANDLE), command_buffer_);
-  DCHECK_EQ(static_cast<VkFence>(VK_NULL_HANDLE), submission_fence_);
   DCHECK(!recording_);
   command_pool_->DecrementCommandBufferCount();
 }
@@ -45,27 +45,15 @@
     return false;
   }
 
-  VkFenceCreateInfo fence_create_info = {};
-  fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-  fence_create_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
-
-  result =
-      vkCreateFence(device, &fence_create_info, nullptr, &submission_fence_);
-  if (VK_SUCCESS != result) {
-    DLOG(ERROR) << "vkCreateFence(submission) failed: " << result;
-    return false;
-  }
-
   record_type_ = RECORD_TYPE_EMPTY;
   return true;
 }
 
 void VulkanCommandBuffer::Destroy() {
   VkDevice device = device_queue_->GetVulkanDevice();
-  if (VK_NULL_HANDLE != submission_fence_) {
-    DCHECK(SubmissionFinished());
-    vkDestroyFence(device, submission_fence_, nullptr);
-    submission_fence_ = VK_NULL_HANDLE;
+  if (submission_fence_.is_valid()) {
+    DCHECK(device_queue_->GetFenceHelper()->HasPassed(submission_fence_));
+    submission_fence_ = VulkanFenceHelper::FenceHandle();
   }
 
   if (VK_NULL_HANDLE != command_buffer_) {
@@ -94,15 +82,22 @@
 
   VkResult result = VK_SUCCESS;
 
-  result =
-      vkResetFences(device_queue_->GetVulkanDevice(), 1, &submission_fence_);
+  VkFence fence;
+  result = device_queue_->GetFenceHelper()->GetFence(&fence);
   if (VK_SUCCESS != result) {
-    DLOG(ERROR) << "vkResetFences() failed: " << result;
+    DLOG(ERROR) << "Failed to create fence: " << result;
     return false;
   }
 
-  result = vkQueueSubmit(device_queue_->GetVulkanQueue(), 1, &submit_info,
-                         submission_fence_);
+  result =
+      vkQueueSubmit(device_queue_->GetVulkanQueue(), 1, &submit_info, fence);
+
+  if (VK_SUCCESS != result) {
+    vkDestroyFence(device_queue_->GetVulkanDevice(), fence, nullptr);
+    submission_fence_ = VulkanFenceHelper::FenceHandle();
+  } else {
+    submission_fence_ = device_queue_->GetFenceHelper()->EnqueueFence(fence);
+  }
 
   PostExecution();
   if (VK_SUCCESS != result) {
@@ -127,13 +122,17 @@
 }
 
 void VulkanCommandBuffer::Wait(uint64_t timeout) {
-  VkDevice device = device_queue_->GetVulkanDevice();
-  vkWaitForFences(device, 1, &submission_fence_, true, timeout);
+  if (!submission_fence_.is_valid())
+    return;
+
+  device_queue_->GetFenceHelper()->Wait(submission_fence_, timeout);
 }
 
 bool VulkanCommandBuffer::SubmissionFinished() {
-  VkDevice device = device_queue_->GetVulkanDevice();
-  return VK_SUCCESS == vkGetFenceStatus(device, submission_fence_);
+  if (!submission_fence_.is_valid())
+    return true;
+
+  return device_queue_->GetFenceHelper()->HasPassed(submission_fence_);
 }
 
 void VulkanCommandBuffer::PostExecution() {
@@ -151,8 +150,7 @@
   if (record_type_ == RECORD_TYPE_DIRTY) {
     // Block if command buffer is still in use. This can be externally avoided
     // using the asynchronous SubmissionFinished() function.
-    VkDevice device = device_queue_->GetVulkanDevice();
-    vkWaitForFences(device, 1, &submission_fence_, true, UINT64_MAX);
+    Wait(UINT64_MAX);
     VkResult result = vkResetCommandBuffer(command_buffer_, 0);
     if (VK_SUCCESS != result) {
       DLOG(ERROR) << "vkResetCommandBuffer() failed: " << result;
diff --git a/gpu/vulkan/vulkan_command_buffer.h b/gpu/vulkan/vulkan_command_buffer.h
index b55b02c..0709267 100644
--- a/gpu/vulkan/vulkan_command_buffer.h
+++ b/gpu/vulkan/vulkan_command_buffer.h
@@ -10,6 +10,7 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "gpu/vulkan/vulkan_export.h"
+#include "gpu/vulkan/vulkan_fence_helper.h"
 
 namespace gpu {
 
@@ -74,7 +75,7 @@
   VulkanDeviceQueue* device_queue_;
   VulkanCommandPool* command_pool_;
   VkCommandBuffer command_buffer_ = VK_NULL_HANDLE;
-  VkFence submission_fence_ = VK_NULL_HANDLE;
+  VulkanFenceHelper::FenceHandle submission_fence_;
 
   DISALLOW_COPY_AND_ASSIGN(VulkanCommandBuffer);
 };
diff --git a/gpu/vulkan/vulkan_device_queue.cc b/gpu/vulkan/vulkan_device_queue.cc
index 4fb92a3..4c327ac 100644
--- a/gpu/vulkan/vulkan_device_queue.cc
+++ b/gpu/vulkan/vulkan_device_queue.cc
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "gpu/vulkan/vulkan_command_pool.h"
+#include "gpu/vulkan/vulkan_fence_helper.h"
 #include "gpu/vulkan/vulkan_function_pointers.h"
 
 namespace gpu {
@@ -154,6 +155,8 @@
 
   vkGetDeviceQueue(vk_device_, queue_index, 0, &vk_queue_);
 
+  cleanup_helper_ = std::make_unique<VulkanFenceHelper>(this);
+
   return true;
 }
 
@@ -173,10 +176,14 @@
   vk_queue_ = vk_queue;
   vk_queue_index_ = vk_queue_index;
   enabled_extensions_ = std::move(enabled_extensions);
+
+  cleanup_helper_ = std::make_unique<VulkanFenceHelper>(this);
   return true;
 }
 
 void VulkanDeviceQueue::Destroy() {
+  cleanup_helper_.reset();
+
   if (VK_NULL_HANDLE != owned_vk_device_) {
     vkDestroyDevice(owned_vk_device_, nullptr);
     owned_vk_device_ = VK_NULL_HANDLE;
diff --git a/gpu/vulkan/vulkan_device_queue.h b/gpu/vulkan/vulkan_device_queue.h
index 45467fb..a5b95429 100644
--- a/gpu/vulkan/vulkan_device_queue.h
+++ b/gpu/vulkan/vulkan_device_queue.h
@@ -17,6 +17,7 @@
 
 namespace gpu {
 
+class VulkanFenceHelper;
 class VulkanCommandPool;
 
 class VULKAN_EXPORT VulkanDeviceQueue {
@@ -72,6 +73,8 @@
 
   std::unique_ptr<gpu::VulkanCommandPool> CreateCommandPool();
 
+  VulkanFenceHelper* GetFenceHelper() const { return cleanup_helper_.get(); }
+
  private:
   gfx::ExtensionSet enabled_extensions_;
   VkPhysicalDevice vk_physical_device_ = VK_NULL_HANDLE;
@@ -80,6 +83,7 @@
   VkQueue vk_queue_ = VK_NULL_HANDLE;
   uint32_t vk_queue_index_ = 0;
   const VkInstance vk_instance_;
+  std::unique_ptr<VulkanFenceHelper> cleanup_helper_;
 
   DISALLOW_COPY_AND_ASSIGN(VulkanDeviceQueue);
 };
diff --git a/gpu/vulkan/vulkan_fence_helper.cc b/gpu/vulkan/vulkan_fence_helper.cc
new file mode 100644
index 0000000..a423576
--- /dev/null
+++ b/gpu/vulkan/vulkan_fence_helper.cc
@@ -0,0 +1,206 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/vulkan/vulkan_fence_helper.h"
+
+#include "base/bind.h"
+#include "gpu/vulkan/vulkan_device_queue.h"
+#include "gpu/vulkan/vulkan_function_pointers.h"
+
+namespace gpu {
+
+VulkanFenceHelper::FenceHandle::FenceHandle() = default;
+VulkanFenceHelper::FenceHandle::FenceHandle(VkFence fence,
+                                            uint64_t generation_id)
+    : fence_(fence), generation_id_(generation_id) {}
+VulkanFenceHelper::FenceHandle::FenceHandle(const FenceHandle& other) = default;
+VulkanFenceHelper::FenceHandle& VulkanFenceHelper::FenceHandle::operator=(
+    const FenceHandle& other) = default;
+
+VulkanFenceHelper::VulkanFenceHelper(VulkanDeviceQueue* device_queue)
+    : device_queue_(device_queue) {}
+
+VulkanFenceHelper::~VulkanFenceHelper() {
+  PerformImmediateCleanup();
+}
+
+// TODO(ericrk): Handle recycling fences.
+VkResult VulkanFenceHelper::GetFence(VkFence* fence) {
+  VkFenceCreateInfo create_info{
+      .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+      .pNext = nullptr,
+      .flags = 0,
+  };
+  return vkCreateFence(device_queue_->GetVulkanDevice(), &create_info,
+                       nullptr /* pAllocator */, fence);
+}
+
+VulkanFenceHelper::FenceHandle VulkanFenceHelper::EnqueueFence(VkFence fence) {
+  FenceHandle handle(fence, next_generation_++);
+  cleanup_tasks_.emplace(handle, std::move(tasks_pending_fence_));
+  tasks_pending_fence_ = std::vector<CleanupTask>();
+
+  return handle;
+}
+
+bool VulkanFenceHelper::Wait(FenceHandle handle,
+                             uint64_t timeout_in_nanoseconds) {
+  if (HasPassed(handle))
+    return true;
+
+  VkResult result =
+      vkWaitForFences(device_queue_->GetVulkanDevice(), 1, &handle.fence_, true,
+                      timeout_in_nanoseconds);
+
+  // After waiting, we can process cleanup tasks.
+  ProcessCleanupTasks();
+
+  return result == VK_SUCCESS;
+}
+
+bool VulkanFenceHelper::HasPassed(FenceHandle handle) {
+  // Process cleanup tasks which advances our |current_generation_|.
+  ProcessCleanupTasks();
+
+  return current_generation_ >= handle.generation_id_;
+}
+
+void VulkanFenceHelper::EnqueueCleanupTaskForSubmittedWork(CleanupTask task) {
+  tasks_pending_fence_.emplace_back(std::move(task));
+}
+
+void VulkanFenceHelper::ProcessCleanupTasks() {
+  VkDevice device = device_queue_->GetVulkanDevice();
+
+  // Iterate over our pending cleanup fences / tasks, advancing
+  // |current_generation_| as far as possible. This assumes that fences pass in
+  // order, which isn't a hard API guarantee, but should be close enough /
+  // efficient enough for the purpose or processing cleanup tasks.
+  //
+  // Also runs any cleanup tasks for generations that have passed. Create a
+  // temporary vector of tasks to run to avoid reentrancy issues.
+  std::vector<CleanupTask> tasks_to_run;
+  while (!cleanup_tasks_.empty()) {
+    TasksForFence& tasks_for_fence = cleanup_tasks_.front();
+    VkResult result = vkGetFenceStatus(device, tasks_for_fence.handle.fence_);
+    if (result == VK_NOT_READY)
+      break;
+    if (result != VK_SUCCESS) {
+      PerformImmediateCleanup();
+      return;
+    }
+    current_generation_ = tasks_for_fence.handle.generation_id_;
+    vkDestroyFence(device, tasks_for_fence.handle.fence_, nullptr);
+
+    tasks_to_run.insert(tasks_to_run.end(),
+                        std::make_move_iterator(tasks_for_fence.tasks.begin()),
+                        std::make_move_iterator(tasks_for_fence.tasks.end()));
+    cleanup_tasks_.pop();
+  }
+
+  for (auto& task : tasks_to_run)
+    std::move(task).Run(device_queue_, false /* device_lost */);
+}
+
+VulkanFenceHelper::FenceHandle VulkanFenceHelper::GenerateCleanupFence() {
+  if (tasks_pending_fence_.empty())
+    return FenceHandle();
+
+  VkFence fence = VK_NULL_HANDLE;
+  VkResult result = GetFence(&fence);
+  if (result != VK_SUCCESS) {
+    PerformImmediateCleanup();
+    return FenceHandle();
+  }
+  result = vkQueueSubmit(device_queue_->GetVulkanQueue(), 0, nullptr, fence);
+  if (result != VK_SUCCESS) {
+    vkDestroyFence(device_queue_->GetVulkanDevice(), fence, nullptr);
+    PerformImmediateCleanup();
+    return FenceHandle();
+  }
+
+  return EnqueueFence(fence);
+}
+
+void VulkanFenceHelper::EnqueueSemaphoreCleanupForSubmittedWork(
+    VkSemaphore semaphore) {
+  if (semaphore == VK_NULL_HANDLE)
+    return;
+
+  EnqueueSemaphoresCleanupForSubmittedWork({semaphore});
+}
+
+void VulkanFenceHelper::EnqueueSemaphoresCleanupForSubmittedWork(
+    std::vector<VkSemaphore> semaphores) {
+  if (semaphores.empty())
+    return;
+
+  EnqueueCleanupTaskForSubmittedWork(base::BindOnce(
+      [](std::vector<VkSemaphore> semaphores, VulkanDeviceQueue* device_queue,
+         bool /* is_lost */) {
+        for (VkSemaphore semaphore : semaphores) {
+          vkDestroySemaphore(device_queue->GetVulkanDevice(), semaphore,
+                             nullptr);
+        }
+      },
+      std::move(semaphores)));
+}
+
+void VulkanFenceHelper::EnqueueImageCleanupForSubmittedWork(
+    VkImage image,
+    VkDeviceMemory memory) {
+  if (image == VK_NULL_HANDLE && memory == VK_NULL_HANDLE)
+    return;
+
+  EnqueueCleanupTaskForSubmittedWork(base::BindOnce(
+      [](VkImage image, VkDeviceMemory memory, VulkanDeviceQueue* device_queue,
+         bool /* is_lost */) {
+        if (image != VK_NULL_HANDLE)
+          vkDestroyImage(device_queue->GetVulkanDevice(), image, nullptr);
+        if (memory != VK_NULL_HANDLE)
+          vkFreeMemory(device_queue->GetVulkanDevice(), memory, nullptr);
+      },
+      image, memory));
+}
+
+void VulkanFenceHelper::PerformImmediateCleanup() {
+  // Rather than caring about fences, just wait for queue idle if possible.
+  VkResult result = vkQueueWaitIdle(device_queue_->GetVulkanQueue());
+  // Wait can only fail for three reasons - device loss, host OOM, device OOM.
+  // If we hit an OOM, treat this as a crash. There isn't a great way to
+  // recover from this.
+  CHECK(result == VK_SUCCESS || result == VK_ERROR_DEVICE_LOST);
+  bool device_lost = result == VK_ERROR_DEVICE_LOST;
+
+  // Run all cleanup tasks. Create a temporary vector of tasks to run to avoid
+  // reentrancy issues.
+  std::vector<CleanupTask> tasks_to_run;
+  tasks_to_run.insert(tasks_to_run.end(),
+                      std::make_move_iterator(tasks_pending_fence_.begin()),
+                      std::make_move_iterator(tasks_pending_fence_.end()));
+  tasks_pending_fence_.clear();
+  while (!cleanup_tasks_.empty()) {
+    auto& tasks_for_fence = cleanup_tasks_.front();
+    vkDestroyFence(device_queue_->GetVulkanDevice(),
+                   tasks_for_fence.handle.fence_, nullptr);
+    tasks_to_run.insert(tasks_to_run.end(),
+                        std::make_move_iterator(tasks_for_fence.tasks.begin()),
+                        std::make_move_iterator(tasks_for_fence.tasks.end()));
+    cleanup_tasks_.pop();
+  }
+  for (auto& task : tasks_to_run)
+    std::move(task).Run(device_queue_, device_lost);
+}
+
+VulkanFenceHelper::TasksForFence::TasksForFence(FenceHandle handle,
+                                                std::vector<CleanupTask> tasks)
+    : handle(handle), tasks(std::move(tasks)) {}
+VulkanFenceHelper::TasksForFence::~TasksForFence() = default;
+VulkanFenceHelper::TasksForFence::TasksForFence(TasksForFence&& other) =
+    default;
+VulkanFenceHelper::TasksForFence&
+VulkanFenceHelper::TasksForFence::TasksForFence::operator=(
+    TasksForFence&& other) = default;
+
+}  // namespace gpu
diff --git a/gpu/vulkan/vulkan_fence_helper.h b/gpu/vulkan/vulkan_fence_helper.h
new file mode 100644
index 0000000..a4d5827
--- /dev/null
+++ b/gpu/vulkan/vulkan_fence_helper.h
@@ -0,0 +1,122 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_VULKAN_VULKAN_FENCE_HELPER_H_
+#define GPU_VULKAN_VULKAN_FENCE_HELPER_H_
+
+#include <vulkan/vulkan.h>
+
+#include "base/callback.h"
+#include "base/containers/queue.h"
+#include "base/macros.h"
+#include "gpu/vulkan/vulkan_export.h"
+
+namespace gpu {
+
+class VulkanDeviceQueue;
+
+class VULKAN_EXPORT VulkanFenceHelper {
+ public:
+  explicit VulkanFenceHelper(VulkanDeviceQueue* device_queue);
+  ~VulkanFenceHelper();
+
+  // Class representing a fence registered with this system. Should be treated
+  // as an opaque handle.
+  class FenceHandle {
+   public:
+    FenceHandle();
+    FenceHandle(const FenceHandle& other);
+    FenceHandle& operator=(const FenceHandle& other);
+
+    bool is_valid() const { return fence_ != VK_NULL_HANDLE; }
+
+   private:
+    friend class VulkanFenceHelper;
+    FenceHandle(VkFence fence, uint64_t generation_id);
+
+    VkFence fence_ = VK_NULL_HANDLE;
+    uint64_t generation_id_ = 0;
+  };
+
+  // General fence management functions. Should be used by any Chrome code
+  // which creates / submits fences. By registering fences with this class and
+  // checking them via the returned FenceHandle, we are able to leverage these
+  // same fences for running cleanup tasks.
+  //
+  // In typical cases, callers will call GetFence to generate/reuse a fence,
+  // submit this fence, then call EnqueueFence to register it with this system.
+  //
+  // In cases where fences are not being generated by Chrome (or in cases where
+  // we can't use this helper, such as Skia), consumers should ensure that
+  // GenerateCleanupFence is called once per frame to allow cleanup tasks to be
+  // processed.
+  //
+  // Creates or recycles a fence.
+  VkResult GetFence(VkFence* fence);
+  // Enqueues a fence which must eventually signal (must have been submitted).
+  // This function takes ownership of the fence. Returns a FenceHandle which
+  // can be used to wait on this fence / check status.
+  // Note: This should be called immediately after submitting a fence, as
+  // calling this will attach cleanup tasks to the fence. If cleanup tasks
+  // are able to be inserted between fence submission and this call, we can
+  // end up with incorrect cleanup.
+  FenceHandle EnqueueFence(VkFence fence);
+  // Generates and submits a fence.
+  // TODO(ericrk): We should avoid this in all cases if possible.
+  FenceHandle GenerateCleanupFence();
+
+  // Helper functions which allow clients to wait for or check the statusof a
+  // fence submitted with EnqueueFence.
+  //
+  // Waits for the given fence associated with the given generation id to pass.
+  bool Wait(FenceHandle handle, uint64_t timeout_in_nanoseconds = UINT64_MAX);
+  // Checks whether the given generation id has passed.
+  bool HasPassed(FenceHandle handle);
+
+  // Cleanup helpers. Allow callers to enqueue cleanup tasks which will be run
+  // after the next fence provided by EnqueueFence or GenerateCleanupFence
+  // passes. Tasks must only be enqueued if all relevant work has already been
+  // submitted to the queue - it must be the case that the task can immediately
+  // be run after a vkQueueWaitIdle. To ensure that cleanup tasks run, callers
+  // should ensure that ProcessCleanupTasks is called once per frame.
+  using CleanupTask = base::OnceCallback<void(VulkanDeviceQueue* device_queue,
+                                              bool device_lost)>;
+  // Submits a cleanup task for already submitted work.  ProcessCleanupTasks
+  // must be called periodically to ensure these run.
+  void EnqueueCleanupTaskForSubmittedWork(CleanupTask task);
+  // Processes CleanupTasks for which a fence has passed.
+  void ProcessCleanupTasks();
+  // Helpers for common types:
+  void EnqueueSemaphoreCleanupForSubmittedWork(VkSemaphore semaphore);
+  void EnqueueSemaphoresCleanupForSubmittedWork(
+      std::vector<VkSemaphore> semaphores);
+  void EnqueueImageCleanupForSubmittedWork(VkImage image,
+                                           VkDeviceMemory memory);
+
+ private:
+  void PerformImmediateCleanup();
+
+  VulkanDeviceQueue* const device_queue_;
+
+  std::vector<CleanupTask> tasks_pending_fence_;
+  uint64_t next_generation_ = 1;
+  uint64_t current_generation_ = 0;
+
+  struct TasksForFence {
+    TasksForFence(FenceHandle handle, std::vector<CleanupTask> tasks);
+    ~TasksForFence();
+    TasksForFence(TasksForFence&& other);
+    TasksForFence& operator=(TasksForFence&& other);
+
+    FenceHandle handle;
+    std::vector<CleanupTask> tasks;
+  };
+  base::queue<TasksForFence> cleanup_tasks_;
+
+  DISALLOW_COPY_AND_ASSIGN(VulkanFenceHelper);
+};
+
+}  // namespace gpu
+
+#endif  // GPU_VULKAN_VULKAN_FENCE_HELPER_H_
diff --git a/gpu/vulkan/vulkan_fence_helper_unittest.cc b/gpu/vulkan/vulkan_fence_helper_unittest.cc
new file mode 100644
index 0000000..2b68af3
--- /dev/null
+++ b/gpu/vulkan/vulkan_fence_helper_unittest.cc
@@ -0,0 +1,96 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include "base/bind.h"
+#include "gpu/vulkan/tests/basic_vulkan_test.h"
+#include "gpu/vulkan/vulkan_device_queue.h"
+#include "gpu/vulkan/vulkan_fence_helper.h"
+#include "gpu/vulkan/vulkan_function_pointers.h"
+#include "gpu/vulkan/vulkan_util.h"
+
+namespace gpu {
+
+using VulkanFenceHelperTest = BasicVulkanTest;
+
+TEST_F(VulkanFenceHelperTest, BasicFenceUsage) {
+  VulkanFenceHelper* fence_helper = GetDeviceQueue()->GetFenceHelper();
+  VkFence fence = VK_NULL_HANDLE;
+  ASSERT_TRUE(VK_SUCCESS == fence_helper->GetFence(&fence));
+  ASSERT_TRUE(fence != VK_NULL_HANDLE);
+  ASSERT_TRUE(VK_SUCCESS == vkQueueSubmit(GetDeviceQueue()->GetVulkanQueue(), 0,
+                                          nullptr, fence));
+  VulkanFenceHelper::FenceHandle fence_handle =
+      fence_helper->EnqueueFence(fence);
+  EXPECT_TRUE(fence_helper->Wait(fence_handle, UINT64_MAX));
+  EXPECT_TRUE(fence_helper->HasPassed(fence_handle));
+}
+
+TEST_F(VulkanFenceHelperTest, TestBasicCallback) {
+  VulkanFenceHelper* fence_helper = GetDeviceQueue()->GetFenceHelper();
+  bool cleanup_run = false;
+  fence_helper->EnqueueCleanupTaskForSubmittedWork(
+      base::BindOnce([](bool* cleanup_run, VulkanDeviceQueue* device_queue,
+                        bool is_lost) { *cleanup_run = true; },
+                     &cleanup_run));
+  VulkanFenceHelper::FenceHandle fence_handle =
+      fence_helper->GenerateCleanupFence();
+  EXPECT_TRUE(fence_handle.is_valid());
+  fence_helper->Wait(fence_handle, UINT64_MAX);
+  EXPECT_TRUE(cleanup_run);
+}
+
+TEST_F(VulkanFenceHelperTest, TestBasicCallbackExternalSubmission) {
+  VulkanFenceHelper* fence_helper = GetDeviceQueue()->GetFenceHelper();
+  bool cleanup_run = false;
+  fence_helper->EnqueueCleanupTaskForSubmittedWork(
+      base::BindOnce([](bool* cleanup_run, VulkanDeviceQueue* device_queue,
+                        bool is_lost) { *cleanup_run = true; },
+                     &cleanup_run));
+  VkFence fence = VK_NULL_HANDLE;
+  ASSERT_TRUE(VK_SUCCESS == fence_helper->GetFence(&fence));
+  ASSERT_TRUE(fence != VK_NULL_HANDLE);
+  ASSERT_TRUE(VK_SUCCESS == vkQueueSubmit(GetDeviceQueue()->GetVulkanQueue(), 0,
+                                          nullptr, fence));
+  VulkanFenceHelper::FenceHandle fence_handle =
+      fence_helper->EnqueueFence(fence);
+  EXPECT_TRUE(fence_handle.is_valid());
+  fence_helper->Wait(fence_handle, UINT64_MAX);
+  EXPECT_TRUE(cleanup_run);
+}
+
+TEST_F(VulkanFenceHelperTest, TestMultipleCallbacks) {
+  VulkanFenceHelper* fence_helper = GetDeviceQueue()->GetFenceHelper();
+  uint32_t cleanups_run = 0;
+  auto increment_cleanups_callback =
+      [](uint32_t expected_index, uint32_t* cleanups_run,
+         VulkanDeviceQueue* device_queue, bool is_lost) {
+        EXPECT_EQ(expected_index, *cleanups_run);
+        *cleanups_run = *cleanups_run + 1;
+      };
+
+  // Enqueue 5 callbacks.
+  for (int i = 0; i < 5; i++) {
+    fence_helper->EnqueueCleanupTaskForSubmittedWork(
+        base::BindOnce(increment_cleanups_callback, i, &cleanups_run));
+  }
+
+  // Generate a cleanup fence for the first 5 callbacks.
+  VulkanFenceHelper::FenceHandle fence_handle =
+      fence_helper->GenerateCleanupFence();
+
+  // Enqueue 5 more callbacks.
+  for (int i = 5; i < 10; i++) {
+    fence_helper->EnqueueCleanupTaskForSubmittedWork(
+        base::BindOnce(increment_cleanups_callback, i, &cleanups_run));
+  }
+
+  // Generate a cleanup fence for the next 5 callbacks.
+  fence_handle = fence_helper->GenerateCleanupFence();
+  EXPECT_TRUE(fence_handle.is_valid());
+  fence_helper->Wait(fence_handle, UINT64_MAX);
+  EXPECT_EQ(10u, cleanups_run);
+}
+}  // namespace gpu
diff --git a/headless/test/headless_protocol_browsertest.cc b/headless/test/headless_protocol_browsertest.cc
index 5fd86f9..d39dd0e 100644
--- a/headless/test/headless_protocol_browsertest.cc
+++ b/headless/test/headless_protocol_browsertest.cc
@@ -211,8 +211,8 @@
 HEADLESS_PROTOCOL_TEST(VirtualTimeInterrupt,
                        "emulation/virtual-time-interrupt.js")
 
-// Flaky on Linux. TODO(crbug.com/930717): Re-enable.
-#if defined(OS_LINUX)
+// Flaky on Linux & Mac. TODO(crbug.com/930717): Re-enable.
+#if defined(OS_LINUX) || defined(OS_MACOSX)
 #define MAYBE_VirtualTimeCrossProcessNavigation \
   DISABLED_VirtualTimeCrossProcessNavigation
 #else
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm
index c956971..491ce8d 100644
--- a/ios/chrome/browser/about_flags.mm
+++ b/ios/chrome/browser/about_flags.mm
@@ -581,6 +581,11 @@
     {"translate-manual-trigger", flag_descriptions::kTranslateManualTriggerName,
      flag_descriptions::kTranslateManualTriggerDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(translate::kTranslateMobileManualTrigger)},
+    {"omnibox-use-default-search-engine-favicon",
+     flag_descriptions::kOmniboxUseDefaultSearchEngineFaviconName,
+     flag_descriptions::kOmniboxUseDefaultSearchEngineFaviconDescription,
+     flags_ui::kOsIos,
+     FEATURE_VALUE_TYPE(kOmniboxUseDefaultSearchEngineFavicon)},
 };
 
 // Add all switches from experimental flags to |command_line|.
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
index 9914a4c5..c89742a 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -313,6 +313,11 @@
     "Switches the omnibox suggestions and omnibox itself to display the new "
     "design with favicons, new suggestion layout, rich entity support.";
 
+const char kOmniboxUseDefaultSearchEngineFaviconName[] =
+    "Default search engine favicon in the omnibox";
+const char kOmniboxUseDefaultSearchEngineFaviconDescription[] =
+    "Shows default search engine favicon in the omnibox";
+
 const char kNonModalDialogsName[] = "Use non-modal JavaScript dialogs";
 const char kNonModalDialogsDescription[] =
     "Presents JavaScript dialogs non-modally so that the user can change tabs "
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h
index b023572..89b0e27f 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -249,6 +249,11 @@
 extern const char kNewOmniboxPopupLayoutName[];
 extern const char kNewOmniboxPopupLayoutDescription[];
 
+// Title and description for the flag to show default search engine favicon in
+// the omnibox
+extern const char kOmniboxUseDefaultSearchEngineFaviconName[];
+extern const char kOmniboxUseDefaultSearchEngineFaviconDescription[];
+
 // Title and description for the flag to enable non-modal JavaScript dialogs.
 extern const char kNonModalDialogsName[];
 extern const char kNonModalDialogsDescription[];
diff --git a/ios/chrome/browser/signin/authentication_service.h b/ios/chrome/browser/signin/authentication_service.h
index 82d0c0d..c17f7fe 100644
--- a/ios/chrome/browser/signin/authentication_service.h
+++ b/ios/chrome/browser/signin/authentication_service.h
@@ -22,6 +22,7 @@
 }
 
 class AuthenticationServiceDelegate;
+class AuthenticationServiceFake;
 @class ChromeIdentity;
 class PrefService;
 class SyncSetupService;
@@ -115,6 +116,7 @@
 
  private:
   friend class AuthenticationServiceTest;
+  friend class AuthenticationServiceFake;
 
   // Method called each time the application enters foreground.
   void OnApplicationEnterForeground();
diff --git a/ios/chrome/browser/signin/authentication_service_fake.mm b/ios/chrome/browser/signin/authentication_service_fake.mm
index 604bbc4..f3566eb 100644
--- a/ios/chrome/browser/signin/authentication_service_fake.mm
+++ b/ios/chrome/browser/signin/authentication_service_fake.mm
@@ -12,6 +12,7 @@
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #include "ios/chrome/browser/signin/identity_manager_factory.h"
 #include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/public/provider/chrome/browser/signin/chrome_identity.h"
 
@@ -34,6 +35,9 @@
 
 void AuthenticationServiceFake::SignIn(ChromeIdentity* identity,
                                        const std::string& hosted_domain) {
+  // Needs to call PrepareForFirstSyncSetup to behave like
+  // AuthenticationService.
+  sync_setup_service_->PrepareForFirstSyncSetup();
   authenticated_identity_ = identity;
 }
 
diff --git a/ios/chrome/browser/ui/alert_view_controller/BUILD.gn b/ios/chrome/browser/ui/alert_view_controller/BUILD.gn
new file mode 100644
index 0000000..772e3bc
--- /dev/null
+++ b/ios/chrome/browser/ui/alert_view_controller/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("alert_view_controller") {
+  sources = [
+    "alert_view_controller.h",
+    "alert_view_controller.mm",
+  ]
+  deps = []
+  libs = [ "UIKit.framework" ]
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
diff --git a/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h
new file mode 100644
index 0000000..df06f68
--- /dev/null
+++ b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h
@@ -0,0 +1,56 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_ALERT_VIEW_CONTROLLER_ALERT_VIEW_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_UI_ALERT_VIEW_CONTROLLER_ALERT_VIEW_CONTROLLER_H_
+
+#import <UIKit/UIKit.h>
+
+// This class is a replacement for UIAlertAction.
+// Current limitations:
+//     Actions Styles are not supported.
+@interface AlertAction : NSObject
+
+// The title for this action.
+@property(nonatomic, readonly) NSString* title;
+
+// Initializes an action with |title| and |handler|.
++ (instancetype)actionWithTitle:(NSString*)title
+                        handler:(void (^)(AlertAction* action))handler;
+
+- (instancetype)init NS_UNAVAILABLE;
+
+@end
+
+// This class is a replacement for UIAlertController that supports custom
+// presentation styles, i.e. change modalPresentationStyle,
+// modalTransitionStyle, or transitioningDelegate. The style is more similar to
+// the rest of Chromium. Current limitations:
+//     Action Sheet Style is not supported.
+//     Text fields are not supported.
+@interface AlertViewController : UIViewController
+
+// The title of the alert, will appear at the top and in bold.
+@property(nonatomic, copy) NSString* title;
+
+// The message of the alert, will appear after the title.
+@property(nonatomic, copy) NSString* message;
+
+// The actions that had been added to this alert.
+@property(nonatomic, readonly) NSArray<AlertAction*>* actions;
+
+// The text fields that had been added to this alert.
+@property(nonatomic, readonly) NSArray<UITextField*>* textFields;
+
+// Adds an action to the alert.
+- (void)addAction:(AlertAction*)action;
+
+// Adds a text field and with an optional block to configure the properties of
+// the text field.
+- (void)addTextFieldWithConfigurationHandler:
+    (void (^)(UITextField* textField))configurationHandler;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_ALERT_VIEW_CONTROLLER_ALERT_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm
new file mode 100644
index 0000000..7ee218c
--- /dev/null
+++ b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm
@@ -0,0 +1,186 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h"
+
+#import "ios/chrome/common/ui_util/constraints_ui_util.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+
+// The alpha of the black chrome behind the alert view.
+constexpr CGFloat kBackgroundAlpha = 0.4;
+
+// Properties of the alert shadow.
+constexpr CGFloat kShadowOffsetX = 0;
+constexpr CGFloat kShadowOffsetY = 15;
+constexpr CGFloat kShadowRadius = 13;
+constexpr float kShadowOpacity = 0.12;
+
+// Properties of the alert view.
+constexpr CGFloat kCornerRadius = 12;
+constexpr CGFloat kMinimumWidth = 30;
+constexpr CGFloat kMinimumHeight = 30;
+constexpr CGFloat kMinimumMargin = 4;
+
+}  // namespace
+
+@interface AlertAction ()
+@property(nonatomic, readwrite) NSString* title;
+@property(nonatomic, copy) void (^handler)(AlertAction* action);
+@end
+
+@implementation AlertAction
+
++ (instancetype)actionWithTitle:(NSString*)title
+                        handler:(void (^)(AlertAction* action))handler {
+  AlertAction* action = [[AlertAction alloc] init];
+  action.title = title;
+  action.handler = handler;
+  return action;
+}
+
+@end
+
+@interface AlertViewController ()
+@property(nonatomic, readwrite) NSArray<AlertAction*>* actions;
+@property(nonatomic, readwrite) NSArray<UITextField*>* textFields;
+
+// This is the view with the shadow, white background and round corners.
+// Everything will be added here.
+@property(nonatomic, strong) UIView* contentView;
+
+@end
+
+@implementation AlertViewController
+
+@dynamic title;
+
+- (void)addAction:(AlertAction*)action {
+  if (!self.actions) {
+    self.actions = @[ action ];
+    return;
+  }
+  self.actions = [self.actions arrayByAddingObject:action];
+}
+
+- (void)addTextFieldWithConfigurationHandler:
+    (void (^)(UITextField* textField))configurationHandler {
+  // TODO(crbug.com/951303): Implement support.
+}
+
+- (void)loadView {
+  [super loadView];
+  UIView* grayBackground = [[UIView alloc] init];
+  grayBackground.backgroundColor =
+      [[UIColor blackColor] colorWithAlphaComponent:kBackgroundAlpha];
+  grayBackground.translatesAutoresizingMaskIntoConstraints = NO;
+  [self.view addSubview:grayBackground];
+  AddSameConstraints(grayBackground, self.view.safeAreaLayoutGuide);
+
+  self.contentView = [[UIView alloc] init];
+  self.contentView.backgroundColor = [UIColor whiteColor];
+  self.contentView.layer.cornerRadius = kCornerRadius;
+  self.contentView.layer.shadowOffset =
+      CGSizeMake(kShadowOffsetX, kShadowOffsetY);
+  self.contentView.layer.shadowRadius = kShadowRadius;
+  self.contentView.layer.shadowOpacity = kShadowOpacity;
+  self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
+  [self.view addSubview:self.contentView];
+  [NSLayoutConstraint activateConstraints:@[
+    // Centering
+    [self.contentView.centerXAnchor
+        constraintEqualToAnchor:self.view.centerXAnchor],
+    [self.contentView.centerYAnchor
+        constraintEqualToAnchor:self.view.centerYAnchor],
+
+    // Minimum Size
+    [self.contentView.widthAnchor
+        constraintGreaterThanOrEqualToConstant:kMinimumWidth],
+    [self.contentView.heightAnchor
+        constraintGreaterThanOrEqualToConstant:kMinimumHeight],
+
+    // Maximum Size
+    [self.contentView.topAnchor
+        constraintGreaterThanOrEqualToAnchor:self.view.safeAreaLayoutGuide
+                                                 .topAnchor
+                                    constant:kMinimumMargin],
+    [self.contentView.bottomAnchor
+        constraintLessThanOrEqualToAnchor:self.view.safeAreaLayoutGuide
+                                              .bottomAnchor
+                                 constant:-kMinimumMargin],
+    [self.contentView.trailingAnchor
+        constraintLessThanOrEqualToAnchor:self.view.safeAreaLayoutGuide
+                                              .trailingAnchor
+                                 constant:-kMinimumMargin],
+    [self.contentView.leadingAnchor
+        constraintGreaterThanOrEqualToAnchor:self.view.safeAreaLayoutGuide
+                                                 .leadingAnchor
+                                    constant:kMinimumMargin],
+
+  ]];
+
+  UIStackView* stackView = [[UIStackView alloc] init];
+  stackView.axis = UILayoutConstraintAxisVertical;
+  stackView.translatesAutoresizingMaskIntoConstraints = NO;
+  [self.contentView addSubview:stackView];
+  AddSameConstraints(stackView, self.contentView);
+
+  if (self.title.length) {
+    UILabel* titleLabel = [[UILabel alloc] init];
+    titleLabel.font =
+        [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
+    titleLabel.textAlignment = NSTextAlignmentCenter;
+    titleLabel.text = self.title;
+    titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
+    [self.contentView addSubview:titleLabel];
+
+    [NSLayoutConstraint activateConstraints:@[
+      [titleLabel.trailingAnchor
+          constraintEqualToAnchor:self.contentView.trailingAnchor],
+      [titleLabel.leadingAnchor
+          constraintEqualToAnchor:self.contentView.leadingAnchor],
+    ]];
+    [stackView addArrangedSubview:titleLabel];
+  }
+
+  if (self.message.length) {
+    UILabel* messageLabel = [[UILabel alloc] init];
+    messageLabel.numberOfLines = 0;
+    messageLabel.font =
+        [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline];
+    messageLabel.textAlignment = NSTextAlignmentCenter;
+    messageLabel.text = self.message;
+    messageLabel.translatesAutoresizingMaskIntoConstraints = NO;
+    [self.contentView addSubview:messageLabel];
+
+    [NSLayoutConstraint activateConstraints:@[
+      [messageLabel.trailingAnchor
+          constraintEqualToAnchor:self.contentView.trailingAnchor],
+      [messageLabel.leadingAnchor
+          constraintEqualToAnchor:self.contentView.leadingAnchor],
+    ]];
+    [stackView addArrangedSubview:messageLabel];
+  }
+
+  for (AlertAction* action in self.actions) {
+    UIButton* button = [UIButton buttonWithType:UIButtonTypeSystem];
+    [button setTitle:action.title forState:UIControlStateNormal];
+    button.contentHorizontalAlignment =
+        UIControlContentHorizontalAlignmentCenter;
+    button.translatesAutoresizingMaskIntoConstraints = NO;
+    [self.contentView addSubview:button];
+
+    [NSLayoutConstraint activateConstraints:@[
+      [button.trailingAnchor
+          constraintEqualToAnchor:self.contentView.trailingAnchor],
+      [button.leadingAnchor
+          constraintEqualToAnchor:self.contentView.leadingAnchor],
+    ]];
+    [stackView addArrangedSubview:button];
+  }
+}
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
index 2fd2356..4684baa 100644
--- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
@@ -316,10 +316,11 @@
   // |unifiedConsentService| may be null in unit tests.
   if (unifiedConsentService)
     unifiedConsentService->SetUrlKeyedAnonymizedDataCollectionEnabled(true);
-  SyncSetupService* syncSetupService =
-      SyncSetupServiceFactory::GetForBrowserState(_browserState);
-  syncSetupService->PrepareForFirstSyncSetup();
   if (!_unifiedConsentCoordinator.settingsLinkWasTapped) {
+    // FirstSetupComplete flag should be only turned on when the user agrees
+    // to start Sync.
+    SyncSetupService* syncSetupService =
+        SyncSetupServiceFactory::GetForBrowserState(_browserState);
     syncSetupService->SetFirstSetupComplete();
     syncSetupService->CommitSyncChanges();
   }
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn
index ccd9122bf..b4fe1e1 100644
--- a/ios/chrome/browser/ui/browser_view/BUILD.gn
+++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -44,6 +44,7 @@
     "//ios/chrome/browser/find_in_page",
     "//ios/chrome/browser/first_run",
     "//ios/chrome/browser/geolocation:geolocation_internal",
+    "//ios/chrome/browser/infobars",
     "//ios/chrome/browser/language",
     "//ios/chrome/browser/metrics:metrics_internal",
     "//ios/chrome/browser/net",
@@ -65,6 +66,7 @@
     "//ios/chrome/browser/ui/activity_services:coordinator",
     "//ios/chrome/browser/ui/activity_services/requirements",
     "//ios/chrome/browser/ui/alert_coordinator",
+    "//ios/chrome/browser/ui/authentication",
     "//ios/chrome/browser/ui/autofill:autofill",
     "//ios/chrome/browser/ui/autofill/manual_fill",
     "//ios/chrome/browser/ui/autofill/manual_fill:manual_fill_ui",
@@ -113,6 +115,7 @@
     "//ios/chrome/browser/ui/sad_tab:coordinator",
     "//ios/chrome/browser/ui/settings/sync/utils",
     "//ios/chrome/browser/ui/side_swipe",
+    "//ios/chrome/browser/ui/signin_interaction/public",
     "//ios/chrome/browser/ui/snackbar",
     "//ios/chrome/browser/ui/static_content",
     "//ios/chrome/browser/ui/tabs",
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index cd0ccb2a..749ae4d 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -42,6 +42,7 @@
 #import "ios/chrome/browser/find_in_page/find_tab_helper.h"
 #include "ios/chrome/browser/first_run/first_run.h"
 #import "ios/chrome/browser/geolocation/omnibox_geolocation_controller.h"
+#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
 #import "ios/chrome/browser/language/url_language_histogram_factory.h"
 #import "ios/chrome/browser/metrics/new_tab_page_uma.h"
 #import "ios/chrome/browser/metrics/size_class_recorder.h"
@@ -77,6 +78,7 @@
 #import "ios/chrome/browser/ui/activity_services/activity_service_legacy_coordinator.h"
 #import "ios/chrome/browser/ui/activity_services/requirements/activity_service_presentation.h"
 #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h"
+#import "ios/chrome/browser/ui/authentication/re_signin_infobar_delegate.h"
 #import "ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.h"
 #import "ios/chrome/browser/ui/browser_container/browser_container_view_controller.h"
 #import "ios/chrome/browser/ui/browser_view/browser_view_controller_dependency_factory.h"
@@ -128,8 +130,10 @@
 #import "ios/chrome/browser/ui/presenters/vertical_animation_container.h"
 #import "ios/chrome/browser/ui/reading_list/offline_page_native_content.h"
 #import "ios/chrome/browser/ui/sad_tab/sad_tab_coordinator.h"
+#import "ios/chrome/browser/ui/settings/sync/utils/sync_util.h"
 #import "ios/chrome/browser/ui/side_swipe/side_swipe_controller.h"
 #import "ios/chrome/browser/ui/side_swipe/swipe_view.h"
+#import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h"
 #import "ios/chrome/browser/ui/static_content/static_html_native_content.h"
 #import "ios/chrome/browser/ui/tabs/background_tab_animation_view.h"
 #import "ios/chrome/browser/ui/tabs/foreground_tab_animation_view.h"
@@ -378,6 +382,7 @@
                                      PasswordControllerDelegate,
                                      PreloadControllerDelegate,
                                      SideSwipeControllerDelegate,
+                                     SigninPresenter,
                                      SnapshotGeneratorDelegate,
                                      TabModelObserver,
                                      TabStripPresentation,
@@ -2031,7 +2036,7 @@
   self.infobarContainerCoordinator = [[InfobarContainerCoordinator alloc]
       initWithBaseViewController:self
                     browserState:_browserState
-                        tabModel:self.tabModel];
+                    webStateList:self.tabModel.webStateList];
   self.infobarContainerCoordinator.commandDispatcher = self.dispatcher;
   self.infobarContainerCoordinator.positioner = self;
   self.infobarContainerCoordinator.syncPresenter = self;
@@ -4392,6 +4397,27 @@
   DCHECK(tab);
   _temporaryNativeController = nil;
 
+  // When adding new tabs, check what kind of reminder infobar should
+  // be added to the new tab. Try to add only one of them.
+  // This check is done when a new tab is added either through the Tools Menu
+  // "New Tab", through a long press on the Tab Switcher button "New Tab", and
+  // through creating a New Tab from the Tab Switcher. This method is called
+  // after a new tab has added and finished initial navigation. If this is added
+  // earlier, the initial navigation may end up clearing the infobar(s) that are
+  // just added.
+  web::WebState* webState = tab.webState;
+  DCHECK(webState);
+
+  infobars::InfoBarManager* infoBarManager =
+      InfoBarManagerImpl::FromWebState(webState);
+  NSString* tabID = TabIdTabHelper::FromWebState(webState)->tab_id();
+  [[UpgradeCenter sharedInstance] addInfoBarToManager:infoBarManager
+                                             forTabId:tabID];
+  if (!ReSignInInfoBarDelegate::Create(self.browserState, tab,
+                                       self /* id<SigninPresenter> */)) {
+    DisplaySyncErrors(self.browserState, tab, self /* id<SyncPresenter> */);
+  }
+
   // The rest of this function initiates the new tab animation, which is
   // phone-specific.  Call the foreground tab added completion block; for
   // iPhones, this will get executed after the animation has finished.
@@ -4841,6 +4867,12 @@
   }
 }
 
+#pragma mark - SigninPresenter
+
+- (void)showSignin:(ShowSigninCommand*)command {
+  [self.dispatcher showSignin:command baseViewController:self];
+}
+
 #pragma mark - SyncPresenter (Public)
 
 - (void)showReauthenticateSignin {
diff --git a/ios/chrome/browser/ui/infobars/BUILD.gn b/ios/chrome/browser/ui/infobars/BUILD.gn
index 2c41579..ea440e7e 100644
--- a/ios/chrome/browser/ui/infobars/BUILD.gn
+++ b/ios/chrome/browser/ui/infobars/BUILD.gn
@@ -18,15 +18,10 @@
     "//ios/chrome/browser",
     "//ios/chrome/browser/infobars",
     "//ios/chrome/browser/infobars:badge",
-    "//ios/chrome/browser/tabs",
-    "//ios/chrome/browser/ui/authentication",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/coordinators:chrome_coordinators",
     "//ios/chrome/browser/ui/fullscreen",
     "//ios/chrome/browser/ui/infobars/coordinators",
-    "//ios/chrome/browser/ui/settings/sync/utils",
-    "//ios/chrome/browser/ui/signin_interaction/public",
-    "//ios/chrome/browser/ui/translate",
     "//ios/chrome/browser/upgrade",
     "//ios/chrome/browser/web:tab_id_tab_helper",
     "//ios/chrome/browser/web_state_list",
diff --git a/ios/chrome/browser/ui/infobars/infobar_container_coordinator.h b/ios/chrome/browser/ui/infobars/infobar_container_coordinator.h
index 2a06c6e..6d01424 100644
--- a/ios/chrome/browser/ui/infobars/infobar_container_coordinator.h
+++ b/ios/chrome/browser/ui/infobars/infobar_container_coordinator.h
@@ -12,18 +12,19 @@
 }
 
 @class CommandDispatcher;
-@class TabModel;
 @protocol InfobarPositioner;
 @protocol SyncPresenter;
+class WebStateList;
 
 // Coordinator that owns and manages an InfobarContainer.
 @interface InfobarContainerCoordinator : ChromeCoordinator
 
-// TODO(crbug.com/892376): Stop passing TabModel and use WebStateList instead.
+// TODO(crbug.com/892376): Pass a Browser object instead of BrowserState and
+// WebStateList once BVC has a Browser pointer.
 - (instancetype)initWithBaseViewController:(UIViewController*)viewController
                               browserState:
                                   (ios::ChromeBrowserState*)browserState
-                                  tabModel:(TabModel*)tabModel
+                              webStateList:(WebStateList*)webStateList
     NS_DESIGNATED_INITIALIZER;
 ;
 
diff --git a/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm b/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm
index efdd1b3..8b88fc3 100644
--- a/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm
+++ b/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm
@@ -17,7 +17,6 @@
 #import "ios/chrome/browser/ui/infobars/infobar_feature.h"
 #import "ios/chrome/browser/ui/infobars/infobar_positioner.h"
 #include "ios/chrome/browser/ui/infobars/legacy_infobar_container_view_controller.h"
-#import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h"
 #include "ios/chrome/browser/upgrade/upgrade_center.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -30,11 +29,9 @@
 const double kBannerPresentationDurationInSeconds = 6.0;
 }  // namespace
 
-@interface InfobarContainerCoordinator () <
-    InfobarContainerConsumer,
-    SigninPresenter>
+@interface InfobarContainerCoordinator () <InfobarContainerConsumer>
 
-@property(nonatomic, assign) TabModel* tabModel;
+@property(nonatomic, assign) WebStateList* webStateList;
 
 // ViewController of the Infobar currently being presented, can be nil.
 @property(nonatomic, weak) UIViewController* infobarViewController;
@@ -53,11 +50,11 @@
 - (instancetype)initWithBaseViewController:(UIViewController*)viewController
                               browserState:
                                   (ios::ChromeBrowserState*)browserState
-                                  tabModel:(TabModel*)tabModel {
+                              webStateList:(WebStateList*)webStateList {
   self = [super initWithBaseViewController:viewController
                               browserState:browserState];
   if (self) {
-    _tabModel = tabModel;
+    _webStateList = webStateList;
   }
   return self;
 }
@@ -85,11 +82,9 @@
   self.mediator = [[InfobarContainerMediator alloc]
       initWithConsumer:self
         legacyConsumer:self.legacyContainerViewController
-          browserState:self.browserState
-              tabModel:self.tabModel];
+          webStateList:self.webStateList];
 
   self.mediator.syncPresenter = self.syncPresenter;
-  self.mediator.signinPresenter = self;
 
   [[UpgradeCenter sharedInstance] registerClient:self.mediator
                                   withDispatcher:self.dispatcher];
@@ -202,11 +197,4 @@
   [infobarCoordinator presentInfobarModal];
 }
 
-#pragma mark - SigninPresenter
-
-- (void)showSignin:(ShowSigninCommand*)command {
-  [self.dispatcher showSignin:command
-           baseViewController:self.baseViewController];
-}
-
 @end
diff --git a/ios/chrome/browser/ui/infobars/infobar_container_mediator.h b/ios/chrome/browser/ui/infobars/infobar_container_mediator.h
index 1f37b9f..e5a1882 100644
--- a/ios/chrome/browser/ui/infobars/infobar_container_mediator.h
+++ b/ios/chrome/browser/ui/infobars/infobar_container_mediator.h
@@ -10,25 +10,21 @@
 #import "ios/chrome/browser/ui/infobars/infobar_badge_ui_delegate.h"
 #include "ios/chrome/browser/upgrade/upgrade_center.h"
 
-namespace ios {
-class ChromeBrowserState;
-}
-
 @protocol InfobarContainerConsumer;
 @protocol SigninPresenter;
 @protocol SyncPresenter;
-@class TabModel;
+class WebStateList;
 
 @interface InfobarContainerMediator
     : NSObject <InfobarBadgeUIDelegate, UpgradeCenterClient>
 
 // Designated initializer. None of the parameters are retained.
-// TODO(crbug.com/927064): BrowserState shouldn't be passed to the mediator, the
-// legacy consumer won't be needed once legacyInfobars are no longer supported.
+// TODO(crbug.com/927064): The legacy consumer won't be needed once
+// legacyInfobars are no longer supported.
 - (instancetype)initWithConsumer:(id<InfobarContainerConsumer>)consumer
                   legacyConsumer:(id<InfobarContainerConsumer>)legacyConsumer
-                    browserState:(ios::ChromeBrowserState*)browserState
-                        tabModel:(TabModel*)tabModel NS_DESIGNATED_INITIALIZER;
+                    webStateList:(WebStateList*)webStateList
+    NS_DESIGNATED_INITIALIZER;
 ;
 
 - (instancetype)init NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/ui/infobars/infobar_container_mediator.mm b/ios/chrome/browser/ui/infobars/infobar_container_mediator.mm
index 8002bdbe..9eb45ea6 100644
--- a/ios/chrome/browser/ui/infobars/infobar_container_mediator.mm
+++ b/ios/chrome/browser/ui/infobars/infobar_container_mediator.mm
@@ -7,13 +7,8 @@
 #include "ios/chrome/browser/infobars/infobar_badge_tab_helper.h"
 #include "ios/chrome/browser/infobars/infobar_container_ios.h"
 #include "ios/chrome/browser/infobars/infobar_manager_impl.h"
-#import "ios/chrome/browser/tabs/tab.h"
-#import "ios/chrome/browser/tabs/tab_model.h"
-#import "ios/chrome/browser/tabs/tab_model_observer.h"
-#import "ios/chrome/browser/ui/authentication/re_signin_infobar_delegate.h"
 #import "ios/chrome/browser/ui/infobars/infobar_container_consumer.h"
 #import "ios/chrome/browser/ui/infobars/infobar_feature.h"
-#import "ios/chrome/browser/ui/settings/sync/utils/sync_util.h"
 #include "ios/chrome/browser/upgrade/upgrade_center.h"
 #import "ios/chrome/browser/web/tab_id_tab_helper.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
@@ -23,20 +18,14 @@
 #error "This file requires ARC support."
 #endif
 
-@interface InfobarContainerMediator ()<TabModelObserver,
-                                       WebStateListObserving> {
+@interface InfobarContainerMediator () <WebStateListObserving> {
   // A single infobar container handles all infobars in all tabs. It keeps
-  // track of infobars for current tab (accessed via infobar helper of
-  // the current tab).
+  // track of infobars for current Webstate.
   std::unique_ptr<InfoBarContainerIOS> _infoBarContainer;
   // Bridge class to deliver webStateList notifications.
   std::unique_ptr<WebStateListObserverBridge> _webStateListObserver;
 }
 
-// The mediator's BrowserState.
-@property(nonatomic, assign, readonly) ios::ChromeBrowserState* browserState;
-// The mediator's TabModel.
-@property(nonatomic, weak, readonly) TabModel* tabModel;
 // The WebStateList that this mediator listens for any changes on its Webstates.
 @property(nonatomic, assign) WebStateList* webStateList;
 
@@ -48,66 +37,30 @@
 
 - (instancetype)initWithConsumer:(id<InfobarContainerConsumer>)consumer
                   legacyConsumer:(id<InfobarContainerConsumer>)legacyConsumer
-                    browserState:(ios::ChromeBrowserState*)browserState
-                        tabModel:(TabModel*)tabModel {
+                    webStateList:(WebStateList*)webStateList {
   self = [super init];
   if (self) {
-    _browserState = browserState;
-    _tabModel = tabModel;
-    _webStateList = _tabModel.webStateList;
+    _webStateList = webStateList;
 
     _infoBarContainer.reset(new InfoBarContainerIOS(consumer, legacyConsumer));
     infobars::InfoBarManager* infoBarManager = nullptr;
-    if (_tabModel.currentTab) {
-      DCHECK(_tabModel.currentTab.webState);
+    if (_webStateList->GetActiveWebState()) {
       infoBarManager =
-          InfoBarManagerImpl::FromWebState(_tabModel.currentTab.webState);
+          InfoBarManagerImpl::FromWebState(_webStateList->GetActiveWebState());
     }
     _infoBarContainer->ChangeInfoBarManager(infoBarManager);
 
     _webStateListObserver = std::make_unique<WebStateListObserverBridge>(self);
     _webStateList->AddObserver(_webStateListObserver.get());
-    [_tabModel addObserver:self];
   }
   return self;
 }
 
 - (void)dealloc {
-  [_tabModel removeObserver:self];
   _webStateList->RemoveObserver(_webStateListObserver.get());
   _webStateListObserver.reset();
 }
 
-#pragma mark - TabModelObserver
-
-// TODO(crbug.com/892376): Stop observing TabModel and use WebStateList instead.
-- (void)tabModel:(TabModel*)model
-    newTabWillOpen:(Tab*)tab
-      inBackground:(BOOL)background {
-  // When adding new tabs, check what kind of reminder infobar should
-  // be added to the new tab. Try to add only one of them.
-  // This check is done when a new tab is added either through the Tools Menu
-  // "New Tab", through a long press on the Tab Switcher button "New Tab", and
-  // through creating a New Tab from the Tab Switcher. This method is called
-  // after a new tab has added and finished initial navigation. If this is added
-  // earlier, the initial navigation may end up clearing the infobar(s) that are
-  // just added.
-  web::WebState* webState = tab.webState;
-  DCHECK(webState);
-
-  infobars::InfoBarManager* infoBarManager =
-      InfoBarManagerImpl::FromWebState(webState);
-  NSString* tabID = TabIdTabHelper::FromWebState(webState)->tab_id();
-  [[UpgradeCenter sharedInstance] addInfoBarToManager:infoBarManager
-                                             forTabId:tabID];
-  if (!ReSignInInfoBarDelegate::Create(
-          self.browserState, tab,
-          self.signinPresenter /* id<SigninPresenter> */)) {
-    DisplaySyncErrors(self.browserState, tab,
-                      self.syncPresenter /* id<SyncPresenter> */);
-  }
-}
-
 #pragma mark - WebStateListObserver
 
 - (void)webStateList:(WebStateList*)webStateList
@@ -184,11 +137,10 @@
 #pragma mark - UpgradeCenterClient
 
 - (void)showUpgrade:(UpgradeCenter*)center {
-  DCHECK(self.tabModel.webStateList);
+  DCHECK(self.webStateList);
   // Add an infobar on all the open tabs.
-  WebStateList* webStateList = self.tabModel.webStateList;
-  for (int index = 0; index < webStateList->count(); ++index) {
-    web::WebState* webState = webStateList->GetWebStateAt(index);
+  for (int index = 0; index < self.webStateList->count(); ++index) {
+    web::WebState* webState = self.webStateList->GetWebStateAt(index);
     NSString* tabID = TabIdTabHelper::FromWebState(webState)->tab_id();
     infobars::InfoBarManager* infoBarManager =
         InfoBarManagerImpl::FromWebState(webState);
diff --git a/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h b/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h
index 1d3f1d8..73f2a0a 100644
--- a/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h
+++ b/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h
@@ -14,9 +14,11 @@
 @protocol AdvancedSigninSettingsCoordinatorDelegate <NSObject>
 
 // Called when the user closes AdvancedSigninSettingsCoordinator.
+// |signedin|, YES if the view is confirmed or aborted, and NO if the view is
+// canceled.
 - (void)advancedSigninSettingsCoordinatorDidClose:
             (AdvancedSigninSettingsCoordinator*)coordinator
-                                          success:(BOOL)success;
+                                         signedin:(BOOL)signedin;
 
 @end
 
@@ -30,10 +32,11 @@
 // Global dispatcher.
 @property(nonatomic, weak) id<ApplicationCommands> dispatcher;
 
-// Cancels the coordinator, and calls the delegate. This method does nothing if
-// called twice.
+// Aborts the sign-in flow, and calls the delegate. Aborting the Advanced
+// sync settings doesn't sign out the user. The sync is left unsetup and doesn't
+// start. This method does nothing if called twice.
 // |dismiss|, dismisses the view controller if YES.
-- (void)cancelWithDismiss:(BOOL)dismiss;
+- (void)abortWithDismiss:(BOOL)dismiss;
 
 @end
 
diff --git a/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.mm
index c1cdaac..7ccbf7c7 100644
--- a/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.mm
@@ -27,6 +27,16 @@
 
 using l10n_util::GetNSString;
 
+// Advanced sign-in settings result.
+typedef NS_ENUM(NSInteger, AdvancedSigninSettingsCoordinatorResult) {
+  // The user confirmed the advanced sync settings.
+  AdvancedSyncSettingsCoordinatorResultConfirm,
+  // The user canceled the advanced sync settings.
+  AdvancedSigninSettingsCoordinatorResultCancel,
+  // Chrome aborted the advanced sync settings.
+  AdvancedSigninSettingsCoordinatorResultInterrupted,
+};
+
 @interface AdvancedSigninSettingsCoordinator ()
 
 // Google services settings coordinator.
@@ -68,41 +78,61 @@
                  completion:nil];
 }
 
-- (void)cancelWithDismiss:(BOOL)dismiss {
+- (void)abortWithDismiss:(BOOL)dismiss {
   if (!self.advancedSigninSettingsNavigationController) {
     return;
   }
   DCHECK_EQ(self.advancedSigninSettingsNavigationController,
             self.baseViewController.presentedViewController);
-  void (^completion)(void) = ^{
-    [self finishedWithSuccess:NO];
-  };
   if (dismiss) {
-    [self.baseViewController dismissViewControllerAnimated:YES
-                                                completion:completion];
+    [self dismissViewControllerAndFinishWithResult:
+              AdvancedSigninSettingsCoordinatorResultInterrupted];
   } else {
-    completion();
+    [self
+        finishedWithResult:AdvancedSigninSettingsCoordinatorResultInterrupted];
   }
 }
 
 #pragma mark - Private
 
 // Called once the view controller has been removed (if needed).
-// |success|, YES if the user accepts to sync.
-- (void)finishedWithSuccess:(BOOL)success {
+// |result|, YES if the user accepts to sync.
+- (void)finishedWithResult:(AdvancedSigninSettingsCoordinatorResult)result {
   DCHECK(self.advancedSigninSettingsNavigationController);
-  if (success) {
-    SyncSetupServiceFactory::GetForBrowserState(self.browserState)
-        ->SetFirstSetupComplete();
-  } else {
-    AuthenticationServiceFactory::GetForBrowserState(self.browserState)
-        ->SignOut(signin_metrics::ABORT_SIGNIN, nil);
+  SyncSetupService* syncSetupService =
+      SyncSetupServiceFactory::GetForBrowserState(self.browserState);
+  switch (result) {
+    case AdvancedSyncSettingsCoordinatorResultConfirm:
+      base::RecordAction(
+          base::UserMetricsAction("Signin_Signin_ConfirmAdvancedSyncSettings"));
+      if (syncSetupService->IsSyncEnabled()) {
+        // FirstSetupComplete flag should be only turned on when the user agrees
+        // to start Sync.
+        syncSetupService->PrepareForFirstSyncSetup();
+        syncSetupService->SetFirstSetupComplete();
+      }
+      break;
+    case AdvancedSigninSettingsCoordinatorResultCancel:
+      base::RecordAction(base::UserMetricsAction(
+          "Signin_Signin_ConfirmCancelAdvancedSyncSettings"));
+      syncSetupService->CommitSyncChanges();
+      AuthenticationServiceFactory::GetForBrowserState(self.browserState)
+          ->SignOut(signin_metrics::ABORT_SIGNIN, nil);
+      break;
+    case AdvancedSigninSettingsCoordinatorResultInterrupted:
+      base::RecordAction(
+          base::UserMetricsAction("Signin_Signin_AbortAdvancedSyncSettings"));
+      break;
   }
   [self.googleServicesSettingsCoordinator stop];
   self.googleServicesSettingsCoordinator.delegate = nil;
   self.googleServicesSettingsCoordinator = nil;
+  DCHECK(!syncSetupService->HasUncommittedChanges())
+      << "-[GoogleServicesSettingsCoordinator stop] should commit sync "
+         "changes.";
+  BOOL signedin = result != AdvancedSigninSettingsCoordinatorResultCancel;
   [self.delegate advancedSigninSettingsCoordinatorDidClose:self
-                                                   success:success];
+                                                  signedin:signedin];
   self.advancedSigninSettingsNavigationController = nil;
 }
 
@@ -163,15 +193,10 @@
 // sync preferences chosen by the user, starts the sync, close the completion
 // callback and closes the advanced sign-in settings.
 - (void)navigationConfirmButtonAction {
-  base::RecordAction(
-      base::UserMetricsAction("Signin_Signin_ConfirmAdvancedSyncSettings"));
   DCHECK_EQ(self.advancedSigninSettingsNavigationController,
             self.baseViewController.presentedViewController);
-  void (^completion)(void) = ^{
-    [self finishedWithSuccess:YES];
-  };
-  [self.baseViewController dismissViewControllerAnimated:YES
-                                              completion:completion];
+  [self dismissViewControllerAndFinishWithResult:
+            AdvancedSyncSettingsCoordinatorResultConfirm];
 }
 
 // Called when a button of |self.cancelConfirmationAlertCoordinator| is pressed.
@@ -180,13 +205,25 @@
   [self.cancelConfirmationAlertCoordinator stop];
   self.cancelConfirmationAlertCoordinator = nil;
   if (cancelSync) {
-    base::RecordAction(base::UserMetricsAction(
-        "Signin_Signin_ConfirmCancelAdvancedSyncSettings"));
-    [self cancelWithDismiss:YES];
+    [self dismissViewControllerAndFinishWithResult:
+              AdvancedSigninSettingsCoordinatorResultCancel];
   } else {
     base::RecordAction(base::UserMetricsAction(
         "Signin_Signin_CancelCancelAdvancedSyncSettings"));
   }
 }
 
+// Dismisses the current view controller with animation, and calls
+// -[self finishedWithResult:] with |result|.
+- (void)dismissViewControllerAndFinishWithResult:
+    (AdvancedSigninSettingsCoordinatorResult)result {
+  DCHECK_EQ(self.advancedSigninSettingsNavigationController,
+            self.baseViewController.presentedViewController);
+  [self.baseViewController
+      dismissViewControllerAnimated:YES
+                         completion:^{
+                           [self finishedWithResult:result];
+                         }];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
index add9152..fb53eed 100644
--- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
@@ -113,11 +113,14 @@
     SyncSetupService* syncSetupService =
         SyncSetupServiceFactory::GetForBrowserState(self.browserState);
     if (self.mode == GoogleServicesSettingsModeSettings &&
-        !syncSetupService->IsFirstSetupComplete()) {
-      // Sign-in workflow has been interrupted. FirstSetupComplete flag needs to
-      // be turned on.
-      syncSetupService->PrepareForFirstSyncSetup();
-      syncSetupService->SetFirstSetupComplete();
+        !syncSetupService->IsFirstSetupComplete() &&
+        syncSetupService->IsSyncEnabled()) {
+      // Google services settings has been opened in the settings mode, and
+      // FirstSetupComplete is off, this means the user never accepted or
+      // refused to turn Sync on.
+      // When closing, FirstSetupComplete is still off, so the user doesn't
+      // want to turn Sync on. To acknowledge, Sync has to be turned off.
+      syncSetupService->SetSyncEnabled(false);
     }
     syncSetupService->CommitSyncChanges();
   }
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
index 99d6303..f9279e3 100644
--- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
@@ -96,6 +96,8 @@
 
 // Returns YES if the user is authenticated.
 @property(nonatomic, assign, readonly) BOOL isAuthenticated;
+// Returns YES if Sync setup is in progress.
+@property(nonatomic, assign, readonly) BOOL isSyncSetupInProgress;
 // Returns YES if the user cannot turn on sync for enterprise policy reasons.
 @property(nonatomic, assign, readonly) BOOL isSyncDisabledByAdministrator;
 // Returns YES if the user is allowed to turn on sync (even if there is a sync
@@ -239,10 +241,11 @@
   self.accountItem.image =
       [self.resizedAvatarCache resizedAvatarForIdentity:identity];
   self.accountItem.text = identity.userFullName;
-  if (self.syncSetupService->HasFinishedInitialSetup()) {
-    self.accountItem.detailText = identity.userEmail;
-  } else {
+  if (self.mode == GoogleServicesSettingsModeAdvancedSigninSettings ||
+      self.isSyncSetupInProgress) {
     self.accountItem.detailText = GetNSString(IDS_IOS_SYNC_SETUP_IN_PROGRESS);
+  } else {
+    self.accountItem.detailText = identity.userEmail;
   }
 }
 
@@ -408,21 +411,28 @@
 - (BOOL)updateSyncChromeDataItem {
   TableViewModel* model = self.consumer.tableViewModel;
   if (self.isSyncCanBeAvailable) {
-    if (self.syncChromeDataSwitchItem) {
-      BOOL needsUpdate = self.syncChromeDataSwitchItem.on !=
-                         self.syncSetupService->IsSyncingAllDataTypes();
-      self.syncChromeDataSwitchItem.on = self.syncSetupService->IsSyncEnabled();
-      return needsUpdate;
+    BOOL needsUpdate = NO;
+    if (!self.syncChromeDataSwitchItem) {
+      self.syncChromeDataSwitchItem =
+          [self switchItemWithItemType:SyncChromeDataItemType
+                          textStringID:
+                              IDS_IOS_GOOGLE_SERVICES_SETTINGS_SYNC_CHROME_DATA
+                        detailStringID:0
+                              dataType:0];
+      [model addItem:self.syncChromeDataSwitchItem
+          toSectionWithIdentifier:SyncSectionIdentifier];
+      needsUpdate = YES;
     }
-    self.syncChromeDataSwitchItem = [self
-        switchItemWithItemType:SyncChromeDataItemType
-                  textStringID:IDS_IOS_GOOGLE_SERVICES_SETTINGS_SYNC_CHROME_DATA
-                detailStringID:0
-                      dataType:0];
-    self.syncChromeDataSwitchItem.on = self.syncSetupService->IsSyncEnabled();
-    [model addItem:self.syncChromeDataSwitchItem
-        toSectionWithIdentifier:SyncSectionIdentifier];
-    return YES;
+    // Sync is not active when |syncSetupService->IsFirstSetupComplete()| is
+    // false. Show sync being turned off in the UI in this cases.
+    BOOL isSyncEnabled =
+        self.syncSetupService->IsSyncEnabled() &&
+        (self.syncSetupService->IsFirstSetupComplete() ||
+         self.mode == GoogleServicesSettingsModeAdvancedSigninSettings);
+    needsUpdate =
+        needsUpdate || isSyncEnabled != self.syncChromeDataSwitchItem.on;
+    self.syncChromeDataSwitchItem.on = isSyncEnabled;
+    return needsUpdate;
   }
   if (!self.syncChromeDataSwitchItem)
     return NO;
@@ -481,6 +491,13 @@
   return self.authService->IsAuthenticated();
 }
 
+- (BOOL)isSyncSetupInProgress {
+  return self.isAuthenticated &&
+         (self.mode == GoogleServicesSettingsModeAdvancedSigninSettings ||
+          (self.syncSetupService->IsSyncEnabled() &&
+           !self.syncSetupService->IsFirstSetupComplete()));
+}
+
 - (BOOL)isSyncDisabledByAdministrator {
   return (self.syncService->GetDisableReasons() &
           syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY) != 0;
@@ -615,6 +632,17 @@
       break;
     case SyncChromeDataItemType:
       self.syncSetupService->SetSyncEnabled(value);
+      if (self.mode == GoogleServicesSettingsModeSettings &&
+          !self.syncSetupService->IsFirstSetupComplete()) {
+        // FirstSetupComplete flag needs to be turned on when the user enables
+        // sync for the first time. This flag should not be turned on in
+        // GoogleServicesSettingsModeAdvancedSigninSettings. In that mode,
+        // this flag should be turned on only when the user clicks the confirm
+        // button.
+        CHECK(value);
+        self.syncSetupService->PrepareForFirstSyncSetup();
+        self.syncSetupService->SetFirstSetupComplete();
+      }
       break;
     case IdentityItemType:
     case SignInItemType:
diff --git a/ios/chrome/browser/ui/signin_interaction/signin_interaction_coordinator.mm b/ios/chrome/browser/ui/signin_interaction/signin_interaction_coordinator.mm
index 995f8e34..4bf6dc6 100644
--- a/ios/chrome/browser/ui/signin_interaction/signin_interaction_coordinator.mm
+++ b/ios/chrome/browser/ui/signin_interaction/signin_interaction_coordinator.mm
@@ -118,26 +118,26 @@
 
 - (void)cancel {
   [self.controller cancel];
-  [self.advancedSigninSettingsCoordinator cancelWithDismiss:NO];
+  [self.advancedSigninSettingsCoordinator abortWithDismiss:NO];
 }
 
 - (void)cancelAndDismiss {
   [self.controller cancelAndDismiss];
-  [self.advancedSigninSettingsCoordinator cancelWithDismiss:YES];
+  [self.advancedSigninSettingsCoordinator abortWithDismiss:YES];
 }
 
 - (BOOL)isActive {
   return self.controller != nil;
 }
 
-#pragma mark - AdvancedSigninSettingsCoordinatorDelegates
+#pragma mark - AdvancedSigninSettingsCoordinatorDelegate
 
 - (void)advancedSigninSettingsCoordinatorDidClose:
             (AdvancedSigninSettingsCoordinator*)coordinator
-                                          success:(BOOL)success {
+                                         signedin:(BOOL)signedin {
   DCHECK_EQ(self.advancedSigninSettingsCoordinator, coordinator);
   self.advancedSigninSettingsCoordinator = nil;
-  [self signinDoneWithSuccess:success];
+  [self signinDoneWithSuccess:signedin];
 }
 
 #pragma mark - SigninInteractionPresenting
diff --git a/ios/chrome/browser/ui/ui_feature_flags.cc b/ios/chrome/browser/ui/ui_feature_flags.cc
index 5cda4d9..66eff5f 100644
--- a/ios/chrome/browser/ui/ui_feature_flags.cc
+++ b/ios/chrome/browser/ui/ui_feature_flags.cc
@@ -34,3 +34,6 @@
 
 const base::Feature kNewOmniboxPopupLayout{"NewOmniboxPopupLayout",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
+
+const base::Feature kOmniboxUseDefaultSearchEngineFavicon{
+    "OmniboxUseDefaultSearchEngineFavicon", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/ui_feature_flags.h b/ios/chrome/browser/ui/ui_feature_flags.h
index 883336831..f4a0128 100644
--- a/ios/chrome/browser/ui/ui_feature_flags.h
+++ b/ios/chrome/browser/ui/ui_feature_flags.h
@@ -39,4 +39,8 @@
 // favicon in the omnibox, rich entities support, new layout.
 extern const base::Feature kNewOmniboxPopupLayout;
 
+// Feature to display the omnibox with default search engine favicon
+// in the omnibox.
+extern const base::Feature kOmniboxUseDefaultSearchEngineFavicon;
+
 #endif  // IOS_CHROME_BROWSER_UI_UI_FEATURE_FLAGS_H_
diff --git a/media/DEPS b/media/DEPS
index 671a0df..e5e9d61 100644
--- a/media/DEPS
+++ b/media/DEPS
@@ -19,6 +19,7 @@
   "+third_party/libyuv",
   "+third_party/opus",
   "+third_party/skia",
+  "+ui/base/mpris/buildflags",
   "+ui/display",
   "+ui/events",
   "+ui/gfx",
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn
index f873b15..fcc6ab6c 100644
--- a/media/base/BUILD.gn
+++ b/media/base/BUILD.gn
@@ -314,6 +314,7 @@
     "//skia",
     "//third_party/libyuv",
     "//third_party/widevine/cdm:headers",
+    "//ui/base/mpris/buildflags",
     "//ui/display:display",
     "//ui/events:events_base",
     "//url:url",
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 31c4054..28f4f38 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -6,6 +6,7 @@
 
 #include "base/command_line.h"
 #include "build/build_config.h"
+#include "ui/base/mpris/buildflags/buildflags.h"
 
 namespace switches {
 
@@ -335,7 +336,8 @@
 // Enables handling of hardware media keys for controlling media.
 const base::Feature kHardwareMediaKeyHandling{
   "HardwareMediaKeyHandling",
-#if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_MACOSX)
+#if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_MACOSX) || \
+    BUILDFLAG(USE_MPRIS)
       base::FEATURE_ENABLED_BY_DEFAULT
 #else
       base::FEATURE_DISABLED_BY_DEFAULT
diff --git a/mojo/core/channel_mac.cc b/mojo/core/channel_mac.cc
index 450bd17e..0ea384d 100644
--- a/mojo/core/channel_mac.cc
+++ b/mojo/core/channel_mac.cc
@@ -17,8 +17,6 @@
 #include "base/containers/buffer_iterator.h"
 #include "base/containers/circular_deque.h"
 #include "base/containers/span.h"
-#include "base/debug/crash_logging.h"
-#include "base/debug/dump_without_crashing.h"
 #include "base/logging.h"
 #include "base/mac/mach_logging.h"
 #include "base/mac/scoped_mach_msg_destroy.h"
@@ -117,11 +115,6 @@
                               size_t extra_header_size,
                               std::vector<PlatformHandle>* handles,
                               bool* deferred) override {
-    // TODO(https://crbug.com/946372): Remove when fixed.
-    static base::debug::CrashKeyString* error_crash_key =
-        base::debug::AllocateCrashKeyString("channel-mac-handles-error",
-                                            base::debug::CrashKeySize::Size64);
-
     // Validate the incoming handles. If validation fails, ensure they are
     // destroyed.
     std::vector<PlatformHandle> incoming_handles;
@@ -130,14 +123,12 @@
     if (extra_header_size <
         sizeof(Message::MachPortsExtraHeader) +
             (incoming_handles.size() * sizeof(Message::MachPortsEntry))) {
-      base::debug::SetCrashKeyString(error_crash_key, "extra_header_size");
       return false;
     }
 
     const auto* mach_ports_header =
         reinterpret_cast<const Message::MachPortsExtraHeader*>(extra_header);
     if (mach_ports_header->num_ports != incoming_handles.size()) {
-      base::debug::SetCrashKeyString(error_crash_key, "num_ports mismatch");
       return false;
     }
 
@@ -145,29 +136,19 @@
       auto type = static_cast<PlatformHandle::Type>(
           mach_ports_header->entries[i].mach_entry.type);
       if (type == PlatformHandle::Type::kNone) {
-        base::debug::SetCrashKeyString(
-            error_crash_key, base::StringPrintf("kNone handle #%d", i));
         return false;
       } else if (type == PlatformHandle::Type::kFd &&
                  incoming_handles[i].is_mach_send()) {
         int fd = fileport_makefd(incoming_handles[i].GetMachSendRight().get());
         if (fd < 0) {
-          base::debug::SetCrashKeyString(
-              error_crash_key,
-              base::StringPrintf("fileport_makefd %d -%d #%d", fd, errno, i));
           return false;
         }
         incoming_handles[i] = PlatformHandle(base::ScopedFD(fd));
       } else if (type != incoming_handles[i].type()) {
-        base::debug::SetCrashKeyString(
-            error_crash_key,
-            base::StringPrintf("handle mismatch %d != -%d #%d", type,
-                               incoming_handles[i].type(), i));
         return false;
       }
     }
 
-    base::debug::ClearCrashKeyString(error_crash_key);
     *handles = std::move(incoming_handles);
     return true;
   }
@@ -646,12 +627,6 @@
     size_t ignored;
     DispatchResult result = TryDispatchMessage(payload, &ignored);
     if (result != DispatchResult::kOK) {
-      // TODO(https://crbug.com/946372): Remove when fixed.
-      static auto* error_crash_key = base::debug::AllocateCrashKeyString(
-          "channel-mac-try-dispatch", base::debug::CrashKeySize::Size32);
-      base::debug::SetCrashKeyString(error_crash_key,
-                                     base::StringPrintf("%d", result));
-      base::debug::DumpWithoutCrashing();
       OnError(Error::kReceivedMalformedData);
       return;
     }
diff --git a/mojo/core/spliced_message_pipe_unittest.cc b/mojo/core/spliced_message_pipe_unittest.cc
index 3185d5e0..575dd03 100644
--- a/mojo/core/spliced_message_pipe_unittest.cc
+++ b/mojo/core/spliced_message_pipe_unittest.cc
@@ -267,7 +267,14 @@
 // No multi-process support for iOS.
 #if !defined(OS_IOS)
 
-TEST_F(SplicedMessagePipeTest, Multiprocess) {
+#if defined(OS_FUCHSIA)
+// Flaky: https://crbug.com/950983
+#define MAYBE_Multiprocess DISABLED_Multiprocess
+#else
+#define MAYBE_Multiprocess Multiprocess
+#endif
+
+TEST_F(SplicedMessagePipeTest, MAYBE_Multiprocess) {
   MojoHandle a, b;
   CreateMessagePipe(&a, &b);
   RunTestClient("Client1", [&](MojoHandle h) {
diff --git a/net/dns/dns_test_util.cc b/net/dns/dns_test_util.cc
index eab0df05..7270bd67 100644
--- a/net/dns/dns_test_util.cc
+++ b/net/dns/dns_test_util.cc
@@ -304,7 +304,6 @@
     }
   }
 
-  void SetRequestContext(URLRequestContext*) override {}
   void SetRequestPriority(RequestPriority priority) override {}
 
   MockDnsClientRule::Result result_;
@@ -458,7 +457,8 @@
       uint16_t qtype,
       DnsTransactionFactory::CallbackType callback,
       const NetLogWithSource&,
-      SecureDnsMode secure_dns_mode) override {
+      SecureDnsMode secure_dns_mode,
+      URLRequestContext* url_request_context) override {
     std::unique_ptr<MockTransaction> transaction =
         std::make_unique<MockTransaction>(rules_, hostname, qtype,
                                           secure_dns_mode, std::move(callback));
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
index 02af9b87..198b3dd4 100644
--- a/net/dns/dns_transaction.cc
+++ b/net/dns/dns_transaction.cc
@@ -797,7 +797,8 @@
                      DnsTransactionFactory::CallbackType callback,
                      const NetLogWithSource& net_log,
                      const OptRecordRdata* opt_rdata,
-                     SecureDnsMode secure_dns_mode)
+                     SecureDnsMode secure_dns_mode,
+                     URLRequestContext* url_request_context)
       : session_(session),
         hostname_(hostname),
         qtype_(qtype),
@@ -811,6 +812,7 @@
         had_tcp_attempt_(false),
         doh_attempt_(false),
         first_server_index_(0),
+        url_request_context_(url_request_context),
         request_priority_(DEFAULT_PRIORITY) {
     DCHECK(session_.get());
     DCHECK(!hostname_.empty());
@@ -858,10 +860,6 @@
     }
   }
 
-  void SetRequestContext(URLRequestContext* context) override {
-    url_request_context_ = context;
-  }
-
   void SetRequestPriority(RequestPriority priority) override {
     request_priority_ = priority;
   }
@@ -1289,10 +1287,11 @@
       uint16_t qtype,
       CallbackType callback,
       const NetLogWithSource& net_log,
-      SecureDnsMode secure_dns_mode) override {
+      SecureDnsMode secure_dns_mode,
+      URLRequestContext* url_request_context) override {
     return std::make_unique<DnsTransactionImpl>(
         session_.get(), hostname, qtype, std::move(callback), net_log,
-        opt_rdata_.get(), secure_dns_mode);
+        opt_rdata_.get(), secure_dns_mode, url_request_context);
   }
 
   void AddEDNSOption(const OptRecordRdata::Opt& opt) override {
diff --git a/net/dns/dns_transaction.h b/net/dns/dns_transaction.h
index 9576551c..6e9cde2 100644
--- a/net/dns/dns_transaction.h
+++ b/net/dns/dns_transaction.h
@@ -42,8 +42,6 @@
   // Starts the transaction.  Always completes asynchronously.
   virtual void Start() = 0;
 
-  virtual void SetRequestContext(URLRequestContext*) = 0;
-
   virtual void SetRequestPriority(RequestPriority priority) = 0;
 };
 
@@ -83,7 +81,8 @@
       uint16_t qtype,
       CallbackType callback,
       const NetLogWithSource& net_log,
-      SecureDnsMode secure_dns_mode) WARN_UNUSED_RESULT = 0;
+      SecureDnsMode secure_dns_mode,
+      URLRequestContext* url_request_context) WARN_UNUSED_RESULT = 0;
 
   // The given EDNS0 option will be included in all DNS queries performed by
   // transactions from this factory.
diff --git a/net/dns/dns_transaction_unittest.cc b/net/dns/dns_transaction_unittest.cc
index 9fd28aa..a83ecfa 100644
--- a/net/dns/dns_transaction_unittest.cc
+++ b/net/dns/dns_transaction_unittest.cc
@@ -303,8 +303,7 @@
         base::Bind(&TransactionHelper::OnTransactionComplete,
                    base::Unretained(this)),
         NetLogWithSource::Make(&net_log_, net::NetLogSourceType::NONE),
-        secure_dns_mode_);
-    transaction_->SetRequestContext(&request_context_);
+        secure_dns_mode_, &request_context_);
     transaction_->SetRequestPriority(DEFAULT_PRIORITY);
     EXPECT_EQ(hostname_, transaction_->GetHostname());
     EXPECT_EQ(qtype_, transaction_->GetType());
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc
index e740cffb..fbbaa025 100644
--- a/net/dns/host_resolver_manager.cc
+++ b/net/dns/host_resolver_manager.cc
@@ -999,8 +999,7 @@
             base::BindOnce(&DnsTask::OnTransactionComplete,
                            base::Unretained(this), tick_clock_->NowTicks(),
                            dns_query_type),
-            net_log_, secure_dns_mode);
-    trans->SetRequestContext(delegate_->url_request_context());
+            net_log_, secure_dns_mode, delegate_->url_request_context());
     trans->SetRequestPriority(delegate_->priority());
     return trans;
   }
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 118a1ff..f425393 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -165,6 +165,9 @@
 int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info,
                                   CompletionOnceCallback callback,
                                   const NetLogWithSource& net_log) {
+  if (request_info->load_flags & LOAD_ONLY_FROM_CACHE)
+    return ERR_CACHE_MISS;
+
   DCHECK(request_info->traffic_annotation.is_valid());
   net_log_ = net_log;
   request_ = request_info;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 52c3c54b..16559b3 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -19640,6 +19640,21 @@
 
 #endif  // BUILDFLAG(ENABLE_REPORTING)
 
+TEST_F(HttpNetworkTransactionTest, AlwaysFailRequestToCache) {
+  HttpRequestInfo request;
+  request.method = "GET";
+  request.url = GURL("http://example.org/");
+
+  request.load_flags = LOAD_ONLY_FROM_CACHE;
+
+  std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+  HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
+  TestCompletionCallback callback1;
+  int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
+
+  EXPECT_THAT(rv, IsError(ERR_CACHE_MISS));
+}
+
 TEST_F(HttpNetworkTransactionTest, ZeroRTTDoesntConfirm) {
   HttpRequestInfo request;
   request.method = "GET";
diff --git a/services/service_manager/sandbox/linux/bpf_audio_policy_linux.cc b/services/service_manager/sandbox/linux/bpf_audio_policy_linux.cc
index f9c155ce..ee63d9e 100644
--- a/services/service_manager/sandbox/linux/bpf_audio_policy_linux.cc
+++ b/services/service_manager/sandbox/linux/bpf_audio_policy_linux.cc
@@ -7,8 +7,10 @@
 #include <sys/socket.h>
 
 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
+#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
 #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
 #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
+#include "sandbox/linux/services/syscall_wrappers.h"
 #include "sandbox/linux/syscall_broker/broker_process.h"
 #include "sandbox/linux/system_headers/linux_futex.h"
 #include "sandbox/linux/system_headers/linux_syscalls.h"
@@ -88,6 +90,23 @@
 #endif
     }
 #endif
+#if defined(__NR_kill)
+    case __NR_kill: {
+      // man kill says:
+      // "If sig is 0, then no signal is sent, but existence and permission
+      //  checks are still performed; this can be used to check for the
+      //  existence of a process ID or process group ID that the caller is
+      //  permitted to signal."
+      //
+      // This seems to be tripping up at least ESET's NOD32 anti-virus, causing
+      // an unnecessary crash in the audio process. See: http://crbug.com/904787
+      const Arg<pid_t> pid(0);
+      const Arg<int> sig(1);
+      return If(pid == sandbox::sys_getpid(), Allow())
+          .ElseIf(sig == 0, Error(EPERM))
+          .Else(sandbox::CrashSIGSYSKill());
+    }
+#endif
 #if defined(__NR_socket)
     case __NR_socket: {
       const Arg<int> domain(0);
diff --git a/services/video_capture/broadcasting_receiver.cc b/services/video_capture/broadcasting_receiver.cc
index 78fadc1..29fe674 100644
--- a/services/video_capture/broadcasting_receiver.cc
+++ b/services/video_capture/broadcasting_receiver.cc
@@ -288,10 +288,11 @@
   auto buffer_context_iter = FindUnretiredBufferContextFromBufferId(buffer_id);
   CHECK(buffer_context_iter != buffer_contexts_.end());
   auto& buffer_context = *buffer_context_iter;
-  buffer_context.set_access_permission(std::move(access_permission));
   for (auto& client : clients_) {
     if (client.second.is_suspended())
       continue;
+    if (access_permission)
+      buffer_context.set_access_permission(std::move(access_permission));
     mojom::ScopedAccessPermissionPtr consumer_access_permission;
     mojo::MakeStrongBinding(
         std::make_unique<ConsumerAccessPermission>(base::BindOnce(
diff --git a/services/video_capture/broadcasting_receiver_unittest.cc b/services/video_capture/broadcasting_receiver_unittest.cc
index 452f805..e5685f4 100644
--- a/services/video_capture/broadcasting_receiver_unittest.cc
+++ b/services/video_capture/broadcasting_receiver_unittest.cc
@@ -17,6 +17,10 @@
 
 namespace video_capture {
 
+static const size_t kArbitraryDummyBufferSize = 8u;
+static const int kArbiraryBufferId = 123;
+static const int kArbiraryFrameFeedbackId = 456;
+
 class FakeAccessPermission : public mojom::ScopedAccessPermission {
  public:
   FakeAccessPermission(base::OnceClosure destruction_cb)
@@ -36,33 +40,32 @@
         std::make_unique<MockReceiver>(mojo::MakeRequest(&receiver_1));
     mock_receiver_2_ =
         std::make_unique<MockReceiver>(mojo::MakeRequest(&receiver_2));
-    broadcaster_.AddClient(std::move(receiver_1),
-                           media::VideoCaptureBufferType::kSharedMemory);
-    broadcaster_.AddClient(std::move(receiver_2),
-                           media::VideoCaptureBufferType::kSharedMemory);
+    client_id_1_ = broadcaster_.AddClient(
+        std::move(receiver_1), media::VideoCaptureBufferType::kSharedMemory);
+    client_id_2_ = broadcaster_.AddClient(
+        std::move(receiver_2), media::VideoCaptureBufferType::kSharedMemory);
+
+    ASSERT_TRUE(shm_provider.InitForSize(kArbitraryDummyBufferSize));
+    media::mojom::VideoBufferHandlePtr buffer_handle =
+        media::mojom::VideoBufferHandle::New();
+    buffer_handle->set_shared_buffer_handle(
+        shm_provider.GetHandleForInterProcessTransit(true /*read_only*/));
+    broadcaster_.OnNewBuffer(kArbiraryBufferId, std::move(buffer_handle));
   }
 
  protected:
   BroadcastingReceiver broadcaster_;
   std::unique_ptr<MockReceiver> mock_receiver_1_;
   std::unique_ptr<MockReceiver> mock_receiver_2_;
+  int32_t client_id_1_;
+  int32_t client_id_2_;
+  media::SharedMemoryHandleProvider shm_provider;
   base::test::ScopedTaskEnvironment task_environment_;
 };
 
 TEST_F(
     BroadcastingReceiverTest,
     HoldsOnToAccessPermissionForRetiredBufferUntilLastClientFinishedConsuming) {
-  media::SharedMemoryHandleProvider shm_provider;
-  const size_t kArbitraryDummyBufferSize = 8u;
-  ASSERT_TRUE(shm_provider.InitForSize(kArbitraryDummyBufferSize));
-  media::mojom::VideoBufferHandlePtr buffer_handle =
-      media::mojom::VideoBufferHandle::New();
-  buffer_handle->set_shared_buffer_handle(
-      shm_provider.GetHandleForInterProcessTransit(true /*read_only*/));
-  static const int kArbiraryBufferId = 123;
-  static const int kArbiraryFrameFeedbackId = 456;
-  broadcaster_.OnNewBuffer(kArbiraryBufferId, std::move(buffer_handle));
-
   base::RunLoop frame_arrived_at_receiver_1;
   base::RunLoop frame_arrived_at_receiver_2;
   EXPECT_CALL(*mock_receiver_1_, DoOnFrameReadyInBuffer(_, _, _, _))
@@ -126,4 +129,33 @@
   EXPECT_TRUE(access_permission_has_been_released);
 }
 
+TEST_F(BroadcastingReceiverTest,
+       DoesNotHoldOnToAccessPermissionWhenAllClientsAreSuspended) {
+  EXPECT_CALL(*mock_receiver_1_, DoOnFrameReadyInBuffer(_, _, _, _)).Times(0);
+  EXPECT_CALL(*mock_receiver_2_, DoOnFrameReadyInBuffer(_, _, _, _)).Times(0);
+
+  broadcaster_.SuspendClient(client_id_1_);
+  broadcaster_.SuspendClient(client_id_2_);
+
+  mojom::ScopedAccessPermissionPtr access_permission;
+  bool access_permission_has_been_released = false;
+  mojo::MakeStrongBinding(std::make_unique<FakeAccessPermission>(base::BindOnce(
+                              [](bool* access_permission_has_been_released) {
+                                *access_permission_has_been_released = true;
+                              },
+                              &access_permission_has_been_released)),
+                          mojo::MakeRequest(&access_permission));
+  media::mojom::VideoFrameInfoPtr frame_info =
+      media::mojom::VideoFrameInfo::New();
+  media::VideoFrameMetadata frame_metadata;
+  frame_info->metadata = frame_metadata.GetInternalValues().Clone();
+  broadcaster_.OnFrameReadyInBuffer(kArbiraryBufferId, kArbiraryFrameFeedbackId,
+                                    std::move(access_permission),
+                                    std::move(frame_info));
+
+  // expect that |access_permission| is released
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(access_permission_has_been_released);
+}
+
 }  // namespace video_capture
diff --git a/services/video_capture/test/mock_device_shared_access_unittest.cc b/services/video_capture/test/mock_device_shared_access_unittest.cc
index 1fd271aa..d99ca7c 100644
--- a/services/video_capture/test/mock_device_shared_access_unittest.cc
+++ b/services/video_capture/test/mock_device_shared_access_unittest.cc
@@ -14,6 +14,7 @@
 #include "media/capture/video/video_capture_system_impl.h"
 #include "services/service_manager/public/cpp/service_keepalive.h"
 #include "services/video_capture/device_factory_media_to_mojo_adapter.h"
+#include "services/video_capture/device_media_to_mojo_adapter.h"
 #include "services/video_capture/public/cpp/mock_receiver.h"
 #include "services/video_capture/public/mojom/device_factory_provider.mojom.h"
 #include "services/video_capture/public/mojom/video_source.mojom.h"
@@ -33,8 +34,8 @@
   MockDeviceSharedAccessTest()
       : mock_receiver_1_(mojo::MakeRequest(&receiver_1_)),
         mock_receiver_2_(mojo::MakeRequest(&receiver_2_)),
-        service_keepalive_(nullptr, base::nullopt),
-        next_arbitrary_frame_feedback_id_(123) {}
+        next_arbitrary_frame_feedback_id_(123),
+        service_keepalive_(nullptr, base::nullopt) {}
   ~MockDeviceSharedAccessTest() override {}
 
   void SetUp() override {
@@ -259,9 +260,10 @@
   mojom::ReceiverPtr receiver_2_;
   MockReceiver mock_receiver_2_;
 
+  int32_t next_arbitrary_frame_feedback_id_;
+
  private:
   service_manager::ServiceKeepalive service_keepalive_;
-  int32_t next_arbitrary_frame_feedback_id_;
 };
 
 // This alias ensures test output is easily attributed to this service's tests.
@@ -429,6 +431,38 @@
   SendFrameAndExpectToArriveAtBothSubscribers();
 }
 
+TEST_F(MockVideoCaptureDeviceSharedAccessTest, SuspendAndResumeSingleClient) {
+  LetClient1ConnectWithRequestableSettingsAndExpectToGetThem();
+  subscription_1_->Activate();
+  {
+    base::RunLoop wait_loop;
+    subscription_1_->Suspend(base::BindOnce(
+        [](base::RunLoop* wait_loop) { wait_loop->Quit(); }, &wait_loop));
+    wait_loop.Run();
+  }
+  EXPECT_CALL(mock_receiver_1_, DoOnFrameReadyInBuffer(_, _, _, _)).Times(0);
+
+  // Send a couple of frames. We want to send at least as many frames as
+  // the maximum buffer count in the video frame pool to make sure that
+  // buffers are properly released and reused.
+  mock_device_.SendOnStarted();
+  for (int i = 0; i < DeviceMediaToMojoAdapter::max_buffer_pool_buffer_count();
+       i++) {
+    const int32_t kArbitraryRotation = 0;
+    const int32_t kArbitraryFrameFeedbackId =
+        next_arbitrary_frame_feedback_id_++;
+    mock_device_.SendStubFrame(requestable_settings_.requested_format,
+                               kArbitraryRotation, kArbitraryFrameFeedbackId);
+    // We need to wait until the frame has arrived at BroadcastingReceiver
+    base::RunLoop().RunUntilIdle();
+  }
+  Mock::VerifyAndClearExpectations(&mock_receiver_1_);
+
+  subscription_1_->Resume();
+  subscription_1_.FlushForTesting();
+  SendFrameAndExpectToArriveOnlyAtSubscriber1();
+}
+
 TEST_F(MockVideoCaptureDeviceSharedAccessTest,
        CreateNewSubscriptionAfterClosingExistingOneUsesNewSettings) {
   LetClient1ConnectWithRequestableSettingsAndExpectToGetThem();
diff --git a/storage/browser/fileapi/sandbox_file_system_backend.cc b/storage/browser/fileapi/sandbox_file_system_backend.cc
index 5e2f0d1..b1a073e 100644
--- a/storage/browser/fileapi/sandbox_file_system_backend.cc
+++ b/storage/browser/fileapi/sandbox_file_system_backend.cc
@@ -19,6 +19,7 @@
 #include "storage/browser/fileapi/file_stream_reader.h"
 #include "storage/browser/fileapi/file_stream_writer.h"
 #include "storage/browser/fileapi/file_system_context.h"
+#include "storage/browser/fileapi/file_system_features.h"
 #include "storage/browser/fileapi/file_system_operation.h"
 #include "storage/browser/fileapi/file_system_operation_context.h"
 #include "storage/browser/fileapi/file_system_options.h"
@@ -38,8 +39,8 @@
 SandboxFileSystemBackend::SandboxFileSystemBackend(
     SandboxFileSystemBackendDelegate* delegate)
     : delegate_(delegate),
-      enable_temporary_file_system_in_incognito_(false) {
-}
+      enable_temporary_file_system_in_incognito_(base::FeatureList::IsEnabled(
+          features::kEnableFilesystemInIncognito)) {}
 
 SandboxFileSystemBackend::~SandboxFileSystemBackend() = default;
 
@@ -125,7 +126,9 @@
 
 bool SandboxFileSystemBackend::SupportsStreaming(
     const storage::FileSystemURL& url) const {
-  return false;
+  // Streaming is required for in-memory implementation to access memory-backed
+  // files.
+  return delegate_->file_system_options().is_incognito();
 }
 
 bool SandboxFileSystemBackend::HasInplaceCopyImplementation(
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json
index 8aaef0b..a0a18877 100644
--- a/testing/buildbot/chromium.win.json
+++ b/testing/buildbot/chromium.win.json
@@ -3219,22 +3219,6 @@
         }
       },
       {
-        "args": [
-          "--test-type=integration"
-        ],
-        "isolate_name": "chromedriver_py_tests",
-        "name": "chromedriver_py_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "cpu": "x86-64",
-              "os": "Windows-10-15063"
-            }
-          ]
-        }
-      },
-      {
         "isolate_name": "chromedriver_replay_unittests",
         "name": "chromedriver_replay_unittests",
         "swarming": {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 3dd01ab..8aa8a09c 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -353,6 +353,13 @@
       }
     }
   },
+  'chromedriver_py_tests': {
+    'remove_from': [
+      # Timeout happens sometimes (crbug.com/951799).
+      'Win10 Tests x64',
+      'Win10 Tests x64 (dbg)',
+    ],
+  },
   'components_unittests': {
     'modifications': {
       # chromium.memory
diff --git a/third_party/android_crazy_linker/BUILD.gn b/third_party/android_crazy_linker/BUILD.gn
index f9e1358..a7c21e02 100644
--- a/third_party/android_crazy_linker/BUILD.gn
+++ b/third_party/android_crazy_linker/BUILD.gn
@@ -144,6 +144,12 @@
       public_configs = [ ":crazy_config" ]
       configs -= [ "//build/config/compiler:chromium_code" ]
       configs += [ "//build/config/compiler:no_chromium_code" ]
+
+      # This is used to allow shared memory regions to work on Android Q+
+      # See http://crbug.com/949804
+      deps = [
+        "//third_party/ashmem",
+      ]
     }
   }
 
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_ashmem.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_ashmem.cpp
index 875bf74..2dbdcca 100644
--- a/third_party/android_crazy_linker/src/src/crazy_linker_ashmem.cpp
+++ b/third_party/android_crazy_linker/src/src/crazy_linker_ashmem.cpp
@@ -11,7 +11,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include <linux/ashmem.h>
+#include "third_party/ashmem/ashmem.h"
 
 #include "crazy_linker_system.h"
 #include "crazy_linker_memory_mapping.h"
@@ -19,30 +19,16 @@
 namespace crazy {
 
 bool AshmemRegion::Allocate(size_t region_size, const char* region_name) {
-  int fd = TEMP_FAILURE_RETRY(open("/dev/ashmem", O_RDWR));
+  int fd = ashmem_create_region(region_name, region_size);
   if (fd < 0)
     return false;
 
-  if (ioctl(fd, ASHMEM_SET_SIZE, region_size) < 0)
-    goto ERROR;
-
-  if (region_name) {
-    char buf[256];
-    strlcpy(buf, region_name, sizeof(buf));
-    if (ioctl(fd, ASHMEM_SET_NAME, buf) < 0)
-      goto ERROR;
-  }
-
   Reset(fd);
   return true;
-
-ERROR:
-  ::close(fd);
-  return false;
 }
 
 bool AshmemRegion::SetProtectionFlags(int prot) {
-  return ioctl(fd_, ASHMEM_SET_PROT_MASK, prot) == 0;
+  return ashmem_set_prot_region(fd_, prot) == 0;
 }
 
 // static
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index 22de4a7..1a56b5b 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -209,7 +209,7 @@
 
 // Allows for synchronous XHR requests during page dismissal
 const base::Feature kForbidSyncXHRInPageDismissal{
-    "ForbidSyncXHRInPageDismissal", base::FEATURE_DISABLED_BY_DEFAULT};
+    "ForbidSyncXHRInPageDismissal", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Emergency lever that can be used to restore DeviceOrientationEvent and
 // DeviceMotionEvent functionality in non-secure browsing contexts.
diff --git a/third_party/blink/renderer/core/dom/text.cc b/third_party/blink/renderer/core/dom/text.cc
index 8f5a7531..67f8b5c 100644
--- a/third_party/blink/renderer/core/dom/text.cc
+++ b/third_party/blink/renderer/core/dom/text.cc
@@ -403,11 +403,11 @@
       // The computed style or the need for an anonymous inline wrapper for a
       // display:contents text child changed.
       SetNeedsReattachLayoutTree();
-      return;
+    } else {
+      layout_text->SetStyle(std::move(new_style));
+      if (NeedsStyleRecalc())
+        layout_text->SetText(DataImpl());
     }
-    layout_text->SetStyle(std::move(new_style));
-    if (NeedsStyleRecalc())
-      layout_text->SetText(DataImpl());
   } else if (new_style && (NeedsStyleRecalc() || change.ReattachLayoutTree() ||
                            NeedsWhitespaceLayoutObject(*new_style))) {
     SetNeedsReattachLayoutTree();
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 1612018..c9dfdd6 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -4320,15 +4320,13 @@
   if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
       RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
     DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kPrePaintClean);
-    if (const auto* scroll =
-            GetLayoutView()->FirstFragment().PaintProperties()->Scroll()) {
-      reasons = scroll->GetMainThreadScrollingReasons();
-    }
+    const auto* properties = GetLayoutView()->FirstFragment().PaintProperties();
+    if (properties && properties->Scroll())
+      reasons = properties->Scroll()->GetMainThreadScrollingReasons();
   } else {
     DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kCompositingClean);
     reasons = main_thread_scrolling_reasons_;
-    if (GraphicsLayer* layer_for_scrolling =
-            LayoutViewport()->LayerForScrolling()) {
+    if (auto* layer_for_scrolling = LayoutViewport()->LayerForScrolling()) {
       if (cc::Layer* cc_layer = layer_for_scrolling->CcLayer())
         reasons = cc_layer->GetMainThreadScrollingReasons();
     }
diff --git a/third_party/blink/renderer/core/paint/paint_invalidator.cc b/third_party/blink/renderer/core/paint/paint_invalidator.cc
index 86379cd..59cc574 100644
--- a/third_party/blink/renderer/core/paint/paint_invalidator.cc
+++ b/third_party/blink/renderer/core/paint/paint_invalidator.cc
@@ -93,15 +93,10 @@
     if (!disable_flip) {
       if (object.IsBox()) {
         ToLayoutBox(object).FlipForWritingMode(rect);
-      } else if (!(context.subtree_flags &
-                   PaintInvalidatorContext::kSubtreeSlowPathRect)) {
-        // For CAP and the GeometryMapper path, we also need to convert the
-        // rect for non-boxes into physical coordinates before applying paint
-        // offset. (Otherwise we'll call mapToVisualrectInAncestorSpace() which
-        // requires physical coordinates for boxes, but "physical coordinates
-        // with flipped block-flow direction" for non-boxes for which we don't
-        // need to flip.)
-        // TODO(wangxianzhu): Avoid containingBlock().
+      } else {
+        // Also convert the rect for non-boxes into physical coordinates before
+        // applying paint offset.
+        // TODO(wangxianzhu): Avoid ContainingBlock().
         object.ContainingBlock()->FlipForWritingMode(rect);
       }
     }
@@ -336,17 +331,6 @@
   object.GetMutableForPainting().EnsureIsReadyForPaintInvalidation();
 
   UpdatePaintingLayer(object, context);
-
-  // TODO(chrishtr): refactor to remove these slow paths by expanding their
-  // LocalVisualRect to include repeated locations.
-  if (object.IsTableSection()) {
-    const auto& section = ToLayoutTableSection(object);
-    if (section.IsRepeatingHeaderGroup() || section.IsRepeatingFooterGroup())
-      context.subtree_flags |= PaintInvalidatorContext::kSubtreeSlowPathRect;
-  }
-  if (object.IsFixedPositionObjectInPagedMedia())
-    context.subtree_flags |= PaintInvalidatorContext::kSubtreeSlowPathRect;
-
   UpdatePaintInvalidationContainer(object, context);
   UpdateEmptyVisualRectFlag(object, context);
 
diff --git a/third_party/blink/renderer/core/paint/paint_invalidator.h b/third_party/blink/renderer/core/paint/paint_invalidator.h
index c177695..cd5a9fd 100644
--- a/third_party/blink/renderer/core/paint/paint_invalidator.h
+++ b/third_party/blink/renderer/core/paint/paint_invalidator.h
@@ -81,9 +81,6 @@
     kSubtreeFullInvalidation = 1 << 2,
     kSubtreeFullInvalidationForStackedContents = 1 << 3,
 
-    // For repeated objects inside multicolumn.
-    kSubtreeSlowPathRect = 1 << 4,
-
     // When this flag is set, no paint or raster invalidation will be issued
     // for the subtree.
     //
diff --git a/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js b/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js
index 4ac5147..0188e67 100644
--- a/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js
+++ b/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js
@@ -992,6 +992,7 @@
       'textEditorAutoDetectIndent',
       'textEditorBracketMatching',
       'textEditorIndent',
+      'textEditorTabMovesFocus',
       'timelineCaptureFilmStrip',
       'timelineCaptureLayersAndPictures',
       'timelineCaptureMemory',
diff --git a/third_party/blink/renderer/devtools/front_end/sources/module.json b/third_party/blink/renderer/devtools/front_end/sources/module.json
index 2bad0b32dc..cbe6029 100644
--- a/third_party/blink/renderer/devtools/front_end/sources/module.json
+++ b/third_party/blink/renderer/devtools/front_end/sources/module.json
@@ -427,6 +427,24 @@
         {
             "type": "setting",
             "category": "Sources",
+            "title": "Enable tab moves focus",
+            "settingName": "textEditorTabMovesFocus",
+            "settingType": "boolean",
+            "defaultValue": false,
+            "options": [
+                {
+                    "value": true,
+                    "title": "Enable tab moves focus"
+                },
+                {
+                    "value": false,
+                    "title": "Disable tab moves focus"
+                }
+            ]
+        },
+        {
+            "type": "setting",
+            "category": "Sources",
             "title": "Detect indentation",
             "settingName": "textEditorAutoDetectIndent",
             "settingType": "boolean",
diff --git a/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js b/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js
index 1335b70..9581a54 100644
--- a/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js
+++ b/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js
@@ -561,6 +561,10 @@
    * @param {!Event} e
    */
   _handleKeyDown(e) {
+    if (e.key === 'Tab' && Common.moduleSetting('textEditorTabMovesFocus').get()) {
+      e.consume(false);
+      return;
+    }
     if (this._autocompleteController && this._autocompleteController.keyDown(e))
       e.consume(true);
   }
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc
index b235b20f..f1ad817 100644
--- a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc
+++ b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc
@@ -182,10 +182,13 @@
   // types (which could be platform-specific ones), there's a chance that the
   // files are on remote filesystem.  If the port has returned metadata just
   // pass it to File constructor (so we may cache the metadata).
+  // If |metadata.platform_path|, filesystem will decide about the actual
+  // storage location based on the url.
   // FIXME: We should use the snapshot metadata for all files.
   // https://www.w3.org/Bugs/Public/show_bug.cgi?id=17746
-  if (type == mojom::blink::FileSystemType::kTemporary ||
-      type == mojom::blink::FileSystemType::kPersistent)
+  if (!metadata.platform_path.IsEmpty() &&
+      (type == mojom::blink::FileSystemType::kTemporary ||
+       type == mojom::blink::FileSystemType::kPersistent))
     return File::CreateForFileSystemFile(metadata.platform_path, name);
 
   const File::UserVisibility user_visibility =
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni
index f71964b..dea3c0f 100644
--- a/third_party/blink/renderer/modules/modules_idl_files.gni
+++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -394,6 +394,7 @@
           "webgl/oes_texture_half_float.idl",
           "webgl/oes_texture_half_float_linear.idl",
           "webgl/oes_vertex_array_object.idl",
+          "webgl/ovr_multiview_2.idl",
           "webgl/webgl2_rendering_context.idl",
           "webgl/webgl_active_info.idl",
           "webgl/webgl_buffer.idl",
@@ -413,7 +414,6 @@
           "webgl/webgl_lose_context.idl",
           "webgl/webgl_multi_draw_instanced.idl",
           "webgl/webgl_multi_draw.idl",
-          "webgl/webgl_multiview.idl",
           "webgl/webgl_program.idl",
           "webgl/webgl_query.idl",
           "webgl/webgl_renderbuffer.idl",
diff --git a/third_party/blink/renderer/modules/webgl/BUILD.gn b/third_party/blink/renderer/modules/webgl/BUILD.gn
index c6e827d..36169ad 100644
--- a/third_party/blink/renderer/modules/webgl/BUILD.gn
+++ b/third_party/blink/renderer/modules/webgl/BUILD.gn
@@ -45,6 +45,8 @@
     "oes_texture_half_float_linear.h",
     "oes_vertex_array_object.cc",
     "oes_vertex_array_object.h",
+    "ovr_multiview_2.cc",
+    "ovr_multiview_2.h",
     "webgl2_rendering_context.cc",
     "webgl2_rendering_context.h",
     "webgl2_rendering_context_base.cc",
@@ -97,8 +99,6 @@
     "webgl_multi_draw_common.h",
     "webgl_multi_draw_instanced.cc",
     "webgl_multi_draw_instanced.h",
-    "webgl_multiview.cc",
-    "webgl_multiview.h",
     "webgl_object.cc",
     "webgl_object.h",
     "webgl_program.cc",
diff --git a/third_party/blink/renderer/modules/webgl/ovr_multiview_2.cc b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.cc
new file mode 100644
index 0000000..8e4a3467
--- /dev/null
+++ b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.cc
@@ -0,0 +1,95 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/webgl/ovr_multiview_2.h"
+
+#include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h"
+#include "third_party/blink/renderer/modules/webgl/webgl_framebuffer.h"
+#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h"
+
+namespace blink {
+
+OVRMultiview2::OVRMultiview2(WebGLRenderingContextBase* context)
+    : WebGLExtension(context) {
+  context->ExtensionsUtil()->EnsureExtensionEnabled("GL_OVR_multiview2");
+  context->ContextGL()->GetIntegerv(GL_MAX_VIEWS_OVR, &max_views_ovr_);
+}
+
+WebGLExtensionName OVRMultiview2::GetName() const {
+  return kOVRMultiview2Name;
+}
+
+OVRMultiview2* OVRMultiview2::Create(WebGLRenderingContextBase* context) {
+  return MakeGarbageCollected<OVRMultiview2>(context);
+}
+
+void OVRMultiview2::framebufferTextureMultiviewOVR(GLenum target,
+                                                   GLenum attachment,
+                                                   WebGLTexture* texture,
+                                                   GLint level,
+                                                   GLint base_view_index,
+                                                   GLsizei num_views) {
+  WebGLExtensionScopedContext scoped(this);
+  if (scoped.IsLost())
+    return;
+  if (!scoped.Context()->ValidateNullableWebGLObject(
+          "framebufferTextureMultiviewOVR", texture))
+    return;
+  GLenum textarget = texture ? texture->GetTarget() : 0;
+  if (texture) {
+    if (textarget != GL_TEXTURE_2D_ARRAY) {
+      scoped.Context()->SynthesizeGLError(GL_INVALID_OPERATION,
+                                          "framebufferTextureMultiviewOVR",
+                                          "invalid texture type");
+      return;
+    }
+    if (num_views < 1) {
+      scoped.Context()->SynthesizeGLError(GL_INVALID_VALUE,
+                                          "framebufferTextureMultiviewOVR",
+                                          "numViews is less than one");
+      return;
+    }
+    if (num_views > max_views_ovr_) {
+      scoped.Context()->SynthesizeGLError(
+          GL_INVALID_VALUE, "framebufferTextureMultiviewOVR",
+          "numViews is more than the value of MAX_VIEWS_OVR");
+      return;
+    }
+    if (!static_cast<WebGL2RenderingContextBase*>(scoped.Context())
+             ->ValidateTexFuncLayer("framebufferTextureMultiviewOVR", textarget,
+                                    base_view_index))
+      return;
+    if (!static_cast<WebGL2RenderingContextBase*>(scoped.Context())
+             ->ValidateTexFuncLayer("framebufferTextureMultiviewOVR", textarget,
+                                    base_view_index + num_views - 1))
+      return;
+    if (!scoped.Context()->ValidateTexFuncLevel(
+            "framebufferTextureMultiviewOVR", textarget, level))
+      return;
+  }
+
+  WebGLFramebuffer* framebuffer_binding =
+      scoped.Context()->GetFramebufferBinding(target);
+  if (!framebuffer_binding || !framebuffer_binding->Object()) {
+    scoped.Context()->SynthesizeGLError(GL_INVALID_OPERATION,
+                                        "framebufferTextureMultiviewOVR",
+                                        "no framebuffer bound");
+    return;
+  }
+
+  framebuffer_binding->SetAttachmentForBoundFramebuffer(
+      target, attachment, textarget, texture, level, base_view_index,
+      num_views);
+  scoped.Context()->ApplyStencilTest();
+}
+
+bool OVRMultiview2::Supported(WebGLRenderingContextBase* context) {
+  return context->ExtensionsUtil()->SupportsExtension("GL_OVR_multiview2");
+}
+
+const char* OVRMultiview2::ExtensionName() {
+  return "OVR_multiview2";
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h
new file mode 100644
index 0000000..f6a3ff9
--- /dev/null
+++ b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h
@@ -0,0 +1,37 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OVR_MULTIVIEW_2_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OVR_MULTIVIEW_2_H_
+
+#include "third_party/blink/renderer/modules/webgl/webgl_extension.h"
+
+namespace blink {
+
+class OVRMultiview2 final : public WebGLExtension {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  static OVRMultiview2* Create(WebGLRenderingContextBase*);
+  static bool Supported(WebGLRenderingContextBase*);
+  static const char* ExtensionName();
+
+  explicit OVRMultiview2(WebGLRenderingContextBase*);
+
+  WebGLExtensionName GetName() const override;
+
+  void framebufferTextureMultiviewOVR(GLenum target,
+                                      GLenum attachment,
+                                      WebGLTexture* texture,
+                                      GLint level,
+                                      GLint baseViewIndex,
+                                      GLsizei numViews);
+
+ private:
+  GLsizei max_views_ovr_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OVR_MULTIVIEW_2_H_
diff --git a/third_party/blink/renderer/modules/webgl/webgl_multiview.idl b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.idl
similarity index 79%
rename from third_party/blink/renderer/modules/webgl/webgl_multiview.idl
rename to third_party/blink/renderer/modules/webgl/ovr_multiview_2.idl
index 2ca349f..b004ba1a 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_multiview.idl
+++ b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.idl
@@ -2,19 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// https://www.khronos.org/registry/webgl/extensions/WEBGL_multiview/
+// https://www.khronos.org/registry/webgl/extensions/OVR_multiview2/
 
 [
     NoInterfaceObject,
     DoNotCheckConstants
 ]
-interface WebGLMultiview {
+interface OVRMultiview2 {
     const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR = 0x9630;
     const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR = 0x9632;
     const GLenum MAX_VIEWS_OVR = 0x9631;
     const GLenum FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR = 0x9633;
 
-    void framebufferTextureMultiviewWEBGL(GLenum target, GLenum attachment,
+    void framebufferTextureMultiviewOVR(GLenum target, GLenum attachment,
                                           WebGLTexture? texture, GLint level,
                                           GLint baseViewIndex,
                                           GLsizei numViews);
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
index 96adf00..f39b291 100644
--- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
@@ -20,6 +20,7 @@
 #include "third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.h"
 #include "third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h"
 #include "third_party/blink/renderer/modules/webgl/oes_texture_float_linear.h"
+#include "third_party/blink/renderer/modules/webgl/ovr_multiview_2.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.h"
@@ -33,7 +34,6 @@
 #include "third_party/blink/renderer/modules/webgl/webgl_lose_context.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_multi_draw.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced.h"
-#include "third_party/blink/renderer/modules/webgl/webgl_multiview.h"
 #include "third_party/blink/renderer/modules/webgl/webgl_video_texture.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h"
 
@@ -146,8 +146,8 @@
   RegisterExtension<WebGLMultiDraw>(webgl_multi_draw_, kDraftExtension);
   RegisterExtension<WebGLMultiDrawInstanced>(webgl_multi_draw_instanced_,
                                              kDraftExtension);
-  RegisterExtension<WebGLMultiview>(webgl_multiview_, kDraftExtension);
   RegisterExtension<WebGLVideoTexture>(webgl_video_texture_, kDraftExtension);
+  RegisterExtension<OVRMultiview2>(ovr_multiview2_, kDraftExtension);
 }
 
 void WebGL2RenderingContext::Trace(blink::Visitor* visitor) {
@@ -157,6 +157,7 @@
   visitor->Trace(ext_texture_filter_anisotropic_);
   visitor->Trace(khr_parallel_shader_compile_);
   visitor->Trace(oes_texture_float_linear_);
+  visitor->Trace(ovr_multiview2_);
   visitor->Trace(webgl_compressed_texture_astc_);
   visitor->Trace(webgl_compressed_texture_etc_);
   visitor->Trace(webgl_compressed_texture_etc1_);
@@ -168,7 +169,6 @@
   visitor->Trace(webgl_lose_context_);
   visitor->Trace(webgl_multi_draw_);
   visitor->Trace(webgl_multi_draw_instanced_);
-  visitor->Trace(webgl_multiview_);
   visitor->Trace(webgl_video_texture_);
   WebGL2RenderingContextBase::Trace(visitor);
 }
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h
index 36c2d17c..5765703e 100644
--- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h
+++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h
@@ -18,11 +18,11 @@
 class EXTFloatBlend;
 class EXTTextureFilterAnisotropic;
 class OESTextureFloatLinear;
+class OVRMultiview2;
 class WebGLDebugRendererInfo;
 class WebGLLoseContext;
 class WebGLMultiDraw;
 class WebGLMultiDrawInstanced;
-class WebGLMultiview;
 class KHRParallelShaderCompile;
 class WebGLVideoTexture;
 
@@ -71,6 +71,7 @@
   Member<EXTTextureFilterAnisotropic> ext_texture_filter_anisotropic_;
   Member<KHRParallelShaderCompile> khr_parallel_shader_compile_;
   Member<OESTextureFloatLinear> oes_texture_float_linear_;
+  Member<OVRMultiview2> ovr_multiview2_;
   Member<WebGLCompressedTextureASTC> webgl_compressed_texture_astc_;
   Member<WebGLCompressedTextureETC> webgl_compressed_texture_etc_;
   Member<WebGLCompressedTextureETC1> webgl_compressed_texture_etc1_;
@@ -82,7 +83,6 @@
   Member<WebGLLoseContext> webgl_lose_context_;
   Member<WebGLMultiDraw> webgl_multi_draw_;
   Member<WebGLMultiDrawInstanced> webgl_multi_draw_instanced_;
-  Member<WebGLMultiview> webgl_multiview_;
   Member<WebGLVideoTexture> webgl_video_texture_;
 };
 
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
index 25ea271..2b89184 100644
--- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
@@ -5697,18 +5697,16 @@
       case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
         return WebGLAny(script_state, GL_LINEAR);
       case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
-        if (ExtensionEnabled(kWebGLMultiviewName))
+        if (ExtensionEnabled(kOVRMultiview2Name))
           return WebGLAny(script_state, 0);
-        SynthesizeGLError(
-            GL_INVALID_ENUM, kFunctionName,
-            "invalid parameter name, WEBGL_multiview not enabled");
+        SynthesizeGLError(GL_INVALID_ENUM, kFunctionName,
+                          "invalid parameter name, OVR_multiview2 not enabled");
         return ScriptValue::CreateNull(script_state);
       case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR:
-        if (ExtensionEnabled(kWebGLMultiviewName))
+        if (ExtensionEnabled(kOVRMultiview2Name))
           return WebGLAny(script_state, 0);
-        SynthesizeGLError(
-            GL_INVALID_ENUM, kFunctionName,
-            "invalid parameter name, WEBGL_multiview not enabled");
+        SynthesizeGLError(GL_INVALID_ENUM, kFunctionName,
+                          "invalid parameter name, OVR_multiview2 not enabled");
         return ScriptValue::CreateNull(script_state);
       default:
         SynthesizeGLError(GL_INVALID_ENUM, kFunctionName,
@@ -5788,10 +5786,9 @@
     }
     case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
     case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR: {
-      if (!ExtensionEnabled(kWebGLMultiviewName)) {
-        SynthesizeGLError(
-            GL_INVALID_ENUM, kFunctionName,
-            "invalid parameter name, WEBGL_multiview not enabled");
+      if (!ExtensionEnabled(kOVRMultiview2Name)) {
+        SynthesizeGLError(GL_INVALID_ENUM, kFunctionName,
+                          "invalid parameter name, OVR_multiview2 not enabled");
         return ScriptValue::CreateNull(script_state);
       }
       GLint value = 0;
diff --git a/third_party/blink/renderer/modules/webgl/webgl_extension_name.h b/third_party/blink/renderer/modules/webgl/webgl_extension_name.h
index 03e849c..474a38a 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_extension_name.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_extension_name.h
@@ -28,6 +28,7 @@
   kOESTextureHalfFloatLinearName,
   kOESTextureHalfFloatName,
   kOESVertexArrayObjectName,
+  kOVRMultiview2Name,
   kWebGLColorBufferFloatName,
   kWebGLCompressedTextureASTCName,
   kWebGLCompressedTextureETCName,
diff --git a/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc b/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc
index fd87ef5..0746836d 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc
@@ -251,7 +251,7 @@
       case GL_TEXTURE_2D_ARRAY:
         if (num_views > 0) {
           DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D_ARRAY), tex_target);
-          Context()->ContextGL()->FramebufferTextureMultiviewLayeredANGLE(
+          Context()->ContextGL()->FramebufferTextureMultiviewOVR(
               target, attachment, texture_id, level, layer, num_views);
         } else {
           Context()->ContextGL()->FramebufferTextureLayer(
diff --git a/third_party/blink/renderer/modules/webgl/webgl_multiview.cc b/third_party/blink/renderer/modules/webgl/webgl_multiview.cc
deleted file mode 100644
index 0419e82..0000000
--- a/third_party/blink/renderer/modules/webgl/webgl_multiview.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/modules/webgl/webgl_multiview.h"
-
-#include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h"
-#include "third_party/blink/renderer/modules/webgl/webgl_framebuffer.h"
-#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h"
-
-namespace blink {
-
-WebGLMultiview::WebGLMultiview(WebGLRenderingContextBase* context)
-    : WebGLExtension(context) {
-  context->ExtensionsUtil()->EnsureExtensionEnabled("GL_ANGLE_multiview");
-  context->ContextGL()->GetIntegerv(GL_MAX_VIEWS_OVR, &max_views_ovr_);
-}
-
-WebGLExtensionName WebGLMultiview::GetName() const {
-  return kWebGLMultiviewName;
-}
-
-WebGLMultiview* WebGLMultiview::Create(WebGLRenderingContextBase* context) {
-  return MakeGarbageCollected<WebGLMultiview>(context);
-}
-
-void WebGLMultiview::framebufferTextureMultiviewWEBGL(GLenum target,
-                                                      GLenum attachment,
-                                                      WebGLTexture* texture,
-                                                      GLint level,
-                                                      GLint base_view_index,
-                                                      GLsizei num_views) {
-  WebGLExtensionScopedContext scoped(this);
-  if (scoped.IsLost())
-    return;
-  if (!scoped.Context()->ValidateNullableWebGLObject(
-          "framebufferTextureMultiviewWEBGL", texture))
-    return;
-  GLenum textarget = texture ? texture->GetTarget() : 0;
-  if (texture) {
-    if (textarget != GL_TEXTURE_2D_ARRAY) {
-      scoped.Context()->SynthesizeGLError(GL_INVALID_OPERATION,
-                                          "framebufferTextureMultiviewWEBGL",
-                                          "invalid texture type");
-      return;
-    }
-    if (num_views < 1) {
-      scoped.Context()->SynthesizeGLError(GL_INVALID_VALUE,
-                                          "framebufferTextureMultiviewWEBGL",
-                                          "numViews is less than one");
-      return;
-    }
-    if (num_views > max_views_ovr_) {
-      scoped.Context()->SynthesizeGLError(
-          GL_INVALID_VALUE, "framebufferTextureMultiviewWEBGL",
-          "numViews is more than the value of MAX_VIEWS_OVR");
-      return;
-    }
-    if (!static_cast<WebGL2RenderingContextBase*>(scoped.Context())
-             ->ValidateTexFuncLayer("framebufferTextureMultiviewWEBGL",
-                                    textarget, base_view_index))
-      return;
-    if (!static_cast<WebGL2RenderingContextBase*>(scoped.Context())
-             ->ValidateTexFuncLayer("framebufferTextureMultiviewWEBGL",
-                                    textarget, base_view_index + num_views - 1))
-      return;
-    if (!scoped.Context()->ValidateTexFuncLevel(
-            "framebufferTextureMultiviewWEBGL", textarget, level))
-      return;
-  }
-
-  WebGLFramebuffer* framebuffer_binding =
-      scoped.Context()->GetFramebufferBinding(target);
-  if (!framebuffer_binding || !framebuffer_binding->Object()) {
-    scoped.Context()->SynthesizeGLError(GL_INVALID_OPERATION,
-                                        "framebufferTextureMultiviewWEBGL",
-                                        "no framebuffer bound");
-    return;
-  }
-  // Don't allow modifications to opaque framebuffer attachements.
-  if (framebuffer_binding->Opaque()) {
-    scoped.Context()->SynthesizeGLError(GL_INVALID_OPERATION,
-                                        "framebufferTextureMultiviewWEBGL",
-                                        "opaque framebuffer bound");
-    return;
-  }
-
-  framebuffer_binding->SetAttachmentForBoundFramebuffer(
-      target, attachment, textarget, texture, level, base_view_index,
-      num_views);
-  scoped.Context()->ApplyStencilTest();
-}
-
-bool WebGLMultiview::Supported(WebGLRenderingContextBase* context) {
-  return context->ExtensionsUtil()->SupportsExtension("GL_ANGLE_multiview");
-}
-
-const char* WebGLMultiview::ExtensionName() {
-  return "WEBGL_multiview";
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgl/webgl_multiview.h b/third_party/blink/renderer/modules/webgl/webgl_multiview.h
deleted file mode 100644
index 8f76d0f..0000000
--- a/third_party/blink/renderer/modules/webgl/webgl_multiview.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_MULTIVIEW_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_MULTIVIEW_H_
-
-#include "third_party/blink/renderer/modules/webgl/webgl_extension.h"
-
-namespace blink {
-
-class WebGLMultiview final : public WebGLExtension {
-  DEFINE_WRAPPERTYPEINFO();
-
- public:
-  static WebGLMultiview* Create(WebGLRenderingContextBase*);
-  static bool Supported(WebGLRenderingContextBase*);
-  static const char* ExtensionName();
-
-  explicit WebGLMultiview(WebGLRenderingContextBase*);
-
-  WebGLExtensionName GetName() const override;
-
-  void framebufferTextureMultiviewWEBGL(GLenum target,
-                                        GLenum attachment,
-                                        WebGLTexture* texture,
-                                        GLint level,
-                                        GLint baseViewIndex,
-                                        GLsizei numViews);
-
- private:
-  GLsizei max_views_ovr_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_MULTIVIEW_H_
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index cf44193..84cacc3 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -3405,10 +3405,10 @@
           "invalid parameter name, EXT_disjoint_timer_query not enabled");
       return ScriptValue::CreateNull(script_state);
     case GL_MAX_VIEWS_OVR:
-      if (ExtensionEnabled(kWebGLMultiviewName))
+      if (ExtensionEnabled(kOVRMultiview2Name))
         return GetIntParameter(script_state, pname);
       SynthesizeGLError(GL_INVALID_ENUM, "getParameter",
-                        "invalid parameter name, WEBGL_multiview not enabled");
+                        "invalid parameter name, OVR_multiview2 not enabled");
       return ScriptValue::CreateNull(script_state);
     default:
       if ((ExtensionEnabled(kWebGLDrawBuffersName) || IsWebGL2OrHigher()) &&
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
index 132311a..eba175f 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -623,6 +623,7 @@
   friend class WebGLObject;
   friend class WebGLContextObject;
   friend class OESVertexArrayObject;
+  friend class OVRMultiview2;
   friend class WebGLDebugShaders;
   friend class WebGLCompressedTextureASTC;
   friend class WebGLCompressedTextureETC;
@@ -633,7 +634,6 @@
   friend class WebGLMultiDraw;
   friend class WebGLMultiDrawCommon;
   friend class WebGLMultiDrawInstanced;
-  friend class WebGLMultiview;
   friend class WebGLRenderingContextErrorMessageCallback;
   friend class WebGLVertexArrayObjectBase;
   friend class WebGLVideoTexture;
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 3ea264aa..ee4878ff 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -6266,3 +6266,7 @@
 crbug.com/951638 [ Linux ] virtual/mouseevent_fractional/fast/events/mouse-right-coords-in-zoom-and-scroll-right.html [ Pass Failure ]
 crbug.com/951638 [ Mac10.13 Debug ] virtual/mouseevent_fractional/fast/events/mouse-right-coords-in-zoom-and-scroll-right.html [ Pass Failure ]
 crbug.com/951638 [ Win7 ] virtual/mouseevent_fractional/fast/events/mouse-right-coords-in-zoom-and-scroll-right.html [ Pass Failure ]
+
+# Sheriff 2019-04-11
+crbug.com/951774 [ Linux ] virtual/video-surface-layer/media/controls/modern/overlay-play-button-tap-to-hide.html [ Pass Timeout ]
+crbug.com/951811 [ Mac10.13 ] external/wpt/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-top-left.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
index c0623e4d..168fe69 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -470247,7 +470247,7 @@
    "support"
   ],
   "tools/ci/azure/install_safari.yml": [
-   "88381085665fe71c40933a5ad4a59cbe15463236",
+   "be18f8376467b516a68e026c493b8fb679697236",
    "support"
   ],
   "tools/ci/azure/pip_install.yml": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scoping/reference/green-text.html b/third_party/blink/web_tests/external/wpt/css/css-scoping/reference/green-text.html
new file mode 100644
index 0000000..95736b4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-scoping/reference/green-text.html
@@ -0,0 +1,3 @@
+<!doctype html>
+<title>CSS Test: Reference</title>
+<p style="color:green">This text should be green.</p>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scoping/reslot-text-inheritance.html b/third_party/blink/web_tests/external/wpt/css/css-scoping/reslot-text-inheritance.html
new file mode 100644
index 0000000..43711c8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-scoping/reslot-text-inheritance.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<html class="reftest-wait">
+<title>CSS Test: Re-slotted text node inheritance</title>
+<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo">
+<link rel="match" href="reference/green-text.html">
+<script src="/common/reftest-wait.js"></script>
+<p id="host">This text should be green.</p>
+<script>
+  const root = host.attachShadow({mode:"open"});
+  root.innerHTML = `
+    <slot style="color:green" name="no-match"></slot>
+    <slot style="color:red"></slot>
+  `;
+  host.offsetTop;
+  root.querySelector("slot").removeAttribute("name");
+  takeScreenshot();
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/azure/install_safari.yml b/third_party/blink/web_tests/external/wpt/tools/ci/azure/install_safari.yml
index 8838108..be18f83 100644
--- a/third_party/blink/web_tests/external/wpt/tools/ci/azure/install_safari.yml
+++ b/third_party/blink/web_tests/external/wpt/tools/ci/azure/install_safari.yml
@@ -1,19 +1,19 @@
 parameters:
   channel: preview
 
+# Should match https://web-platform-tests.org/running-tests/safari.html
 steps:
 - ${{ if eq(parameters.channel, 'preview') }}:
   - script: |
       # This is equivalent to `Homebrew/homebrew-cask-versions/safari-technology-preview`,
       # but the raw URL is used to bypass caching.
       HOMEBREW_NO_AUTO_UPDATE=1 brew cask install https://raw.githubusercontent.com/Homebrew/homebrew-cask-versions/master/Casks/safari-technology-preview.rb
-      # https://web-platform-tests.org/running-tests/safari.html
       sudo "/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver" --enable
-      defaults write com.apple.Safari WebKitJavaScriptCanOpenWindowsAutomatically 1
+      defaults write com.apple.SafariTechnologyPreview WebKitJavaScriptCanOpenWindowsAutomatically 1
+      defaults write com.apple.SafariTechnologyPreview ExperimentalServerTimingEnabled 1
     displayName: 'Install Safari Technology Preview'
 - ${{ if eq(parameters.channel, 'stable') }}:
   - script: |
-      # https://web-platform-tests.org/running-tests/safari.html
       sudo safaridriver --enable
       defaults write com.apple.Safari WebKitJavaScriptCanOpenWindowsAutomatically 1
     displayName: 'Configure Safari'
diff --git a/third_party/blink/web_tests/http/tests/devtools/editor/text-editor-toggle-tab-moves-focus-expected.txt b/third_party/blink/web_tests/http/tests/devtools/editor/text-editor-toggle-tab-moves-focus-expected.txt
new file mode 100644
index 0000000..9dfe2ab
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/devtools/editor/text-editor-toggle-tab-moves-focus-expected.txt
@@ -0,0 +1,37 @@
+This test verifies text editor's enabling and disabling tab moves focus behavior
+
+
+Running: testDefaultTabBehavior
+Focus is on:
+TEXTAREA:Code editor
+After pressing tab, focus is on:
+TEXTAREA:Code editor
+..|function.foo().{
+..var.x.=.11;
+..return.x
+}
+
+Running: testEnableTabMovesFocus
+Enable tab moves focus and press Tab key
+Focus is on:
+TEXTAREA:Code editor
+After pressing tab, focus is on:
+BUTTON:Select an element in the page to inspect it
+|function.foo().{
+..var.x.=.11;
+..return.x
+}
+After pressing shift + tab, focus is on:
+TEXTAREA:Code editor
+
+Running: testDisableTabMovesFocus
+Disable tab moves focus and press Tab key
+Focus is on:
+TEXTAREA:Code editor
+After pressing tab, focus is on:
+TEXTAREA:Code editor
+..|function.foo().{
+..var.x.=.11;
+..return.x
+}
+
diff --git a/third_party/blink/web_tests/http/tests/devtools/editor/text-editor-toggle-tab-moves-focus.js b/third_party/blink/web_tests/http/tests/devtools/editor/text-editor-toggle-tab-moves-focus.js
new file mode 100644
index 0000000..327b360
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/devtools/editor/text-editor-toggle-tab-moves-focus.js
@@ -0,0 +1,83 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(async function() {
+  TestRunner.addResult(`This test verifies text editor's enabling and disabling tab moves focus behavior\n`);
+  await TestRunner.loadModule('sources_test_runner');
+  await TestRunner.showPanel('sources');
+
+  var textEditor = SourcesTestRunner.createTestEditor();
+  textEditor.setMimeType('text/javascript');
+  textEditor.setReadOnly(false);
+  const text = `function foo() {
+  var x = 11;
+  return x
+}`;
+
+  function dumpFocus() {
+    var element = document.deepActiveElement();
+    if (!element) {
+      TestRunner.addResult('null');
+      return;
+    }
+    var name = element.tagName;
+    if (element.id)
+      name += '#' + element.id;
+    if (element.getAttribute('aria-label'))
+      name += ':' + element.getAttribute('aria-label');
+    else if (element.title)
+      name += ':' + element.title;
+    else if (element.textContent && element.textContent.length < 50) {
+      name += ':' + element.textContent.replace('\u200B', '');
+    } else if (element.className)
+      name += '.' + element.className.split(' ').join('.');
+    TestRunner.addResult(name);
+  }
+
+  function setUpTextEditor(text) {
+    textEditor.setText(text);
+    textEditor.focus();
+    SourcesTestRunner.setLineSelections(textEditor, [{line: 0, column: 0}]);
+  }
+
+  function pressTabAndDump(next) {
+    TestRunner.addResult(`Focus is on:`);
+    dumpFocus();
+    eventSender.keyDown('Tab');
+    TestRunner.addResult(`After pressing tab, focus is on:`);
+    dumpFocus();
+    SourcesTestRunner.dumpTextWithSelection(textEditor, true);
+  }
+
+  var testSuite = [
+    function testDefaultTabBehavior(next) {
+      setUpTextEditor(text);
+
+      pressTabAndDump();
+      next();
+    },
+
+    function testEnableTabMovesFocus(next) {
+      setUpTextEditor(text);
+
+      Common.moduleSetting('textEditorTabMovesFocus').set(true);
+      TestRunner.addResult(`Enable tab moves focus and press Tab key`);
+      pressTabAndDump();
+      eventSender.keyDown('Tab', ['shiftKey']);
+      TestRunner.addResult(`After pressing shift + tab, focus is on:`);
+      dumpFocus();
+      next();
+    },
+
+    function testDisableTabMovesFocus(next) {
+      setUpTextEditor(text);
+
+      Common.moduleSetting('textEditorTabMovesFocus').set(false);
+      TestRunner.addResult(`Disable tab moves focus and press Tab key`);
+      pressTabAndDump();
+      next();
+    },
+  ];
+  TestRunner.runTestSuite(testSuite);
+})();
\ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/xmlhttprequest/xmlhttprequest-unload-sync-expected.txt b/third_party/blink/web_tests/http/tests/xmlhttprequest/xmlhttprequest-unload-sync-expected.txt
deleted file mode 100644
index 4b0cf22..0000000
--- a/third_party/blink/web_tests/http/tests/xmlhttprequest/xmlhttprequest-unload-sync-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CONSOLE WARNING: line 8: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-Test behavior of sync XHR during unload
-
-PASS: sync XHR completed successfully
diff --git a/third_party/blink/web_tests/http/tests/xmlhttprequest/xmlhttprequest-unload-sync.html b/third_party/blink/web_tests/http/tests/xmlhttprequest/xmlhttprequest-unload-sync.html
deleted file mode 100644
index 051f3f41..0000000
--- a/third_party/blink/web_tests/http/tests/xmlhttprequest/xmlhttprequest-unload-sync.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<html>
-<body>
-<p>Test behavior of sync XHR during unload</p>
-<script>
-var consoleMessages = document.createElement("ul");
-document.body.appendChild(consoleMessages);
-
-if (window.testRunner) {
-    testRunner.waitUntilDone();
-    testRunner.dumpAsText();
-}
-
-function subframeLoaded()
-{
-    document.getElementById('ifr').contentWindow.location.assign("data:text/html,DONE");
-}
-
-function completed(msg)
-{
-    log(msg);
-    if (window.testRunner)
-        testRunner.notifyDone();
-}
-
-function log(message)
-{
-    var item = document.createElement("li");
-    item.appendChild(document.createTextNode(message));
-    consoleMessages.appendChild(item);
-}
-</script>
-<div id="framediv">
-<iframe id="ifr" name="ifr" src="resources/xmlhttprequest-in-unload-sync.html"></iframe>
-</div>
-</body>
-</html>
diff --git a/third_party/metrics_proto/README.chromium b/third_party/metrics_proto/README.chromium
index 5ce3406..57f1d5c 100644
--- a/third_party/metrics_proto/README.chromium
+++ b/third_party/metrics_proto/README.chromium
@@ -1,8 +1,8 @@
 Name: Metrics Protos
 Short Name: metrics_proto
 URL: This is the canonical public repository
-Version: 241818494
-Date: 2019/04/03 UTC
+Version: 242980535
+Date: 2019/04/11 UTC
 License: BSD
 Security Critical: Yes
 
diff --git a/third_party/metrics_proto/cast_logs.proto b/third_party/metrics_proto/cast_logs.proto
index 9d43c077..8dab9f5 100644
--- a/third_party/metrics_proto/cast_logs.proto
+++ b/third_party/metrics_proto/cast_logs.proto
@@ -163,7 +163,7 @@
   repeated CastConnectionInfo cast_connection_info = 2;
 
   // Stores Cast-enabled device specific events with a various context data.
-  // Next tag: 22
+  // Next tag: 23
   message CastEventProto {
     // The name of the action, hashed by same logic used to hash user action
     // event and histogram.
@@ -229,6 +229,9 @@
 
     // Optional value to log ui version.
     optional string ui_version = 20;
+
+    // Optional field to log SELINUX audit detail.
+    optional string selinux_audit_detail = 22;
   }
   repeated CastEventProto cast_event = 3;
 
diff --git a/third_party/metrics_proto/system_profile.proto b/third_party/metrics_proto/system_profile.proto
index 43f9ce58..e771ad9 100644
--- a/third_party/metrics_proto/system_profile.proto
+++ b/third_party/metrics_proto/system_profile.proto
@@ -80,7 +80,7 @@
   optional string application_locale = 4;
 
   // Information on the user's operating system.
-  // Next tag: 7
+  // Next tag: 8
   message OS {
     // The user's operating system. This should be one of:
     // - Android
@@ -111,6 +111,21 @@
     // ChromeOS and Android, have a kernel version that the OS release version
     // was built with that differs from the version field above.
     optional string kernel_version = 6;
+
+    // Information on ChromeOS ARC runtime. This is collected to ease analysis
+    // on ARC-specific metrics, since this info varies by different boards /
+    // build configs / releases.
+    // Next tag: 2
+    message Arc {
+      // Android release number from build.prop "ro.build.version.release", e.g.
+      // "7.1.1" for N and "9" for P.
+      optional string release = 1;
+    }
+    // Available since M76. This field is reported if current build supports
+    // ARC, regardless of whether ARC is enabled or not. Check "Arc.State"
+    // histogram to determine if ARC is enabled for current report.
+    // Logged on ChromeOS only.
+    optional Arc arc = 7;
   }
   optional OS os = 5;
 
diff --git a/third_party/webrtc_overrides/rtc_base/event.cc b/third_party/webrtc_overrides/rtc_base/event.cc
index 014bc87..f81232c 100644
--- a/third_party/webrtc_overrides/rtc_base/event.cc
+++ b/third_party/webrtc_overrides/rtc_base/event.cc
@@ -28,13 +28,13 @@
   event_.Reset();
 }
 
-bool Event::Wait(int milliseconds) {
-  if (milliseconds == kForever) {
+bool Event::Wait(int give_up_after_ms) {
+  if (give_up_after_ms == kForever) {
     event_.Wait();
     return true;
   }
 
-  return event_.TimedWait(base::TimeDelta::FromMilliseconds(milliseconds));
+  return event_.TimedWait(base::TimeDelta::FromMilliseconds(give_up_after_ms));
 }
 
 }  // namespace rtc
diff --git a/third_party/webrtc_overrides/rtc_base/event.h b/third_party/webrtc_overrides/rtc_base/event.h
index 2d290e69..47a34cd 100644
--- a/third_party/webrtc_overrides/rtc_base/event.h
+++ b/third_party/webrtc_overrides/rtc_base/event.h
@@ -24,8 +24,11 @@
   void Reset();
 
   // Wait for the event to become signaled, for the specified number of
-  // |milliseconds|.  To wait indefinetly, pass kForever.
-  bool Wait(int milliseconds);
+  // milliseconds.  To wait indefinetly, pass kForever.
+  bool Wait(int give_up_after_ms);
+  bool Wait(int give_up_after_ms, int /*warn_after_ms*/) {
+    return Wait(give_up_after_ms);
+  }
 
  private:
   base::WaitableEvent event_;
diff --git a/tools/mb/mb.py b/tools/mb/mb.py
index e42688f8..e2b1cc1 100755
--- a/tools/mb/mb.py
+++ b/tools/mb/mb.py
@@ -613,35 +613,18 @@
     return ' '.join(gn_args)
 
   def Lookup(self):
-    vals = self.ReadIOSBotConfig()
-    if not vals:
-      self.ReadConfigFile()
-      config = self.ConfigFromArgs()
-      if config.startswith('//'):
-        if not self.Exists(self.ToAbsPath(config)):
-          raise MBErr('args file "%s" not found' % config)
-        vals = self.DefaultVals()
-        vals['args_file'] = config
-      else:
-        if not config in self.configs:
-          raise MBErr('Config "%s" not found in %s' %
-                      (config, self.args.config_file))
-        vals = self.FlattenConfig(config)
-    return vals
-
-  def ReadIOSBotConfig(self):
-    if not self.args.master or not self.args.builder:
-      return {}
-    path = self.PathJoin(self.chromium_src_dir, 'ios', 'build', 'bots',
-                         self.args.master, self.args.builder + '.json')
-    if not self.Exists(path):
-      return {}
-
-    contents = json.loads(self.ReadFile(path))
-    gn_args = ' '.join(contents.get('gn_args', []))
-
-    vals = self.DefaultVals()
-    vals['gn_args'] = gn_args
+    self.ReadConfigFile()
+    config = self.ConfigFromArgs()
+    if config.startswith('//'):
+      if not self.Exists(self.ToAbsPath(config)):
+        raise MBErr('args file "%s" not found' % config)
+      vals = self.DefaultVals()
+      vals['args_file'] = config
+    else:
+      if not config in self.configs:
+        raise MBErr('Config "%s" not found in %s' %
+                    (config, self.args.config_file))
+      vals = self.FlattenConfig(config)
     return vals
 
   def ReadConfigFile(self):
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 77b9db073..3307404 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -21783,6 +21783,7 @@
 <action-suffix separator="." ordering="suffix">
   <suffix name="Cancel" label="User canceled downloading an offline item."/>
   <suffix name="MenuDelete" label="User deleted a specific offline item."/>
+  <suffix name="MenuRename" label="User renamed a specific offline item."/>
   <suffix name="MenuShare" label="User shared a specific offline item."/>
   <suffix name="Open" label="User opened an offline item."/>
   <suffix name="Pause" label="User paused downloading an offline item."/>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index c0ab3bc..98ca28aa 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -1187,6 +1187,7 @@
   <int value="4" label="MENU_SHARE"/>
   <int value="5" label="MENU_DELETE"/>
   <int value="6" label="RETRY"/>
+  <int value="7" label="MENU_RENAME"/>
 </enum>
 
 <enum name="Android.DownloadManager.Menu.Actions">
@@ -16478,6 +16479,7 @@
   <int value="542" label="SignedHTTPExchangeEnabled"/>
   <int value="543" label="DeviceQuickFixBuildToken"/>
   <int value="544" label="ExtensionInstallListsMergeEnabled"/>
+  <int value="545" label="SamlInSessionPasswordChangeEnabled"/>
 </enum>
 
 <enum name="EnterprisePolicyInvalidations">
diff --git a/ui/base/mpris/mpris_service_impl.cc b/ui/base/mpris/mpris_service_impl.cc
index 1ba28f8..76ca36f 100644
--- a/ui/base/mpris/mpris_service_impl.cc
+++ b/ui/base/mpris/mpris_service_impl.cc
@@ -212,7 +212,9 @@
 
 void MprisServiceImpl::OnOwnership(const std::string& service_name,
                                    bool success) {
-  DCHECK(success);
+  if (!success)
+    return;
+
   service_ready_ = true;
 
   for (MprisServiceObserver& obs : observers_)
@@ -387,7 +389,7 @@
 
 void MprisServiceImpl::EmitPropertiesChangedSignal(
     const PropertyMap& changed_properties) {
-  if (!bus_ || !exported_object_)
+  if (!bus_ || !exported_object_ || !service_ready_)
     return;
 
   // |signal| follows the PropertiesChanged API:
diff --git a/ui/file_manager/file_manager/cws_widget/cws_widget_container_error_dialog.js b/ui/file_manager/file_manager/cws_widget/cws_widget_container_error_dialog.js
index 800dde2d..a065ab2 100644
--- a/ui/file_manager/file_manager/cws_widget/cws_widget_container_error_dialog.js
+++ b/ui/file_manager/file_manager/cws_widget/cws_widget_container_error_dialog.js
@@ -2,58 +2,54 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-/**
- * @param {HTMLElement} parentNode Node to be parent for this dialog.
- * @constructor
- * @extends {cr.ui.dialogs.BaseDialog}
- */
-function CWSWidgetContainerErrorDialog(parentNode) {
-  cr.ui.dialogs.BaseDialog.call(this, parentNode);
-}
-
-CWSWidgetContainerErrorDialog.prototype = {
-  __proto__: cr.ui.dialogs.BaseDialog.prototype
-};
-
-/**
- * Whether the dialog is showm.
- * @return {boolean}
- */
-CWSWidgetContainerErrorDialog.prototype.shown = function() {
-  return this.container_.classList.contains('shown');
-};
-
-/**
- * One-time initialization of DOM.
- * @protected
- */
-CWSWidgetContainerErrorDialog.prototype.initDom_ = function() {
-  cr.ui.dialogs.BaseDialog.prototype.initDom_.call(this);
-  this.frame_.classList.add('cws-widget-error-dialog-frame');
-  var img = this.document_.createElement('div');
-  img.className = 'cws-widget-error-dialog-img';
-  this.frame_.insertBefore(img, this.text_);
-
-  this.title_.hidden = true;
-  this.closeButton_.hidden = true;
-  this.cancelButton_.hidden = true;
-  this.text_.classList.add('cws-widget-error-dialog-text');
-
-  // Don't allow OK button to lose focus, in order to prevent webview content
-  // from stealing focus.
-  // BaseDialog keeps focus by removing all other focusable elements from tab
-  // order (by setting their tabIndex to -1). This doesn't work for webviews
-  // because the webview embedder cannot access the webview DOM tree, and thus
-  // fails to remove elements in the webview from tab order.
-  this.okButton_.addEventListener('blur', this.refocusOkButton_.bind(this));
-};
-
-/**
- * Focuses OK button.
- * @private
- */
-CWSWidgetContainerErrorDialog.prototype.refocusOkButton_ = function() {
-  if (this.shown()) {
-    this.okButton_.focus();
+class CWSWidgetContainerErrorDialog extends cr.ui.dialogs.BaseDialog {
+  /**
+   * @param {HTMLElement} parentNode Node to be parent for this dialog.
+   */
+  constructor(parentNode) {
+    super(parentNode);
   }
-};
+
+  /**
+   * Whether the dialog is showm.
+   * @return {boolean}
+   */
+  shown() {
+    return this.container_.classList.contains('shown');
+  }
+
+  /**
+   * One-time initialization of DOM.
+   * @protected
+   */
+  initDom_() {
+    super.initDom_();
+    this.frame_.classList.add('cws-widget-error-dialog-frame');
+    var img = this.document_.createElement('div');
+    img.className = 'cws-widget-error-dialog-img';
+    this.frame_.insertBefore(img, this.text_);
+
+    this.title_.hidden = true;
+    this.closeButton_.hidden = true;
+    this.cancelButton_.hidden = true;
+    this.text_.classList.add('cws-widget-error-dialog-text');
+
+    // Don't allow OK button to lose focus, in order to prevent webview content
+    // from stealing focus.
+    // BaseDialog keeps focus by removing all other focusable elements from tab
+    // order (by setting their tabIndex to -1). This doesn't work for webviews
+    // because the webview embedder cannot access the webview DOM tree, and thus
+    // fails to remove elements in the webview from tab order.
+    this.okButton_.addEventListener('blur', this.refocusOkButton_.bind(this));
+  }
+
+  /**
+   * Focuses OK button.
+   * @private
+   */
+  refocusOkButton_() {
+    if (this.shown()) {
+      this.okButton_.focus();
+    }
+  }
+}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog.js
index 977d363..17b7ab9 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog.js
@@ -29,7 +29,7 @@
 
     // The OK button normally dismisses the dialog, so add a button we can
     // customize.
-    this.installButton_ = this.okButton_.cloneNode();
+    this.installButton_ = this.okButton_.cloneNode(false /* deep */);
     this.installButton_.textContent =
         str('INSTALL_LINUX_PACKAGE_INSTALL_BUTTON');
     this.installButton_.addEventListener(
diff --git a/ui/gfx/image/image.cc b/ui/gfx/image/image.cc
index d7237707..eecf022 100644
--- a/ui/gfx/image/image.cc
+++ b/ui/gfx/image/image.cc
@@ -109,10 +109,8 @@
   ImageRepPNG() : ImageRep(Image::kImageRepPNG) {
   }
 
-  ImageRepPNG(const std::vector<ImagePNGRep>& image_png_reps)
-      : ImageRep(Image::kImageRepPNG),
-        image_png_reps_(image_png_reps) {
-  }
+  explicit ImageRepPNG(const std::vector<ImagePNGRep>& image_png_reps)
+      : ImageRep(Image::kImageRepPNG), image_png_reps_(image_png_reps) {}
 
   ~ImageRepPNG() override {}
 
@@ -125,11 +123,11 @@
     if (!size_cache_) {
       for (auto it = image_reps().begin(); it != image_reps().end(); ++it) {
         if (it->scale == 1.0f) {
-          size_cache_.reset(new gfx::Size(it->Size()));
+          size_cache_ = it->Size();
           return *size_cache_;
         }
       }
-      size_cache_.reset(new gfx::Size);
+      size_cache_ = gfx::Size();
     }
 
     return *size_cache_;
@@ -141,29 +139,29 @@
   std::vector<ImagePNGRep> image_png_reps_;
 
   // Cached to avoid having to parse the raw data multiple times.
-  mutable std::unique_ptr<gfx::Size> size_cache_;
+  mutable base::Optional<gfx::Size> size_cache_;
 
   DISALLOW_COPY_AND_ASSIGN(ImageRepPNG);
 };
 
 class ImageRepSkia : public ImageRep {
  public:
-  explicit ImageRepSkia(std::unique_ptr<ImageSkia> image)
-      : ImageRep(Image::kImageRepSkia), image_(std::move(image)) {}
+  explicit ImageRepSkia(ImageSkia image)
+      : ImageRep(Image::kImageRepSkia), image_(image) {}
 
   ~ImageRepSkia() override {}
 
-  int Width() const override { return image_->width(); }
+  int Width() const override { return image_.width(); }
 
-  int Height() const override { return image_->height(); }
+  int Height() const override { return image_.height(); }
 
-  gfx::Size Size() const override { return image_->size(); }
+  gfx::Size Size() const override { return image_.size(); }
 
-  const ImageSkia* image() const { return image_.get(); }
-  ImageSkia* image() { return image_.get(); }
+  const ImageSkia* image() const { return &image_; }
+  ImageSkia* image() { return &image_; }
 
  private:
-  std::unique_ptr<ImageSkia> image_;
+  ImageSkia image_;
 
   DISALLOW_COPY_AND_ASSIGN(ImageRepSkia);
 };
@@ -235,7 +233,7 @@
 // themselves not threadsafe.
 class ImageStorage : public base::RefCounted<ImageStorage> {
  public:
-  ImageStorage(Image::RepresentationType default_type)
+  explicit ImageStorage(Image::RepresentationType default_type)
       : default_representation_type_(default_type)
 #if defined(OS_MACOSX) && !defined(OS_IOS)
         ,
@@ -342,8 +340,7 @@
 Image::Image(const ImageSkia& image) {
   if (!image.isNull()) {
     storage_ = new internal::ImageStorage(Image::kImageRepSkia);
-    AddRepresentation(std::make_unique<internal::ImageRepSkia>(
-        std::make_unique<ImageSkia>(image)));
+    AddRepresentation(std::make_unique<internal::ImageRepSkia>(image));
   }
 }
 
@@ -422,16 +419,16 @@
         const internal::ImageRepCocoaTouch* native_rep =
             GetRepresentation(kImageRepCocoaTouch, true)
                 ->AsImageRepCocoaTouch();
-        scoped_rep.reset(new internal::ImageRepSkia(std::make_unique<ImageSkia>(
-            ImageSkiaFromUIImage(native_rep->image()))));
+        scoped_rep.reset(new internal::ImageRepSkia(
+            ImageSkia(ImageSkiaFromUIImage(native_rep->image()))));
         break;
       }
 #elif defined(OS_MACOSX)
       case kImageRepCocoa: {
         const internal::ImageRepCocoa* native_rep =
             GetRepresentation(kImageRepCocoa, true)->AsImageRepCocoa();
-        scoped_rep.reset(new internal::ImageRepSkia(std::make_unique<ImageSkia>(
-            ImageSkiaFromNSImage(native_rep->image()))));
+        scoped_rep.reset(new internal::ImageRepSkia(
+            ImageSkia(ImageSkiaFromNSImage(native_rep->image()))));
         break;
       }
 #endif
diff --git a/ui/gfx/image/image_generic.cc b/ui/gfx/image/image_generic.cc
index 9d90008..95432b6 100644
--- a/ui/gfx/image/image_generic.cc
+++ b/ui/gfx/image/image_generic.cc
@@ -17,11 +17,11 @@
 namespace {
 
 // Returns a 16x16 red image to visually show error in decoding PNG.
-std::unique_ptr<ImageSkia> GetErrorImageSkia() {
+ImageSkia GetErrorImageSkia() {
   SkBitmap bitmap;
   bitmap.allocN32Pixels(16, 16);
   bitmap.eraseARGB(0xff, 0xff, 0, 0);
-  return std::make_unique<ImageSkia>(ImageSkiaRep(bitmap, 1.0f));
+  return ImageSkia(ImageSkiaRep(bitmap, 1.0f));
 }
 
 class PNGImageSource : public ImageSkiaSource {
@@ -90,8 +90,7 @@
 
 }  // namespace
 
-std::unique_ptr<ImageSkia> ImageSkiaFromPNG(
-    const std::vector<ImagePNGRep>& image_png_reps) {
+ImageSkia ImageSkiaFromPNG(const std::vector<ImagePNGRep>& image_png_reps) {
   if (image_png_reps.empty())
     return GetErrorImageSkia();
   std::unique_ptr<PNGImageSource> image_source(new PNGImageSource);
@@ -104,7 +103,7 @@
   DCHECK(!size.IsEmpty());
   if (size.IsEmpty())
     return GetErrorImageSkia();
-  return std::make_unique<ImageSkia>(std::move(image_source), size);
+  return ImageSkia(std::move(image_source), size);
 }
 
 scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromImageSkia(
diff --git a/ui/gfx/image/image_ios.mm b/ui/gfx/image/image_ios.mm
index 1272728..916b218 100644
--- a/ui/gfx/image/image_ios.mm
+++ b/ui/gfx/image/image_ios.mm
@@ -109,18 +109,18 @@
   return Get1xPNGBytesFromUIImage(image);
 }
 
-std::unique_ptr<ImageSkia> ImageSkiaFromPNG(
+ImageSkia ImageSkiaFromPNG(
     const std::vector<gfx::ImagePNGRep>& image_png_reps) {
   // iOS does not expose libpng, so conversion from PNG to ImageSkia must go
   // through UIImage.
-  auto image_skia = std::make_unique<gfx::ImageSkia>();
+  ImageSkia image_skia;
   for (size_t i = 0; i < image_png_reps.size(); ++i) {
     base::scoped_nsobject<UIImage> uiimage(
         CreateUIImageFromImagePNGRep(image_png_reps[i]));
     gfx::ImageSkiaRep image_skia_rep = ImageSkiaRepOfScaleFromUIImage(
         uiimage, image_png_reps[i].scale);
     if (!image_skia_rep.is_null())
-      image_skia->AddRepresentation(image_skia_rep);
+      image_skia.AddRepresentation(image_skia_rep);
   }
   return image_skia;
 }
diff --git a/ui/gfx/image/image_platform.h b/ui/gfx/image/image_platform.h
index 6eeebe3..e77500c 100644
--- a/ui/gfx/image/image_platform.h
+++ b/ui/gfx/image/image_platform.h
@@ -46,8 +46,7 @@
 gfx::Size NSImageSize(NSImage* image);
 #endif  // defined(OS_MACOSX)
 
-std::unique_ptr<ImageSkia> ImageSkiaFromPNG(
-    const std::vector<ImagePNGRep>& image_png_reps);
+ImageSkia ImageSkiaFromPNG(const std::vector<ImagePNGRep>& image_png_reps);
 scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromImageSkia(
     const ImageSkia* image_skia);
 
diff --git a/ui/gfx/image/image_unittest.cc b/ui/gfx/image/image_unittest.cc
index c25b09ac..b82a941 100644
--- a/ui/gfx/image/image_unittest.cc
+++ b/ui/gfx/image/image_unittest.cc
@@ -4,6 +4,8 @@
 
 #include <stddef.h>
 
+#include <utility>
+
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkCanvas.h"
@@ -575,6 +577,72 @@
   EXPECT_EQ(1U, image2.RepresentationCount());
 }
 
+TEST_F(ImageTest, Copy_PreservesRepresentation) {
+  const gfx::Size kSize1x(25, 25);
+  const gfx::Size kSize2x(50, 50);
+  std::vector<gfx::ImagePNGRep> image_png_reps;
+  image_png_reps.push_back(
+      gfx::ImagePNGRep(gt::CreatePNGBytes(kSize1x.width()), 1.0f));
+  image_png_reps.push_back(
+      gfx::ImagePNGRep(gt::CreatePNGBytes(kSize2x.width()), 2.0f));
+  gfx::Image image(image_png_reps);
+
+  gfx::ImageSkia image_skia = image.AsImageSkia();
+  EXPECT_EQ(kSize1x, image_skia.size());
+  SkISize size = image_skia.GetRepresentation(2.0f).GetBitmap().dimensions();
+  EXPECT_EQ(kSize2x, gfx::Size(size.fWidth, size.fHeight));
+
+  gfx::Image image2(image);
+  gfx::ImageSkia image_skia2 = image2.AsImageSkia();
+  EXPECT_EQ(kSize1x, image_skia2.size());
+  size = image_skia2.GetRepresentation(2.0f).GetBitmap().dimensions();
+  EXPECT_EQ(kSize2x, gfx::Size(size.fWidth, size.fHeight));
+
+  EXPECT_TRUE(image_skia.BackedBySameObjectAs(image_skia2));
+}
+
+TEST_F(ImageTest, Copy_PreventsDuplication) {
+  const gfx::Size kSize1x(25, 25);
+  const gfx::Size kSize2x(50, 50);
+  std::vector<gfx::ImagePNGRep> image_png_reps;
+  image_png_reps.push_back(
+      gfx::ImagePNGRep(gt::CreatePNGBytes(kSize1x.width()), 1.0f));
+  image_png_reps.push_back(
+      gfx::ImagePNGRep(gt::CreatePNGBytes(kSize2x.width()), 2.0f));
+  gfx::Image image(image_png_reps);
+
+  gfx::Image image2(image);
+
+  gfx::ImageSkia image_skia = image.AsImageSkia();
+  EXPECT_EQ(kSize1x, image_skia.size());
+  SkISize size = image_skia.GetRepresentation(2.0f).GetBitmap().dimensions();
+  EXPECT_EQ(kSize2x, gfx::Size(size.fWidth, size.fHeight));
+
+  gfx::ImageSkia image_skia2 = image2.AsImageSkia();
+  EXPECT_EQ(kSize1x, image_skia2.size());
+  size = image_skia2.GetRepresentation(2.0f).GetBitmap().dimensions();
+  EXPECT_EQ(kSize2x, gfx::Size(size.fWidth, size.fHeight));
+
+  EXPECT_TRUE(image_skia.BackedBySameObjectAs(image_skia2));
+}
+
+TEST_F(ImageTest, Copy_PreservesBackingStore) {
+  const gfx::Size kSize1x(25, 25);
+
+  gfx::Image image(gt::CreateImageSkia(kSize1x.width(), kSize1x.height()));
+  gfx::Image image2 = gfx::Image::CreateFrom1xBitmap(image.AsBitmap());
+
+  gfx::ImageSkia image_skia = image.AsImageSkia();
+  gfx::ImageSkia image_skia2 = image2.AsImageSkia();
+
+  // Because we haven't copied the image representation (scale info, etc.) the
+  // new Skia image isn't backed by the same object, but it should still contain
+  // the same bitmap data.
+  EXPECT_FALSE(image_skia2.BackedBySameObjectAs(image_skia));
+  EXPECT_EQ(image_skia.bitmap()->getPixels(),
+            image_skia2.bitmap()->getPixels());
+}
+
 TEST_F(ImageTest, MultiResolutionImageSkia) {
   const int kWidth1x = 10;
   const int kHeight1x = 12;
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py
index 843a5d7..1be8d8d 100755
--- a/ui/gl/generate_bindings.py
+++ b/ui/gl/generate_bindings.py
@@ -619,8 +619,8 @@
   'arguments': 'GLenum target, GLenum attachment, GLuint texture, GLint level, '
                'GLint layer', },
 { 'return_type': 'void',
-  'versions': [{'name': 'glFramebufferTextureMultiviewLayeredANGLE',
-                'extensions': ['GL_ANGLE_multiview']}],
+  'versions': [{'name': 'glFramebufferTextureMultiviewOVR',
+                'extensions': ['GL_OVR_multiview2']}],
   'arguments': 'GLenum target, GLenum attachment, GLuint texture, GLint level, '
                'GLint baseViewIndex, GLsizei numViews', },
 { 'return_type': 'void',
diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h
index 82213de98..209a524 100644
--- a/ui/gl/gl_bindings.h
+++ b/ui/gl/gl_bindings.h
@@ -451,7 +451,7 @@
 #define GL_SERVICE_LOG_CODE_BLOCK(code) code
 #endif
 
-// ANGLE_multiview constants.
+// OVR_multiview2 constants.
 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630
 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632
 #define GL_MAX_VIEWS_OVR 0x9631
diff --git a/ui/gl/gl_bindings_api_autogen_gl.h b/ui/gl/gl_bindings_api_autogen_gl.h
index fd648bd..2daabaa 100644
--- a/ui/gl/gl_bindings_api_autogen_gl.h
+++ b/ui/gl/gl_bindings_api_autogen_gl.h
@@ -401,12 +401,12 @@
                                  GLuint texture,
                                  GLint level,
                                  GLint layer) override;
-void glFramebufferTextureMultiviewLayeredANGLEFn(GLenum target,
-                                                 GLenum attachment,
-                                                 GLuint texture,
-                                                 GLint level,
-                                                 GLint baseViewIndex,
-                                                 GLsizei numViews) override;
+void glFramebufferTextureMultiviewOVRFn(GLenum target,
+                                        GLenum attachment,
+                                        GLuint texture,
+                                        GLint level,
+                                        GLint baseViewIndex,
+                                        GLsizei numViews) override;
 void glFrontFaceFn(GLenum mode) override;
 void glGenBuffersARBFn(GLsizei n, GLuint* buffers) override;
 void glGenerateMipmapEXTFn(GLenum target) override;
diff --git a/ui/gl/gl_bindings_autogen_gl.cc b/ui/gl/gl_bindings_autogen_gl.cc
index ce23491..beeedfd 100644
--- a/ui/gl/gl_bindings_autogen_gl.cc
+++ b/ui/gl/gl_bindings_autogen_gl.cc
@@ -289,8 +289,6 @@
       gfx::HasExtension(extensions, "GL_ANGLE_instanced_arrays");
   ext.b_GL_ANGLE_multi_draw =
       gfx::HasExtension(extensions, "GL_ANGLE_multi_draw");
-  ext.b_GL_ANGLE_multiview =
-      gfx::HasExtension(extensions, "GL_ANGLE_multiview");
   ext.b_GL_ANGLE_request_extension =
       gfx::HasExtension(extensions, "GL_ANGLE_request_extension");
   ext.b_GL_ANGLE_robust_client_memory =
@@ -433,6 +431,8 @@
       gfx::HasExtension(extensions, "GL_OES_texture_buffer");
   ext.b_GL_OES_vertex_array_object =
       gfx::HasExtension(extensions, "GL_OES_vertex_array_object");
+  ext.b_GL_OVR_multiview = gfx::HasExtension(extensions, "GL_OVR_multiview");
+  ext.b_GL_OVR_multiview2 = gfx::HasExtension(extensions, "GL_OVR_multiview2");
 
   if (ver->IsAtLeastGL(4u, 1u) || ver->IsAtLeastGLES(3u, 1u)) {
     fn.glActiveShaderProgramFn = reinterpret_cast<glActiveShaderProgramProc>(
@@ -1062,10 +1062,10 @@
             GetGLProcAddress("glFramebufferTextureLayer"));
   }
 
-  if (ext.b_GL_ANGLE_multiview) {
-    fn.glFramebufferTextureMultiviewLayeredANGLEFn =
-        reinterpret_cast<glFramebufferTextureMultiviewLayeredANGLEProc>(
-            GetGLProcAddress("glFramebufferTextureMultiviewLayeredANGLE"));
+  if (ext.b_GL_OVR_multiview2 || ext.b_GL_OVR_multiview) {
+    fn.glFramebufferTextureMultiviewOVRFn =
+        reinterpret_cast<glFramebufferTextureMultiviewOVRProc>(
+            GetGLProcAddress("glFramebufferTextureMultiviewOVR"));
   }
 
   if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
@@ -3587,13 +3587,13 @@
                                           layer);
 }
 
-void GLApiBase::glFramebufferTextureMultiviewLayeredANGLEFn(GLenum target,
-                                                            GLenum attachment,
-                                                            GLuint texture,
-                                                            GLint level,
-                                                            GLint baseViewIndex,
-                                                            GLsizei numViews) {
-  driver_->fn.glFramebufferTextureMultiviewLayeredANGLEFn(
+void GLApiBase::glFramebufferTextureMultiviewOVRFn(GLenum target,
+                                                   GLenum attachment,
+                                                   GLuint texture,
+                                                   GLint level,
+                                                   GLint baseViewIndex,
+                                                   GLsizei numViews) {
+  driver_->fn.glFramebufferTextureMultiviewOVRFn(
       target, attachment, texture, level, baseViewIndex, numViews);
 }
 
@@ -6892,17 +6892,16 @@
                                        layer);
 }
 
-void TraceGLApi::glFramebufferTextureMultiviewLayeredANGLEFn(
-    GLenum target,
-    GLenum attachment,
-    GLuint texture,
-    GLint level,
-    GLint baseViewIndex,
-    GLsizei numViews) {
-  TRACE_EVENT_BINARY_EFFICIENT0(
-      "gpu", "TraceGLAPI::glFramebufferTextureMultiviewLayeredANGLE")
-  gl_api_->glFramebufferTextureMultiviewLayeredANGLEFn(
-      target, attachment, texture, level, baseViewIndex, numViews);
+void TraceGLApi::glFramebufferTextureMultiviewOVRFn(GLenum target,
+                                                    GLenum attachment,
+                                                    GLuint texture,
+                                                    GLint level,
+                                                    GLint baseViewIndex,
+                                                    GLsizei numViews) {
+  TRACE_EVENT_BINARY_EFFICIENT0("gpu",
+                                "TraceGLAPI::glFramebufferTextureMultiviewOVR")
+  gl_api_->glFramebufferTextureMultiviewOVRFn(target, attachment, texture,
+                                              level, baseViewIndex, numViews);
 }
 
 void TraceGLApi::glFrontFaceFn(GLenum mode) {
@@ -10896,20 +10895,19 @@
                                        layer);
 }
 
-void DebugGLApi::glFramebufferTextureMultiviewLayeredANGLEFn(
-    GLenum target,
-    GLenum attachment,
-    GLuint texture,
-    GLint level,
-    GLint baseViewIndex,
-    GLsizei numViews) {
-  GL_SERVICE_LOG("glFramebufferTextureMultiviewLayeredANGLE"
+void DebugGLApi::glFramebufferTextureMultiviewOVRFn(GLenum target,
+                                                    GLenum attachment,
+                                                    GLuint texture,
+                                                    GLint level,
+                                                    GLint baseViewIndex,
+                                                    GLsizei numViews) {
+  GL_SERVICE_LOG("glFramebufferTextureMultiviewOVR"
                  << "(" << GLEnums::GetStringEnum(target) << ", "
                  << GLEnums::GetStringEnum(attachment) << ", " << texture
                  << ", " << level << ", " << baseViewIndex << ", " << numViews
                  << ")");
-  gl_api_->glFramebufferTextureMultiviewLayeredANGLEFn(
-      target, attachment, texture, level, baseViewIndex, numViews);
+  gl_api_->glFramebufferTextureMultiviewOVRFn(target, attachment, texture,
+                                              level, baseViewIndex, numViews);
 }
 
 void DebugGLApi::glFrontFaceFn(GLenum mode) {
@@ -15363,14 +15361,13 @@
   NoContextHelper("glFramebufferTextureLayer");
 }
 
-void NoContextGLApi::glFramebufferTextureMultiviewLayeredANGLEFn(
-    GLenum target,
-    GLenum attachment,
-    GLuint texture,
-    GLint level,
-    GLint baseViewIndex,
-    GLsizei numViews) {
-  NoContextHelper("glFramebufferTextureMultiviewLayeredANGLE");
+void NoContextGLApi::glFramebufferTextureMultiviewOVRFn(GLenum target,
+                                                        GLenum attachment,
+                                                        GLuint texture,
+                                                        GLint level,
+                                                        GLint baseViewIndex,
+                                                        GLsizei numViews) {
+  NoContextHelper("glFramebufferTextureMultiviewOVR");
 }
 
 void NoContextGLApi::glFrontFaceFn(GLenum mode) {
diff --git a/ui/gl/gl_bindings_autogen_gl.h b/ui/gl/gl_bindings_autogen_gl.h
index 2cad1d8..a0241f5 100644
--- a/ui/gl/gl_bindings_autogen_gl.h
+++ b/ui/gl/gl_bindings_autogen_gl.h
@@ -462,7 +462,7 @@
                                                              GLuint texture,
                                                              GLint level,
                                                              GLint layer);
-typedef void(GL_BINDING_CALL* glFramebufferTextureMultiviewLayeredANGLEProc)(
+typedef void(GL_BINDING_CALL* glFramebufferTextureMultiviewOVRProc)(
     GLenum target,
     GLenum attachment,
     GLuint texture,
@@ -1840,7 +1840,6 @@
   bool b_GL_ANGLE_framebuffer_multisample;
   bool b_GL_ANGLE_instanced_arrays;
   bool b_GL_ANGLE_multi_draw;
-  bool b_GL_ANGLE_multiview;
   bool b_GL_ANGLE_request_extension;
   bool b_GL_ANGLE_robust_client_memory;
   bool b_GL_ANGLE_translated_shader_source;
@@ -1917,6 +1916,8 @@
   bool b_GL_OES_mapbuffer;
   bool b_GL_OES_texture_buffer;
   bool b_GL_OES_vertex_array_object;
+  bool b_GL_OVR_multiview;
+  bool b_GL_OVR_multiview2;
 };
 
 struct ProcsGL {
@@ -2051,8 +2052,7 @@
   glFramebufferTexture2DMultisampleEXTProc
       glFramebufferTexture2DMultisampleEXTFn;
   glFramebufferTextureLayerProc glFramebufferTextureLayerFn;
-  glFramebufferTextureMultiviewLayeredANGLEProc
-      glFramebufferTextureMultiviewLayeredANGLEFn;
+  glFramebufferTextureMultiviewOVRProc glFramebufferTextureMultiviewOVRFn;
   glFrontFaceProc glFrontFaceFn;
   glGenBuffersARBProc glGenBuffersARBFn;
   glGenerateMipmapEXTProc glGenerateMipmapEXTFn;
@@ -2814,13 +2814,12 @@
                                            GLuint texture,
                                            GLint level,
                                            GLint layer) = 0;
-  virtual void glFramebufferTextureMultiviewLayeredANGLEFn(
-      GLenum target,
-      GLenum attachment,
-      GLuint texture,
-      GLint level,
-      GLint baseViewIndex,
-      GLsizei numViews) = 0;
+  virtual void glFramebufferTextureMultiviewOVRFn(GLenum target,
+                                                  GLenum attachment,
+                                                  GLuint texture,
+                                                  GLint level,
+                                                  GLint baseViewIndex,
+                                                  GLsizei numViews) = 0;
   virtual void glFrontFaceFn(GLenum mode) = 0;
   virtual void glGenBuffersARBFn(GLsizei n, GLuint* buffers) = 0;
   virtual void glGenerateMipmapEXTFn(GLenum target) = 0;
@@ -4226,8 +4225,8 @@
   ::gl::g_current_gl_context->glFramebufferTexture2DMultisampleEXTFn
 #define glFramebufferTextureLayer \
   ::gl::g_current_gl_context->glFramebufferTextureLayerFn
-#define glFramebufferTextureMultiviewLayeredANGLE \
-  ::gl::g_current_gl_context->glFramebufferTextureMultiviewLayeredANGLEFn
+#define glFramebufferTextureMultiviewOVR \
+  ::gl::g_current_gl_context->glFramebufferTextureMultiviewOVRFn
 #define glFrontFace ::gl::g_current_gl_context->glFrontFaceFn
 #define glGenBuffersARB ::gl::g_current_gl_context->glGenBuffersARBFn
 #define glGenerateMipmapEXT ::gl::g_current_gl_context->glGenerateMipmapEXTFn
diff --git a/ui/gl/gl_bindings_autogen_mock.cc b/ui/gl/gl_bindings_autogen_mock.cc
index 99c01875..3f16ef6 100644
--- a/ui/gl/gl_bindings_autogen_mock.cc
+++ b/ui/gl/gl_bindings_autogen_mock.cc
@@ -1428,16 +1428,15 @@
 }
 
 void GL_BINDING_CALL
-MockGLInterface::Mock_glFramebufferTextureMultiviewLayeredANGLE(
-    GLenum target,
-    GLenum attachment,
-    GLuint texture,
-    GLint level,
-    GLint baseViewIndex,
-    GLsizei numViews) {
-  MakeGlMockFunctionUnique("glFramebufferTextureMultiviewLayeredANGLE");
-  interface_->FramebufferTextureMultiviewLayeredANGLE(
-      target, attachment, texture, level, baseViewIndex, numViews);
+MockGLInterface::Mock_glFramebufferTextureMultiviewOVR(GLenum target,
+                                                       GLenum attachment,
+                                                       GLuint texture,
+                                                       GLint level,
+                                                       GLint baseViewIndex,
+                                                       GLsizei numViews) {
+  MakeGlMockFunctionUnique("glFramebufferTextureMultiviewOVR");
+  interface_->FramebufferTextureMultiviewOVR(target, attachment, texture, level,
+                                             baseViewIndex, numViews);
 }
 
 void GL_BINDING_CALL MockGLInterface::Mock_glFrontFace(GLenum mode) {
@@ -5386,9 +5385,9 @@
   if (strcmp(name, "glFramebufferTextureLayer") == 0)
     return reinterpret_cast<GLFunctionPointerType>(
         Mock_glFramebufferTextureLayer);
-  if (strcmp(name, "glFramebufferTextureMultiviewLayeredANGLE") == 0)
+  if (strcmp(name, "glFramebufferTextureMultiviewOVR") == 0)
     return reinterpret_cast<GLFunctionPointerType>(
-        Mock_glFramebufferTextureMultiviewLayeredANGLE);
+        Mock_glFramebufferTextureMultiviewOVR);
   if (strcmp(name, "glFrontFace") == 0)
     return reinterpret_cast<GLFunctionPointerType>(Mock_glFrontFace);
   if (strcmp(name, "glGenBuffers") == 0)
diff --git a/ui/gl/gl_bindings_autogen_mock.h b/ui/gl/gl_bindings_autogen_mock.h
index 4473299..1bbf8395 100644
--- a/ui/gl/gl_bindings_autogen_mock.h
+++ b/ui/gl/gl_bindings_autogen_mock.h
@@ -608,12 +608,12 @@
                                                            GLint level,
                                                            GLint layer);
 static void GL_BINDING_CALL
-Mock_glFramebufferTextureMultiviewLayeredANGLE(GLenum target,
-                                               GLenum attachment,
-                                               GLuint texture,
-                                               GLint level,
-                                               GLint baseViewIndex,
-                                               GLsizei numViews);
+Mock_glFramebufferTextureMultiviewOVR(GLenum target,
+                                      GLenum attachment,
+                                      GLuint texture,
+                                      GLint level,
+                                      GLint baseViewIndex,
+                                      GLsizei numViews);
 static void GL_BINDING_CALL Mock_glFrontFace(GLenum mode);
 static void GL_BINDING_CALL Mock_glGenBuffers(GLsizei n, GLuint* buffers);
 static void GL_BINDING_CALL Mock_glGenFencesAPPLE(GLsizei n, GLuint* fences);
diff --git a/ui/gl/gl_mock_autogen_gl.h b/ui/gl/gl_mock_autogen_gl.h
index 28e475b..c786528 100644
--- a/ui/gl/gl_mock_autogen_gl.h
+++ b/ui/gl/gl_mock_autogen_gl.h
@@ -361,7 +361,7 @@
                   GLuint texture,
                   GLint level,
                   GLint layer));
-MOCK_METHOD6(FramebufferTextureMultiviewLayeredANGLE,
+MOCK_METHOD6(FramebufferTextureMultiviewOVR,
              void(GLenum target,
                   GLenum attachment,
                   GLuint texture,
diff --git a/ui/gl/gl_stub_autogen_gl.h b/ui/gl/gl_stub_autogen_gl.h
index b62f4aa2..175483d 100644
--- a/ui/gl/gl_stub_autogen_gl.h
+++ b/ui/gl/gl_stub_autogen_gl.h
@@ -401,12 +401,12 @@
                                  GLuint texture,
                                  GLint level,
                                  GLint layer) override {}
-void glFramebufferTextureMultiviewLayeredANGLEFn(GLenum target,
-                                                 GLenum attachment,
-                                                 GLuint texture,
-                                                 GLint level,
-                                                 GLint baseViewIndex,
-                                                 GLsizei numViews) override {}
+void glFramebufferTextureMultiviewOVRFn(GLenum target,
+                                        GLenum attachment,
+                                        GLuint texture,
+                                        GLint level,
+                                        GLint baseViewIndex,
+                                        GLsizei numViews) override {}
 void glFrontFaceFn(GLenum mode) override {}
 void glGenBuffersARBFn(GLsizei n, GLuint* buffers) override {}
 void glGenerateMipmapEXTFn(GLenum target) override {}
diff --git a/ui/ozone/platform/scenic/scenic_window.cc b/ui/ozone/platform/scenic/scenic_window.cc
index e26bea4..167369bf 100644
--- a/ui/ozone/platform/scenic/scenic_window.cc
+++ b/ui/ozone/platform/scenic/scenic_window.cc
@@ -176,8 +176,8 @@
 
   // Translate the node by half of the view dimensions to put it in the center
   // of the view.
-  node_.SetTranslationRH(size_dips_.width() / 2.0, size_dips_.height() / 2.0,
-                         0.f);
+  node_.SetTranslation(size_dips_.width() / 2.0, size_dips_.height() / 2.0,
+                       0.f);
 
   // Scale the render node so that surface rect can always be 1x1.
   render_node_.SetScale(size_dips_.width(), size_dips_.height(), 1.f);
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd
index 0fb031b..ca7f8e9 100644
--- a/ui/strings/ui_strings.grd
+++ b/ui/strings/ui_strings.grd
@@ -946,6 +946,14 @@
       <message name="IDS_BADGE_UNREAD_NOTIFICATIONS" desc="The accessibility text which will be read by a screen reader when there are notifcatications">
         {UNREAD_NOTIFICATIONS, plural, =1 {1 Unread Notification} other {# Unread Notifications}}
       </message>
+
+      <!-- Send Tab To Self -->
+      <message name="IDS_SEND_TAB_TO_SELF_INFOBAR_MESSAGE" desc="The message text for the infobar when a user receives a shared tab from another device.">
+        Received a tab
+      </message>
+      <message name="IDS_SEND_TAB_TO_SELF_INFOBAR_MESSAGE_URL" desc="Clickable text displayed as part of a URL in the inforbar displayed when a user receives a shared tab from another device.">
+        Open
+      </message>
     </messages>
   </release>
 </grit>
diff --git a/ui/views/controls/slider.cc b/ui/views/controls/slider.cc
index 9ddc227..75432a2 100644
--- a/ui/views/controls/slider.cc
+++ b/ui/views/controls/slider.cc
@@ -33,12 +33,11 @@
 namespace {
 
 // Color of slider at the active and the disabled state, respectively.
-constexpr SkColor kActiveColor = SkColorSetARGB(0xFF, 0x42, 0x85, 0xF4);
-constexpr SkColor kDisabledColor = SkColorSetARGB(0xFF, 0xBD, 0xBD, 0xBD);
-constexpr uint8_t kHighlightColorAlpha = 0x4D;
+constexpr SkColor kActiveColor = SkColorSetARGB(0xFF, 0x25, 0x81, 0xDF);
+constexpr SkColor kDisabledColor = SkColorSetARGB(0x6E, 0xF1, 0xF3, 0xF4);
 
-// Color of the empty portion of the slider
-const SkColor kEmptySliderColor = SkColorSetARGB(0xFF, 0xBD, 0xBD, 0xBD);
+constexpr uint8_t kActiveColorAlpha = 0x40;
+constexpr uint8_t kDisabledColorAlpha = 0x19;
 
 // The thickness of the slider.
 constexpr int kLineThickness = 2;
@@ -266,9 +265,10 @@
   const int x = content.x() + full + kThumbRadius;
   const SkColor current_thumb_color =
       is_active_ ? kActiveColor : kDisabledColor;
+  const uint8_t current_color_alpha =
+      is_active_ ? kActiveColorAlpha : kDisabledColorAlpha;
   const SkColor empty_slider_color =
-      is_active_ ? kEmptySliderColor
-                 : SkColorSetA(kEmptySliderColor, kHighlightColorAlpha);
+      SkColorSetA(current_thumb_color, current_color_alpha);
 
   // Padding used to adjust space between slider ends and slider thumb.
   // Value is negative when slider is active so that there is no separation
@@ -294,7 +294,7 @@
   if (thumb_highlight_radius > kThumbRadius) {
     cc::PaintFlags highlight;
     SkColor highlight_color =
-        SkColorSetA(current_thumb_color, kHighlightColorAlpha);
+        SkColorSetA(current_thumb_color, current_color_alpha);
     highlight.setColor(highlight_color);
     highlight.setAntiAlias(true);
     canvas->DrawCircle(thumb_center, thumb_highlight_radius, highlight);
diff --git a/ui/webui/resources/js/cr/ui/dialogs.js b/ui/webui/resources/js/cr/ui/dialogs.js
index 95d84fe..c404399 100644
--- a/ui/webui/resources/js/cr/ui/dialogs.js
+++ b/ui/webui/resources/js/cr/ui/dialogs.js
@@ -18,10 +18,33 @@
     // so we can restore it when we're hidden.
     this.previousActiveElement_ = null;
 
-    this.initDom_();
-
+    // TODO: Rename these protected fields to remove the underscore, to comply
+    // with the style guide.
     /** @private{boolean} */
     this.showing_ = false;
+
+    /** @protected {?Element} */
+    this.container_ = null;
+
+    /** @protected {?Element} */
+    this.frame_ = null;
+
+    /** @protected {?Element} */
+    this.title_ = null;
+
+    /** @protected {?Element} */
+    this.text_ = null;
+
+    /** @protected {?Element} */
+    this.closeButton_ = null;
+
+    /** @protected {?Element} */
+    this.okButton_ = null;
+
+    /** @protected {?Element} */
+    this.cancelButton_ = null;
+
+    this.initDom_();
   }
 
   /**