You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by bo...@apache.org on 2012/05/24 18:31:08 UTC
[8/15] android commit: [CB-463] rewrite of accel plugin
[CB-463] rewrite of accel plugin
Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/commit/71e47aa7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/tree/71e47aa7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/diff/71e47aa7
Branch: refs/heads/CordovaWebView
Commit: 71e47aa77286298ddf03dc1fa8c9c42046877aad
Parents: 0850229
Author: Fil Maj <ma...@gmail.com>
Authored: Mon May 14 13:00:11 2012 -0700
Committer: Fil Maj <ma...@gmail.com>
Committed: Fri May 18 15:20:54 2012 -0700
----------------------------------------------------------------------
.../src/org/apache/cordova/AccelListener.java | 392 ++++++++-------
1 files changed, 203 insertions(+), 189 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/71e47aa7/framework/src/org/apache/cordova/AccelListener.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/AccelListener.java b/framework/src/org/apache/cordova/AccelListener.java
index f751e4e..40ddec4 100755
--- a/framework/src/org/apache/cordova/AccelListener.java
+++ b/framework/src/org/apache/cordova/AccelListener.java
@@ -18,7 +18,11 @@
*/
package org.apache.cordova;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import org.apache.cordova.api.CordovaInterface;
import org.apache.cordova.api.Plugin;
@@ -32,6 +36,8 @@ import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
+import android.location.Location;
+import android.util.Log;
import android.content.Context;
/**
@@ -40,20 +46,20 @@ import android.content.Context;
*/
public class AccelListener extends Plugin implements SensorEventListener {
- public static int STOPPED = 0;
- public static int STARTING = 1;
+ public static int STOPPED = 0;
+ public static int STARTING = 1;
public static int RUNNING = 2;
public static int ERROR_FAILED_TO_START = 3;
- public float TIMEOUT = 30000; // Timeout in msec to shut off listener
-
- float x,y,z; // most recent acceleration values
- long timestamp; // time of most recent value
- int status; // status of listener
- long lastAccessTime; // time the value was last retrieved
+ private float x,y,z; // most recent acceleration values
+ private long timestamp; // time of most recent value
+ private int status; // status of listener
- private SensorManager sensorManager;// Sensor manager
- Sensor mSensor; // Acceleration sensor returned by sensor manager
+ private SensorManager sensorManager; // Sensor manager
+ private Sensor mSensor; // Acceleration sensor returned by sensor manager
+
+ private HashMap<String, String> watches = new HashMap<String, String>();
+ private List<String> callbacks = new ArrayList<String>();
/**
* Create an accelerometer listener.
@@ -66,169 +72,149 @@ public class AccelListener extends Plugin implements SensorEventListener {
this.setStatus(AccelListener.STOPPED);
}
- /**
- * Sets the context of the Command. This can then be used to do things like
- * get file paths associated with the Activity.
- *
- * @param ctx The context of the main Activity.
- */
- public void setContext(CordovaInterface ctx) {
- super.setContext(ctx);
+ /**
+ * Sets the context of the Command. This can then be used to do things like
+ * get file paths associated with the Activity.
+ *
+ * @param ctx The context of the main Activity.
+ */
+ public void setContext(CordovaInterface ctx) {
+ super.setContext(ctx);
this.sensorManager = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE);
- }
+ }
- /**
- * Executes the request and returns PluginResult.
- *
- * @param action The action to execute.
- * @param args JSONArry of arguments for the plugin.
- * @param callbackId The callback id used when calling back into JavaScript.
- * @return A PluginResult object with a status and message.
- */
- public PluginResult execute(String action, JSONArray args, String callbackId) {
- PluginResult.Status status = PluginResult.Status.OK;
- String result = "";
-
- try {
- if (action.equals("getStatus")) {
- int i = this.getStatus();
- return new PluginResult(status, i);
- }
- else if (action.equals("start")) {
- int i = this.start();
- return new PluginResult(status, i);
- }
- else if (action.equals("stop")) {
- this.stop();
- return new PluginResult(status, 0);
- }
- else if (action.equals("getAcceleration")) {
- // If not running, then this is an async call, so don't worry about waiting
- if (this.status != AccelListener.RUNNING) {
- int r = this.start();
- if (r == AccelListener.ERROR_FAILED_TO_START) {
- return new PluginResult(PluginResult.Status.IO_EXCEPTION, AccelListener.ERROR_FAILED_TO_START);
- }
- // Wait until running
- long timeout = 2000;
- while ((this.status == STARTING) && (timeout > 0)) {
- timeout = timeout - 100;
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- if (timeout == 0) {
- return new PluginResult(PluginResult.Status.IO_EXCEPTION, AccelListener.ERROR_FAILED_TO_START);
- }
- }
- this.lastAccessTime = System.currentTimeMillis();
- JSONObject r = new JSONObject();
- r.put("x", this.x);
- r.put("y", this.y);
- r.put("z", this.z);
- // TODO: Should timestamp be sent?
- r.put("timestamp", this.timestamp);
- return new PluginResult(status, r);
- }
- else if (action.equals("setTimeout")) {
- try {
- float timeout = Float.parseFloat(args.getString(0));
- this.setTimeout(timeout);
- return new PluginResult(status, 0);
- } catch (NumberFormatException e) {
- status = PluginResult.Status.INVALID_ACTION;
- e.printStackTrace();
- } catch (JSONException e) {
- status = PluginResult.Status.JSON_EXCEPTION;
- e.printStackTrace();
- }
- }
- else if (action.equals("getTimeout")) {
- float f = this.getTimeout();
- return new PluginResult(status, f);
- } else {
- // Unsupported action
- return new PluginResult(PluginResult.Status.INVALID_ACTION);
- }
- return new PluginResult(status, result);
- } catch (JSONException e) {
- return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
- }
- }
+ /**
+ * Executes the request and returns PluginResult.
+ *
+ * @param action The action to execute.
+ * @param args JSONArry of arguments for the plugin.
+ * @param callbackId The callback id used when calling back into JavaScript.
+ * @return A PluginResult object with a status and message.
+ */
+ public PluginResult execute(String action, JSONArray args, String callbackId) {
+ PluginResult.Status status = PluginResult.Status.NO_RESULT;
+ String message = "";
+ PluginResult result = new PluginResult(status, message);
+ result.setKeepCallback(true);
+ try {
+ if (action.equals("getAcceleration")) {
+ if (this.status != AccelListener.RUNNING) {
+ // If not running, then this is an async call, so don't worry about waiting
+ // We drop the callback onto our stack, call start, and let start and the sensor callback fire off the callback down the road
+ this.callbacks.add(callbackId);
+ this.start();
+ } else {
+ return new PluginResult(PluginResult.Status.OK, this.getAccelerationJSON());
+ }
+ }
+ else if (action.equals("addWatch")) {
+ String watchId = args.getString(0);
+ this.watches.put(watchId, callbackId);
+ if (this.status != AccelListener.RUNNING) {
+ this.start();
+ }
+ }
+ else if (action.equals("clearWatch")) {
+ String watchId = args.getString(0);
+ if (this.watches.containsKey(watchId)) {
+ this.watches.remove(watchId);
+ if (this.size() == 0) {
+ this.stop();
+ }
+ }
+ return new PluginResult(PluginResult.Status.OK);
+ } else {
+ // Unsupported action
+ return new PluginResult(PluginResult.Status.INVALID_ACTION);
+ }
+ } catch (JSONException e) {
+ return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
+ }
+ 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) {
- if (action.equals("getStatus")) {
- return true;
- }
- else if (action.equals("getAcceleration")) {
- // Can only return value if RUNNING
- if (this.status == AccelListener.RUNNING) {
- return true;
- }
- }
- else if (action.equals("getTimeout")) {
- return true;
- }
- return false;
- }
+ /**
+ * 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) {
+ if (action.equals("getAcceleration") && this.status == AccelListener.RUNNING) {
+ return true;
+ } else if (action.equals("addWatch") && this.status == AccelListener.RUNNING) {
+ return true;
+ } else if (action.equals("clearWatch")) {
+ return true;
+ }
+ return false;
+ }
/**
* Called by AccelBroker when listener is to be shut down.
* Stop listener.
*/
public void onDestroy() {
- this.stop();
+ this.stop();
}
//--------------------------------------------------------------------------
// LOCAL METHODS
//--------------------------------------------------------------------------
+ private int size() {
+ return this.watches.size() + this.callbacks.size();
+ }
/**
* Start listening for acceleration sensor.
*
* @return status of listener
*/
- public int start() {
-
- // If already starting or running, then just return
- if ((this.status == AccelListener.RUNNING) || (this.status == AccelListener.STARTING)) {
- return this.status;
- }
+ private int start() {
+ // If already starting or running, then just return
+ if ((this.status == AccelListener.RUNNING) || (this.status == AccelListener.STARTING)) {
+ return this.status;
+ }
+
+ this.setStatus(AccelListener.STARTING);
+
+ // Get accelerometer from sensor manager
+ List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
- // Get accelerometer from sensor manager
- List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
-
- // If found, then register as listener
- if ((list != null) && (list.size() > 0)) {
- this.mSensor = list.get(0);
- this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_FASTEST);
- this.setStatus(AccelListener.STARTING);
- this.lastAccessTime = System.currentTimeMillis();
- }
-
- // If error, then set status to error
- else {
- this.setStatus(AccelListener.ERROR_FAILED_TO_START);
- }
-
- return this.status;
+ // If found, then register as listener
+ if ((list != null) && (list.size() > 0)) {
+ this.mSensor = list.get(0);
+ this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_FASTEST);
+ this.setStatus(AccelListener.STARTING);
+ } else {
+ this.setStatus(AccelListener.ERROR_FAILED_TO_START);
+ this.fail(AccelListener.ERROR_FAILED_TO_START, "No sensors found to register accelerometer listening to.");
+ return this.status;
+ }
+
+ // Wait until running
+ long timeout = 2000;
+ while ((this.status == STARTING) && (timeout > 0)) {
+ timeout = timeout - 100;
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ if (timeout == 0) {
+ this.setStatus(AccelListener.ERROR_FAILED_TO_START);
+ this.fail(AccelListener.ERROR_FAILED_TO_START, "Accelerometer could not be started.");
+ }
+ return this.status;
}
/**
* Stop listening to acceleration sensor.
*/
- public void stop() {
+ private void stop() {
if (this.status != AccelListener.STOPPED) {
- this.sensorManager.unregisterListener(this);
+ this.sensorManager.unregisterListener(this);
}
this.setStatus(AccelListener.STOPPED);
}
@@ -248,64 +234,92 @@ public class AccelListener extends Plugin implements SensorEventListener {
* @param SensorEvent event
*/
public void onSensorChanged(SensorEvent event) {
-
- // Only look at accelerometer events
+ // Only look at accelerometer events
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) {
return;
}
// If not running, then just return
if (this.status == AccelListener.STOPPED) {
- return;
+ return;
}
+ this.setStatus(AccelListener.RUNNING);
+
// Save time that event was received
this.timestamp = System.currentTimeMillis();
this.x = event.values[0];
this.y = event.values[1];
- this.z = event.values[2];
+ this.z = event.values[2];
- this.setStatus(AccelListener.RUNNING);
+ this.win();
+
+ if (this.size() == 0) {
+ this.stop();
+ }
+ }
- // If values haven't been read for TIMEOUT time, then turn off accelerometer sensor to save power
- if ((this.timestamp - this.lastAccessTime) > this.TIMEOUT) {
- this.stop();
- }
+ private void fail(int code, String message) {
+ // Error object
+ JSONObject errorObj = new JSONObject();
+ try {
+ errorObj.put("code", code);
+ errorObj.put("message", message);
+ } catch (JSONException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ PluginResult err = new PluginResult(PluginResult.Status.ERROR, errorObj);
+
+ for (String callbackId: this.callbacks)
+ {
+ this.error(err, callbackId);
+ }
+ this.callbacks.clear();
+
+ err.setKeepCallback(true);
+
+ Iterator it = this.watches.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry pairs = (Map.Entry)it.next();
+ this.error(err, (String)pairs.getValue());
+ }
+ }
+
+ private void win() {
+ // Success return object
+ PluginResult result = new PluginResult(PluginResult.Status.OK, this.getAccelerationJSON());
+
+ for (String callbackId: this.callbacks)
+ {
+ this.success(result, callbackId);
+ }
+ this.callbacks.clear();
+
+ result.setKeepCallback(true);
+
+ Iterator it = this.watches.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry pairs = (Map.Entry)it.next();
+ this.success(result, (String)pairs.getValue());
+ }
}
- /**
- * Get status of accelerometer sensor.
- *
- * @return status
- */
- public int getStatus() {
- return this.status;
- }
-
- /**
- * Set the timeout to turn off accelerometer sensor if getX() hasn't been called.
- *
- * @param timeout Timeout in msec.
- */
- public void setTimeout(float timeout) {
- this.TIMEOUT = timeout;
- }
-
- /**
- * Get the timeout to turn off accelerometer sensor if getX() hasn't been called.
- *
- * @return timeout in msec
- */
- public float getTimeout() {
- return this.TIMEOUT;
- }
-
- /**
- * Set the status and send it to JavaScript.
- * @param status
- */
private void setStatus(int status) {
- this.status = status;
+ this.status = status;
+ }
+
+ private JSONObject getAccelerationJSON() {
+ JSONObject r = new JSONObject();
+ try {
+ r.put("x", this.x);
+ r.put("y", this.y);
+ r.put("z", this.z);
+ r.put("timestamp", this.timestamp);
+ } catch (JSONException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return r;
}
-
-}
+}
\ No newline at end of file