[CB-463] rewrite of accel plugin

This commit is contained in:
Fil Maj 2012-05-14 13:00:11 -07:00
parent 0850229c9f
commit 71e47aa772

View File

@ -18,7 +18,11 @@
*/ */
package org.apache.cordova; package org.apache.cordova;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import org.apache.cordova.api.CordovaInterface; import org.apache.cordova.api.CordovaInterface;
import org.apache.cordova.api.Plugin; import org.apache.cordova.api.Plugin;
@ -32,6 +36,8 @@ import android.hardware.Sensor;
import android.hardware.SensorEvent; import android.hardware.SensorEvent;
import android.hardware.SensorEventListener; import android.hardware.SensorEventListener;
import android.hardware.SensorManager; import android.hardware.SensorManager;
import android.location.Location;
import android.util.Log;
import android.content.Context; import android.content.Context;
/** /**
@ -45,15 +51,15 @@ public class AccelListener extends Plugin implements SensorEventListener {
public static int RUNNING = 2; public static int RUNNING = 2;
public static int ERROR_FAILED_TO_START = 3; public static int ERROR_FAILED_TO_START = 3;
public float TIMEOUT = 30000; // Timeout in msec to shut off listener private float x,y,z; // most recent acceleration values
private long timestamp; // time of most recent value
private int status; // status of listener
float x,y,z; // most recent acceleration values private SensorManager sensorManager; // Sensor manager
long timestamp; // time of most recent value private Sensor mSensor; // Acceleration sensor returned by sensor manager
int status; // status of listener
long lastAccessTime; // time the value was last retrieved
private SensorManager sensorManager;// Sensor manager private HashMap<String, String> watches = new HashMap<String, String>();
Sensor mSensor; // Acceleration sensor returned by sensor manager private List<String> callbacks = new ArrayList<String>();
/** /**
* Create an accelerometer listener. * Create an accelerometer listener.
@ -86,76 +92,45 @@ public class AccelListener extends Plugin implements SensorEventListener {
* @return A PluginResult object with a status and message. * @return A PluginResult object with a status and message.
*/ */
public PluginResult execute(String action, JSONArray args, String callbackId) { public PluginResult execute(String action, JSONArray args, String callbackId) {
PluginResult.Status status = PluginResult.Status.OK; PluginResult.Status status = PluginResult.Status.NO_RESULT;
String result = ""; String message = "";
PluginResult result = new PluginResult(status, message);
result.setKeepCallback(true);
try { try {
if (action.equals("getStatus")) { if (action.equals("getAcceleration")) {
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) { if (this.status != AccelListener.RUNNING) {
int r = this.start(); // If not running, then this is an async call, so don't worry about waiting
if (r == AccelListener.ERROR_FAILED_TO_START) { // We drop the callback onto our stack, call start, and let start and the sensor callback fire off the callback down the road
return new PluginResult(PluginResult.Status.IO_EXCEPTION, AccelListener.ERROR_FAILED_TO_START); this.callbacks.add(callbackId);
} this.start();
// Wait until running } else {
long timeout = 2000; return new PluginResult(PluginResult.Status.OK, this.getAccelerationJSON());
while ((this.status == STARTING) && (timeout > 0)) {
timeout = timeout - 100;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} }
} }
if (timeout == 0) { else if (action.equals("addWatch")) {
return new PluginResult(PluginResult.Status.IO_EXCEPTION, AccelListener.ERROR_FAILED_TO_START); String watchId = args.getString(0);
this.watches.put(watchId, callbackId);
if (this.status != AccelListener.RUNNING) {
this.start();
} }
} }
this.lastAccessTime = System.currentTimeMillis(); else if (action.equals("clearWatch")) {
JSONObject r = new JSONObject(); String watchId = args.getString(0);
r.put("x", this.x); if (this.watches.containsKey(watchId)) {
r.put("y", this.y); this.watches.remove(watchId);
r.put("z", this.z); if (this.size() == 0) {
// TODO: Should timestamp be sent? this.stop();
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")) { return new PluginResult(PluginResult.Status.OK);
float f = this.getTimeout();
return new PluginResult(status, f);
} else { } else {
// Unsupported action // Unsupported action
return new PluginResult(PluginResult.Status.INVALID_ACTION); return new PluginResult(PluginResult.Status.INVALID_ACTION);
} }
return new PluginResult(status, result);
} catch (JSONException e) { } catch (JSONException e) {
return new PluginResult(PluginResult.Status.JSON_EXCEPTION); return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
} }
return result;
} }
/** /**
@ -165,16 +140,11 @@ public class AccelListener extends Plugin implements SensorEventListener {
* @return T=returns value * @return T=returns value
*/ */
public boolean isSynch(String action) { public boolean isSynch(String action) {
if (action.equals("getStatus")) { if (action.equals("getAcceleration") && this.status == AccelListener.RUNNING) {
return true; return true;
} } else if (action.equals("addWatch") && this.status == AccelListener.RUNNING) {
else if (action.equals("getAcceleration")) {
// Can only return value if RUNNING
if (this.status == AccelListener.RUNNING) {
return true; return true;
} } else if (action.equals("clearWatch")) {
}
else if (action.equals("getTimeout")) {
return true; return true;
} }
return false; return false;
@ -192,18 +162,22 @@ public class AccelListener extends Plugin implements SensorEventListener {
// LOCAL METHODS // LOCAL METHODS
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
private int size() {
return this.watches.size() + this.callbacks.size();
}
/** /**
* Start listening for acceleration sensor. * Start listening for acceleration sensor.
* *
* @return status of listener * @return status of listener
*/ */
public int start() { private int start() {
// If already starting or running, then just return // If already starting or running, then just return
if ((this.status == AccelListener.RUNNING) || (this.status == AccelListener.STARTING)) { if ((this.status == AccelListener.RUNNING) || (this.status == AccelListener.STARTING)) {
return this.status; return this.status;
} }
this.setStatus(AccelListener.STARTING);
// Get accelerometer from sensor manager // Get accelerometer from sensor manager
List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER); List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
@ -212,21 +186,33 @@ public class AccelListener extends Plugin implements SensorEventListener {
this.mSensor = list.get(0); this.mSensor = list.get(0);
this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_FASTEST); this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_FASTEST);
this.setStatus(AccelListener.STARTING); this.setStatus(AccelListener.STARTING);
this.lastAccessTime = System.currentTimeMillis(); } else {
}
// If error, then set status to error
else {
this.setStatus(AccelListener.ERROR_FAILED_TO_START); 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; return this.status;
} }
/** /**
* Stop listening to acceleration sensor. * Stop listening to acceleration sensor.
*/ */
public void stop() { private void stop() {
if (this.status != AccelListener.STOPPED) { if (this.status != AccelListener.STOPPED) {
this.sensorManager.unregisterListener(this); this.sensorManager.unregisterListener(this);
} }
@ -248,7 +234,6 @@ public class AccelListener extends Plugin implements SensorEventListener {
* @param SensorEvent event * @param SensorEvent event
*/ */
public void onSensorChanged(SensorEvent event) { public void onSensorChanged(SensorEvent event) {
// Only look at accelerometer events // Only look at accelerometer events
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) { if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) {
return; return;
@ -259,53 +244,82 @@ public class AccelListener extends Plugin implements SensorEventListener {
return; return;
} }
this.setStatus(AccelListener.RUNNING);
// Save time that event was received // Save time that event was received
this.timestamp = System.currentTimeMillis(); this.timestamp = System.currentTimeMillis();
this.x = event.values[0]; this.x = event.values[0];
this.y = event.values[1]; this.y = event.values[1];
this.z = event.values[2]; this.z = event.values[2];
this.setStatus(AccelListener.RUNNING); this.win();
// If values haven't been read for TIMEOUT time, then turn off accelerometer sensor to save power if (this.size() == 0) {
if ((this.timestamp - this.lastAccessTime) > this.TIMEOUT) {
this.stop(); this.stop();
} }
} }
/** private void fail(int code, String message) {
* Get status of accelerometer sensor. // Error object
* JSONObject errorObj = new JSONObject();
* @return status try {
*/ errorObj.put("code", code);
public int getStatus() { errorObj.put("message", message);
return this.status; } 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() {
* Set the timeout to turn off accelerometer sensor if getX() hasn't been called. // Success return object
* PluginResult result = new PluginResult(PluginResult.Status.OK, this.getAccelerationJSON());
* @param timeout Timeout in msec.
*/ for (String callbackId: this.callbacks)
public void setTimeout(float timeout) { {
this.TIMEOUT = timeout; 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 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) { 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;
}
} }