| Index: mojo/services/native_viewport/platform_viewport_android.cc
 | 
| 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 0000000000000000000000000000000000000000..90bfc76b926f0d4099f7328d373d09fccfc8565b
 | 
| --- /dev/null
 | 
| +++ b/mojo/services/native_viewport/platform_viewport_android.cc
 | 
| @@ -0,0 +1,208 @@
 | 
| +// 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 "mojo/converters/geometry/geometry_type_converters.h"
 | 
| +#include "mojo/converters/input_events/input_events_type_converters.h"
 | 
| +#include "ui/events/event.h"
 | 
| +#include "ui/events/keycodes/keyboard_code_conversion_android.h"
 | 
| +#include "ui/gfx/geometry/point.h"
 | 
| +
 | 
| +namespace native_viewport {
 | 
| +namespace {
 | 
| +
 | 
| +mojo::EventType MotionEventActionToEventType(jint action) {
 | 
| +  switch (action) {
 | 
| +    case AMOTION_EVENT_ACTION_DOWN:
 | 
| +    case AMOTION_EVENT_ACTION_POINTER_DOWN:
 | 
| +      return mojo::EVENT_TYPE_POINTER_DOWN;
 | 
| +    case AMOTION_EVENT_ACTION_UP:
 | 
| +    case AMOTION_EVENT_ACTION_POINTER_UP:
 | 
| +      return mojo::EVENT_TYPE_POINTER_UP;
 | 
| +    case AMOTION_EVENT_ACTION_MOVE:
 | 
| +      return mojo::EVENT_TYPE_POINTER_MOVE;
 | 
| +    case AMOTION_EVENT_ACTION_CANCEL:
 | 
| +      return mojo::EVENT_TYPE_POINTER_CANCEL;
 | 
| +    case AMOTION_EVENT_ACTION_OUTSIDE:
 | 
| +    case AMOTION_EVENT_ACTION_HOVER_MOVE:
 | 
| +    case AMOTION_EVENT_ACTION_SCROLL:
 | 
| +    case AMOTION_EVENT_ACTION_HOVER_ENTER:
 | 
| +    case AMOTION_EVENT_ACTION_HOVER_EXIT:
 | 
| +    default:
 | 
| +      NOTIMPLEMENTED() << "Unimplemented motion action: " << action;
 | 
| +  }
 | 
| +  return mojo::EVENT_TYPE_UNKNOWN;
 | 
| +}
 | 
| +
 | 
| +}  // namespace
 | 
| +
 | 
| +////////////////////////////////////////////////////////////////////////////////
 | 
| +// 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_);
 | 
| +  delegate_->OnAcceleratedWidgetDestroyed();
 | 
| +  ReleaseWindow();
 | 
| +}
 | 
| +
 | 
| +void PlatformViewportAndroid::SurfaceSetSize(JNIEnv* env,
 | 
| +                                             jobject obj,
 | 
| +                                             jint width,
 | 
| +                                             jint height,
 | 
| +                                             jfloat density) {
 | 
| +  metrics_ = mojo::ViewportMetrics::New();
 | 
| +  metrics_->size = mojo::Size::New();
 | 
| +  metrics_->size->width = static_cast<int>(width);
 | 
| +  metrics_->size->height = static_cast<int>(height);
 | 
| +  metrics_->device_pixel_ratio = density;
 | 
| +  delegate_->OnMetricsChanged(metrics_.Clone());
 | 
| +}
 | 
| +
 | 
| +bool PlatformViewportAndroid::TouchEvent(JNIEnv* env,
 | 
| +                                         jobject obj,
 | 
| +                                         jlong time_ms,
 | 
| +                                         jint masked_action,
 | 
| +                                         jint pointer_id,
 | 
| +                                         jfloat x,
 | 
| +                                         jfloat y,
 | 
| +                                         jfloat pressure,
 | 
| +                                         jfloat touch_major,
 | 
| +                                         jfloat touch_minor,
 | 
| +                                         jfloat orientation,
 | 
| +                                         jfloat h_wheel,
 | 
| +                                         jfloat v_wheel) {
 | 
| +  mojo::EventPtr event(mojo::Event::New());
 | 
| +  event->time_stamp = time_ms;
 | 
| +  event->action = MotionEventActionToEventType(masked_action);
 | 
| +  if (event->action == mojo::EVENT_TYPE_UNKNOWN)
 | 
| +    return false;
 | 
| +
 | 
| +  event->pointer_data = mojo::PointerData::New();
 | 
| +  event->pointer_data->pointer_id = pointer_id;
 | 
| +  event->pointer_data->x = x;
 | 
| +  event->pointer_data->y = y;
 | 
| +  event->pointer_data->screen_x = x;
 | 
| +  event->pointer_data->screen_y = y;
 | 
| +  event->pointer_data->pressure = pressure;
 | 
| +  event->pointer_data->radius_major = touch_major;
 | 
| +  event->pointer_data->radius_minor = touch_minor;
 | 
| +  event->pointer_data->orientation = orientation;
 | 
| +  event->pointer_data->horizontal_wheel = h_wheel;
 | 
| +  event->pointer_data->vertical_wheel = v_wheel;
 | 
| +  delegate_->OnEvent(event.Pass());
 | 
| +
 | 
| +  return true;
 | 
| +}
 | 
| +
 | 
| +bool PlatformViewportAndroid::KeyEvent(JNIEnv* env,
 | 
| +                                       jobject obj,
 | 
| +                                       bool pressed,
 | 
| +                                       jint key_code,
 | 
| +                                       jint unicode_character) {
 | 
| +  ui::KeyEvent event(pressed ? ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED,
 | 
| +                     ui::KeyboardCodeFromAndroidKeyCode(key_code), 0);
 | 
| +  event.set_platform_keycode(key_code);
 | 
| +  delegate_->OnEvent(mojo::Event::From(event));
 | 
| +  if (pressed && unicode_character) {
 | 
| +    ui::KeyEvent char_event(unicode_character,
 | 
| +                            ui::KeyboardCodeFromAndroidKeyCode(key_code), 0);
 | 
| +    char_event.set_platform_keycode(key_code);
 | 
| +    delegate_->OnEvent(mojo::Event::From(char_event));
 | 
| +  }
 | 
| +  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 metrics_->size.To<gfx::Size>();
 | 
| +}
 | 
| +
 | 
| +void PlatformViewportAndroid::SetBounds(const gfx::Rect& bounds) {
 | 
| +  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 native_viewport
 | 
| 
 |