Home | History | Annotate | Download | only in android
      1 // Copyright (c) 2012 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 "content/browser/android/touch_point.h"
      6 
      7 #include "base/debug/debugger.h"
      8 #include "base/logging.h"
      9 #include "base/time/time.h"
     10 
     11 #include "jni/TouchPoint_jni.h"
     12 
     13 using WebKit::WebTouchEvent;
     14 using WebKit::WebTouchPoint;
     15 
     16 namespace {
     17 
     18 void MaybeAddTouchPoint(JNIEnv* env,
     19                         jobject pt,
     20                         float dpi_scale,
     21                         WebKit::WebTouchEvent& event) {
     22   WebTouchPoint::State state = static_cast<WebTouchPoint::State>(
     23       Java_TouchPoint_getState(env, pt));
     24   if (state == WebTouchPoint::StateUndefined)
     25     return;
     26 
     27   // When generating a cancel event from an event of a different type, the
     28   // touch points are out of sync, so we ensure the points are marked as
     29   // canceled as well.
     30   if (event.type == WebTouchEvent::TouchCancel)
     31     state = WebTouchPoint::StateCancelled;
     32 
     33   // Record the current number of points in the WebTouchEvent
     34   const int idx = event.touchesLength;
     35   DCHECK_LT(idx, WebKit::WebTouchEvent::touchesLengthCap);
     36 
     37   WebTouchPoint wtp;
     38   wtp.id = Java_TouchPoint_getId(env, pt);
     39   wtp.state = state;
     40   wtp.position.x = Java_TouchPoint_getX(env, pt) / dpi_scale;
     41   wtp.position.y = Java_TouchPoint_getY(env, pt) / dpi_scale;
     42   // TODO(joth): Raw event co-ordinates.
     43   wtp.screenPosition = wtp.position;
     44   wtp.force = Java_TouchPoint_getPressure(env, pt);
     45 
     46   // TODO(djsollen): WebKit stores touch point size as a pair of radii, which
     47   // are integers.  We receive touch point size from Android as a float
     48   // between 0 and 1 and interpret 'size' as an elliptical area.  We convert
     49   // size to a radius and then scale up to avoid truncating away all of the
     50   // data. W3C spec is for the radii to be in units of screen pixels. Need to
     51   // change.
     52   const static double PI = 3.1415926;
     53   const static double SCALE_FACTOR = 1024.0;
     54   const int radius = static_cast<int>(
     55       (sqrt(Java_TouchPoint_getSize(env, pt)) / PI) * SCALE_FACTOR);
     56   wtp.radiusX = radius / dpi_scale;
     57   wtp.radiusY = radius / dpi_scale;
     58   // Since our radii are equal, a rotation angle doesn't mean anything.
     59   wtp.rotationAngle = 0.0;
     60 
     61   // Add the newly created WebTouchPoint to the event
     62   event.touches[idx] = wtp;
     63   ++(event.touchesLength);
     64 }
     65 
     66 }  // namespace
     67 
     68 namespace content {
     69 
     70 void TouchPoint::BuildWebTouchEvent(JNIEnv* env,
     71                                     jint type,
     72                                     jlong time_ms,
     73                                     float dpi_scale,
     74                                     jobjectArray pts,
     75                                     WebKit::WebTouchEvent& event) {
     76   event.type = static_cast<WebTouchEvent::Type>(type);
     77   event.timeStampSeconds =
     78       static_cast<double>(time_ms) / base::Time::kMillisecondsPerSecond;
     79   int arrayLength = env->GetArrayLength(pts);
     80   // Loop until either all of the input points have been consumed or the output
     81   // array has been filled
     82   for (int i = 0; i < arrayLength; i++) {
     83     jobject pt = env->GetObjectArrayElement(pts, i);
     84     MaybeAddTouchPoint(env, pt, dpi_scale, event);
     85     if (event.touchesLength >= event.touchesLengthCap)
     86       break;
     87   }
     88   DCHECK_GT(event.touchesLength, 0U);
     89 }
     90 
     91 static void RegisterConstants(JNIEnv* env) {
     92    Java_TouchPoint_initializeConstants(
     93        env,
     94        WebKit::WebTouchEvent::TouchStart,
     95        WebKit::WebTouchEvent::TouchMove,
     96        WebKit::WebTouchEvent::TouchEnd,
     97        WebKit::WebTouchEvent::TouchCancel,
     98        WebKit::WebTouchPoint::StateUndefined,
     99        WebKit::WebTouchPoint::StateReleased,
    100        WebKit::WebTouchPoint::StatePressed,
    101        WebKit::WebTouchPoint::StateMoved,
    102        WebKit::WebTouchPoint::StateStationary,
    103        WebKit::WebTouchPoint::StateCancelled);
    104 }
    105 
    106 bool RegisterTouchPoint(JNIEnv* env) {
    107   if (!RegisterNativesImpl(env))
    108     return false;
    109 
    110   RegisterConstants(env);
    111 
    112   return true;
    113 }
    114 
    115 }  // namespace content
    116