From 3ee69c99e1eac254adeb8e1ad71294a23500eee6 Mon Sep 17 00:00:00 2001 From: Jim Chen Date: Fri, 8 Jul 2016 11:39:09 -0400 Subject: [PATCH] Bug 1283844 - Implement SENSOR_EVENT as native call; r=snorp Remove SENSOR_EVENT from GeckoEvent and implement it as a native method in GeckoAppShell that is invoked by the sensor event listener in GeckoAppShell. --- .../java/org/mozilla/gecko/GeckoAppShell.java | 82 +++++++++++++- .../java/org/mozilla/gecko/GeckoEvent.java | 103 ------------------ widget/android/AndroidJavaWrappers.cpp | 10 -- widget/android/AndroidJavaWrappers.h | 1 - widget/android/nsAppShell.cpp | 92 ++++++++-------- 5 files changed, 127 insertions(+), 161 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java b/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java index b9dde5a9d85e..60a320c5355c 100644 --- a/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java @@ -534,14 +534,94 @@ public class GeckoAppShell am.cancel(pi); } + @WrapForJNI + /* package */ static native void onSensorChanged(int hal_type, float x, float y, float z, + float w, int accuracy, long time); + private static class DefaultListeners implements SensorEventListener { @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } + private static int HalSensorAccuracyFor(int androidAccuracy) { + switch (androidAccuracy) { + case SensorManager.SENSOR_STATUS_UNRELIABLE: + return GeckoHalDefines.SENSOR_ACCURACY_UNRELIABLE; + case SensorManager.SENSOR_STATUS_ACCURACY_LOW: + return GeckoHalDefines.SENSOR_ACCURACY_LOW; + case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM: + return GeckoHalDefines.SENSOR_ACCURACY_MED; + case SensorManager.SENSOR_STATUS_ACCURACY_HIGH: + return GeckoHalDefines.SENSOR_ACCURACY_HIGH; + } + return GeckoHalDefines.SENSOR_ACCURACY_UNKNOWN; + } + @Override public void onSensorChanged(SensorEvent s) { - GeckoAppShell.sendEventToGecko(GeckoEvent.createSensorEvent(s)); + int sensor_type = s.sensor.getType(); + int hal_type = 0; + float x = 0.0f, y = 0.0f, z = 0.0f, w = 0.0f; + final int accuracy = HalSensorAccuracyFor(s.accuracy); + // SensorEvent timestamp is in nanoseconds, Gecko expects microseconds. + final long time = s.timestamp / 1000; + + switch (sensor_type) { + case Sensor.TYPE_ACCELEROMETER: + case Sensor.TYPE_LINEAR_ACCELERATION: + case Sensor.TYPE_ORIENTATION: + if (sensor_type == Sensor.TYPE_ACCELEROMETER) { + hal_type = GeckoHalDefines.SENSOR_ACCELERATION; + } else if (sensor_type == Sensor.TYPE_LINEAR_ACCELERATION) { + hal_type = GeckoHalDefines.SENSOR_LINEAR_ACCELERATION; + } else { + hal_type = GeckoHalDefines.SENSOR_ORIENTATION; + } + x = s.values[0]; + y = s.values[1]; + z = s.values[2]; + break; + + case Sensor.TYPE_GYROSCOPE: + hal_type = GeckoHalDefines.SENSOR_GYROSCOPE; + x = (float) Math.toDegrees(s.values[0]); + y = (float) Math.toDegrees(s.values[1]); + z = (float) Math.toDegrees(s.values[2]); + break; + + case Sensor.TYPE_PROXIMITY: + hal_type = GeckoHalDefines.SENSOR_PROXIMITY; + x = s.values[0]; + z = s.sensor.getMaximumRange(); + break; + + case Sensor.TYPE_LIGHT: + hal_type = GeckoHalDefines.SENSOR_LIGHT; + x = s.values[0]; + break; + + case Sensor.TYPE_ROTATION_VECTOR: + case Sensor.TYPE_GAME_ROTATION_VECTOR: // API >= 18 + hal_type = (sensor_type == Sensor.TYPE_ROTATION_VECTOR ? + GeckoHalDefines.SENSOR_ROTATION_VECTOR : + GeckoHalDefines.SENSOR_GAME_ROTATION_VECTOR); + x = s.values[0]; + y = s.values[1]; + z = s.values[2]; + if (s.values.length >= 4) { + w = s.values[3]; + } else { + // s.values[3] was optional in API <= 18, so we need to compute it + // The values form a unit quaternion, so we can compute the angle of + // rotation purely based on the given 3 values. + w = 1.0f - s.values[0] * s.values[0] - + s.values[1] * s.values[1] - s.values[2] * s.values[2]; + w = (w > 0.0f) ? (float) Math.sqrt(w) : 0.0f; + } + break; + } + + GeckoAppShell.onSensorChanged(hal_type, x, y, z, w, accuracy, time); } } diff --git a/mobile/android/base/java/org/mozilla/gecko/GeckoEvent.java b/mobile/android/base/java/org/mozilla/gecko/GeckoEvent.java index 3adf6146b8dc..c744c634e447 100644 --- a/mobile/android/base/java/org/mozilla/gecko/GeckoEvent.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoEvent.java @@ -15,9 +15,6 @@ import org.mozilla.gecko.gfx.ImmutableViewportMetrics; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorManager; import android.location.Address; import android.location.Location; import android.os.SystemClock; @@ -71,7 +68,6 @@ public class GeckoEvent { public enum NativeGeckoEvent { NATIVE_POKE(0), MOTION_EVENT(2), - SENSOR_EVENT(3), LOCATION_EVENT(5), LOAD_URI(12), NOOP(15), @@ -347,105 +343,6 @@ public class GeckoEvent { } } - private static int HalSensorAccuracyFor(int androidAccuracy) { - switch (androidAccuracy) { - case SensorManager.SENSOR_STATUS_UNRELIABLE: - return GeckoHalDefines.SENSOR_ACCURACY_UNRELIABLE; - case SensorManager.SENSOR_STATUS_ACCURACY_LOW: - return GeckoHalDefines.SENSOR_ACCURACY_LOW; - case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM: - return GeckoHalDefines.SENSOR_ACCURACY_MED; - case SensorManager.SENSOR_STATUS_ACCURACY_HIGH: - return GeckoHalDefines.SENSOR_ACCURACY_HIGH; - } - return GeckoHalDefines.SENSOR_ACCURACY_UNKNOWN; - } - - public static GeckoEvent createSensorEvent(SensorEvent s) { - int sensor_type = s.sensor.getType(); - GeckoEvent event = null; - - switch (sensor_type) { - - case Sensor.TYPE_ACCELEROMETER: - event = GeckoEvent.get(NativeGeckoEvent.SENSOR_EVENT); - event.mFlags = GeckoHalDefines.SENSOR_ACCELERATION; - event.mMetaState = HalSensorAccuracyFor(s.accuracy); - event.mX = s.values[0]; - event.mY = s.values[1]; - event.mZ = s.values[2]; - break; - - case Sensor.TYPE_LINEAR_ACCELERATION: - event = GeckoEvent.get(NativeGeckoEvent.SENSOR_EVENT); - event.mFlags = GeckoHalDefines.SENSOR_LINEAR_ACCELERATION; - event.mMetaState = HalSensorAccuracyFor(s.accuracy); - event.mX = s.values[0]; - event.mY = s.values[1]; - event.mZ = s.values[2]; - break; - - case Sensor.TYPE_ORIENTATION: - event = GeckoEvent.get(NativeGeckoEvent.SENSOR_EVENT); - event.mFlags = GeckoHalDefines.SENSOR_ORIENTATION; - event.mMetaState = HalSensorAccuracyFor(s.accuracy); - event.mX = s.values[0]; - event.mY = s.values[1]; - event.mZ = s.values[2]; - break; - - case Sensor.TYPE_GYROSCOPE: - event = GeckoEvent.get(NativeGeckoEvent.SENSOR_EVENT); - event.mFlags = GeckoHalDefines.SENSOR_GYROSCOPE; - event.mMetaState = HalSensorAccuracyFor(s.accuracy); - event.mX = Math.toDegrees(s.values[0]); - event.mY = Math.toDegrees(s.values[1]); - event.mZ = Math.toDegrees(s.values[2]); - break; - - case Sensor.TYPE_PROXIMITY: - event = GeckoEvent.get(NativeGeckoEvent.SENSOR_EVENT); - event.mFlags = GeckoHalDefines.SENSOR_PROXIMITY; - event.mMetaState = HalSensorAccuracyFor(s.accuracy); - event.mX = s.values[0]; - event.mY = 0; - event.mZ = s.sensor.getMaximumRange(); - break; - - case Sensor.TYPE_LIGHT: - event = GeckoEvent.get(NativeGeckoEvent.SENSOR_EVENT); - event.mFlags = GeckoHalDefines.SENSOR_LIGHT; - event.mMetaState = HalSensorAccuracyFor(s.accuracy); - event.mX = s.values[0]; - break; - - case Sensor.TYPE_ROTATION_VECTOR: - case Sensor.TYPE_GAME_ROTATION_VECTOR: // API >= 18 - event = GeckoEvent.get(NativeGeckoEvent.SENSOR_EVENT); - event.mFlags = (sensor_type == Sensor.TYPE_ROTATION_VECTOR ? - GeckoHalDefines.SENSOR_ROTATION_VECTOR : - GeckoHalDefines.SENSOR_GAME_ROTATION_VECTOR); - event.mMetaState = HalSensorAccuracyFor(s.accuracy); - event.mX = s.values[0]; - event.mY = s.values[1]; - event.mZ = s.values[2]; - if (s.values.length >= 4) { - event.mW = s.values[3]; - } else { - // s.values[3] was optional in API <= 18, so we need to compute it - // The values form a unit quaternion, so we can compute the angle of - // rotation purely based on the given 3 values. - event.mW = 1 - s.values[0] * s.values[0] - s.values[1] * s.values[1] - s.values[2] * s.values[2]; - event.mW = (event.mW > 0.0) ? Math.sqrt(event.mW) : 0.0; - } - break; - } - - // SensorEvent timestamp is in nanoseconds, Gecko expects microseconds. - event.mTime = s.timestamp / 1000; - return event; - } - public static GeckoEvent createLocationEvent(Location l) { GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.LOCATION_EVENT); event.mLocation = l; diff --git a/widget/android/AndroidJavaWrappers.cpp b/widget/android/AndroidJavaWrappers.cpp index 7f00490538b6..8e4dcad787da 100644 --- a/widget/android/AndroidJavaWrappers.cpp +++ b/widget/android/AndroidJavaWrappers.cpp @@ -366,16 +366,6 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj) break; - case SENSOR_EVENT: - mX = jenv->GetDoubleField(jobj, jXField); - mY = jenv->GetDoubleField(jobj, jYField); - mZ = jenv->GetDoubleField(jobj, jZField); - mW = jenv->GetDoubleField(jobj, jWField); - mFlags = jenv->GetIntField(jobj, jFlagsField); - mMetaState = jenv->GetIntField(jobj, jMetaStateField); - mTime = jenv->GetLongField(jobj, jTimeField); - break; - case LOCATION_EVENT: { jobject location = jenv->GetObjectField(jobj, jLocationField); mGeoPosition = AndroidLocation::CreateGeoPosition(jenv, location); diff --git a/widget/android/AndroidJavaWrappers.h b/widget/android/AndroidJavaWrappers.h index b3d916afc403..422fbbf67d3f 100644 --- a/widget/android/AndroidJavaWrappers.h +++ b/widget/android/AndroidJavaWrappers.h @@ -623,7 +623,6 @@ public: enum { NATIVE_POKE = 0, MOTION_EVENT = 2, - SENSOR_EVENT = 3, LOCATION_EVENT = 5, LOAD_URI = 12, NOOP = 15, diff --git a/widget/android/nsAppShell.cpp b/widget/android/nsAppShell.cpp index f100d85ca44a..236288ae53a2 100644 --- a/widget/android/nsAppShell.cpp +++ b/widget/android/nsAppShell.cpp @@ -312,6 +312,52 @@ public: obsServ->NotifyObservers(nullptr, aTopic->ToCString().get(), aData ? aData->ToString().get() : nullptr); } + + static void OnSensorChanged(int32_t aType, float aX, float aY, float aZ, + float aW, int32_t aAccuracy, int64_t aTime) + { + AutoTArray values; + + switch (aType) { + // Bug 938035, transfer HAL data for orientation sensor to meet w3c + // spec, ex: HAL report alpha=90 means East but alpha=90 means West + // in w3c spec + case hal::SENSOR_ORIENTATION: + values.AppendElement(360.0f - aX); + values.AppendElement(-aY); + values.AppendElement(-aZ); + break; + + case hal::SENSOR_LINEAR_ACCELERATION: + case hal::SENSOR_ACCELERATION: + case hal::SENSOR_GYROSCOPE: + case hal::SENSOR_PROXIMITY: + values.AppendElement(aX); + values.AppendElement(aY); + values.AppendElement(aZ); + break; + + case hal::SENSOR_LIGHT: + values.AppendElement(aX); + break; + + case hal::SENSOR_ROTATION_VECTOR: + case hal::SENSOR_GAME_ROTATION_VECTOR: + values.AppendElement(aX); + values.AppendElement(aY); + values.AppendElement(aZ); + values.AppendElement(aW); + break; + + default: + __android_log_print(ANDROID_LOG_ERROR, "Gecko", + "Unknown sensor type %d", aType); + } + + hal::SensorData sdata(hal::SensorType(aType), aTime, values, + hal::SensorAccuracyType(aAccuracy)); + hal::NotifySensorChange(sdata); + } }; nsAppShell::nsAppShell() @@ -623,52 +669,6 @@ nsAppShell::LegacyGeckoEvent::Run() nsAppShell::Get()->NativeEventCallback(); break; - case AndroidGeckoEvent::SENSOR_EVENT: { - AutoTArray values; - mozilla::hal::SensorType type = (mozilla::hal::SensorType) curEvent->Flags(); - - switch (type) { - // Bug 938035, transfer HAL data for orientation sensor to meet w3c - // spec, ex: HAL report alpha=90 means East but alpha=90 means West - // in w3c spec - case hal::SENSOR_ORIENTATION: - values.AppendElement(360 -curEvent->X()); - values.AppendElement(-curEvent->Y()); - values.AppendElement(-curEvent->Z()); - break; - case hal::SENSOR_LINEAR_ACCELERATION: - case hal::SENSOR_ACCELERATION: - case hal::SENSOR_GYROSCOPE: - case hal::SENSOR_PROXIMITY: - values.AppendElement(curEvent->X()); - values.AppendElement(curEvent->Y()); - values.AppendElement(curEvent->Z()); - break; - - case hal::SENSOR_LIGHT: - values.AppendElement(curEvent->X()); - break; - - case hal::SENSOR_ROTATION_VECTOR: - case hal::SENSOR_GAME_ROTATION_VECTOR: - values.AppendElement(curEvent->X()); - values.AppendElement(curEvent->Y()); - values.AppendElement(curEvent->Z()); - values.AppendElement(curEvent->W()); - break; - - default: - __android_log_print(ANDROID_LOG_ERROR, - "Gecko", "### SENSOR_EVENT fired, but type wasn't known %d", - type); - } - - const hal::SensorAccuracyType &accuracy = (hal::SensorAccuracyType) curEvent->MetaState(); - hal::SensorData sdata(type, curEvent->Time(), values, accuracy); - hal::NotifySensorChange(sdata); - } - break; - case AndroidGeckoEvent::LOCATION_EVENT: { if (!gLocationCallback) break;