blob: 0eb11410cb946d28390731207adda5f2d9fd8eb2 [file] [log] [blame]
/*
* Copyright (C) 2014 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.hardware.cts.helpers;
import junit.framework.Assert;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
/**
* Helper class that provides a way to identify if movement has been detected in the device.
*
* Notes:
* Alpha is calculated as:
* t / ( t + dT)
* Where
* t - low-pass filter's time-constant
* dT - event delivery rate
*/
public abstract class MovementDetectorHelper implements SensorEventListener {
private static final float MOVEMENT_DETECTION_ACCELERATION_THRESHOLD = 4.0f;
private static final float ALPHA = 0.8f;
private final float[] mGravity = {0.0f, 0.0f, 0.0f};
private final SensorManager mSensorManager;
private final Sensor mAccelerometer;
private boolean mInitialized;
public MovementDetectorHelper(Context context) {
mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
Assert.assertNotNull("SensorManager", mSensorManager);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (mAccelerometer == null) {
throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER);
}
}
public synchronized void start() {
if (mInitialized) {
return;
}
mInitialized = mSensorManager
.registerListener(this, mAccelerometer,SensorManager.SENSOR_DELAY_NORMAL);
Assert.assertTrue(mInitialized);
}
public synchronized void stop() {
if (!mInitialized) {
return;
}
mSensorManager.unregisterListener(this);
mInitialized = false;
}
protected abstract void onMovementDetected();
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
@Override
public void onSensorChanged(SensorEvent event) {
float[] linearAcceleration = {0.0f, 0.0f, 0.0f};
if (mGravity[0] == 0f && mGravity[2] == 0f) {
mGravity[0] = event.values[0];
mGravity[1] = event.values[1];
mGravity[2] = event.values[2];
} else {
// Isolate the force of gravity with the low-pass filter.
mGravity[0] = ALPHA * mGravity[0] + (1 - ALPHA) * event.values[0];
mGravity[1] = ALPHA * mGravity[1] + (1 - ALPHA) * event.values[1];
mGravity[2] = ALPHA * mGravity[2] + (1 - ALPHA) * event.values[2];
}
// Remove the gravity contribution with the high-pass filter.
linearAcceleration[0] = event.values[0] - mGravity[0];
linearAcceleration[1] = event.values[1] - mGravity[1];
linearAcceleration[2] = event.values[2] - mGravity[2];
float totalAcceleration = Math.abs(linearAcceleration[0])
+ Math.abs(linearAcceleration[1])
+ Math.abs(linearAcceleration[2]);
if (totalAcceleration > MOVEMENT_DETECTION_ACCELERATION_THRESHOLD) {
onMovementDetected();
}
}
}