diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc
index 5764c4a..e28ad84 100644
--- a/ash/test/ash_test_helper.cc
+++ b/ash/test/ash_test_helper.cc
@@ -160,6 +160,10 @@
 void AshTestHelper::TearDown() {
   // Tear down the shell.
   Shell::DeleteInstance();
+
+  // Suspend the tear down until all resources are returned via
+  // MojoCompositorFrameSinkClient::ReclaimResources()
+  RunAllPendingInMessageLoop();
   material_design_state_.reset();
   test::MaterialDesignControllerTestAPI::Uninitialize();
   ash_test_environment_->TearDown();
diff --git a/build/config/ios/rules.gni b/build/config/ios/rules.gni
index 778a56b..d6170c49 100644
--- a/build/config/ios/rules.gni
+++ b/build/config/ios/rules.gni
@@ -795,7 +795,7 @@
 #       string, path of the xib or storyboard to compile.
 #
 # Forwards all variables to the bundle_data target.
-template("bundle_data_xib") {
+template("bundle_data_ib_file") {
   assert(defined(invoker.source), "source needs to be defined for $target_name")
 
   _source_extension = get_path_info(invoker.source, "extension")
@@ -803,12 +803,19 @@
          "source must be a .xib or .storyboard for $target_name")
 
   _target_name = target_name
-  _compile_xib = target_name + "_compile_xib"
+  if (_source_extension == "xib") {
+    _compile_ib_file = target_name + "_compile_xib"
+    _output_extension = "nib"
+  } else {
+    _compile_ib_file = target_name + "_compile_storyboard"
+    _output_extension = "storyboardc"
+  }
 
-  compile_xibs(_compile_xib) {
+  compile_ib_files(_compile_ib_file) {
     sources = [
       invoker.source,
     ]
+    output_extension = _output_extension
     visibility = [ ":$_target_name" ]
     ibtool_flags = [
       "--minimum-deployment-target",
@@ -827,9 +834,9 @@
     if (!defined(public_deps)) {
       public_deps = []
     }
-    public_deps += [ ":$_compile_xib" ]
+    public_deps += [ ":$_compile_ib_file" ]
 
-    sources = get_target_outputs(":$_compile_xib")
+    sources = get_target_outputs(":$_compile_ib_file")
 
     outputs = [
       "{{bundle_resources_dir}}/{{source_file_part}}",
diff --git a/build/config/mac/base_rules.gni b/build/config/mac/base_rules.gni
index 92e73a8..341c750 100644
--- a/build/config/mac/base_rules.gni
+++ b/build/config/mac/base_rules.gni
@@ -202,7 +202,7 @@
   }
 }
 
-# Template to combile .xib or .storyboard files.
+# Template to compile .xib and .storyboard files.
 #
 # Arguments
 #
@@ -211,7 +211,7 @@
 #
 #     ibtool_flags:
 #         (optional) list of string, additional flags to pass to the ibtool
-template("compile_xibs") {
+template("compile_ib_files") {
   action_foreach(target_name) {
     forward_variables_from(invoker,
                            [
@@ -219,23 +219,28 @@
                              "visibility",
                            ])
     assert(defined(invoker.sources),
-           "Sources must be specified for $target_name")
+           "sources must be specified for $target_name")
+    assert(defined(invoker.output_extension),
+           "output_extension must be specified for $target_name")
 
     ibtool_flags = []
     if (defined(invoker.ibtool_flags)) {
       ibtool_flags = invoker.ibtool_flags
     }
 
-    script = "//build/config/mac/compile_xib.py"
+    _output_extension = invoker.output_extension
+
+    script = "//build/config/mac/compile_ib_files.py"
     sources = invoker.sources
     outputs = [
-      "$target_gen_dir/$target_name/{{source_name_part}}.nib",
+      "$target_gen_dir/$target_name/{{source_name_part}}.$_output_extension",
     ]
     args = [
       "--input",
       "{{source}}",
       "--output",
-      rebase_path("$target_gen_dir/$target_name/{{source_name_part}}.nib"),
+      rebase_path(
+          "$target_gen_dir/$target_name/{{source_name_part}}.$_output_extension"),
     ]
     if (!use_system_xcode) {
       args += [
diff --git a/build/config/mac/compile_xib.py b/build/config/mac/compile_ib_files.py
similarity index 100%
rename from build/config/mac/compile_xib.py
rename to build/config/mac/compile_ib_files.py
diff --git a/build/config/mac/rules.gni b/build/config/mac/rules.gni
index f595034..dd7b4a5 100644
--- a/build/config/mac/rules.gni
+++ b/build/config/mac/rules.gni
@@ -77,10 +77,11 @@
   _target_name = target_name
   _compile_target_name = _target_name + "_compile_ibtool"
 
-  compile_xibs(_compile_target_name) {
+  compile_ib_files(_compile_target_name) {
     forward_variables_from(invoker, [ "testonly" ])
     visibility = [ ":$_target_name" ]
     sources = invoker.sources
+    output_extension = "nib"
     ibtool_flags = [
       "--minimum-deployment-target",
       mac_deployment_target,
diff --git a/chrome/browser/media/webrtc/desktop_media_list_ash_unittest.cc b/chrome/browser/media/webrtc/desktop_media_list_ash_unittest.cc
index 39d98cc..c8db1f8 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_ash_unittest.cc
+++ b/chrome/browser/media/webrtc/desktop_media_list_ash_unittest.cc
@@ -38,6 +38,12 @@
   DesktopMediaListAshTest() {}
   ~DesktopMediaListAshTest() override {}
 
+  void TearDown() override {
+    // Reset the unique_ptr so the list stops refreshing.
+    list_.reset();
+    ash::test::AshTestBase::TearDown();
+  }
+
   void CreateList(int source_types) {
     list_.reset(new DesktopMediaListAsh(source_types));
     list_->SetThumbnailSize(gfx::Size(kThumbnailSize, kThumbnailSize));
diff --git a/components/exo/BUILD.gn b/components/exo/BUILD.gn
index d4aebaf..0086efe7 100644
--- a/components/exo/BUILD.gn
+++ b/components/exo/BUILD.gn
@@ -9,6 +9,10 @@
   sources = [
     "buffer.cc",
     "buffer.h",
+    "compositor_frame_sink.cc",
+    "compositor_frame_sink.h",
+    "compositor_frame_sink_holder.cc",
+    "compositor_frame_sink_holder.h",
     "display.cc",
     "display.h",
     "gamepad.cc",
@@ -156,6 +160,7 @@
     "//base",
     "//base/test:test_support",
     "//device/gamepad:test_helpers",
+    "//mojo/edk/embedder:headers",
   ]
 
   data_deps = [
diff --git a/components/exo/DEPS b/components/exo/DEPS
index 6eb071a..17b1c94c 100644
--- a/components/exo/DEPS
+++ b/components/exo/DEPS
@@ -4,8 +4,15 @@
   "+chromeos/audio/chromeos_sounds.h",
   "+device/gamepad",
   "+gpu",
+  "+mojo/public/cpp",
   "+services/ui/public/cpp",
   "+third_party/khronos",
   "+third_party/skia",
   "+ui",
 ]
+
+specific_include_rules = {
+  "run_all_unittests\.cc": [
+    "+mojo/edk/embedder/embedder.h",
+  ],
+}
diff --git a/components/exo/compositor_frame_sink.cc b/components/exo/compositor_frame_sink.cc
new file mode 100644
index 0000000..9d4ab95
--- /dev/null
+++ b/components/exo/compositor_frame_sink.cc
@@ -0,0 +1,101 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/compositor_frame_sink.h"
+
+#include "cc/surfaces/surface.h"
+#include "cc/surfaces/surface_manager.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace exo {
+
+////////////////////////////////////////////////////////////////////////////////
+// ExoComopositorFrameSink, public:
+
+// static
+void CompositorFrameSink::Create(
+    const cc::FrameSinkId& frame_sink_id,
+    cc::SurfaceManager* surface_manager,
+    cc::mojom::MojoCompositorFrameSinkClientPtr client,
+    cc::mojom::MojoCompositorFrameSinkRequest request) {
+  std::unique_ptr<CompositorFrameSink> impl =
+      base::MakeUnique<CompositorFrameSink>(frame_sink_id, surface_manager,
+                                            std::move(client));
+  CompositorFrameSink* compositor_frame_sink = impl.get();
+  compositor_frame_sink->binding_ =
+      mojo::MakeStrongBinding(std::move(impl), std::move(request));
+}
+
+CompositorFrameSink::CompositorFrameSink(
+    const cc::FrameSinkId& frame_sink_id,
+    cc::SurfaceManager* surface_manager,
+    cc::mojom::MojoCompositorFrameSinkClientPtr client)
+    : support_(this, surface_manager, frame_sink_id, nullptr),
+      client_(std::move(client)) {}
+
+CompositorFrameSink::~CompositorFrameSink() {}
+
+////////////////////////////////////////////////////////////////////////////////
+// cc::mojom::MojoCompositorFrameSink overrides:
+
+void CompositorFrameSink::SetNeedsBeginFrame(bool needs_begin_frame) {
+  support_.SetNeedsBeginFrame(needs_begin_frame);
+}
+
+void CompositorFrameSink::SubmitCompositorFrame(
+    const cc::LocalFrameId& local_frame_id,
+    cc::CompositorFrame frame) {
+  support_.SubmitCompositorFrame(local_frame_id, std::move(frame));
+}
+
+void CompositorFrameSink::AddSurfaceReferences(
+    const std::vector<cc::SurfaceReference>& references) {
+  // TODO(fsamuel, staraz): Implement this.
+  NOTIMPLEMENTED();
+}
+
+void CompositorFrameSink::RemoveSurfaceReferences(
+    const std::vector<cc::SurfaceReference>& references) {
+  // TODO(fsamuel, staraz): Implement this.
+  NOTIMPLEMENTED();
+}
+
+void CompositorFrameSink::EvictFrame() {
+  support_.EvictFrame();
+}
+
+void CompositorFrameSink::Require(const cc::LocalFrameId& local_frame_id,
+                                  const cc::SurfaceSequence& sequence) {
+  support_.Require(local_frame_id, sequence);
+}
+
+void CompositorFrameSink::Satisfy(const cc::SurfaceSequence& sequence) {
+  support_.Satisfy(sequence);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// cc::CompositorFrameSinkSupportClient overrides:
+
+void CompositorFrameSink::DidReceiveCompositorFrameAck() {
+  if (client_)
+    client_->DidReceiveCompositorFrameAck();
+}
+
+void CompositorFrameSink::OnBeginFrame(const cc::BeginFrameArgs& args) {
+  if (client_)
+    client_->OnBeginFrame(args);
+}
+
+void CompositorFrameSink::ReclaimResources(
+    const cc::ReturnedResourceArray& resources) {
+  if (client_)
+    client_->ReclaimResources(resources);
+}
+
+void CompositorFrameSink::WillDrawSurface() {
+  if (client_)
+    client_->WillDrawSurface();
+}
+
+}  // namespace exo
diff --git a/components/exo/compositor_frame_sink.h b/components/exo/compositor_frame_sink.h
new file mode 100644
index 0000000..4eace4b
--- /dev/null
+++ b/components/exo/compositor_frame_sink.h
@@ -0,0 +1,61 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EXO_EXO_COMPOSITOR_FRAME_SINK_H_
+#define COMPONENTS_EXO_EXO_COMPOSITOR_FRAME_SINK_H_
+
+#include "cc/ipc/compositor_frame.mojom.h"
+#include "cc/ipc/mojo_compositor_frame_sink.mojom.h"
+#include "cc/resources/transferable_resource.h"
+#include "cc/surfaces/compositor_frame_sink_support.h"
+#include "cc/surfaces/compositor_frame_sink_support_client.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace exo {
+
+class CompositorFrameSink : public cc::CompositorFrameSinkSupportClient,
+                            public cc::mojom::MojoCompositorFrameSink {
+ public:
+  static void Create(const cc::FrameSinkId& frame_sink_id,
+                     cc::SurfaceManager* surface_manager,
+                     cc::mojom::MojoCompositorFrameSinkClientPtr client,
+                     cc::mojom::MojoCompositorFrameSinkRequest request);
+
+  CompositorFrameSink(const cc::FrameSinkId& frame_sink_id,
+                      cc::SurfaceManager* surface_manager,
+                      cc::mojom::MojoCompositorFrameSinkClientPtr client);
+
+  ~CompositorFrameSink() override;
+
+  // Overridden from cc::mojom::MojoCompositorFrameSink:
+  void SetNeedsBeginFrame(bool needs_begin_frame) override;
+  void SubmitCompositorFrame(const cc::LocalFrameId& local_frame_id,
+                             cc::CompositorFrame frame) override;
+  void AddSurfaceReferences(
+      const std::vector<cc::SurfaceReference>& references) override;
+  void RemoveSurfaceReferences(
+      const std::vector<cc::SurfaceReference>& references) override;
+  void EvictFrame() override;
+  void Require(const cc::LocalFrameId& local_frame_id,
+               const cc::SurfaceSequence& sequence) override;
+  void Satisfy(const cc::SurfaceSequence& sequence) override;
+
+  // Overridden from cc::CompositorFrameSinkSupportClient:
+  void DidReceiveCompositorFrameAck() override;
+  void OnBeginFrame(const cc::BeginFrameArgs& args) override;
+  void ReclaimResources(const cc::ReturnedResourceArray& resources) override;
+  void WillDrawSurface() override;
+
+ private:
+  cc::CompositorFrameSinkSupport support_;
+  cc::mojom::MojoCompositorFrameSinkClientPtr client_;
+  cc::ReturnedResourceArray surface_returned_resources_;
+  mojo::StrongBindingPtr<cc::mojom::MojoCompositorFrameSink> binding_;
+
+  DISALLOW_COPY_AND_ASSIGN(CompositorFrameSink);
+};
+
+}  // namespace exo
+
+#endif  // COMPONENTS_EXO_EXO_COMPOSITOR_FRAME_SINK_H_
diff --git a/components/exo/compositor_frame_sink_holder.cc b/components/exo/compositor_frame_sink_holder.cc
new file mode 100644
index 0000000..dd82aff
--- /dev/null
+++ b/components/exo/compositor_frame_sink_holder.cc
@@ -0,0 +1,142 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/compositor_frame_sink_holder.h"
+
+#include "cc/resources/returned_resource.h"
+#include "components/exo/surface.h"
+
+namespace exo {
+
+////////////////////////////////////////////////////////////////////////////////
+// CompositorFrameSinkHolder, public:
+
+CompositorFrameSinkHolder::CompositorFrameSinkHolder(
+    Surface* surface,
+    std::unique_ptr<CompositorFrameSink> frame_sink,
+    cc::mojom::MojoCompositorFrameSinkClientRequest request)
+    : surface_(surface),
+      frame_sink_(std::move(frame_sink)),
+      begin_frame_source_(base::MakeUnique<cc::ExternalBeginFrameSource>(this)),
+      binding_(this, std::move(request)),
+      weak_factory_(this) {
+  surface_->AddSurfaceObserver(this);
+}
+
+bool CompositorFrameSinkHolder::HasReleaseCallbackForResource(
+    cc::ResourceId id) {
+  return release_callbacks_.find(id) != release_callbacks_.end();
+}
+
+void CompositorFrameSinkHolder::AddResourceReleaseCallback(
+    cc::ResourceId id,
+    std::unique_ptr<cc::SingleReleaseCallback> callback) {
+  release_callbacks_[id] = std::make_pair(this, std::move(callback));
+}
+
+void CompositorFrameSinkHolder::ActivateFrameCallbacks(
+    std::list<FrameCallback>* frame_callbacks) {
+  active_frame_callbacks_.splice(active_frame_callbacks_.end(),
+                                 *frame_callbacks);
+  UpdateNeedsBeginFrame();
+}
+
+void CompositorFrameSinkHolder::CancelFrameCallbacks() {
+  // Call pending frame callbacks with a null frame time to indicate that they
+  // have been cancelled.
+  for (const auto& frame_callback : active_frame_callbacks_)
+    frame_callback.Run(base::TimeTicks());
+}
+
+void CompositorFrameSinkHolder::SetNeedsBeginFrame(bool needs_begin_frame) {
+  needs_begin_frame_ = needs_begin_frame;
+  OnNeedsBeginFrames(needs_begin_frame);
+}
+
+void CompositorFrameSinkHolder::Satisfy(const cc::SurfaceSequence& sequence) {
+  frame_sink_->Satisfy(sequence);
+}
+
+void CompositorFrameSinkHolder::Require(const cc::SurfaceId& id,
+                                        const cc::SurfaceSequence& sequence) {
+  frame_sink_->Require(id.local_frame_id(), sequence);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// cc::mojom::MojoCompositorFrameSinkClient overrides:
+
+void CompositorFrameSinkHolder::DidReceiveCompositorFrameAck() {
+  // TODO(staraz): Implement this
+}
+
+void CompositorFrameSinkHolder::OnBeginFrame(const cc::BeginFrameArgs& args) {
+  while (!active_frame_callbacks_.empty()) {
+    active_frame_callbacks_.front().Run(args.frame_time);
+    active_frame_callbacks_.pop_front();
+  }
+  begin_frame_source_->OnBeginFrame(args);
+}
+
+void CompositorFrameSinkHolder::ReclaimResources(
+    const cc::ReturnedResourceArray& resources) {
+  for (auto& resource : resources) {
+    auto it = release_callbacks_.find(resource.id);
+    DCHECK(it != release_callbacks_.end());
+    std::unique_ptr<cc::SingleReleaseCallback> callback =
+        std::move(it->second.second);
+    release_callbacks_.erase(it);
+    callback->Run(resource.sync_token, resource.lost);
+  }
+}
+
+void CompositorFrameSinkHolder::WillDrawSurface() {
+  if (surface_)
+    surface_->WillDraw();
+
+  UpdateNeedsBeginFrame();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// cc::BeginFrameObserver overrides:
+
+const cc::BeginFrameArgs& CompositorFrameSinkHolder::LastUsedBeginFrameArgs()
+    const {
+  return last_begin_frame_args_;
+}
+
+void CompositorFrameSinkHolder::OnBeginFrameSourcePausedChanged(bool paused) {}
+
+////////////////////////////////////////////////////////////////////////////////
+// cc::ExternalBeginFrameSouceClient overrides:
+
+void CompositorFrameSinkHolder::OnNeedsBeginFrames(bool needs_begin_frames) {
+  frame_sink_->SetNeedsBeginFrame(needs_begin_frames);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// SurfaceObserver overrides:
+
+void CompositorFrameSinkHolder::OnSurfaceDestroying(Surface* surface) {
+  surface_->RemoveSurfaceObserver(this);
+  surface_ = nullptr;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ExoComopositorFrameSink, private:
+
+CompositorFrameSinkHolder::~CompositorFrameSinkHolder() {}
+
+void CompositorFrameSinkHolder::UpdateNeedsBeginFrame() {
+  if (!begin_frame_source_)
+    return;
+
+  bool needs_begin_frame = !active_frame_callbacks_.empty();
+  if (needs_begin_frame == needs_begin_frame_)
+    return;
+
+  needs_begin_frame_ = needs_begin_frame;
+  OnNeedsBeginFrames(needs_begin_frame_);
+}
+
+}  // namespace exo
diff --git a/components/exo/compositor_frame_sink_holder.h b/components/exo/compositor_frame_sink_holder.h
new file mode 100644
index 0000000..59cc987
--- /dev/null
+++ b/components/exo/compositor_frame_sink_holder.h
@@ -0,0 +1,108 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EXO_COMPOSITOR_FRAME_SINK_HOLDER_H_
+#define COMPONENTS_EXO_COMPOSITOR_FRAME_SINK_HOLDER_H_
+
+#include <list>
+#include <map>
+#include <memory>
+
+#include "cc/ipc/mojo_compositor_frame_sink.mojom.h"
+#include "cc/resources/single_release_callback.h"
+#include "cc/resources/transferable_resource.h"
+#include "cc/scheduler/begin_frame_source.h"
+#include "components/exo/compositor_frame_sink.h"
+#include "components/exo/surface_observer.h"
+#include "mojo/public/cpp/bindings/binding.h"
+
+namespace exo {
+class Surface;
+
+// This class talks to MojoCompositorFrameSink and keeps track of references to
+// the contents of Buffers. It's keeped alive by references from
+// release_callbacks_. It's destroyed when its owning Surface is destroyed and
+// the last outstanding release callback is called.
+class CompositorFrameSinkHolder
+    : public base::RefCounted<CompositorFrameSinkHolder>,
+      public cc::ExternalBeginFrameSourceClient,
+      public cc::mojom::MojoCompositorFrameSinkClient,
+      public cc::BeginFrameObserver,
+      public SurfaceObserver {
+ public:
+  CompositorFrameSinkHolder(
+      Surface* surface,
+      std::unique_ptr<CompositorFrameSink> frame_sink,
+      cc::mojom::MojoCompositorFrameSinkClientRequest request);
+
+  bool HasReleaseCallbackForResource(cc::ResourceId id);
+  void AddResourceReleaseCallback(
+      cc::ResourceId id,
+      std::unique_ptr<cc::SingleReleaseCallback> callback);
+
+  CompositorFrameSink* GetCompositorFrameSink() { return frame_sink_.get(); }
+
+  base::WeakPtr<CompositorFrameSinkHolder> GetWeakPtr() {
+    return weak_factory_.GetWeakPtr();
+  }
+
+  using FrameCallback = base::Callback<void(base::TimeTicks frame_time)>;
+  void ActivateFrameCallbacks(std::list<FrameCallback>* frame_callbacks);
+  void CancelFrameCallbacks();
+
+  void SetNeedsBeginFrame(bool needs_begin_frame);
+
+  void Satisfy(const cc::SurfaceSequence& sequence);
+  void Require(const cc::SurfaceId& id, const cc::SurfaceSequence& sequence);
+
+  // Overridden from cc::mojom::MojoCompositorFrameSinkClient:
+  void DidReceiveCompositorFrameAck() override;
+  void OnBeginFrame(const cc::BeginFrameArgs& args) override;
+  void ReclaimResources(const cc::ReturnedResourceArray& resources) override;
+  void WillDrawSurface() override;
+
+  // Overridden from cc::BeginFrameObserver:
+  const cc::BeginFrameArgs& LastUsedBeginFrameArgs() const override;
+  void OnBeginFrameSourcePausedChanged(bool paused) override;
+
+  // Overridden from cc::ExternalBeginFrameSouceClient:
+  void OnNeedsBeginFrames(bool needs_begin_frames) override;
+
+  // Overridden from SurfaceObserver:
+  void OnSurfaceDestroying(Surface* surface) override;
+
+ private:
+  friend class base::RefCounted<CompositorFrameSinkHolder>;
+
+  ~CompositorFrameSinkHolder() override;
+
+  void UpdateNeedsBeginFrame();
+
+  // Each release callback holds a reference to the CompositorFrameSinkHolder
+  // itself to keep it alive. Running and erasing the callbacks might result in
+  // the instance being destroyed. Therefore, we should not access any member
+  // variables after running and erasing the callbacks.
+  using ResourceReleaseCallbackMap =
+      std::map<int,
+               std::pair<scoped_refptr<CompositorFrameSinkHolder>,
+                         std::unique_ptr<cc::SingleReleaseCallback>>>;
+  ResourceReleaseCallbackMap release_callbacks_;
+
+  Surface* surface_;
+  std::unique_ptr<CompositorFrameSink> frame_sink_;
+
+  std::list<FrameCallback> active_frame_callbacks_;
+  std::unique_ptr<cc::ExternalBeginFrameSource> begin_frame_source_;
+  bool needs_begin_frame_ = false;
+  cc::BeginFrameArgs last_begin_frame_args_;
+  mojo::Binding<cc::mojom::MojoCompositorFrameSinkClient> binding_;
+
+  base::WeakPtrFactory<CompositorFrameSinkHolder> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(CompositorFrameSinkHolder);
+};
+
+}  // namespace exo
+
+#endif  // COMPONENTS_EXO_COMPOSITOR_FRAME_SINK_HOLDER_H_
diff --git a/components/exo/surface.cc b/components/exo/surface.cc
index 8c5ed61..2c23fc3 100644
--- a/components/exo/surface.cc
+++ b/components/exo/surface.cc
@@ -18,9 +18,7 @@
 #include "cc/quads/texture_draw_quad.h"
 #include "cc/resources/single_release_callback.h"
 #include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_factory.h"
 #include "cc/surfaces/surface_id_allocator.h"
-#include "cc/surfaces/surface_manager.h"
 #include "components/exo/buffer.h"
 #include "components/exo/surface_delegate.h"
 #include "components/exo/surface_observer.h"
@@ -141,73 +139,24 @@
   DISALLOW_COPY_AND_ASSIGN(CustomWindowTargeter);
 };
 
-void SatisfyCallback(cc::SurfaceManager* manager,
-                     const cc::SurfaceSequence& sequence) {
-  std::vector<uint32_t> sequences;
-  sequences.push_back(sequence.sequence);
-  manager->DidSatisfySequences(sequence.frame_sink_id, &sequences);
-}
-
-void RequireCallback(cc::SurfaceManager* manager,
-                     const cc::SurfaceId& id,
-                     const cc::SurfaceSequence& sequence) {
-  cc::Surface* surface = manager->GetSurfaceForId(id);
-  if (!surface) {
-    LOG(ERROR) << "Attempting to require callback on nonexistent surface";
-    return;
-  }
-  surface->AddDestructionDependency(sequence);
-}
-
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
-// SurfaceFactoryOwner, public:
-
-SurfaceFactoryOwner::SurfaceFactoryOwner() {}
-
-////////////////////////////////////////////////////////////////////////////////
-// cc::SurfaceFactoryClient overrides:
-
-void SurfaceFactoryOwner::ReturnResources(
-    const cc::ReturnedResourceArray& resources) {
-  scoped_refptr<SurfaceFactoryOwner> holder(this);
-  for (auto& resource : resources) {
-    auto it = release_callbacks_.find(resource.id);
-    DCHECK(it != release_callbacks_.end());
-    it->second.second->Run(resource.sync_token, resource.lost);
-    release_callbacks_.erase(it);
-  }
-}
-
-void SurfaceFactoryOwner::WillDrawSurface(const cc::LocalFrameId& id,
-                                          const gfx::Rect& damage_rect) {
-  if (surface_)
-    surface_->WillDraw();
-}
-
-void SurfaceFactoryOwner::SetBeginFrameSource(
-    cc::BeginFrameSource* begin_frame_source) {
-  if (surface_)
-    surface_->SetBeginFrameSource(begin_frame_source);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// SurfaceFactoryOwner, private:
-
-SurfaceFactoryOwner::~SurfaceFactoryOwner() {
-  if (surface_factory_->manager())
-    surface_factory_->manager()->InvalidateFrameSinkId(frame_sink_id_);
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // Surface, public:
 
 Surface::Surface()
     : window_(new aura::Window(new CustomWindowDelegate(this))),
-      surface_manager_(
-          aura::Env::GetInstance()->context_factory()->GetSurfaceManager()),
-      factory_owner_(new SurfaceFactoryOwner) {
+      frame_sink_id_(
+          aura::Env::GetInstance()->context_factory()->AllocateFrameSinkId()) {
+  cc::mojom::MojoCompositorFrameSinkClientPtr frame_sink_holder_ptr;
+  cc::mojom::MojoCompositorFrameSinkClientRequest frame_sink_client_request =
+      mojo::GetProxy(&frame_sink_holder_ptr);
+  std::unique_ptr<CompositorFrameSink> frame_sink(new CompositorFrameSink(
+      frame_sink_id_,
+      aura::Env::GetInstance()->context_factory()->GetSurfaceManager(),
+      std::move(frame_sink_holder_ptr)));
+  compositor_frame_sink_holder_ = new CompositorFrameSinkHolder(
+      this, std::move(frame_sink), std::move(frame_sink_client_request));
   window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
   window_->SetName("ExoSurface");
   window_->SetProperty(kSurfaceKey, this);
@@ -215,15 +164,6 @@
   window_->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter));
   window_->set_owned_by_parent(false);
   window_->AddObserver(this);
-  factory_owner_->surface_ = this;
-  factory_owner_->frame_sink_id_ =
-      aura::Env::GetInstance()->context_factory()->AllocateFrameSinkId();
-  factory_owner_->id_allocator_.reset(new cc::SurfaceIdAllocator());
-  surface_manager_->RegisterFrameSinkId(factory_owner_->frame_sink_id_);
-  surface_manager_->RegisterSurfaceFactoryClient(factory_owner_->frame_sink_id_,
-                                                 factory_owner_.get());
-  factory_owner_->surface_factory_.reset(new cc::SurfaceFactory(
-      factory_owner_->frame_sink_id_, surface_manager_, factory_owner_.get()));
   aura::Env::GetInstance()->context_factory()->AddObserver(this);
 }
 
@@ -235,22 +175,11 @@
   window_->RemoveObserver(this);
   window_->layer()->SetShowSolidColorContent();
 
-  factory_owner_->surface_ = nullptr;
-
-  // Call pending frame callbacks with a null frame time to indicate that they
-  // have been cancelled.
   frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_);
-  active_frame_callbacks_.splice(active_frame_callbacks_.end(),
-                                 frame_callbacks_);
-  for (const auto& frame_callback : active_frame_callbacks_)
-    frame_callback.Run(base::TimeTicks());
-  if (begin_frame_source_ && needs_begin_frame_)
-    begin_frame_source_->RemoveObserver(this);
+  compositor_frame_sink_holder_->ActivateFrameCallbacks(&frame_callbacks_);
+  compositor_frame_sink_holder_->CancelFrameCallbacks();
 
-  factory_owner_->surface_factory_->EvictSurface();
-
-  surface_manager_->UnregisterSurfaceFactoryClient(
-      factory_owner_->frame_sink_id_);
+  compositor_frame_sink_holder_->GetCompositorFrameSink()->EvictFrame();
 }
 
 // static
@@ -259,7 +188,7 @@
 }
 
 cc::SurfaceId Surface::GetSurfaceId() const {
-  return cc::SurfaceId(factory_owner_->frame_sink_id_, local_frame_id_);
+  return cc::SurfaceId(frame_sink_id_, local_frame_id_);
 }
 
 void Surface::Attach(Buffer* buffer) {
@@ -476,7 +405,7 @@
   cc::LocalFrameId old_local_frame_id = local_frame_id_;
   if (needs_commit_to_new_surface_ || !local_frame_id_.is_valid()) {
     needs_commit_to_new_surface_ = false;
-    local_frame_id_ = factory_owner_->id_allocator_->GenerateId();
+    local_frame_id_ = id_allocator_.GenerateId();
   }
 
   UpdateSurface(true);
@@ -489,9 +418,11 @@
     window_->layer()->SetBounds(
         gfx::Rect(window_->layer()->bounds().origin(), content_size_));
     window_->layer()->SetShowSurface(
-        cc::SurfaceId(factory_owner_->frame_sink_id_, local_frame_id_),
-        base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)),
-        base::Bind(&RequireCallback, base::Unretained(surface_manager_)),
+        cc::SurfaceId(frame_sink_id_, local_frame_id_),
+        base::Bind(&CompositorFrameSinkHolder::Satisfy,
+                   compositor_frame_sink_holder_),
+        base::Bind(&CompositorFrameSinkHolder::Require,
+                   compositor_frame_sink_holder_),
         content_size_, contents_surface_to_layer_scale, content_size_);
     window_->layer()->SetFillsBoundsOpaquely(
         state_.blend_mode == SkBlendMode::kSrc ||
@@ -503,7 +434,8 @@
   pending_damage_.setEmpty();
 
   DCHECK(!current_resource_.id ||
-         factory_owner_->release_callbacks_.count(current_resource_.id));
+         compositor_frame_sink_holder_->HasReleaseCallbackForResource(
+             current_resource_.id));
 
   // Move pending frame callbacks to the end of frame_callbacks_.
   frame_callbacks_.splice(frame_callbacks_.end(), pending_frame_callbacks_);
@@ -608,18 +540,7 @@
 }
 
 void Surface::WillDraw() {
-  active_frame_callbacks_.splice(active_frame_callbacks_.end(),
-                                 frame_callbacks_);
-  UpdateNeedsBeginFrame();
-}
-
-void Surface::SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source) {
-  if (begin_frame_source_ && needs_begin_frame_) {
-    begin_frame_source_->RemoveObserver(this);
-    needs_begin_frame_ = false;
-  }
-  begin_frame_source_ = begin_frame_source;
-  UpdateNeedsBeginFrame();
+  compositor_frame_sink_holder_->ActivateFrameCallbacks(&frame_callbacks_);
 }
 
 void Surface::CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces() {
@@ -636,26 +557,12 @@
 }
 
 void Surface::OnWindowAddedToRootWindow(aura::Window* window) {
-  window->layer()->GetCompositor()->AddFrameSink(
-      factory_owner_->frame_sink_id_);
+  window->layer()->GetCompositor()->AddFrameSink(frame_sink_id_);
 }
 
 void Surface::OnWindowRemovingFromRootWindow(aura::Window* window,
                                              aura::Window* new_root) {
-  window->layer()->GetCompositor()->RemoveFrameSink(
-      factory_owner_->frame_sink_id_);
-}
-
-void Surface::OnBeginFrame(const cc::BeginFrameArgs& args) {
-  while (!active_frame_callbacks_.empty()) {
-    active_frame_callbacks_.front().Run(args.frame_time);
-    active_frame_callbacks_.pop_front();
-  }
-  last_begin_frame_args_ = args;
-}
-
-const cc::BeginFrameArgs& Surface::LastUsedBeginFrameArgs() const {
-  return last_begin_frame_args_;
+  window->layer()->GetCompositor()->RemoveFrameSink(frame_sink_id_);
 }
 
 Surface::State::State() : input_region(SkIRect::MakeLargest()) {}
@@ -743,8 +650,8 @@
                                                  texture_mailbox.target());
     resource.is_overlay_candidate = texture_mailbox.is_overlay_candidate();
 
-    factory_owner_->release_callbacks_[resource.id] = std::make_pair(
-        factory_owner_, std::move(texture_mailbox_release_callback));
+    compositor_frame_sink_holder_->AddResourceReleaseCallback(
+        resource.id, std::move(texture_mailbox_release_callback));
     current_resource_ = resource;
   } else {
     current_resource_.id = 0;
@@ -834,24 +741,8 @@
   }
 
   frame.render_pass_list.push_back(std::move(render_pass));
-
-  factory_owner_->surface_factory_->SubmitCompositorFrame(
-      local_frame_id_, std::move(frame), cc::SurfaceFactory::DrawCallback());
-}
-
-void Surface::UpdateNeedsBeginFrame() {
-  if (!begin_frame_source_)
-    return;
-
-  bool needs_begin_frame = !active_frame_callbacks_.empty();
-  if (needs_begin_frame == needs_begin_frame_)
-    return;
-
-  needs_begin_frame_ = needs_begin_frame;
-  if (needs_begin_frame)
-    begin_frame_source_->AddObserver(this);
-  else
-    begin_frame_source_->RemoveObserver(this);
+  compositor_frame_sink_holder_->GetCompositorFrameSink()
+      ->SubmitCompositorFrame(local_frame_id_, std::move(frame));
 }
 
 int64_t Surface::SetPropertyInternal(const void* key,
diff --git a/components/exo/surface.h b/components/exo/surface.h
index 032cd57f..c0dd787 100644
--- a/components/exo/surface.h
+++ b/components/exo/surface.h
@@ -17,7 +17,9 @@
 #include "base/observer_list.h"
 #include "cc/resources/transferable_resource.h"
 #include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/surface_factory_client.h"
+#include "cc/surfaces/surface_id_allocator.h"
+#include "components/exo/compositor_frame_sink.h"
+#include "components/exo/compositor_frame_sink_holder.h"
 #include "third_party/skia/include/core/SkBlendMode.h"
 #include "third_party/skia/include/core/SkRegion.h"
 #include "ui/aura/window.h"
@@ -31,7 +33,6 @@
 }
 
 namespace cc {
-class SurfaceFactory;
 class SurfaceIdAllocator;
 }
 
@@ -57,42 +58,9 @@
 // change in the future when better hardware cursor support is added.
 using CursorProvider = Pointer;
 
-// This class owns the SurfaceFactory and keeps track of references to the
-// contents of Buffers. It's keeped alive by references from
-// release_callbacks_. It's destroyed when its owning Surface is destroyed and
-// the last outstanding release callback is called.
-class SurfaceFactoryOwner : public base::RefCounted<SurfaceFactoryOwner>,
-                            public cc::SurfaceFactoryClient {
- public:
-  SurfaceFactoryOwner();
-
-  // Overridden from cc::SurfaceFactoryClient:
-  void ReturnResources(const cc::ReturnedResourceArray& resources) override;
-  void WillDrawSurface(const cc::LocalFrameId& id,
-                       const gfx::Rect& damage_rect) override;
-  void SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source) override;
-
- private:
-  friend class base::RefCounted<SurfaceFactoryOwner>;
-  friend class Surface;
-
-  ~SurfaceFactoryOwner() override;
-
-  std::map<int,
-           std::pair<scoped_refptr<SurfaceFactoryOwner>,
-                     std::unique_ptr<cc::SingleReleaseCallback>>>
-      release_callbacks_;
-  cc::FrameSinkId frame_sink_id_;
-  std::unique_ptr<cc::SurfaceIdAllocator> id_allocator_;
-  std::unique_ptr<cc::SurfaceFactory> surface_factory_;
-  Surface* surface_ = nullptr;
-};
-
 // This class represents a rectangular area that is displayed on the screen.
 // It has a location, size and pixel contents.
-class Surface : public ui::ContextFactoryObserver,
-                public aura::WindowObserver,
-                public cc::BeginFrameObserver {
+class Surface : public ui::ContextFactoryObserver, public aura::WindowObserver {
  public:
   using PropertyDeallocator = void (*)(int64_t value);
 
@@ -104,9 +72,12 @@
 
   aura::Window* window() { return window_.get(); }
 
-  const cc::LocalFrameId& local_frame_id() const { return local_frame_id_; }
   cc::SurfaceId GetSurfaceId() const;
 
+  CompositorFrameSinkHolder* compositor_frame_sink_holder() {
+    return compositor_frame_sink_holder_.get();
+  }
+
   // Set a buffer as the content of this surface. A buffer can only be attached
   // to one surface at a time.
   void Attach(Buffer* buffer);
@@ -229,11 +200,6 @@
   void OnWindowRemovingFromRootWindow(aura::Window* window,
                                       aura::Window* new_root) override;
 
-  // Overridden from cc::BeginFrameObserver:
-  void OnBeginFrame(const cc::BeginFrameArgs& args) override;
-  const cc::BeginFrameArgs& LastUsedBeginFrameArgs() const override;
-  void OnBeginFrameSourcePausedChanged(bool paused) override {}
-
   // Sets the |value| of the given surface |property|. Setting to the default
   // value (e.g., NULL) removes the property. The caller is responsible for the
   // lifetime of any object set as a property on the Surface.
@@ -314,9 +280,6 @@
   // current_resource_.
   void UpdateSurface(bool full_damage);
 
-  // Adds/Removes begin frame observer based on state.
-  void UpdateNeedsBeginFrame();
-
   int64_t SetPropertyInternal(const void* key,
                               const char* name,
                               PropertyDeallocator deallocator,
@@ -350,13 +313,13 @@
   // The buffer that will become the content of surface when Commit() is called.
   BufferAttachment pending_buffer_;
 
-  cc::SurfaceManager* surface_manager_;
-
-  scoped_refptr<SurfaceFactoryOwner> factory_owner_;
-
-  // The Surface Id currently attached to the window.
+  const cc::FrameSinkId frame_sink_id_;
   cc::LocalFrameId local_frame_id_;
 
+  scoped_refptr<CompositorFrameSinkHolder> compositor_frame_sink_holder_;
+
+  cc::SurfaceIdAllocator id_allocator_;
+
   // The next resource id the buffer will be attached to.
   int next_resource_id_ = 1;
 
@@ -370,7 +333,6 @@
   // be drawn. They fire at the first begin frame notification after this.
   std::list<FrameCallback> pending_frame_callbacks_;
   std::list<FrameCallback> frame_callbacks_;
-  std::list<FrameCallback> active_frame_callbacks_;
 
   // This is the state that has yet to be committed.
   State pending_state_;
@@ -407,11 +369,6 @@
   // maintains.
   SurfaceDelegate* delegate_ = nullptr;
 
-  // The begin frame source being observed.
-  cc::BeginFrameSource* begin_frame_source_ = nullptr;
-  cc::BeginFrameArgs last_begin_frame_args_;
-  bool needs_begin_frame_ = false;
-
   struct Value {
     const char* name;
     int64_t value;
diff --git a/components/exo/surface_unittest.cc b/components/exo/surface_unittest.cc
index 570e4ac..2e82a57 100644
--- a/components/exo/surface_unittest.cc
+++ b/components/exo/surface_unittest.cc
@@ -50,6 +50,11 @@
   // attached buffer.
   surface->Attach(nullptr);
   surface->Commit();
+  // CompositorFrameSinkHolder::ReclaimResources() gets called via
+  // MojoCompositorFrameSinkClient interface. We need to wait here for the mojo
+  // call to finish so that the release callback finishes running before
+  // the assertion below.
+  RunAllPendingInMessageLoop();
   ASSERT_EQ(1, release_buffer_call_count);
 }
 
@@ -205,6 +210,7 @@
   surface->Attach(buffer.get());
   surface->SetBlendMode(SkBlendMode::kSrc);
   surface->Commit();
+  RunAllPendingInMessageLoop();
 
   const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get());
   ASSERT_EQ(1u, frame.render_pass_list.size());
@@ -222,6 +228,7 @@
 
   surface->Attach(buffer.get());
   surface->Commit();
+  RunAllPendingInMessageLoop();
 
   const cc::CompositorFrame& frame = GetFrameFromSurface(surface.get());
   ASSERT_EQ(1u, frame.render_pass_list.size());
diff --git a/components/exo/test/run_all_unittests.cc b/components/exo/test/run_all_unittests.cc
index e69d387..eedc4d93 100644
--- a/components/exo/test/run_all_unittests.cc
+++ b/components/exo/test/run_all_unittests.cc
@@ -6,9 +6,17 @@
 #include "base/bind.h"
 #include "base/test/launcher/unit_test_launcher.h"
 
+#if !defined(OS_IOS)
+#include "mojo/edk/embedder/embedder.h"
+#endif
+
 int main(int argc, char** argv) {
   ash::test::AuraShellTestSuite test_suite(argc, argv);
 
+#if !defined(OS_IOS)
+  mojo::edk::Init();
+#endif
+
   return base::LaunchUnitTestsSerially(
       argc, argv, base::Bind(&ash::test::AuraShellTestSuite::Run,
                              base::Unretained(&test_suite)));
diff --git a/components/exo/wayland/clients/motion_events.cc b/components/exo/wayland/clients/motion_events.cc
index 37cdb04..9f7f86e7 100644
--- a/components/exo/wayland/clients/motion_events.cc
+++ b/components/exo/wayland/clients/motion_events.cc
@@ -673,6 +673,7 @@
     if (!frame.callback_pending) {
       DCHECK_GT(pending_frames.size(), 0u);
       wl_surface_set_buffer_scale(surface.get(), scale_);
+      wl_surface_damage(surface.get(), 0, 0, width_ / scale_, height_ / scale_);
       wl_surface_attach(surface.get(), pending_frames.front(), 0, 0);
       pending_frames.pop_front();
 
diff --git a/device/generic_sensor/BUILD.gn b/device/generic_sensor/BUILD.gn
index 4f7d3fa..110970c 100644
--- a/device/generic_sensor/BUILD.gn
+++ b/device/generic_sensor/BUILD.gn
@@ -77,8 +77,8 @@
     ]
 
     sources += [
-      "linux/platform_sensor_manager.cc",
-      "linux/platform_sensor_manager.h",
+      "linux/sensor_device_manager.cc",
+      "linux/sensor_device_manager.h",
       "platform_sensor_provider_linux.cc",
       "platform_sensor_provider_linux.h",
     ]
diff --git a/device/generic_sensor/linux/platform_sensor_manager.cc b/device/generic_sensor/linux/sensor_device_manager.cc
similarity index 98%
rename from device/generic_sensor/linux/platform_sensor_manager.cc
rename to device/generic_sensor/linux/sensor_device_manager.cc
index 87fecca..4fc0434 100644
--- a/device/generic_sensor/linux/platform_sensor_manager.cc
+++ b/device/generic_sensor/linux/sensor_device_manager.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "device/generic_sensor/linux/platform_sensor_manager.h"
+#include "device/generic_sensor/linux/sensor_device_manager.h"
 
 #include "base/strings/string_number_conversions.h"
 #include "base/threading/thread_restrictions.h"
diff --git a/device/generic_sensor/linux/platform_sensor_manager.h b/device/generic_sensor/linux/sensor_device_manager.h
similarity index 93%
rename from device/generic_sensor/linux/platform_sensor_manager.h
rename to device/generic_sensor/linux/sensor_device_manager.h
index 5d45e38..09528e8 100644
--- a/device/generic_sensor/linux/platform_sensor_manager.h
+++ b/device/generic_sensor/linux/sensor_device_manager.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef DEVICE_GENERIC_SENSOR_LINUX_PLATFORM_SENSOR_MANAGER_H_
-#define DEVICE_GENERIC_SENSOR_LINUX_PLATFORM_SENSOR_MANAGER_H_
+#ifndef DEVICE_GENERIC_SENSOR_LINUX_SENSOR_DEVICE_MANAGER_H_
+#define DEVICE_GENERIC_SENSOR_LINUX_SENSOR_DEVICE_MANAGER_H_
 
 #include "base/scoped_observer.h"
 
@@ -80,4 +80,4 @@
 
 }  // namespace device
 
-#endif  // DEVICE_GENERIC_SENSOR_LINUX_PLATFORM_SENSOR_MANAGER_H_
+#endif  // DEVICE_GENERIC_SENSOR_LINUX_SENSOR_DEVICE_MANAGER_H_
diff --git a/device/generic_sensor/platform_sensor_and_provider_unittest_linux.cc b/device/generic_sensor/platform_sensor_and_provider_unittest_linux.cc
index 0f74b89..074e7b7 100644
--- a/device/generic_sensor/platform_sensor_and_provider_unittest_linux.cc
+++ b/device/generic_sensor/platform_sensor_and_provider_unittest_linux.cc
@@ -10,8 +10,8 @@
 #include "base/strings/string_util.h"
 
 #include "device/generic_sensor/generic_sensor_consts.h"
-#include "device/generic_sensor/linux/platform_sensor_manager.h"
 #include "device/generic_sensor/linux/sensor_data_linux.h"
+#include "device/generic_sensor/linux/sensor_device_manager.h"
 #include "device/generic_sensor/platform_sensor_provider_linux.h"
 
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/device/generic_sensor/platform_sensor_provider_linux.cc b/device/generic_sensor/platform_sensor_provider_linux.cc
index 6451fa3..736c82ff 100644
--- a/device/generic_sensor/platform_sensor_provider_linux.cc
+++ b/device/generic_sensor/platform_sensor_provider_linux.cc
@@ -202,7 +202,7 @@
     const std::string& device_node) {
   DCHECK(CalledOnValidThread());
   auto it = sensor_devices_by_type_.find(type);
-  if (it == sensor_devices_by_type_.end() &&
+  if (it != sensor_devices_by_type_.end() &&
       it->second->device_node == device_node)
     sensor_devices_by_type_.erase(it);
 }
diff --git a/device/generic_sensor/platform_sensor_provider_linux.h b/device/generic_sensor/platform_sensor_provider_linux.h
index 7417c599..7e15590 100644
--- a/device/generic_sensor/platform_sensor_provider_linux.h
+++ b/device/generic_sensor/platform_sensor_provider_linux.h
@@ -7,7 +7,7 @@
 
 #include "device/generic_sensor/platform_sensor_provider.h"
 
-#include "device/generic_sensor/linux/platform_sensor_manager.h"
+#include "device/generic_sensor/linux/sensor_device_manager.h"
 
 namespace base {
 template <typename T>
diff --git a/ios/chrome/app/resources/BUILD.gn b/ios/chrome/app/resources/BUILD.gn
index f89503e..90f39bab 100644
--- a/ios/chrome/app/resources/BUILD.gn
+++ b/ios/chrome/app/resources/BUILD.gn
@@ -107,7 +107,7 @@
   ]
 }
 
-bundle_data_xib("launchscreen_xib") {
+bundle_data_ib_file("launchscreen_xib") {
   source = "LaunchScreen.xib"
   deps = [
     ios_launchscreen_assets_target,
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn
index ebaf2c47..8883299f 100644
--- a/ios/chrome/browser/ui/BUILD.gn
+++ b/ios/chrome/browser/ui/BUILD.gn
@@ -77,7 +77,7 @@
   ]
 }
 
-bundle_data_xib("native_content_controller_test_xib") {
+bundle_data_ib_file("native_content_controller_test_xib") {
   visibility = [ ":unit_tests" ]
   testonly = true
   source = "native_content_controller_test.xib"
diff --git a/ios/chrome/browser/ui/downloads/BUILD.gn b/ios/chrome/browser/ui/downloads/BUILD.gn
index 80010bd..033ec0c 100644
--- a/ios/chrome/browser/ui/downloads/BUILD.gn
+++ b/ios/chrome/browser/ui/downloads/BUILD.gn
@@ -29,6 +29,6 @@
   ]
 }
 
-bundle_data_xib("download_manager_controller_xib") {
+bundle_data_ib_file("download_manager_controller_xib") {
   source = "resources/DownloadManagerController.xib"
 }