summaryrefslogtreecommitdiff
path: root/chromium/content/browser/android/touch_point.cc
blob: 1a10e6ecfca5e5e7fd5361ac221b014a5fcc69e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Copyright (c) 2012 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 "content/browser/android/touch_point.h"

#include "base/debug/debugger.h"
#include "base/logging.h"
#include "base/time/time.h"

#include "jni/TouchPoint_jni.h"

using WebKit::WebTouchEvent;
using WebKit::WebTouchPoint;

namespace {

void MaybeAddTouchPoint(JNIEnv* env,
                        jobject pt,
                        float dpi_scale,
                        WebKit::WebTouchEvent& event) {
  WebTouchPoint::State state = static_cast<WebTouchPoint::State>(
      Java_TouchPoint_getState(env, pt));
  if (state == WebTouchPoint::StateUndefined)
    return;

  // When generating a cancel event from an event of a different type, the
  // touch points are out of sync, so we ensure the points are marked as
  // canceled as well.
  if (event.type == WebTouchEvent::TouchCancel)
    state = WebTouchPoint::StateCancelled;

  // Record the current number of points in the WebTouchEvent
  const int idx = event.touchesLength;
  DCHECK_LT(idx, WebKit::WebTouchEvent::touchesLengthCap);

  WebTouchPoint wtp;
  wtp.id = Java_TouchPoint_getId(env, pt);
  wtp.state = state;
  wtp.position.x = Java_TouchPoint_getX(env, pt) / dpi_scale;
  wtp.position.y = Java_TouchPoint_getY(env, pt) / dpi_scale;
  // TODO(joth): Raw event co-ordinates.
  wtp.screenPosition = wtp.position;
  wtp.force = Java_TouchPoint_getPressure(env, pt);

  // TODO(djsollen): WebKit stores touch point size as a pair of radii, which
  // are integers.  We receive touch point size from Android as a float
  // between 0 and 1 and interpret 'size' as an elliptical area.  We convert
  // size to a radius and then scale up to avoid truncating away all of the
  // data. W3C spec is for the radii to be in units of screen pixels. Need to
  // change.
  const static double PI = 3.1415926;
  const static double SCALE_FACTOR = 1024.0;
  const int radius = static_cast<int>(
      (sqrt(Java_TouchPoint_getSize(env, pt)) / PI) * SCALE_FACTOR);
  wtp.radiusX = radius / dpi_scale;
  wtp.radiusY = radius / dpi_scale;
  // Since our radii are equal, a rotation angle doesn't mean anything.
  wtp.rotationAngle = 0.0;

  // Add the newly created WebTouchPoint to the event
  event.touches[idx] = wtp;
  ++(event.touchesLength);
}

}  // namespace

namespace content {

void TouchPoint::BuildWebTouchEvent(JNIEnv* env,
                                    jint type,
                                    jlong time_ms,
                                    float dpi_scale,
                                    jobjectArray pts,
                                    WebKit::WebTouchEvent& event) {
  event.type = static_cast<WebTouchEvent::Type>(type);
  event.timeStampSeconds =
      static_cast<double>(time_ms) / base::Time::kMillisecondsPerSecond;
  int arrayLength = env->GetArrayLength(pts);
  // Loop until either all of the input points have been consumed or the output
  // array has been filled
  for (int i = 0; i < arrayLength; i++) {
    jobject pt = env->GetObjectArrayElement(pts, i);
    MaybeAddTouchPoint(env, pt, dpi_scale, event);
    if (event.touchesLength >= event.touchesLengthCap)
      break;
  }
  DCHECK_GT(event.touchesLength, 0U);
}

static void RegisterConstants(JNIEnv* env) {
   Java_TouchPoint_initializeConstants(
       env,
       WebKit::WebTouchEvent::TouchStart,
       WebKit::WebTouchEvent::TouchMove,
       WebKit::WebTouchEvent::TouchEnd,
       WebKit::WebTouchEvent::TouchCancel,
       WebKit::WebTouchPoint::StateUndefined,
       WebKit::WebTouchPoint::StateReleased,
       WebKit::WebTouchPoint::StatePressed,
       WebKit::WebTouchPoint::StateMoved,
       WebKit::WebTouchPoint::StateStationary,
       WebKit::WebTouchPoint::StateCancelled);
}

bool RegisterTouchPoint(JNIEnv* env) {
  if (!RegisterNativesImpl(env))
    return false;

  RegisterConstants(env);

  return true;
}

}  // namespace content