diff --git a/.cordova/config.json b/.cordova/config.json
new file mode 100644
index 0000000..5ec683f
--- /dev/null
+++ b/.cordova/config.json
@@ -0,0 +1 @@
+{"id":"io.cordova.hellocordova","name":"HelloCordova"}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index ede92e8..4b7817c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1,6 @@
*.DS_Store
-example/ios/exampleWizViewManager.xcodeproj/xcuserdata/*
-example/ios/exampleWizViewManager.xcodeproj/project.xcworkspace/*
-example/ios/CordovaLib/CordovaLib.xcodeproj/xcuserdata/*
-example/ios/www/*
-!example/ios/www/cordova.js
-!example/ios/www/cordova_plugins.js
-!example/ios/www/phonegap/plugin/wizViewManager/wizViewManager.js
-!example/ios/www/phonegap/plugin/wizViewMessenger/wizViewMessenger.js
+*.xcworkspace
+xcuserdata
.idea/
bin/
gen/
diff --git a/README.md b/README.md
index 4913451..b5a11dd 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# phonegap-plugin-wizViewManager
-- PhoneGap Version : 3.0
+- PhoneGap Version : 2.6 and above
- last update : 27/02/2014
# Description
diff --git a/example/README.md b/example/README.md
deleted file mode 100644
index a4e612f..0000000
--- a/example/README.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# SETUP FOR BUILDING
-
-To build this example, PhoneGap requires that the plugin be installed in the
-correct location relative to this example's www directory. So we must copy
-(or link) the plugin JavaScript code to the www directory used by the application.
-We must also copy (or link) the plugin native code based on the target platform.
-
-The details of how we do this are as follows:
-
-
-# iOS
-
-For native Objective-C code, the Xcode project directly references the code
-using relative path references.
-
-For JavaScript code, the XCode project performs the following copy operations
-as part of it's pre-build process:
-
- cp -r $PROJECT_DIR/../www $PROJECT_DIR
- cp -r $PROJECT_DIR/../../www/phonegap $PROJECT_DIR/www
-
-
diff --git a/example/android/ant.properties b/example/android/ant.properties
deleted file mode 100644
index b0971e8..0000000
--- a/example/android/ant.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-# This file is used to override default values used by the Ant build system.
-#
-# This file must be checked into Version Control Systems, as it is
-# integral to the build system of your project.
-
-# This file is only used by the Ant script.
-
-# You can use this to override default values such as
-# 'source.dir' for the location of your java source folder and
-# 'out.dir' for the location of your output folder.
-
-# You can also use it define how the release builds are signed by declaring
-# the following properties:
-# 'key.store' for the location of your keystore and
-# 'key.alias' for the name of the key to use.
-# The password will be asked during the build when you use the 'release' target.
-
diff --git a/example/android/assets/www/config.xml b/example/android/assets/www/config.xml
deleted file mode 100644
index e4b1d64..0000000
--- a/example/android/assets/www/config.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
- HelloWorld
-
- Hello World sample application that responds to the deviceready event.
-
-
- PhoneGap Team
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/example/android/libs/cordova-3.0.0.jar b/example/android/libs/cordova-3.0.0.jar
deleted file mode 100644
index e4a74c9..0000000
Binary files a/example/android/libs/cordova-3.0.0.jar and /dev/null differ
diff --git a/example/android/res/drawable-hdpi/ic_launcher.png b/example/android/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index 96a442e..0000000
Binary files a/example/android/res/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/example/android/res/drawable-ldpi/ic_launcher.png b/example/android/res/drawable-ldpi/ic_launcher.png
deleted file mode 100644
index 9923872..0000000
Binary files a/example/android/res/drawable-ldpi/ic_launcher.png and /dev/null differ
diff --git a/example/android/res/drawable-mdpi/ic_launcher.png b/example/android/res/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 359047d..0000000
Binary files a/example/android/res/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/example/android/res/drawable-xhdpi/ic_launcher.png b/example/android/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index 71c6d76..0000000
Binary files a/example/android/res/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/example/android/res/layout/main.xml b/example/android/res/layout/main.xml
deleted file mode 100644
index a94a119..0000000
--- a/example/android/res/layout/main.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
diff --git a/example/android/res/xml/config.xml b/example/android/res/xml/config.xml
deleted file mode 100644
index b426508..0000000
--- a/example/android/res/xml/config.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
- Hello Cordova
-
- A sample Apache Cordova application that responds to the deviceready event.
-
-
- Apache Cordova Team
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/example/android/src/jp/wizcorp/phonegap/plugin/wizViewManager/WizViewManagerPlugin.java b/example/android/src/jp/wizcorp/phonegap/plugin/wizViewManager/WizViewManagerPlugin.java
deleted file mode 100644
index 7241200..0000000
--- a/example/android/src/jp/wizcorp/phonegap/plugin/wizViewManager/WizViewManagerPlugin.java
+++ /dev/null
@@ -1,825 +0,0 @@
-/*
- * __ __ _ _ _
- * / / /\ \ (_)______ _ _ __ __| | /\ /(_) _____ __ /\/\ __ _ _ __ __ _ __ _ ___ _ __
- * \ \/ \/ / |_ / _` | '__/ _` | \ \ / / |/ _ \ \ /\ / / / \ / _` | '_ \ / _` |/ _` |/ _ \ '__|
- * \ /\ /| |/ / (_| | | | (_| | \ V /| | __/\ V V / / /\/\ \ (_| | | | | (_| | (_| | __/ |
- * \/ \/ |_/___\__,_|_| \__,_| \_/ |_|\___| \_/\_/ \/ \/\__,_|_| |_|\__,_|\__, |\___|_|
- * |___/ |___/ |___/
- * @author Ally Ogilvie
- * @copyright Wizcorp Inc. [ Incorporated Wizards ] 2013
- * @file - WizViewManagerPlugin.java
- * @about - Handle view and communication.
-*/
-package jp.wizcorp.phonegap.plugin.wizViewManager;
-
-import android.view.ViewGroup;
-import android.webkit.WebResourceResponse;
-import android.widget.LinearLayout;
-import org.apache.cordova.*;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.util.Log;
-import android.view.View;
-import android.webkit.WebView;
-
-import java.io.ByteArrayInputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-
-public class WizViewManagerPlugin extends CordovaPlugin {
-
- // The following files can be open natively by the WebView
- public static String[] whitelist = {
- ".txt", ".md",
- ".php", ".java", ".html", ".htm", ".xml", ".css", ".js",
- ".jpg", ".png", ".jpeg", ".gif", ".tif", "."
- };
- // The following files can be opened with the helper prefix in a WebView;
- // http://docs.google.com/a/wizcorp.jp/gview?embedded=true&url=
- public static String[] helperList = {
- ".docx", ".doc",
- ".xls", ".xlsx",
- ".ppt", ".pptx",
- ".pdf", ".pages",
- ".ai", ".psd",
- ".h", ".m", ".c", ".cc", ".cpp",
- ".webm", ".mpeg4", ".3gpp", ".mov", ".avi", ".mpegps", ".wmv", ".flv"
- };
- private String TAG = "WizViewManagerPlugin";
-
- static JSONObject viewList = new JSONObject();
- static CordovaInterface _cordova;
- static CordovaWebView _webView;
-
- @Override
- public void initialize(CordovaInterface cordova, CordovaWebView webView) {
- _cordova = cordova;
- _webView = webView;
- Log.d(TAG, "Initialize Plugin");
- // By default, get a pointer to mainView and add mainView to the viewList as it always exists (hold phonegap's view)
- if (!viewList.has("mainView")) {
- // Cordova view is not in the viewList so add it.
- try {
- viewList.put("mainView", webView);
- webView.loadUrl("javascript:window.name = 'mainView';");
- } catch (JSONException e) {
- // Error handle (this should never happen!)
- Log.e(TAG, "Critical error. Failed to retrieve Cordova's view");
- }
- }
- super.initialize(cordova, webView);
-
- webView.getSettings().setDomStorageEnabled(true);
-
- webView.getSettings().setLoadWithOverviewMode(true);
- webView.getSettings().setUseWideViewPort(true);
- }
-
- @android.annotation.TargetApi(11)
- public WebResourceResponse shouldInterceptRequest(String url) {
- ByteArrayInputStream stream = new ByteArrayInputStream(url.getBytes());
- this.onOverrideUrlLoading(url);
- return new WebResourceResponse("text/plain", "UTF-8", stream);
- }
-
- @Override
- public boolean onOverrideUrlLoading(String url) {
-
- Log.d(TAG, "[Override URL] ****** "+ url);
-
- String[] urlArray;
- String splitter = "://";
-
- // Split url by only 2 in the event "://" occurs elsewhere (SHOULD be impossible because you string encoded right!?)
- urlArray = url.split(splitter,2);
-
- if (urlArray[0].equalsIgnoreCase("wizpostmessage")) {
-
- String[] msgData;
- splitter = "\\?";
-
- // Split url by only 2 again to make sure we only spit at the first "?"
- msgData = urlArray[1].split(splitter);
- // target View = msgData[0] and message = msgData[1]
- // Get webview list from View Manager
- JSONObject viewList = WizViewManagerPlugin.getViews();
-
- if (viewList.has(msgData[1]) ) {
-
- WebView targetView;
- try {
- targetView = (WebView) viewList.get(msgData[1]);
-
- // send data to mainView
- String data2send = msgData[2];
- try {
- data2send = URLDecoder.decode(data2send, "UTF-8");
- } catch (UnsupportedEncodingException e) {
-
- }
- data2send = data2send.replace("'", "\\'");
- Log.d(TAG, "[wizMessage] targetView ****** is " + msgData[1] + " -> " + targetView + " with data -> " + data2send);
- targetView.loadUrl("javascript:wizViewMessenger.__triggerMessageEvent('" + msgData[0] + "', '" + msgData[1] + "', '" + data2send + "', '" + msgData[3] + "');");
-
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- // app will handle this url, don't change the browser url
- return true;
- }
-
- if (urlArray[0].equalsIgnoreCase("wizmessageview") ) {
-
- String[] msgData;
- splitter = "\\?";
-
- // Split url by only 2 again to make sure we only spit at the first "?"
- msgData = urlArray[1].split(splitter);
-
-
- // target View = msgData[0] and message = msgData[1]
-
- // Get webview list from View Manager
- JSONObject viewList = WizViewManagerPlugin.getViews();
-
- if (viewList.has(msgData[0]) ) {
-
- WebView targetView;
- try {
- targetView = (WebView) viewList.get(msgData[0]);
-
- // send data to mainView
- String data2send = msgData[1];
- data2send = data2send.replace("'", "\\'");
- Log.d(TAG, "[wizMessage] targetView ****** is " + msgData[0]+ " -> " + targetView + " with data -> "+data2send );
- targetView.loadUrl("javascript:(wizMessageReceiver('"+data2send+"'))");
-
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- // app will handle this url, don't change the browser url
- return true;
- }
-
- return super.onOverrideUrlLoading(url);
- }
-
-/*
- @Override
- public void onPageFinished(WebView wView, String url) {
- WizViewManagerPlugin.updateViewList();
- }
-*/
- @Override
- public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
-
- Log.d(TAG, "[action] ****** " + action );
-
- if (action.equals("createView")) {
- // Create a new view
- Log.d(TAG, "[createView] ****** " + args.toString() );
-
- final String viewName;
- final JSONObject settings;
- try {
- // Get view name
- viewName = args.getString(0);
- settings = args.optJSONObject(1);
- Log.d(TAG, "Create view with settings : " + settings);
-
- } catch (Exception e) {
- Log.e(TAG, "Exception: " + e);
- callbackContext.error("Cannot create view. Missing view name parameter");
- return true;
- }
-
- // Create a final link so we can run on UI thread
- Log.d(TAG, "list: " + viewList.names().toString());
-
- // Create link to callback
- final CallbackContext create_cb = callbackContext;
-
- cordova.getActivity().runOnUiThread(
- new Runnable() {
- @Override
- public void run() {
- WizWebView wizWebView = new WizWebView(viewName, settings, cordova.getActivity(), create_cb);
- // Put our new View into viewList
- try {
- viewList.put(viewName, wizWebView);
- updateViewList();
- } catch (JSONException e) {
- // Error handle
- e.printStackTrace();
- }
- }
- }
- );
-
- // Wait for callback
- PluginResult res = new PluginResult(PluginResult.Status.NO_RESULT);
- res.setKeepCallback(true);
- callbackContext.sendPluginResult(res);
-
- // Clean up
- callbackContext = null;
-
- return true;
-
- } else if (action.equals("removeView")) {
- // TODO: Async callback
- // Remove a view from the application
- Log.d(TAG, "[removeView] ****** " + args.toString() );
-
- final String viewName;
- try {
- // Get view name
- viewName = args.getString(0);
- } catch (Exception e) {
- Log.e(TAG, "Cannot remove view. Missing view name parameter");
- callbackContext.error("Cannot remove view. Missing view name parameter");
- return true;
- }
-
- // Find WebView by this name and remove it
- if (viewList.has(viewName) ) {
- final WizWebView targetView = (WizWebView) viewList.get(viewName);
-
- cordova.getActivity().runOnUiThread(
- new Runnable() {
- @Override
- public void run() {
- ViewGroup viewGroup = (ViewGroup) targetView.getParent();
- viewGroup.removeView(targetView);
- viewGroup = null;
- }
- });
-
- viewList.remove(viewName);
- updateViewList();
-
- // Remove is running on a different thread, but for now assume view was removed
- callbackContext.success();
- return true;
- } else {
- // Cannot find view
- Log.e(TAG, "Cannot remove view. View not found");
- callbackContext.error("Cannot remove view. View not found");
- return true;
- }
-
- } else if (action.equals("hideView")) {
- // TODO: Async callback
- // TODO: animations like iOS
-
- // Hide a particular view...
- Log.d(TAG, "[hideView] ****** " + args.toString() );
-
- final String viewName;
-
- // set defaults for animations
- long animDuration = 500;
- String animType = "none";
-
- try {
- viewName = args.getString(0);
- // analyse settings object
- try {
-
- JSONObject settings = (JSONObject) args.get(1);
-
- if (settings.has("animation")) {
- JSONObject animation = settings.getJSONObject("animation");
-
- if (animation.has("duration")) {
- animDuration = (long)animation.getInt("duration");
- }
-
- if (animation.has("type")) {
- animType = animation.getString("type");
- }
- }
-
- } catch (Exception e) {
- // no settings, use default
-
- }
-
- // Find WebView by this name and hide it
- if (viewList.has(viewName) ) {
-
- final WebView targetView = (WebView) viewList.get(viewName);
-
- final long duration = animDuration;
- final String type = animType;
-
- cordova.getActivity().runOnUiThread(
- new Runnable() {
- @Override
- public void run() {
- /*
- hideCallbackId = callbackId;
- result = new PluginResult(Status.NO_RESULT);
- result.setKeepCallback(true);
- */
-
- // get current layout view then add our 999 buffer to bring back to view
- // final RelativeLayout layouter = (RelativeLayout) targetView.getParent();
-
- if (targetView.getPaddingLeft() == 0) {
-
- targetView.setVisibility(View.INVISIBLE);
- targetView.setPadding(999, 0, 0, 0);
- /*
- Animation animation;
- if (type.equals("none")) {
-
- targetView.setVisibility(View.INVISIBLE);
- // layouter.setPadding(layouter.getPaddingLeft()+999, 0, 0, 0);
-
- } else if (type.equals("fadeOut")) {
-
- animation = AnimationUtils.loadAnimation(cordova.getActivity(), R.anim.view_fadeout);
- animation.setFillAfter(true);
- animation.setFillEnabled(true);
- animation.setDuration((long) duration);
- animation.setAnimationListener(new AnimationListener() {
-
- public void onAnimationEnd(Animation animation) {
- Log.d(TAG, "[hide - layouter.getPaddingLeft()] ****** " + layouter.getPaddingLeft());
-
-
- layouter.setPadding(layouter.getPaddingLeft()+999, 0, 0, 0);
- Log.d(TAG, "[hide - layouter.getPaddingLeft()] ****** " + layouter.getPaddingLeft());
-
- targetView.setVisibility(View.INVISIBLE);
- Log.d(TAG, "[hide - layouter.getPaddingLeft()] ****** " + layouter.getPaddingLeft());
-
- }
-
- public void onAnimationRepeat(Animation animation) {
-
- }
-
- public void onAnimationStart(Animation animation) {
-
- }
-
- });
-
- targetView.startAnimation(animation);
-
- } else if (type.equals("zoomOut")) {
-
- animation = AnimationUtils.loadAnimation(cordova.getActivity(), R.anim.view_zoomout);
- animation.setFillAfter(true);
- animation.setFillEnabled(true);
- animation.setDuration((long) duration);
- animation.setAnimationListener(new AnimationListener() {
-
- public void onAnimationEnd(Animation animation) {
- targetView.setVisibility(View.INVISIBLE);
- layouter.setPadding(layouter.getPaddingLeft()+999, 0, 0, 0);
-
- }
-
- public void onAnimationRepeat(Animation animation) {
-
- }
-
- public void onAnimationStart(Animation animation) {
-
- }
-
- });
-
- targetView.startAnimation(animation);
- }
- */
-
- } else {
- // already hidden, just callback
- Log.d(TAG, "[hide - view already invisible]");
-
-
- }
- }
- }
- );
-
- callbackContext.success();
- return true;
-
- } else {
- // Error handle
- callbackContext.error("cannot find view");
- return true;
- }
-
- } catch (JSONException e) {
- // Error handle
- callbackContext.error("missing view name parameter");
- return true;
- }
-
- // callbackContext.success();
- // return true;
-
- } else if (action.equals("showView")) {
- // TODO: Async callback
- // TODO: animations like iOS
- // Show a particular view...
- Log.d(TAG, "[showView] ****** " + args.toString() );
-
- String viewName;
-
- // Set defaults for animations
- long animDuration = 500;
- String animType = "none";
-
- try {
- viewName = args.getString(0);
-
-/*
- // Analyse settings object
- try {
- JSONObject settings = (JSONObject) args.get(1);
-
- if (settings.has("animation")) {
- JSONObject animation = settings.getJSONObject("animation");
-
- if (animation.has("duration")) {
- animDuration = (long)animation.getInt("duration");
- }
-
- if (animation.has("type")) {
- animType = animation.getString("type");
- }
- }
-
- } catch (Exception e) {
- // No settings, use default
- Log.d(TAG, "Do options set, using defaults");
- }
-*/
-
- // Find WebView by this name and show it
- if (viewList.has(viewName) ) {
- Log.d(TAG, "Get WebView in view list");
- final WebView targetView = (WebView) viewList.get(viewName);
- Log.d(TAG, targetView.toString());
- long duration = animDuration;
-
- cordova.getActivity().runOnUiThread(
- new Runnable() {
- @Override
- public void run() {
- if (targetView.getVisibility() == View.INVISIBLE) {
-
- // Get current layout view then minus our 999 buffer to bring back to view
- // final RelativeLayout layouter = (RelativeLayout) targetView.getParent();
- targetView.getPaddingLeft();
- Log.d(TAG, "[show - targetView.getPaddingLeft()] ****** " + targetView.getPaddingLeft());
-
- if (targetView.getPaddingLeft() == 999) {
- /*
- Animation animation;
-
- if (animType.equals("none")) {
-
- Log.d(TAG, "[show - layouter.getPaddingLeft()] ****** " + layouter.getPaddingLeft());
-
- layouter.setPadding(layouter.getPaddingLeft()-999, 0, 0, 0);
- targetView.setVisibility(View.VISIBLE);
-
- Log.d(TAG, "[show - layouter.getPaddingLeft()] ****** " + layouter.getPaddingLeft());
-
-
- } else if (animType.equals("fadeIn")) {
-
- animation = AnimationUtils.loadAnimation(cordova.getActivity(), R.anim.view_fadein);
- animation.setFillAfter(true);
- animation.setFillEnabled(true);
- animation.setDuration((long) duration);
-
- animation.setAnimationListener(new AnimationListener() {
-
- public void onAnimationEnd(Animation animation) {
-
- }
-
- public void onAnimationRepeat(Animation animation) {
-
- }
-
- public void onAnimationStart(Animation animation) {
- layouter.setPadding(layouter.getPaddingLeft()-999, 0, 0, 0);
- targetView.setVisibility(View.VISIBLE);
- }
-
- });
-
- targetView.startAnimation(animation);
-
- } else if (animType.equals("zoomIn")) {
-
- animation = AnimationUtils.loadAnimation(cordova.getActivity(), R.anim.view_zoomin);
- animation.setFillAfter(true);
- animation.setFillEnabled(true);
- animation.setDuration((long) duration);
-
- animation.setAnimationListener(new AnimationListener() {
-
- public void onAnimationEnd(Animation animation) {
-
-
- }
-
- public void onAnimationRepeat(Animation animation) {
-
- }
-
- public void onAnimationStart(Animation animation) {
- layouter.setPadding(layouter.getPaddingLeft()-999, 0, 0, 0);
- targetView.setVisibility(View.VISIBLE);
- }
-
- });
-
- targetView.startAnimation(animation);
-
- }
- */
- // callbackContext.success();
- // return true;
- // No animations
- targetView.setVisibility(View.VISIBLE);
- targetView.setPadding(0, 0, 0, 0);
- Log.d(TAG, "[show - targetView.getPaddingLeft()] ****** " + targetView.getPaddingLeft());
- } else {
- // already shown, just callback
- Log.d(TAG, "[show - view already visible]");
-
- }
- }
- }
- }
- );
-
- callbackContext.success();
- return true;
-
- } else {
- // Error handle
- Log.e(TAG, "Cannot show. Cannot find view");
- callbackContext.error("Cannot show. Cannot find view");
- return true;
- }
-
- } catch (JSONException e) {
- // Error handle
- Log.e(TAG, "Cannot show. Missing view name parameter");
- callbackContext.error("Cannot show. Missing view name parameter");
- return true;
- }
-
- } else if (action.equals("setLayout")) {
-
- try {
- String viewName = args.getString(0);
- final JSONObject options = args.getJSONObject(1);
-
- if (viewName.equals("mainView")) {
- final CordovaWebView targetView = (CordovaWebView) viewList.get(viewName);
-
- cordova.getActivity().runOnUiThread(
- new Runnable() {
- @Override
- public void run() {
- WizViewManagerPlugin.setLayout(targetView, options);
- }
- }
- );
- } else {
- final WizWebView targetView = (WizWebView) viewList.get(viewName);
-
- cordova.getActivity().runOnUiThread(
- new Runnable() {
- @Override
- public void run() {
- targetView.setLayout(options, null);
- }
- }
- );
- }
-
- } catch (Exception e) {
- Log.e(TAG, "Error: " + e);
- }
-
- callbackContext.success();
-
- return true;
-
- } else if (action.equals("load")) {
- Log.d(TAG, "[load] ****** ");
-
- String viewName;
- try {
- viewName = args.getString(0);
- } catch (JSONException e) {
- Log.e(TAG, "Cannot load into view. Missing view name parameter");
- callbackContext.error("Cannot load into view. Missing view name parameter");
- return true;
- }
-
- // Find WebView by this name and show it
- if (viewList.has(viewName) ) {
- final WizWebView targetView = (WizWebView) viewList.get(viewName);
- JSONObject options = args.getJSONObject(1);
-
- if (options.has("src")) {
- final String url = options.getString("src");
- Log.d(TAG, "[load] url>> " + url);
- final CallbackContext load_cb = callbackContext;
- cordova.getActivity().runOnUiThread(
- new Runnable() {
- public void run() {
- targetView.load(url, load_cb);
- }
- }
- );
- } else {
- Log.e(TAG, "Cannot load into view. No source to load.");
- callbackContext.error("Cannot load into view. No source to load.");
- return true;
- }
-
- // Wait for callback
- PluginResult res = new PluginResult(PluginResult.Status.NO_RESULT);
- res.setKeepCallback(true);
- callbackContext.sendPluginResult(res);
-
- // Clean up
- callbackContext = null;
- return true;
-
- } else {
- Log.e(TAG, "Cannot update view. Missing view name parameter");
- callbackContext.error("Cannot update view. Missing view name parameter");
- return true;
- }
- }
- return false;
- }
-
- public static JSONObject getViews() {
- return viewList;
- }
-
- public static void updateViewList() {
- CordovaWebView targetView = null;
- String jsString = "";
- try {
- // Build JS execution String form all view names in viewList
- targetView = (CordovaWebView) viewList.get("mainView");
- JSONArray viewListNameArray = viewList.names();
- jsString += "window.wizViewManager.updateViewList(" + viewListNameArray.toString() + "); ";
- Log.d("wizViewManager", "Execute JS: " + jsString);
- Log.d("wizViewManager", "Updated view list");
- } catch (JSONException ex) {
- return;
- }
- final CordovaWebView _targetView = targetView;
- final String _jsString = jsString;
-
- _cordova.getActivity().runOnUiThread(
- new Runnable() {
- public void run() {
- if (_targetView != null) {
- _targetView.loadUrl("javascript:" + _jsString);
- }
- }
- }
- );
-
- // Clean up references
- targetView = null;
- jsString = null;
- }
-
- public static void setLayout(CordovaWebView webView, JSONObject settings) {
-
- Log.d("WizViewManager", "Setting up mainView layout...");
- Log.d("WizViewManager", webView.toString());
-
- String url;
- // Size
- int _height = webView.getHeight();
- int _width = webView.getWidth();
- // Margins
- int _x = 0;
- int _y = 0;
- int _top = 0;
- int _bottom = 0;
-
- int _right = 0;
- int _left = 0;
-
- if (settings.has("height")) {
- try {
- _height = settings.getInt("height");
- } catch (JSONException e) {
- // default
- _height = ViewGroup.LayoutParams.MATCH_PARENT;
- }
- }
-
- if (settings.has("width")) {
- try {
- _width = settings.getInt("width");
- } catch (JSONException e) {
- // default
- _width = ViewGroup.LayoutParams.MATCH_PARENT;
- }
- }
-
- if (settings.has("x")) {
- try {
- _x = settings.getInt("x");
- } catch (JSONException e) {
- // default
- _x = 0;
- }
- }
-
- if (settings.has("y")) {
- try {
- _y = settings.getInt("y");
- } catch (JSONException e) {
- // default
- _y = 0;
- }
- }
-
- if (settings.has("left")) {
- try {
- _left = _x + settings.getInt("left");
- _width -= _left;
- } catch (JSONException e) {
- // default
- _left = _x;
- }
- }
-
- if (settings.has("right")) {
- try {
- _right = settings.getInt("right");
- _width += _right;
- } catch (JSONException e) {
- // default
- _right = 0;
- }
- }
-
- if (settings.has("top")) {
- try {
- _top = _y + settings.getInt("top");
- } catch (JSONException e) {
- // default
- _top = _y;
- }
- }
- if (settings.has("bottom")) {
- try {
- _bottom = settings.getInt("bottom") - _y;
- } catch (JSONException e) {
- // default
- _bottom = 0 - _y;
- }
- }
-/*
- ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams) webView.getLayoutParams();
- Log.d("WizViewManager", marginParams.toString());
- marginParams.setMargins(_left, _top, _right, _bottom);
-
- webView.setLayoutParams(marginParams);
-*/
- LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) webView.getLayoutParams();
- Log.d("WizViewManager", layoutParams.toString());
- layoutParams.setMargins(_left, _top, _right, _bottom);
- layoutParams.height = _height;
- layoutParams.width = _width;
-
- webView.setLayoutParams(layoutParams);
-
- Log.d("WizViewManager", "new layout -> width: " + layoutParams.width + " - height: " + layoutParams.height + " - margins: " + layoutParams.leftMargin + "," + layoutParams.topMargin + "," + layoutParams.rightMargin + "," + layoutParams.bottomMargin);
- }
-
-}
diff --git a/example/android/src/jp/wizcorp/phonegap/plugin/wizViewManager/WizWebView.java b/example/android/src/jp/wizcorp/phonegap/plugin/wizViewManager/WizWebView.java
deleted file mode 100644
index 6ffc36e..0000000
--- a/example/android/src/jp/wizcorp/phonegap/plugin/wizViewManager/WizWebView.java
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- * __ __ _ _ __ __ _ _
- * / / /\ \ (_)______ _ _ __ __| | / / /\ \ \___| |__/\ /(_) _____ __
- * \ \/ \/ / |_ / _` | '__/ _` | \ \/ \/ / _ \ '_ \ \ / / |/ _ \ \ /\ / /
- * \ /\ /| |/ / (_| | | | (_| | \ /\ / __/ |_) \ V /| | __/\ V V /
- * \/ \/ |_/___\__,_|_| \__,_| \/ \/ \___|_.__/ \_/ |_|\___| \_/\_/
- *
- * @author Ally Ogilvie
- * @copyright Wizcorp Inc. [ Incorporated Wizards ] 2013
- * @file - WizViewManagerPlugin.java
- * @about - Builder and controller for Wizard WebView Navigation
-*/
-package jp.wizcorp.phonegap.plugin.wizViewManager;
-
-import android.app.Activity;
-import android.content.res.AssetManager;
-import android.graphics.Color;
-import android.os.Build;
-import android.view.Gravity;
-import android.view.ViewGroup;
-import android.webkit.MimeTypeMap;
-import android.widget.RelativeLayout;
-import org.apache.cordova.CallbackContext;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.util.Log;
-import android.view.View;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.widget.FrameLayout;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLDecoder;
-
-@TargetApi(Build.VERSION_CODES.HONEYCOMB)
-@SuppressLint("SetJavaScriptEnabled")
-public class WizWebView extends WebView {
-
- private String TAG = "WizWebView";
- private CallbackContext create_cb;
- private CallbackContext load_cb;
- private Context mContext;
-
- static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
- new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT,
- Gravity.CENTER);
-
- public WizWebView(String viewName, JSONObject settings, Context context, CallbackContext callbackContext) {
- // Constructor method
- super(context);
-
- mContext = context;
-
- Log.d("WizWebView", "[WizWebView] *************************************");
- Log.d("WizWebView", "[WizWebView] building - new Wizard View");
- Log.d("WizWebView", "[WizWebView] -> " + viewName);
- Log.d("WizWebView", "[WizWebView] *************************************");
-
- // Hold create callback and execute after page load
- this.create_cb = callbackContext;
-
- // Set invisible by default, developer MUST call show to see the view
- this.setVisibility(View.INVISIBLE);
-
- // WizWebView Settings
- WebSettings webSettings = this.getSettings();
-
- webSettings.setJavaScriptEnabled(true);
-
- webSettings.setDomStorageEnabled(true);
-
- webSettings.setLoadWithOverviewMode(true);
- webSettings.setUseWideViewPort(true);
-
- if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
- Level16Apis.enableUniversalAccess(webSettings);
- }
-
- this.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
-
- this.loadUrl("javascript:window.name = '" + viewName + "';");
-
- ViewGroup frame = (ViewGroup) ((Activity) context).findViewById(android.R.id.content);
-
- // Creating a new RelativeLayout fill its parent by default
- RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
- RelativeLayout.LayoutParams.FILL_PARENT,
- RelativeLayout.LayoutParams.FILL_PARENT);
-
- // Default full screen
- frame.addView(this, rlp);
-
- this.setPadding(999, 0, 0, 0);
-
- // Set a transparent background
- this.setBackgroundColor(Color.TRANSPARENT);
- if (Build.VERSION.SDK_INT >= 11) this.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);
-
- // Override url loading on WebViewClient
- this.setWebViewClient(new WebViewClient () {
- @Override
- public boolean shouldOverrideUrlLoading(WebView wView, String url) {
- Log.d("WizWebView", "[WizWebView] ****** " + url);
-
- String[] urlArray;
- String splitter = "://";
-
- // Split url by only 2 in the event "://" occurs elsewhere (SHOULD be impossible because you string encoded right!?)
- urlArray = url.split(splitter,2);
-
- if (urlArray[0].equalsIgnoreCase("wizpostmessage")) {
-
- String[] msgData;
- splitter = "\\?";
-
- // Split url by only 2 again to make sure we only spit at the first "?"
- msgData = urlArray[1].split(splitter);
- // target View = msgData[0] and message = msgData[1]
- // Get webview list from View Manager
- JSONObject viewList = WizViewManagerPlugin.getViews();
-
- if (viewList.has(msgData[1]) ) {
-
- WebView targetView;
- try {
- targetView = (WebView) viewList.get(msgData[1]);
-
- // send data to mainView
- String data2send = msgData[2];
- try {
- data2send = URLDecoder.decode(data2send, "UTF-8");
- } catch (UnsupportedEncodingException e) {
-
- }
- data2send = data2send.replace("'", "\\'");
- // Log.d("WizWebView", "[wizMessage] targetView ****** is " + msgData[1] + " -> " + targetView + " with data -> " + data2send);
- targetView.loadUrl("javascript:wizViewMessenger.__triggerMessageEvent('" + msgData[0] + "', '" + msgData[1] + "', '" + data2send + "', '" + msgData[3] + "');");
-
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- // app will handle this url, don't change the browser url
- return true;
- }
-
- if (urlArray[0].equalsIgnoreCase("wizmessageview") ) {
-
- String[] msgData;
- splitter = "\\?";
-
- // Split url by only 2 again to make sure we only spit at the first "?"
- msgData = urlArray[1].split(splitter);
-
-
- // target View = msgData[0] and message = msgData[1]
-
- // Get webview list from View Manager
- JSONObject viewList = WizViewManagerPlugin.getViews();
-
- if (viewList.has(msgData[0])) {
-
- WebView targetView;
- try {
- targetView = (WebView) viewList.get(msgData[0]);
-
- // send data to mainView
- String data2send = msgData[1];
- data2send = data2send.replace("'", "\\'");
- // Log.d(TAG, "[wizMessage] targetView ****** is " + msgData[0] + " -> " + targetView + " with data -> " + data2send);
- targetView.loadUrl("javascript:(wizMessageReceiver('" + data2send + "'))");
-
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- // app will handle this url, don't change the browser url
- return true;
- }
- // allow all other url requests
- return false;
- }
-
- @Override
- public void onPageFinished(WebView wView, String url) {
-
- WizViewManagerPlugin.updateViewList();
-
- // Push wizViewMessenger
-
- String jsString = "var WizViewMessenger = function () {};\n" +
- "console.log('trythis');" +
- "WizViewMessenger.prototype.postMessage = function (message, targetView) { \n" +
- " var type;\n" +
- " if (Object.prototype.toString.call(message) === \"[object Array]\") {\n" +
- " type = \"Array\";\n" +
- " message = JSON.stringify(message);\n" +
- " } else if (Object.prototype.toString.call(message) === \"[object String]\") {\n" +
- " type = \"String\";\n" +
- " } else if (Object.prototype.toString.call(message) === \"[object Number]\") {\n" +
- " type = \"Number\";\n" +
- " message = JSON.stringify(message);\n" +
- " } else if (Object.prototype.toString.call(message) === \"[object Boolean]\") {\n" +
- " type = \"Boolean\";\n" +
- " message = message.toString();\n" +
- " } else if (Object.prototype.toString.call(message) === \"[object Function]\") {\n" +
- " type = \"Function\";\n" +
- " message = message.toString();\n" +
- " } else if (Object.prototype.toString.call(message) === \"[object Object]\") {\n" +
- " type = \"Object\";\n" +
- " message = JSON.stringify(message);\n" +
- " } else {\n" +
- " console.error(\"WizViewMessenger posted unknown type!\");\n" +
- " return;\n" +
- " }\n" +
- " \n" +
- "\tvar iframe = document.createElement('IFRAME');\n" +
- "\tiframe.setAttribute('src', 'wizPostMessage://'+ window.encodeURIComponent(window.name) + '?' + window.encodeURIComponent(targetView) + '?' + window.encodeURIComponent(message) + '?' + type );\n" +
- "\tsetTimeout(function () {" +
- "\tdocument.documentElement.appendChild(iframe);\n" +
- "\tiframe.parentNode.removeChild(iframe);\n" +
- "\tiframe = null;\t\t\n" +
- "\t}, 1);" +
- "};\n" +
- " \n" +
- "WizViewMessenger.prototype.__triggerMessageEvent = function (origin, target, data, type) { \n" +
- " if (type === \"Array\") {\n" +
- " data = JSON.parse(data);\n" +
- " } else if (type === \"String\") {\n" +
- " // Stringy String String\n" +
- " } else if (type === \"Number\") {\n" +
- " data = JSON.parse(data);\n" +
- " } else if (type === \"Boolean\") {\n" +
- " data = Boolean(data);\n" +
- " } else if (type === \"Function\") {\n" +
- " } else if (type === \"Object\") {\n" +
- " data = JSON.parse(data);\n" +
- " } else {\n" +
- " \tconsole.error(\"Message Event received unknown type!\");\n" +
- " return;\n" +
- " }\n" +
- "\t\n" +
- "\tvar event = document.createEvent(\"HTMLEvents\");\n" +
- "\tevent.initEvent(\"message\", true, true);\n" +
- "\tevent.eventName = \"message\";\n" +
- "\tevent.memo = { };\n" +
- "\tevent.origin = origin;\n" +
- "\tevent.source = target;\n" +
- "\tevent.data = data;\n" +
- "\tdispatchEvent(event);\n" +
- "};\n" +
- "\n" +
- "window.wizViewMessenger = new WizViewMessenger();";
-
- wView.loadUrl("javascript:" + jsString);
-
- if (create_cb != null) {
- create_cb.success();
- Log.d(TAG, "View created and loaded");
- // Callback used, don't call it again.
- create_cb = null;
- }
-
- if (load_cb != null) {
- load_cb.success();
- Log.d(TAG, "View finished load");
- // Callback used, don't call it again.
- load_cb = null;
- }
- }
-
- public void onReceivedError(WebView view, int errorCod, String description, String failingUrl) {
- Log.e(TAG, "Error: Cannot load " + failingUrl + " \n Reason: " + description);
- if (create_cb != null) {
- create_cb.error(description);
- // Callback used, don't call it again.
- create_cb = null;
- }
- }
- });
-
- // Analyse settings object
- if (settings != null) {
- this.setLayout(settings, create_cb);
- } else {
- // Apply Defaults
- this.setLayoutParams(COVER_SCREEN_GRAVITY_CENTER);
- }
-
- Log.d(TAG, "Create complete");
- } // ************ END CONSTRUCTOR **************
-
- public void setLayout(JSONObject settings, CallbackContext callback) {
- Log.d(TAG, "Setting up layout...");
-
- String url;
-
- // Set default settings to max screen
- ViewGroup parent = (ViewGroup) this.getParent();
-
- // Size
- int _parentHeight = parent.getHeight();
- int _parentWidth = parent.getWidth();
- int _height = _parentHeight;
- int _width = _parentWidth;
-
- // Margins
- int _x = 0;
- int _y = 0;
- int _top = 0;
- int _bottom = 0;
- int _right = 0;
- int _left = 0;
-
- if (settings.has("height")) {
- try {
- _height = settings.getInt("height");
- } catch (JSONException e) {
- // ignore
- Log.e(TAG, "Error obtaining 'height' in settings");
- }
- }
-
- if (settings.has("width")) {
- try {
- _width = settings.getInt("width");
- } catch (JSONException e) {
- // ignore
- Log.e(TAG, "Error obtaining 'width' in settings");
- }
- }
-
- if (settings.has("x")) {
- try {
- _x = settings.getInt("x");
- _left = _x;
- _width = _width + _x;
- } catch (JSONException e) {
- // ignore
- Log.e(TAG, "Error obtaining 'x' in settings");
- }
- }
-
- if (settings.has("y")) {
- try {
- _y = settings.getInt("y");
- _top = _y;
- _height = _height + _y;
- } catch (JSONException e) {
- // ignore
- Log.e(TAG, "Error obtaining 'y' in settings");
- }
- }
-
- if (settings.has("left")) {
- try {
- _left = _left + settings.getInt("left");
- _width -= _left;
- } catch (JSONException e) {
- // ignore
- Log.e(TAG, "Error obtaining 'left' in settings");
- }
- } else {
- // default
- if (_x != 0) {
- _left = _x;
- }
- }
-
- if (settings.has("right")) {
- try {
- _right = settings.getInt("right");
- _width = _width - _right;
- } catch (JSONException e) {
- // ignore
- Log.e(TAG, "Error obtaining 'right' in settings");
- }
- }
-
- if (settings.has("top")) {
- try {
- _top = _top + settings.getInt("top");
- } catch (JSONException e) {
- // ignore
- Log.e(TAG, "Error obtaining 'top' in settings");
- }
- } else {
- // default
- if (_y != 0) {
- _top = _y;
- }
- }
-
- if (settings.has("bottom")) {
- try {
- _top = _top + _parentHeight - _height - settings.getInt("bottom");
- _bottom = - settings.getInt("bottom");
- } catch (JSONException e) {
- // ignore
- Log.e(TAG, "Error obtaining 'bottom' in settings");
- }
- }
-
- FrameLayout.LayoutParams newLayoutParams = (FrameLayout.LayoutParams) this.getLayoutParams();
- newLayoutParams.setMargins(_left, _top, _right, _bottom);
- newLayoutParams.height = _height;
- newLayoutParams.width = _width;
-
- this.setLayoutParams(newLayoutParams);
-
- Log.d(TAG, "new layout -> width: " + newLayoutParams.width + " - height: " + newLayoutParams.height + " - margins: " + newLayoutParams.leftMargin + "," + newLayoutParams.topMargin + "," + newLayoutParams.rightMargin + "," + newLayoutParams.bottomMargin);
-
- if (settings.has("src")) {
- try {
- url = settings.getString("src");
- load(url, callback);
- } catch (JSONException e) {
- // default
- // nothing to load
- Log.e(TAG, "Loading source from settings exception : " + e);
- }
- } else {
- Log.d(TAG, "No source to load");
- }
- }
-
- public void load(String source, CallbackContext callbackContext) {
- // Link up our callback
- load_cb = callbackContext;
-
- // Check source extension
- try {
- URL url = new URL(source); // Check for the protocol
- url.toURI(); // Extra checking required for validation of URI
-
- // If we did not fall out here then source is a valid URI, check extension
- if (url.getPath().length() > 0) {
- // Not loading a straight domain, check extension of non-domain path
- String ext = MimeTypeMap.getFileExtensionFromUrl(url.getPath());
- Log.d(TAG, "URL ext: " + ext);
- if (validateExtension("." + ext)) {
- // Load this
- this.loadUrl(source);
- } else {
- // Check if file type is in the helperList
- if (requiresHelper("." + ext)) {
- // Load this
- this.loadUrl("http://docs.google.com/gview?embedded=true&url=" + source);
- } else {
- // Not valid extension in whitelist and cannot be helped
- Log.e(TAG, "Not a valid file extension!");
- if (load_cb != null) {
- load_cb.error("Not a valid file extension.");
- load_cb = null;
- }
- }
- }
- return;
-
- } else {
- // URL has no path, for example - http://google.com
- Log.d(TAG, "load URL: " + source);
- this.loadUrl(source);
- }
-
- } catch (MalformedURLException ex1) {
- // Missing protocol, assume local file
-
- // Check cache for latest file
- File cache = mContext.getApplicationContext().getCacheDir();
- File file = new File(cache.getAbsolutePath() + "/" + source);
- if (file.exists()) {
- // load it
- Log.d(TAG, "load: " + "file:///" + cache.getAbsolutePath() + "/" + source);
- source = ("file:///" + cache.getAbsolutePath() + "/" + source);
- } else {
- // Check file exists in bundle assets
- AssetManager mg = mContext.getResources().getAssets();
- try {
- mg.open("www/" + source);
- Log.d(TAG, "load: file:///android_asset/www/" + source);
- source = "file:///android_asset/www/" + source;
- } catch (IOException ex) {
- // Not in bundle assets. Try full path
- file = new File(source);
- if (file.exists()) {
- Log.d(TAG, "load: file:///" + source);
- source = "file:///" + source;
- file = null;
- } else {
- // File cannot be found
- Log.e(TAG, "File: " + source + " cannot be found!");
- if (load_cb != null) {
- load_cb.error("File: " + source + " cannot be found!");
- load_cb = null;
- }
- return;
- }
- }
- }
- this.loadUrl(source);
- } catch (URISyntaxException ex2) {
- Log.e(TAG, "URISyntaxException loading: file://" + source);
- if (load_cb != null) {
- load_cb.error("URISyntaxException loading: file://" + source);
- load_cb = null;
- }
- }
- }
-
- private boolean validateExtension(String candidate) {
- for (String s: WizViewManagerPlugin.whitelist) {
- // Check extension exists in whitelist
- if (s.equalsIgnoreCase(candidate)) {
- return true;
- }
- }
- return false;
- }
-
- private boolean requiresHelper(String candidate) {
- for (String s: WizViewManagerPlugin.helperList) {
- // Check extension exists in helperList
- if (s.equalsIgnoreCase(candidate)) {
- return true;
- }
- }
- return false;
- }
-
- @TargetApi(16)
- private static class Level16Apis {
- static void enableUniversalAccess(WebSettings settings) {
- settings.setAllowUniversalAccessFromFileURLs(true);
- }
- }
-}
-
diff --git a/example/ios/CordovaLib/Cordova.framework/Cordova b/example/ios/CordovaLib/Cordova.framework/Cordova
deleted file mode 120000
index ffdd7e5..0000000
--- a/example/ios/CordovaLib/Cordova.framework/Cordova
+++ /dev/null
@@ -1 +0,0 @@
-Versions/Current/Cordova
\ No newline at end of file
diff --git a/example/ios/CordovaLib/Cordova.framework/Headers b/example/ios/CordovaLib/Cordova.framework/Headers
deleted file mode 120000
index a177d2a..0000000
--- a/example/ios/CordovaLib/Cordova.framework/Headers
+++ /dev/null
@@ -1 +0,0 @@
-Versions/Current/Headers
\ No newline at end of file
diff --git a/example/ios/CordovaLib/Cordova.framework/Resources b/example/ios/CordovaLib/Cordova.framework/Resources
deleted file mode 120000
index 953ee36..0000000
--- a/example/ios/CordovaLib/Cordova.framework/Resources
+++ /dev/null
@@ -1 +0,0 @@
-Versions/Current/Resources
\ No newline at end of file
diff --git a/example/ios/CordovaLib/Cordova.framework/Versions/A/Cordova b/example/ios/CordovaLib/Cordova.framework/Versions/A/Cordova
deleted file mode 100644
index e7d04c5..0000000
Binary files a/example/ios/CordovaLib/Cordova.framework/Versions/A/Cordova and /dev/null differ
diff --git a/example/ios/CordovaLib/Cordova.framework/Versions/A/Resources/Info.plist b/example/ios/CordovaLib/Cordova.framework/Versions/A/Resources/Info.plist
deleted file mode 100644
index a493033..0000000
Binary files a/example/ios/CordovaLib/Cordova.framework/Versions/A/Resources/Info.plist and /dev/null differ
diff --git a/example/ios/CordovaLib/Cordova.framework/Versions/A/Resources/en.lproj/InfoPlist.strings b/example/ios/CordovaLib/Cordova.framework/Versions/A/Resources/en.lproj/InfoPlist.strings
deleted file mode 100644
index 3967e06..0000000
Binary files a/example/ios/CordovaLib/Cordova.framework/Versions/A/Resources/en.lproj/InfoPlist.strings and /dev/null differ
diff --git a/example/ios/CordovaLib/Cordova.framework/Versions/Current b/example/ios/CordovaLib/Cordova.framework/Versions/Current
deleted file mode 120000
index 8c7e5a6..0000000
--- a/example/ios/CordovaLib/Cordova.framework/Versions/Current
+++ /dev/null
@@ -1 +0,0 @@
-A
\ No newline at end of file
diff --git a/example/ios/README.md b/example/ios/README.md
deleted file mode 100644
index 45313c6..0000000
--- a/example/ios/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# SETUP FOR BUILDING
-
-To build this example, PhoneGap requires that the plugin be installed in the
-correct location relative to this example's www directory. So we must copy or
-link the plugin javascript code to the www directory.
-
-Currently, the XCode project performs the copy method (described below) as part
-of it's build process.
-
-Copy Javascript Files Method:
- mkdir -p ../www/phonegap
- cp -r ../../www/phonegap ../www
-
-
-** REMEMBER TO ADD YOUR CORDOVA.FRAMEWORK TO THE EXAMPLE PROJECT **
\ No newline at end of file
diff --git a/example/ios/exampleWizViewManager/Resources/splash/Default-568h@2x.png b/example/ios/exampleWizViewManager/Resources/splash/Default-568h@2x.png
deleted file mode 100644
index 0891b7a..0000000
Binary files a/example/ios/exampleWizViewManager/Resources/splash/Default-568h@2x.png and /dev/null differ
diff --git a/example/ios/exampleWizViewManager/Resources/splash/Default-568h@2x~iphone.png b/example/ios/exampleWizViewManager/Resources/splash/Default-568h@2x~iphone.png
deleted file mode 100755
index aec2d8c..0000000
Binary files a/example/ios/exampleWizViewManager/Resources/splash/Default-568h@2x~iphone.png and /dev/null differ
diff --git a/example/ios/exampleWizViewManager/Resources/splash/Default-Landscape@2x~ipad.png b/example/ios/exampleWizViewManager/Resources/splash/Default-Landscape@2x~ipad.png
deleted file mode 100755
index 95c542d..0000000
Binary files a/example/ios/exampleWizViewManager/Resources/splash/Default-Landscape@2x~ipad.png and /dev/null differ
diff --git a/example/ios/exampleWizViewManager/Resources/splash/Default-Landscape~ipad.png b/example/ios/exampleWizViewManager/Resources/splash/Default-Landscape~ipad.png
deleted file mode 100755
index f8e2b52..0000000
Binary files a/example/ios/exampleWizViewManager/Resources/splash/Default-Landscape~ipad.png and /dev/null differ
diff --git a/example/ios/exampleWizViewManager/Resources/splash/Default-Portrait@2x~ipad.png b/example/ios/exampleWizViewManager/Resources/splash/Default-Portrait@2x~ipad.png
deleted file mode 100755
index aae1862..0000000
Binary files a/example/ios/exampleWizViewManager/Resources/splash/Default-Portrait@2x~ipad.png and /dev/null differ
diff --git a/example/ios/exampleWizViewManager/Resources/splash/Default-Portrait~ipad.png b/example/ios/exampleWizViewManager/Resources/splash/Default-Portrait~ipad.png
deleted file mode 100755
index af9158a..0000000
Binary files a/example/ios/exampleWizViewManager/Resources/splash/Default-Portrait~ipad.png and /dev/null differ
diff --git a/example/ios/exampleWizViewManager/Resources/splash/Default@2x~iphone.png b/example/ios/exampleWizViewManager/Resources/splash/Default@2x~iphone.png
deleted file mode 100644
index bd24886..0000000
Binary files a/example/ios/exampleWizViewManager/Resources/splash/Default@2x~iphone.png and /dev/null differ
diff --git a/example/ios/exampleWizViewManager/Resources/splash/Default~iphone.png b/example/ios/exampleWizViewManager/Resources/splash/Default~iphone.png
deleted file mode 100644
index 6fcba56..0000000
Binary files a/example/ios/exampleWizViewManager/Resources/splash/Default~iphone.png and /dev/null differ
diff --git a/example/ios/exampleWizViewManager/en.lproj/InfoPlist.strings b/example/ios/exampleWizViewManager/en.lproj/InfoPlist.strings
deleted file mode 100644
index 477b28f..0000000
--- a/example/ios/exampleWizViewManager/en.lproj/InfoPlist.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Localized versions of Info.plist keys */
-
diff --git a/example/ios/exampleWizViewManager/exampleWizViewManager-Info.plist b/example/ios/exampleWizViewManager/exampleWizViewManager-Info.plist
deleted file mode 100644
index 4acc332..0000000
--- a/example/ios/exampleWizViewManager/exampleWizViewManager-Info.plist
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
-
-
- CFBundleIcons
-
- CFBundlePrimaryIcon
-
- CFBundleIconFiles
-
- icon.png
- icon@2x.png
- icon-72.png
- icon-72@2x.png
-
- UIPrerenderedIcon
-
-
-
- UISupportedInterfaceOrientations~ipad
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeRight
-
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationPortrait
-
- CFBundleDevelopmentRegion
- English
- CFBundleDisplayName
- ${PRODUCT_NAME}
- CFBundleExecutable
- ${EXECUTABLE_NAME}
- CFBundleIconFile
- icon.png
- CFBundleIdentifier
- jp.wizcorp.exampleWizViewManager
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- ${PRODUCT_NAME}
- CFBundlePackageType
- APPL
- CFBundleSignature
- ????
- CFBundleVersion
- 1.0
- LSRequiresIPhoneOS
-
- NSMainNibFile
-
- NSMainNibFile~ipad
-
-
-
diff --git a/platforms/android/.classpath b/platforms/android/.classpath
new file mode 100644
index 0000000..7bc01d9
--- /dev/null
+++ b/platforms/android/.classpath
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/platforms/android/.project b/platforms/android/.project
new file mode 100644
index 0000000..602b9b1
--- /dev/null
+++ b/platforms/android/.project
@@ -0,0 +1,33 @@
+
+
+ HelloCordova
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/example/android/AndroidManifest.xml b/platforms/android/AndroidManifest.xml
similarity index 69%
rename from example/android/AndroidManifest.xml
rename to platforms/android/AndroidManifest.xml
index b0556a1..fb971a7 100644
--- a/example/android/AndroidManifest.xml
+++ b/platforms/android/AndroidManifest.xml
@@ -1,17 +1,14 @@
-
+
-
+
-
-
-
-
+
diff --git a/platforms/android/CordovaLib/.classpath b/platforms/android/CordovaLib/.classpath
new file mode 100644
index 0000000..7bc01d9
--- /dev/null
+++ b/platforms/android/CordovaLib/.classpath
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/platforms/android/CordovaLib/.project b/platforms/android/CordovaLib/.project
new file mode 100644
index 0000000..4a53c2f
--- /dev/null
+++ b/platforms/android/CordovaLib/.project
@@ -0,0 +1,33 @@
+
+
+ HelloCordova-CordovaLib
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/platforms/android/CordovaLib/AndroidManifest.xml b/platforms/android/CordovaLib/AndroidManifest.xml
new file mode 100755
index 0000000..15a9702
--- /dev/null
+++ b/platforms/android/CordovaLib/AndroidManifest.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
diff --git a/example/android/build.xml b/platforms/android/CordovaLib/build.xml
similarity index 98%
rename from example/android/build.xml
rename to platforms/android/CordovaLib/build.xml
index c8d0fec..18829c4 100644
--- a/example/android/build.xml
+++ b/platforms/android/CordovaLib/build.xml
@@ -1,5 +1,5 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/platforms/android/cordova/android_sdk_version b/platforms/android/cordova/android_sdk_version
new file mode 100755
index 0000000..547f41b
--- /dev/null
+++ b/platforms/android/cordova/android_sdk_version
@@ -0,0 +1,29 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var android_sdk_version = require('./lib/android_sdk_version');
+
+android_sdk_version.run().done(null, function(err) {
+ console.log(err);
+ process.exit(2);
+});
+
+
diff --git a/platforms/android/cordova/build b/platforms/android/cordova/build
new file mode 100755
index 0000000..a38f3b6
--- /dev/null
+++ b/platforms/android/cordova/build
@@ -0,0 +1,37 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var build = require('./lib/build'),
+ reqs = require('./lib/check_reqs'),
+ args = process.argv;
+
+// Support basic help commands
+if(args[2] == '--help' || args[2] == '/?' || args[2] == '-h' ||
+ args[2] == 'help' || args[2] == '-help' || args[2] == '/help') {
+ build.help();
+} else {
+ reqs.run().then(function() {
+ return build.run(args[2]);
+ }).done(null, function(err) {
+ console.error(err);
+ process.exit(2);
+ });
+}
diff --git a/platforms/android/cordova/build.bat b/platforms/android/cordova/build.bat
new file mode 100644
index 0000000..46e966a
--- /dev/null
+++ b/platforms/android/cordova/build.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script_path="%~dp0build"
+IF EXIST %script_path% (
+ node %script_path% %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'build' script in 'cordova' folder, aborting...>&2
+ EXIT /B 1
+)
\ No newline at end of file
diff --git a/platforms/android/cordova/check_reqs b/platforms/android/cordova/check_reqs
new file mode 100755
index 0000000..372a383
--- /dev/null
+++ b/platforms/android/cordova/check_reqs
@@ -0,0 +1,31 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var check_reqs = require('./lib/check_reqs');
+
+check_reqs.run().done(
+ function success() {
+ console.log('Looks like your environment fully supports cordova-android development!');
+ }, function fail(err) {
+ console.log(err);
+ process.exit(2);
+ }
+);
diff --git a/platforms/android/cordova/clean b/platforms/android/cordova/clean
new file mode 100755
index 0000000..4e0808b
--- /dev/null
+++ b/platforms/android/cordova/clean
@@ -0,0 +1,36 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var clean = require('./lib/clean'),
+ reqs = require('./lib/check_reqs'),
+ args = process.argv;
+
+// Usage support for when args are given
+if(args.length > 2) {
+ clean.help();
+} else {
+ reqs.run().done(function() {
+ return clean.run();
+ }, function(err) {
+ console.error('ERROR: ' + err);
+ process.exit(2);
+ });
+}
diff --git a/platforms/android/cordova/clean.bat b/platforms/android/cordova/clean.bat
new file mode 100644
index 0000000..445ef6e
--- /dev/null
+++ b/platforms/android/cordova/clean.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script_path="%~dp0clean"
+IF EXIST %script_path% (
+ node %script_path% %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'clean' script in 'cordova' folder, aborting...>&2
+ EXIT /B 1
+)
\ No newline at end of file
diff --git a/platforms/android/cordova/defaults.xml b/platforms/android/cordova/defaults.xml
new file mode 100644
index 0000000..24e5725
--- /dev/null
+++ b/platforms/android/cordova/defaults.xml
@@ -0,0 +1,50 @@
+
+
+
+ Hello Cordova
+
+
+ A sample Apache Cordova application that responds to the deviceready event.
+
+
+
+ Apache Cordova Team
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/platforms/android/cordova/lib/android_sdk_version.js b/platforms/android/cordova/lib/android_sdk_version.js
new file mode 100755
index 0000000..d03e1e7
--- /dev/null
+++ b/platforms/android/cordova/lib/android_sdk_version.js
@@ -0,0 +1,65 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var shell = require('shelljs'),
+ child_process = require('child_process'),
+ Q = require('q');
+
+get_highest_sdk = function(results){
+ var reg = /\d+/;
+ var apiLevels = [];
+ for(var i=0;i/.exec(manifestData);
+ if (!activityTag) throw new Error('Could not find within ' + manifestPath);
+ var activityName = /\bandroid:name\s*=\s*"(.+?)"/.exec(activityTag);
+ if (!activityName) throw new Error('Could not find android:name within ' + manifestPath);
+
+ return packageName[1] + '/.' + activityName[1];
+}
+
+exports.getActivityName = function() {
+ return cachedAppInfo = cachedAppInfo || readAppInfoFromManifest();
+};
diff --git a/platforms/android/cordova/lib/build.js b/platforms/android/cordova/lib/build.js
new file mode 100644
index 0000000..3b960c6
--- /dev/null
+++ b/platforms/android/cordova/lib/build.js
@@ -0,0 +1,87 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var shell = require('shelljs'),
+ exec = require('./exec'),
+ Q = require('q'),
+ clean = require('./clean'),
+ path = require('path'),
+ fs = require('fs'),
+ ROOT = path.join(__dirname, '..', '..');
+
+/*
+ * Builds the project with ant.
+ * Returns a promise.
+ */
+module.exports.run = function(build_type) {
+ //default build type
+ build_type = typeof build_type !== 'undefined' ? build_type : "--debug";
+ var cmd;
+ switch(build_type) {
+ case '--debug' :
+ cmd = 'ant debug -f "' + path.join(ROOT, 'build.xml') + '"';
+ break;
+ case '--release' :
+ cmd = 'ant release -f "' + path.join(ROOT, 'build.xml') + '"';
+ break;
+ case '--nobuild' :
+ console.log('Skipping build...');
+ return Q();
+ default :
+ return Q.reject('Build option \'' + build_type + '\' not recognized.');
+ }
+ if(cmd) {
+ return clean.run() // TODO: Can we stop cleaning every time and let ant build incrementally?
+ .then(function() {
+ return exec(cmd);
+ });
+ }
+ return Q();
+}
+
+/*
+ * Gets the path to the apk file, if not such file exists then
+ * the script will error out. (should we error or just return undefined?)
+ */
+module.exports.get_apk = function() {
+ if(fs.existsSync(path.join(ROOT, 'bin'))) {
+ var bin_files = fs.readdirSync(path.join(ROOT, 'bin'));
+ for (file in bin_files) {
+ if(path.extname(bin_files[file]) == '.apk') {
+ return path.join(ROOT, 'bin', bin_files[file]);
+ }
+ }
+ console.error('ERROR : No .apk found in \'bin\' folder');
+ process.exit(2);
+ } else {
+ console.error('ERROR : unable to find project bin folder, could not locate .apk');
+ process.exit(2);
+ }
+}
+
+module.exports.help = function() {
+ console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'corodva', 'build')) + ' [build_type]');
+ console.log('Build Types : ');
+ console.log(' \'--debug\': Default build, will build project in using ant debug');
+ console.log(' \'--release\': will build project using ant release');
+ console.log(' \'--nobuild\': will skip build process (can be used with run command)');
+ process.exit(0);
+}
diff --git a/platforms/android/cordova/lib/check_reqs.js b/platforms/android/cordova/lib/check_reqs.js
new file mode 100644
index 0000000..1c6f0f8
--- /dev/null
+++ b/platforms/android/cordova/lib/check_reqs.js
@@ -0,0 +1,96 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var shell = require('shelljs'),
+ child_process = require('child_process'),
+ Q = require('q'),
+ path = require('path'),
+ fs = require('fs'),
+ ROOT = path.join(__dirname, '..', '..');
+
+// Get valid target from framework/project.properties
+module.exports.get_target = function() {
+ if(fs.existsSync(path.join(ROOT, 'framework', 'project.properties'))) {
+ var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'framework', 'project.properties'));
+ return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
+ } else if (fs.existsSync(path.join(ROOT, 'project.properties'))) {
+ // if no target found, we're probably in a project and project.properties is in ROOT.
+ // this is called on the project itself, and can support Google APIs AND Vanilla Android
+ var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties')) ||
+ shell.grep(/target=Google Inc.:Google APIs:[\d+]/, path.join(ROOT, 'project.properties'));
+ return target.split('=')[1].replace('\n', '').replace('\r', '');
+ }
+}
+
+// Returns a promise.
+module.exports.check_ant = function() {
+ var d = Q.defer();
+ child_process.exec('ant -version', function(err, stdout, stderr) {
+ if (err) d.reject(new Error('ERROR : executing command \'ant\', make sure you have ant installed and added to your path.'));
+ else d.resolve();
+ });
+ return d.promise;
+}
+
+// Returns a promise.
+module.exports.check_java = function() {
+ var d = Q.defer();
+ child_process.exec('java -version', function(err, stdout, stderr) {
+ if(err) {
+ var msg =
+ 'Failed to run \'java -version\', make sure your java environment is set up\n' +
+ 'including JDK and JRE.\n' +
+ 'Your JAVA_HOME variable is ' + process.env.JAVA_HOME + '\n';
+ d.reject(new Error(msg + err));
+ }
+ else d.resolve();
+ });
+ return d.promise;
+}
+
+// Returns a promise.
+module.exports.check_android = function() {
+ var valid_target = this.get_target();
+ var d = Q.defer();
+ child_process.exec('android list targets', function(err, stdout, stderr) {
+ if (err) d.reject(stderr);
+ else d.resolve(stdout);
+ });
+
+ return d.promise.then(function(output) {
+ if (!output.match(valid_target)) {
+ return Q.reject(new Error('Please install Android target ' + valid_target.split('-')[1] + ' (the Android newest SDK). Make sure you have the latest Android tools installed as well. Run \"android\" from your command-line to install/update any missing SDKs or tools.'));
+ }
+ return Q();
+ }, function(stderr) {
+ if (stderr.match(/command\snot\sfound/)) {
+ return Q.reject(new Error('The command \"android\" failed. Make sure you have the latest Android SDK installed, and the \"android\" command (inside the tools/ folder) is added to your path.'));
+ } else {
+ return Q.reject(new Error('An error occurred while listing Android targets'));
+ }
+ });
+}
+
+// Returns a promise.
+module.exports.run = function() {
+ return Q.all([this.check_ant(), this.check_java(), this.check_android()]);
+}
+
diff --git a/platforms/android/cordova/lib/clean.js b/platforms/android/cordova/lib/clean.js
new file mode 100644
index 0000000..4fc43af
--- /dev/null
+++ b/platforms/android/cordova/lib/clean.js
@@ -0,0 +1,38 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var exec = require('./exec'),
+ path = require('path'),
+ ROOT = path.join(__dirname, '..', '..');
+
+/*
+ * Cleans the project using ant
+ * Returns a promise.
+ */
+module.exports.run = function() {
+ return exec('ant clean -f "' + path.join(ROOT, 'build.xml') + '"');
+}
+
+module.exports.help = function() {
+ console.log('Usage: ' + path.relative(process.cwd(), process.argv[1]));
+ console.log('Cleans the project directory.');
+ process.exit(0);
+}
diff --git a/platforms/android/cordova/lib/device.js b/platforms/android/cordova/lib/device.js
new file mode 100644
index 0000000..a50ac8e
--- /dev/null
+++ b/platforms/android/cordova/lib/device.js
@@ -0,0 +1,86 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var exec = require('./exec'),
+ Q = require('q'),
+ path = require('path'),
+ build = require('./build'),
+ appinfo = require('./appinfo'),
+ ROOT = path.join(__dirname, '..', '..');
+
+/**
+ * Returns a promise for the list of the device ID's found
+ */
+module.exports.list = function() {
+ return exec('adb devices')
+ .then(function(output) {
+ var response = output.split('\n');
+ var device_list = [];
+ for (var i = 1; i < response.length; i++) {
+ if (response[i].match(/\w+\tdevice/) && !response[i].match(/emulator/)) {
+ device_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
+ }
+ }
+ return device_list;
+ });
+}
+
+/*
+ * Installs a previously built application on the device
+ * and launches it.
+ * Returns a promise.
+ */
+module.exports.install = function(target) {
+ var launchName;
+ return this.list()
+ .then(function(device_list) {
+ if (!device_list || !device_list.length)
+ return Q.reject('ERROR: Failed to deploy to device, no devices found.');
+
+ // default device
+ target = typeof target !== 'undefined' ? target : device_list[0];
+
+ if (device_list.indexOf(target) < 0)
+ return Q.reject('ERROR: Unable to find target \'' + target + '\'.');
+
+ var apk_path = build.get_apk();
+ launchName = appinfo.getActivityName();
+ console.log('Installing app on device...');
+ var cmd = 'adb -s ' + target + ' install -r "' + apk_path + '"';
+ return exec(cmd);
+ }).then(function(output) {
+ if (output.match(/Failure/)) return Q.reject('ERROR: Failed to install apk to device: ' + output);
+
+ //unlock screen
+ var cmd = 'adb -s ' + target + ' shell input keyevent 82';
+ return exec(cmd);
+ }, function(err) { return Q.reject('ERROR: Failed to install apk to device: ' + err); })
+ .then(function() {
+ // launch the application
+ console.log('Launching application...');
+ var cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
+ return exec(cmd);
+ }).then(function() {
+ console.log('LANCH SUCCESS');
+ }, function(err) {
+ return Q.reject('ERROR: Failed to launch application on device: ' + err);
+ });
+}
diff --git a/platforms/android/cordova/lib/emulator.js b/platforms/android/cordova/lib/emulator.js
new file mode 100644
index 0000000..fe24480
--- /dev/null
+++ b/platforms/android/cordova/lib/emulator.js
@@ -0,0 +1,330 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var shell = require('shelljs'),
+ exec = require('./exec'),
+ Q = require('q'),
+ path = require('path'),
+ appinfo = require('./appinfo'),
+ build = require('./build'),
+ ROOT = path.join(__dirname, '..', '..'),
+ child_process = require('child_process'),
+ new_emulator = 'cordova_emulator';
+
+/**
+ * Returns a Promise for a list of emulator images in the form of objects
+ * {
+ name : ,
+ path : ,
+ target : ,
+ abi : ,
+ skin :
+ }
+ */
+module.exports.list_images = function() {
+ return exec('android list avds')
+ .then(function(output) {
+ var response = output.split('\n');
+ var emulator_list = [];
+ for (var i = 1; i < response.length; i++) {
+ // To return more detailed information use img_obj
+ var img_obj = {};
+ if (response[i].match(/Name:\s/)) {
+ img_obj['name'] = response[i].split('Name: ')[1].replace('\r', '');
+ if (response[i + 1].match(/Path:\s/)) {
+ i++;
+ img_obj['path'] = response[i].split('Path: ')[1].replace('\r', '');
+ }
+ if (response[i + 1].match(/\(API\slevel\s/)) {
+ i++;
+ img_obj['target'] = response[i].replace('\r', '');
+ }
+ if (response[i + 1].match(/ABI:\s/)) {
+ i++;
+ img_obj['abi'] = response[i].split('ABI: ')[1].replace('\r', '');
+ }
+ if (response[i + 1].match(/Skin:\s/)) {
+ i++;
+ img_obj['skin'] = response[i].split('Skin: ')[1].replace('\r', '');
+ }
+
+ emulator_list.push(img_obj);
+ }
+ /* To just return a list of names use this
+ if (response[i].match(/Name:\s/)) {
+ emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
+ }*/
+
+ }
+ return emulator_list;
+ });
+}
+
+/**
+ * Will return the closest avd to the projects target
+ * or undefined if no avds exist.
+ * Returns a promise.
+ */
+module.exports.best_image = function() {
+ var project_target = this.get_target().replace('android-', '');
+ return this.list_images()
+ .then(function(images) {
+ var closest = 9999;
+ var best = images[0];
+ for (i in images) {
+ var target = images[i].target;
+ if(target) {
+ var num = target.split('(API level ')[1].replace(')', '');
+ if (num == project_target) {
+ return images[i];
+ } else if (project_target - num < closest && project_target > num) {
+ var closest = project_target - num;
+ best = images[i];
+ }
+ }
+ }
+ return best;
+ });
+}
+
+// Returns a promise.
+module.exports.list_started = function() {
+ return exec('adb devices')
+ .then(function(output) {
+ var response = output.split('\n');
+ var started_emulator_list = [];
+ for (var i = 1; i < response.length; i++) {
+ if (response[i].match(/device/) && response[i].match(/emulator/)) {
+ started_emulator_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
+ }
+ }
+ return started_emulator_list;
+ });
+}
+
+module.exports.get_target = function() {
+ var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties'));
+ return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
+}
+
+// Returns a promise.
+module.exports.list_targets = function() {
+ return exec('android list targets')
+ .then(function(output) {
+ var target_out = output.split('\n');
+ var targets = [];
+ for (var i = target_out.length; i >= 0; i--) {
+ if(target_out[i].match(/id:/)) {
+ targets.push(targets[i].split(' ')[1]);
+ }
+ }
+ return targets;
+ });
+}
+
+/*
+ * Starts an emulator with the given ID,
+ * and returns the started ID of that emulator.
+ * If no ID is given it will used the first image availible,
+ * if no image is availible it will error out (maybe create one?).
+ *
+ * Returns a promise.
+ */
+module.exports.start = function(emulator_ID) {
+ var self = this;
+ var emulator_id, num_started, started_emulators;
+
+ return self.list_started()
+ .then(function(list) {
+ started_emulators = list;
+ num_started = started_emulators.length;
+ if (typeof emulator_ID === 'undefined') {
+ return self.list_images()
+ .then(function(emulator_list) {
+ if (emulator_list.length > 0) {
+ return self.best_image()
+ .then(function(best) {
+ emulator_ID = best.name;
+ console.log('WARNING : no emulator specified, defaulting to ' + emulator_ID);
+ return emulator_ID;
+ });
+ } else {
+ return Q.reject('ERROR : No emulator images (avds) found, if you would like to create an\n' +
+ ' avd follow the instructions provided here:\n' +
+ ' http://developer.android.com/tools/devices/index.html\n' +
+ ' Or run \'android create avd --name --target \'\n' +
+ ' in on the command line.');
+ }
+ });
+ } else {
+ return Q(emulator_ID);
+ }
+ }).then(function() {
+ var cmd, args;
+ if(process.platform == 'win32' || process.platform == 'win64') {
+ cmd = '%comspec%';
+ args = ['/c', 'start', 'cmd', '/c', 'emulator', '-avd', emulator_ID];
+ } else {
+ cmd = 'emulator';
+ args = ['-avd', emulator_ID];
+ }
+ var proc = child_process.spawn(cmd, args, { stdio: 'inherit', detached: true });
+ proc.unref(); // Don't wait for it to finish, since the emulator will probably keep running for a long time.
+ }).then(function() {
+ // wait for emulator to start
+ console.log('Waiting for emulator...');
+ return self.wait_for_emulator(num_started);
+ }).then(function(new_started) {
+ if (new_started.length > 1) {
+ for (i in new_started) {
+ if (started_emulators.indexOf(new_started[i]) < 0) {
+ emulator_id = new_started[i];
+ }
+ }
+ } else {
+ emulator_id = new_started[0];
+ }
+ if (!emulator_id) return Q.reject('ERROR : Failed to start emulator, could not find new emulator');
+
+ //wait for emulator to boot up
+ process.stdout.write('Booting up emulator (this may take a while)...');
+ return self.wait_for_boot(emulator_id);
+ }).then(function() {
+ console.log('BOOT COMPLETE');
+
+ //unlock screen
+ return exec('adb -s ' + emulator_id + ' shell input keyevent 82');
+ }).then(function() {
+ //return the new emulator id for the started emulators
+ return emulator_id;
+ });
+}
+
+/*
+ * Waits for the new emulator to apear on the started-emulator list.
+ * Returns a promise with a list of newly started emulators' IDs.
+ */
+module.exports.wait_for_emulator = function(num_running) {
+ var self = this;
+ return self.list_started()
+ .then(function(new_started) {
+ if (new_started.length > num_running) {
+ return new_started;
+ } else {
+ return Q.delay(1000).then(function() {
+ return self.wait_for_emulator(num_running);
+ });
+ }
+ });
+}
+
+/*
+ * Waits for the boot animation property of the emulator to switch to 'stopped'
+ */
+module.exports.wait_for_boot = function(emulator_id) {
+ var self = this;
+ return exec('adb -s ' + emulator_id + ' shell getprop init.svc.bootanim')
+ .then(function(output) {
+ if (output.match(/stopped/)) {
+ return;
+ } else {
+ process.stdout.write('.');
+ return Q.delay(3000).then(function() {
+ return self.wait_for_boot(emulator_id);
+ });
+ }
+ });
+}
+
+/*
+ * Create avd
+ * TODO : Enter the stdin input required to complete the creation of an avd.
+ * Returns a promise.
+ */
+module.exports.create_image = function(name, target) {
+ console.log('Creating avd named ' + name);
+ if (target) {
+ return exec('android create avd --name ' + name + ' --target ' + target)
+ .then(null, function(error) {
+ console.error('ERROR : Failed to create emulator image : ');
+ console.error(' Do you have the latest android targets including ' + target + '?');
+ console.error(create.output);
+ });
+ } else {
+ console.log('WARNING : Project target not found, creating avd with a different target but the project may fail to install.');
+ return exec('android create avd --name ' + name + ' --target ' + this.list_targets()[0])
+ .then(function() {
+ // TODO: This seems like another error case, even though it always happens.
+ console.error('ERROR : Unable to create an avd emulator, no targets found.');
+ console.error('Please insure you have targets availible by runing the "android" command');
+ return Q.reject();
+ }, function(error) {
+ console.error('ERROR : Failed to create emulator image : ');
+ console.error(error);
+ });
+ }
+}
+
+/*
+ * Installs a previously built application on the emulator and launches it.
+ * If no target is specified, then it picks one.
+ * If no started emulators are found, error out.
+ * Returns a promise.
+ */
+module.exports.install = function(target) {
+ var self = this;
+ return this.list_started()
+ .then(function(emulator_list) {
+ if (emulator_list.length < 1) {
+ return Q.reject('No started emulators found, please start an emultor before deploying your project.');
+ }
+
+ // default emulator
+ target = typeof target !== 'undefined' ? target : emulator_list[0];
+ if (emulator_list.indexOf(target) < 0) {
+ return Q.reject('Unable to find target \'' + target + '\'. Failed to deploy to emulator.');
+ }
+
+ console.log('Installing app on emulator...');
+ var apk_path = build.get_apk();
+ return exec('adb -s ' + target + ' install -r "' + apk_path + '"');
+ }).then(function(output) {
+ if (output.match(/Failure/)) {
+ return Q.reject('Failed to install apk to emulator: ' + output);
+ }
+ return Q();
+ }, function(err) {
+ return Q.reject('Failed to install apk to emulator: ' + err);
+ }).then(function() {
+ //unlock screen
+ return exec('adb -s ' + target + ' shell input keyevent 82');
+ }).then(function() {
+ // launch the application
+ console.log('Launching application...');
+ var launchName = appinfo.getActivityName();
+ cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
+ return exec(cmd);
+ }).then(function(output) {
+ console.log('LAUNCH SUCCESS');
+ }, function(err) {
+ return Q.reject('Failed to launch app on emulator: ' + err);
+ });
+}
diff --git a/platforms/android/cordova/lib/exec.js b/platforms/android/cordova/lib/exec.js
new file mode 100644
index 0000000..6afa9c0
--- /dev/null
+++ b/platforms/android/cordova/lib/exec.js
@@ -0,0 +1,43 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var child_process = require('child_process'),
+ Q = require('q');
+
+// Takes a command and optional current working directory.
+// Returns a promise that either resolves with the stdout, or
+// rejects with an error message and the stderr.
+module.exports = function(cmd, opt_cwd) {
+ var d = Q.defer();
+ console.log('exec: ' + cmd);
+ try {
+ child_process.exec(cmd, {cwd: opt_cwd}, function(err, stdout, stderr) {
+ console.log([cmd, err, stdout, stderr]);
+ if (err) d.reject('Error executing "' + cmd + '": ' + stderr);
+ else d.resolve(stdout);
+ });
+ } catch(e) {
+ console.error('error caught: ' + e);
+ d.reject(e);
+ }
+ return d.promise;
+}
+
diff --git a/platforms/android/cordova/lib/install-device b/platforms/android/cordova/lib/install-device
new file mode 100755
index 0000000..fc4b784
--- /dev/null
+++ b/platforms/android/cordova/lib/install-device
@@ -0,0 +1,42 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var device = require('./device'),
+ args = process.argv;
+
+if(args.length > 2) {
+ var install_target;
+ if (args[2].substring(0, 9) == '--target=') {
+ install_target = args[2].substring(9, args[2].length);
+ device.install(install_target).done(null, function(err) {
+ console.error('ERROR: ' + err);
+ process.exit(2);
+ });
+ } else {
+ console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
+ process.exit(2);
+ }
+} else {
+ device.install().done(null, function(err) {
+ console.error('ERROR: ' + err);
+ process.exit(2);
+ });
+}
diff --git a/platforms/android/cordova/lib/install-device.bat b/platforms/android/cordova/lib/install-device.bat
new file mode 100644
index 0000000..ac7214a
--- /dev/null
+++ b/platforms/android/cordova/lib/install-device.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script_path="%~dp0install-device"
+IF EXIST %script_path% (
+ node "%script_path%" %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'install-device' script in 'cordova\lib' folder, aborting...>&2
+ EXIT /B 1
+)
\ No newline at end of file
diff --git a/platforms/android/cordova/lib/install-emulator b/platforms/android/cordova/lib/install-emulator
new file mode 100755
index 0000000..aa2a34f
--- /dev/null
+++ b/platforms/android/cordova/lib/install-emulator
@@ -0,0 +1,38 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var emulator = require('./emulator'),
+ args = process.argv;
+
+var install_target;
+if(args.length > 2) {
+ if (args[2].substring(0, 9) == '--target=') {
+ install_target = args[2].substring(9, args[2].length);
+ } else {
+ console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
+ process.exit(2);
+ }
+}
+
+emulator.install(install_target).done(null, function(err) {
+ console.error('ERROR: ' + err);
+ process.exit(2);
+});
diff --git a/platforms/android/cordova/lib/install-emulator.bat b/platforms/android/cordova/lib/install-emulator.bat
new file mode 100644
index 0000000..1ec6779
--- /dev/null
+++ b/platforms/android/cordova/lib/install-emulator.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script_path="%~dp0install-emulator"
+IF EXIST %script_path% (
+ node "%script_path%" %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'install-emulator' script in 'cordova\lib' folder, aborting...>&2
+ EXIT /B 1
+)
\ No newline at end of file
diff --git a/platforms/android/cordova/lib/list-devices b/platforms/android/cordova/lib/list-devices
new file mode 100755
index 0000000..e390bff
--- /dev/null
+++ b/platforms/android/cordova/lib/list-devices
@@ -0,0 +1,33 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var devices = require('./device');
+
+// Usage support for when args are given
+devices.list().done(function(device_list) {
+ device_list && device_list.forEach(function(dev) {
+ console.log(dev);
+ });
+}, function(err) {
+ console.error('ERROR: ' + err);
+ process.exit(2);
+});
+
diff --git a/platforms/android/cordova/lib/list-devices.bat b/platforms/android/cordova/lib/list-devices.bat
new file mode 100644
index 0000000..c0bcdd9
--- /dev/null
+++ b/platforms/android/cordova/lib/list-devices.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script_path="%~dp0list-devices"
+IF EXIST %script_path% (
+ node "%script_path%" %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'list-devices' script in 'cordova\lib' folder, aborting...>&2
+ EXIT /B 1
+)
\ No newline at end of file
diff --git a/platforms/android/cordova/lib/list-emulator-images b/platforms/android/cordova/lib/list-emulator-images
new file mode 100755
index 0000000..996cf55
--- /dev/null
+++ b/platforms/android/cordova/lib/list-emulator-images
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var emulators = require('./emulator');
+
+// Usage support for when args are given
+emulators.list_images().done(function(emulator_list) {
+ emulator_list && emulator_list.forEach(function(emu) {
+ console.log(emu.name);
+ });
+}, function(err) {
+ console.error('ERROR: ' + err);
+ process.exit(2);
+});
diff --git a/platforms/android/cordova/lib/list-emulator-images.bat b/platforms/android/cordova/lib/list-emulator-images.bat
new file mode 100644
index 0000000..661cbf9
--- /dev/null
+++ b/platforms/android/cordova/lib/list-emulator-images.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script_path="%~dp0list-emulator-images"
+IF EXIST %script_path% (
+ node "%script_path%" %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'list-emulator-images' script in 'cordova\lib' folder, aborting...>&2
+ EXIT /B 1
+)
diff --git a/platforms/android/cordova/lib/list-started-emulators b/platforms/android/cordova/lib/list-started-emulators
new file mode 100755
index 0000000..2ae8c5a
--- /dev/null
+++ b/platforms/android/cordova/lib/list-started-emulators
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var emulators = require('./emulator');
+
+// Usage support for when args are given
+emulators.list_started().done(function(emulator_list) {
+ emulator_list && emulator_list.forEach(function(emu) {
+ console.log(emu);
+ });
+}, function(err) {
+ console.error('ERROR: ' + err);
+ process.exit(2);
+});
diff --git a/platforms/android/cordova/lib/list-started-emulators.bat b/platforms/android/cordova/lib/list-started-emulators.bat
new file mode 100644
index 0000000..a4e88f7
--- /dev/null
+++ b/platforms/android/cordova/lib/list-started-emulators.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script_path="%~dp0list-started-emulators"
+IF EXIST %script_path% (
+ node "%script_path%" %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'list-started-emulators' script in 'cordova\lib' folder, aborting...>&2
+ EXIT /B 1
+)
\ No newline at end of file
diff --git a/platforms/android/cordova/lib/log.js b/platforms/android/cordova/lib/log.js
new file mode 100644
index 0000000..7339b1c
--- /dev/null
+++ b/platforms/android/cordova/lib/log.js
@@ -0,0 +1,57 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var shell = require('shelljs'),
+ path = require('path'),
+ Q = require('q'),
+ child_process = require('child_process'),
+ ROOT = path.join(__dirname, '..', '..');
+
+/*
+ * Starts running logcat in the shell.
+ * Returns a promise.
+ */
+module.exports.run = function() {
+ var cmd = 'adb logcat | grep -v nativeGetEnabledTags';
+ var d = Q.defer();
+ var adb = child_process.spawn('adb', ['logcat']);
+
+ adb.stdout.on('data', function(data) {
+ var lines = data ? data.toString().split('\n') : [];
+ var out = lines.filter(function(x) { return x.indexOf('nativeGetEnabledTags') < 0; });
+ console.log(out.join('\n'));
+ });
+
+ adb.stderr.on('data', console.error);
+ adb.on('close', function(code) {
+ if (code > 0) {
+ d.reject('Failed to run logcat command.');
+ } else d.resolve();
+ });
+
+ return d.promise;
+}
+
+module.exports.help = function() {
+ console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'corodva', 'log')));
+ console.log('Gives the logcat output on the command line.');
+ process.exit(0);
+}
diff --git a/platforms/android/cordova/lib/run.js b/platforms/android/cordova/lib/run.js
new file mode 100644
index 0000000..6806014
--- /dev/null
+++ b/platforms/android/cordova/lib/run.js
@@ -0,0 +1,139 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var path = require('path'),
+ build = require('./build'),
+ emulator = require('./emulator'),
+ device = require('./device'),
+ Q = require('q');
+
+/*
+ * Runs the application on a device if availible.
+ * If not device is found, it will use a started emulator.
+ * If no started emulators are found it will attempt to start an avd.
+ * If no avds are found it will error out.
+ * Returns a promise.
+ */
+ module.exports.run = function(args) {
+ var build_type;
+ var install_target;
+
+ for (var i=2; i 0 ? Q() : emulator.start();
+ return p.then(function() { emulator.install(); });
+ });
+ } else if (install_target) {
+ var devices, started_emulators, avds;
+ return device.list()
+ .then(function(res) {
+ devices = res;
+ return emulator.list_started();
+ }).then(function(res) {
+ started_emulators = res;
+ return emulator.list_images();
+ }).then(function(res) {
+ avds = res;
+ if (devices.indexOf(install_target) > -1) {
+ return device.install(install_target);
+ } else if (started_emulators.indexOf(install_target) > -1) {
+ return emulator.install(install_target);
+ } else {
+ // if target emulator isn't started, then start it.
+ var emulator_ID;
+ for(avd in avds) {
+ if(avds[avd].name == install_target) {
+ return emulator.start(install_target)
+ .then(function() { emulator.install(emulator_ID); });
+ }
+ }
+ return Q.reject('Target \'' + install_target + '\' not found, unable to run project');
+ }
+ });
+ } else {
+ // no target given, deploy to device if availible, otherwise use the emulator.
+ return device.list()
+ .then(function(device_list) {
+ if (device_list.length > 0) {
+ console.log('WARNING : No target specified, deploying to device \'' + device_list[0] + '\'.');
+ return device.install(device_list[0]);
+ } else {
+ return emulator.list_started()
+ .then(function(emulator_list) {
+ if (emulator_list.length > 0) {
+ console.log('WARNING : No target specified, deploying to emulator \'' + emulator_list[0] + '\'.');
+ return emulator.install(emulator_list[0]);
+ } else {
+ console.log('WARNING : No started emulators found, starting an emulator.');
+ return emulator.best_image()
+ .then(function(best_avd) {
+ if(best_avd) {
+ return emulator.start(best_avd.name)
+ .then(function(emulator_ID) {
+ console.log('WARNING : No target specified, deploying to emulator \'' + emulator_ID + '\'.');
+ return emulator.install(emulator_ID);
+ });
+ } else {
+ return emulator.start();
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+}
+
+module.exports.help = function() {
+ console.log('Usage: ' + path.relative(process.cwd(), args[0]) + ' [options]');
+ console.log('Build options :');
+ console.log(' --debug : Builds project in debug mode');
+ console.log(' --release : Builds project in release mode');
+ console.log(' --nobuild : Runs the currently built project without recompiling');
+ console.log('Deploy options :');
+ console.log(' --device : Will deploy the built project to a device');
+ console.log(' --emulator : Will deploy the built project to an emulator if one exists');
+ console.log(' --target= : Installs to the target with the specified id.');
+ process.exit(0);
+}
diff --git a/platforms/android/cordova/lib/start-emulator b/platforms/android/cordova/lib/start-emulator
new file mode 100755
index 0000000..f96bdc3
--- /dev/null
+++ b/platforms/android/cordova/lib/start-emulator
@@ -0,0 +1,39 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var emulator = require('./emulator'),
+ args = process.argv;
+
+var install_target;
+if(args.length > 2) {
+ if (args[2].substring(0, 9) == '--target=') {
+ install_target = args[2].substring(9, args[2].length);
+ } else {
+ console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
+ process.exit(2);
+ }
+}
+
+emulator.start(install_target).done(null, function(err) {
+ console.error('ERROR: ' + err);
+ process.exit(2);
+});
+
diff --git a/platforms/android/cordova/lib/start-emulator.bat b/platforms/android/cordova/lib/start-emulator.bat
new file mode 100644
index 0000000..9329d95
--- /dev/null
+++ b/platforms/android/cordova/lib/start-emulator.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script_path="%~dp0start-emulator"
+IF EXIST %script_path% (
+ node "%script_path%" %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'start-emulator' script in 'cordova\lib' folder, aborting...>&2
+ EXIT /B 1
+)
\ No newline at end of file
diff --git a/platforms/android/cordova/log b/platforms/android/cordova/log
new file mode 100755
index 0000000..47f0605
--- /dev/null
+++ b/platforms/android/cordova/log
@@ -0,0 +1,36 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+*/
+
+var log = require('./lib/log'),
+ reqs = require('./lib/check_reqs'),
+ args = process.argv;
+
+// Usage support for when args are given
+if(args.length > 2) {
+ log.help();
+} else {
+ reqs.run().done(function() {
+ return log.run();
+ }, function(err) {
+ console.error('ERROR: ' + err);
+ process.exit(2);
+ });
+}
diff --git a/platforms/android/cordova/log.bat b/platforms/android/cordova/log.bat
new file mode 100644
index 0000000..4b2b434
--- /dev/null
+++ b/platforms/android/cordova/log.bat
@@ -0,0 +1,26 @@
+:: 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.
+
+@ECHO OFF
+SET script_path="%~dp0log"
+IF EXIST %script_path% (
+ node %script_path% %*
+) ELSE (
+ ECHO.
+ ECHO ERROR: Could not find 'log' script in 'cordova' folder, aborting...>&2
+ EXIT /B 1
+)
\ No newline at end of file
diff --git a/platforms/android/cordova/node_modules/.bin/shjs b/platforms/android/cordova/node_modules/.bin/shjs
new file mode 120000
index 0000000..a044997
--- /dev/null
+++ b/platforms/android/cordova/node_modules/.bin/shjs
@@ -0,0 +1 @@
+../shelljs/bin/shjs
\ No newline at end of file
diff --git a/platforms/android/cordova/node_modules/q/CONTRIBUTING.md b/platforms/android/cordova/node_modules/q/CONTRIBUTING.md
new file mode 100644
index 0000000..500ab17
--- /dev/null
+++ b/platforms/android/cordova/node_modules/q/CONTRIBUTING.md
@@ -0,0 +1,40 @@
+
+For pull requests:
+
+- Be consistent with prevalent style and design decisions.
+- Add a Jasmine spec to `specs/q-spec.js`.
+- Use `npm test` to avoid regressions.
+- Run tests in `q-spec/run.html` in as many supported browsers as you
+ can find the will to deal with.
+- Do not build minified versions; we do this each release.
+- If you would be so kind, add a note to `CHANGES.md` in an
+ appropriate section:
+
+ - `Next Major Version` if it introduces backward incompatibilities
+ to code in the wild using documented features.
+ - `Next Minor Version` if it adds a new feature.
+ - `Next Patch Version` if it fixes a bug.
+
+For releases:
+
+- Run `npm test`.
+- Run tests in `q-spec/run.html` in a representative sample of every
+ browser under the sun.
+- Run `npm run cover` and make sure you're happy with the results.
+- Run `npm run minify` and be sure to commit the resulting `q.min.js`.
+- Note the Gzipped size output by the previous command, and update
+ `README.md` if it has changed to 1 significant digit.
+- Stash any local changes.
+- Update `CHANGES.md` to reflect all changes in the differences
+ between `HEAD` and the previous tagged version. Give credit where
+ credit is due.
+- Update `README.md` to address all new, non-experimental features.
+- Update the API reference on the Wiki to reflect all non-experimental
+ features.
+- Use `npm version major|minor|patch` to update `package.json`,
+ commit, and tag the new version.
+- Use `npm publish` to send up a new release.
+- Send an email to the q-continuum mailing list announcing the new
+ release and the notes from the change log. This helps folks
+ maintaining other package ecosystems.
+
diff --git a/platforms/android/cordova/node_modules/q/LICENSE b/platforms/android/cordova/node_modules/q/LICENSE
new file mode 100644
index 0000000..76c5fe4
--- /dev/null
+++ b/platforms/android/cordova/node_modules/q/LICENSE
@@ -0,0 +1,19 @@
+
+Copyright 2009–2012 Kristopher Michael Kowal. All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
diff --git a/platforms/android/cordova/node_modules/q/README.md b/platforms/android/cordova/node_modules/q/README.md
new file mode 100644
index 0000000..c0f513c
--- /dev/null
+++ b/platforms/android/cordova/node_modules/q/README.md
@@ -0,0 +1,813 @@
+[![Build Status](https://secure.travis-ci.org/kriskowal/q.png?branch=master)](http://travis-ci.org/kriskowal/q)
+
+
+
+
+
+If a function cannot return a value or throw an exception without
+blocking, it can return a promise instead. A promise is an object
+that represents the return value or the thrown exception that the
+function may eventually provide. A promise can also be used as a
+proxy for a [remote object][Q-Connection] to overcome latency.
+
+[Q-Connection]: https://github.com/kriskowal/q-connection
+
+On the first pass, promises can mitigate the “[Pyramid of
+Doom][POD]”: the situation where code marches to the right faster
+than it marches forward.
+
+[POD]: http://calculist.org/blog/2011/12/14/why-coroutines-wont-work-on-the-web/
+
+```javascript
+step1(function (value1) {
+ step2(value1, function(value2) {
+ step3(value2, function(value3) {
+ step4(value3, function(value4) {
+ // Do something with value4
+ });
+ });
+ });
+});
+```
+
+With a promise library, you can flatten the pyramid.
+
+```javascript
+Q.fcall(promisedStep1)
+.then(promisedStep2)
+.then(promisedStep3)
+.then(promisedStep4)
+.then(function (value4) {
+ // Do something with value4
+})
+.catch(function (error) {
+ // Handle any error from all above steps
+})
+.done();
+```
+
+With this approach, you also get implicit error propagation, just like `try`,
+`catch`, and `finally`. An error in `promisedStep1` will flow all the way to
+the `catch` function, where it’s caught and handled. (Here `promisedStepN` is
+a version of `stepN` that returns a promise.)
+
+The callback approach is called an “inversion of control”.
+A function that accepts a callback instead of a return value
+is saying, “Don’t call me, I’ll call you.”. Promises
+[un-invert][IOC] the inversion, cleanly separating the input
+arguments from control flow arguments. This simplifies the
+use and creation of API’s, particularly variadic,
+rest and spread arguments.
+
+[IOC]: http://www.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript
+
+
+## Getting Started
+
+The Q module can be loaded as:
+
+- A ``
+
+
+
+