summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcore/java/android/webkit/DeviceMotionService.java170
-rw-r--r--core/java/android/webkit/DeviceOrientationManager.java12
-rw-r--r--core/java/android/webkit/WebViewCore.java10
3 files changed, 191 insertions, 1 deletions
diff --git a/core/java/android/webkit/DeviceMotionService.java b/core/java/android/webkit/DeviceMotionService.java
new file mode 100755
index 000000000000..4027c26839a2
--- /dev/null
+++ b/core/java/android/webkit/DeviceMotionService.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+import android.os.Message;
+import android.webkit.DeviceOrientationManager;
+import java.lang.Runnable;
+import java.util.List;
+
+
+final class DeviceMotionService implements SensorEventListener {
+ private DeviceOrientationManager mManager;
+ private boolean mIsRunning;
+ private Handler mHandler;
+ private SensorManager mSensorManager;
+ private Context mContext;
+ private boolean mHaveSentErrorEvent;
+ private Runnable mUpdateRunnable;
+ private float mLastAcceleration[];
+
+ private static final int INTERVAL_MILLIS = 100;
+
+ public DeviceMotionService(DeviceOrientationManager manager, Context context) {
+ mManager = manager;
+ assert(mManager != null);
+ mContext = context;
+ assert(mContext != null);
+ }
+
+ public void start() {
+ mIsRunning = true;
+ registerForSensor();
+ }
+
+ public void stop() {
+ mIsRunning = false;
+ stopSendingUpdates();
+ unregisterFromSensor();
+ }
+
+ public void suspend() {
+ if (mIsRunning) {
+ stopSendingUpdates();
+ unregisterFromSensor();
+ }
+ }
+
+ public void resume() {
+ if (mIsRunning) {
+ registerForSensor();
+ }
+ }
+
+ private void sendErrorEvent() {
+ assert WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName());
+ // The spec requires that each listener receives the error event only once.
+ if (mHaveSentErrorEvent)
+ return;
+ mHaveSentErrorEvent = true;
+ createHandler();
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ assert WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName());
+ if (mIsRunning) {
+ // The special case of all nulls is used to signify a failure to get data.
+ mManager.onMotionChange(null, null, null, 0.0);
+ }
+ }
+ });
+ }
+
+ private void createHandler() {
+ if (mHandler != null) {
+ return;
+ }
+
+ mHandler = new Handler();
+ mUpdateRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mManager.onMotionChange(new Double(mLastAcceleration[0]),
+ new Double(mLastAcceleration[1]), new Double(mLastAcceleration[2]),
+ INTERVAL_MILLIS);
+ mHandler.postDelayed(mUpdateRunnable, INTERVAL_MILLIS);
+ // Now that we have successfully sent some data, reset whether we've sent an error.
+ mHaveSentErrorEvent = false;
+ }
+ };
+ }
+
+ private void startSendingUpdates() {
+ createHandler();
+ mUpdateRunnable.run();
+ }
+
+ private void stopSendingUpdates() {
+ mHandler.removeCallbacks(mUpdateRunnable);
+ mLastAcceleration = null;
+ }
+
+ private void registerForSensor() {
+ if (!registerForAccelerometerSensor()) {
+ sendErrorEvent();
+ }
+ }
+
+ private SensorManager getSensorManager() {
+ assert WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName());
+ if (mSensorManager == null) {
+ mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
+ }
+ return mSensorManager;
+ }
+
+ private boolean registerForAccelerometerSensor() {
+ List<Sensor> sensors = getSensorManager().getSensorList(Sensor.TYPE_ACCELEROMETER);
+ if (sensors.isEmpty()) {
+ return false;
+ }
+ createHandler();
+ // TODO: Consider handling multiple sensors.
+ return getSensorManager().registerListener(
+ this, sensors.get(0), SensorManager.SENSOR_DELAY_UI, mHandler);
+ }
+
+ private void unregisterFromSensor() {
+ getSensorManager().unregisterListener(this);
+ }
+
+ /**
+ * SensorEventListener implementation.
+ * Callbacks happen on the thread on which we registered - the WebCore thread.
+ */
+ public void onSensorChanged(SensorEvent event) {
+ assert(event.values.length == 3);
+ assert WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName());
+ assert(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER);
+
+ boolean firstData = mLastAcceleration == null;
+ mLastAcceleration = event.values;
+ if (firstData) {
+ startSendingUpdates();
+ }
+ }
+
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ assert WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName());
+ }
+}
diff --git a/core/java/android/webkit/DeviceOrientationManager.java b/core/java/android/webkit/DeviceOrientationManager.java
index aac2f43a2b89..2076a9e72ee0 100644
--- a/core/java/android/webkit/DeviceOrientationManager.java
+++ b/core/java/android/webkit/DeviceOrientationManager.java
@@ -26,7 +26,6 @@ package android.webkit;
*/
public final class DeviceOrientationManager {
private WebViewCore mWebViewCore;
- private DeviceOrientationService mService;
public DeviceOrientationManager(WebViewCore webViewCore) {
mWebViewCore = webViewCore;
@@ -51,6 +50,14 @@ public final class DeviceOrientationManager {
canProvideGamma, gamma);
}
+ // We only provide accelerationIncludingGravity.
+ public void onMotionChange(Double x, Double y, Double z, double interval) {
+ nativeOnMotionChange(mWebViewCore,
+ x != null, x != null ? x.doubleValue() : 0.0,
+ y != null, y != null ? y.doubleValue() : 0.0,
+ z != null, z != null ? z.doubleValue() : 0.0,
+ interval);
+ }
public void onOrientationChange(Double alpha, Double beta, Double gamma) {
nativeOnOrientationChange(mWebViewCore,
alpha != null, alpha != null ? alpha.doubleValue() : 0.0,
@@ -63,6 +70,9 @@ public final class DeviceOrientationManager {
private static native void nativeSetMockOrientation(WebViewCore webViewCore,
boolean canProvideAlpha, double alpha, boolean canProvideBeta, double beta,
boolean canProvideGamma, double gamma);
+ private static native void nativeOnMotionChange(WebViewCore webViewCore,
+ boolean canProvideX, double x, boolean canProvideY, double y,
+ boolean canProvideZ, double z, double interval);
private static native void nativeOnOrientationChange(WebViewCore webViewCore,
boolean canProvideAlpha, double alpha, boolean canProvideBeta, double beta,
boolean canProvideGamma, double gamma);
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 7c089d8500ac..73ead27227d7 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -34,6 +34,7 @@ import android.util.SparseBooleanArray;
import android.view.KeyEvent;
import android.view.SurfaceView;
import android.view.View;
+import android.webkit.DeviceMotionService;
import android.webkit.DeviceOrientationManager;
import android.webkit.DeviceOrientationService;
@@ -120,6 +121,7 @@ final class WebViewCore {
private int mWebkitScrollY = 0;
private DeviceOrientationManager mDeviceOrientationManager = new DeviceOrientationManager(this);
+ private DeviceMotionService mDeviceMotionService;
private DeviceOrientationService mDeviceOrientationService;
// The thread name used to identify the WebCore thread and for use in
@@ -2553,6 +2555,14 @@ final class WebViewCore {
canProvideGamma, gamma);
}
+ protected DeviceMotionService getDeviceMotionService() {
+ if (mDeviceMotionService == null) {
+ mDeviceMotionService =
+ new DeviceMotionService(mDeviceOrientationManager, mContext);
+ }
+ return mDeviceMotionService;
+ }
+
protected DeviceOrientationService getDeviceOrientationService() {
if (mDeviceOrientationService == null) {
mDeviceOrientationService =