summaryrefslogtreecommitdiff
path: root/core/java/android/webkit/DeviceMotionService.java
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-10-06 14:34:15 +0100
committerSteve Block <steveblock@google.com>2010-10-08 20:26:50 +0100
commitdc82a29b1108622694fb9f1036e2225eafac58c1 (patch)
tree56747a5dc89b9f7f3dc9d5ba2699ff023fb876f2 /core/java/android/webkit/DeviceMotionService.java
parentb5c564fed2aa3b0c6b4b4f3289532f5f00ce4eca (diff)
Implement DeviceMotionEvent
Requires a corresponding change in external/webkit ... https://android-git.corp.google.com/g/72906 Bug: 2495651 Change-Id: I60b2fc5a9fce459c3cef76b3b634485dfb276eae
Diffstat (limited to 'core/java/android/webkit/DeviceMotionService.java')
-rwxr-xr-xcore/java/android/webkit/DeviceMotionService.java170
1 files changed, 170 insertions, 0 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());
+ }
+}