Home | History | Annotate | Download | only in native_viewport
      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 
     15 namespace mojo {
     16 
     17 ui::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
     35 bool PlatformViewportAndroid::Register(JNIEnv* env) {
     36   return RegisterNativesImpl(env);
     37 }
     38 
     39 PlatformViewportAndroid::PlatformViewportAndroid(Delegate* delegate)
     40     : delegate_(delegate),
     41       window_(NULL),
     42       id_generator_(0),
     43       weak_factory_(this) {
     44 }
     45 
     46 PlatformViewportAndroid::~PlatformViewportAndroid() {
     47   if (window_)
     48     ReleaseWindow();
     49 }
     50 
     51 void PlatformViewportAndroid::Destroy(JNIEnv* env, jobject obj) {
     52   delegate_->OnDestroyed();
     53 }
     54 
     55 void 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 
     69 void PlatformViewportAndroid::SurfaceDestroyed(JNIEnv* env, jobject obj) {
     70   DCHECK(window_);
     71   ReleaseWindow();
     72 }
     73 
     74 void PlatformViewportAndroid::SurfaceSetSize(JNIEnv* env, jobject obj,
     75                                              jint width, jint height) {
     76   bounds_ = gfx::Rect(width, height);
     77   delegate_->OnBoundsChanged(bounds_);
     78 }
     79 
     80 bool 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 
    100 void 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 
    108 void PlatformViewportAndroid::Show() {
    109   // Nothing to do. View is created visible.
    110 }
    111 
    112 void PlatformViewportAndroid::Hide() {
    113   // Nothing to do. View is always visible.
    114 }
    115 
    116 void 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 
    123 gfx::Size PlatformViewportAndroid::GetSize() {
    124   return bounds_.size();
    125 }
    126 
    127 void PlatformViewportAndroid::SetBounds(const gfx::Rect& bounds) {
    128   NOTIMPLEMENTED();
    129 }
    130 
    131 void PlatformViewportAndroid::SetCapture() {
    132   NOTIMPLEMENTED();
    133 }
    134 
    135 void PlatformViewportAndroid::ReleaseCapture() {
    136   NOTIMPLEMENTED();
    137 }
    138 
    139 ////////////////////////////////////////////////////////////////////////////////
    140 // PlatformViewportAndroid, private:
    141 
    142 void PlatformViewportAndroid::ReleaseWindow() {
    143   ANativeWindow_release(window_);
    144   window_ = NULL;
    145 }
    146 
    147 ////////////////////////////////////////////////////////////////////////////////
    148 // PlatformViewport, public:
    149 
    150 // static
    151 scoped_ptr<PlatformViewport> PlatformViewport::Create(Delegate* delegate) {
    152   return scoped_ptr<PlatformViewport>(
    153       new PlatformViewportAndroid(delegate)).Pass();
    154 }
    155 
    156 }  // namespace mojo
    157