Return-Path: X-Original-To: apmail-incubator-callback-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-callback-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 5AFAB9DC5 for ; Fri, 18 May 2012 22:20:40 +0000 (UTC) Received: (qmail 85163 invoked by uid 500); 18 May 2012 22:20:40 -0000 Delivered-To: apmail-incubator-callback-commits-archive@incubator.apache.org Received: (qmail 85141 invoked by uid 500); 18 May 2012 22:20:40 -0000 Mailing-List: contact callback-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: callback-dev@incubator.apache.org Delivered-To: mailing list callback-commits@incubator.apache.org Received: (qmail 85074 invoked by uid 99); 18 May 2012 22:20:40 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 18 May 2012 22:20:40 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id E9E3516CD3; Fri, 18 May 2012 22:20:39 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: filmaj@apache.org To: callback-commits@incubator.apache.org X-Mailer: ASF-Git Admin Mailer Subject: [5/8] android commit: [CB-463] rewrite of accel plugin Message-Id: <20120518222039.E9E3516CD3@tyr.zones.apache.org> Date: Fri, 18 May 2012 22:20:39 +0000 (UTC) [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/master Commit: 71e47aa77286298ddf03dc1fa8c9c42046877aad Parents: 0850229 Author: Fil Maj Authored: Mon May 14 13:00:11 2012 -0700 Committer: Fil Maj 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 watches = new HashMap(); + private List callbacks = new ArrayList(); /** * 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 list = this.sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER); - // Get accelerometer from sensor manager - List 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