summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/app/android/content_jni_registrar.cc2
-rw-r--r--content/browser/android/touch_point.cc108
-rw-r--r--content/browser/android/touch_point.h27
-rw-r--r--content/content_browser.gypi2
-rw-r--r--content/content_jni.gypi2
-rw-r--r--content/public/android/java/org/chromium/content/browser/TouchPoint.java144
6 files changed, 285 insertions, 0 deletions
diff --git a/content/app/android/content_jni_registrar.cc b/content/app/android/content_jni_registrar.cc
index a9fe08d..9f858b9 100644
--- a/content/app/android/content_jni_registrar.cc
+++ b/content/app/android/content_jni_registrar.cc
@@ -14,6 +14,7 @@
#include "content/browser/android/device_info.h"
#include "content/browser/android/download_controller.h"
#include "content/browser/android/sandboxed_process_launcher.h"
+#include "content/browser/android/touch_point.h"
#include "content/common/android/command_line.h"
#include "content/common/android/surface_callback.h"
#include "content/common/android/trace_event_binding.h"
@@ -32,6 +33,7 @@ base::android::RegistrationMethod kContentRegisteredMethods[] = {
{ "SandboxedProcessLauncher", content::RegisterSandboxedProcessLauncher },
{ "SandboxedProcessService", content::RegisterSandboxedProcessService },
{ "SurfaceCallback", content::RegisterSurfaceCallback },
+ { "TouchPoint", content::RegisterTouchPoint },
{ "TraceEvent", RegisterTraceEvent },
};
diff --git a/content/browser/android/touch_point.cc b/content/browser/android/touch_point.cc
new file mode 100644
index 0000000..17d888d
--- /dev/null
+++ b/content/browser/android/touch_point.cc
@@ -0,0 +1,108 @@
+// 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/time.h"
+#include "base/logging.h"
+
+#include "jni/touch_point_jni.h"
+
+using WebKit::WebTouchEvent;
+using WebKit::WebTouchPoint;
+
+namespace {
+
+void MaybeAddTouchPoint(JNIEnv* env, jobject pt, 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);
+ wtp.position.y = Java_TouchPoint_getY(env, pt);
+ // 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;
+ wtp.radiusY = radius;
+ // 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,
+ 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, 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
diff --git a/content/browser/android/touch_point.h b/content/browser/android/touch_point.h
new file mode 100644
index 0000000..7bbc379
--- /dev/null
+++ b/content/browser/android/touch_point.h
@@ -0,0 +1,27 @@
+// 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.
+
+#ifndef CONTENT_BROWSER_ANDROID_TOUCH_POINT_H_
+#define CONTENT_BROWSER_ANDROID_TOUCH_POINT_H_
+#pragma once
+
+#include <jni.h>
+
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
+
+namespace content {
+
+// This class provides a helper method to convert a java object array of touch
+// events into a WebKit::WebTouchEvent.
+class TouchPoint {
+ public:
+ static void BuildWebTouchEvent(JNIEnv* env, jint type, jlong time_ms,
+ jobjectArray pts, WebKit::WebTouchEvent& event);
+};
+
+bool RegisterTouchPoint(JNIEnv* env);
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_ANDROID_CHROME_VIEW_H_
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index ce0439d..4d8dbd7 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -201,6 +201,8 @@
'browser/android/download_controller.h',
'browser/android/sandboxed_process_launcher.cc',
'browser/android/sandboxed_process_launcher.h',
+ 'browser/android/touch_point.cc',
+ 'browser/android/touch_point.h',
'browser/appcache/appcache_dispatcher_host.cc',
'browser/appcache/appcache_dispatcher_host.h',
'browser/appcache/appcache_frontend_proxy.cc',
diff --git a/content/content_jni.gypi b/content/content_jni.gypi
index 0a97966..0ab5255 100644
--- a/content/content_jni.gypi
+++ b/content/content_jni.gypi
@@ -20,6 +20,7 @@
'public/android/java/org/chromium/content/browser/DownloadController.java',
'public/android/java/org/chromium/content/browser/LocationProvider.java',
'public/android/java/org/chromium/content/browser/SandboxedProcessLauncher.java',
+ 'public/android/java/org/chromium/content/browser/TouchPoint.java',
'public/android/java/org/chromium/content/common/CommandLine.java',
'public/android/java/org/chromium/content/common/SurfaceCallback.java',
'public/android/java/org/chromium/content/common/TraceEvent.java',
@@ -36,6 +37,7 @@
'<(SHARED_INTERMEDIATE_DIR)/content/jni/download_controller_jni.h',
'<(SHARED_INTERMEDIATE_DIR)/content/jni/location_provider_jni.h',
'<(SHARED_INTERMEDIATE_DIR)/content/jni/sandboxed_process_launcher_jni.h',
+ '<(SHARED_INTERMEDIATE_DIR)/content/jni/touch_point_jni.h',
'<(SHARED_INTERMEDIATE_DIR)/content/jni/command_line_jni.h',
'<(SHARED_INTERMEDIATE_DIR)/content/jni/surface_callback_jni.h',
'<(SHARED_INTERMEDIATE_DIR)/content/jni/trace_event_jni.h',
diff --git a/content/public/android/java/org/chromium/content/browser/TouchPoint.java b/content/public/android/java/org/chromium/content/browser/TouchPoint.java
new file mode 100644
index 0000000..66e35b1
--- /dev/null
+++ b/content/public/android/java/org/chromium/content/browser/TouchPoint.java
@@ -0,0 +1,144 @@
+// 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.
+
+package org.chromium.content.browser;
+
+import android.util.Log;
+import android.view.MotionEvent;
+
+import org.chromium.base.CalledByNative;
+
+// This class converts android MotionEvent into an array of touch points so
+// that they can be forwarded to the renderer process.
+class TouchPoint {
+
+ public static final int CONVERSION_ERROR = -1;
+
+ // Type of motion event to send to the native side. The values originate from their
+ // webkit WebInputEvent counterparts, and are set via initializeConstants().
+ private static int TOUCH_EVENT_TYPE_START;
+ private static int TOUCH_EVENT_TYPE_MOVE;
+ private static int TOUCH_EVENT_TYPE_END;
+ private static int TOUCH_EVENT_TYPE_CANCEL;
+
+ // Type of motion event to send to the native side. The values originate from their
+ // webkit WebTouchPoint counterparts, and are set via initializeConstants().
+ private static int TOUCH_POINT_STATE_UNDEFINED;
+ private static int TOUCH_POINT_STATE_RELEASED;
+ private static int TOUCH_POINT_STATE_PRESSED;
+ private static int TOUCH_POINT_STATE_MOVED;
+ private static int TOUCH_POINT_STATE_STATIONARY;
+ private static int TOUCH_POINT_STATE_CANCELLED;
+
+ private final int mState;
+ private final int mId;
+ private final float mX;
+ private final float mY;
+ private final float mSize;
+ private final float mPressure;
+
+ TouchPoint(int state, int id, float x, float y, float size, float pressure) {
+ mState = state;
+ mId = id;
+ mX = x;
+ mY = y;
+ mSize = size;
+ mPressure = pressure;
+ }
+
+ // The following methods are called by native to parse the java TouchPoint
+ // object it has received.
+ @SuppressWarnings("unused")
+ @CalledByNative
+ public int getState() { return mState; }
+
+ @SuppressWarnings("unused")
+ @CalledByNative
+ public int getId() { return mId; }
+
+ @SuppressWarnings("unused")
+ @CalledByNative
+ public int getX() { return (int) mX; }
+
+ @SuppressWarnings("unused")
+ @CalledByNative
+ public int getY() { return (int) mY; }
+
+ @SuppressWarnings("unused")
+ @CalledByNative
+ public double getSize() { return mSize; }
+
+ @SuppressWarnings("unused")
+ @CalledByNative
+ public double getPressure() { return mPressure; }
+
+ // Converts a MotionEvent into an array of touch points.
+ // Returns the WebTouchEvent::Type for the MotionEvent and -1 for failure.
+ public static int createTouchPoints(MotionEvent event, TouchPoint[] pts) {
+ int type;
+ int defaultState;
+
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ type = TOUCH_EVENT_TYPE_START;
+ defaultState = TOUCH_POINT_STATE_PRESSED;
+ break;
+ case MotionEvent.ACTION_MOVE:
+ type = TOUCH_EVENT_TYPE_MOVE;
+ defaultState = TOUCH_POINT_STATE_MOVED;
+ break;
+ case MotionEvent.ACTION_UP:
+ type = TOUCH_EVENT_TYPE_END;
+ defaultState = TOUCH_POINT_STATE_RELEASED;
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ type = TOUCH_EVENT_TYPE_CANCEL;
+ defaultState = TOUCH_POINT_STATE_CANCELLED;
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN: // fall through.
+ case MotionEvent.ACTION_POINTER_UP:
+ type = TOUCH_EVENT_TYPE_MOVE;
+ defaultState = TOUCH_POINT_STATE_STATIONARY;
+ break;
+ default:
+ Log.e("Chromium", "Unknown motion event action: " + event.getActionMasked());
+ return CONVERSION_ERROR;
+ }
+
+ for (int i = 0; i < pts.length; ++i) {
+ int state = defaultState;
+ if (defaultState == TOUCH_POINT_STATE_STATIONARY && event.getActionIndex() == i) {
+ // An additional pointer has started or ended. Map this pointer state as
+ // required, and all other pointers as "stationary".
+ state = event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN ?
+ TOUCH_POINT_STATE_PRESSED : TOUCH_POINT_STATE_RELEASED;
+ }
+ pts[i] = new TouchPoint(state, event.getPointerId(i),
+ event.getX(i), event.getY(i),
+ event.getSize(i), event.getPressure(i));
+ }
+
+ return type;
+ }
+
+ // This method is called by native to initialize all the constants from
+ // their counterparts in WebInputEvent and WebTouchPoint.
+ @SuppressWarnings("unused")
+ @CalledByNative
+ private static void initializeConstants(
+ int touchTypeStart, int touchTypeMove, int touchTypeEnd, int touchTypeCancel,
+ int touchPointUndefined, int touchPointReleased, int touchPointPressed,
+ int touchPointMoved, int touchPointStationary, int touchPointCancelled) {
+ TOUCH_EVENT_TYPE_START = touchTypeStart;
+ TOUCH_EVENT_TYPE_MOVE = touchTypeMove;
+ TOUCH_EVENT_TYPE_END = touchTypeEnd;
+ TOUCH_EVENT_TYPE_CANCEL = touchTypeCancel;
+ TOUCH_POINT_STATE_UNDEFINED = touchPointUndefined;
+ TOUCH_POINT_STATE_RELEASED = touchPointReleased;
+ TOUCH_POINT_STATE_PRESSED = touchPointPressed;
+ TOUCH_POINT_STATE_MOVED = touchPointMoved;
+ TOUCH_POINT_STATE_STATIONARY = touchPointStationary;
+ TOUCH_POINT_STATE_CANCELLED = touchPointCancelled;
+ }
+}