[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 <maj....@gmail.com>
Authored: Mon May 14 13:00:11 2012 -0700
Committer: Fil Maj <maj....@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

Reply via email to