--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -2745,8 +2745,10 @@
             }],
           ],
         }],
-        ['use_aura==1 and chromeos==0 and use_ozone==0 and OS=="linux"', {
+        ['use_aura==1 and chromeos==0 and OS=="linux"', {
           'cflags': [ '<!@(pkg-config --cflags glib-2.0)', ],
+	}],
+        ['use_aura==1 and chromeos==0 and use_ozone==0 and OS=="linux"', {
           'dependencies': [
             # gtk2 is the only component that can interact with gtk2 in our new
             # world.
--- a/ui/ozone/BUILD.gn
+++ b/ui/ozone/BUILD.gn
@@ -23,6 +23,11 @@ if (ozone_platform_test) {
   ozone_platform_deps += [ "platform/test" ]
 }
 
+if (ozone_platform_mir) {
+  ozone_platforms += [ "mir" ]
+  ozone_platform_deps += [ "platform/mir" ]
+}
+
 if (ozone_platform_caca) {
   ozone_platforms += [ "caca" ]
   ozone_platform_deps += [ "platform/caca" ]
--- a/ui/ozone/ozone.gni
+++ b/ui/ozone/ozone.gni
@@ -17,6 +17,7 @@ declare_args() {
   ozone_platform_egltest = false
   ozone_platform_gbm = false
   ozone_platform_test = false
+  ozone_platform_mir = false
 
   if (ozone_auto_platforms) {
     # Use test as the default platform.
@@ -27,5 +28,6 @@ declare_args() {
     ozone_platform_dri = true
     ozone_platform_test = true
     ozone_platform_egltest = true
+    ozone_platform_mir = true
   }
 }
--- a/ui/ozone/ozone.gyp
+++ b/ui/ozone/ozone.gyp
@@ -210,5 +210,10 @@
         'platform/test/test.gypi',
       ],
     }],
+    ['<(ozone_platform_mir) == 1', {
+      'includes': [
+        'platform/mir/mir.gypi',
+      ],
+    }],
   ],
 }
--- /dev/null
+++ b/ui/ozone/platform/mir/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("mir") {
+  sources = [
+    "ozone_platform_mir.cc",
+    "ozone_platform_mir.h",
+    "mir_window.cc",
+    "mir_window.h",
+    "mir_window_manager.cc",
+    "mir_window_manager.h",
+  ]
+
+  deps = [
+    "//base",
+    "//skia",
+    "//ui/base",
+    "//ui/gfx/geometry",
+  ]
+}
--- /dev/null
+++ b/ui/ozone/platform/mir/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+third_party/skia/include",
+]
--- /dev/null
+++ b/ui/ozone/platform/mir/desktop_window_tree_host_ozone.h
@@ -0,0 +1,33 @@
+#include <list>
+
+#include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
+#include "ui/platform_window/platform_window_delegate.h"
+#include "ui/events/platform/platform_event_dispatcher.h"
+#include "ui/aura/window_tree_host.h"
+
+namespace views {
+
+class VIEWS_EXPORT DesktopWindowTreeHostOzone
+    : public DesktopWindowTreeHost,
+      public aura::WindowTreeHost,
+      public ui::PlatformWindowDelegate,
+      public ui::PlatformEventDispatcher,
+      public ui::EventSource {
+
+  static std::vector<aura::Window*>* aura_windows_;
+
+  bool IsMaximized() const;
+
+  bool IsFullscreen() const;
+
+  static std::list<gfx::AcceleratedWidget>& open_windows();
+
+public:
+  static const std::vector<aura::Window*>& GetAllOpenWindows();
+
+  static aura::Window* GetContentWindowForAcceleratedWidget(gfx::AcceleratedWidget widget);
+
+};
+
+
+}
--- /dev/null
+++ b/ui/ozone/platform/mir/mir.gypi
@@ -0,0 +1,40 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'variables': {
+    'internal_ozone_platform_deps': [
+      'ozone_platform_mir',
+    ],
+    'internal_ozone_platforms': [
+      'mir'
+    ],
+  },
+  'targets': [
+    {
+      'target_name': 'ozone_platform_mir',
+      'type': 'static_library',
+      'defines': [
+        'OZONE_IMPLEMENTATION',
+      ],
+      'dependencies': [
+        '../../base/base.gyp:base',
+        '../events/events.gyp:events',
+        '../gfx/gfx.gyp:gfx',
+      ],
+      'sources': [
+        'ozone_platform_mir.cc',
+        'ozone_platform_mir.h',
+        'mir_window.cc',
+        'mir_window.h',
+        'mir_window_manager.cc',
+        'mir_window_manager.h',
+	'desktop_window_tree_host_ozone_mir.cc',
+	'ozone_platform_mir.cc',
+	'ozone_platform_mir.h',
+	'util.cc',
+      ],
+    },
+  ],
+}
--- /dev/null
+++ b/ui/ozone/platform/mir/mir_window.cc
@@ -0,0 +1,80 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/mir/mir_window.h"
+
+#include <string>
+
+#include "base/files/file_path.h"
+#include "base/strings/string_number_conversions.h"
+#include "ui/events/platform/platform_event_source.h"
+#include "ui/ozone/platform/mir/mir_window_manager.h"
+#include "ui/platform_window/platform_window_delegate.h"
+
+namespace ui {
+
+MirWindow::MirWindow(PlatformWindowDelegate* delegate,
+                       MirWindowManager* manager,
+                       const gfx::Rect& bounds)
+    : delegate_(delegate), manager_(manager), bounds_(bounds) {
+  widget_ = manager_->AddWindow(this);
+  delegate_->OnAcceleratedWidgetAvailable(widget_);
+}
+
+MirWindow::~MirWindow() {
+  manager_->RemoveWindow(widget_, this);
+}
+
+base::FilePath MirWindow::path() {
+  base::FilePath base_path = manager_->base_path();
+  if (base_path.empty() || base_path == base::FilePath("/dev/null"))
+    return base_path;
+
+  // Disambiguate multiple window output files with the window id.
+  return base_path.Append(base::IntToString(widget_));
+}
+
+gfx::Rect MirWindow::GetBounds() {
+  return bounds_;
+}
+
+void MirWindow::SetBounds(const gfx::Rect& bounds) {
+  bounds_ = bounds;
+  delegate_->OnBoundsChanged(bounds);
+}
+
+void MirWindow::Show() {
+}
+
+void MirWindow::Hide() {
+}
+
+void MirWindow::Close() {
+}
+
+void MirWindow::SetCapture() {
+}
+
+void MirWindow::ReleaseCapture() {
+}
+
+void MirWindow::ToggleFullscreen() {
+}
+
+void MirWindow::Maximize() {
+}
+
+void MirWindow::Minimize() {
+}
+
+void MirWindow::Restore() {
+}
+
+void MirWindow::SetCursor(PlatformCursor cursor) {
+}
+
+void MirWindow::MoveCursorTo(const gfx::Point& location) {
+}
+
+}  // namespace ui
--- /dev/null
+++ b/ui/ozone/platform/mir/mir_window.h
@@ -0,0 +1,54 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_MIR_MIR_WINDOW_H_
+#define UI_OZONE_PLATFORM_MIR_MIR_WINDOW_H_
+
+#include "base/files/file_path.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/platform_window/platform_window.h"
+
+namespace ui {
+
+class PlatformWindowDelegate;
+class MirWindowManager;
+
+class MirWindow : public PlatformWindow {
+ public:
+  MirWindow(PlatformWindowDelegate* delegate,
+             MirWindowManager* manager,
+             const gfx::Rect& bounds);
+  virtual ~MirWindow();
+
+  // Path for image file for this window.
+  base::FilePath path();
+
+  // PlatformWindow:
+  virtual gfx::Rect GetBounds() OVERRIDE;
+  virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE;
+  virtual void Show() OVERRIDE;
+  virtual void Hide() OVERRIDE;
+  virtual void Close() OVERRIDE;
+  virtual void SetCapture() OVERRIDE;
+  virtual void ReleaseCapture() OVERRIDE;
+  virtual void ToggleFullscreen() OVERRIDE;
+  virtual void Maximize() OVERRIDE;
+  virtual void Minimize() OVERRIDE;
+  virtual void Restore() OVERRIDE;
+  virtual void SetCursor(PlatformCursor cursor) OVERRIDE;
+  virtual void MoveCursorTo(const gfx::Point& location) OVERRIDE;
+
+ private:
+  PlatformWindowDelegate* delegate_;
+  MirWindowManager* manager_;
+  gfx::Rect bounds_;
+  gfx::AcceleratedWidget widget_;
+
+  DISALLOW_COPY_AND_ASSIGN(MirWindow);
+};
+
+}  // namespace ui
+
+#endif  // UI_OZONE_PLATFORM_MIR_MIR_WINDOW_H_
--- /dev/null
+++ b/ui/ozone/platform/mir/mir_window_manager.cc
@@ -0,0 +1,112 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/mir/mir_window_manager.h"
+
+#include "base/bind.h"
+#include "base/files/file_util.h"
+#include "base/location.h"
+#include "base/stl_util.h"
+#include "base/threading/worker_pool.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkSurface.h"
+#include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/skia_util.h"
+#include "ui/gfx/vsync_provider.h"
+#include "ui/ozone/public/surface_ozone_canvas.h"
+
+namespace ui {
+
+namespace {
+
+void WriteDataToFile(const base::FilePath& location, const SkBitmap& bitmap) {
+  DCHECK(!location.empty());
+  std::vector<unsigned char> png_data;
+  gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, true, &png_data);
+  base::WriteFile(location,
+                  reinterpret_cast<const char*>(vector_as_array(&png_data)),
+                  png_data.size());
+}
+
+class FileSurface : public SurfaceOzoneCanvas {
+ public:
+  FileSurface(const base::FilePath& location) : location_(location) {}
+  virtual ~FileSurface() {}
+
+  // SurfaceOzoneCanvas overrides:
+  virtual void ResizeCanvas(const gfx::Size& viewport_size) OVERRIDE {
+    surface_ = skia::AdoptRef(SkSurface::NewRaster(SkImageInfo::MakeN32Premul(
+        viewport_size.width(), viewport_size.height())));
+  }
+  virtual skia::RefPtr<SkCanvas> GetCanvas() OVERRIDE {
+    return skia::SharePtr(surface_->getCanvas());
+  }
+  virtual void PresentCanvas(const gfx::Rect& damage) OVERRIDE {
+    if (location_.empty())
+      return;
+    SkBitmap bitmap;
+    bitmap.setInfo(surface_->getCanvas()->imageInfo());
+
+    // TODO(dnicoara) Use SkImage instead to potentially avoid a copy.
+    // See crbug.com/361605 for details.
+    if (surface_->getCanvas()->readPixels(&bitmap, 0, 0)) {
+      base::WorkerPool::PostTask(
+          FROM_HERE, base::Bind(&WriteDataToFile, location_, bitmap), true);
+    }
+  }
+  virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() OVERRIDE {
+    return scoped_ptr<gfx::VSyncProvider>();
+  }
+
+ private:
+  base::FilePath location_;
+  skia::RefPtr<SkSurface> surface_;
+};
+
+}  // namespace
+
+MirWindowManager::MirWindowManager(const base::FilePath& dump_location)
+    : location_(dump_location) {
+}
+
+MirWindowManager::~MirWindowManager() {
+}
+
+void MirWindowManager::Initialize() {
+  if (location_.empty())
+    return;
+  if (!DirectoryExists(location_) && !base::CreateDirectory(location_) &&
+      location_ != base::FilePath("/dev/null"))
+    PLOG(FATAL) << "unable to create output directory";
+  if (!base::PathIsWritable(location_))
+    PLOG(FATAL) << "unable to write to output location";
+}
+
+int32_t MirWindowManager::AddWindow(MirWindow* window) {
+  return windows_.Add(window);
+}
+
+void MirWindowManager::RemoveWindow(int32_t window_id, MirWindow* window) {
+  DCHECK_EQ(window, windows_.Lookup(window_id));
+  windows_.Remove(window_id);
+}
+
+base::FilePath MirWindowManager::base_path() const {
+  return location_;
+}
+
+scoped_ptr<SurfaceOzoneCanvas> MirWindowManager::CreateCanvasForWidget(
+    gfx::AcceleratedWidget widget) {
+  MirWindow* window = windows_.Lookup(widget);
+  DCHECK(window);
+  return make_scoped_ptr<SurfaceOzoneCanvas>(new FileSurface(window->path()));
+}
+
+bool MirWindowManager::LoadEGLGLES2Bindings(
+    AddGLLibraryCallback add_gl_library,
+    SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
+  return false;
+}
+
+}  // namespace ui
--- /dev/null
+++ b/ui/ozone/platform/mir/mir_window_manager.h
@@ -0,0 +1,51 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_MIR_FILE_SURFACE_FACTORY_H_
+#define UI_OZONE_PLATFORM_MIR_FILE_SURFACE_FACTORY_H_
+
+#include "base/files/file_path.h"
+#include "base/id_map.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/ozone/platform/mir/mir_window.h"
+#include "ui/ozone/public/surface_factory_ozone.h"
+
+namespace ui {
+
+class MirWindowManager : public SurfaceFactoryOzone {
+ public:
+  explicit MirWindowManager(const base::FilePath& dump_location);
+  virtual ~MirWindowManager();
+
+  // Initialize (mainly check that we have a place to write output to).
+  void Initialize();
+
+  // Register a new window. Returns the window id.
+  int32_t AddWindow(MirWindow* window);
+
+  // Remove a window.
+  void RemoveWindow(int32_t window_id, MirWindow* window);
+
+  // User-supplied path for images.
+  base::FilePath base_path() const;
+
+  // SurfaceFactoryOzone:
+  virtual scoped_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget(
+      gfx::AcceleratedWidget w) OVERRIDE;
+  virtual bool LoadEGLGLES2Bindings(
+      AddGLLibraryCallback add_gl_library,
+      SetGLGetProcAddressProcCallback set_gl_get_proc_address) OVERRIDE;
+
+ private:
+  base::FilePath location_;
+
+  IDMap<MirWindow> windows_;
+
+  DISALLOW_COPY_AND_ASSIGN(MirWindowManager);
+};
+
+}  // namespace ui
+
+#endif  // UI_OZONE_PLATFORM_MIR_FILE_SURFACE_FACTORY_H_
--- /dev/null
+++ b/ui/ozone/platform/mir/ozone_platform_mir.cc
@@ -0,0 +1,98 @@
+// Copyright 2013 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 "ui/ozone/platform/mir/ozone_platform_mir.h"
+
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
+#include "ui/events/platform/platform_event_source.h"
+#include "ui/ozone/platform/mir/mir_window.h"
+#include "ui/ozone/platform/mir/mir_window_manager.h"
+#include "ui/ozone/public/cursor_factory_ozone.h"
+#include "ui/ozone/public/gpu_platform_support.h"
+#include "ui/ozone/public/gpu_platform_support_host.h"
+#include "ui/ozone/public/ozone_platform.h"
+#include "ui/ozone/public/ozone_switches.h"
+
+#if defined(OS_CHROMEOS)
+#include "ui/ozone/common/chromeos/native_display_delegate_ozone.h"
+#endif
+
+namespace ui {
+
+namespace {
+
+// OzonePlatform for testing
+//
+// This platform dumps images to a file for testing purposes.
+class OzonePlatformMir : public OzonePlatform {
+ public:
+  OzonePlatformMir(const base::FilePath& dump_file) : file_path_(dump_file) {}
+  virtual ~OzonePlatformMir() {}
+
+  // OzonePlatform:
+  virtual ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() OVERRIDE {
+    return window_manager_.get();
+  }
+  virtual CursorFactoryOzone* GetCursorFactoryOzone() OVERRIDE {
+    return cursor_factory_ozone_.get();
+  }
+  virtual GpuPlatformSupport* GetGpuPlatformSupport() OVERRIDE {
+    return gpu_platform_support_.get();
+  }
+  virtual GpuPlatformSupportHost* GetGpuPlatformSupportHost() OVERRIDE {
+    return gpu_platform_support_host_.get();
+  }
+  virtual scoped_ptr<PlatformWindow> CreatePlatformWindow(
+      PlatformWindowDelegate* delegate,
+      const gfx::Rect& bounds) OVERRIDE {
+    return make_scoped_ptr<PlatformWindow>(
+        new MirWindow(delegate, window_manager_.get(), bounds));
+  }
+
+#if defined(OS_CHROMEOS)
+  virtual scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate()
+      OVERRIDE {
+    return scoped_ptr<NativeDisplayDelegate>(new NativeDisplayDelegateOzone());
+  }
+#endif
+
+  virtual void InitializeUI() OVERRIDE {
+    window_manager_.reset(new MirWindowManager(file_path_));
+    window_manager_->Initialize();
+    // This unbreaks tests that create their own.
+    if (!PlatformEventSource::GetInstance())
+      platform_event_source_ = PlatformEventSource::CreateDefault();
+
+    cursor_factory_ozone_.reset(new BitmapCursorFactoryOzone);
+    gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost());
+  }
+
+  virtual void InitializeGPU() OVERRIDE {
+    gpu_platform_support_.reset(CreateStubGpuPlatformSupport());
+  }
+
+ private:
+  scoped_ptr<MirWindowManager> window_manager_;
+  scoped_ptr<PlatformEventSource> platform_event_source_;
+  scoped_ptr<CursorFactoryOzone> cursor_factory_ozone_;
+  scoped_ptr<GpuPlatformSupport> gpu_platform_support_;
+  scoped_ptr<GpuPlatformSupportHost> gpu_platform_support_host_;
+  base::FilePath file_path_;
+
+  DISALLOW_COPY_AND_ASSIGN(OzonePlatformMir);
+};
+
+}  // namespace
+
+OzonePlatform* CreateOzonePlatformMir() {
+  CommandLine* cmd = CommandLine::ForCurrentProcess();
+  base::FilePath location;
+  if (cmd->HasSwitch(switches::kOzoneDumpFile))
+    location = cmd->GetSwitchValuePath(switches::kOzoneDumpFile);
+  return new OzonePlatformMir(location);
+}
+
+}  // namespace ui
--- /dev/null
+++ b/ui/ozone/platform/mir/ozone_platform_mir.h
@@ -0,0 +1,17 @@
+// Copyright 2013 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 UI_OZONE_PLATFORM_MIR_OZONE_PLATFORM_MIR_H_
+#define UI_OZONE_PLATFORM_MIR_OZONE_PLATFORM_MIR_H_
+
+namespace ui {
+
+class OzonePlatform;
+
+// Constructor hook for use in ozone_platform_list.cc
+OzonePlatform* CreateOzonePlatformMir();
+
+}  // namespace ui
+
+#endif  // UI_OZONE_PLATFORM_MIR_OZONE_PLATFORM_MIR_H_
