This commit is contained in:
Joe Bowser 2013-06-24 11:31:47 -07:00
commit 7e15ff930d
4 changed files with 66 additions and 12 deletions

View File

@ -66,7 +66,7 @@ elif [[ "$#" -eq 1 ]] ; then
$DIR/build $DIR/build
$DIR/lib/install-device $DIR/lib/install-device
elif [[ $1 == "--emulator" ]] ; then elif [[ $1 == "--emulator" ]] ; then
#$DIR/build $DIR/build
run_on_emulator run_on_emulator
elif [[ $1 =~ "--target=" ]]; then elif [[ $1 =~ "--target=" ]]; then
$DIR/build $DIR/build

View File

@ -48,9 +48,9 @@ import org.json.JSONException;
jsMessageQueue.setPaused(true); jsMessageQueue.setPaused(true);
try { try {
boolean wasSync = pluginManager.exec(service, action, callbackId, arguments); pluginManager.exec(service, action, callbackId, arguments);
String ret = ""; String ret = "";
if (!NativeToJsMessageQueue.DISABLE_EXEC_CHAINING || wasSync) { if (!NativeToJsMessageQueue.DISABLE_EXEC_CHAINING) {
ret = jsMessageQueue.popAndEncode(); ret = jsMessageQueue.popAndEncode();
} }
return ret; return ret;

View File

@ -63,6 +63,19 @@ public class PluginEntry {
this.onload = onload; this.onload = onload;
} }
/**
* Alternate constructor
*
* @param service The name of the service
* @param plugin The plugin associated with this entry
*/
public PluginEntry(String service, CordovaPlugin plugin) {
this.service = service;
this.plugin = plugin;
this.pluginClass = plugin.getClass().getName();
this.onload = false;
}
/** /**
* Create plugin object. * Create plugin object.
* If plugin is already created, then just return it. * If plugin is already created, then just return it.

View File

@ -22,7 +22,9 @@ import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaWebView; import org.apache.cordova.CordovaWebView;
import org.json.JSONException; import org.json.JSONException;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -55,6 +57,8 @@ public class PluginManager {
// This would allow how all URLs are handled to be offloaded to a plugin // This would allow how all URLs are handled to be offloaded to a plugin
protected HashMap<String, String> urlMap = new HashMap<String, String>(); protected HashMap<String, String> urlMap = new HashMap<String, String>();
private AtomicInteger numPendingUiExecs;
/** /**
* Constructor. * Constructor.
* *
@ -65,6 +69,7 @@ public class PluginManager {
this.ctx = ctx; this.ctx = ctx;
this.app = app; this.app = app;
this.firstRun = true; this.firstRun = true;
this.numPendingUiExecs = new AtomicInteger(0);
} }
/** /**
@ -86,6 +91,9 @@ public class PluginManager {
this.clearPluginObjects(); this.clearPluginObjects();
} }
// Insert PluginManager service
this.addService(new PluginEntry("PluginManager", new PluginManagerService()));
// Start up all plugins that have onload specified // Start up all plugins that have onload specified
this.startupPlugins(); this.startupPlugins();
} }
@ -200,15 +208,29 @@ public class PluginManager {
* this is an async plugin call. * this is an async plugin call.
* @param rawArgs An Array literal string containing any arguments needed in the * @param rawArgs An Array literal string containing any arguments needed in the
* plugin execute method. * plugin execute method.
* @return Whether the task completed synchronously.
*/ */
public boolean exec(String service, String action, String callbackId, String rawArgs) { public void exec(final String service, final String action, final String callbackId, final String rawArgs) {
CordovaPlugin plugin = this.getPlugin(service); if (numPendingUiExecs.get() > 0) {
numPendingUiExecs.getAndIncrement();
this.ctx.getActivity().runOnUiThread(new Runnable() {
public void run() {
execHelper(service, action, callbackId, rawArgs);
numPendingUiExecs.getAndDecrement();
}
});
} else {
Log.d(TAG, "running exec normally");
execHelper(service, action, callbackId, rawArgs);
}
}
private void execHelper(final String service, final String action, final String callbackId, final String rawArgs) {
CordovaPlugin plugin = getPlugin(service);
if (plugin == null) { if (plugin == null) {
Log.d(TAG, "exec() call to unknown plugin: " + service); Log.d(TAG, "exec() call to unknown plugin: " + service);
PluginResult cr = new PluginResult(PluginResult.Status.CLASS_NOT_FOUND_EXCEPTION); PluginResult cr = new PluginResult(PluginResult.Status.CLASS_NOT_FOUND_EXCEPTION);
app.sendPluginResult(cr, callbackId); app.sendPluginResult(cr, callbackId);
return true; return;
} }
try { try {
CallbackContext callbackContext = new CallbackContext(callbackId, app); CallbackContext callbackContext = new CallbackContext(callbackId, app);
@ -216,19 +238,16 @@ public class PluginManager {
if (!wasValidAction) { if (!wasValidAction) {
PluginResult cr = new PluginResult(PluginResult.Status.INVALID_ACTION); PluginResult cr = new PluginResult(PluginResult.Status.INVALID_ACTION);
app.sendPluginResult(cr, callbackId); app.sendPluginResult(cr, callbackId);
return true;
} }
return callbackContext.isFinished();
} catch (JSONException e) { } catch (JSONException e) {
PluginResult cr = new PluginResult(PluginResult.Status.JSON_EXCEPTION); PluginResult cr = new PluginResult(PluginResult.Status.JSON_EXCEPTION);
app.sendPluginResult(cr, callbackId); app.sendPluginResult(cr, callbackId);
return true;
} }
} }
@Deprecated @Deprecated
public boolean exec(String service, String action, String callbackId, String jsonArgs, boolean async) { public void exec(String service, String action, String callbackId, String jsonArgs, boolean async) {
return exec(service, action, callbackId, jsonArgs); exec(service, action, callbackId, jsonArgs);
} }
/** /**
@ -400,4 +419,26 @@ public class PluginManager {
LOG.e(TAG, "https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-android.git;a=blob;f=framework/res/xml/plugins.xml"); LOG.e(TAG, "https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-android.git;a=blob;f=framework/res/xml/plugins.xml");
LOG.e(TAG, "====================================================================================="); LOG.e(TAG, "=====================================================================================");
} }
private class PluginManagerService extends CordovaPlugin {
@Override
public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {
if ("startup".equals(action)) {
// The onPageStarted event of CordovaWebViewClient resets the queue of messages to be returned to javascript in response
// to exec calls. Since this event occurs on the UI thread and exec calls happen on the WebCore thread it is possible
// that onPageStarted occurs after exec calls have started happening on a new page, which can cause the message queue
// to be reset between the queuing of a new message and its retrieval by javascript. To avoid this from happening,
// javascript always sends a "startup" exec upon loading a new page which causes all future exec calls to happen on the UI
// thread (and hence after onPageStarted) until there are no more pending exec calls remaining.
numPendingUiExecs.getAndIncrement();
ctx.getActivity().runOnUiThread(new Runnable() {
public void run() {
numPendingUiExecs.getAndDecrement();
}
});
return true;
}
return false;
}
}
} }