From 86a2830d75af5008f239583ccc2231a670092f29 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 30 Jun 2014 23:59:53 +0530 Subject: [PATCH 1/6] Displaying error when regex does not match. On my ubuntu when `android` is not found typical output is: ``` /bin/sh: 1: android: not found ``` close #104 --- bin/lib/check_reqs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/lib/check_reqs.js b/bin/lib/check_reqs.js index 1c6f0f8c..3296acc1 100644 --- a/bin/lib/check_reqs.js +++ b/bin/lib/check_reqs.js @@ -84,7 +84,7 @@ module.exports.check_android = function() { 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')); + return Q.reject(new Error('An error occurred while listing Android targets. Error: ' + stderr )); } }); } From 0a3714e5e0f6046caf9468395aa0587888eb8408 Mon Sep 17 00:00:00 2001 From: Eion Robb Date: Sun, 22 Jun 2014 09:43:30 +1200 Subject: [PATCH 2/6] Fix for `android` not being in PATH check on Windows close #103 --- bin/lib/check_reqs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/lib/check_reqs.js b/bin/lib/check_reqs.js index 3296acc1..91875f5c 100644 --- a/bin/lib/check_reqs.js +++ b/bin/lib/check_reqs.js @@ -81,7 +81,7 @@ module.exports.check_android = function() { } return Q(); }, function(stderr) { - if (stderr.match(/command\snot\sfound/)) { + if (stderr.match(/command\snot\sfound/) || stderr.match(/is not recognized as an internal or external command/)) { 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. Error: ' + stderr )); From 62101e85ffeed6620ae940f76cf51149aec54cf2 Mon Sep 17 00:00:00 2001 From: Matt Ray Date: Thu, 8 May 2014 15:37:09 -0400 Subject: [PATCH 3/6] Update to check for Google Glass APIs This prevents the 'cordova build android' process from blowing up on this step if you assign the GDK as the target and want to rebuild via the CLI. close #100 --- bin/lib/check_reqs.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bin/lib/check_reqs.js b/bin/lib/check_reqs.js index 91875f5c..a4ad3ad6 100644 --- a/bin/lib/check_reqs.js +++ b/bin/lib/check_reqs.js @@ -36,6 +36,10 @@ module.exports.get_target = function() { // 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')); + if(target == "" || !target) { + // Try Google Glass APIs + target = shell.grep(/target=Google Inc.:Glass Development Kit Preview:[\d+]/, path.join(ROOT, 'project.properties')); + } return target.split('=')[1].replace('\n', '').replace('\r', ''); } } From a33cdc9c7b106313eb0952c54a4c07e690e4426c Mon Sep 17 00:00:00 2001 From: Andrew Grieve Date: Mon, 14 Jul 2014 14:06:47 -0400 Subject: [PATCH 4/6] Fix broken unit test due to missing Config.init() call --- test/src/org/apache/cordova/test/CordovaWebViewTestActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/src/org/apache/cordova/test/CordovaWebViewTestActivity.java b/test/src/org/apache/cordova/test/CordovaWebViewTestActivity.java index e35b6e7f..06070cc5 100644 --- a/test/src/org/apache/cordova/test/CordovaWebViewTestActivity.java +++ b/test/src/org/apache/cordova/test/CordovaWebViewTestActivity.java @@ -48,6 +48,7 @@ public class CordovaWebViewTestActivity extends Activity implements CordovaInter setContentView(R.layout.main); cordovaWebView = (CordovaWebView) findViewById(R.id.cordovaWebView); + Config.init(this); cordovaWebView.init(this, new CordovaWebViewClient(this, cordovaWebView), new CordovaChromeClient(this, cordovaWebView), Config.getPluginEntries(), Config.getWhitelist(), Config.getPreferences()); From 145b50a320edfa8b5397849fc20a6295f8823ff6 Mon Sep 17 00:00:00 2001 From: Andrew Grieve Date: Mon, 14 Jul 2014 14:08:27 -0400 Subject: [PATCH 5/6] Move plugin instantiation and instance storing logic PluginEntry->PluginManager Instantiation and storing of the instance should be owned privately by PluginManager, not exposed via an unprotected public API. That said, this refactoring does not make any breaking changes to the public API, except for removing the createPlugin call in PluginEntry, which should not be called by anyone other than PluginManager anyway. --- .../src/org/apache/cordova/PluginEntry.java | 84 +++--------- .../src/org/apache/cordova/PluginManager.java | 122 ++++++++++-------- 2 files changed, 88 insertions(+), 118 deletions(-) diff --git a/framework/src/org/apache/cordova/PluginEntry.java b/framework/src/org/apache/cordova/PluginEntry.java index e94cf1c7..03a44daf 100755 --- a/framework/src/org/apache/cordova/PluginEntry.java +++ b/framework/src/org/apache/cordova/PluginEntry.java @@ -20,11 +20,8 @@ package org.apache.cordova; import java.util.List; -import org.apache.cordova.CordovaWebView; -import org.apache.cordova.CordovaInterface; import org.apache.cordova.CordovaPlugin; - /** * This class represents a service entry object. */ @@ -33,34 +30,31 @@ public class PluginEntry { /** * The name of the service that this plugin implements */ - public String service = ""; + public String service; /** * The plugin class name that implements the service. */ - public String pluginClass = ""; + public String pluginClass; /** - * The plugin object. - * Plugin objects are only created when they are called from JavaScript. (see PluginManager.exec) - * The exception is if the onload flag is set, then they are created when PluginManager is initialized. + * The pre-instantiated plugin to use for this entry. */ - public CordovaPlugin plugin = null; + public CordovaPlugin plugin; /** * Flag that indicates the plugin object should be created when PluginManager is initialized. */ - public boolean onload = false; + public boolean onload; private List urlFilters; + /** - * @param service The name of the service - * @param plugin The plugin associated with this entry + * Constructs with a CordovaPlugin already instantiated. */ public PluginEntry(String service, CordovaPlugin plugin) { - this(service, plugin.getClass().getName(), true, null); - this.plugin = plugin; + this(service, plugin.getClass().getName(), true, plugin, null); } /** @@ -69,67 +63,27 @@ public class PluginEntry { * @param onload Create plugin object when HTML page is loaded */ public PluginEntry(String service, String pluginClass, boolean onload) { - this(service, pluginClass, onload, null); + this(service, pluginClass, onload, null, null); } - + @Deprecated // urlFilters are going away public PluginEntry(String service, String pluginClass, boolean onload, List urlFilters) { this.service = service; this.pluginClass = pluginClass; this.onload = onload; this.urlFilters = urlFilters; + plugin = null; + } + + private PluginEntry(String service, String pluginClass, boolean onload, CordovaPlugin plugin, List urlFilters) { + this.service = service; + this.pluginClass = pluginClass; + this.onload = onload; + this.urlFilters = urlFilters; + this.plugin = plugin; } public List getUrlFilters() { return urlFilters; } - - /** - * Create plugin object. - * If plugin is already created, then just return it. - * - * @return The plugin object - */ - public CordovaPlugin createPlugin(CordovaWebView webView, CordovaInterface ctx) { - if (this.plugin != null) { - return this.plugin; - } - try { - Class c = getClassByName(this.pluginClass); - if (isCordovaPlugin(c)) { - this.plugin = (CordovaPlugin) c.newInstance(); - this.plugin.privateInitialize(ctx, webView, webView.getPreferences()); - return plugin; - } - } catch (Exception e) { - e.printStackTrace(); - System.out.println("Error adding plugin " + this.pluginClass + "."); - } - return null; - } - - /** - * Get the class. - * - * @param clazz - * @return a reference to the named class - * @throws ClassNotFoundException - */ - private Class getClassByName(final String clazz) throws ClassNotFoundException { - Class c = null; - if ((clazz != null) && !("".equals(clazz))) { - c = Class.forName(clazz); - } - return c; - } - - /** - * Returns whether the given class extends CordovaPlugin. - */ - private boolean isCordovaPlugin(Class c) { - if (c != null) { - return CordovaPlugin.class.isAssignableFrom(c); - } - return false; - } } diff --git a/framework/src/org/apache/cordova/PluginManager.java b/framework/src/org/apache/cordova/PluginManager.java index 02d45ab3..eb3e6f9c 100755 --- a/framework/src/org/apache/cordova/PluginManager.java +++ b/framework/src/org/apache/cordova/PluginManager.java @@ -45,7 +45,8 @@ public class PluginManager { private static final int SLOW_EXEC_WARNING_THRESHOLD = Debug.isDebuggerConnected() ? 60 : 16; // List of service entries - private final HashMap entries = new HashMap(); + private final HashMap pluginMap = new HashMap(); + private final HashMap entryMap = new HashMap(); private final CordovaInterface ctx; private final CordovaWebView app; @@ -73,8 +74,7 @@ public class PluginManager { public void setPluginEntries(List pluginEntries) { this.onPause(false); this.onDestroy(); - this.clearPluginObjects(); - entries.clear(); + pluginMap.clear(); urlMap.clear(); for (PluginEntry entry : pluginEntries) { addService(entry); @@ -88,7 +88,7 @@ public class PluginManager { LOG.d(TAG, "init()"); this.onPause(false); this.onDestroy(); - this.clearPluginObjects(); + pluginMap.clear(); this.startupPlugins(); } @@ -100,18 +100,16 @@ public class PluginManager { * Delete all plugin objects. */ public void clearPluginObjects() { - for (PluginEntry entry : this.entries.values()) { - entry.plugin = null; - } + pluginMap.clear(); } /** * Create plugins objects that have onload set. */ public void startupPlugins() { - for (PluginEntry entry : this.entries.values()) { + for (PluginEntry entry : entryMap.values()) { if (entry.onload) { - entry.createPlugin(this.app, this.ctx); + getPlugin(entry.service); } } } @@ -177,15 +175,21 @@ public class PluginManager { * @return CordovaPlugin or null */ public CordovaPlugin getPlugin(String service) { - PluginEntry entry = this.entries.get(service); - if (entry == null) { - return null; + CordovaPlugin ret = pluginMap.get(service); + if (ret == null) { + PluginEntry pe = entryMap.get(service); + if (pe == null) { + return null; + } + if (pe.plugin != null) { + ret = pe.plugin; + } else { + ret = instantiatePlugin(pe.pluginClass); + } + ret.privateInitialize(ctx, app, app.getPreferences()); + pluginMap.put(service, ret); } - CordovaPlugin plugin = entry.plugin; - if (plugin == null) { - plugin = entry.createPlugin(this.app, this.ctx); - } - return plugin; + return ret; } /** @@ -207,11 +211,16 @@ public class PluginManager { * @param entry The plugin entry */ public void addService(PluginEntry entry) { - this.entries.put(entry.service, entry); + this.entryMap.put(entry.service, entry); List urlFilters = entry.getUrlFilters(); if (urlFilters != null) { urlMap.put(entry.service, urlFilters); } + if (entry.plugin != null) { + entry.plugin.privateInitialize(ctx, app, app.getPreferences()); + pluginMap.put(entry.service, entry.plugin); + } + } /** @@ -220,10 +229,8 @@ public class PluginManager { * @param multitasking Flag indicating if multitasking is turned on for app */ public void onPause(boolean multitasking) { - for (PluginEntry entry : this.entries.values()) { - if (entry.plugin != null) { - entry.plugin.onPause(multitasking); - } + for (CordovaPlugin plugin : this.pluginMap.values()) { + plugin.onPause(multitasking); } } @@ -233,10 +240,8 @@ public class PluginManager { * @param multitasking Flag indicating if multitasking is turned on for app */ public void onResume(boolean multitasking) { - for (PluginEntry entry : this.entries.values()) { - if (entry.plugin != null) { - entry.plugin.onResume(multitasking); - } + for (CordovaPlugin plugin : this.pluginMap.values()) { + plugin.onResume(multitasking); } } @@ -244,10 +249,8 @@ public class PluginManager { * The final call you receive before your activity is destroyed. */ public void onDestroy() { - for (PluginEntry entry : this.entries.values()) { - if (entry.plugin != null) { - entry.plugin.onDestroy(); - } + for (CordovaPlugin plugin : this.pluginMap.values()) { + plugin.onDestroy(); } } @@ -263,12 +266,10 @@ public class PluginManager { if (obj != null) { return obj; } - for (PluginEntry entry : this.entries.values()) { - if (entry.plugin != null) { - obj = entry.plugin.onMessage(id, data); - if (obj != null) { - return obj; - } + for (CordovaPlugin plugin : this.pluginMap.values()) { + obj = plugin.onMessage(id, data); + if (obj != null) { + return obj; } } return null; @@ -278,10 +279,8 @@ public class PluginManager { * Called when the activity receives a new intent. */ public void onNewIntent(Intent intent) { - for (PluginEntry entry : this.entries.values()) { - if (entry.plugin != null) { - entry.plugin.onNewIntent(intent); - } + for (CordovaPlugin plugin : this.pluginMap.values()) { + plugin.onNewIntent(intent); } } @@ -296,7 +295,7 @@ public class PluginManager { // Instead, plugins should not include and instead ensure // that they are loaded before this function is called (either by setting // the onload or by making an exec() call to them) - for (PluginEntry entry : this.entries.values()) { + for (PluginEntry entry : this.entryMap.values()) { List urlFilters = urlMap.get(entry.service); if (urlFilters != null) { for (String s : urlFilters) { @@ -304,8 +303,9 @@ public class PluginManager { return getPlugin(entry.service).onOverrideUrlLoading(url); } } - } else if (entry.plugin != null) { - if (entry.plugin.onOverrideUrlLoading(url)) { + } else { + CordovaPlugin plugin = pluginMap.get(entry.service); + if (plugin != null && plugin.onOverrideUrlLoading(url)) { return true; } } @@ -317,22 +317,38 @@ public class PluginManager { * Called when the app navigates or refreshes. */ public void onReset() { - for (PluginEntry entry : this.entries.values()) { - if (entry.plugin != null) { - entry.plugin.onReset(); - } + for (CordovaPlugin plugin : this.pluginMap.values()) { + plugin.onReset(); } } Uri remapUri(Uri uri) { - for (PluginEntry entry : this.entries.values()) { - if (entry.plugin != null) { - Uri ret = entry.plugin.remapUri(uri); - if (ret != null) { - return ret; - } + for (CordovaPlugin plugin : this.pluginMap.values()) { + Uri ret = plugin.remapUri(uri); + if (ret != null) { + return ret; } } return null; } + + /** + * Create a plugin based on class name. + */ + private CordovaPlugin instantiatePlugin(String className) { + CordovaPlugin ret = null; + try { + Class c = null; + if ((className != null) && !("".equals(className))) { + c = Class.forName(className); + } + if (c != null & CordovaPlugin.class.isAssignableFrom(c)) { + ret = (CordovaPlugin) c.newInstance(); + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("Error adding plugin " + className + "."); + } + return ret; + } } From b934c1be6a90ac88c077d5bd922c66fa1cf32363 Mon Sep 17 00:00:00 2001 From: Andrew Grieve Date: Mon, 14 Jul 2014 14:10:19 -0400 Subject: [PATCH 6/6] @Deprecate methods of PluginManager that were never meant to be public --- framework/src/org/apache/cordova/PluginManager.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/framework/src/org/apache/cordova/PluginManager.java b/framework/src/org/apache/cordova/PluginManager.java index eb3e6f9c..689c3c86 100755 --- a/framework/src/org/apache/cordova/PluginManager.java +++ b/framework/src/org/apache/cordova/PluginManager.java @@ -84,6 +84,7 @@ public class PluginManager { /** * Init when loading a new HTML page into webview. */ + @Deprecated // Should not be exposed as public. public void init() { LOG.d(TAG, "init()"); this.onPause(false); @@ -99,6 +100,7 @@ public class PluginManager { /** * Delete all plugin objects. */ + @Deprecated // Should not be exposed as public. public void clearPluginObjects() { pluginMap.clear(); } @@ -106,6 +108,7 @@ public class PluginManager { /** * Create plugins objects that have onload set. */ + @Deprecated // Should not be exposed as public. public void startupPlugins() { for (PluginEntry entry : entryMap.values()) { if (entry.onload) { @@ -228,6 +231,7 @@ public class PluginManager { * * @param multitasking Flag indicating if multitasking is turned on for app */ + @Deprecated // Should not be public public void onPause(boolean multitasking) { for (CordovaPlugin plugin : this.pluginMap.values()) { plugin.onPause(multitasking); @@ -239,6 +243,7 @@ public class PluginManager { * * @param multitasking Flag indicating if multitasking is turned on for app */ + @Deprecated // Should not be public public void onResume(boolean multitasking) { for (CordovaPlugin plugin : this.pluginMap.values()) { plugin.onResume(multitasking); @@ -248,6 +253,7 @@ public class PluginManager { /** * The final call you receive before your activity is destroyed. */ + @Deprecated // Should not be public public void onDestroy() { for (CordovaPlugin plugin : this.pluginMap.values()) { plugin.onDestroy(); @@ -278,6 +284,7 @@ public class PluginManager { /** * Called when the activity receives a new intent. */ + @Deprecated // Should not be public public void onNewIntent(Intent intent) { for (CordovaPlugin plugin : this.pluginMap.values()) { plugin.onNewIntent(intent); @@ -290,6 +297,7 @@ public class PluginManager { * @param url The URL that is being changed to. * @return Return false to allow the URL to load, return true to prevent the URL from loading. */ + @Deprecated // Should not be public public boolean onOverrideUrlLoading(String url) { // Deprecated way to intercept URLs. (process tags). // Instead, plugins should not include and instead ensure @@ -316,6 +324,7 @@ public class PluginManager { /** * Called when the app navigates or refreshes. */ + @Deprecated // Should not be public public void onReset() { for (CordovaPlugin plugin : this.pluginMap.values()) { plugin.onReset();