Implement DeviceMotionEvent

Requires a corresponding change in external/webkit ...
https://android-git.corp.google.com/g/72906

Bug: 2495651
Change-Id: I60b2fc5a9fce459c3cef76b3b634485dfb276eae
This commit is contained in:
Steve Block
2010-10-06 14:34:15 +01:00
parent b5c564fed2
commit dc82a29b11
3 changed files with 191 additions and 1 deletions

View File

@@ -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());
}
}

View File

@@ -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);

View File

@@ -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 =