Add new sensor types.
1. Add uncalibrated gyros and magnetic field sensor. 2. Change max number of events from 3 to 16. 3. Add new APIs for trigger sensors. Change-Id: Ifac5c0024c8e5f88b721e5cd97ff26afaaa36717
This commit is contained in:
@@ -10296,16 +10296,20 @@ package android.hardware {
|
||||
field public static final int TYPE_ACCELEROMETER = 1; // 0x1
|
||||
field public static final int TYPE_ALL = -1; // 0xffffffff
|
||||
field public static final int TYPE_AMBIENT_TEMPERATURE = 13; // 0xd
|
||||
field public static final int TYPE_GAME_ROTATION_VECTOR = 15; // 0xf
|
||||
field public static final int TYPE_GRAVITY = 9; // 0x9
|
||||
field public static final int TYPE_GYROSCOPE = 4; // 0x4
|
||||
field public static final int TYPE_GYROSCOPE_UNCALIBRATED = 16; // 0x10
|
||||
field public static final int TYPE_LIGHT = 5; // 0x5
|
||||
field public static final int TYPE_LINEAR_ACCELERATION = 10; // 0xa
|
||||
field public static final int TYPE_MAGNETIC_FIELD = 2; // 0x2
|
||||
field public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14; // 0xe
|
||||
field public static final deprecated int TYPE_ORIENTATION = 3; // 0x3
|
||||
field public static final int TYPE_PRESSURE = 6; // 0x6
|
||||
field public static final int TYPE_PROXIMITY = 8; // 0x8
|
||||
field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc
|
||||
field public static final int TYPE_ROTATION_VECTOR = 11; // 0xb
|
||||
field public static final int TYPE_SIGNIFICANT_MOTION = 17; // 0x11
|
||||
field public static final deprecated int TYPE_TEMPERATURE = 7; // 0x7
|
||||
}
|
||||
|
||||
@@ -10327,6 +10331,7 @@ package android.hardware {
|
||||
}
|
||||
|
||||
public abstract class SensorManager {
|
||||
method public boolean cancelTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor);
|
||||
method public static float getAltitude(float, float);
|
||||
method public static void getAngleChange(float[], float[], float[]);
|
||||
method public android.hardware.Sensor getDefaultSensor(int);
|
||||
@@ -10342,6 +10347,7 @@ package android.hardware {
|
||||
method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int);
|
||||
method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, android.os.Handler);
|
||||
method public static boolean remapCoordinateSystem(float[], int, int, float[]);
|
||||
method public boolean requestTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor);
|
||||
method public deprecated void unregisterListener(android.hardware.SensorListener);
|
||||
method public deprecated void unregisterListener(android.hardware.SensorListener, int);
|
||||
method public void unregisterListener(android.hardware.SensorEventListener, android.hardware.Sensor);
|
||||
@@ -10405,6 +10411,17 @@ package android.hardware {
|
||||
field public static final float STANDARD_GRAVITY = 9.80665f;
|
||||
}
|
||||
|
||||
public final class TriggerEvent {
|
||||
field public android.hardware.Sensor sensor;
|
||||
field public long timestamp;
|
||||
field public final float[] values;
|
||||
}
|
||||
|
||||
public abstract class TriggerEventListener {
|
||||
ctor public TriggerEventListener();
|
||||
method public abstract void onTrigger(android.hardware.TriggerEvent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.hardware.display {
|
||||
|
||||
@@ -114,11 +114,90 @@ public final class Sensor {
|
||||
/** A constant describing an ambient temperature sensor type */
|
||||
public static final int TYPE_AMBIENT_TEMPERATURE = 13;
|
||||
|
||||
/**
|
||||
/**
|
||||
* A constant describing a magnetic field uncalibrated sensor type. See
|
||||
* {@link android.hardware.SensorEvent#values SensorEvent.values} for more
|
||||
* details.
|
||||
* <p>
|
||||
* No periodic calibration is performed (ie: there are no discontinuities
|
||||
* in the data stream while using this sensor). Assumptions that the
|
||||
* magnetic field is due to the Earth's poles is avoided. Factory calibration
|
||||
* and temperature compensation is still performed.
|
||||
* </p>
|
||||
*/
|
||||
public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14;
|
||||
|
||||
/**
|
||||
* Identical to {@link #TYPE_ROTATION_VECTOR} except that it doesn't
|
||||
* use the geomagnetic field. Therefore the Y axis doesn't
|
||||
* point north, but instead to some other reference, that reference is
|
||||
* allowed to drift by the same order of magnitude as the gyroscope
|
||||
* drift around the Z axis.
|
||||
* <p>
|
||||
* In the ideal case, a phone rotated and returning to the same real-world
|
||||
* orientation should report the same game rotation vector
|
||||
* (without using the earth's geomagnetic field). However, the orientation
|
||||
* may drift somewhat over time.
|
||||
* </p>
|
||||
*/
|
||||
|
||||
public static final int TYPE_GAME_ROTATION_VECTOR = 15;
|
||||
|
||||
/**
|
||||
* A constant describing a gyroscope uncalibrated sensor type. See
|
||||
* {@link android.hardware.SensorEvent#values SensorEvent.values} for more
|
||||
* details.
|
||||
* <p>
|
||||
* No gyro-drift compensation is performed.
|
||||
* Factory calibration and temperature compensation is still applied
|
||||
* to the rate of rotation (angular speeds).
|
||||
* </p>
|
||||
*/
|
||||
public static final int TYPE_GYROSCOPE_UNCALIBRATED = 16;
|
||||
|
||||
/**
|
||||
* A constant describing the significant motion trigger sensor.
|
||||
* See {@link android.hardware.SensorEvent#values} for more details.
|
||||
* <p>
|
||||
* It triggers when an event occurs and then automatically disables
|
||||
* itself. The sensor continues to operate while the device is asleep
|
||||
* and will automatically wake the device to notify when significant
|
||||
* motion is detected. The application does not need to hold any wake
|
||||
* locks for this sensor to trigger.
|
||||
* </p>
|
||||
*/
|
||||
public static final int TYPE_SIGNIFICANT_MOTION = 17;
|
||||
|
||||
/**
|
||||
* A constant describing all sensor types.
|
||||
*/
|
||||
public static final int TYPE_ALL = -1;
|
||||
|
||||
/* Reporting mode constants for sensors. Each sensor will have exactly one
|
||||
reporting mode associated with it. */
|
||||
// Events are reported at a constant rate.
|
||||
static int REPORTING_MODE_CONTINUOUS = 1;
|
||||
|
||||
// Events are reported only when the value changes.
|
||||
static int REPORTING_MODE_ON_CHANGE = 2;
|
||||
|
||||
// Upon detection of an event, the sensor deactivates itself and then sends a single event.
|
||||
static int REPORTING_MODE_ONE_SHOT = 3;
|
||||
|
||||
// Note: This needs to be updated, whenever a new sensor is added.
|
||||
private static int[] sSensorReportingModes = {
|
||||
REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS,
|
||||
REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS,
|
||||
REPORTING_MODE_ON_CHANGE, REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS,
|
||||
REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ON_CHANGE,
|
||||
REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS,
|
||||
REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ONE_SHOT };
|
||||
|
||||
static int getReportingMode(Sensor sensor) {
|
||||
// mType starts from offset 1.
|
||||
return sSensorReportingModes[sensor.mType - 1];
|
||||
}
|
||||
|
||||
/* Some of these fields are set only by the native bindings in
|
||||
* SensorManager.
|
||||
*/
|
||||
@@ -132,7 +211,6 @@ public final class Sensor {
|
||||
private float mPower;
|
||||
private int mMinDelay;
|
||||
|
||||
|
||||
Sensor() {
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,9 @@
|
||||
package android.hardware;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This class represents a {@link android.hardware.Sensor Sensor} event and
|
||||
* holds informations such as the sensor's type, the time-stamp, accuracy and of
|
||||
* course the sensor's {@link SensorEvent#values data}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <u>Definition of the coordinate system used by the SensorEvent API.</u>
|
||||
@@ -67,15 +65,9 @@ public class SensorEvent {
|
||||
* Sensor.TYPE_ACCELEROMETER}:</h4> All values are in SI units (m/s^2)
|
||||
*
|
||||
* <ul>
|
||||
* <p>
|
||||
* values[0]: Acceleration minus Gx on the x-axis
|
||||
* </p>
|
||||
* <p>
|
||||
* values[1]: Acceleration minus Gy on the y-axis
|
||||
* </p>
|
||||
* <p>
|
||||
* values[2]: Acceleration minus Gz on the z-axis
|
||||
* </p>
|
||||
* <li> values[0]: Acceleration minus Gx on the x-axis </li>
|
||||
* <li> values[1]: Acceleration minus Gy on the y-axis </li>
|
||||
* <li> values[2]: Acceleration minus Gz on the z-axis </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
@@ -165,15 +157,9 @@ public class SensorEvent {
|
||||
* definition of positive rotation and does not agree with the definition of
|
||||
* roll given earlier.
|
||||
* <ul>
|
||||
* <p>
|
||||
* values[0]: Angular speed around the x-axis
|
||||
* </p>
|
||||
* <p>
|
||||
* values[1]: Angular speed around the y-axis
|
||||
* </p>
|
||||
* <p>
|
||||
* values[2]: Angular speed around the z-axis
|
||||
* </p>
|
||||
* <li> values[0]: Angular speed around the x-axis </li>
|
||||
* <li> values[1]: Angular speed around the y-axis </li>
|
||||
* <li> values[2]: Angular speed around the z-axis </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Typically the output of the gyroscope is integrated over time to
|
||||
@@ -233,22 +219,19 @@ public class SensorEvent {
|
||||
* </p>
|
||||
* <h4>{@link android.hardware.Sensor#TYPE_LIGHT Sensor.TYPE_LIGHT}:</h4>
|
||||
* <ul>
|
||||
* <p>
|
||||
* values[0]: Ambient light level in SI lux units
|
||||
* <li>values[0]: Ambient light level in SI lux units </li>
|
||||
* </ul>
|
||||
*
|
||||
* <h4>{@link android.hardware.Sensor#TYPE_PRESSURE Sensor.TYPE_PRESSURE}:</h4>
|
||||
* <ul>
|
||||
* <p>
|
||||
* values[0]: Atmospheric pressure in hPa (millibar)
|
||||
* <li>values[0]: Atmospheric pressure in hPa (millibar) </li>
|
||||
* </ul>
|
||||
*
|
||||
* <h4>{@link android.hardware.Sensor#TYPE_PROXIMITY Sensor.TYPE_PROXIMITY}:
|
||||
* </h4>
|
||||
*
|
||||
* <ul>
|
||||
* <p>
|
||||
* values[0]: Proximity sensor distance measured in centimeters
|
||||
* <li>values[0]: Proximity sensor distance measured in centimeters </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
@@ -304,39 +287,23 @@ public class SensorEvent {
|
||||
* </p>
|
||||
*
|
||||
* <ul>
|
||||
* <p>
|
||||
* values[0]: x*sin(θ/2)
|
||||
* </p>
|
||||
* <p>
|
||||
* values[1]: y*sin(θ/2)
|
||||
* </p>
|
||||
* <p>
|
||||
* values[2]: z*sin(θ/2)
|
||||
* </p>
|
||||
* <p>
|
||||
* values[3]: cos(θ/2) <i>(optional: only if value.length = 4)</i>
|
||||
* </p>
|
||||
* <li> values[0]: x*sin(θ/2) </li>
|
||||
* <li> values[1]: y*sin(θ/2) </li>
|
||||
* <li> values[2]: z*sin(θ/2) </li>
|
||||
* <li> values[3]: cos(θ/2) <i>(optional: only if value.length = 4)</i> </li>
|
||||
* </ul>
|
||||
*
|
||||
* <h4>{@link android.hardware.Sensor#TYPE_ORIENTATION
|
||||
* Sensor.TYPE_ORIENTATION}:</h4> All values are angles in degrees.
|
||||
*
|
||||
* <ul>
|
||||
* <p>
|
||||
* values[0]: Azimuth, angle between the magnetic north direction and the
|
||||
* <li> values[0]: Azimuth, angle between the magnetic north direction and the
|
||||
* y-axis, around the z-axis (0 to 359). 0=North, 90=East, 180=South,
|
||||
* 270=West
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* values[1]: Pitch, rotation around x-axis (-180 to 180), with positive
|
||||
* values when the z-axis moves <b>toward</b> the y-axis.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* values[2]: Roll, rotation around y-axis (-90 to 90), with positive values
|
||||
* when the x-axis moves <b>toward</b> the z-axis.
|
||||
* </p>
|
||||
* 270=West </li>
|
||||
* <li> values[1]: Pitch, rotation around x-axis (-180 to 180), with positive
|
||||
* values when the z-axis moves <b>toward</b> the y-axis. </li>
|
||||
* <li> values[2]: Roll, rotation around y-axis (-90 to 90), with positive values
|
||||
* when the x-axis moves <b>toward</b> the z-axis. </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
@@ -364,9 +331,7 @@ public class SensorEvent {
|
||||
* <h4>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY
|
||||
* Sensor.TYPE_RELATIVE_HUMIDITY}:</h4>
|
||||
* <ul>
|
||||
* <p>
|
||||
* values[0]: Relative ambient air humidity in percent
|
||||
* </p>
|
||||
* <li> values[0]: Relative ambient air humidity in percent </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* When relative ambient air humidity and ambient temperature are
|
||||
@@ -423,21 +388,58 @@ public class SensorEvent {
|
||||
* </h4>
|
||||
*
|
||||
* <ul>
|
||||
* <p>
|
||||
* values[0]: ambient (room) temperature in degree Celsius.
|
||||
* <li> values[0]: ambient (room) temperature in degree Celsius.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @see SensorEvent
|
||||
* @see GeomagneticField
|
||||
*
|
||||
* <h4>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD_UNCALIBRATED} </h4>
|
||||
* All values are in micro-Tesla (uT) and measure the ambient magnetic field
|
||||
* in the X, Y and Z axis.
|
||||
* <p>
|
||||
* No periodic calibration is performed (ie: there are no discontinuities
|
||||
* in the data stream while using this sensor). Assumptions that the the
|
||||
* magnetic field is due to the Earth's poles is avoided. Factory calibration
|
||||
* and temperature compensation is still performed.
|
||||
* </p>
|
||||
*
|
||||
* <h4> {@link android.hardware.Sensor#TYPE_GYROSCOPE_UNCALIBRATED} </h4>
|
||||
* All values are in radians/second and measure the rate of rotation
|
||||
* around the X, Y and Z axis. An estimation of the drift on each axis is
|
||||
* reported as well.
|
||||
* <p>
|
||||
* No gyro-drift compensation is performed. Factory calibration and temperature
|
||||
* compensation is still applied to the rate of rotation (angular speeds).
|
||||
* </p>
|
||||
* <p>
|
||||
* The coordinate system is the same as is used for the
|
||||
* {@link android.hardware.Sensor#TYPE_ACCELEROMETER}
|
||||
* Rotation is positive in the counter-clockwise direction (right-hand rule).
|
||||
* That is, an observer looking from some positive location on the x, y or z axis
|
||||
* at a device positioned on the origin would report positive rotation if the device
|
||||
* appeared to be rotating counter clockwise.
|
||||
* The range would at least be 17.45 rad/s (ie: ~1000 deg/s).
|
||||
* <ul>
|
||||
* <li> values[0] : angular speed (w/o drift compensation) around the X axis in rad/s </li>
|
||||
* <li> values[1] : angular speed (w/o drift compensation) around the Y axis in rad/s </li>
|
||||
* <li> values[2] : angular speed (w/o drift compensation) around the Z axis in rad/s </li>
|
||||
* <li> values[3] : estimated drift around X axis in rad/s </li>
|
||||
* <li> values[4] : estimated drift around Y axis in rad/s </li>
|
||||
* <li> values[5] : estimated drift around Z axis in rad/s </li>
|
||||
* </ul>
|
||||
* </p>
|
||||
* <h4></h4>
|
||||
* <h4> Pro Tip: Always use the length of the values array while performing operations
|
||||
* on it. In earlier versions, this used to be always 3 which has changed now. </h4>
|
||||
*/
|
||||
|
||||
public final float[] values;
|
||||
|
||||
/**
|
||||
* The sensor that generated this event. See
|
||||
* {@link android.hardware.SensorManager SensorManager} for details.
|
||||
*/
|
||||
public Sensor sensor;
|
||||
public Sensor sensor;
|
||||
|
||||
/**
|
||||
* The accuracy of this event. See {@link android.hardware.SensorManager
|
||||
@@ -445,13 +447,11 @@ public class SensorEvent {
|
||||
*/
|
||||
public int accuracy;
|
||||
|
||||
|
||||
/**
|
||||
* The time in nanosecond at which the event happened
|
||||
*/
|
||||
public long timestamp;
|
||||
|
||||
|
||||
SensorEvent(int size) {
|
||||
values = new float[size];
|
||||
}
|
||||
|
||||
@@ -38,7 +38,11 @@ import java.util.List;
|
||||
* hours. Note that the system will <i>not</i> disable sensors automatically when
|
||||
* the screen turns off.
|
||||
* </p>
|
||||
*
|
||||
* <p class="note">
|
||||
* Note: Don't use this mechanism with a Trigger Sensor, have a look
|
||||
* at {@link TriggerEventListener}. {@link Sensor#TYPE_SIGNIFICANT_MOTION}
|
||||
* is an example of a trigger sensor.
|
||||
* </p>
|
||||
* <pre class="prettyprint">
|
||||
* public class SensorActivity extends Activity, implements SensorEventListener {
|
||||
* private final SensorManager mSensorManager;
|
||||
@@ -515,6 +519,12 @@ public abstract class SensorManager {
|
||||
/**
|
||||
* Unregisters a listener for the sensors with which it is registered.
|
||||
*
|
||||
* <p class="note"></p>
|
||||
* Note: Don't use this method with a one shot trigger sensor such as
|
||||
* {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
|
||||
* Use {@link #cancelTriggerSensor(TriggerEventListener, Sensor)} instead.
|
||||
* </p>
|
||||
*
|
||||
* @param listener
|
||||
* a SensorEventListener object
|
||||
*
|
||||
@@ -524,6 +534,7 @@ public abstract class SensorManager {
|
||||
* @see #unregisterListener(SensorEventListener)
|
||||
* @see #registerListener(SensorEventListener, Sensor, int)
|
||||
*
|
||||
* @throws IllegalArgumentException when sensor is a trigger sensor.
|
||||
*/
|
||||
public void unregisterListener(SensorEventListener listener, Sensor sensor) {
|
||||
if (listener == null || sensor == null) {
|
||||
@@ -558,6 +569,12 @@ public abstract class SensorManager {
|
||||
* Registers a {@link android.hardware.SensorEventListener
|
||||
* SensorEventListener} for the given sensor.
|
||||
*
|
||||
* <p class="note"></p>
|
||||
* Note: Don't use this method with a one shot trigger sensor such as
|
||||
* {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
|
||||
* Use {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead.
|
||||
* </p>
|
||||
*
|
||||
* @param listener
|
||||
* A {@link android.hardware.SensorEventListener SensorEventListener}
|
||||
* object.
|
||||
@@ -584,6 +601,7 @@ public abstract class SensorManager {
|
||||
* @see #unregisterListener(SensorEventListener)
|
||||
* @see #unregisterListener(SensorEventListener, Sensor)
|
||||
*
|
||||
* @throws IllegalArgumentException when sensor is null or a trigger sensor
|
||||
*/
|
||||
public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) {
|
||||
return registerListener(listener, sensor, rate, null);
|
||||
@@ -593,6 +611,12 @@ public abstract class SensorManager {
|
||||
* Registers a {@link android.hardware.SensorEventListener
|
||||
* SensorEventListener} for the given sensor.
|
||||
*
|
||||
* <p class="note"></p>
|
||||
* Note: Don't use this method with a one shot trigger sensor such as
|
||||
* {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
|
||||
* Use {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead.
|
||||
* </p>
|
||||
*
|
||||
* @param listener
|
||||
* A {@link android.hardware.SensorEventListener SensorEventListener}
|
||||
* object.
|
||||
@@ -623,6 +647,7 @@ public abstract class SensorManager {
|
||||
* @see #unregisterListener(SensorEventListener)
|
||||
* @see #unregisterListener(SensorEventListener, Sensor)
|
||||
*
|
||||
* @throws IllegalArgumentException when sensor is null or a trigger sensor
|
||||
*/
|
||||
public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate,
|
||||
Handler handler) {
|
||||
@@ -1310,6 +1335,68 @@ public abstract class SensorManager {
|
||||
Q[3] = rv[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests receiving trigger events for a trigger sensor.
|
||||
*
|
||||
* <p>
|
||||
* When the sensor detects a trigger event condition, such as significant motion in
|
||||
* the case of the {@link Sensor#TYPE_SIGNIFICANT_MOTION}, the provided trigger listener
|
||||
* will be invoked once and then its request to receive trigger events will be canceled.
|
||||
* To continue receiving trigger events, the application must request to receive trigger
|
||||
* events again.
|
||||
* </p>
|
||||
*
|
||||
* @param listener The listener on which the
|
||||
* {@link TriggerEventListener#onTrigger(TriggerEvent)} will be delivered.
|
||||
* @param sensor The sensor to be enabled.
|
||||
*
|
||||
* @return true if the sensor was successfully enabled.
|
||||
*
|
||||
* @throws IllegalArgumentException when sensor is null or not a trigger sensor.
|
||||
*/
|
||||
public boolean requestTriggerSensor(TriggerEventListener listener, Sensor sensor) {
|
||||
return requestTriggerSensorImpl(listener, sensor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
protected abstract boolean requestTriggerSensorImpl(TriggerEventListener listener,
|
||||
Sensor sensor);
|
||||
|
||||
/**
|
||||
* Cancels receiving trigger events for a trigger sensor.
|
||||
*
|
||||
* <p>
|
||||
* Note that a Trigger sensor will be auto disabled if
|
||||
* {@link TriggerEventListener#onTrigger(TriggerEvent)} has triggered.
|
||||
* This method is provided in case the user wants to explicitly cancel the request
|
||||
* to receive trigger events.
|
||||
* </p>
|
||||
*
|
||||
* @param listener The listener on which the
|
||||
* {@link TriggerEventListener#onTrigger(TriggerEvent)}
|
||||
* is delivered.It should be the same as the one used
|
||||
* in {@link #requestTriggerSensor(TriggerEventListener, Sensor)}
|
||||
* @param sensor The sensor for which the trigger request should be canceled.
|
||||
* If null, it cancels receiving trigger for all sensors associated
|
||||
* with the listener.
|
||||
*
|
||||
* @return true if successfully canceled.
|
||||
*
|
||||
* @throws IllegalArgumentException when sensor is a trigger sensor.
|
||||
*/
|
||||
public boolean cancelTriggerSensor(TriggerEventListener listener, Sensor sensor) {
|
||||
return cancelTriggerSensorImpl(listener, sensor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
protected abstract boolean cancelTriggerSensorImpl(TriggerEventListener listener,
|
||||
Sensor sensor);
|
||||
|
||||
|
||||
private LegacySensorManager getLegacySensorManager() {
|
||||
synchronized (mSensorListByType) {
|
||||
if (mLegacySensorManager == null) {
|
||||
|
||||
@@ -16,18 +16,19 @@
|
||||
|
||||
package android.hardware;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
|
||||
import dalvik.system.CloseGuard;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.MessageQueue;
|
||||
import android.util.Log;
|
||||
import android.util.Pools;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.SparseIntArray;
|
||||
import dalvik.system.CloseGuard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sensor manager implementation that communicates with the built-in
|
||||
@@ -45,22 +46,21 @@ public class SystemSensorManager extends SensorManager {
|
||||
private static final SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>();
|
||||
|
||||
// Listener list
|
||||
private final ArrayList<SensorEventListenerSensorPair> mListenerDelegates = new ArrayList<SensorEventListenerSensorPair>();
|
||||
private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners =
|
||||
new HashMap<SensorEventListener, SensorEventQueue>();
|
||||
private final HashMap<TriggerEventListener, TriggerEventQueue> mTriggerListeners =
|
||||
new HashMap<TriggerEventListener, TriggerEventQueue>();
|
||||
|
||||
// Common pool of sensor events.
|
||||
private static SensorEventPool sPool;
|
||||
private static final int MAX_EVENTS = 16;
|
||||
private static Pools.SynchronizedPool<SensorEvent> sSensorEventPool;
|
||||
private static Pools.SynchronizedPool<TriggerEvent> sTriggerEventPool;
|
||||
|
||||
// Looper associated with the context in which this instance was created.
|
||||
private final Looper mMainLooper;
|
||||
|
||||
// maps a SensorEventListener to a SensorEventQueue
|
||||
private final Hashtable<SensorEventListener, SensorEventQueue> mSensorEventQueueMap;
|
||||
|
||||
/** {@hide} */
|
||||
public SystemSensorManager(Looper mainLooper) {
|
||||
mMainLooper = mainLooper;
|
||||
mSensorEventQueueMap = new Hashtable<SensorEventListener, SensorEventQueue>();
|
||||
|
||||
synchronized(sSensorModuleLock) {
|
||||
if (!sSensorModuleInitialized) {
|
||||
sSensorModuleInitialized = true;
|
||||
@@ -81,7 +81,10 @@ public class SystemSensorManager extends SensorManager {
|
||||
}
|
||||
} while (i>0);
|
||||
|
||||
sPool = new SensorEventPool( sFullSensorsList.size()*2 );
|
||||
sSensorEventPool = new Pools.SynchronizedPool<SensorEvent>(
|
||||
sFullSensorsList.size()*2);
|
||||
sTriggerEventPool = new Pools.SynchronizedPool<TriggerEvent>(
|
||||
sFullSensorsList.size()*2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,128 +105,133 @@ public class SystemSensorManager extends SensorManager {
|
||||
// Invariants to preserve:
|
||||
// - one Looper per SensorEventListener
|
||||
// - one Looper per SensorEventQueue
|
||||
// We map SensorEventListeners to a SensorEventQueue, which holds the looper
|
||||
// We map SensorEventListener to a SensorEventQueue, which holds the looper
|
||||
if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
|
||||
|
||||
if (sensor == null) throw new NullPointerException("sensor cannot be null");
|
||||
// Trigger Sensors should use the requestTriggerSensor call.
|
||||
if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) return false;
|
||||
|
||||
boolean result;
|
||||
synchronized (mSensorEventQueueMap) {
|
||||
// check if we already have this SensorEventListener, Sensor pair
|
||||
// registered -- if so, we ignore the register. This is not ideal
|
||||
// but this is what the implementation has always been doing.
|
||||
for (SensorEventListenerSensorPair l : mListenerDelegates) {
|
||||
if (l.isSameListenerSensorPair(listener, sensor)) {
|
||||
// already added, just return silently.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// now find the SensorEventQueue associated to this listener
|
||||
SensorEventQueue queue = mSensorEventQueueMap.get(listener);
|
||||
if (queue != null) {
|
||||
result = queue.addSensor(sensor, delay);
|
||||
if (result) {
|
||||
// create a new ListenerDelegate for this pair
|
||||
mListenerDelegates.add(new SensorEventListenerSensorPair(listener, sensor));
|
||||
}
|
||||
} else {
|
||||
synchronized (mSensorListeners) {
|
||||
SensorEventQueue queue = mSensorListeners.get(listener);
|
||||
if (queue == null) {
|
||||
Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
|
||||
queue = new SensorEventQueue(listener, looper.getQueue());
|
||||
result = queue.addSensor(sensor, delay);
|
||||
if (result) {
|
||||
// create a new ListenerDelegate for this pair
|
||||
mListenerDelegates.add(new SensorEventListenerSensorPair(listener, sensor));
|
||||
mSensorEventQueueMap.put(listener, queue);
|
||||
} else {
|
||||
queue = new SensorEventQueue(listener, looper);
|
||||
if (!queue.addSensor(sensor, delay)) {
|
||||
queue.dispose();
|
||||
return false;
|
||||
}
|
||||
mSensorListeners.put(listener, queue);
|
||||
return true;
|
||||
} else {
|
||||
return queue.addSensor(sensor, delay);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
|
||||
synchronized (mSensorEventQueueMap) {
|
||||
// Trigger Sensors should use the cancelTriggerSensor call.
|
||||
if (sensor != null && Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) {
|
||||
return;
|
||||
}
|
||||
|
||||
// remove this listener/sensor from our list
|
||||
final ArrayList<SensorEventListenerSensorPair> copy =
|
||||
new ArrayList<SensorEventListenerSensorPair>(mListenerDelegates);
|
||||
int lastIndex = copy.size()-1;
|
||||
for (int i=lastIndex ; i>= 0 ; i--) {
|
||||
if (copy.get(i).isSameListenerSensorPair(listener, sensor)) {
|
||||
mListenerDelegates.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
// find the SensorEventQueue associated to this SensorEventListener
|
||||
SensorEventQueue queue = mSensorEventQueueMap.get(listener);
|
||||
synchronized (mSensorListeners) {
|
||||
SensorEventQueue queue = mSensorListeners.get(listener);
|
||||
if (queue != null) {
|
||||
if (sensor != null) {
|
||||
queue.removeSensor(sensor);
|
||||
boolean result;
|
||||
if (sensor == null) {
|
||||
result = queue.removeAllSensors();
|
||||
} else {
|
||||
queue.removeAllSensors();
|
||||
result = queue.removeSensor(sensor);
|
||||
}
|
||||
if (!queue.hasSensors()) {
|
||||
mSensorEventQueueMap.remove(listener);
|
||||
if (result && !queue.hasSensors()) {
|
||||
mSensorListeners.remove(listener);
|
||||
queue.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
|
||||
if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
|
||||
|
||||
/*
|
||||
* ListenerDelegate is essentially a SensorEventListener, Sensor pair
|
||||
* and is associated with a single SensorEventQueue.
|
||||
*/
|
||||
private static final class SensorEventListenerSensorPair {
|
||||
private final SensorEventListener mSensorEventListener;
|
||||
private final Sensor mSensor;
|
||||
public SensorEventListenerSensorPair(SensorEventListener listener, Sensor sensor) {
|
||||
mSensorEventListener = listener;
|
||||
mSensor = sensor;
|
||||
}
|
||||
public boolean isSameListenerSensorPair(SensorEventListener listener, Sensor sensor) {
|
||||
// if sensor is null, we match only on the listener
|
||||
if (sensor != null) {
|
||||
return (listener == mSensorEventListener) &&
|
||||
(sensor.getHandle() == mSensor.getHandle());
|
||||
if (Sensor.getReportingMode(sensor) != Sensor.REPORTING_MODE_ONE_SHOT) return false;
|
||||
|
||||
synchronized (mTriggerListeners) {
|
||||
TriggerEventQueue queue = mTriggerListeners.get(listener);
|
||||
if (queue == null) {
|
||||
queue = new TriggerEventQueue(listener, mMainLooper, this);
|
||||
if (!queue.addSensor(sensor, 0)) {
|
||||
queue.dispose();
|
||||
return false;
|
||||
}
|
||||
mTriggerListeners.put(listener, queue);
|
||||
return true;
|
||||
} else {
|
||||
return (listener == mSensorEventListener);
|
||||
return queue.addSensor(sensor, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
|
||||
if (sensor != null && Sensor.getReportingMode(sensor) != Sensor.REPORTING_MODE_ONE_SHOT) {
|
||||
return false;
|
||||
}
|
||||
synchronized (mTriggerListeners) {
|
||||
TriggerEventQueue queue = mTriggerListeners.get(listener);
|
||||
if (queue != null) {
|
||||
boolean result;
|
||||
if (sensor == null) {
|
||||
result = queue.removeAllSensors();
|
||||
} else {
|
||||
result = queue.removeSensor(sensor);
|
||||
}
|
||||
if (result && !queue.hasSensors()) {
|
||||
mTriggerListeners.remove(listener);
|
||||
queue.dispose();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SensorEventQueue is the communication channel with the sensor service,
|
||||
* there is a one-to-one mapping between SensorEventQueue and
|
||||
* SensorEventListener.
|
||||
* BaseEventQueue is the communication channel with the sensor service,
|
||||
* SensorEventQueue, TriggerEventQueue are subclases and there is one-to-one mapping between
|
||||
* the queues and the listeners.
|
||||
*/
|
||||
private static final class SensorEventQueue {
|
||||
private static native int nativeInitSensorEventQueue(SensorEventQueue eventQ, MessageQueue msgQ, float[] scratch);
|
||||
private static abstract class BaseEventQueue {
|
||||
private native int nativeInitBaseEventQueue(BaseEventQueue eventQ, MessageQueue msgQ,
|
||||
float[] scratch);
|
||||
private static native int nativeEnableSensor(int eventQ, int handle, int us);
|
||||
private static native int nativeDisableSensor(int eventQ, int handle);
|
||||
private static native void nativeDestroySensorEventQueue(int eventQ);
|
||||
private int nSensorEventQueue;
|
||||
private final SensorEventListener mListener;
|
||||
private final SparseBooleanArray mActiveSensors = new SparseBooleanArray();
|
||||
private final SparseIntArray mSensorAccuracies = new SparseIntArray();
|
||||
private final SparseBooleanArray mFirstEvent = new SparseBooleanArray();
|
||||
protected final SparseIntArray mSensorAccuracies = new SparseIntArray();
|
||||
protected final SparseBooleanArray mFirstEvent = new SparseBooleanArray();
|
||||
private final CloseGuard mCloseGuard = CloseGuard.get();
|
||||
private final float[] mScratch = new float[16];
|
||||
|
||||
public SensorEventQueue(SensorEventListener listener, MessageQueue msgQ) {
|
||||
nSensorEventQueue = nativeInitSensorEventQueue(this, msgQ, mScratch);
|
||||
mListener = listener;
|
||||
BaseEventQueue(Looper looper) {
|
||||
nSensorEventQueue = nativeInitBaseEventQueue(this, looper.getQueue(), mScratch);
|
||||
mCloseGuard.open("dispose");
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
dispose(false);
|
||||
}
|
||||
|
||||
public boolean addSensor(Sensor sensor, int delay) {
|
||||
// Check if already present.
|
||||
if (mActiveSensors.get(sensor.getHandle())) return false;
|
||||
|
||||
if (enableSensor(sensor, delay) == 0) {
|
||||
mActiveSensors.put(sensor.getHandle(), true);
|
||||
return true;
|
||||
@@ -231,7 +239,7 @@ public class SystemSensorManager extends SensorManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeAllSensors() {
|
||||
public boolean removeAllSensors() {
|
||||
for (int i=0 ; i<mActiveSensors.size(); i++) {
|
||||
if (mActiveSensors.valueAt(i) == true) {
|
||||
int handle = mActiveSensors.keyAt(i);
|
||||
@@ -244,21 +252,24 @@ public class SystemSensorManager extends SensorManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void removeSensor(Sensor sensor) {
|
||||
public boolean removeSensor(Sensor sensor) {
|
||||
final int handle = sensor.getHandle();
|
||||
if (mActiveSensors.get(handle)) {
|
||||
disableSensor(sensor);
|
||||
mActiveSensors.put(sensor.getHandle(), false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasSensors() {
|
||||
// no more sensors are set
|
||||
return mActiveSensors.indexOfValue(true) >= 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
@@ -291,17 +302,30 @@ public class SystemSensorManager extends SensorManager {
|
||||
if (sensor == null) throw new NullPointerException();
|
||||
return nativeDisableSensor(nSensorEventQueue, sensor.getHandle());
|
||||
}
|
||||
protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy,
|
||||
long timestamp);
|
||||
}
|
||||
|
||||
static final class SensorEventQueue extends BaseEventQueue {
|
||||
private final SensorEventListener mListener;
|
||||
|
||||
public SensorEventQueue(SensorEventListener listener, Looper looper) {
|
||||
super(looper);
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
// Called from native code.
|
||||
@SuppressWarnings("unused")
|
||||
private void dispatchSensorEvent(int handle, float[] values, int inAccuracy, long timestamp) {
|
||||
// this is always called on the same thread.
|
||||
final SensorEvent t = sPool.getFromPool();
|
||||
@Override
|
||||
protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
|
||||
long timestamp) {
|
||||
final Sensor sensor = sHandleToSensor.get(handle);
|
||||
SensorEvent t = sSensorEventPool.acquire();
|
||||
if (t == null) t = new SensorEvent(MAX_EVENTS);
|
||||
try {
|
||||
final Sensor sensor = sHandleToSensor.get(handle);
|
||||
final SensorEventListener listener = mListener;
|
||||
// FIXME: handle more than 3 values
|
||||
System.arraycopy(values, 0, t.values, 0, 3);
|
||||
// Copy the entire values array.
|
||||
// Any changes in length will be handled at the native layer.
|
||||
System.arraycopy(values, 0, t.values, 0, t.values.length);
|
||||
t.timestamp = timestamp;
|
||||
t.accuracy = inAccuracy;
|
||||
t.sensor = sensor;
|
||||
@@ -313,72 +337,57 @@ public class SystemSensorManager extends SensorManager {
|
||||
final int accuracy = mSensorAccuracies.get(handle);
|
||||
if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
|
||||
mSensorAccuracies.put(handle, t.accuracy);
|
||||
listener.onAccuracyChanged(t.sensor, t.accuracy);
|
||||
mListener.onAccuracyChanged(t.sensor, t.accuracy);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// For other sensors, just report the accuracy once
|
||||
if (mFirstEvent.get(handle) == false) {
|
||||
mFirstEvent.put(handle, true);
|
||||
listener.onAccuracyChanged(
|
||||
mListener.onAccuracyChanged(
|
||||
t.sensor, SENSOR_STATUS_ACCURACY_HIGH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
listener.onSensorChanged(t);
|
||||
mListener.onSensorChanged(t);
|
||||
} finally {
|
||||
sPool.returnToPool(t);
|
||||
sSensorEventPool.release(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A dumb pool of SensorEvent
|
||||
*/
|
||||
private static final class SensorEventPool {
|
||||
private final int mPoolSize;
|
||||
private final SensorEvent mPool[];
|
||||
private int mNumItemsInPool;
|
||||
static final class TriggerEventQueue extends BaseEventQueue {
|
||||
private final TriggerEventListener mListener;
|
||||
private SensorManager mManager;
|
||||
|
||||
private SensorEvent createSensorEvent() {
|
||||
// maximal size for all legacy events is 3
|
||||
return new SensorEvent(3);
|
||||
public TriggerEventQueue(TriggerEventListener listener, Looper looper,
|
||||
SensorManager manager) {
|
||||
super(looper);
|
||||
mListener = listener;
|
||||
mManager = manager;
|
||||
}
|
||||
|
||||
SensorEventPool(int poolSize) {
|
||||
mPoolSize = poolSize;
|
||||
mNumItemsInPool = poolSize;
|
||||
mPool = new SensorEvent[poolSize];
|
||||
}
|
||||
// Called from native code.
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
protected void dispatchSensorEvent(int handle, float[] values, int accuracy, long timestamp) {
|
||||
final Sensor sensor = sHandleToSensor.get(handle);
|
||||
TriggerEvent t = sTriggerEventPool.acquire();
|
||||
if (t == null) t = new TriggerEvent(MAX_EVENTS);
|
||||
|
||||
SensorEvent getFromPool() {
|
||||
SensorEvent t = null;
|
||||
synchronized (this) {
|
||||
if (mNumItemsInPool > 0) {
|
||||
// remove the "top" item from the pool
|
||||
final int index = mPoolSize - mNumItemsInPool;
|
||||
t = mPool[index];
|
||||
mPool[index] = null;
|
||||
mNumItemsInPool--;
|
||||
}
|
||||
}
|
||||
if (t == null) {
|
||||
// the pool was empty or this item was removed from the pool for
|
||||
// the first time. In any case, we need to create a new item.
|
||||
t = createSensorEvent();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
try {
|
||||
// Copy the entire values array.
|
||||
// Any changes in length will be handled at the native layer.
|
||||
System.arraycopy(values, 0, t.values, 0, t.values.length);
|
||||
t.timestamp = timestamp;
|
||||
t.sensor = sensor;
|
||||
|
||||
void returnToPool(SensorEvent t) {
|
||||
synchronized (this) {
|
||||
// is there space left in the pool?
|
||||
if (mNumItemsInPool < mPoolSize) {
|
||||
// if so, return the item to the pool
|
||||
mNumItemsInPool++;
|
||||
final int index = mPoolSize - mNumItemsInPool;
|
||||
mPool[index] = t;
|
||||
}
|
||||
// A trigger sensor should be auto disabled.
|
||||
mManager.cancelTriggerSensorImpl(mListener, sensor);
|
||||
|
||||
mListener.onTrigger(t);
|
||||
} finally {
|
||||
sTriggerEventPool.release(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
62
core/java/android/hardware/TriggerEvent.java
Normal file
62
core/java/android/hardware/TriggerEvent.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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;
|
||||
|
||||
/**
|
||||
* This class represents a Trigger Event - the event
|
||||
* associated with a Trigger Sensor. When the sensor detects a trigger
|
||||
* event condition, such as significant motion in the case of the
|
||||
* {@link Sensor#TYPE_SIGNIFICANT_MOTION}, the {@link TriggerEventListener}
|
||||
* is called with the TriggerEvent. The sensor is automatically canceled
|
||||
* after the trigger.
|
||||
* <p>
|
||||
* This class holds information such as the value of the sensor
|
||||
* when the trigger happened, the timestamp along with detailed
|
||||
* information regarding the Sensor itself.
|
||||
* </p>
|
||||
* @see android.hardware.SensorManager
|
||||
* @see android.hardware.TriggerEvent
|
||||
* @see android.hardware.Sensor
|
||||
*/
|
||||
public final class TriggerEvent {
|
||||
/**
|
||||
* <p>
|
||||
* The length and contents of the {@link #values values} array depends on
|
||||
* which {@link android.hardware.Sensor sensor} type is being monitored (see
|
||||
* also {@link SensorEvent} for a definition of the coordinate system used).
|
||||
* </p>
|
||||
* <h4> {@link Sensor#TYPE_SIGNIFICANT_MOTION} </h4>
|
||||
* The value field is of length 1. value[0] = 1.0 when the sensor triggers.
|
||||
* 1.0 is the only allowed value.
|
||||
*/
|
||||
public final float[] values;
|
||||
|
||||
/**
|
||||
* The sensor that generated this event. See
|
||||
* {@link android.hardware.SensorManager SensorManager} for details.
|
||||
*/
|
||||
public Sensor sensor;
|
||||
|
||||
/**
|
||||
* The time in nanosecond at which the event happened
|
||||
*/
|
||||
public long timestamp;
|
||||
|
||||
TriggerEvent(int size) {
|
||||
values = new float[size];
|
||||
}
|
||||
}
|
||||
78
core/java/android/hardware/TriggerEventListener.java
Normal file
78
core/java/android/hardware/TriggerEventListener.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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;
|
||||
|
||||
/**
|
||||
* This class is the listener used to handle Trigger Sensors.
|
||||
* Trigger Sensors are sensors that trigger an event and are automatically
|
||||
* disabled. {@link Sensor#TYPE_SIGNIFICANT_MOTION} is one such example.
|
||||
* <p>
|
||||
* SensorManager lets you access the device's {@link android.hardware.Sensor
|
||||
* sensors}. Get an instance of this class by calling
|
||||
* {@link android.content.Context#getSystemService(java.lang.String)
|
||||
* Context.getSystemService()} with the argument
|
||||
* {@link android.content.Context#SENSOR_SERVICE}.
|
||||
* Usage details are explained in the example below.
|
||||
* </p>
|
||||
*
|
||||
* <pre class="prettyprint">
|
||||
* class TriggerListener extends TriggerEventListener {
|
||||
* public void onTrigger(TriggerEvent event) {
|
||||
* // Do Work.
|
||||
*
|
||||
* // As it is a one shot sensor, it will be canceled automatically.
|
||||
* // SensorManager.requestTriggerSensor(this, mSigMotion); needs to
|
||||
* // be called again, if needed.
|
||||
* }
|
||||
* }
|
||||
* public class SensorActivity extends Activity {
|
||||
* private final SensorManager mSensorManager;
|
||||
* private final Sensor mSigMotion;
|
||||
* private final TriggerEventListener mListener = new TriggerEventListener();
|
||||
*
|
||||
* public SensorActivity() {
|
||||
* mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
|
||||
* mSigMotion = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
|
||||
* }
|
||||
*
|
||||
* protected void onResume() {
|
||||
* super.onResume();
|
||||
* mSensorManager.requestTriggerSensor(mListener, mSigMotion);
|
||||
* }
|
||||
*
|
||||
* protected void onPause() {
|
||||
* super.onPause();
|
||||
* // Call disable to ensure that the trigger request has been canceled.
|
||||
* mSensorManager.cancelTriggerSensor(mListener, mSigMotion);
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see TriggerEvent
|
||||
* @see Sensor
|
||||
*/
|
||||
public abstract class TriggerEventListener {
|
||||
/**
|
||||
* The method that will be called when the sensor
|
||||
* is triggered. Override this method in your implementation
|
||||
* of this class.
|
||||
*
|
||||
* @param event The details of the event.
|
||||
*/
|
||||
public abstract void onTrigger(TriggerEvent event);
|
||||
}
|
||||
@@ -31,7 +31,7 @@
|
||||
static struct {
|
||||
jclass clazz;
|
||||
jmethodID dispatchSensorEvent;
|
||||
} gSensorEventQueueClassInfo;
|
||||
} gBaseEventQueueClassInfo;
|
||||
|
||||
namespace android {
|
||||
|
||||
@@ -145,7 +145,7 @@ private:
|
||||
env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);
|
||||
|
||||
env->CallVoidMethod(mReceiverObject,
|
||||
gSensorEventQueueClassInfo.dispatchSensorEvent,
|
||||
gBaseEventQueueClassInfo.dispatchSensorEvent,
|
||||
buffer[i].sensor,
|
||||
mScratch,
|
||||
buffer[i].vector.status,
|
||||
@@ -209,9 +209,9 @@ static JNINativeMethod gSystemSensorManagerMethods[] = {
|
||||
(void*)nativeGetNextSensor },
|
||||
};
|
||||
|
||||
static JNINativeMethod gSensorEventQueueMethods[] = {
|
||||
{"nativeInitSensorEventQueue",
|
||||
"(Landroid/hardware/SystemSensorManager$SensorEventQueue;Landroid/os/MessageQueue;[F)I",
|
||||
static JNINativeMethod gBaseEventQueueMethods[] = {
|
||||
{"nativeInitBaseEventQueue",
|
||||
"(Landroid/hardware/SystemSensorManager$BaseEventQueue;Landroid/os/MessageQueue;[F)I",
|
||||
(void*)nativeInitSensorEventQueue },
|
||||
|
||||
{"nativeEnableSensor",
|
||||
@@ -245,13 +245,13 @@ int register_android_hardware_SensorManager(JNIEnv *env)
|
||||
jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager",
|
||||
gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods));
|
||||
|
||||
jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager$SensorEventQueue",
|
||||
gSensorEventQueueMethods, NELEM(gSensorEventQueueMethods));
|
||||
jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager$BaseEventQueue",
|
||||
gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods));
|
||||
|
||||
FIND_CLASS(gSensorEventQueueClassInfo.clazz, "android/hardware/SystemSensorManager$SensorEventQueue");
|
||||
FIND_CLASS(gBaseEventQueueClassInfo.clazz, "android/hardware/SystemSensorManager$BaseEventQueue");
|
||||
|
||||
GET_METHOD_ID(gSensorEventQueueClassInfo.dispatchSensorEvent,
|
||||
gSensorEventQueueClassInfo.clazz,
|
||||
GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchSensorEvent,
|
||||
gBaseEventQueueClassInfo.clazz,
|
||||
"dispatchSensorEvent", "(I[FIJ)V");
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user