platform_viewport_android.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "mojo/services/native_viewport/platform_viewport_android.h"
6
7#include <android/input.h>
8#include <android/native_window_jni.h>
9
10#include "base/android/jni_android.h"
11#include "jni/PlatformViewportAndroid_jni.h"
12#include "ui/events/event.h"
13#include "ui/gfx/point.h"
14
15namespace mojo {
16
17ui::EventType MotionEventActionToEventType(jint action) {
18  switch (action) {
19    case AMOTION_EVENT_ACTION_DOWN:
20      return ui::ET_TOUCH_PRESSED;
21    case AMOTION_EVENT_ACTION_MOVE:
22      return ui::ET_TOUCH_MOVED;
23    case AMOTION_EVENT_ACTION_UP:
24      return ui::ET_TOUCH_RELEASED;
25    default:
26      NOTREACHED();
27  }
28  return ui::ET_UNKNOWN;
29}
30
31////////////////////////////////////////////////////////////////////////////////
32// PlatformViewportAndroid, public:
33
34// static
35bool PlatformViewportAndroid::Register(JNIEnv* env) {
36  return RegisterNativesImpl(env);
37}
38
39PlatformViewportAndroid::PlatformViewportAndroid(Delegate* delegate)
40    : delegate_(delegate),
41      window_(NULL),
42      id_generator_(0),
43      weak_factory_(this) {
44}
45
46PlatformViewportAndroid::~PlatformViewportAndroid() {
47  if (window_)
48    ReleaseWindow();
49}
50
51void PlatformViewportAndroid::Destroy(JNIEnv* env, jobject obj) {
52  delegate_->OnDestroyed();
53}
54
55void PlatformViewportAndroid::SurfaceCreated(JNIEnv* env,
56                                             jobject obj,
57                                             jobject jsurface) {
58  base::android::ScopedJavaLocalRef<jobject> protector(env, jsurface);
59  // Note: This ensures that any local references used by
60  // ANativeWindow_fromSurface are released immediately. This is needed as a
61  // workaround for https://code.google.com/p/android/issues/detail?id=68174
62  {
63    base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env);
64    window_ = ANativeWindow_fromSurface(env, jsurface);
65  }
66  delegate_->OnAcceleratedWidgetAvailable(window_);
67}
68
69void PlatformViewportAndroid::SurfaceDestroyed(JNIEnv* env, jobject obj) {
70  DCHECK(window_);
71  ReleaseWindow();
72}
73
74void PlatformViewportAndroid::SurfaceSetSize(JNIEnv* env, jobject obj,
75                                             jint width, jint height) {
76  bounds_ = gfx::Rect(width, height);
77  delegate_->OnBoundsChanged(bounds_);
78}
79
80bool PlatformViewportAndroid::TouchEvent(JNIEnv* env, jobject obj,
81                                         jint pointer_id,
82                                         jint action,
83                                         jfloat x, jfloat y,
84                                         jlong time_ms) {
85  gfx::Point location(static_cast<int>(x), static_cast<int>(y));
86  ui::TouchEvent event(MotionEventActionToEventType(action), location,
87                       id_generator_.GetGeneratedID(pointer_id),
88                       base::TimeDelta::FromMilliseconds(time_ms));
89  // TODO(beng): handle multiple touch-points.
90  delegate_->OnEvent(&event);
91  if (action == ui::ET_TOUCH_RELEASED)
92    id_generator_.ReleaseNumber(pointer_id);
93
94  return true;
95}
96
97////////////////////////////////////////////////////////////////////////////////
98// PlatformViewportAndroid, PlatformViewport implementation:
99
100void PlatformViewportAndroid::Init(const gfx::Rect& bounds) {
101  JNIEnv* env = base::android::AttachCurrentThread();
102  Java_PlatformViewportAndroid_createForActivity(
103      env,
104      base::android::GetApplicationContext(),
105      reinterpret_cast<jlong>(this));
106}
107
108void PlatformViewportAndroid::Show() {
109  // Nothing to do. View is created visible.
110}
111
112void PlatformViewportAndroid::Hide() {
113  // Nothing to do. View is always visible.
114}
115
116void PlatformViewportAndroid::Close() {
117  // TODO(beng): close activity containing MojoView?
118
119  // TODO(beng): perform this in response to view destruction.
120  delegate_->OnDestroyed();
121}
122
123gfx::Size PlatformViewportAndroid::GetSize() {
124  return bounds_.size();
125}
126
127void PlatformViewportAndroid::SetBounds(const gfx::Rect& bounds) {
128  NOTIMPLEMENTED();
129}
130
131void PlatformViewportAndroid::SetCapture() {
132  NOTIMPLEMENTED();
133}
134
135void PlatformViewportAndroid::ReleaseCapture() {
136  NOTIMPLEMENTED();
137}
138
139////////////////////////////////////////////////////////////////////////////////
140// PlatformViewportAndroid, private:
141
142void PlatformViewportAndroid::ReleaseWindow() {
143  ANativeWindow_release(window_);
144  window_ = NULL;
145}
146
147////////////////////////////////////////////////////////////////////////////////
148// PlatformViewport, public:
149
150// static
151scoped_ptr<PlatformViewport> PlatformViewport::Create(Delegate* delegate) {
152  return scoped_ptr<PlatformViewport>(
153      new PlatformViewportAndroid(delegate)).Pass();
154}
155
156}  // namespace mojo
157