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.
5 #include "components/native_viewport/platform_viewport_android.h"
7 #include <android/input.h>
8 #include <android/native_window_jni.h>
10 #include "base/android/jni_android.h"
11 #include "jni/PlatformViewportAndroid_jni.h"
12 #include "mojo/converters/geometry/geometry_type_converters.h"
13 #include "mojo/converters/input_events/input_events_type_converters.h"
14 #include "ui/events/event.h"
15 #include "ui/events/keycodes/keyboard_code_conversion_android.h"
16 #include "ui/gfx/geometry/point.h"
18 namespace native_viewport
{
21 mojo::EventType
MotionEventActionToEventType(jint action
) {
23 case AMOTION_EVENT_ACTION_DOWN
:
24 case AMOTION_EVENT_ACTION_POINTER_DOWN
:
25 return mojo::EVENT_TYPE_POINTER_DOWN
;
26 case AMOTION_EVENT_ACTION_UP
:
27 case AMOTION_EVENT_ACTION_POINTER_UP
:
28 return mojo::EVENT_TYPE_POINTER_UP
;
29 case AMOTION_EVENT_ACTION_MOVE
:
30 return mojo::EVENT_TYPE_POINTER_MOVE
;
31 case AMOTION_EVENT_ACTION_CANCEL
:
32 return mojo::EVENT_TYPE_POINTER_CANCEL
;
33 case AMOTION_EVENT_ACTION_OUTSIDE
:
34 case AMOTION_EVENT_ACTION_HOVER_MOVE
:
35 case AMOTION_EVENT_ACTION_SCROLL
:
36 case AMOTION_EVENT_ACTION_HOVER_ENTER
:
37 case AMOTION_EVENT_ACTION_HOVER_EXIT
:
39 NOTIMPLEMENTED() << "Unimplemented motion action: " << action
;
41 return mojo::EVENT_TYPE_UNKNOWN
;
46 ////////////////////////////////////////////////////////////////////////////////
47 // PlatformViewportAndroid, public:
50 bool PlatformViewportAndroid::Register(JNIEnv
* env
) {
51 return RegisterNativesImpl(env
);
54 PlatformViewportAndroid::PlatformViewportAndroid(Delegate
* delegate
)
55 : delegate_(delegate
),
61 PlatformViewportAndroid::~PlatformViewportAndroid() {
64 if (!java_platform_viewport_android_
.is_empty()) {
65 JNIEnv
* env
= base::android::AttachCurrentThread();
66 Java_PlatformViewportAndroid_detach(
67 env
, java_platform_viewport_android_
.get(env
).obj());
71 void PlatformViewportAndroid::Destroy(JNIEnv
* env
, jobject obj
) {
72 delegate_
->OnDestroyed();
75 void PlatformViewportAndroid::SurfaceCreated(JNIEnv
* env
,
78 base::android::ScopedJavaLocalRef
<jobject
> protector(env
, jsurface
);
79 // Note: This ensures that any local references used by
80 // ANativeWindow_fromSurface are released immediately. This is needed as a
81 // workaround for https://code.google.com/p/android/issues/detail?id=68174
83 base::android::ScopedJavaLocalFrame
scoped_local_reference_frame(env
);
84 window_
= ANativeWindow_fromSurface(env
, jsurface
);
86 delegate_
->OnAcceleratedWidgetAvailable(window_
);
89 void PlatformViewportAndroid::SurfaceDestroyed(JNIEnv
* env
, jobject obj
) {
91 delegate_
->OnAcceleratedWidgetDestroyed();
95 void PlatformViewportAndroid::SurfaceSetSize(JNIEnv
* env
,
100 metrics_
= mojo::ViewportMetrics::New();
101 metrics_
->size
= mojo::Size::New();
102 metrics_
->size
->width
= static_cast<int>(width
);
103 metrics_
->size
->height
= static_cast<int>(height
);
104 metrics_
->device_pixel_ratio
= density
;
105 delegate_
->OnMetricsChanged(metrics_
.Clone());
108 bool PlatformViewportAndroid::TouchEvent(JNIEnv
* env
,
121 mojo::EventPtr
event(mojo::Event::New());
123 (base::TimeTicks() + base::TimeDelta::FromMilliseconds(time_ms
))
125 event
->action
= MotionEventActionToEventType(masked_action
);
126 if (event
->action
== mojo::EVENT_TYPE_UNKNOWN
)
129 event
->pointer_data
= mojo::PointerData::New();
130 event
->pointer_data
->pointer_id
= pointer_id
;
131 event
->pointer_data
->x
= x
;
132 event
->pointer_data
->y
= y
;
133 event
->pointer_data
->screen_x
= x
;
134 event
->pointer_data
->screen_y
= y
;
135 event
->pointer_data
->pressure
= pressure
;
136 event
->pointer_data
->radius_major
= touch_major
;
137 event
->pointer_data
->radius_minor
= touch_minor
;
138 event
->pointer_data
->orientation
= orientation
;
139 event
->pointer_data
->horizontal_wheel
= h_wheel
;
140 event
->pointer_data
->vertical_wheel
= v_wheel
;
141 delegate_
->OnEvent(event
.Pass());
146 bool PlatformViewportAndroid::KeyEvent(JNIEnv
* env
,
150 jint unicode_character
) {
151 ui::KeyEvent
event(pressed
? ui::ET_KEY_PRESSED
: ui::ET_KEY_RELEASED
,
152 ui::KeyboardCodeFromAndroidKeyCode(key_code
), 0);
153 event
.set_platform_keycode(key_code
);
154 delegate_
->OnEvent(mojo::Event::From(event
));
155 if (pressed
&& unicode_character
) {
156 ui::KeyEvent
char_event(unicode_character
,
157 ui::KeyboardCodeFromAndroidKeyCode(key_code
), 0);
158 char_event
.set_platform_keycode(key_code
);
159 delegate_
->OnEvent(mojo::Event::From(char_event
));
164 ////////////////////////////////////////////////////////////////////////////////
165 // PlatformViewportAndroid, PlatformViewport implementation:
167 void PlatformViewportAndroid::Init(const gfx::Rect
& bounds
) {
168 JNIEnv
* env
= base::android::AttachCurrentThread();
169 java_platform_viewport_android_
= JavaObjectWeakGlobalRef(
170 env
, Java_PlatformViewportAndroid_createForActivity(
171 env
, base::android::GetApplicationContext(),
172 reinterpret_cast<jlong
>(this)).obj());
175 void PlatformViewportAndroid::Show() {
176 // Nothing to do. View is created visible.
179 void PlatformViewportAndroid::Hide() {
180 // Nothing to do. View is always visible.
183 void PlatformViewportAndroid::Close() {
184 // TODO(beng): close activity containing MojoView?
186 // TODO(beng): perform this in response to view destruction.
187 delegate_
->OnDestroyed();
190 gfx::Size
PlatformViewportAndroid::GetSize() {
191 return metrics_
->size
.To
<gfx::Size
>();
194 void PlatformViewportAndroid::SetBounds(const gfx::Rect
& bounds
) {
198 ////////////////////////////////////////////////////////////////////////////////
199 // PlatformViewportAndroid, private:
201 void PlatformViewportAndroid::ReleaseWindow() {
202 ANativeWindow_release(window_
);
206 ////////////////////////////////////////////////////////////////////////////////
207 // PlatformViewport, public:
210 scoped_ptr
<PlatformViewport
> PlatformViewport::Create(Delegate
* delegate
) {
211 return scoped_ptr
<PlatformViewport
>(
212 new PlatformViewportAndroid(delegate
)).Pass();
215 } // namespace native_viewport