1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package android.hardware.cts.helpers; 18 19 import junit.framework.Assert; 20 21 import android.content.Context; 22 import android.hardware.Sensor; 23 import android.hardware.SensorEvent; 24 import android.hardware.SensorEventListener; 25 import android.hardware.SensorManager; 26 27 /** 28 * Helper class that provides a way to identify if movement has been detected in the device. 29 * 30 * Notes: 31 * Alpha is calculated as: 32 * t / ( t + dT) 33 * Where 34 * t - low-pass filter's time-constant 35 * dT - event delivery rate 36 */ 37 public abstract class MovementDetectorHelper implements SensorEventListener { 38 private static final float MOVEMENT_DETECTION_ACCELERATION_THRESHOLD = 4.0f; 39 private static final float ALPHA = 0.8f; 40 41 private final float[] mGravity = {0.0f, 0.0f, 0.0f}; 42 43 private final SensorManager mSensorManager; 44 private final Sensor mAccelerometer; 45 46 private boolean mInitialized; 47 MovementDetectorHelper(Context context)48 public MovementDetectorHelper(Context context) { 49 mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 50 Assert.assertNotNull("SensorManager", mSensorManager); 51 52 mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 53 if (mAccelerometer == null) { 54 throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER); 55 } 56 } 57 start()58 public synchronized void start() { 59 if (mInitialized) { 60 return; 61 } 62 63 mInitialized = mSensorManager 64 .registerListener(this, mAccelerometer,SensorManager.SENSOR_DELAY_NORMAL); 65 Assert.assertTrue(mInitialized); 66 } 67 stop()68 public synchronized void stop() { 69 if (!mInitialized) { 70 return; 71 } 72 73 mSensorManager.unregisterListener(this); 74 mInitialized = false; 75 } 76 onMovementDetected()77 protected abstract void onMovementDetected(); 78 79 @Override onAccuracyChanged(Sensor sensor, int accuracy)80 public void onAccuracyChanged(Sensor sensor, int accuracy) {} 81 82 @Override onSensorChanged(SensorEvent event)83 public void onSensorChanged(SensorEvent event) { 84 float[] linearAcceleration = {0.0f, 0.0f, 0.0f}; 85 86 if (mGravity[0] == 0f && mGravity[2] == 0f) { 87 mGravity[0] = event.values[0]; 88 mGravity[1] = event.values[1]; 89 mGravity[2] = event.values[2]; 90 } else { 91 // Isolate the force of gravity with the low-pass filter. 92 mGravity[0] = ALPHA * mGravity[0] + (1 - ALPHA) * event.values[0]; 93 mGravity[1] = ALPHA * mGravity[1] + (1 - ALPHA) * event.values[1]; 94 mGravity[2] = ALPHA * mGravity[2] + (1 - ALPHA) * event.values[2]; 95 } 96 97 // Remove the gravity contribution with the high-pass filter. 98 linearAcceleration[0] = event.values[0] - mGravity[0]; 99 linearAcceleration[1] = event.values[1] - mGravity[1]; 100 linearAcceleration[2] = event.values[2] - mGravity[2]; 101 102 float totalAcceleration = Math.abs(linearAcceleration[0]) 103 + Math.abs(linearAcceleration[1]) 104 + Math.abs(linearAcceleration[2]); 105 106 if (totalAcceleration > MOVEMENT_DETECTION_ACCELERATION_THRESHOLD) { 107 onMovementDetected(); 108 } 109 } 110 } 111