You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by de...@apache.org on 2012/04/03 14:59:30 UTC
[3/15] webworks commit: Normalize Accelerometer values and cleanup.
Normalize Accelerometer values and cleanup.
- Normalize return values to sync with other platforms.
- Delay first returned values until sensor is active.
- Cleanup formatting/whitespace and variable scoping.
Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/commit/6aec9eb8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/tree/6aec9eb8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/diff/6aec9eb8
Branch: refs/heads/master
Commit: 6aec9eb8347864dafaeb5002a6b26b289bfd1c27
Parents: cee777c
Author: Drew Walters <de...@apache.org>
Authored: Thu Mar 29 13:18:00 2012 -0500
Committer: Drew Walters <de...@apache.org>
Committed: Thu Mar 29 13:18:00 2012 -0500
----------------------------------------------------------------------
.../cordova/accelerometer/Accelerometer.java | 378 ++++++++------
1 files changed, 216 insertions(+), 162 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cordova-blackberry-webworks/blob/6aec9eb8/framework/ext/src/org/apache/cordova/accelerometer/Accelerometer.java
----------------------------------------------------------------------
diff --git a/framework/ext/src/org/apache/cordova/accelerometer/Accelerometer.java b/framework/ext/src/org/apache/cordova/accelerometer/Accelerometer.java
index 25cf783..a299ff7 100644
--- a/framework/ext/src/org/apache/cordova/accelerometer/Accelerometer.java
+++ b/framework/ext/src/org/apache/cordova/accelerometer/Accelerometer.java
@@ -32,194 +32,248 @@ import net.rim.device.api.system.Application;
public class Accelerometer extends Plugin implements AccelerometerListener {
- public static final String ACTION_GET_ACCELERATION = "getAcceleration";
- public static final String ACTION_SET_TIMEOUT = "setTimeout";
- public static final String ACTION_GET_TIMEOUT = "getTimeout";
- public static final String ACTION_STOP = "stop";
-
- public static int STOPPED = 0;
- public static int STARTED = 1;
-
- private static AccelerometerSensor.Channel _rawDataChannel = null; // the single channel to the device sensor
- int status; // status of this listener
- public float timeout = 30000; // timeout in msec to close sensor channel
- long lastAccessTime; // last time accel data was retrieved
-
- public PluginResult execute(String action, JSONArray args, String calbackId) {
-
- PluginResult result = null;
-
- if (!AccelerometerSensor.isSupported()) {
- result = new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, "Accelerometer sensor not supported");
- }
- else if (ACTION_GET_ACCELERATION.equals(action)) {
- JSONObject accel = new JSONObject();
- try {
- AccelerometerData accelData = getCurrentAcceleration();
- accel.put("x", (int)accelData.getLastXAcceleration());
- accel.put("y", (int)accelData.getLastYAcceleration());
- accel.put("z", (int)accelData.getLastZAcceleration());
- accel.put("timestamp", accelData.getLastTimestamp());
- } catch (JSONException e) {
- return new PluginResult(PluginResult.Status.JSON_EXCEPTION, "JSONException:" + e.getMessage());
- }
- result = new PluginResult(PluginResult.Status.OK, accel);
- }
- else if (ACTION_GET_TIMEOUT.equals(action)) {
- float f = this.getTimeout();
- return new PluginResult(PluginResult.Status.OK, Float.toString(f));
- }
- else if (ACTION_SET_TIMEOUT.equals(action)) {
- try {
- float t = Float.parseFloat(args.getString(0));
- this.setTimeout(t);
- return new PluginResult(PluginResult.Status.OK, "");
- } catch (NumberFormatException e) {
- return new PluginResult(PluginResult.Status.ERROR, e.getMessage());
- } catch (JSONException e) {
- return new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
- }
- }
- else if (ACTION_STOP.equals(action)) {
- this.stop();
- return new PluginResult(PluginResult.Status.OK, "");
- }
- else {
- result = new PluginResult(PluginResult.Status.INVALID_ACTION, "Accelerometer: Invalid action:" + action);
- }
-
- return result;
- }
-
- /**
- * Identifies if action to be executed returns a value and should be run synchronously.
- *
- * @param action The action to execute
- * @return T=returns value
- */
- public boolean isSynch(String action) {
- return true;
- }
+ private static final String ACTION_GET_ACCELERATION = "getAcceleration";
+ private static final String ACTION_SET_TIMEOUT = "setTimeout";
+ private static final String ACTION_GET_TIMEOUT = "getTimeout";
+ private static final String ACTION_STOP = "stop";
+
+ private static final int STOPPED = 0;
+ private static final int RUNNING = 2;
+ private static final int ERROR_FAILED_TO_START = 3;
+
+ // BlackBerry uses a value of 1000 (AccelerometerSensor.G_FORCE_VALUE) to
+ // represent g force constant. Spec uses m/s^2. This constant is used
+ // to normalize BlackBerry values to the spec.
+ private static final short G_FORCE_NORMALIZE = 981;
+
+ // the single channel to the device sensor
+ private static AccelerometerSensor.Channel _rawDataChannel = null;
+
+ private int status = STOPPED; // status of this listener
+ private float timeout = 30000; // timeout in msec to close sensor channel
+ private long lastAccessTime; // last time accel data was retrieved
+
+ public PluginResult execute(String action, JSONArray args, String calbackId) {
+
+ PluginResult result = null;
+
+ if (!AccelerometerSensor.isSupported()) {
+ result = new PluginResult(
+ PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION,
+ "Accelerometer sensor not supported");
+ } else if (ACTION_GET_ACCELERATION.equals(action)) {
+ AccelerometerData accelData = getCurrentAcceleration();
+ if (accelData == null) {
+ return new PluginResult(PluginResult.Status.IO_EXCEPTION,
+ ERROR_FAILED_TO_START);
+ }
+
+ JSONObject accel = new JSONObject();
+ try {
+ accel.put("x", normalize(accelData.getLastXAcceleration()));
+ accel.put("y", normalize(accelData.getLastYAcceleration()));
+ accel.put("z", normalize(accelData.getLastZAcceleration()));
+ accel.put("timestamp", accelData.getLastTimestamp());
+ } catch (JSONException e) {
+ return new PluginResult(PluginResult.Status.JSON_EXCEPTION,
+ "JSONException:" + e.getMessage());
+ }
+ result = new PluginResult(PluginResult.Status.OK, accel);
+ } else if (ACTION_GET_TIMEOUT.equals(action)) {
+ float f = getTimeout();
+ return new PluginResult(PluginResult.Status.OK, Float.toString(f));
+ } else if (ACTION_SET_TIMEOUT.equals(action)) {
+ try {
+ float t = Float.parseFloat(args.getString(0));
+ setTimeout(t);
+ return new PluginResult(PluginResult.Status.OK, status);
+ } catch (NumberFormatException e) {
+ return new PluginResult(PluginResult.Status.ERROR,
+ e.getMessage());
+ } catch (JSONException e) {
+ return new PluginResult(PluginResult.Status.JSON_EXCEPTION,
+ e.getMessage());
+ }
+ } else if (ACTION_STOP.equals(action)) {
+ stop();
+ return new PluginResult(PluginResult.Status.OK, STOPPED);
+ } else {
+ result = new PluginResult(PluginResult.Status.INVALID_ACTION,
+ "Accelerometer: Invalid action:" + action);
+ }
+
+ return result;
+ }
+
+ /**
+ * Identifies if action to be executed returns a value and should be run
+ * synchronously.
+ *
+ * @param action
+ * The action to execute
+ * @return T=returns value
+ */
+ public boolean isSynch(String action) {
+ return true;
+ }
+
+ /**
+ * Set the timeout to turn off accelerometer sensor.
+ *
+ * @param timeout
+ * Timeout in msec.
+ */
+ private void setTimeout(float timeout) {
+ this.timeout = timeout;
+ }
/**
- * Get status of accelerometer sensor.
+ * Get the timeout to turn off accelerometer sensor.
*
- * @return status
+ * @return timeout in msec
*/
- public int getStatus() {
- return this.status;
- }
-
- /**
- * Set the status and send it to JavaScript.
- * @param status
- */
- private void setStatus(int status) {
- this.status = status;
- }
-
- /**
- * Set the timeout to turn off accelerometer sensor.
- *
- * @param timeout Timeout in msec.
- */
- public void setTimeout(float timeout) {
- this.timeout = timeout;
- }
-
- /**
- * Get the timeout to turn off accelerometer sensor.
- *
- * @return timeout in msec
- */
- public float getTimeout() {
- return this.timeout;
- }
-
- /**
- * Opens a raw data channel to the accelerometer sensor.
- * @return the AccelerometerSensor.Channel for the application
- */
- private static AccelerometerSensor.Channel getChannel() {
- // an application can only have one open channel
- if (_rawDataChannel == null || !_rawDataChannel.isOpen()) {
- _rawDataChannel = AccelerometerSensor.openRawDataChannel(
- Application.getApplication());
- Logger.log(Accelerometer.class.getName() +": sensor channel opened");
- }
- return _rawDataChannel;
- }
-
- /**
- * Returns last acceleration data from the accelerometer sensor.
- * @return AccelerometerData with last acceleration data
- */
- private AccelerometerData getCurrentAcceleration() {
- // open sensor channel
- if (this.getStatus() != STARTED) {
- this.start();
- }
-
- // get the last acceleration
- AccelerometerData accelData = getChannel().getAccelerometerData();
-
- Logger.log(this.getClass().getName() +
- ": x=" + accelData.getLastXAcceleration() +
- ", y=" + accelData.getLastYAcceleration() +
- ", z=" + accelData.getLastZAcceleration() +
- ", timestamp=" + accelData.getLastTimestamp());
-
- // remember the access time (for timeout purposes)
- this.lastAccessTime = System.currentTimeMillis();
-
- return accelData;
- }
-
- /**
- * Implements the AccelerometerListener method. We listen for the purpose
- * of closing the application's accelerometer sensor channel after timeout
- * has been exceeded.
- */
- public void onData(AccelerometerData accelData) {
+ private float getTimeout() {
+ return timeout;
+ }
+
+ /**
+ * Opens a raw data channel to the accelerometer sensor.
+ *
+ * @return the AccelerometerSensor.Channel for the application
+ */
+ private static AccelerometerSensor.Channel getChannel() {
+ // an application can only have one open channel
+ if (_rawDataChannel == null || !_rawDataChannel.isOpen()) {
+ _rawDataChannel = AccelerometerSensor
+ .openRawDataChannel(Application.getApplication());
+ Logger.log(Accelerometer.class.getName()
+ + ": sensor channel opened");
+ }
+ return _rawDataChannel;
+ }
+
+ /**
+ * Returns last acceleration data from the accelerometer sensor.
+ *
+ * @return AccelerometerData with last acceleration data
+ */
+ private AccelerometerData getCurrentAcceleration() {
+ AccelerometerData accelData;
+
+ if (status != RUNNING) {
+ accelData = start();
+ }
+ else {
+ // get the last acceleration
+ accelData = getChannel().getAccelerometerData();
+ }
+
+ // remember the access time (for timeout purposes)
+ lastAccessTime = System.currentTimeMillis();
+
+ return accelData;
+ }
+
+ /**
+ * Implements the AccelerometerListener method. We listen for the purpose of
+ * closing the application's accelerometer sensor channel after timeout has
+ * been exceeded.
+ */
+ public void onData(AccelerometerData accelData) {
// time that accel event was received
long timestamp = accelData.getLastTimestamp();
// If values haven't been read for length of timeout,
// turn off accelerometer sensor to save power
- if ((timestamp - this.lastAccessTime) > this.timeout) {
- this.stop();
- }
- }
+ if ((timestamp - lastAccessTime) > timeout) {
+ Logger.log("stopping due to timeout, status = " + status);
+ stop();
+ }
+ }
- /**
- * Adds this listener to sensor channel.
- */
- public void start() {
- // open the sensor channel and register listener
- getChannel().setAccelerometerListener(this);
+ /**
+ * Adds this listener to sensor channel.
+ */
+ private AccelerometerData start() {
+ // open the sensor channel and register listener
+ getChannel().setAccelerometerListener(this);
+ Logger.log(this.getClass().getName() + ": sensor listener added");
- Logger.log(this.getClass().getName() +": sensor listener added");
+ // Need to wait until sensor is active. Otherwise, first query will
+ // return zeros for all values. Wait up to 2 seconds.
+ int waittime = 2000;
+ AccelerometerData accelData = null;
+ while (waittime > 0) {
+ accelData = getChannel().getAccelerometerData();
+ // If any value is not zero, assume sensor is active and break out.
+ if (accelData.getLastXAcceleration() != 0
+ || accelData.getLastYAcceleration() != 0
+ || accelData.getLastZAcceleration() != 0) {
+ break;
+ }
- this.setStatus(STARTED);
- }
+ // Sleep and give sensor more time to warm up.
+ waittime -= 100;
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // Sensor failed to start.
+ if (waittime == 0) {
+ stop();
+ return null;
+ }
+
+ status = RUNNING;
+
+ return accelData;
+ }
/**
* Stops accelerometer listener and closes the sensor channel.
*/
- public void stop() {
+ private void stop() {
// close the sensor channel
if (_rawDataChannel != null && _rawDataChannel.isOpen()) {
_rawDataChannel.close();
- Logger.log(this.getClass().getName() +": sensor channel closed");
+ Logger.log(this.getClass().getName() + ": sensor channel closed");
}
- this.setStatus(STOPPED);
+ status = STOPPED;
}
/**
* Called when Plugin is destroyed.
*/
public void onDestroy() {
- this.stop();
+ stop();
+ }
+
+ /**
+ * Normalize the range of values returned by BlackBerry to the agreed upon
+ * cross platform range.
+ *
+ * @param value
+ * @return normalized value
+ */
+ private double normalize(short value) {
+ // Integer multiplication is less troublesome then floating point.
+ StringBuffer buf = new StringBuffer(String.valueOf(value
+ * G_FORCE_NORMALIZE));
+
+ // Manipulate the string to properly insert zeros and decimal point so
+ // something like -708910 becomes -7.08910 and 764 becomes .00764.
+ // Due to the values returned by BlackBerry there will always be 5
+ // decimal precision in the normalized value.
+ int idx = buf.charAt(0) == '-' ? 1 : 0;
+ while (buf.length() < (5 + idx)) {
+ buf.insert(idx, '0');
+ }
+ buf.insert(buf.length() - 5, '.');
+
+ return Double.parseDouble(buf.toString());
}
}