You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ag...@apache.org on 2013/06/29 03:53:19 UTC

[2/4] android commit: [CB-4038] Move non-deprecated classes from the api package into the main package.

[CB-4038] Move non-deprecated classes from the api package into the main package.


Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/04ff14e6
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/04ff14e6
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/04ff14e6

Branch: refs/heads/2.9.x
Commit: 04ff14e629e5596f04f997ba0d9879df8d258ff6
Parents: 67e97a8
Author: Andrew Grieve <ag...@chromium.org>
Authored: Thu Jun 27 22:29:18 2013 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Fri Jun 28 17:52:00 2013 -0400

----------------------------------------------------------------------
 .../src/org/apache/cordova/CallbackContext.java | 147 +++++++
 .../org/apache/cordova/CordovaInterface.java    |  70 +++
 .../src/org/apache/cordova/CordovaPlugin.java   | 182 ++++++++
 framework/src/org/apache/cordova/LOG.java       | 234 ++++++++++
 .../src/org/apache/cordova/PluginEntry.java     | 130 ++++++
 .../src/org/apache/cordova/PluginManager.java   | 438 +++++++++++++++++++
 .../src/org/apache/cordova/PluginResult.java    | 179 ++++++++
 .../org/apache/cordova/api/CallbackContext.java | 124 +-----
 .../apache/cordova/api/CordovaInterface.java    |  46 +-
 .../org/apache/cordova/api/CordovaPlugin.java   | 162 +------
 framework/src/org/apache/cordova/api/LOG.java   | 214 +--------
 .../src/org/apache/cordova/api/PluginEntry.java | 107 +----
 .../org/apache/cordova/api/PluginManager.java   | 415 +-----------------
 .../org/apache/cordova/api/PluginResult.java    | 139 +-----
 14 files changed, 1400 insertions(+), 1187 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ff14e6/framework/src/org/apache/cordova/CallbackContext.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CallbackContext.java b/framework/src/org/apache/cordova/CallbackContext.java
new file mode 100644
index 0000000..09ee70e
--- /dev/null
+++ b/framework/src/org/apache/cordova/CallbackContext.java
@@ -0,0 +1,147 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+package org.apache.cordova;
+
+import org.json.JSONArray;
+
+import android.util.Log;
+
+import org.apache.cordova.CordovaWebView;
+import org.json.JSONObject;
+
+public class CallbackContext {
+    private static final String LOG_TAG = "CordovaPlugin";
+
+    private String callbackId;
+    private CordovaWebView webView;
+    private boolean finished;
+    private int changingThreads;
+
+    public CallbackContext(String callbackId, CordovaWebView webView) {
+        this.callbackId = callbackId;
+        this.webView = webView;
+    }
+    
+    public boolean isFinished() {
+        return finished;
+    }
+    
+    public boolean isChangingThreads() {
+        return changingThreads > 0;
+    }
+    
+    public String getCallbackId() {
+        return callbackId;
+    }
+
+    public void sendPluginResult(PluginResult pluginResult) {
+        synchronized (this) {
+            if (finished) {
+                Log.w(LOG_TAG, "Attempted to send a second callback for ID: " + callbackId + "\nResult was: " + pluginResult.getMessage());
+                return;
+            } else {
+                finished = !pluginResult.getKeepCallback();
+            }
+        }
+        webView.sendPluginResult(pluginResult, callbackId);
+    }
+
+    /**
+     * Helper for success callbacks that just returns the Status.OK by default
+     *
+     * @param message           The message to add to the success result.
+     */
+    public void success(JSONObject message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
+    }
+
+    /**
+     * Helper for success callbacks that just returns the Status.OK by default
+     *
+     * @param message           The message to add to the success result.
+     */
+    public void success(String message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
+    }
+
+    /**
+     * Helper for success callbacks that just returns the Status.OK by default
+     *
+     * @param message           The message to add to the success result.
+     */
+    public void success(JSONArray message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
+    }
+
+    /**
+     * Helper for success callbacks that just returns the Status.OK by default
+     *
+     * @param message           The message to add to the success result.
+     */
+    public void success(byte[] message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
+    }
+    
+    /**
+     * Helper for success callbacks that just returns the Status.OK by default
+     *
+     * @param message           The message to add to the success result.
+     */
+    public void success(int message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
+    }
+
+    /**
+     * Helper for success callbacks that just returns the Status.OK by default
+     *
+     * @param message           The message to add to the success result.
+     */
+    public void success() {
+        sendPluginResult(new PluginResult(PluginResult.Status.OK));
+    }
+
+    /**
+     * Helper for error callbacks that just returns the Status.ERROR by default
+     *
+     * @param message           The message to add to the error result.
+     */
+    public void error(JSONObject message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
+    }
+
+    /**
+     * Helper for error callbacks that just returns the Status.ERROR by default
+     *
+     * @param message           The message to add to the error result.
+     * @param callbackId        The callback id used when calling back into JavaScript.
+     */
+    public void error(String message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
+    }
+
+    /**
+     * Helper for error callbacks that just returns the Status.ERROR by default
+     *
+     * @param message           The message to add to the error result.
+     * @param callbackId        The callback id used when calling back into JavaScript.
+     */
+    public void error(int message) {
+        sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ff14e6/framework/src/org/apache/cordova/CordovaInterface.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaInterface.java b/framework/src/org/apache/cordova/CordovaInterface.java
new file mode 100755
index 0000000..d63d8dd
--- /dev/null
+++ b/framework/src/org/apache/cordova/CordovaInterface.java
@@ -0,0 +1,70 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+package org.apache.cordova;
+
+import android.app.Activity;
+import android.content.Intent;
+
+import java.util.concurrent.ExecutorService;
+
+/**
+ * The Activity interface that is implemented by CordovaActivity.
+ * It is used to isolate plugin development, and remove dependency on entire Cordova library.
+ */
+public interface CordovaInterface {
+
+    /**
+     * Launch an activity for which you would like a result when it finished. When this activity exits,
+     * your onActivityResult() method will be called.
+     *
+     * @param command     The command object
+     * @param intent      The intent to start
+     * @param requestCode   The request code that is passed to callback to identify the activity
+     */
+    abstract public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode);
+
+    /**
+     * Set the plugin to be called when a sub-activity exits.
+     *
+     * @param plugin      The plugin on which onActivityResult is to be called
+     */
+    abstract public void setActivityResultCallback(CordovaPlugin plugin);
+
+    /**
+     * Get the Android activity.
+     *
+     * @return
+     */
+    public abstract Activity getActivity();
+    
+
+    /**
+     * Called when a message is sent to plugin.
+     *
+     * @param id            The message id
+     * @param data          The message data
+     * @return              Object or null
+     */
+    public Object onMessage(String id, Object data);
+    
+    /**
+     * Returns a shared thread pool that can be used for background tasks.
+     */
+    public ExecutorService getThreadPool();
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ff14e6/framework/src/org/apache/cordova/CordovaPlugin.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaPlugin.java b/framework/src/org/apache/cordova/CordovaPlugin.java
new file mode 100644
index 0000000..3955e49
--- /dev/null
+++ b/framework/src/org/apache/cordova/CordovaPlugin.java
@@ -0,0 +1,182 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+package org.apache.cordova;
+
+import org.apache.cordova.CordovaArgs;
+import org.apache.cordova.CordovaWebView;
+import org.apache.cordova.UriResolver;
+import org.json.JSONArray;
+import org.json.JSONException;
+
+import android.content.Intent;
+import android.net.Uri;
+
+/**
+ * Plugins must extend this class and override one of the execute methods.
+ */
+public class CordovaPlugin {
+    public String id;
+    public CordovaWebView webView;					// WebView object
+    public CordovaInterface cordova;
+
+    /**
+     * @param cordova The context of the main Activity.
+     * @param webView The associated CordovaWebView.
+     */
+    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
+        assert this.cordova == null;
+        this.cordova = cordova;
+        this.webView = webView;
+    }
+
+    /**
+     * Executes the request.
+     *
+     * This method is called from the WebView thread. To do a non-trivial amount of work, use:
+     *     cordova.getThreadPool().execute(runnable);
+     *
+     * To run on the UI thread, use:
+     *     cordova.getActivity().runOnUiThread(runnable);
+     *
+     * @param action          The action to execute.
+     * @param rawArgs         The exec() arguments in JSON form.
+     * @param callbackContext The callback context used when calling back into JavaScript.
+     * @return                Whether the action was valid.
+     */
+    public boolean execute(String action, String rawArgs, CallbackContext callbackContext) throws JSONException {
+        JSONArray args = new JSONArray(rawArgs);
+        return execute(action, args, callbackContext);
+    }
+
+    /**
+     * Executes the request.
+     *
+     * This method is called from the WebView thread. To do a non-trivial amount of work, use:
+     *     cordova.getThreadPool().execute(runnable);
+     *
+     * To run on the UI thread, use:
+     *     cordova.getActivity().runOnUiThread(runnable);
+     *
+     * @param action          The action to execute.
+     * @param args            The exec() arguments.
+     * @param callbackContext The callback context used when calling back into JavaScript.
+     * @return                Whether the action was valid.
+     */
+    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
+        CordovaArgs cordovaArgs = new CordovaArgs(args);
+        return execute(action, cordovaArgs, callbackContext);
+    }
+
+    /**
+     * Executes the request.
+     *
+     * This method is called from the WebView thread. To do a non-trivial amount of work, use:
+     *     cordova.getThreadPool().execute(runnable);
+     *
+     * To run on the UI thread, use:
+     *     cordova.getActivity().runOnUiThread(runnable);
+     *
+     * @param action          The action to execute.
+     * @param args            The exec() arguments, wrapped with some Cordova helpers.
+     * @param callbackContext The callback context used when calling back into JavaScript.
+     * @return                Whether the action was valid.
+     */
+    public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
+        return false;
+    }
+
+    /**
+     * Called when the system is about to start resuming a previous activity.
+     *
+     * @param multitasking		Flag indicating if multitasking is turned on for app
+     */
+    public void onPause(boolean multitasking) {
+    }
+
+    /**
+     * Called when the activity will start interacting with the user.
+     *
+     * @param multitasking		Flag indicating if multitasking is turned on for app
+     */
+    public void onResume(boolean multitasking) {
+    }
+
+    /**
+     * Called when the activity receives a new intent.
+     */
+    public void onNewIntent(Intent intent) {
+    }
+
+    /**
+     * The final call you receive before your activity is destroyed.
+     */
+    public void onDestroy() {
+    }
+
+    /**
+     * Called when a message is sent to plugin.
+     *
+     * @param id            The message id
+     * @param data          The message data
+     * @return              Object to stop propagation or null
+     */
+    public Object onMessage(String id, Object data) {
+        return null;
+    }
+
+    /**
+     * Called when an activity you launched exits, giving you the requestCode you started it with,
+     * the resultCode it returned, and any additional data from it.
+     *
+     * @param requestCode		The request code originally supplied to startActivityForResult(),
+     * 							allowing you to identify who this result came from.
+     * @param resultCode		The integer result code returned by the child activity through its setResult().
+     * @param data				An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
+     */
+    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+    }
+
+    /**
+     * By specifying a <url-filter> in config.xml you can map a URL (using startsWith atm) to this method.
+     *
+     * @param url				The URL that is trying to be loaded in the Cordova webview.
+     * @return					Return true to prevent the URL from loading. Default is false.
+     */
+    public boolean onOverrideUrlLoading(String url) {
+        return false;
+    }
+
+    /**
+     * Hook for overriding the default URI handling mechanism.
+     * Applies to WebView requests as well as requests made by plugins.
+     */
+    public UriResolver resolveUri(Uri uri) {
+        return null;
+    }
+
+    /**
+     * Called when the WebView does a top-level navigation or refreshes.
+     *
+     * Plugins should stop any long-running processes and clean up internal state.
+     *
+     * Does nothing by default.
+     */
+    public void onReset() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ff14e6/framework/src/org/apache/cordova/LOG.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/LOG.java b/framework/src/org/apache/cordova/LOG.java
new file mode 100755
index 0000000..d5fdfdd
--- /dev/null
+++ b/framework/src/org/apache/cordova/LOG.java
@@ -0,0 +1,234 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+package org.apache.cordova;
+
+import android.util.Log;
+
+/**
+ * Log to Android logging system.
+ *
+ * Log message can be a string or a printf formatted string with arguments.
+ * See http://developer.android.com/reference/java/util/Formatter.html
+ */
+public class LOG {
+
+    public static final int VERBOSE = Log.VERBOSE;
+    public static final int DEBUG = Log.DEBUG;
+    public static final int INFO = Log.INFO;
+    public static final int WARN = Log.WARN;
+    public static final int ERROR = Log.ERROR;
+
+    // Current log level
+    public static int LOGLEVEL = Log.ERROR;
+
+    /**
+     * Set the current log level.
+     *
+     * @param logLevel
+     */
+    public static void setLogLevel(int logLevel) {
+        LOGLEVEL = logLevel;
+        Log.i("CordovaLog", "Changing log level to " + logLevel);
+    }
+
+    /**
+     * Set the current log level.
+     *
+     * @param logLevel
+     */
+    public static void setLogLevel(String logLevel) {
+        if ("VERBOSE".equals(logLevel)) LOGLEVEL = VERBOSE;
+        else if ("DEBUG".equals(logLevel)) LOGLEVEL = DEBUG;
+        else if ("INFO".equals(logLevel)) LOGLEVEL = INFO;
+        else if ("WARN".equals(logLevel)) LOGLEVEL = WARN;
+        else if ("ERROR".equals(logLevel)) LOGLEVEL = ERROR;
+        Log.i("CordovaLog", "Changing log level to " + logLevel + "(" + LOGLEVEL + ")");
+    }
+
+    /**
+     * Determine if log level will be logged
+     *
+     * @param logLevel
+     * @return
+     */
+    public static boolean isLoggable(int logLevel) {
+        return (logLevel >= LOGLEVEL);
+    }
+
+    /**
+     * Verbose log message.
+     *
+     * @param tag
+     * @param s
+     */
+    public static void v(String tag, String s) {
+        if (LOG.VERBOSE >= LOGLEVEL) Log.v(tag, s);
+    }
+
+    /**
+     * Debug log message.
+     *
+     * @param tag
+     * @param s
+     */
+    public static void d(String tag, String s) {
+        if (LOG.DEBUG >= LOGLEVEL) Log.d(tag, s);
+    }
+
+    /**
+     * Info log message.
+     *
+     * @param tag
+     * @param s
+     */
+    public static void i(String tag, String s) {
+        if (LOG.INFO >= LOGLEVEL) Log.i(tag, s);
+    }
+
+    /**
+     * Warning log message.
+     *
+     * @param tag
+     * @param s
+     */
+    public static void w(String tag, String s) {
+        if (LOG.WARN >= LOGLEVEL) Log.w(tag, s);
+    }
+
+    /**
+     * Error log message.
+     *
+     * @param tag
+     * @param s
+     */
+    public static void e(String tag, String s) {
+        if (LOG.ERROR >= LOGLEVEL) Log.e(tag, s);
+    }
+
+    /**
+     * Verbose log message.
+     *
+     * @param tag
+     * @param s
+     * @param e
+     */
+    public static void v(String tag, String s, Throwable e) {
+        if (LOG.VERBOSE >= LOGLEVEL) Log.v(tag, s, e);
+    }
+
+    /**
+     * Debug log message.
+     *
+     * @param tag
+     * @param s
+     * @param e
+     */
+    public static void d(String tag, String s, Throwable e) {
+        if (LOG.DEBUG >= LOGLEVEL) Log.d(tag, s, e);
+    }
+
+    /**
+     * Info log message.
+     *
+     * @param tag
+     * @param s
+     * @param e
+     */
+    public static void i(String tag, String s, Throwable e) {
+        if (LOG.INFO >= LOGLEVEL) Log.i(tag, s, e);
+    }
+
+    /**
+     * Warning log message.
+     *
+     * @param tag
+     * @param s
+     * @param e
+     */
+    public static void w(String tag, String s, Throwable e) {
+        if (LOG.WARN >= LOGLEVEL) Log.w(tag, s, e);
+    }
+
+    /**
+     * Error log message.
+     *
+     * @param tag
+     * @param s
+     * @param e
+     */
+    public static void e(String tag, String s, Throwable e) {
+        if (LOG.ERROR >= LOGLEVEL) Log.e(tag, s, e);
+    }
+
+    /**
+     * Verbose log message with printf formatting.
+     *
+     * @param tag
+     * @param s
+     * @param args
+     */
+    public static void v(String tag, String s, Object... args) {
+        if (LOG.VERBOSE >= LOGLEVEL) Log.v(tag, String.format(s, args));
+    }
+
+    /**
+     * Debug log message with printf formatting.
+     *
+     * @param tag
+     * @param s
+     * @param args
+     */
+    public static void d(String tag, String s, Object... args) {
+        if (LOG.DEBUG >= LOGLEVEL) Log.d(tag, String.format(s, args));
+    }
+
+    /**
+     * Info log message with printf formatting.
+     *
+     * @param tag
+     * @param s
+     * @param args
+     */
+    public static void i(String tag, String s, Object... args) {
+        if (LOG.INFO >= LOGLEVEL) Log.i(tag, String.format(s, args));
+    }
+
+    /**
+     * Warning log message with printf formatting.
+     *
+     * @param tag
+     * @param s
+     * @param args
+     */
+    public static void w(String tag, String s, Object... args) {
+        if (LOG.WARN >= LOGLEVEL) Log.w(tag, String.format(s, args));
+    }
+
+    /**
+     * Error log message with printf formatting.
+     *
+     * @param tag
+     * @param s
+     * @param args
+     */
+    public static void e(String tag, String s, Object... args) {
+        if (LOG.ERROR >= LOGLEVEL) Log.e(tag, String.format(s, args));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ff14e6/framework/src/org/apache/cordova/PluginEntry.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/PluginEntry.java b/framework/src/org/apache/cordova/PluginEntry.java
new file mode 100755
index 0000000..8149395
--- /dev/null
+++ b/framework/src/org/apache/cordova/PluginEntry.java
@@ -0,0 +1,130 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+ */
+package org.apache.cordova;
+
+import org.apache.cordova.CordovaWebView;
+
+//import android.content.Context;
+//import android.webkit.WebView;
+
+/**
+ * This class represents a service entry object.
+ */
+public class PluginEntry {
+
+    /**
+     * The name of the service that this plugin implements
+     */
+    public String service = "";
+
+    /**
+     * The plugin class name that implements the service.
+     */
+    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.
+     */
+    public CordovaPlugin plugin = null;
+
+    /**
+     * Flag that indicates the plugin object should be created when PluginManager is initialized.
+     */
+    public boolean onload = false;
+
+    /**
+     * Constructor
+     *
+     * @param service               The name of the service
+     * @param pluginClass           The plugin class name
+     * @param onload                Create plugin object when HTML page is loaded
+     */
+    public PluginEntry(String service, String pluginClass, boolean onload) {
+        this.service = service;
+        this.pluginClass = pluginClass;
+        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.
+     * 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 {
+            @SuppressWarnings("rawtypes")
+            Class c = getClassByName(this.pluginClass);
+            if (isCordovaPlugin(c)) {
+                this.plugin = (CordovaPlugin) c.newInstance();
+                this.plugin.initialize(ctx, webView);
+                return plugin;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("Error adding plugin " + this.pluginClass + ".");
+        }
+        return null;
+    }
+
+    /**
+     * Get the class.
+     *
+     * @param clazz
+     * @return
+     * @throws ClassNotFoundException
+     */
+    @SuppressWarnings("rawtypes")
+    private Class getClassByName(final String clazz) throws ClassNotFoundException {
+        Class c = null;
+        if (clazz != null) {
+            c = Class.forName(clazz);
+        }
+        return c;
+    }
+
+    /**
+     * Returns whether the given class extends CordovaPlugin.
+     */
+    @SuppressWarnings("rawtypes")
+    private boolean isCordovaPlugin(Class c) {
+        if (c != null) {
+            return org.apache.cordova.api.CordovaPlugin.class.isAssignableFrom(c);
+        }
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ff14e6/framework/src/org/apache/cordova/PluginManager.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/PluginManager.java b/framework/src/org/apache/cordova/PluginManager.java
new file mode 100755
index 0000000..51a97e6
--- /dev/null
+++ b/framework/src/org/apache/cordova/PluginManager.java
@@ -0,0 +1,438 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+ */
+package org.apache.cordova;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+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.UriResolver;
+import org.json.JSONException;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Intent;
+import android.content.res.XmlResourceParser;
+
+import android.net.Uri;
+import android.util.Log;
+import android.webkit.WebResourceResponse;
+
+/**
+ * PluginManager is exposed to JavaScript in the Cordova WebView.
+ *
+ * Calling native plugin code can be done by calling PluginManager.exec(...)
+ * from JavaScript.
+ */
+public class PluginManager {
+    private static String TAG = "PluginManager";
+
+    // List of service entries
+    private final HashMap<String, PluginEntry> entries = new HashMap<String, PluginEntry>();
+
+    private final CordovaInterface ctx;
+    private final CordovaWebView app;
+
+    // Flag to track first time through
+    private boolean firstRun;
+
+    // Map URL schemes like foo: to plugins that want to handle those schemes
+    // This would allow how all URLs are handled to be offloaded to a plugin
+    protected HashMap<String, String> urlMap = new HashMap<String, String>();
+
+    private AtomicInteger numPendingUiExecs;
+
+    /**
+     * Constructor.
+     *
+     * @param app
+     * @param ctx
+     */
+    public PluginManager(CordovaWebView app, CordovaInterface ctx) {
+        this.ctx = ctx;
+        this.app = app;
+        this.firstRun = true;
+        this.numPendingUiExecs = new AtomicInteger(0);
+    }
+
+    /**
+     * Init when loading a new HTML page into webview.
+     */
+    public void init() {
+        LOG.d(TAG, "init()");
+
+        // If first time, then load plugins from config.xml file
+        if (this.firstRun) {
+            this.loadPlugins();
+            this.firstRun = false;
+        }
+
+        // Stop plugins on current HTML page and discard plugin objects
+        else {
+            this.onPause(false);
+            this.onDestroy();
+            this.clearPluginObjects();
+        }
+
+        // Insert PluginManager service
+        this.addService(new PluginEntry("PluginManager", new PluginManagerService()));
+
+        // Start up all plugins that have onload specified
+        this.startupPlugins();
+    }
+
+    /**
+     * Load plugins from res/xml/config.xml
+     */
+    public void loadPlugins() {
+        int id = this.ctx.getActivity().getResources().getIdentifier("config", "xml", this.ctx.getActivity().getPackageName());
+        if(id == 0)
+        {
+            id = this.ctx.getActivity().getResources().getIdentifier("plugins", "xml", this.ctx.getActivity().getPackageName());
+            LOG.i(TAG, "Using plugins.xml instead of config.xml.  plugins.xml will eventually be deprecated");
+        }
+        if (id == 0) {
+            this.pluginConfigurationMissing();
+            //We have the error, we need to exit without crashing!
+            return;
+        }
+        XmlResourceParser xml = this.ctx.getActivity().getResources().getXml(id);
+        int eventType = -1;
+        String service = "", pluginClass = "", paramType = "";
+        boolean onload = false;
+        boolean insideFeature = false;
+        while (eventType != XmlResourceParser.END_DOCUMENT) {
+            if (eventType == XmlResourceParser.START_TAG) {
+                String strNode = xml.getName();
+                //This is for the old scheme
+                if (strNode.equals("plugin")) {
+                    service = xml.getAttributeValue(null, "name");
+                    pluginClass = xml.getAttributeValue(null, "value");
+                    Log.d(TAG, "<plugin> tags are deprecated, please use <features> instead. <plugin> will no longer work as of Cordova 3.0");
+                    onload = "true".equals(xml.getAttributeValue(null, "onload"));
+                }
+                //What is this?
+                else if (strNode.equals("url-filter")) {
+                    this.urlMap.put(xml.getAttributeValue(null, "value"), service);
+                }
+                else if (strNode.equals("feature")) {
+                    //Check for supported feature sets  aka. plugins (Accelerometer, Geolocation, etc)
+                    //Set the bit for reading params
+                    insideFeature = true;
+                    service = xml.getAttributeValue(null, "name");
+                }
+                else if (insideFeature && strNode.equals("param")) {
+                    paramType = xml.getAttributeValue(null, "name");
+                    if (paramType.equals("service")) // check if it is using the older service param
+                        service = xml.getAttributeValue(null, "value");
+                    else if (paramType.equals("package") || paramType.equals("android-package"))
+                        pluginClass = xml.getAttributeValue(null,"value");
+                    else if (paramType.equals("onload"))
+                        onload = "true".equals(xml.getAttributeValue(null, "value"));
+                }
+            }
+            else if (eventType == XmlResourceParser.END_TAG)
+            {
+                String strNode = xml.getName();
+                if (strNode.equals("feature") || strNode.equals("plugin"))
+                {
+                    PluginEntry entry = new PluginEntry(service, pluginClass, onload);
+                    this.addService(entry);
+
+                    //Empty the strings to prevent plugin loading bugs
+                    service = "";
+                    pluginClass = "";
+                    insideFeature = false;
+                }
+            }
+            try {
+                eventType = xml.next();
+            } catch (XmlPullParserException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Delete all plugin objects.
+     */
+    public void clearPluginObjects() {
+        for (PluginEntry entry : this.entries.values()) {
+            entry.plugin = null;
+        }
+    }
+
+    /**
+     * Create plugins objects that have onload set.
+     */
+    public void startupPlugins() {
+        for (PluginEntry entry : this.entries.values()) {
+            if (entry.onload) {
+                entry.createPlugin(this.app, this.ctx);
+            }
+        }
+    }
+
+    /**
+     * Receives a request for execution and fulfills it by finding the appropriate
+     * Java class and calling it's execute method.
+     *
+     * PluginManager.exec can be used either synchronously or async. In either case, a JSON encoded
+     * string is returned that will indicate if any errors have occurred when trying to find
+     * or execute the class denoted by the clazz argument.
+     *
+     * @param service       String containing the service to run
+     * @param action        String containing the action that the class is supposed to perform. This is
+     *                      passed to the plugin execute method and it is up to the plugin developer
+     *                      how to deal with it.
+     * @param callbackId    String containing the id of the callback that is execute in JavaScript if
+     *                      this is an async plugin call.
+     * @param rawArgs       An Array literal string containing any arguments needed in the
+     *                      plugin execute method.
+     */
+    public void exec(final String service, final String action, final String callbackId, final String rawArgs) {
+        if (numPendingUiExecs.get() > 0) {
+            numPendingUiExecs.getAndIncrement();
+            this.ctx.getActivity().runOnUiThread(new Runnable() {
+                public void run() {
+                    execHelper(service, action, callbackId, rawArgs);
+                    numPendingUiExecs.getAndDecrement();
+                }
+            });
+        } else {
+            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) {
+            Log.d(TAG, "exec() call to unknown plugin: " + service);
+            PluginResult cr = new PluginResult(PluginResult.Status.CLASS_NOT_FOUND_EXCEPTION);
+            app.sendPluginResult(cr, callbackId);
+            return;
+        }
+        try {
+            CallbackContext callbackContext = new CallbackContext(callbackId, app);
+            boolean wasValidAction = plugin.execute(action, rawArgs, callbackContext);
+            if (!wasValidAction) {
+                PluginResult cr = new PluginResult(PluginResult.Status.INVALID_ACTION);
+                app.sendPluginResult(cr, callbackId);
+            }
+        } catch (JSONException e) {
+            PluginResult cr = new PluginResult(PluginResult.Status.JSON_EXCEPTION);
+            app.sendPluginResult(cr, callbackId);
+        }
+    }
+
+    @Deprecated
+    public void exec(String service, String action, String callbackId, String jsonArgs, boolean async) {
+        exec(service, action, callbackId, jsonArgs);
+    }
+
+    /**
+     * Get the plugin object that implements the service.
+     * If the plugin object does not already exist, then create it.
+     * If the service doesn't exist, then return null.
+     *
+     * @param service       The name of the service.
+     * @return              CordovaPlugin or null
+     */
+    public CordovaPlugin getPlugin(String service) {
+        PluginEntry entry = this.entries.get(service);
+        if (entry == null) {
+            return null;
+        }
+        CordovaPlugin plugin = entry.plugin;
+        if (plugin == null) {
+            plugin = entry.createPlugin(this.app, this.ctx);
+        }
+        return plugin;
+    }
+
+    /**
+     * Add a plugin class that implements a service to the service entry table.
+     * This does not create the plugin object instance.
+     *
+     * @param service           The service name
+     * @param className         The plugin class name
+     */
+    public void addService(String service, String className) {
+        PluginEntry entry = new PluginEntry(service, className, false);
+        this.addService(entry);
+    }
+
+    /**
+     * Add a plugin class that implements a service to the service entry table.
+     * This does not create the plugin object instance.
+     *
+     * @param entry             The plugin entry
+     */
+    public void addService(PluginEntry entry) {
+        this.entries.put(entry.service, entry);
+    }
+
+    /**
+     * Called when the system is about to start resuming a previous activity.
+     *
+     * @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);
+            }
+        }
+    }
+
+    /**
+     * Called when the activity will start interacting with the user.
+     *
+     * @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);
+            }
+        }
+    }
+
+    /**
+     * 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();
+            }
+        }
+    }
+
+    /**
+     * Send a message to all plugins.
+     *
+     * @param id                The message id
+     * @param data              The message data
+     * @return
+     */
+    public Object postMessage(String id, Object data) {
+        Object obj = this.ctx.onMessage(id, data);
+        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;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 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);
+            }
+        }
+    }
+
+    /**
+     * Called when the URL of the webview changes.
+     *
+     * @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.
+     */
+    public boolean onOverrideUrlLoading(String url) {
+        Iterator<Entry<String, String>> it = this.urlMap.entrySet().iterator();
+        while (it.hasNext()) {
+            HashMap.Entry<String, String> pairs = it.next();
+            if (url.startsWith(pairs.getKey())) {
+                return this.getPlugin(pairs.getValue()).onOverrideUrlLoading(url);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Called when the app navigates or refreshes.
+     */
+    public void onReset() {
+        Iterator<PluginEntry> it = this.entries.values().iterator();
+        while (it.hasNext()) {
+            CordovaPlugin plugin = it.next().plugin;
+            if (plugin != null) {
+                plugin.onReset();
+            }
+        }
+    }
+
+
+    private void pluginConfigurationMissing() {
+        LOG.e(TAG, "=====================================================================================");
+        LOG.e(TAG, "ERROR: config.xml is missing.  Add res/xml/config.xml to your project.");
+        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, "=====================================================================================");
+    }
+
+    UriResolver resolveUri(Uri uri) {
+        for (PluginEntry entry : this.entries.values()) {
+            if (entry.plugin != null) {
+                UriResolver ret = entry.plugin.resolveUri(uri);
+                if (ret != null) {
+                    return ret;
+                }
+            }
+        }
+        return null;
+    }
+
+    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;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ff14e6/framework/src/org/apache/cordova/PluginResult.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/PluginResult.java b/framework/src/org/apache/cordova/PluginResult.java
new file mode 100755
index 0000000..920cbc2
--- /dev/null
+++ b/framework/src/org/apache/cordova/PluginResult.java
@@ -0,0 +1,179 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+package org.apache.cordova;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import android.util.Base64;
+
+public class PluginResult {
+    private final int status;
+    private final int messageType;
+    private boolean keepCallback = false;
+    private String strMessage;
+    private String encodedMessage;
+
+    public PluginResult(Status status) {
+        this(status, PluginResult.StatusMessages[status.ordinal()]);
+    }
+
+    public PluginResult(Status status, String message) {
+        this.status = status.ordinal();
+        this.messageType = message == null ? MESSAGE_TYPE_NULL : MESSAGE_TYPE_STRING;
+        this.strMessage = message;
+    }
+
+    public PluginResult(Status status, JSONArray message) {
+        this.status = status.ordinal();
+        this.messageType = MESSAGE_TYPE_JSON;
+        encodedMessage = message.toString();
+    }
+
+    public PluginResult(Status status, JSONObject message) {
+        this.status = status.ordinal();
+        this.messageType = MESSAGE_TYPE_JSON;
+        encodedMessage = message.toString();
+    }
+
+    public PluginResult(Status status, int i) {
+        this.status = status.ordinal();
+        this.messageType = MESSAGE_TYPE_NUMBER;
+        this.encodedMessage = ""+i;
+    }
+
+    public PluginResult(Status status, float f) {
+        this.status = status.ordinal();
+        this.messageType = MESSAGE_TYPE_NUMBER;
+        this.encodedMessage = ""+f;
+    }
+
+    public PluginResult(Status status, boolean b) {
+        this.status = status.ordinal();
+        this.messageType = MESSAGE_TYPE_BOOLEAN;
+        this.encodedMessage = Boolean.toString(b);
+    }
+
+    public PluginResult(Status status, byte[] data) {
+        this(status, data, false);
+    }
+
+    public PluginResult(Status status, byte[] data, boolean binaryString) {
+        this.status = status.ordinal();
+        this.messageType = binaryString ? MESSAGE_TYPE_BINARYSTRING : MESSAGE_TYPE_ARRAYBUFFER;
+        this.encodedMessage = Base64.encodeToString(data, Base64.NO_WRAP);
+    }
+    
+    public void setKeepCallback(boolean b) {
+        this.keepCallback = b;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+    public int getMessageType() {
+        return messageType;
+    }
+
+    public String getMessage() {
+        if (encodedMessage == null) {
+            encodedMessage = JSONObject.quote(strMessage);
+        }
+        return encodedMessage;
+    }
+
+    /**
+     * If messageType == MESSAGE_TYPE_STRING, then returns the message string.
+     * Otherwise, returns null.
+     */
+    public String getStrMessage() {
+        return strMessage;
+    }
+
+    public boolean getKeepCallback() {
+        return this.keepCallback;
+    }
+
+    @Deprecated // Use sendPluginResult instead of sendJavascript.
+    public String getJSONString() {
+        return "{\"status\":" + this.status + ",\"message\":" + this.getMessage() + ",\"keepCallback\":" + this.keepCallback + "}";
+    }
+
+    @Deprecated // Use sendPluginResult instead of sendJavascript.
+    public String toCallbackString(String callbackId) {
+        // If no result to be sent and keeping callback, then no need to sent back to JavaScript
+        if ((status == PluginResult.Status.NO_RESULT.ordinal()) && keepCallback) {
+        	return null;
+        }
+
+        // Check the success (OK, NO_RESULT & !KEEP_CALLBACK)
+        if ((status == PluginResult.Status.OK.ordinal()) || (status == PluginResult.Status.NO_RESULT.ordinal())) {
+            return toSuccessCallbackString(callbackId);
+        }
+
+        return toErrorCallbackString(callbackId);
+    }
+
+    @Deprecated // Use sendPluginResult instead of sendJavascript.
+    public String toSuccessCallbackString(String callbackId) {
+        return "cordova.callbackSuccess('"+callbackId+"',"+this.getJSONString()+");";
+    }
+
+    @Deprecated // Use sendPluginResult instead of sendJavascript.
+    public String toErrorCallbackString(String callbackId) {
+        return "cordova.callbackError('"+callbackId+"', " + this.getJSONString()+ ");";
+    }
+
+    public static final int MESSAGE_TYPE_STRING = 1;
+    public static final int MESSAGE_TYPE_JSON = 2;
+    public static final int MESSAGE_TYPE_NUMBER = 3;
+    public static final int MESSAGE_TYPE_BOOLEAN = 4;
+    public static final int MESSAGE_TYPE_NULL = 5;
+    public static final int MESSAGE_TYPE_ARRAYBUFFER = 6;
+    // Use BINARYSTRING when your string may contain null characters.
+    // This is required to work around a bug in the platform :(.
+    public static final int MESSAGE_TYPE_BINARYSTRING = 7;
+
+    public static String[] StatusMessages = new String[] {
+        "No result",
+        "OK",
+        "Class not found",
+        "Illegal access",
+        "Instantiation error",
+        "Malformed url",
+        "IO error",
+        "Invalid action",
+        "JSON error",
+        "Error"
+    };
+
+    public enum Status {
+        NO_RESULT,
+        OK,
+        CLASS_NOT_FOUND_EXCEPTION,
+        ILLEGAL_ACCESS_EXCEPTION,
+        INSTANTIATION_EXCEPTION,
+        MALFORMED_URL_EXCEPTION,
+        IO_EXCEPTION,
+        INVALID_ACTION,
+        JSON_EXCEPTION,
+        ERROR
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ff14e6/framework/src/org/apache/cordova/api/CallbackContext.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/api/CallbackContext.java b/framework/src/org/apache/cordova/api/CallbackContext.java
index 237d0f4..7eaae7e 100644
--- a/framework/src/org/apache/cordova/api/CallbackContext.java
+++ b/framework/src/org/apache/cordova/api/CallbackContext.java
@@ -18,130 +18,10 @@
 */
 package org.apache.cordova.api;
 
-import org.json.JSONArray;
-
-import android.util.Log;
-
 import org.apache.cordova.CordovaWebView;
-import org.json.JSONObject;
-
-public class CallbackContext {
-    private static final String LOG_TAG = "CordovaPlugin";
-
-    private String callbackId;
-    private CordovaWebView webView;
-    private boolean finished;
-    private int changingThreads;
 
+public class CallbackContext extends org.apache.cordova.CallbackContext {
     public CallbackContext(String callbackId, CordovaWebView webView) {
-        this.callbackId = callbackId;
-        this.webView = webView;
-    }
-    
-    public boolean isFinished() {
-        return finished;
-    }
-    
-    public boolean isChangingThreads() {
-        return changingThreads > 0;
-    }
-    
-    public String getCallbackId() {
-        return callbackId;
-    }
-
-    public void sendPluginResult(PluginResult pluginResult) {
-        synchronized (this) {
-            if (finished) {
-                Log.w(LOG_TAG, "Attempted to send a second callback for ID: " + callbackId + "\nResult was: " + pluginResult.getMessage());
-                return;
-            } else {
-                finished = !pluginResult.getKeepCallback();
-            }
-        }
-        webView.sendPluginResult(pluginResult, callbackId);
-    }
-
-    /**
-     * Helper for success callbacks that just returns the Status.OK by default
-     *
-     * @param message           The message to add to the success result.
-     */
-    public void success(JSONObject message) {
-        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
-    }
-
-    /**
-     * Helper for success callbacks that just returns the Status.OK by default
-     *
-     * @param message           The message to add to the success result.
-     */
-    public void success(String message) {
-        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
-    }
-
-    /**
-     * Helper for success callbacks that just returns the Status.OK by default
-     *
-     * @param message           The message to add to the success result.
-     */
-    public void success(JSONArray message) {
-        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
-    }
-
-    /**
-     * Helper for success callbacks that just returns the Status.OK by default
-     *
-     * @param message           The message to add to the success result.
-     */
-    public void success(byte[] message) {
-        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
-    }
-    
-    /**
-     * Helper for success callbacks that just returns the Status.OK by default
-     *
-     * @param message           The message to add to the success result.
-     */
-    public void success(int message) {
-        sendPluginResult(new PluginResult(PluginResult.Status.OK, message));
-    }
-
-    /**
-     * Helper for success callbacks that just returns the Status.OK by default
-     *
-     * @param message           The message to add to the success result.
-     */
-    public void success() {
-        sendPluginResult(new PluginResult(PluginResult.Status.OK));
-    }
-
-    /**
-     * Helper for error callbacks that just returns the Status.ERROR by default
-     *
-     * @param message           The message to add to the error result.
-     */
-    public void error(JSONObject message) {
-        sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
-    }
-
-    /**
-     * Helper for error callbacks that just returns the Status.ERROR by default
-     *
-     * @param message           The message to add to the error result.
-     * @param callbackId        The callback id used when calling back into JavaScript.
-     */
-    public void error(String message) {
-        sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
-    }
-
-    /**
-     * Helper for error callbacks that just returns the Status.ERROR by default
-     *
-     * @param message           The message to add to the error result.
-     * @param callbackId        The callback id used when calling back into JavaScript.
-     */
-    public void error(int message) {
-        sendPluginResult(new PluginResult(PluginResult.Status.ERROR, message));
+        super(callbackId, webView);
     }
 }

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ff14e6/framework/src/org/apache/cordova/api/CordovaInterface.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/api/CordovaInterface.java b/framework/src/org/apache/cordova/api/CordovaInterface.java
index 8ef8ed0..40b584b 100755
--- a/framework/src/org/apache/cordova/api/CordovaInterface.java
+++ b/framework/src/org/apache/cordova/api/CordovaInterface.java
@@ -18,53 +18,9 @@
 */
 package org.apache.cordova.api;
 
-import android.app.Activity;
-import android.content.Intent;
-
-import java.util.concurrent.ExecutorService;
-
 /**
  * The Activity interface that is implemented by CordovaActivity.
  * It is used to isolate plugin development, and remove dependency on entire Cordova library.
  */
-public interface CordovaInterface {
-
-    /**
-     * Launch an activity for which you would like a result when it finished. When this activity exits,
-     * your onActivityResult() method will be called.
-     *
-     * @param command     The command object
-     * @param intent      The intent to start
-     * @param requestCode   The request code that is passed to callback to identify the activity
-     */
-    abstract public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode);
-
-    /**
-     * Set the plugin to be called when a sub-activity exits.
-     *
-     * @param plugin      The plugin on which onActivityResult is to be called
-     */
-    abstract public void setActivityResultCallback(CordovaPlugin plugin);
-
-    /**
-     * Get the Android activity.
-     *
-     * @return
-     */
-    public abstract Activity getActivity();
-    
-
-    /**
-     * Called when a message is sent to plugin.
-     *
-     * @param id            The message id
-     * @param data          The message data
-     * @return              Object or null
-     */
-    public Object onMessage(String id, Object data);
-    
-    /**
-     * Returns a shared thread pool that can be used for background tasks.
-     */
-    public ExecutorService getThreadPool();
+public interface CordovaInterface extends org.apache.cordova.CordovaInterface {
 }

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ff14e6/framework/src/org/apache/cordova/api/CordovaPlugin.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/api/CordovaPlugin.java b/framework/src/org/apache/cordova/api/CordovaPlugin.java
index 07035e5..5830ed7 100644
--- a/framework/src/org/apache/cordova/api/CordovaPlugin.java
+++ b/framework/src/org/apache/cordova/api/CordovaPlugin.java
@@ -18,165 +18,5 @@
 */
 package org.apache.cordova.api;
 
-import org.apache.cordova.CordovaArgs;
-import org.apache.cordova.CordovaWebView;
-import org.apache.cordova.UriResolver;
-import org.json.JSONArray;
-import org.json.JSONException;
-
-import android.content.Intent;
-import android.net.Uri;
-
-/**
- * Plugins must extend this class and override one of the execute methods.
- */
-public class CordovaPlugin {
-    public String id;
-    public CordovaWebView webView;					// WebView object
-    public CordovaInterface cordova;
-
-    /**
-     * @param cordova The context of the main Activity.
-     * @param webView The associated CordovaWebView.
-     */
-    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
-        assert this.cordova == null;
-        this.cordova = cordova;
-        this.webView = webView;
-    }
-
-    /**
-     * Executes the request.
-     *
-     * This method is called from the WebView thread. To do a non-trivial amount of work, use:
-     *     cordova.getThreadPool().execute(runnable);
-     *
-     * To run on the UI thread, use:
-     *     cordova.getActivity().runOnUiThread(runnable);
-     *
-     * @param action          The action to execute.
-     * @param rawArgs         The exec() arguments in JSON form.
-     * @param callbackContext The callback context used when calling back into JavaScript.
-     * @return                Whether the action was valid.
-     */
-    public boolean execute(String action, String rawArgs, CallbackContext callbackContext) throws JSONException {
-        JSONArray args = new JSONArray(rawArgs);
-        return execute(action, args, callbackContext);
-    }
-
-    /**
-     * Executes the request.
-     *
-     * This method is called from the WebView thread. To do a non-trivial amount of work, use:
-     *     cordova.getThreadPool().execute(runnable);
-     *
-     * To run on the UI thread, use:
-     *     cordova.getActivity().runOnUiThread(runnable);
-     *
-     * @param action          The action to execute.
-     * @param args            The exec() arguments.
-     * @param callbackContext The callback context used when calling back into JavaScript.
-     * @return                Whether the action was valid.
-     */
-    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
-        CordovaArgs cordovaArgs = new CordovaArgs(args);
-        return execute(action, cordovaArgs, callbackContext);
-    }
-
-    /**
-     * Executes the request.
-     *
-     * This method is called from the WebView thread. To do a non-trivial amount of work, use:
-     *     cordova.getThreadPool().execute(runnable);
-     *
-     * To run on the UI thread, use:
-     *     cordova.getActivity().runOnUiThread(runnable);
-     *
-     * @param action          The action to execute.
-     * @param args            The exec() arguments, wrapped with some Cordova helpers.
-     * @param callbackContext The callback context used when calling back into JavaScript.
-     * @return                Whether the action was valid.
-     */
-    public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
-        return false;
-    }
-
-    /**
-     * Called when the system is about to start resuming a previous activity.
-     *
-     * @param multitasking		Flag indicating if multitasking is turned on for app
-     */
-    public void onPause(boolean multitasking) {
-    }
-
-    /**
-     * Called when the activity will start interacting with the user.
-     *
-     * @param multitasking		Flag indicating if multitasking is turned on for app
-     */
-    public void onResume(boolean multitasking) {
-    }
-
-    /**
-     * Called when the activity receives a new intent.
-     */
-    public void onNewIntent(Intent intent) {
-    }
-
-    /**
-     * The final call you receive before your activity is destroyed.
-     */
-    public void onDestroy() {
-    }
-
-    /**
-     * Called when a message is sent to plugin.
-     *
-     * @param id            The message id
-     * @param data          The message data
-     * @return              Object to stop propagation or null
-     */
-    public Object onMessage(String id, Object data) {
-        return null;
-    }
-
-    /**
-     * Called when an activity you launched exits, giving you the requestCode you started it with,
-     * the resultCode it returned, and any additional data from it.
-     *
-     * @param requestCode		The request code originally supplied to startActivityForResult(),
-     * 							allowing you to identify who this result came from.
-     * @param resultCode		The integer result code returned by the child activity through its setResult().
-     * @param data				An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
-     */
-    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
-    }
-
-    /**
-     * By specifying a <url-filter> in config.xml you can map a URL (using startsWith atm) to this method.
-     *
-     * @param url				The URL that is trying to be loaded in the Cordova webview.
-     * @return					Return true to prevent the URL from loading. Default is false.
-     */
-    public boolean onOverrideUrlLoading(String url) {
-        return false;
-    }
-
-    /**
-     * Hook for overriding the default URI handling mechanism.
-     * Applies to WebView requests as well as requests made by plugins.
-     */
-    public UriResolver resolveUri(Uri uri) {
-        return null;
-    }
-
-    /**
-     * Called when the WebView does a top-level navigation or refreshes.
-     *
-     * Plugins should stop any long-running processes and clean up internal state.
-     *
-     * Does nothing by default.
-     */
-    public void onReset() {
-    }
+public class CordovaPlugin extends org.apache.cordova.CordovaPlugin {
 }

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ff14e6/framework/src/org/apache/cordova/api/LOG.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/api/LOG.java b/framework/src/org/apache/cordova/api/LOG.java
index 91f035b..57972d7 100755
--- a/framework/src/org/apache/cordova/api/LOG.java
+++ b/framework/src/org/apache/cordova/api/LOG.java
@@ -18,217 +18,5 @@
 */
 package org.apache.cordova.api;
 
-import android.util.Log;
-
-/**
- * Log to Android logging system.
- *
- * Log message can be a string or a printf formatted string with arguments.
- * See http://developer.android.com/reference/java/util/Formatter.html
- */
-public class LOG {
-
-    public static final int VERBOSE = Log.VERBOSE;
-    public static final int DEBUG = Log.DEBUG;
-    public static final int INFO = Log.INFO;
-    public static final int WARN = Log.WARN;
-    public static final int ERROR = Log.ERROR;
-
-    // Current log level
-    public static int LOGLEVEL = Log.ERROR;
-
-    /**
-     * Set the current log level.
-     *
-     * @param logLevel
-     */
-    public static void setLogLevel(int logLevel) {
-        LOGLEVEL = logLevel;
-        Log.i("CordovaLog", "Changing log level to " + logLevel);
-    }
-
-    /**
-     * Set the current log level.
-     *
-     * @param logLevel
-     */
-    public static void setLogLevel(String logLevel) {
-        if ("VERBOSE".equals(logLevel)) LOGLEVEL = VERBOSE;
-        else if ("DEBUG".equals(logLevel)) LOGLEVEL = DEBUG;
-        else if ("INFO".equals(logLevel)) LOGLEVEL = INFO;
-        else if ("WARN".equals(logLevel)) LOGLEVEL = WARN;
-        else if ("ERROR".equals(logLevel)) LOGLEVEL = ERROR;
-        Log.i("CordovaLog", "Changing log level to " + logLevel + "(" + LOGLEVEL + ")");
-    }
-
-    /**
-     * Determine if log level will be logged
-     *
-     * @param logLevel
-     * @return
-     */
-    public static boolean isLoggable(int logLevel) {
-        return (logLevel >= LOGLEVEL);
-    }
-
-    /**
-     * Verbose log message.
-     *
-     * @param tag
-     * @param s
-     */
-    public static void v(String tag, String s) {
-        if (LOG.VERBOSE >= LOGLEVEL) Log.v(tag, s);
-    }
-
-    /**
-     * Debug log message.
-     *
-     * @param tag
-     * @param s
-     */
-    public static void d(String tag, String s) {
-        if (LOG.DEBUG >= LOGLEVEL) Log.d(tag, s);
-    }
-
-    /**
-     * Info log message.
-     *
-     * @param tag
-     * @param s
-     */
-    public static void i(String tag, String s) {
-        if (LOG.INFO >= LOGLEVEL) Log.i(tag, s);
-    }
-
-    /**
-     * Warning log message.
-     *
-     * @param tag
-     * @param s
-     */
-    public static void w(String tag, String s) {
-        if (LOG.WARN >= LOGLEVEL) Log.w(tag, s);
-    }
-
-    /**
-     * Error log message.
-     *
-     * @param tag
-     * @param s
-     */
-    public static void e(String tag, String s) {
-        if (LOG.ERROR >= LOGLEVEL) Log.e(tag, s);
-    }
-
-    /**
-     * Verbose log message.
-     *
-     * @param tag
-     * @param s
-     * @param e
-     */
-    public static void v(String tag, String s, Throwable e) {
-        if (LOG.VERBOSE >= LOGLEVEL) Log.v(tag, s, e);
-    }
-
-    /**
-     * Debug log message.
-     *
-     * @param tag
-     * @param s
-     * @param e
-     */
-    public static void d(String tag, String s, Throwable e) {
-        if (LOG.DEBUG >= LOGLEVEL) Log.d(tag, s, e);
-    }
-
-    /**
-     * Info log message.
-     *
-     * @param tag
-     * @param s
-     * @param e
-     */
-    public static void i(String tag, String s, Throwable e) {
-        if (LOG.INFO >= LOGLEVEL) Log.i(tag, s, e);
-    }
-
-    /**
-     * Warning log message.
-     *
-     * @param tag
-     * @param s
-     * @param e
-     */
-    public static void w(String tag, String s, Throwable e) {
-        if (LOG.WARN >= LOGLEVEL) Log.w(tag, s, e);
-    }
-
-    /**
-     * Error log message.
-     *
-     * @param tag
-     * @param s
-     * @param e
-     */
-    public static void e(String tag, String s, Throwable e) {
-        if (LOG.ERROR >= LOGLEVEL) Log.e(tag, s, e);
-    }
-
-    /**
-     * Verbose log message with printf formatting.
-     *
-     * @param tag
-     * @param s
-     * @param args
-     */
-    public static void v(String tag, String s, Object... args) {
-        if (LOG.VERBOSE >= LOGLEVEL) Log.v(tag, String.format(s, args));
-    }
-
-    /**
-     * Debug log message with printf formatting.
-     *
-     * @param tag
-     * @param s
-     * @param args
-     */
-    public static void d(String tag, String s, Object... args) {
-        if (LOG.DEBUG >= LOGLEVEL) Log.d(tag, String.format(s, args));
-    }
-
-    /**
-     * Info log message with printf formatting.
-     *
-     * @param tag
-     * @param s
-     * @param args
-     */
-    public static void i(String tag, String s, Object... args) {
-        if (LOG.INFO >= LOGLEVEL) Log.i(tag, String.format(s, args));
-    }
-
-    /**
-     * Warning log message with printf formatting.
-     *
-     * @param tag
-     * @param s
-     * @param args
-     */
-    public static void w(String tag, String s, Object... args) {
-        if (LOG.WARN >= LOGLEVEL) Log.w(tag, String.format(s, args));
-    }
-
-    /**
-     * Error log message with printf formatting.
-     *
-     * @param tag
-     * @param s
-     * @param args
-     */
-    public static void e(String tag, String s, Object... args) {
-        if (LOG.ERROR >= LOGLEVEL) Log.e(tag, String.format(s, args));
-    }
-
+public class LOG extends org.apache.cordova.LOG {
 }

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/04ff14e6/framework/src/org/apache/cordova/api/PluginEntry.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/api/PluginEntry.java b/framework/src/org/apache/cordova/api/PluginEntry.java
index f66dcda..0f6c11d 100755
--- a/framework/src/org/apache/cordova/api/PluginEntry.java
+++ b/framework/src/org/apache/cordova/api/PluginEntry.java
@@ -18,113 +18,12 @@
  */
 package org.apache.cordova.api;
 
-import org.apache.cordova.CordovaWebView;
-
-//import android.content.Context;
-//import android.webkit.WebView;
-
-/**
- * This class represents a service entry object.
- */
-public class PluginEntry {
-
-    /**
-     * The name of the service that this plugin implements
-     */
-    public String service = "";
-
-    /**
-     * The plugin class name that implements the service.
-     */
-    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.
-     */
-    public CordovaPlugin plugin = null;
-
-    /**
-     * Flag that indicates the plugin object should be created when PluginManager is initialized.
-     */
-    public boolean onload = false;
-
-    /**
-     * Constructor
-     *
-     * @param service               The name of the service
-     * @param pluginClass           The plugin class name
-     * @param onload                Create plugin object when HTML page is loaded
-     */
+public class PluginEntry extends org.apache.cordova.PluginEntry {
     public PluginEntry(String service, String pluginClass, boolean onload) {
-        this.service = service;
-        this.pluginClass = pluginClass;
-        this.onload = onload;
+        super(service, pluginClass, 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.
-     * 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 {
-            @SuppressWarnings("rawtypes")
-            Class c = getClassByName(this.pluginClass);
-            if (isCordovaPlugin(c)) {
-                this.plugin = (CordovaPlugin) c.newInstance();
-                this.plugin.initialize(ctx, webView);
-                return plugin;
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-            System.out.println("Error adding plugin " + this.pluginClass + ".");
-        }
-        return null;
-    }
-
-    /**
-     * Get the class.
-     *
-     * @param clazz
-     * @return
-     * @throws ClassNotFoundException
-     */
-    @SuppressWarnings("rawtypes")
-    private Class getClassByName(final String clazz) throws ClassNotFoundException {
-        Class c = null;
-        if (clazz != null) {
-            c = Class.forName(clazz);
-        }
-        return c;
-    }
-
-    /**
-     * Returns whether the given class extends CordovaPlugin.
-     */
-    @SuppressWarnings("rawtypes")
-    private boolean isCordovaPlugin(Class c) {
-        if (c != null) {
-            return org.apache.cordova.api.CordovaPlugin.class.isAssignableFrom(c);
-        }
-        return false;
+        super(service, plugin);
     }
 }