Clone of chromium aad1ce808763f59c7a3753e08f1500a104ecc6fd refs/remotes/origin/HEAD
diff --git a/mojo/services/native_viewport/BUILD.gn b/mojo/services/native_viewport/BUILD.gn
new file mode 100644
index 0000000..036e8e9
--- /dev/null
+++ b/mojo/services/native_viewport/BUILD.gn
@@ -0,0 +1,84 @@
+# 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.
+
+import("//build/config/ui.gni")
+
+if (!is_android) {
+ shared_library("native_viewport") {
+ output_name = "mojo_native_viewport_service"
+
+ deps = [
+ ":lib",
+ "//base",
+ "//mojo/application",
+ "//mojo/public/c/system:for_shared_library",
+ "//mojo/public/cpp/bindings:bindings",
+ "//mojo/services/public/interfaces/native_viewport",
+ "//ui/gl",
+ ]
+
+ sources = [ "main.cc" ]
+ }
+}
+
+source_set("lib") {
+ deps = [
+ "//base",
+ "//cc/surfaces",
+ "//gpu/command_buffer/service",
+ "//mojo/application",
+ "//mojo/common",
+ "//mojo/environment:chromium",
+ "//mojo/services/gles2",
+ "//mojo/services/gles2:interfaces",
+ "//mojo/services/public/cpp/geometry",
+ "//mojo/services/public/cpp/input_events",
+ "//mojo/services/public/cpp/surfaces",
+ "//mojo/services/public/interfaces/geometry",
+ "//mojo/services/public/interfaces/native_viewport",
+ "//mojo/services/public/interfaces/surfaces",
+ "//ui/events",
+ "//ui/events/platform",
+ "//ui/gfx",
+ "//ui/gfx/geometry",
+ "//ui/gl",
+ "//ui/platform_window",
+ ]
+
+ sources = [
+ "gpu_impl.cc",
+ "gpu_impl.h",
+ "native_viewport_impl.cc",
+ "native_viewport_impl.h",
+ "platform_viewport.h",
+ "platform_viewport_android.cc",
+ "platform_viewport_android.h",
+ "platform_viewport_mac.mm",
+ "platform_viewport_headless.cc",
+ "platform_viewport_headless.h",
+ "platform_viewport_win.cc",
+ "viewport_surface.cc",
+ "viewport_surface.h",
+ ]
+
+ if (is_ios) {
+ sources += [ "platform_viewport_stub.cc" ]
+ }
+
+ if (is_android) {
+ deps += [ "//mojo:jni_headers" ]
+ }
+
+ if (use_x11) {
+ sources += [ "platform_viewport_x11.cc" ]
+ deps += [
+ "//ui/events/platform/x11",
+ "//ui/platform_window/x11",
+ ]
+ }
+
+ if (use_ozone) {
+ sources += [ "platform_viewport_ozone.cc" ]
+ }
+}
diff --git a/mojo/services/native_viewport/DEPS b/mojo/services/native_viewport/DEPS
new file mode 100644
index 0000000..abf7ef8
--- /dev/null
+++ b/mojo/services/native_viewport/DEPS
@@ -0,0 +1,18 @@
+include_rules = [
+ "+cc/surfaces",
+ "+gpu/command_buffer/service/mailbox_manager.h",
+ "+mojo/application",
+ "+mojo/services/public/cpp/geometry",
+ "+mojo/services/public/cpp/input_events",
+ "+mojo/services/public/cpp/surfaces",
+ "+mojo/services/public/interfaces/gpu",
+ "+mojo/services/public/interfaces/native_viewport",
+ "+mojo/services/public/interfaces/geometry",
+ "+mojo/services/public/interfaces/surfaces",
+ "+mojo/services/gles2",
+ "+ui/events",
+ "+ui/gfx",
+ "+ui/gl",
+ "+ui/ozone/public",
+ "+ui/platform_window",
+]
diff --git a/mojo/services/native_viewport/android/src/org/chromium/mojo/PlatformViewportAndroid.java b/mojo/services/native_viewport/android/src/org/chromium/mojo/PlatformViewportAndroid.java
new file mode 100644
index 0000000..c3f8075
--- /dev/null
+++ b/mojo/services/native_viewport/android/src/org/chromium/mojo/PlatformViewportAndroid.java
@@ -0,0 +1,91 @@
+// 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.
+
+package org.chromium.mojo;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+
+/**
+ * Exposes SurfaceView to native code.
+ */
+@JNINamespace("mojo")
+public class PlatformViewportAndroid extends SurfaceView {
+
+ private long mNativeMojoViewport;
+ private final SurfaceHolder.Callback mSurfaceCallback;
+
+ @SuppressWarnings("unused")
+ @CalledByNative
+ public static void createForActivity(Activity activity, long nativeViewport) {
+ activity.setContentView(new PlatformViewportAndroid(activity, nativeViewport));
+ }
+
+ public PlatformViewportAndroid(Context context, long nativeViewport) {
+ super(context);
+
+ mNativeMojoViewport = nativeViewport;
+ assert mNativeMojoViewport != 0;
+
+ mSurfaceCallback = new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ assert mNativeMojoViewport != 0;
+ nativeSurfaceSetSize(mNativeMojoViewport, width, height);
+ }
+
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ assert mNativeMojoViewport != 0;
+ nativeSurfaceCreated(mNativeMojoViewport, holder.getSurface());
+ }
+
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ assert mNativeMojoViewport != 0;
+ nativeSurfaceDestroyed(mNativeMojoViewport);
+ }
+ };
+ getHolder().addCallback(mSurfaceCallback);
+
+ }
+
+ // TODO(abarth): Someone needs to call destroy at some point.
+ public void destroy() {
+ getHolder().removeCallback(mSurfaceCallback);
+ nativeDestroy(mNativeMojoViewport);
+ mNativeMojoViewport = 0;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ return nativeTouchEvent(mNativeMojoViewport,
+ event.getPointerId(0),
+ event.getAction(),
+ event.getX(), event.getY(),
+ event.getEventTime());
+ }
+
+ private static native void nativeDestroy(long nativePlatformViewportAndroid);
+ private static native void nativeSurfaceCreated(
+ long nativePlatformViewportAndroid, Surface surface);
+ private static native void nativeSurfaceDestroyed(
+ long nativePlatformViewportAndroid);
+ private static native void nativeSurfaceSetSize(
+ long nativePlatformViewportAndroid,
+ int width, int height);
+ private static native boolean nativeTouchEvent(
+ long nativePlatformViewportAndroid,
+ int pointerId,
+ int action,
+ float x, float y,
+ long timeMs);
+};
diff --git a/mojo/services/native_viewport/gpu_impl.cc b/mojo/services/native_viewport/gpu_impl.cc
new file mode 100644
index 0000000..de0b69e
--- /dev/null
+++ b/mojo/services/native_viewport/gpu_impl.cc
@@ -0,0 +1,43 @@
+// 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 "mojo/services/native_viewport/gpu_impl.h"
+
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "mojo/services/gles2/command_buffer_impl.h"
+#include "mojo/services/public/cpp/geometry/geometry_type_converters.h"
+#include "ui/gl/gl_share_group.h"
+
+namespace mojo {
+
+GpuImpl::GpuImpl(
+ const scoped_refptr<gfx::GLShareGroup>& share_group,
+ const scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager)
+ : share_group_(share_group), mailbox_manager_(mailbox_manager) {
+}
+
+GpuImpl::~GpuImpl() {
+}
+
+void GpuImpl::CreateOnscreenGLES2Context(
+ uint64_t native_viewport_id,
+ SizePtr size,
+ InterfaceRequest<CommandBuffer> command_buffer_request) {
+ gfx::AcceleratedWidget widget = bit_cast<gfx::AcceleratedWidget>(
+ static_cast<uintptr_t>(native_viewport_id));
+ BindToRequest(new CommandBufferImpl(widget,
+ size.To<gfx::Size>(),
+ share_group_.get(),
+ mailbox_manager_.get()),
+ &command_buffer_request);
+}
+
+void GpuImpl::CreateOffscreenGLES2Context(
+ InterfaceRequest<CommandBuffer> command_buffer_request) {
+ BindToRequest(
+ new CommandBufferImpl(share_group_.get(), mailbox_manager_.get()),
+ &command_buffer_request);
+}
+
+} // namespace mojo
diff --git a/mojo/services/native_viewport/gpu_impl.h b/mojo/services/native_viewport/gpu_impl.h
new file mode 100644
index 0000000..ac0f435
--- /dev/null
+++ b/mojo/services/native_viewport/gpu_impl.h
@@ -0,0 +1,49 @@
+// 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 "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "mojo/public/cpp/bindings/interface_impl.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/services/gles2/command_buffer.mojom.h"
+#include "mojo/services/public/interfaces/geometry/geometry.mojom.h"
+#include "mojo/services/public/interfaces/gpu/gpu.mojom.h"
+
+namespace gfx {
+class GLShareGroup;
+}
+
+namespace gpu {
+namespace gles2 {
+class MailboxManager;
+}
+}
+
+namespace mojo {
+
+class GpuImpl : public InterfaceImpl<Gpu> {
+ public:
+ GpuImpl(const scoped_refptr<gfx::GLShareGroup>& share_group,
+ const scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager);
+
+ virtual ~GpuImpl();
+
+ virtual void CreateOnscreenGLES2Context(
+ uint64_t native_viewport_id,
+ SizePtr size,
+ InterfaceRequest<CommandBuffer> command_buffer_request) override;
+
+ virtual void CreateOffscreenGLES2Context(
+ InterfaceRequest<CommandBuffer> command_buffer_request) override;
+
+ private:
+ // We need to share these across all NativeViewport instances so that contexts
+ // they create can share resources with each other via mailboxes.
+ scoped_refptr<gfx::GLShareGroup> share_group_;
+ scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(GpuImpl);
+};
+
+} // namespace mojo
diff --git a/mojo/services/native_viewport/main.cc b/mojo/services/native_viewport/main.cc
new file mode 100644
index 0000000..0185e67
--- /dev/null
+++ b/mojo/services/native_viewport/main.cc
@@ -0,0 +1,111 @@
+// 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 "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "mojo/application/application_runner_chromium.h"
+#include "mojo/public/c/system/main.h"
+#include "mojo/public/cpp/application/application_connection.h"
+#include "mojo/public/cpp/application/application_delegate.h"
+#include "mojo/public/cpp/application/interface_factory_impl.h"
+#include "mojo/services/native_viewport/gpu_impl.h"
+#include "mojo/services/native_viewport/native_viewport_impl.h"
+#include "ui/gl/gl_share_group.h"
+#include "ui/gl/gl_surface.h"
+
+namespace mojo {
+
+class NativeViewportAppDelegate
+ : public ApplicationDelegate,
+ public InterfaceFactory<NativeViewport>,
+ public InterfaceFactory<Gpu>,
+ public InterfaceFactory<NativeViewportConfig> {
+ public:
+ NativeViewportAppDelegate()
+ : share_group_(new gfx::GLShareGroup),
+ mailbox_manager_(new gpu::gles2::MailboxManager),
+ is_test_(false),
+ is_headless_(false),
+ is_initialized_(false) {}
+ virtual ~NativeViewportAppDelegate() {}
+
+ private:
+ class NativeViewportConfigImpl : public InterfaceImpl<NativeViewportConfig> {
+ public:
+ NativeViewportConfigImpl(NativeViewportAppDelegate* app_delegate)
+ : app_delegate_(app_delegate) {}
+
+ virtual void UseTestConfig(
+ const Callback<void()>& callback) override {
+ app_delegate_->is_test_ = true;
+ callback.Run();
+ }
+
+ virtual void UseHeadlessConfig(
+ const Callback<void()>& callback) override {
+ app_delegate_->is_headless_ = true;
+ callback.Run();
+ }
+
+ private:
+ NativeViewportAppDelegate* app_delegate_;
+ };
+
+ // ApplicationDelegate implementation.
+ virtual void Initialize(ApplicationImpl* application) override {
+ app_ = application;
+ }
+
+ virtual bool ConfigureIncomingConnection(
+ mojo::ApplicationConnection* connection) override {
+ connection->AddService<NativeViewport>(this);
+ connection->AddService<Gpu>(this);
+ connection->AddService<NativeViewportConfig>(this);
+ return true;
+ }
+
+ // InterfaceFactory<NativeViewport> implementation.
+ virtual void Create(ApplicationConnection* connection,
+ InterfaceRequest<NativeViewport> request) override {
+#if !defined(COMPONENT_BUILD)
+ if (!is_initialized_) {
+ if (is_test_)
+ gfx::GLSurface::InitializeOneOffForTests();
+ else
+ gfx::GLSurface::InitializeOneOff();
+ is_initialized_ = true;
+ }
+#endif
+ BindToRequest(new NativeViewportImpl(app_, is_headless_), &request);
+ }
+
+ // InterfaceFactory<Gpu> implementation.
+ virtual void Create(ApplicationConnection* connection,
+ InterfaceRequest<Gpu> request) override {
+ BindToRequest(new GpuImpl(share_group_.get(), mailbox_manager_.get()),
+ &request);
+ }
+
+ // InterfaceFactory<NVTestConfig> implementation.
+ virtual void Create(ApplicationConnection* connection,
+ InterfaceRequest<NativeViewportConfig> request) override {
+ BindToRequest(new NativeViewportConfigImpl(this), &request);
+ }
+
+ ApplicationImpl* app_;
+ scoped_refptr<gfx::GLShareGroup> share_group_;
+ scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager_;
+ bool is_test_;
+ bool is_headless_;
+ bool is_initialized_;
+ DISALLOW_COPY_AND_ASSIGN(NativeViewportAppDelegate);
+};
+}
+
+MojoResult MojoMain(MojoHandle shell_handle) {
+ mojo::ApplicationRunnerChromium runner(new mojo::NativeViewportAppDelegate);
+ runner.set_message_loop_type(base::MessageLoop::TYPE_UI);
+ return runner.Run(shell_handle);
+}
diff --git a/mojo/services/native_viewport/native_viewport_impl.cc b/mojo/services/native_viewport/native_viewport_impl.cc
new file mode 100644
index 0000000..3006612
--- /dev/null
+++ b/mojo/services/native_viewport/native_viewport_impl.cc
@@ -0,0 +1,160 @@
+// 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 "mojo/services/native_viewport/native_viewport_impl.h"
+
+#include "base/auto_reset.h"
+#include "base/bind.h"
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/time/time.h"
+#include "mojo/public/cpp/application/application_delegate.h"
+#include "mojo/public/cpp/application/application_impl.h"
+#include "mojo/public/cpp/application/interface_factory.h"
+#include "mojo/services/native_viewport/platform_viewport_headless.h"
+#include "mojo/services/native_viewport/viewport_surface.h"
+#include "mojo/services/public/cpp/geometry/geometry_type_converters.h"
+#include "mojo/services/public/cpp/input_events/input_events_type_converters.h"
+#include "mojo/services/public/cpp/surfaces/surfaces_type_converters.h"
+#include "ui/events/event.h"
+
+namespace mojo {
+namespace {
+
+bool IsRateLimitedEventType(ui::Event* event) {
+ return event->type() == ui::ET_MOUSE_MOVED ||
+ event->type() == ui::ET_MOUSE_DRAGGED ||
+ event->type() == ui::ET_TOUCH_MOVED;
+}
+
+} // namespace
+
+NativeViewportImpl::NativeViewportImpl(ApplicationImpl* app, bool is_headless)
+ : is_headless_(is_headless),
+ widget_id_(0u),
+ waiting_for_event_ack_(false),
+ weak_factory_(this) {
+ app->ConnectToService("mojo:mojo_surfaces_service", &surfaces_service_);
+ // TODO(jamesr): Should be mojo_gpu_service
+ app->ConnectToService("mojo:mojo_native_viewport_service", &gpu_service_);
+}
+
+NativeViewportImpl::~NativeViewportImpl() {
+ // Destroy the NativeViewport early on as it may call us back during
+ // destruction and we want to be in a known state.
+ platform_viewport_.reset();
+}
+
+void NativeViewportImpl::Create(SizePtr size,
+ const Callback<void(uint64_t)>& callback) {
+ create_callback_ = callback;
+ size_ = size.To<gfx::Size>();
+ if (is_headless_)
+ platform_viewport_ = PlatformViewportHeadless::Create(this);
+ else
+ platform_viewport_ = PlatformViewport::Create(this);
+ platform_viewport_->Init(gfx::Rect(size.To<gfx::Size>()));
+}
+
+void NativeViewportImpl::Show() {
+ platform_viewport_->Show();
+}
+
+void NativeViewportImpl::Hide() {
+ platform_viewport_->Hide();
+}
+
+void NativeViewportImpl::Close() {
+ DCHECK(platform_viewport_);
+ platform_viewport_->Close();
+}
+
+void NativeViewportImpl::SetSize(SizePtr size) {
+ platform_viewport_->SetBounds(gfx::Rect(size.To<gfx::Size>()));
+}
+
+void NativeViewportImpl::SubmittedFrame(SurfaceIdPtr child_surface_id) {
+ if (child_surface_id_.is_null()) {
+ // If this is the first indication that the client will use surfaces,
+ // initialize that system.
+ // TODO(jamesr): When everything is converted to surfaces initialize this
+ // eagerly.
+ viewport_surface_.reset(
+ new ViewportSurface(surfaces_service_.get(),
+ gpu_service_.get(),
+ size_,
+ child_surface_id.To<cc::SurfaceId>()));
+ if (widget_id_)
+ viewport_surface_->SetWidgetId(widget_id_);
+ }
+ child_surface_id_ = child_surface_id.To<cc::SurfaceId>();
+ if (viewport_surface_)
+ viewport_surface_->SetChildId(child_surface_id_);
+}
+
+void NativeViewportImpl::OnBoundsChanged(const gfx::Rect& bounds) {
+ if (size_ == bounds.size())
+ return;
+
+ size_ = bounds.size();
+
+ // Wait for the accelerated widget before telling the client of the bounds.
+ if (create_callback_.is_null())
+ ProcessOnBoundsChanged();
+}
+
+void NativeViewportImpl::OnAcceleratedWidgetAvailable(
+ gfx::AcceleratedWidget widget) {
+ widget_id_ = static_cast<uint64_t>(bit_cast<uintptr_t>(widget));
+ // TODO(jamesr): Remove once everything is converted to surfaces.
+ create_callback_.Run(widget_id_);
+ create_callback_.reset();
+ // Immediately tell the client of the size. The size may be wrong, if so we'll
+ // get the right one in the next OnBoundsChanged() call.
+ ProcessOnBoundsChanged();
+ if (viewport_surface_)
+ viewport_surface_->SetWidgetId(widget_id_);
+}
+
+bool NativeViewportImpl::OnEvent(ui::Event* ui_event) {
+ // Must not return early before updating capture.
+ switch (ui_event->type()) {
+ case ui::ET_MOUSE_PRESSED:
+ case ui::ET_TOUCH_PRESSED:
+ platform_viewport_->SetCapture();
+ break;
+ case ui::ET_MOUSE_RELEASED:
+ case ui::ET_TOUCH_RELEASED:
+ platform_viewport_->ReleaseCapture();
+ break;
+ default:
+ break;
+ }
+
+ if (waiting_for_event_ack_ && IsRateLimitedEventType(ui_event))
+ return false;
+
+ client()->OnEvent(
+ Event::From(*ui_event),
+ base::Bind(&NativeViewportImpl::AckEvent, weak_factory_.GetWeakPtr()));
+ waiting_for_event_ack_ = true;
+ return false;
+}
+
+void NativeViewportImpl::OnDestroyed() {
+ client()->OnDestroyed();
+}
+
+void NativeViewportImpl::AckEvent() {
+ waiting_for_event_ack_ = false;
+}
+
+void NativeViewportImpl::ProcessOnBoundsChanged() {
+ client()->OnSizeChanged(Size::From(size_));
+ if (viewport_surface_)
+ viewport_surface_->SetSize(size_);
+}
+
+} // namespace mojo
+
diff --git a/mojo/services/native_viewport/native_viewport_impl.h b/mojo/services/native_viewport/native_viewport_impl.h
new file mode 100644
index 0000000..03918cb
--- /dev/null
+++ b/mojo/services/native_viewport/native_viewport_impl.h
@@ -0,0 +1,69 @@
+// 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 MOJO_SERVICES_NATIVE_VIEWPORT_IMPL_H_
+#define MOJO_SERVICES_NATIVE_VIEWPORT_IMPL_H_
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "cc/surfaces/surface_id.h"
+#include "mojo/services/native_viewport/platform_viewport.h"
+#include "mojo/services/public/interfaces/gpu/gpu.mojom.h"
+#include "mojo/services/public/interfaces/native_viewport/native_viewport.mojom.h"
+#include "mojo/services/public/interfaces/surfaces/surfaces_service.mojom.h"
+#include "ui/gfx/geometry/rect.h"
+
+namespace ui {
+class Event;
+}
+
+namespace mojo {
+class ApplicationImpl;
+class ViewportSurface;
+
+class NativeViewportImpl : public InterfaceImpl<NativeViewport>,
+ public PlatformViewport::Delegate {
+ public:
+ NativeViewportImpl(ApplicationImpl* app, bool is_headless);
+ virtual ~NativeViewportImpl();
+
+ // InterfaceImpl<NativeViewport> implementation.
+ virtual void Create(SizePtr size,
+ const Callback<void(uint64_t)>& callback) override;
+ virtual void Show() override;
+ virtual void Hide() override;
+ virtual void Close() override;
+ virtual void SetSize(SizePtr size) override;
+ virtual void SubmittedFrame(SurfaceIdPtr surface_id) override;
+
+ // PlatformViewport::Delegate implementation.
+ virtual void OnBoundsChanged(const gfx::Rect& bounds) override;
+ virtual void OnAcceleratedWidgetAvailable(
+ gfx::AcceleratedWidget widget) override;
+ virtual bool OnEvent(ui::Event* ui_event) override;
+ virtual void OnDestroyed() override;
+
+ void AckEvent();
+
+ private:
+ void ProcessOnBoundsChanged();
+
+ bool is_headless_;
+ scoped_ptr<PlatformViewport> platform_viewport_;
+ scoped_ptr<ViewportSurface> viewport_surface_;
+ uint64_t widget_id_;
+ gfx::Size size_;
+ GpuPtr gpu_service_;
+ SurfacesServicePtr surfaces_service_;
+ cc::SurfaceId child_surface_id_;
+ bool waiting_for_event_ack_;
+ Callback<void(uint64_t)> create_callback_;
+ base::WeakPtrFactory<NativeViewportImpl> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeViewportImpl);
+};
+
+} // namespace mojo
+
+#endif // MOJO_SERVICES_NATIVE_VIEWPORT_IMPL_H_
diff --git a/mojo/services/native_viewport/platform_viewport.h b/mojo/services/native_viewport/platform_viewport.h
new file mode 100644
index 0000000..a3ba3dc
--- /dev/null
+++ b/mojo/services/native_viewport/platform_viewport.h
@@ -0,0 +1,53 @@
+// 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 MOJO_SERVICES_NATIVE_VIEWPORT_PLATFORM_VIEWPORT_H_
+#define MOJO_SERVICES_NATIVE_VIEWPORT_PLATFORM_VIEWPORT_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/size.h"
+
+namespace gfx {
+class Rect;
+}
+
+namespace ui {
+class Event;
+}
+
+namespace mojo {
+
+// Encapsulation of platform-specific Viewport.
+class PlatformViewport {
+ public:
+ class Delegate {
+ public:
+ virtual ~Delegate() {}
+
+ virtual void OnBoundsChanged(const gfx::Rect& rect) = 0;
+ virtual void OnAcceleratedWidgetAvailable(
+ gfx::AcceleratedWidget widget) = 0;
+ virtual bool OnEvent(ui::Event* ui_event) = 0;
+ virtual void OnDestroyed() = 0;
+ };
+
+ virtual ~PlatformViewport() {}
+
+ virtual void Init(const gfx::Rect& bounds) = 0;
+ virtual void Show() = 0;
+ virtual void Hide() = 0;
+ virtual void Close() = 0;
+ virtual gfx::Size GetSize() = 0;
+ virtual void SetBounds(const gfx::Rect& bounds) = 0;
+
+ virtual void SetCapture() = 0;
+ virtual void ReleaseCapture() = 0;
+
+ static scoped_ptr<PlatformViewport> Create(Delegate* delegate);
+};
+
+} // namespace mojo
+
+#endif // MOJO_SERVICES_NATIVE_VIEWPORT_PLATFORM_VIEWPORT_H_
diff --git a/mojo/services/native_viewport/platform_viewport_android.cc b/mojo/services/native_viewport/platform_viewport_android.cc
new file mode 100644
index 0000000..bbe22c9
--- /dev/null
+++ b/mojo/services/native_viewport/platform_viewport_android.cc
@@ -0,0 +1,156 @@
+// 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 "mojo/services/native_viewport/platform_viewport_android.h"
+
+#include <android/input.h>
+#include <android/native_window_jni.h>
+
+#include "base/android/jni_android.h"
+#include "jni/PlatformViewportAndroid_jni.h"
+#include "ui/events/event.h"
+#include "ui/gfx/point.h"
+
+namespace mojo {
+
+ui::EventType MotionEventActionToEventType(jint action) {
+ switch (action) {
+ case AMOTION_EVENT_ACTION_DOWN:
+ return ui::ET_TOUCH_PRESSED;
+ case AMOTION_EVENT_ACTION_MOVE:
+ return ui::ET_TOUCH_MOVED;
+ case AMOTION_EVENT_ACTION_UP:
+ return ui::ET_TOUCH_RELEASED;
+ default:
+ NOTREACHED();
+ }
+ return ui::ET_UNKNOWN;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// PlatformViewportAndroid, public:
+
+// static
+bool PlatformViewportAndroid::Register(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+PlatformViewportAndroid::PlatformViewportAndroid(Delegate* delegate)
+ : delegate_(delegate),
+ window_(NULL),
+ id_generator_(0),
+ weak_factory_(this) {
+}
+
+PlatformViewportAndroid::~PlatformViewportAndroid() {
+ if (window_)
+ ReleaseWindow();
+}
+
+void PlatformViewportAndroid::Destroy(JNIEnv* env, jobject obj) {
+ delegate_->OnDestroyed();
+}
+
+void PlatformViewportAndroid::SurfaceCreated(JNIEnv* env,
+ jobject obj,
+ jobject jsurface) {
+ base::android::ScopedJavaLocalRef<jobject> protector(env, jsurface);
+ // Note: This ensures that any local references used by
+ // ANativeWindow_fromSurface are released immediately. This is needed as a
+ // workaround for https://code.google.com/p/android/issues/detail?id=68174
+ {
+ base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env);
+ window_ = ANativeWindow_fromSurface(env, jsurface);
+ }
+ delegate_->OnAcceleratedWidgetAvailable(window_);
+}
+
+void PlatformViewportAndroid::SurfaceDestroyed(JNIEnv* env, jobject obj) {
+ DCHECK(window_);
+ ReleaseWindow();
+}
+
+void PlatformViewportAndroid::SurfaceSetSize(JNIEnv* env, jobject obj,
+ jint width, jint height) {
+ bounds_ = gfx::Rect(width, height);
+ delegate_->OnBoundsChanged(bounds_);
+}
+
+bool PlatformViewportAndroid::TouchEvent(JNIEnv* env, jobject obj,
+ jint pointer_id,
+ jint action,
+ jfloat x, jfloat y,
+ jlong time_ms) {
+ gfx::Point location(static_cast<int>(x), static_cast<int>(y));
+ ui::TouchEvent event(MotionEventActionToEventType(action), location,
+ id_generator_.GetGeneratedID(pointer_id),
+ base::TimeDelta::FromMilliseconds(time_ms));
+ // TODO(beng): handle multiple touch-points.
+ delegate_->OnEvent(&event);
+ if (action == ui::ET_TOUCH_RELEASED)
+ id_generator_.ReleaseNumber(pointer_id);
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// PlatformViewportAndroid, PlatformViewport implementation:
+
+void PlatformViewportAndroid::Init(const gfx::Rect& bounds) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_PlatformViewportAndroid_createForActivity(
+ env,
+ base::android::GetApplicationContext(),
+ reinterpret_cast<jlong>(this));
+}
+
+void PlatformViewportAndroid::Show() {
+ // Nothing to do. View is created visible.
+}
+
+void PlatformViewportAndroid::Hide() {
+ // Nothing to do. View is always visible.
+}
+
+void PlatformViewportAndroid::Close() {
+ // TODO(beng): close activity containing MojoView?
+
+ // TODO(beng): perform this in response to view destruction.
+ delegate_->OnDestroyed();
+}
+
+gfx::Size PlatformViewportAndroid::GetSize() {
+ return bounds_.size();
+}
+
+void PlatformViewportAndroid::SetBounds(const gfx::Rect& bounds) {
+ NOTIMPLEMENTED();
+}
+
+void PlatformViewportAndroid::SetCapture() {
+ NOTIMPLEMENTED();
+}
+
+void PlatformViewportAndroid::ReleaseCapture() {
+ NOTIMPLEMENTED();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// PlatformViewportAndroid, private:
+
+void PlatformViewportAndroid::ReleaseWindow() {
+ ANativeWindow_release(window_);
+ window_ = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// PlatformViewport, public:
+
+// static
+scoped_ptr<PlatformViewport> PlatformViewport::Create(Delegate* delegate) {
+ return scoped_ptr<PlatformViewport>(
+ new PlatformViewportAndroid(delegate)).Pass();
+}
+
+} // namespace mojo
diff --git a/mojo/services/native_viewport/platform_viewport_android.h b/mojo/services/native_viewport/platform_viewport_android.h
new file mode 100644
index 0000000..31b0312
--- /dev/null
+++ b/mojo/services/native_viewport/platform_viewport_android.h
@@ -0,0 +1,66 @@
+// 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 MOJO_SERVICES_NATIVE_VIEWPORT_PLATFORM_VIEWPORT_ANDROID_H_
+#define MOJO_SERVICES_NATIVE_VIEWPORT_PLATFORM_VIEWPORT_ANDROID_H_
+
+#include "base/android/jni_weak_ref.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "mojo/services/native_viewport/platform_viewport.h"
+#include "ui/events/event_constants.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/sequential_id_generator.h"
+#include "ui/gfx/size.h"
+
+namespace gpu {
+class GLInProcessContext;
+}
+
+struct ANativeWindow;
+
+namespace mojo {
+
+class PlatformViewportAndroid : public PlatformViewport {
+ public:
+ static bool Register(JNIEnv* env);
+
+ explicit PlatformViewportAndroid(Delegate* delegate);
+ virtual ~PlatformViewportAndroid();
+
+ void Destroy(JNIEnv* env, jobject obj);
+ void SurfaceCreated(JNIEnv* env, jobject obj, jobject jsurface);
+ void SurfaceDestroyed(JNIEnv* env, jobject obj);
+ void SurfaceSetSize(JNIEnv* env, jobject obj, jint width, jint height);
+ bool TouchEvent(JNIEnv* env, jobject obj, jint pointer_id, jint action,
+ jfloat x, jfloat y, jlong time_ms);
+
+ private:
+ // Overridden from PlatformViewport:
+ virtual void Init(const gfx::Rect& bounds) override;
+ virtual void Show() override;
+ virtual void Hide() override;
+ virtual void Close() override;
+ virtual gfx::Size GetSize() override;
+ virtual void SetBounds(const gfx::Rect& bounds) override;
+ virtual void SetCapture() override;
+ virtual void ReleaseCapture() override;
+
+ void ReleaseWindow();
+
+ Delegate* delegate_;
+ ANativeWindow* window_;
+ gfx::Rect bounds_;
+ ui::SequentialIDGenerator id_generator_;
+
+ base::WeakPtrFactory<PlatformViewportAndroid> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(PlatformViewportAndroid);
+};
+
+
+} // namespace mojo
+
+#endif // MOJO_SERVICES_NATIVE_VIEWPORT_PLATFORM_VIEWPORT_ANDROID_H_
diff --git a/mojo/services/native_viewport/platform_viewport_headless.cc b/mojo/services/native_viewport/platform_viewport_headless.cc
new file mode 100644
index 0000000..1c34711
--- /dev/null
+++ b/mojo/services/native_viewport/platform_viewport_headless.cc
@@ -0,0 +1,52 @@
+// 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 "mojo/services/native_viewport/platform_viewport_headless.h"
+
+namespace mojo {
+
+PlatformViewportHeadless::PlatformViewportHeadless(Delegate* delegate)
+ : delegate_(delegate) {
+}
+
+PlatformViewportHeadless::~PlatformViewportHeadless() {
+}
+
+void PlatformViewportHeadless::Init(const gfx::Rect& bounds) {
+ bounds_ = bounds;
+}
+
+void PlatformViewportHeadless::Show() {
+}
+
+void PlatformViewportHeadless::Hide() {
+}
+
+void PlatformViewportHeadless::Close() {
+ delegate_->OnDestroyed();
+}
+
+gfx::Size PlatformViewportHeadless::GetSize() {
+ return bounds_.size();
+}
+
+void PlatformViewportHeadless::SetBounds(const gfx::Rect& bounds) {
+ bounds_ = bounds;
+ delegate_->OnBoundsChanged(bounds_);
+}
+
+void PlatformViewportHeadless::SetCapture() {
+}
+
+void PlatformViewportHeadless::ReleaseCapture() {
+}
+
+// static
+scoped_ptr<PlatformViewport> PlatformViewportHeadless::Create(
+ Delegate* delegate) {
+ return scoped_ptr<PlatformViewport>(
+ new PlatformViewportHeadless(delegate)).Pass();
+}
+
+} // namespace mojo
diff --git a/mojo/services/native_viewport/platform_viewport_headless.h b/mojo/services/native_viewport/platform_viewport_headless.h
new file mode 100644
index 0000000..9b9743f
--- /dev/null
+++ b/mojo/services/native_viewport/platform_viewport_headless.h
@@ -0,0 +1,36 @@
+// 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 "base/macros.h"
+#include "mojo/services/native_viewport/platform_viewport.h"
+#include "ui/gfx/rect.h"
+
+namespace mojo {
+
+class PlatformViewportHeadless : public PlatformViewport {
+ public:
+ virtual ~PlatformViewportHeadless();
+
+ static scoped_ptr<PlatformViewport> Create(Delegate* delegate);
+
+ private:
+ explicit PlatformViewportHeadless(Delegate* delegate);
+
+ // Overridden from PlatformViewport:
+ virtual void Init(const gfx::Rect& bounds) override;
+ virtual void Show() override;
+ virtual void Hide() override;
+ virtual void Close() override;
+ virtual gfx::Size GetSize() override;
+ virtual void SetBounds(const gfx::Rect& bounds) override;
+ virtual void SetCapture() override;
+ virtual void ReleaseCapture() override;
+
+ Delegate* delegate_;
+ gfx::Rect bounds_;
+
+ DISALLOW_COPY_AND_ASSIGN(PlatformViewportHeadless);
+};
+
+} // namespace mojo
diff --git a/mojo/services/native_viewport/platform_viewport_mac.mm b/mojo/services/native_viewport/platform_viewport_mac.mm
new file mode 100644
index 0000000..9d11052
--- /dev/null
+++ b/mojo/services/native_viewport/platform_viewport_mac.mm
@@ -0,0 +1,84 @@
+// 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 "mojo/services/native_viewport/platform_viewport.h"
+
+#import <AppKit/NSApplication.h>
+#import <AppKit/NSView.h>
+#import <AppKit/NSWindow.h>
+
+#include "base/bind.h"
+#include "ui/gfx/rect.h"
+
+namespace mojo {
+
+class PlatformViewportMac : public PlatformViewport {
+ public:
+ PlatformViewportMac(Delegate* delegate)
+ : delegate_(delegate),
+ window_(nil) {
+ }
+
+ virtual ~PlatformViewportMac() {
+ [window_ orderOut:nil];
+ [window_ close];
+ }
+
+ private:
+ // Overridden from PlatformViewport:
+ virtual void Init(const gfx::Rect& bounds) OVERRIDE {
+ [NSApplication sharedApplication];
+
+ rect_ = bounds;
+ window_ = [[NSWindow alloc]
+ initWithContentRect:NSRectFromCGRect(rect_.ToCGRect())
+ styleMask:NSTitledWindowMask
+ backing:NSBackingStoreBuffered
+ defer:NO];
+ delegate_->OnAcceleratedWidgetAvailable([window_ contentView]);
+ delegate_->OnBoundsChanged(rect_);
+ }
+
+ virtual void Show() OVERRIDE {
+ [window_ orderFront:nil];
+ }
+
+ virtual void Hide() OVERRIDE {
+ [window_ orderOut:nil];
+ }
+
+ virtual void Close() OVERRIDE {
+ // TODO(beng): perform this in response to NSWindow destruction.
+ delegate_->OnDestroyed();
+ }
+
+ virtual gfx::Size GetSize() OVERRIDE {
+ return rect_.size();
+ }
+
+ virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE {
+ NOTIMPLEMENTED();
+ }
+
+ virtual void SetCapture() OVERRIDE {
+ NOTIMPLEMENTED();
+ }
+
+ virtual void ReleaseCapture() OVERRIDE {
+ NOTIMPLEMENTED();
+ }
+
+ Delegate* delegate_;
+ NSWindow* window_;
+ gfx::Rect rect_;
+
+ DISALLOW_COPY_AND_ASSIGN(PlatformViewportMac);
+};
+
+// static
+scoped_ptr<PlatformViewport> PlatformViewport::Create(Delegate* delegate) {
+ return scoped_ptr<PlatformViewport>(new PlatformViewportMac(delegate)).Pass();
+}
+
+} // namespace mojo
diff --git a/mojo/services/native_viewport/platform_viewport_ozone.cc b/mojo/services/native_viewport/platform_viewport_ozone.cc
new file mode 100644
index 0000000..b8076fb
--- /dev/null
+++ b/mojo/services/native_viewport/platform_viewport_ozone.cc
@@ -0,0 +1,95 @@
+// 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 "mojo/services/native_viewport/platform_viewport.h"
+
+#include "ui/events/event.h"
+#include "ui/events/platform/platform_event_dispatcher.h"
+#include "ui/events/platform/platform_event_source.h"
+#include "ui/ozone/public/cursor_factory_ozone.h"
+#include "ui/ozone/public/ozone_platform.h"
+#include "ui/ozone/public/surface_factory_ozone.h"
+#include "ui/platform_window/platform_window.h"
+#include "ui/platform_window/platform_window_delegate.h"
+
+namespace mojo {
+
+// TODO(spang): Deduplicate with PlatformViewportX11.. but there's a hack
+// in there that prevents this.
+class PlatformViewportOzone : public PlatformViewport,
+ public ui::PlatformWindowDelegate {
+ public:
+ explicit PlatformViewportOzone(Delegate* delegate) : delegate_(delegate) {
+ ui::OzonePlatform::InitializeForUI();
+ }
+
+ virtual ~PlatformViewportOzone() {
+ // Destroy the platform-window while |this| is still alive.
+ platform_window_.reset();
+ }
+
+ private:
+ // Overridden from PlatformViewport:
+ virtual void Init(const gfx::Rect& bounds) OVERRIDE {
+ platform_window_ =
+ ui::OzonePlatform::GetInstance()->CreatePlatformWindow(this, bounds);
+ }
+
+ virtual void Show() OVERRIDE { platform_window_->Show(); }
+
+ virtual void Hide() OVERRIDE { platform_window_->Hide(); }
+
+ virtual void Close() OVERRIDE { platform_window_->Close(); }
+
+ virtual gfx::Size GetSize() OVERRIDE {
+ return platform_window_->GetBounds().size();
+ }
+
+ virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE {
+ platform_window_->SetBounds(bounds);
+ }
+
+ virtual void SetCapture() OVERRIDE { platform_window_->SetCapture(); }
+
+ virtual void ReleaseCapture() OVERRIDE { platform_window_->ReleaseCapture(); }
+
+ // ui::PlatformWindowDelegate:
+ virtual void OnBoundsChanged(const gfx::Rect& new_bounds) OVERRIDE {
+ delegate_->OnBoundsChanged(new_bounds);
+ }
+
+ virtual void OnDamageRect(const gfx::Rect& damaged_region) OVERRIDE {}
+
+ virtual void DispatchEvent(ui::Event* event) OVERRIDE {
+ delegate_->OnEvent(event);
+ }
+
+ virtual void OnCloseRequest() OVERRIDE { platform_window_->Close(); }
+
+ virtual void OnClosed() OVERRIDE { delegate_->OnDestroyed(); }
+
+ virtual void OnWindowStateChanged(ui::PlatformWindowState state) OVERRIDE {}
+
+ virtual void OnLostCapture() OVERRIDE {}
+
+ virtual void OnAcceleratedWidgetAvailable(
+ gfx::AcceleratedWidget widget) OVERRIDE {
+ delegate_->OnAcceleratedWidgetAvailable(widget);
+ }
+
+ virtual void OnActivationChanged(bool active) OVERRIDE {}
+
+ scoped_ptr<ui::PlatformWindow> platform_window_;
+ Delegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(PlatformViewportOzone);
+};
+
+// static
+scoped_ptr<PlatformViewport> PlatformViewport::Create(Delegate* delegate) {
+ return scoped_ptr<PlatformViewport>(
+ new PlatformViewportOzone(delegate)).Pass();
+}
+
+} // namespace mojo
diff --git a/mojo/services/native_viewport/platform_viewport_stub.cc b/mojo/services/native_viewport/platform_viewport_stub.cc
new file mode 100644
index 0000000..80a7e94
--- /dev/null
+++ b/mojo/services/native_viewport/platform_viewport_stub.cc
@@ -0,0 +1,14 @@
+// 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 "mojo/services/native_viewport/platform_viewport_headless.h"
+
+namespace mojo {
+
+// static
+scoped_ptr<PlatformViewport> PlatformViewport::Create(Delegate* delegate) {
+ return PlatformViewportHeadless::Create(delegate);
+}
+
+} // namespace mojo
diff --git a/mojo/services/native_viewport/platform_viewport_win.cc b/mojo/services/native_viewport/platform_viewport_win.cc
new file mode 100644
index 0000000..2227112
--- /dev/null
+++ b/mojo/services/native_viewport/platform_viewport_win.cc
@@ -0,0 +1,104 @@
+// 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 "mojo/services/native_viewport/platform_viewport.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "ui/gfx/rect.h"
+#include "ui/platform_window/platform_window_delegate.h"
+#include "ui/platform_window/win/win_window.h"
+
+namespace mojo {
+
+class PlatformViewportWin : public PlatformViewport,
+ public ui::PlatformWindowDelegate {
+ public:
+ explicit PlatformViewportWin(Delegate* delegate)
+ : delegate_(delegate) {
+ }
+
+ virtual ~PlatformViewportWin() {
+ // Destroy the platform-window while |this| is still alive.
+ platform_window_.reset();
+ }
+
+ private:
+ // Overridden from PlatformViewport:
+ virtual void Init(const gfx::Rect& bounds) OVERRIDE {
+ platform_window_.reset(new ui::WinWindow(this, bounds));
+ }
+
+ virtual void Show() OVERRIDE {
+ platform_window_->Show();
+ }
+
+ virtual void Hide() OVERRIDE {
+ platform_window_->Hide();
+ }
+
+ virtual void Close() OVERRIDE {
+ platform_window_->Close();
+ }
+
+ virtual gfx::Size GetSize() OVERRIDE {
+ return platform_window_->GetBounds().size();
+ }
+
+ virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE {
+ platform_window_->SetBounds(bounds);
+ }
+
+ virtual void SetCapture() OVERRIDE {
+ platform_window_->SetCapture();
+ }
+
+ virtual void ReleaseCapture() OVERRIDE {
+ platform_window_->ReleaseCapture();
+ }
+
+ // ui::PlatformWindowDelegate:
+ virtual void OnBoundsChanged(const gfx::Rect& new_bounds) OVERRIDE {
+ delegate_->OnBoundsChanged(new_bounds);
+ }
+
+ virtual void OnDamageRect(const gfx::Rect& damaged_region) OVERRIDE {
+ }
+
+ virtual void DispatchEvent(ui::Event* event) OVERRIDE {
+ delegate_->OnEvent(event);
+ }
+
+ virtual void OnCloseRequest() OVERRIDE {
+ platform_window_->Close();
+ }
+
+ virtual void OnClosed() OVERRIDE {
+ delegate_->OnDestroyed();
+ }
+
+ virtual void OnWindowStateChanged(ui::PlatformWindowState state) OVERRIDE {
+ }
+
+ virtual void OnLostCapture() OVERRIDE {
+ }
+
+ virtual void OnAcceleratedWidgetAvailable(
+ gfx::AcceleratedWidget widget) OVERRIDE {
+ delegate_->OnAcceleratedWidgetAvailable(widget);
+ }
+
+ virtual void OnActivationChanged(bool active) OVERRIDE {}
+
+ scoped_ptr<ui::PlatformWindow> platform_window_;
+ Delegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(PlatformViewportWin);
+};
+
+// static
+scoped_ptr<PlatformViewport> PlatformViewport::Create(Delegate* delegate) {
+ return scoped_ptr<PlatformViewport>(new PlatformViewportWin(delegate)).Pass();
+}
+
+} // namespace mojo
diff --git a/mojo/services/native_viewport/platform_viewport_x11.cc b/mojo/services/native_viewport/platform_viewport_x11.cc
new file mode 100644
index 0000000..d4914c7
--- /dev/null
+++ b/mojo/services/native_viewport/platform_viewport_x11.cc
@@ -0,0 +1,150 @@
+// 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 "mojo/services/native_viewport/platform_viewport.h"
+
+#include "base/command_line.h"
+#include "base/message_loop/message_loop.h"
+#include "mojo/services/public/cpp/input_events/lib/mojo_extended_key_event_data.h"
+#include "ui/events/event.h"
+#include "ui/events/event_utils.h"
+#include "ui/events/platform/platform_event_dispatcher.h"
+#include "ui/events/platform/platform_event_source.h"
+#include "ui/gfx/rect.h"
+#include "ui/platform_window/platform_window.h"
+#include "ui/platform_window/platform_window_delegate.h"
+#include "ui/platform_window/x11/x11_window.h"
+
+namespace mojo {
+
+class PlatformViewportX11 : public PlatformViewport,
+ public ui::PlatformWindowDelegate {
+ public:
+ explicit PlatformViewportX11(Delegate* delegate) : delegate_(delegate) {
+ }
+
+ virtual ~PlatformViewportX11() {
+ // Destroy the platform-window while |this| is still alive.
+ platform_window_.reset();
+ }
+
+ private:
+ // Overridden from PlatformViewport:
+ virtual void Init(const gfx::Rect& bounds) OVERRIDE {
+ CHECK(!event_source_);
+ CHECK(!platform_window_);
+
+ event_source_ = ui::PlatformEventSource::CreateDefault();
+
+ platform_window_.reset(new ui::X11Window(this));
+ platform_window_->SetBounds(bounds);
+ }
+
+ virtual void Show() OVERRIDE {
+ platform_window_->Show();
+ }
+
+ virtual void Hide() OVERRIDE {
+ platform_window_->Hide();
+ }
+
+ virtual void Close() OVERRIDE {
+ platform_window_->Close();
+ }
+
+ virtual gfx::Size GetSize() OVERRIDE {
+ return bounds_.size();
+ }
+
+ virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE {
+ platform_window_->SetBounds(bounds);
+ }
+
+ virtual void SetCapture() OVERRIDE {
+ platform_window_->SetCapture();
+ }
+
+ virtual void ReleaseCapture() OVERRIDE {
+ platform_window_->ReleaseCapture();
+ }
+
+ // ui::PlatformWindowDelegate:
+ virtual void OnBoundsChanged(const gfx::Rect& new_bounds) OVERRIDE {
+ bounds_ = new_bounds;
+ delegate_->OnBoundsChanged(new_bounds);
+ }
+
+ virtual void OnDamageRect(const gfx::Rect& damaged_region) OVERRIDE {
+ }
+
+ virtual void DispatchEvent(ui::Event* event) OVERRIDE {
+ delegate_->OnEvent(event);
+
+ // We want to emulate the WM_CHAR generation behaviour of Windows.
+ //
+ // On Linux, we've previously inserted characters by having
+ // InputMethodAuraLinux take all key down events and send a character event
+ // to the TextInputClient. This causes a mismatch in code that has to be
+ // shared between Windows and Linux, including blink code. Now that we're
+ // trying to have one way of doing things, we need to standardize on and
+ // emulate Windows character events.
+ //
+ // This is equivalent to what we're doing in the current Linux port, but
+ // done once instead of done multiple times in different places.
+ if (event->type() == ui::ET_KEY_PRESSED) {
+ ui::KeyEvent* key_press_event = static_cast<ui::KeyEvent*>(event);
+ ui::KeyEvent char_event(key_press_event->GetCharacter(),
+ key_press_event->key_code(),
+ key_press_event->flags());
+
+ DCHECK_EQ(key_press_event->GetCharacter(), char_event.GetCharacter());
+ DCHECK_EQ(key_press_event->key_code(), char_event.key_code());
+ DCHECK_EQ(key_press_event->flags(), char_event.flags());
+
+ char_event.SetExtendedKeyEventData(scoped_ptr<ui::ExtendedKeyEventData>(
+ new MojoExtendedKeyEventData(
+ key_press_event->GetLocatedWindowsKeyboardCode(),
+ key_press_event->GetText(),
+ key_press_event->GetUnmodifiedText())));
+ char_event.set_platform_keycode(key_press_event->platform_keycode());
+
+ delegate_->OnEvent(&char_event);
+ }
+ }
+
+ virtual void OnCloseRequest() OVERRIDE {
+ platform_window_->Close();
+ }
+
+ virtual void OnClosed() OVERRIDE {
+ delegate_->OnDestroyed();
+ }
+
+ virtual void OnWindowStateChanged(ui::PlatformWindowState state) OVERRIDE {
+ }
+
+ virtual void OnLostCapture() OVERRIDE {
+ }
+
+ virtual void OnAcceleratedWidgetAvailable(
+ gfx::AcceleratedWidget widget) OVERRIDE {
+ delegate_->OnAcceleratedWidgetAvailable(widget);
+ }
+
+ virtual void OnActivationChanged(bool active) OVERRIDE {}
+
+ scoped_ptr<ui::PlatformEventSource> event_source_;
+ scoped_ptr<ui::PlatformWindow> platform_window_;
+ Delegate* delegate_;
+ gfx::Rect bounds_;
+
+ DISALLOW_COPY_AND_ASSIGN(PlatformViewportX11);
+};
+
+// static
+scoped_ptr<PlatformViewport> PlatformViewport::Create(Delegate* delegate) {
+ return scoped_ptr<PlatformViewport>(new PlatformViewportX11(delegate)).Pass();
+}
+
+} // namespace mojo
diff --git a/mojo/services/native_viewport/viewport_surface.cc b/mojo/services/native_viewport/viewport_surface.cc
new file mode 100644
index 0000000..8786e8c
--- /dev/null
+++ b/mojo/services/native_viewport/viewport_surface.cc
@@ -0,0 +1,111 @@
+// 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 "mojo/services/native_viewport/viewport_surface.h"
+
+#include "base/bind.h"
+#include "cc/surfaces/surface_id_allocator.h"
+#include "mojo/services/public/cpp/geometry/geometry_type_converters.h"
+#include "mojo/services/public/cpp/surfaces/surfaces_type_converters.h"
+#include "mojo/services/public/cpp/surfaces/surfaces_utils.h"
+#include "ui/gfx/transform.h"
+
+namespace mojo {
+
+ViewportSurface::ViewportSurface(SurfacesService* surfaces_service,
+ Gpu* gpu_service,
+ const gfx::Size& size,
+ cc::SurfaceId child_id)
+ : gpu_service_(gpu_service),
+ widget_id_(0u),
+ size_(size),
+ child_id_(child_id),
+ weak_factory_(this) {
+ surfaces_service->CreateSurfaceConnection(
+ base::Bind(&ViewportSurface::OnSurfaceConnectionCreated,
+ weak_factory_.GetWeakPtr()));
+}
+
+ViewportSurface::~ViewportSurface() {
+}
+
+void ViewportSurface::SetWidgetId(uint64_t widget_id) {
+ widget_id_ = widget_id;
+ if (id_allocator_)
+ BindSurfaceToNativeViewport();
+}
+
+void ViewportSurface::SetSize(const gfx::Size& size) {
+ if (size_ == size)
+ return;
+
+ if (id_.is_null())
+ return;
+
+ surface_->DestroySurface(SurfaceId::From(id_));
+ if (widget_id_)
+ BindSurfaceToNativeViewport();
+}
+
+void ViewportSurface::SetChildId(cc::SurfaceId child_id) {
+ child_id_ = child_id;
+ SubmitFrame();
+}
+
+void ViewportSurface::OnSurfaceConnectionCreated(SurfacePtr surface,
+ uint32_t id_namespace) {
+ surface_ = surface.Pass();
+ surface_.set_client(this);
+ id_allocator_.reset(new cc::SurfaceIdAllocator(id_namespace));
+ if (widget_id_ != 0u)
+ BindSurfaceToNativeViewport();
+}
+
+void ViewportSurface::BindSurfaceToNativeViewport() {
+ CommandBufferPtr cb;
+ gpu_service_->CreateOnscreenGLES2Context(
+ widget_id_, Size::From(size_), Get(&cb));
+
+ id_ = id_allocator_->GenerateId();
+ surface_->CreateGLES2BoundSurface(
+ cb.Pass(), SurfaceId::From(id_), Size::From(size_));
+
+ SubmitFrame();
+}
+
+void ViewportSurface::SubmitFrame() {
+ if (child_id_.is_null() || id_.is_null())
+ return;
+
+ SurfaceQuadStatePtr surface_quad_state = SurfaceQuadState::New();
+ surface_quad_state->surface = SurfaceId::From(child_id_);
+
+ gfx::Rect bounds(size_);
+
+ QuadPtr surface_quad = Quad::New();
+ surface_quad->material = Material::MATERIAL_SURFACE_CONTENT;
+ surface_quad->rect = Rect::From(bounds);
+ surface_quad->opaque_rect = Rect::From(bounds);
+ surface_quad->visible_rect = Rect::From(bounds);
+ surface_quad->needs_blending = true;
+ surface_quad->shared_quad_state_index = 0;
+ surface_quad->surface_quad_state = surface_quad_state.Pass();
+
+ PassPtr pass = CreateDefaultPass(1, bounds);
+
+ pass->quads.push_back(surface_quad.Pass());
+ pass->shared_quad_states.push_back(CreateDefaultSQS(size_));
+
+ FramePtr frame = Frame::New();
+ frame->passes.push_back(pass.Pass());
+ frame->resources.resize(0u);
+ surface_->SubmitFrame(SurfaceId::From(id_), frame.Pass());
+}
+
+void ViewportSurface::ReturnResources(Array<ReturnedResourcePtr> resources) {
+ // We never submit resources so we should never get any back.
+ DCHECK_EQ(0u, resources.size());
+}
+
+} // namespace mojo
diff --git a/mojo/services/native_viewport/viewport_surface.h b/mojo/services/native_viewport/viewport_surface.h
new file mode 100644
index 0000000..2ca8105
--- /dev/null
+++ b/mojo/services/native_viewport/viewport_surface.h
@@ -0,0 +1,58 @@
+// 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 MOJO_SERVICES_NATIVE_VIEWPORT_VIEWPORT_SURFACE_H_
+#define MOJO_SERVICES_NATIVE_VIEWPORT_VIEWPORT_SURFACE_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "cc/surfaces/surface_id.h"
+#include "mojo/services/public/interfaces/gpu/gpu.mojom.h"
+#include "mojo/services/public/interfaces/surfaces/surfaces.mojom.h"
+#include "mojo/services/public/interfaces/surfaces/surfaces_service.mojom.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/size.h"
+
+namespace cc {
+class SurfaceIdAllocator;
+}
+
+namespace mojo {
+
+// This manages the surface that draws to a particular NativeViewport instance.
+class ViewportSurface : public SurfaceClient {
+ public:
+ ViewportSurface(SurfacesService* surfaces_service,
+ Gpu* gpu_service,
+ const gfx::Size& size,
+ cc::SurfaceId child_id);
+ virtual ~ViewportSurface();
+
+ void SetWidgetId(uint64_t widget_id);
+ void SetSize(const gfx::Size& size);
+ void SetChildId(cc::SurfaceId child_id);
+
+ private:
+ void OnSurfaceConnectionCreated(SurfacePtr surface, uint32_t id_namespace);
+ void BindSurfaceToNativeViewport();
+ void SubmitFrame();
+
+ // SurfaceClient implementation.
+ virtual void ReturnResources(Array<ReturnedResourcePtr> resources) OVERRIDE;
+
+ SurfacePtr surface_;
+ Gpu* gpu_service_;
+ uint64_t widget_id_;
+ gfx::Size size_;
+ scoped_ptr<cc::SurfaceIdAllocator> id_allocator_;
+ cc::SurfaceId id_;
+ cc::SurfaceId child_id_;
+ base::WeakPtrFactory<ViewportSurface> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViewportSurface);
+};
+
+} // namespace mojo
+
+#endif // MOJO_SERVICES_NATIVE_VIEWPORT_VIEWPORT_SURFACE_H_