You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by fi...@apache.org on 2013/01/22 02:57:58 UTC

[27/52] [partial] support for 2.4.0rc1. "vendored" the platform libs in. added Gord and Braden as contributors. removed dependency on unzip and axed the old download-cordova code.

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext-qnx/org.apache.cordova/client.js
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext-qnx/org.apache.cordova/client.js b/lib/cordova-blackberry/framework/ext-qnx/org.apache.cordova/client.js
new file mode 100644
index 0000000..f8308b8
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext-qnx/org.apache.cordova/client.js
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2010-2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext-qnx/org.apache.cordova/index.js
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext-qnx/org.apache.cordova/index.js b/lib/cordova-blackberry/framework/ext-qnx/org.apache.cordova/index.js
new file mode 100644
index 0000000..4a60b93
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext-qnx/org.apache.cordova/index.js
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010-2011 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var Whitelist = require("../../lib/policy/whitelist").Whitelist,
+    whitelist = new Whitelist(),
+    noop = function () {};
+
+module.exports = {
+    isWhitelisted: function (success, fail, args) {
+        var url = JSON.parse(decodeURIComponent(args[0])),
+            success = success || noop,
+            fail = fail || noop;
+
+        if (url) {
+            success(whitelist.isAccessAllowed(url));
+        }
+        else {
+            error("please provide an url");
+        }
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext-qnx/org.apache.cordova/manifest.json
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext-qnx/org.apache.cordova/manifest.json b/lib/cordova-blackberry/framework/ext-qnx/org.apache.cordova/manifest.json
new file mode 100644
index 0000000..9efdda2
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext-qnx/org.apache.cordova/manifest.json
@@ -0,0 +1,5 @@
+{
+    "global": false,
+    "namespace": "org.apache.cordova",
+    "dependencies": []
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext-qnx/readme.md
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext-qnx/readme.md b/lib/cordova-blackberry/framework/ext-qnx/readme.md
new file mode 100644
index 0000000..6527192
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext-qnx/readme.md
@@ -0,0 +1 @@
+Placeholder for native extensions needed on qnx

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/.classpath
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/.classpath b/lib/cordova-blackberry/framework/ext/.classpath
new file mode 100644
index 0000000..8d3a567
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="res"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/net.rim.ejde.BlackBerryVMInstallType/BlackBerry JRE 5.0.0"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/.project
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/.project b/lib/cordova-blackberry/framework/ext/.project
new file mode 100644
index 0000000..ecbf8d5
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/.project
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>CordovaExtension</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>net.rim.ejde.internal.builder.BlackBerryPreprocessBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>net.rim.ejde.internal.builder.BlackBerryResourcesBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>net.rim.ejde.BlackBerryPreProcessNature</nature>
+		<nature>net.rim.ejde.BlackBerryProjectCoreNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/.settings/net.rim.browser.tools.debug.widget.prefs
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/.settings/net.rim.browser.tools.debug.widget.prefs b/lib/cordova-blackberry/framework/ext/.settings/net.rim.browser.tools.debug.widget.prefs
new file mode 100644
index 0000000..524fddd
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/.settings/net.rim.browser.tools.debug.widget.prefs
@@ -0,0 +1,3 @@
+#Sun May 23 23:01:24 PDT 2010
+eclipse.preferences.version=1
+outputfolder=build

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/.settings/org.eclipse.jdt.core.prefs b/lib/cordova-blackberry/framework/ext/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..be7e57d
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Sun May 23 23:00:44 PDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=ignore
+org.eclipse.jdt.core.compiler.source=1.3

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/BlackBerry_App_Descriptor.xml
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/BlackBerry_App_Descriptor.xml b/lib/cordova-blackberry/framework/ext/BlackBerry_App_Descriptor.xml
new file mode 100644
index 0000000..bb973e8
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/BlackBerry_App_Descriptor.xml
@@ -0,0 +1,36 @@
+<Properties ModelVersion="1.1.2">
+<!-- 
+     Licensed to the Apache Software Foundation (ASF) under one
+     or more contributor license agreements.  See the NOTICE file
+     distributed with this work for additional information
+     regarding copyright ownership.  The ASF licenses this file
+     to you under the Apache License, Version 2.0 (the
+     "License"); you may not use this file except in compliance
+     with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing,
+     software distributed under the License is distributed on an
+     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+     KIND, either express or implied.  See the License for the
+     specific language governing permissions and limitations
+     under the License.
+-->
+  <General Title="" Version="1.0.0" Vendor="BlackBerry Developer" Description=""/>
+  <Application Type="BlackBerry Application" MainMIDletName="" MainArgs="" HomeScreenPosition="0" StartupTier="7" IsSystemModule="false" IsAutostartup="false"/>
+  <Resources hasTitleResource="false" TitleResourceBundleName="" TitleResourceBundleRelativePath="" TitleResourceBundleClassName="" TitleResourceBundleKey="" DescriptionId="">
+    <Icons/>
+  </Resources>
+  <Compile OutputCompilerMessages="false" ConvertImages="false" CreateWarningForNoExportedRoutine="true" CompressResources="false" AliasList="">
+    <PreprocessorDefines/>
+  </Compile>
+  <Packaging OutputFileName="Cordova" OutputFolder="deliverables" PreBuildStep="" PostBuildStep="" CleanStep="" GenerateALXFile="false">
+    <AlxFiles/>
+  </Packaging>
+  <HiddenProperties>
+    <ClassProtection/>
+    <PackageProtection/>
+  </HiddenProperties>
+  <AlternateEntryPoints/>
+</Properties>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/library.xml
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/library.xml b/lib/cordova-blackberry/framework/ext/src/library.xml
new file mode 100644
index 0000000..d408e9f
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/library.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+-->
+<library>
+	<extension>
+		<entryClass>org.apache.cordova.CordovaExtension</entryClass>
+	</extension>
+	<features>
+		<feature id="org.apache.cordova" version="1.0.0">Cordova JavaScript Extension</feature>
+		<feature id="blackberry.connection" version="1.0.0">Stub in for backwards bb10 support</feature>
+		<feature id="blackberry.io" version="1.0.0">Stub in for backwards bb10 support</feature>
+		<feature id="blackberry.invoked" version="1.0.0">Stub in for backwards bb10 support</feature>
+		<feature id="blackberry.invoke.card" version="1.0.0">Stub in for backwards bb10 support</feature>
+		<feature id="blackberry.ui.contextmenu" version="1.0.0">Stub in for backwards bb10 support</feature>
+		<feature id="blackberry.io.filetransfer" version="1.0.0">Stub in for backwards bb10 support</feature>
+		<feature id="blackberry.pim.contacts" version="1.0.0">Stub in for backwards bb10 support</feature>
+		<feature id="blackberry.bbm.platform" version="1.0.0">Stub in for backwards bb10 support</feature>
+	</features>
+</library>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/CordovaExtension.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/CordovaExtension.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/CordovaExtension.java
new file mode 100644
index 0000000..62943b4
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/CordovaExtension.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * Copyright (c) 2011, Research In Motion Limited.
+ */
+package org.apache.cordova;
+
+import net.rim.device.api.browser.field2.BrowserField;
+import net.rim.device.api.script.ScriptEngine;
+import net.rim.device.api.system.Application;
+import net.rim.device.api.web.WidgetConfig;
+import net.rim.device.api.web.WidgetExtension;
+import net.rim.device.api.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.cordova.api.PluginManager;
+import org.apache.cordova.api.PluginResult;
+import org.apache.cordova.notification.Notification;
+import org.apache.cordova.util.Log;
+import org.apache.cordova.util.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * CordovaExtension is a BlackBerry WebWorks JavaScript extension.  It
+ * represents a single feature that can be used to access device capabilities.
+ */
+public final class CordovaExtension implements WidgetExtension {
+
+    // Weak reference encapsulating BrowserField object used to display the application
+    // We use the weak reference because keeping a direct reference can
+    // cause memory leak issues in WebWorks. Original solution described
+    // and suggested by Tim Neil on the BlackBerry support forums.
+    // Thanks Tim!
+    protected static WeakReference browser = null;
+
+    // Browser script engine
+    //
+    protected static ScriptEngine script;
+
+    // Application name
+    //
+    protected static String appName;
+
+    // Application GUID
+    //
+    protected static long appID;
+
+    // Plugin Manager
+    //
+    protected PluginManager pluginManager;
+
+    // Feature ID
+    //
+    private static final String FEATURE_ID ="org.apache.cordova";
+
+    // Called when the BlackBerry Widget references this extension for the first time.
+    // It provides a list of feature IDs exposed by this extension.
+    //
+    public String[] getFeatureList() {
+      return new String[] {FEATURE_ID};
+    }
+
+    // Called whenever a widget loads a resource that requires a feature ID that is supplied
+    // in the getFeatureList
+    //
+    public void loadFeature(String feature, String version, Document doc,
+            ScriptEngine scriptEngine) throws Exception {
+        script = scriptEngine;
+        // Not sure why logger is not already enabled?
+        Logger.enableLogging();
+        if (feature.equals(FEATURE_ID)) {
+            pluginManager = new PluginManager(this);
+
+            // create and parse the plugins.xml
+            Document c = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(Application.class.getResourceAsStream("/plugins.xml"));
+
+            NodeList plugins = c.getElementsByTagName("plugin");
+            if (plugins.getLength() == 0) {
+                Logger.warn("If you are using any Cordova APIs you will need to "+
+                        "specify them in the config.xml using <gap:plugin name=\"MyPlugin\" "+
+                        "value=\"com.example.MyPlugin\"/>");
+            }
+            for(int i=0; i<plugins.getLength() ; i++){
+                Node plugin = plugins.item(i);
+                Logger.log("Found plugin " + plugin.getAttributes().getNamedItem("name").getNodeValue() + " = " +
+                        plugin.getAttributes().getNamedItem("value").getNodeValue());
+                pluginManager.addService(plugin.getAttributes().getNamedItem("name").getNodeValue(),
+                        plugin.getAttributes().getNamedItem("value").getNodeValue());
+            }
+
+            scriptEngine.addExtension("org.apache.cordova.JavaPluginManager",  pluginManager);
+            scriptEngine.addExtension("org.apache.cordova.Logger",         new Log());
+
+            // let Cordova JavaScript know that extensions have been loaded
+            // if this is premature, we at least set the _nativeReady flag to true
+            // so that when the JS side is ready, it knows native side is too
+            Logger.log(this.getClass().getName() + ": invoking Cordova.onNativeReady.fire()");
+            scriptEngine.executeScript("try {cordova.require('cordova/channel').onNativeReady.fire();} catch(e) {_nativeReady = true;}", null);
+        }
+    }
+
+    // Called so that the extension can get a reference to the configuration or browser field object
+    //
+    public void register(WidgetConfig widgetConfig, BrowserField browserField) {
+        browser = new WeakReference(browserField);
+
+        // grab widget application name and use it to generate a unique ID
+        appName = widgetConfig.getName();
+        appID = Long.parseLong(Math.abs(("org.apache.cordova."+appName).hashCode())+"",16);
+
+        // create a notification profile for the application
+        Notification.registerProfile();
+    }
+
+    /**
+     * Called to clean up any features when the extension is unloaded.  This is
+     * invoked by the WebWorks Framework when another URL is loaded.
+     *
+     * @see net.rim.device.api.web.WidgetExtension#unloadFeatures(org.w3c.dom.Document)
+     */
+    public void unloadFeatures(Document doc) {
+        // Cleanup plugin resources.
+        if (pluginManager != null) {
+            pluginManager.destroy();
+        }
+    }
+
+    public static void invokeScript(final String js) {
+        // Use a new thread so that JavaScript is invoked asynchronously.
+        // Otherwise executeScript doesn't return until JavaScript call back
+        // is finished.
+        (new Thread() {
+            public void run() {
+                try {
+                    script.executeScript(js, null);
+                } catch (Exception e) {
+                    // This is likely an IllegalStateException which is thrown
+                    // because the framework is in the process of being shutdown
+                    // so communication to JavaScript side is not allowed.
+                    Logger.log("Caught exception while executing script: "
+                            + e.getMessage());
+                }
+            }
+        }).start();
+    }
+
+    /**
+     * Invokes the Cordova success callback specified by callbackId.
+     * @param callbackId   unique callback ID
+     * @param result       Cordova PluginResult containing result
+     */
+    public static void invokeSuccessCallback(String callbackId, PluginResult result) {
+      invokeScript(result.toSuccessCallbackString(callbackId));
+    }
+
+    /**
+     * Invokes the Cordova error callback specified by callbackId.
+     * @param callbackId   unique callback ID
+     * @param result       Cordova PluginResult containing result
+     */
+    public static void invokeErrorCallback(String callbackId, PluginResult result) {
+      invokeScript(result.toErrorCallbackString(callbackId));
+    }
+
+    /**
+     * Provides access to the browser instance for the application.
+     */
+    public static BrowserField getBrowserField() {
+      Object o = browser.get();
+      if ( o instanceof BrowserField ) {
+        return (BrowserField)o;
+      } else {
+        return null;
+      }
+    }
+
+    /**
+     * Returns the widget application name.
+     */
+    public static String getAppName() {
+        return appName;
+    }
+
+    /**
+     * Returns unique ID of the widget application.
+     */
+    public static long getAppID() {
+        return appID;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/accelerometer/Accelerometer.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/accelerometer/Accelerometer.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/accelerometer/Accelerometer.java
new file mode 100644
index 0000000..2088122
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/accelerometer/Accelerometer.java
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.accelerometer;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import net.rim.device.api.system.AccelerometerData;
+import net.rim.device.api.system.AccelerometerListener;
+import net.rim.device.api.system.AccelerometerSensor;
+import net.rim.device.api.system.Application;
+
+import org.apache.cordova.api.Plugin;
+import org.apache.cordova.api.PluginResult;
+import org.apache.cordova.json4j.JSONArray;
+import org.apache.cordova.json4j.JSONException;
+import org.apache.cordova.json4j.JSONObject;
+import org.apache.cordova.util.Logger;
+
+public class Accelerometer extends Plugin implements AccelerometerListener {
+    private static final String LOG_TAG = "Accelerometer: ";
+
+    private static final String ACTION_START = "start";
+    private static final String ACTION_STOP = "stop";
+
+    private static final int STOPPED = 0;
+    private static final int STARTING = 1;
+    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 state = STOPPED; // state of this listener
+    private long initTime = 0;
+
+    /**
+     * Reference to single start callbackid
+     */
+    private String callbackId;
+
+    public PluginResult execute(String action, JSONArray args, String callbackId) {
+        PluginResult result;
+        if (!AccelerometerSensor.isSupported()) {
+            result = new PluginResult(
+                    PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION,
+                    "Accelerometer sensor not supported");
+        } else if (ACTION_START.equals(action)) {
+            result = start(callbackId);
+        } else if (ACTION_STOP.equals(action)) {
+            result = stop();
+        } else {
+            result = new PluginResult(PluginResult.Status.INVALID_ACTION,
+                    "Accelerometer: Invalid action:" + action);
+        }
+
+        return result;
+    }
+
+    /**
+     * 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) {
+        short x = accelData.getLastXAcceleration();
+        short y = accelData.getLastYAcceleration();
+        short z = accelData.getLastZAcceleration();
+
+        // If any value is not zero, assume sensor is now active and set state.
+        if (state == STARTING && (x != 0 || y != 0 || z != 0)) {
+            state = RUNNING;
+        }
+
+        if (state == RUNNING) {
+            // Send the new accelerometer data.
+            JSONObject accel = new JSONObject();
+            try {
+                accel.put("x", normalize(x));
+                accel.put("y", normalize(y));
+                accel.put("z", normalize(z));
+                accel.put("timestamp", accelData.getLastTimestamp());
+                sendResult(true,
+                        new PluginResult(PluginResult.Status.OK, accel), true);
+            } catch (JSONException e) {
+                sendResult(false, new PluginResult(
+                        PluginResult.Status.JSON_EXCEPTION, "JSONException:"
+                                + e.getMessage()), false);
+            }
+        } else if ((System.currentTimeMillis() - initTime) > 2000) {
+            // If the sensor does not become active within 2 seconds of
+            // the request to start it, fail out.
+            stop();
+            state = ERROR_FAILED_TO_START;
+            JSONObject errorObj = new JSONObject();
+            try {
+                errorObj.put("code", ERROR_FAILED_TO_START);
+                errorObj.put("message", "Accelerometer could not be started.");
+            } catch (JSONException e) {
+                Logger.log(LOG_TAG
+                        + "Failed to build JSON object for ERROR_FAILED_TO_START.");
+            }
+            sendResult(false, new PluginResult(PluginResult.Status.ERROR,
+                    errorObj), false);
+        }
+    }
+
+    /**
+     * Called when Plugin is destroyed.
+     */
+    public void onDestroy() {
+        stop();
+    }
+
+    /**
+     * Adds a SystemListener to listen for changes to the battery state. The
+     * listener is only registered if one has not already been added.
+     */
+    private PluginResult start(String callbackId) {
+        this.callbackId = callbackId;
+        if (_rawDataChannel == null || !_rawDataChannel.isOpen()) {
+            _rawDataChannel = AccelerometerSensor
+                    .openRawDataChannel(Application.getApplication());
+            Logger.log(LOG_TAG + "sensor channel opened");
+
+            initTime = System.currentTimeMillis();
+            state = STARTING;
+            _rawDataChannel.setAccelerometerListener(this);
+            Logger.log(LOG_TAG + "sensor listener added");
+        }
+
+        PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
+        result.setKeepCallback(true);
+        return result;
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * Helper function to send a PluginResult to the saved call back ID.
+     *
+     * @param issuccess
+     *            true if this is a successful result, false otherwise.
+     * @param result
+     *            the PluginResult to return
+     * @param keepCallback
+     *            Boolean value indicating whether to keep the call back id
+     *            active.
+     */
+    private synchronized void sendResult(boolean issuccess,
+            PluginResult result, boolean keepCallback) {
+
+        if (result != null) {
+            // Must keep the call back active for future watch events.
+            result.setKeepCallback(keepCallback);
+
+            if (issuccess) {
+                success(result, this.callbackId);
+            } else {
+                error(result, this.callbackId);
+            }
+        }
+    }
+
+    /**
+     * Stops accelerometer listener and closes the sensor channel.
+     */
+    private synchronized PluginResult stop() {
+        if (_rawDataChannel != null && _rawDataChannel.isOpen()) {
+
+            // Remove the battery listener.
+            _rawDataChannel.removeAccelerometerListener();
+            _rawDataChannel.close();
+            _rawDataChannel = null;
+
+            Logger.log(LOG_TAG + "sensor channel closed");
+        }
+
+        state = STOPPED;
+
+        return new PluginResult(PluginResult.Status.OK);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/IPlugin.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/IPlugin.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/IPlugin.java
new file mode 100644
index 0000000..7e09d31
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/IPlugin.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.api;
+
+import org.apache.cordova.CordovaExtension;
+import org.apache.cordova.json4j.JSONArray;
+
+/**
+ * Plugin interface must be implemented by any plugin classes.
+ *
+ * The execute method is called by the PluginManager.
+ */
+public interface IPlugin {
+
+	/**
+	 * 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.
+	 */
+	PluginResult execute(String action, JSONArray args, String callbackId);
+
+	/**
+	 * 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);
+
+	/**
+	 * Sets the context of the Plugin. This can then be used to do things like
+	 * get file paths associated with the Activity.
+	 *
+	 * @param ctx The main application class.
+	 */
+	void setContext(CordovaExtension ctx);
+
+    /**
+     * Called when the system is about to start resuming a previous activity.
+     */
+    void onPause();
+
+    /**
+     * Called when the activity will start interacting with the user.
+     */
+    void onResume();
+
+    /**
+     * The final call you receive before your activity is destroyed.
+     */
+    void onDestroy();
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/Plugin.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/Plugin.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/Plugin.java
new file mode 100644
index 0000000..6f70b85
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/Plugin.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.api;
+
+import org.apache.cordova.CordovaExtension;
+import org.apache.cordova.json4j.JSONArray;
+
+/**
+ * Plugin interface must be implemented by any plugin classes.
+ *
+ * The execute method is called by the PluginManager.
+ */
+public abstract class Plugin implements IPlugin {
+
+    public CordovaExtension ctx;					// Main application object
+
+	/**
+	 * 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 abstract PluginResult execute(String action, JSONArray args, String callbackId);
+
+	/**
+	 * 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 false;
+	}
+
+	/**
+	 * Sets the context of the Plugin. 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(CordovaExtension ctx) {
+		this.ctx = ctx;
+	}
+
+    /**
+     * Called when Plugin is paused.
+     */
+    public void onPause() {
+    }
+
+    /**
+     * Called when Plugin is resumed.
+     */
+    public void onResume() {
+    }
+
+    /**
+     * Called when Plugin is destroyed.
+     */
+    public void onDestroy() {
+    }
+
+    /**
+     * Send generic JavaScript statement back to JavaScript.
+     * success(...) and error(...) should be used instead where possible.
+     *
+     * @param statement
+     */
+    public void invokeScript(String statement) {
+        CordovaExtension.invokeScript(statement);
+    }
+
+    /**
+     * Call the JavaScript success callback for this plugin.
+     *
+     * This can be used if the execute code for the plugin is asynchronous meaning
+     * that execute should return null and the callback from the async operation can
+     * call success(...) or error(...)
+     *
+     * @param pluginResult		The result to return.
+	 * @param callbackId		The callback id used when calling back into JavaScript.
+     */
+    public static void success(PluginResult pluginResult, String callbackId) {
+        CordovaExtension.invokeSuccessCallback(callbackId, pluginResult);
+    }
+
+    /**
+     * Call the JavaScript error callback for this plugin.
+     *
+     * @param pluginResult		The result to return.
+	 * @param callbackId		The callback id used when calling back into JavaScript.
+     */
+    public static void error(PluginResult pluginResult, String callbackId) {
+        CordovaExtension.invokeErrorCallback(callbackId, pluginResult);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/PluginManager.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/PluginManager.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/PluginManager.java
new file mode 100644
index 0000000..a8e5e9b
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/PluginManager.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.api;
+
+import java.util.Hashtable;
+
+import org.apache.cordova.CordovaExtension;
+import org.apache.cordova.util.FileUtils;
+import org.apache.cordova.util.Logger;
+
+import net.rim.device.api.script.Scriptable;
+import net.rim.device.api.script.ScriptableFunction;
+
+/**
+ * PluginManager represents an object in the script engine. It can be accessed
+ * from the script environment using <code>cordova.PluginManager</code>.
+ *
+ * PluginManager provides a function, <code>exec</code>, that can be invoked
+ * from the script environment: <code>cordova.PluginManager.exec(...)</code>.
+ * Invoking this function causes the script engine to load the appropriate
+ * Cordova Plugin and perform the specified action.
+ */
+public final class PluginManager extends Scriptable {
+
+    /**
+     * Field used to invoke Plugin actions.
+     */
+    public static String FIELD_EXEC = "exec";
+
+    /**
+     * Field used to cleanup Plugins.
+     */
+    public static String FIELD_DESTROY = "destroy";
+
+    /**
+     * Field used to indicate application has been brought to foreground.
+     */
+    public static String FIELD_RESUME = "resume";
+
+    /**
+     * Field used to indicate application has been sent to background
+     */
+    public static String FIELD_PAUSE = "pause";
+
+    /**
+     * Field used to register a Plugin.
+     */
+    public static String FIELD_ADD_PLUGIN = "addPlugin";
+
+    /**
+     * Loads the appropriate Cordova Plugins and invokes their actions.
+     */
+    private final PluginManagerFunction pluginManagerFunction;
+
+    /**
+     * Maps available services to Java class names.
+     */
+    private Hashtable services = new Hashtable();
+
+    /**
+     * Constructor.  Adds available Cordova services.
+     * @param ext   The Cordova JavaScript Extension
+     */
+    public PluginManager(CordovaExtension ext) {
+        this.pluginManagerFunction = new PluginManagerFunction(ext, this);
+    }
+
+    /**
+     * The following fields are supported from the script environment:
+     *
+     *  <code>cordova.pluginManager.exec</code> - Loads the appropriate
+     *  Plugin and invokes the specified action.
+     *
+     *  <code>cordova.pluginManager.destroy</code> - Invokes the <code>onDestroy</code>
+     *  method on all Plugins to give them a chance to cleanup before exit.
+     */
+    public Object getField(String name) throws Exception {
+        if (name.equals(FIELD_EXEC)) {
+            return this.pluginManagerFunction;
+        }
+        else if (name.equals(FIELD_DESTROY)) {
+            return new ScriptableFunction() {
+                public Object invoke(Object obj, Object[] oargs) throws Exception {
+                    destroy();
+                    return null;
+                }
+            };
+        }
+        else if (name.equals(FIELD_RESUME)) {
+            final PluginManagerFunction plugin_mgr = this.pluginManagerFunction;
+            return new ScriptableFunction() {
+                public Object invoke(Object obj, Object[] oargs) throws Exception {
+                    plugin_mgr.onResume();
+                    return null;
+                }
+            };
+        }
+        else if (name.equals(FIELD_PAUSE)) {
+            final PluginManagerFunction plugin_mgr = this.pluginManagerFunction;
+            return new ScriptableFunction() {
+                public Object invoke(Object obj, Object[] oargs) throws Exception {
+                    plugin_mgr.onPause();
+                    return null;
+                }
+            };
+        }
+        else if (name.equals(FIELD_ADD_PLUGIN)) {
+            Logger.log("Plugins are now added through the plugins.xml in the application root.");
+        }
+        return super.getField(name);
+    }
+
+    /**
+     * Add a class that implements a service.
+     *
+     * @param serviceName   The service name.
+     * @param className     The Java class name that implements the service.
+     */
+    public void addService(String serviceName, String className) {
+        this.services.put(serviceName, className);
+    }
+
+    /**
+     * Cleanup the plugin resources and delete temporary directory that may have
+     * been created.
+     */
+    public void destroy() {
+        // allow plugins to clean up
+        pluginManagerFunction.onDestroy();
+
+        // delete temporary application directory
+        // NOTE: doing this on a background thread doesn't work because the app
+        // is closing and the thread is killed before it completes.
+        try {
+            FileUtils.deleteApplicationTempDirectory();
+        } catch (Exception e) {
+            Logger.log(this.getClass().getName()
+                    + ": error deleting application temp directory: "
+                    + e.getMessage());
+        }
+    }
+
+    /**
+     * Get the class that implements a service.
+     *
+     * @param serviceName   The service name.
+     * @return The Java class name that implements the service.
+     */
+    public String getClassForService(String serviceName) {
+        return (String)this.services.get(serviceName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/PluginManagerFunction.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/PluginManagerFunction.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/PluginManagerFunction.java
new file mode 100644
index 0000000..13a0e77
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/PluginManagerFunction.java
@@ -0,0 +1,240 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.api;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import net.rim.device.api.script.ScriptableFunction;
+
+import org.apache.cordova.CordovaExtension;
+import org.apache.cordova.json4j.JSONArray;
+import org.apache.cordova.json4j.JSONException;
+import org.apache.cordova.util.Logger;
+
+/**
+ * PluginManagerFunction represents a function that can be invoked from the
+ * script environment of the widget framework.  It manages the plugins for
+ * the Cordova JavaScript Extension.
+ *
+ * Calling <code>cordova.pluginManager.exec(...)</code> from JavaScript will
+ * result in this class' <code>invoke()</code> method being called.
+ */
+public class PluginManagerFunction extends ScriptableFunction {
+
+	private final static int ARG_SERVICE = 0;
+	private final static int ARG_ACTION = 1;
+	private final static int ARG_CALLBACK_ID = 2;
+	private final static int ARG_ARGS = 3;
+	private final static int ARG_ASYNC = 4;
+
+	private Hashtable plugins = new Hashtable();
+
+	private final CordovaExtension ext;
+	private final PluginManager pluginManager;
+
+	/**
+	 * Constructor.
+	 * @param ext              The Cordova JavaScript Extension
+	 * @param pluginManager    The PluginManager that exposes the scriptable object.
+	 */
+	public PluginManagerFunction(CordovaExtension ext, PluginManager pluginManager) {
+		this.ext = ext;
+		this.pluginManager = pluginManager;
+	}
+
+	/**
+	 * The invoke method is called when cordova.pluginManager.exec(...) is
+	 * used from the script environment.  It instantiates the appropriate plugin
+	 * and invokes the specified action.  JavaScript arguments are passed in
+	 * as an array of objects.
+	 *
+	 * @param service 		String containing the service to run
+	 * @param action 		String containing the action that the service is supposed to perform. This is
+	 * 						passed to the plugin execute method and it is up to the plugin developer
+	 * 						how to deal with it.
+	 * @param callbackId 	String containing the id of the callback that is executed in JavaScript if
+	 * 						this is an async plugin call.
+	 * @param args 			An Array literal string containing any arguments needed in the
+	 * 						plugin execute method.
+	 * @param async 		Boolean indicating whether the calling JavaScript code is expecting an
+	 * 						immediate return value. If true, either CordovaExtension.callbackSuccess(...) or
+	 * 						CordovaExtension.callbackError(...) is called once the plugin code has executed.
+	 *
+	 * @return 				JSON encoded string with a response message and status.
+	 *
+	 * @see net.rim.device.api.script.ScriptableFunction#invoke(java.lang.Object, java.lang.Object[])
+	 */
+	public Object invoke(Object obj, Object[] oargs) throws Exception {
+		final String service = (String)oargs[ARG_SERVICE];
+		final String action = (String)oargs[ARG_ACTION];
+		final String callbackId = (String)oargs[ARG_CALLBACK_ID];
+		boolean async = (oargs[ARG_ASYNC].toString().equals("true") ? true : false);
+		PluginResult pr = null;
+
+		try {
+			// action arguments
+			final JSONArray args = new JSONArray((String)oargs[ARG_ARGS]);
+
+			// get the class for the specified service
+			String clazz = this.pluginManager.getClassForService(service);
+			Class c = null;
+			if (clazz != null) {
+				c = getClassByName(clazz);
+			}
+
+			if (isCordovaPlugin(c)) {
+				// Create a new instance of the plugin and set the context
+				final Plugin plugin = this.loadPlugin(clazz, c);
+				async = async && !plugin.isSynch(action);
+				if (async) {
+					// Run this async on a background thread so that JavaScript can continue on
+					Thread thread = new Thread(new Runnable() {
+						public void run() {
+							// Call execute on the plugin so that it can do it's thing
+						    final PluginResult result = plugin.execute(action, args, callbackId);
+
+						    if (result != null) {
+						        int status = result.getStatus();
+
+						        // If plugin status is OK,
+						        // or plugin is not going to send an immediate result (NO_RESULT)
+						        if (status == PluginResult.Status.OK.ordinal() ||
+						            status == PluginResult.Status.NO_RESULT.ordinal()) {
+						            CordovaExtension.invokeSuccessCallback(callbackId, result);
+						        }
+						        // error
+						        else {
+						            CordovaExtension.invokeErrorCallback(callbackId, result);
+						        }
+						    }
+						}
+					});
+					thread.start();
+					return "";
+				} else {
+					// Call execute on the plugin so that it can do it's thing
+					pr = plugin.execute(action, args, callbackId);
+				}
+			}
+		} catch (ClassNotFoundException e) {
+		    Logger.log(this.getClass().getName() + ": " + e);
+			pr = new PluginResult(PluginResult.Status.CLASS_NOT_FOUND_EXCEPTION, "ClassNotFoundException: " + e.getMessage());
+		} catch (IllegalAccessException e) {
+            Logger.log(this.getClass().getName() + ": " + e);
+			pr = new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, "IllegalAccessException:" + e.getMessage());
+		} catch (InstantiationException e) {
+            Logger.log(this.getClass().getName() + ": " + e);
+			pr = new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION, "InstantiationException: " + e.getMessage());
+		} catch (JSONException e) {
+            Logger.log(this.getClass().getName() + ": " + e);
+			pr = new PluginResult(PluginResult.Status.JSON_EXCEPTION, "JSONException: " + e.getMessage());
+		}
+		// if async we have already returned at this point unless there was an error...
+		if (async) {
+			CordovaExtension.invokeErrorCallback(callbackId, pr);
+		}
+		return ( pr != null ? pr.getJSONString() : "{ status: 0, message: 'all good' }" );
+	}
+
+	/**
+	 * Get the class.
+	 *
+	 * @param clazz
+	 * @return
+	 * @throws ClassNotFoundException
+	 */
+	private Class getClassByName(final String clazz) throws ClassNotFoundException {
+		return Class.forName(clazz);
+	}
+
+	/**
+	 * Determines if the class implements org.apache.cordova.api.Plugin interface.
+	 *
+	 * @param c The class to check.
+	 * @return Boolean indicating if the class implements org.apache.cordova.api.Plugin
+	 */
+	private boolean isCordovaPlugin(Class c) {
+		if (c != null) {
+			return org.apache.cordova.api.Plugin.class.isAssignableFrom(c) || org.apache.cordova.api.IPlugin.class.isAssignableFrom(c);
+		}
+		return false;
+	}
+
+    /**
+     * Add plugin to be loaded and cached.
+     * If plugin is already created, then just return it.
+     *
+     * @param className				The class to load
+     * @return						The plugin
+     */
+	public Plugin loadPlugin(String className, Class clazz) throws IllegalAccessException, InstantiationException {
+	    if (this.plugins.containsKey(className)) {
+                return this.getPlugin(className);
+	    }
+        Logger.log(this.getClass().getName() + ": Loading plugin " + clazz);
+        Plugin plugin = (Plugin)clazz.newInstance();
+        this.plugins.put(className, plugin);
+        plugin.setContext(this.ext);
+        return plugin;
+    }
+
+    /**
+     * Get the loaded plugin.
+     *
+     * @param className				The class of the loaded plugin.
+     * @return
+     */
+    public Plugin getPlugin(String className) {
+        return (Plugin)this.plugins.get(className);
+    }
+
+    /**
+     * Called when application is paused.
+     */
+    public void onPause() {
+        Enumeration e = this.plugins.elements();
+        while (e.hasMoreElements()) {
+            Plugin plugin = (Plugin)e.nextElement();
+            plugin.onPause();
+        }
+    }
+
+    /**
+     * Called when application is resumed.
+     */
+    public void onResume() {
+        Enumeration e = this.plugins.elements();
+        while (e.hasMoreElements()) {
+            Plugin plugin = (Plugin)e.nextElement();
+            plugin.onResume();
+        }
+    }
+
+    /**
+     * Called when application is destroyed.
+     */
+    public void onDestroy() {
+        Enumeration e = this.plugins.elements();
+        while (e.hasMoreElements()) {
+            Plugin plugin = (Plugin)e.nextElement();
+            plugin.onDestroy();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/PluginResult.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/PluginResult.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/PluginResult.java
new file mode 100644
index 0000000..ce84884
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/api/PluginResult.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.api;
+
+import org.apache.cordova.json4j.JSONArray;
+import org.apache.cordova.json4j.JSONObject;
+
+/**
+ * This class defines the standard object that should be returned as the
+ * result of any Cordova plugin invocation.
+ */
+public class PluginResult {
+
+    private final int status;
+    private final String message;
+    private boolean keepCallback = false;
+
+    public PluginResult(Status status) {
+        this.status = status.ordinal();
+        this.message = JSONObject.quote(status.getMessage());
+    }
+
+    public PluginResult(Status status, String message) {
+        this.status = status.ordinal();
+        this.message = JSONObject.quote(message);
+    }
+
+    public PluginResult(Status status, JSONArray message) {
+        this.status = status.ordinal();
+        this.message = message.toString();
+    }
+
+    public PluginResult(Status status, JSONObject message) {
+        this.status = status.ordinal();
+        this.message = (message != null) ? message.toString(): "null";
+    }
+
+    public PluginResult(Status status, int i) {
+        this.status = status.ordinal();
+        this.message = ""+i;
+    }
+
+    public PluginResult(Status status, float f) {
+        this.status = status.ordinal();
+        this.message = ""+f;
+    }
+
+    public PluginResult(Status status, boolean b) {
+        this.status = status.ordinal();
+        this.message = ""+b;
+    }
+
+    public PluginResult(Status status, long l) {
+        this.status = status.ordinal();
+        this.message = ""+l;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setKeepCallback(boolean b) {
+        this.keepCallback = b;
+    }
+
+    public boolean getKeepCallback() {
+        return this.keepCallback;
+    }
+
+    public String getJSONString() {
+        return "{\"status\":" + this.status + ",\"message\":" + this.message + ",\"keepCallback\":" + this.keepCallback + "}";
+    }
+
+    /**
+     * Returns the JavaScript string that executes the success callback for the
+     * appropriate Cordova plugin.  The string is intended to be passed to the
+     * JavaScript engine.
+     * @param callbackId Unique id of the callback that is associated with the invoked plugin
+     * @return JavaScript string that invokes the appropriate plugin success callback
+     */
+    public String toSuccessCallbackString(String callbackId) {
+        return "try { cordova.callbackSuccess('"+callbackId+"', " + this.getJSONString() + "); } catch(e) { alert('error in callbackSuccess:' + e.message); }";
+    }
+
+    /**
+     * Returns the JavaScript string that executes the error callback for the
+     * appropriate Cordova plugin.  The string is intended to be passed to the
+     * JavaScript engine.
+     * @param callbackId Unique id of the callback that is associated with the invoked plugin
+     * @return JavaScript string that invokes the appropriate plugin error callback
+     */
+    public String toErrorCallbackString(String callbackId) {
+        return "try { cordova.callbackError('"+callbackId+"', " + this.getJSONString() + "); } catch(e) { alert('error in callbackError:' + e.message); }";
+    }
+
+    public String toErrorString() {
+        return "alert('general error');";
+    }
+
+    /**
+     * Enumerates PluginResult status.
+     */
+    public static class Status
+    {
+        private int val;
+        private String message;
+
+        protected Status(int val, String message) {
+            this.val = val;
+            this.message = message;
+        }
+
+        public int ordinal() {
+            return this.val;
+        }
+
+        public String getMessage() {
+            return this.message;
+        }
+
+        public static final Status NO_RESULT = new Status(0, "No result");
+        public static final Status OK = new Status(1, "OK");
+        public static final Status CLASS_NOT_FOUND_EXCEPTION = new Status(2, "Class not found");
+        public static final Status ILLEGAL_ACCESS_EXCEPTION = new Status(3, "Illegal access");
+        public static final Status INSTANTIATION_EXCEPTION = new Status(4, "Instantiation error");
+        public static final Status MALFORMED_URL_EXCEPTION = new Status(5, "Malformed URL");
+        public static final Status IO_EXCEPTION = new Status(6, "IO error");
+        public static final Status INVALID_ACTION = new Status(7, "Invalid action");
+        public static final Status JSON_EXCEPTION = new Status(8, "JSON error");
+        public static final Status ERROR = new Status(9, "Error");
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/app/App.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/app/App.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/app/App.java
new file mode 100644
index 0000000..38ae205
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/app/App.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.app;
+
+import org.apache.cordova.CordovaExtension;
+import org.apache.cordova.api.Plugin;
+import org.apache.cordova.api.PluginResult;
+import org.apache.cordova.json4j.JSONArray;
+
+import net.rim.device.api.browser.field2.BrowserFieldHistory;
+import net.rim.device.api.system.Application;
+import net.rim.device.api.system.SystemListener2;
+
+/**
+ * The App plug-in. This class provides access to application specific
+ * management. The following actions are supported:
+ *
+ *      clearHistory    - Clear the browser history.
+ *      backHistory     - Navigate back in the browser history.
+ *      detectBacklight - Start a system listener for backlight changes.
+ *      ignoreBacklight - Stop the system listener for backlight changes.
+ */
+public class App extends Plugin {
+
+    private final static String ACTION_CLEAR_HISTORY = "clearHistory";
+    private final static String ACTION_BACK_HISTORY = "backHistory";
+    private final static String ACTION_DETECT_BACKLIGHT = "detectBacklight";
+    private final static String ACTION_IGNORE_BACKLIGHT = "ignoreBacklight";
+
+    private SystemListener2 listener = null;
+    private String callbackId = null;
+
+    /**
+     * Executes the requested action and returns a PluginResult.
+     *
+     * @param action
+     *            The action to execute.
+     * @param callbackId
+     *            The callback ID to be invoked upon action completion
+     * @param args
+     *            JSONArry of arguments for the action.
+     * @return A PluginResult object with a status and message.
+     */
+    public PluginResult execute(String action, JSONArray args,
+            final String callbackId) {
+        PluginResult result = null;
+
+        if (ACTION_CLEAR_HISTORY.equals(action)) {
+            BrowserFieldHistory history = CordovaExtension.getBrowserField()
+                    .getHistory();
+            if (history != null) {
+                history.clearHistory();
+            }
+            result = new PluginResult(PluginResult.Status.OK);
+        } else if (ACTION_BACK_HISTORY.equals(action)) {
+            CordovaExtension.getBrowserField().back();
+            result = new PluginResult(PluginResult.Status.OK);
+        } else if (ACTION_DETECT_BACKLIGHT.equals(action)) {
+            addListener(callbackId);
+            result = new PluginResult(PluginResult.Status.NO_RESULT);
+            result.setKeepCallback(true);
+        } else if (ACTION_IGNORE_BACKLIGHT.equals(action)) {
+            removeListener();
+            result = new PluginResult(PluginResult.Status.OK);
+        } else {
+            result = new PluginResult(PluginResult.Status.INVALID_ACTION,
+                    "App: Invalid action: " + action);
+        }
+
+        return result;
+    }
+
+    /**
+     * Called when Plugin is destroyed.
+     */
+    public void onDestroy() {
+        removeListener();
+    }
+
+    /**
+     * Register a system listener for backlight changes if one has not already
+     * been registered.
+     *
+     * @param callbackId
+     *            the callback ID associated with the system listener
+     */
+    private synchronized void addListener(final String callbackId) {
+        if (listener == null) {
+            listener = new SystemListener2() {
+                public void batteryGood() {}
+                public void batteryLow() {}
+                public void batteryStatusChange(int status) {}
+                public void powerOff() {}
+                public void powerUp() {}
+
+                public void backlightStateChange(boolean on) {
+                    PluginResult result = new PluginResult(
+                            PluginResult.Status.OK, on);
+
+                    // Must keep the call back active for future events.
+                    result.setKeepCallback(true);
+                    success(result, callbackId);
+                }
+
+                public void cradleMismatch(boolean mismatch) {}
+                public void fastReset() {}
+                public void powerOffRequested(int reason) {}
+                public void usbConnectionStateChange(int state) {}
+            };
+
+            this.callbackId = callbackId;
+            Application.getApplication().addSystemListener(listener);
+        }
+    }
+
+    /**
+     * Remove the system listener if it is registered and close out the
+     * callback handler.
+     */
+    private synchronized void removeListener() {
+        if (listener != null) {
+            Application.getApplication().removeSystemListener(listener);
+            listener = null;
+
+            if (callbackId != null) {
+                success(new PluginResult(PluginResult.Status.NO_RESULT),
+                        callbackId);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d61deccd/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/battery/Battery.java
----------------------------------------------------------------------
diff --git a/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/battery/Battery.java b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/battery/Battery.java
new file mode 100644
index 0000000..55356a5
--- /dev/null
+++ b/lib/cordova-blackberry/framework/ext/src/org/apache/cordova/battery/Battery.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cordova.battery;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.apache.cordova.api.Plugin;
+import org.apache.cordova.api.PluginResult;
+import org.apache.cordova.json4j.JSONArray;
+import org.apache.cordova.json4j.JSONException;
+import org.apache.cordova.json4j.JSONObject;
+import org.apache.cordova.util.Logger;
+
+import net.rim.device.api.system.Application;
+import net.rim.device.api.system.DeviceInfo;
+import net.rim.device.api.system.SystemListener;
+
+/**
+ * The Battery plug-in. This class provides information about the state of the
+ * battery on the phone. The following actions are supported:
+ *
+ *      start - Start listening for changes in battery level (%) and batter
+ *              charging state.
+ *      stop  - Stop listening for changes in battery level and state.
+ */
+public class Battery extends Plugin {
+
+    /** Actions to start and stop listening for battery changes. */
+    private final static String ACTION_START = "start";
+    private final static String ACTION_STOP = "stop";
+
+    /** The percentage of battery remaining. */
+    private final static String LEVEL = "level";
+
+    /** Whether the battery is currently charging or not. */
+    private final static String CHARGING = "isPlugged";
+
+    // The set of call back IDs to send results to. Using Hashtable because
+    // BlackBerry does not support Collections. There should only ever be one
+    // call back ID, but this allows multiple.
+    private Hashtable callbackIds = new Hashtable();
+
+    private SystemListener batteryListener = null;
+
+    /**
+     * Executes the requested action and returns a PluginResult.
+     *
+     * @param action
+     *            The action to execute.
+     * @param callbackId
+     *            The callback ID to be invoked upon action completion
+     * @param args
+     *            JSONArry of arguments for the action.
+     * @return A PluginResult object with a status and message.
+     */
+    public PluginResult execute(String action, JSONArray args, String callbackId) {
+        PluginResult result = null;
+
+        if (ACTION_START.equals(action)) {
+            // Register a listener to detect battery changes.
+            addListener(callbackId);
+
+            // Don't return any result now, since battery status results are
+            // sent when listener is notified.
+            result = new PluginResult(PluginResult.Status.NO_RESULT);
+
+            // Must keep the call back active for future events.
+            result.setKeepCallback(true);
+        } else if (ACTION_STOP.equals(action)) {
+            // Remove the battery listener and cleanup call back IDs.
+            removeListener();
+            result = new PluginResult(PluginResult.Status.OK);
+        } else {
+            result = new PluginResult(PluginResult.Status.INVALID_ACTION,
+                    "Battery: Invalid action: " + action);
+        }
+
+        return result;
+    }
+
+    /**
+     * Remove the listener when the application is destroyed. Note that onPause
+     * is not overridden, so the listener will continue if the application is
+     * simply paused instead of destroyed.
+     */
+    public void onDestroy() {
+        removeListener();
+    }
+
+    /**
+     * Adds a SystemListener to listen for changes to the battery state. The
+     * listener is only registered if one has not already been added. If a
+     * listener has already been registered the call back id is simply saved so
+     * that it can be notified upon next battery state change.
+     *
+     * @param callbackId
+     *            The reference point to call back when a listener event occurs.
+     */
+    private synchronized void addListener(String callbackId) {
+        callbackIds.put(callbackId, callbackId);
+
+        // Only register a listener if one has not been registered.
+        if (batteryListener == null) {
+            batteryListener = new SystemListener() {
+                // Initialize the charging state and battery level.
+                private boolean prevChargeState = (DeviceInfo
+                        .getBatteryStatus() & DeviceInfo.BSTAT_CHARGING) != 0;
+                private int prevLevel = DeviceInfo.getBatteryLevel();
+
+                public void batteryGood() { }
+                public void batteryLow() { }
+
+                public void batteryStatusChange(int status) {
+                    // The status bits passed into this method are unreliable
+                    // in determining when the battery level has changed.
+                    // Instead, when any state change occurs, get the current
+                    // battery level and report the change if it is different
+                    // then previous value.
+                    int newLevel = DeviceInfo.getBatteryLevel();
+                    boolean newChargeState = (DeviceInfo.BSTAT_CHARGING & status) != 0;
+
+                    // Report change if level or charge state is different then
+                    // previous values.
+                    if (newLevel != prevLevel || newChargeState != prevChargeState) {
+                        prevChargeState = newChargeState;
+                        prevLevel = newLevel;
+
+                        // Store the retrieved properties in a JSON object.
+                        JSONObject connectionInfo = new JSONObject();
+                        try {
+                            connectionInfo.put(LEVEL, newLevel);
+                            connectionInfo.put(CHARGING, newChargeState);
+                        } catch (JSONException e) {
+                            Logger.error("JSONException: " + e.getMessage());
+                            return;
+                        }
+
+                        PluginResult result = new PluginResult(
+                                PluginResult.Status.OK, connectionInfo);
+
+                        sendSuccessResult(result, true);
+                    }
+                }
+
+                public void powerOff() { }
+                public void powerUp() { }
+            };
+            Application.getApplication().addSystemListener(batteryListener);
+        }
+    }
+
+    /**
+     * Remove the registered battery status listener and cleanup the call back
+     * IDs.
+     */
+    private synchronized void removeListener() {
+        if (batteryListener != null) {
+
+            // Remove the battery listener.
+            Application.getApplication().removeSystemListener(batteryListener);
+            batteryListener = null;
+
+            // Close out the call back IDs.
+            sendSuccessResult(new PluginResult(PluginResult.Status.OK), false);
+            callbackIds.clear();
+        }
+    }
+
+    /**
+     * Helper function to send the PluginResult to the saved call back IDs.
+     *
+     * @param result
+     *            the PluginResult to return
+     * @param keepCallback
+     *            Boolean value indicating whether to keep the call back id
+     *            active.
+     */
+    private void sendSuccessResult(PluginResult result, boolean keepCallback) {
+
+        if (result != null) {
+            // Must keep the call back active for future events.
+            result.setKeepCallback(keepCallback);
+
+            // Iterate through the saved call back IDs. Really should only ever
+            // be one.
+            for (Enumeration callbacks = this.callbackIds.elements(); callbacks
+                    .hasMoreElements();) {
+                success(result, (String) callbacks.nextElement());
+            }
+        }
+    }
+
+}