diff --git a/engine/src/flutter/examples/touch-demo.sky b/engine/src/flutter/examples/touch-demo.sky
index 78b86d20b1..2afefd7577 100644
--- a/engine/src/flutter/examples/touch-demo.sky
+++ b/engine/src/flutter/examples/touch-demo.sky
@@ -1,6 +1,5 @@
#!mojo mojo:sky_viewer
-
Ready
-
diff --git a/engine/src/flutter/shell/BUILD.gn b/engine/src/flutter/shell/BUILD.gn
index 30be3cf84c..287cb0f902 100644
--- a/engine/src/flutter/shell/BUILD.gn
+++ b/engine/src/flutter/shell/BUILD.gn
@@ -45,6 +45,8 @@ shared_library("sky_shell") {
"ui/animator.h",
"ui/engine.cc",
"ui/engine.h",
+ "ui/input_event_converter.cc",
+ "ui/input_event_converter.h",
"ui/platform_impl.cc",
"ui/platform_impl.h",
"ui_delegate.cc",
@@ -63,6 +65,7 @@ shared_library("sky_shell") {
"//mojo/services/network/public/interfaces",
"//skia",
"//sky/engine",
+ "//sky/services/viewport",
"//ui/gfx/geometry",
"//ui/gl",
":jni_headers",
@@ -86,6 +89,7 @@ android_library("java") {
"//mojo/public/java:system",
"//mojo/services/network/public/interfaces:interfaces_java",
"//sky/services/oknet",
+ "//sky/services/viewport:viewport_java",
]
}
diff --git a/engine/src/flutter/shell/apk/src/org/domokit/sky/shell/PlatformView.java b/engine/src/flutter/shell/apk/src/org/domokit/sky/shell/PlatformView.java
index ac8879d43c..0934fc5077 100644
--- a/engine/src/flutter/shell/apk/src/org/domokit/sky/shell/PlatformView.java
+++ b/engine/src/flutter/shell/apk/src/org/domokit/sky/shell/PlatformView.java
@@ -5,12 +5,22 @@
package org.domokit.sky.shell;
import android.content.Context;
+import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import org.chromium.base.JNINamespace;
+import org.chromium.mojo.bindings.InterfaceRequest;
+import org.chromium.mojo.system.Core;
+import org.chromium.mojo.system.Pair;
+import org.chromium.mojo.system.impl.CoreImpl;
+import org.chromium.mojom.sky.EventType;
+import org.chromium.mojom.sky.InputEvent;
+import org.chromium.mojom.sky.PointerData;
+import org.chromium.mojom.sky.PointerKind;
+import org.chromium.mojom.sky.ViewportObserver;
/**
* A view containing Sky
@@ -18,6 +28,7 @@ import org.chromium.base.JNINamespace;
@JNINamespace("sky::shell")
public class PlatformView extends SurfaceView {
private long mNativePlatformView;
+ private ViewportObserver.Proxy mViewportObserver;
private final SurfaceHolder.Callback mSurfaceCallback;
public PlatformView(Context context) {
@@ -26,7 +37,7 @@ public class PlatformView extends SurfaceView {
setFocusable(true);
setFocusableInTouchMode(true);
- mNativePlatformView = nativeAttach();
+ attach();
assert mNativePlatformView != 0;
final float density = context.getResources().getDisplayMetrics().density;
@@ -34,8 +45,8 @@ public class PlatformView extends SurfaceView {
mSurfaceCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- assert mNativePlatformView != 0;
- nativeSurfaceSetSize(mNativePlatformView, width, height, density);
+ assert mViewportObserver != null;
+ mViewportObserver.onViewportMetricsChanged(width, height, density);
}
@Override
@@ -69,10 +80,45 @@ public class PlatformView extends SurfaceView {
}
}
- private static native long nativeAttach();
+ private int getTypeForAction(int maskedAction) {
+ if (maskedAction == MotionEvent.ACTION_DOWN)
+ return EventType.POINTER_DOWN;
+ if (maskedAction == MotionEvent.ACTION_UP)
+ return EventType.POINTER_UP;
+ if (maskedAction == MotionEvent.ACTION_MOVE)
+ return EventType.POINTER_MOVE;
+ if (maskedAction == MotionEvent.ACTION_CANCEL)
+ return EventType.POINTER_CANCEL;
+ return EventType.UNKNOWN;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ PointerData pointerData = new PointerData();
+ pointerData.pointer = event.getPointerId(0);
+ pointerData.kind = PointerKind.TOUCH;
+ pointerData.x = event.getX();
+ pointerData.y = event.getY();
+
+ InputEvent inputEvent = new InputEvent();
+ inputEvent.type = getTypeForAction(event.getActionMasked());
+ inputEvent.timeStamp = event.getEventTime();
+ inputEvent.pointerData = pointerData;
+
+ mViewportObserver.onInputEvent(inputEvent);
+ return true;
+ }
+
+ private void attach() {
+ Core core = CoreImpl.getInstance();
+ Pair> result =
+ ViewportObserver.MANAGER.getInterfaceRequest(core);
+ mViewportObserver = result.first;
+ mNativePlatformView = nativeAttach(result.second.passHandle().releaseNativeHandle());
+ }
+
+ private static native long nativeAttach(int inputObserverHandle);
private static native void nativeDetach(long nativePlatformView);
private static native void nativeSurfaceCreated(long nativePlatformView, Surface surface);
private static native void nativeSurfaceDestroyed(long nativePlatformView);
- private static native void nativeSurfaceSetSize(
- long nativePlatformView, int width, int height, float density);
}
diff --git a/engine/src/flutter/shell/platform_view.cc b/engine/src/flutter/shell/platform_view.cc
index e31498dcb3..69a7b10a1c 100644
--- a/engine/src/flutter/shell/platform_view.cc
+++ b/engine/src/flutter/shell/platform_view.cc
@@ -16,8 +16,12 @@
namespace sky {
namespace shell {
-static jlong Attach(JNIEnv* env, jclass clazz) {
- return reinterpret_cast(Shell::Shared().view());
+static jlong Attach(JNIEnv* env, jclass clazz, jint viewportObserverHandle) {
+ PlatformView* view = Shell::Shared().view();
+ view->ConnectToViewportObserver(
+ mojo::MakeRequest(mojo::ScopedMessagePipeHandle(
+ mojo::MessagePipeHandle(viewportObserverHandle))));
+ return reinterpret_cast(view);
}
// static
@@ -34,6 +38,14 @@ PlatformView::~PlatformView() {
ReleaseWindow();
}
+void PlatformView::ConnectToViewportObserver(
+ mojo::InterfaceRequest request) {
+ config_.ui_task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(&UIDelegate::ConnectToViewportObserver, config_.ui_delegate,
+ base::Passed(&request)));
+}
+
void PlatformView::Detach(JNIEnv* env, jobject obj) {
DCHECK(!window_);
}
@@ -60,17 +72,6 @@ void PlatformView::SurfaceDestroyed(JNIEnv* env, jobject obj) {
ReleaseWindow();
}
-void PlatformView::SurfaceSetSize(JNIEnv* env,
- jobject obj,
- jint width,
- jint height,
- jfloat density) {
- config_.ui_task_runner->PostTask(
- FROM_HERE,
- base::Bind(&UIDelegate::OnViewportMetricsChanged, config_.ui_delegate,
- gfx::Size(width, height), density));
-}
-
void PlatformView::ReleaseWindow() {
ANativeWindow_release(window_);
window_ = nullptr;
diff --git a/engine/src/flutter/shell/platform_view.h b/engine/src/flutter/shell/platform_view.h
index 7f83cde083..c6da2e3b6d 100644
--- a/engine/src/flutter/shell/platform_view.h
+++ b/engine/src/flutter/shell/platform_view.h
@@ -33,6 +33,9 @@ class PlatformView {
explicit PlatformView(const Config& config);
~PlatformView();
+ void ConnectToViewportObserver(
+ mojo::InterfaceRequest request);
+
// Called from Java
void Detach(JNIEnv* env, jobject obj);
void SurfaceCreated(JNIEnv* env, jobject obj, jobject jsurface);
diff --git a/engine/src/flutter/shell/ui/engine.cc b/engine/src/flutter/shell/ui/engine.cc
index b316c4cfed..5b1e6da613 100644
--- a/engine/src/flutter/shell/ui/engine.cc
+++ b/engine/src/flutter/shell/ui/engine.cc
@@ -5,10 +5,12 @@
#include "sky/shell/ui/engine.h"
#include "base/bind.h"
+#include "sky/engine/public/platform/WebInputEvent.h"
#include "sky/engine/public/web/Sky.h"
#include "sky/engine/public/web/WebLocalFrame.h"
#include "sky/engine/public/web/WebView.h"
#include "sky/shell/ui/animator.h"
+#include "sky/shell/ui/input_event_converter.h"
#include "sky/shell/ui/platform_impl.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
@@ -19,6 +21,8 @@ namespace shell {
Engine::Engine(const Config& config)
: animator_(new Animator(config, this)),
web_view_(nullptr),
+ device_pixel_ratio_(1.0f),
+ viewport_observer_binding_(this),
weak_factory_(this) {
}
@@ -39,7 +43,7 @@ void Engine::Init(mojo::ScopedMessagePipeHandle service_provider) {
web_view_ = blink::WebView::create(this);
web_view_->setMainFrame(blink::WebLocalFrame::create(this));
web_view_->mainFrame()->load(
- GURL("http://127.0.0.1:8000/sky/examples/spinning-square.sky"));
+ GURL("http://domokit.github.io/sky/examples/spinning-square.sky"));
}
void Engine::BeginFrame(base::TimeTicks frame_time) {
@@ -63,16 +67,30 @@ skia::RefPtr Engine::Paint() {
return skia::AdoptRef(recorder.endRecordingAsPicture());
}
-void Engine::OnViewportMetricsChanged(const gfx::Size& physical_size,
+void Engine::ConnectToViewportObserver(
+ mojo::InterfaceRequest request) {
+ viewport_observer_binding_.Bind(request.Pass());
+}
+
+void Engine::OnViewportMetricsChanged(int width, int height,
float device_pixel_ratio) {
- physical_size_ = physical_size;
+ physical_size_.SetSize(width, height);
+ device_pixel_ratio_ = device_pixel_ratio;
web_view_->setDeviceScaleFactor(device_pixel_ratio);
- gfx::SizeF size = gfx::ScaleSize(physical_size, 1 / device_pixel_ratio);
+ gfx::SizeF size = gfx::ScaleSize(physical_size_, 1 / device_pixel_ratio);
// FIXME: We should be able to set the size of the WebView in floating point
// because its in logical pixels.
web_view_->resize(blink::WebSize(size.width(), size.height()));
}
+void Engine::OnInputEvent(InputEventPtr event) {
+ scoped_ptr web_event =
+ ConvertEvent(event, device_pixel_ratio_);
+ if (!web_event)
+ return;
+ web_view_->handleInputEvent(*web_event);
+}
+
void Engine::initializeLayerTreeView() {
}
diff --git a/engine/src/flutter/shell/ui/engine.h b/engine/src/flutter/shell/ui/engine.h
index ec21ab4e88..1aafbb39f4 100644
--- a/engine/src/flutter/shell/ui/engine.h
+++ b/engine/src/flutter/shell/ui/engine.h
@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/core.h"
#include "skia/ext/refptr.h"
#include "sky/engine/public/web/WebFrameClient.h"
@@ -24,6 +25,7 @@ class Animator;
class PlatformImpl;
class Engine : public UIDelegate,
+ public ViewportObserver,
public blink::WebFrameClient,
public blink::WebViewClient {
public:
@@ -44,8 +46,13 @@ class Engine : public UIDelegate,
private:
// UIDelegate methods:
- void OnViewportMetricsChanged(const gfx::Size& physical_size,
+ void ConnectToViewportObserver(
+ mojo::InterfaceRequest request) override;
+
+ // ViewportObserver:
+ void OnViewportMetricsChanged(int width, int height,
float device_pixel_ratio) override;
+ void OnInputEvent(InputEventPtr event) override;
// WebViewClient methods:
void initializeLayerTreeView() override;
@@ -54,7 +61,9 @@ class Engine : public UIDelegate,
scoped_ptr platform_impl_;
scoped_ptr animator_;
blink::WebView* web_view_;
+ float device_pixel_ratio_;
gfx::Size physical_size_;
+ mojo::Binding viewport_observer_binding_;
base::WeakPtrFactory weak_factory_;
diff --git a/engine/src/flutter/shell/ui/input_event_converter.cc b/engine/src/flutter/shell/ui/input_event_converter.cc
new file mode 100644
index 0000000000..9fcf49c3d2
--- /dev/null
+++ b/engine/src/flutter/shell/ui/input_event_converter.cc
@@ -0,0 +1,64 @@
+// 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 "sky/shell/ui/input_event_converter.h"
+
+#include "base/logging.h"
+#include "base/time/time.h"
+#include "sky/engine/public/platform/WebInputEvent.h"
+
+namespace sky {
+namespace {
+
+scoped_ptr BuildWebPointerEvent(
+ const InputEventPtr& event, float device_pixel_ratio) {
+ scoped_ptr web_event(new blink::WebPointerEvent);
+
+ web_event->timeStampMS =
+ base::TimeDelta::FromInternalValue(event->time_stamp).InMillisecondsF();
+
+ switch (event->type) {
+ case EVENT_TYPE_POINTER_DOWN:
+ web_event->type = blink::WebInputEvent::PointerDown;
+ break;
+ case EVENT_TYPE_POINTER_UP:
+ web_event->type = blink::WebInputEvent::PointerUp;
+ break;
+ case EVENT_TYPE_POINTER_MOVE:
+ web_event->type = blink::WebInputEvent::PointerMove;
+ break;
+ case EVENT_TYPE_POINTER_CANCEL:
+ web_event->type = blink::WebInputEvent::PointerCancel;
+ break;
+ default:
+ NOTIMPLEMENTED() << "Received unexpected event: " << event->type;
+ break;
+ }
+
+ if (event->pointer_data) {
+ if (event->pointer_data->kind == POINTER_KIND_TOUCH)
+ web_event->kind = blink::WebPointerEvent::Touch;
+ web_event->pointer = event->pointer_data->pointer;
+ web_event->x = event->pointer_data->x / device_pixel_ratio;
+ web_event->y = event->pointer_data->y / device_pixel_ratio;
+ }
+
+ return web_event.Pass();
+}
+
+} // namespace
+
+scoped_ptr ConvertEvent(const InputEventPtr& event,
+ float device_pixel_ratio) {
+ if (event->type == EVENT_TYPE_POINTER_DOWN ||
+ event->type == EVENT_TYPE_POINTER_UP ||
+ event->type == EVENT_TYPE_POINTER_MOVE ||
+ event->type == EVENT_TYPE_POINTER_CANCEL) {
+ return BuildWebPointerEvent(event, device_pixel_ratio);
+ }
+
+ return scoped_ptr();
+}
+
+} // namespace mojo
diff --git a/engine/src/flutter/shell/ui/input_event_converter.h b/engine/src/flutter/shell/ui/input_event_converter.h
new file mode 100644
index 0000000000..05a797f0a1
--- /dev/null
+++ b/engine/src/flutter/shell/ui/input_event_converter.h
@@ -0,0 +1,21 @@
+// Copyright 2015 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 SKY_SHELL_UI_INPUT_EVENT_CONVERTER_H_
+#define SKY_SHELL_UI_INPUT_EVENT_CONVERTER_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "sky/services/viewport/input_event.mojom.h"
+
+namespace blink {
+class WebInputEvent;
+}
+
+namespace sky {
+
+scoped_ptr ConvertEvent(const InputEventPtr& event,
+ float device_pixel_ratio);
+}
+
+#endif // SKY_SHELL_UI_INPUT_EVENT_CONVERTER_H_
diff --git a/engine/src/flutter/shell/ui_delegate.h b/engine/src/flutter/shell/ui_delegate.h
index bb7e44b8c1..d50a34acdf 100644
--- a/engine/src/flutter/shell/ui_delegate.h
+++ b/engine/src/flutter/shell/ui_delegate.h
@@ -5,6 +5,8 @@
#ifndef SKY_SHELL_UI_DELEGATE_H_
#define SKY_SHELL_UI_DELEGATE_H_
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "sky/services/viewport/viewport_observer.mojom.h"
#include "ui/gfx/geometry/size.h"
namespace sky {
@@ -12,8 +14,8 @@ namespace shell {
class UIDelegate {
public:
- virtual void OnViewportMetricsChanged(const gfx::Size& size,
- float device_pixel_ratio) = 0;
+ virtual void ConnectToViewportObserver(
+ mojo::InterfaceRequest request) = 0;
protected:
virtual ~UIDelegate();