| Index: ui/platform_window/android/platform_window_android.cc
|
| diff --git a/ui/platform_window/android/platform_window_android.cc b/ui/platform_window/android/platform_window_android.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6d6af405c4b0455261a32125f1f726bc729de9f9
|
| --- /dev/null
|
| +++ b/ui/platform_window/android/platform_window_android.cc
|
| @@ -0,0 +1,216 @@
|
| +// 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.
|
| +
|
| +#include "ui/platform_window/android/platform_window_android.h"
|
| +
|
| +#include <android/input.h>
|
| +#include <android/native_window_jni.h>
|
| +
|
| +#include "base/android/jni_android.h"
|
| +#include "jni/PlatformWindowAndroid_jni.h"
|
| +#include "ui/events/event.h"
|
| +#include "ui/events/keycodes/keyboard_code_conversion_android.h"
|
| +#include "ui/gfx/geometry/point.h"
|
| +#include "ui/platform_window/platform_window_delegate.h"
|
| +
|
| +namespace ui {
|
| +
|
| +namespace {
|
| +
|
| +ui::EventType MotionEventActionToEventType(jint action) {
|
| + switch (action) {
|
| + case AMOTION_EVENT_ACTION_DOWN:
|
| + case AMOTION_EVENT_ACTION_POINTER_DOWN:
|
| + return ui::ET_TOUCH_PRESSED;
|
| + case AMOTION_EVENT_ACTION_UP:
|
| + case AMOTION_EVENT_ACTION_POINTER_UP:
|
| + return ui::ET_TOUCH_RELEASED;
|
| + case AMOTION_EVENT_ACTION_MOVE:
|
| + return ui::ET_TOUCH_MOVED;
|
| + case AMOTION_EVENT_ACTION_CANCEL:
|
| + return ui::ET_TOUCH_CANCELLED;
|
| + 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 ui::ET_UNKNOWN;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// PlatformWindowAndroid, public:
|
| +
|
| +// static
|
| +bool PlatformWindowAndroid::Register(JNIEnv* env) {
|
| + return RegisterNativesImpl(env);
|
| +}
|
| +
|
| +PlatformWindowAndroid::PlatformWindowAndroid(PlatformWindowDelegate* delegate)
|
| + : delegate_(delegate),
|
| + window_(NULL),
|
| + id_generator_(0),
|
| + weak_factory_(this) {
|
| +}
|
| +
|
| +PlatformWindowAndroid::~PlatformWindowAndroid() {
|
| + if (window_)
|
| + ReleaseWindow();
|
| + if (!java_platform_window_android_.is_empty()) {
|
| + JNIEnv* env = base::android::AttachCurrentThread();
|
| + Java_PlatformWindowAndroid_detach(
|
| + env, java_platform_window_android_.get(env).obj());
|
| + }
|
| +}
|
| +
|
| +void PlatformWindowAndroid::Destroy(JNIEnv* env, jobject obj) {
|
| + delegate_->OnClosed();
|
| +}
|
| +
|
| +void PlatformWindowAndroid::SurfaceCreated(JNIEnv* env,
|
| + jobject obj,
|
| + jobject jsurface,
|
| + float device_pixel_ratio) {
|
| + 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 PlatformWindowAndroid::SurfaceDestroyed(JNIEnv* env, jobject obj) {
|
| + DCHECK(window_);
|
| + ReleaseWindow();
|
| + // TODO(sad): Call OnClosed() here?
|
| +}
|
| +
|
| +void PlatformWindowAndroid::SurfaceSetSize(JNIEnv* env,
|
| + jobject obj,
|
| + jint width,
|
| + jint height,
|
| + jfloat density) {
|
| + size_ = gfx::Size(static_cast<int>(width), static_cast<int>(height));
|
| + delegate_->OnBoundsChanged(gfx::Rect(size_));
|
| +}
|
| +
|
| +bool PlatformWindowAndroid::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) {
|
| + ui::EventType event_type = MotionEventActionToEventType(masked_action);
|
| + if (event_type == ui::ET_UNKNOWN)
|
| + return false;
|
| + ui::TouchEvent touch(event_type, gfx::PointF(x, y), ui::EF_NONE, pointer_id,
|
| + base::TimeDelta::FromMilliseconds(time_ms),
|
| + touch_major, touch_minor, orientation, pressure);
|
| + delegate_->DispatchEvent(&touch);
|
| + return true;
|
| +}
|
| +
|
| +bool PlatformWindowAndroid::KeyEvent(JNIEnv* env,
|
| + jobject obj,
|
| + bool pressed,
|
| + jint key_code,
|
| + jint unicode_character) {
|
| + ui::KeyEvent key_event(pressed ? ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED,
|
| + ui::KeyboardCodeFromAndroidKeyCode(key_code), 0);
|
| + key_event.set_platform_keycode(key_code);
|
| + delegate_->DispatchEvent(&key_event);
|
| + if (pressed && unicode_character) {
|
| + ui::KeyEvent char_event(unicode_character,
|
| + ui::KeyboardCodeFromAndroidKeyCode(key_code), 0);
|
| + char_event.set_platform_keycode(key_code);
|
| + delegate_->DispatchEvent(&char_event);
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +void PlatformWindowAndroid::ReleaseWindow() {
|
| + ANativeWindow_release(window_);
|
| + window_ = NULL;
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// PlatformWindowAndroid, PlatformWindow implementation:
|
| +
|
| +void PlatformWindowAndroid::Show() {
|
| + if (!java_platform_window_android_.is_empty())
|
| + return;
|
| + JNIEnv* env = base::android::AttachCurrentThread();
|
| + java_platform_window_android_ = JavaObjectWeakGlobalRef(
|
| + env, Java_PlatformWindowAndroid_createForActivity(
|
| + env, base::android::GetApplicationContext(),
|
| + reinterpret_cast<jlong>(this)).obj());
|
| +}
|
| +
|
| +void PlatformWindowAndroid::Hide() {
|
| + // Nothing to do. View is always visible.
|
| +}
|
| +
|
| +void PlatformWindowAndroid::Close() {
|
| + delegate_->OnCloseRequest();
|
| +}
|
| +
|
| +void PlatformWindowAndroid::SetBounds(const gfx::Rect& bounds) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +gfx::Rect PlatformWindowAndroid::GetBounds() {
|
| + return gfx::Rect(size_);
|
| +}
|
| +
|
| +void PlatformWindowAndroid::SetCapture() {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void PlatformWindowAndroid::ReleaseCapture() {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void PlatformWindowAndroid::ToggleFullscreen() {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void PlatformWindowAndroid::Maximize() {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void PlatformWindowAndroid::Minimize() {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void PlatformWindowAndroid::Restore() {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void PlatformWindowAndroid::SetCursor(PlatformCursor cursor) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void PlatformWindowAndroid::MoveCursorTo(const gfx::Point& location) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void PlatformWindowAndroid::ConfineCursorToBounds(const gfx::Rect& bounds) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +} // namespace ui
|
|
|