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

[4/4] git commit: 2.5.0rc1 (2.5.0 in package.json). Removed old test related to webworks scripts. Updated lbiraries to 2.5.0rc1. Added a VERSION file.

Updated Branches:
  refs/heads/next [created] 2bb8baca8


2.5.0rc1 (2.5.0 in package.json). Removed old test related to webworks scripts. Updated lbiraries to 2.5.0rc1. Added a VERSION file.


Project: http://git-wip-us.apache.org/repos/asf/cordova-cli/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-cli/commit/2bb8baca
Tree: http://git-wip-us.apache.org/repos/asf/cordova-cli/tree/2bb8baca
Diff: http://git-wip-us.apache.org/repos/asf/cordova-cli/diff/2bb8baca

Branch: refs/heads/next
Commit: 2bb8baca8d8707f76b91ddb6696abfaa82985738
Parents: c687ba1
Author: Fil Maj <ma...@gmail.com>
Authored: Thu Feb 21 11:43:23 2013 -0800
Committer: Fil Maj <ma...@gmail.com>
Committed: Thu Feb 21 11:43:23 2013 -0800

----------------------------------------------------------------------
 VERSION                                            |    1 +
 lib/cordova-android/README.md                      |    4 +-
 lib/cordova-android/VERSION                        |    2 +-
 lib/cordova-android/bin/create                     |    7 +
 .../bin/templates/cordova/appinfo.jar              |  Bin 1574 -> 1574 bytes
 .../bin/templates/project/assets/www/index.html    |    2 +-
 .../framework/assets/js/cordova.android.js         |  633 ++++++---------
 .../framework/assets/www/index.html                |    2 +-
 lib/cordova-android/framework/project.properties   |    2 +-
 .../src/org/apache/cordova/CameraLauncher.java     |    9 +-
 .../src/org/apache/cordova/ContactAccessor.java    |    1 -
 .../org/apache/cordova/ContactAccessorSdk5.java    |    3 +-
 .../org/apache/cordova/CordovaChromeClient.java    |    2 -
 .../src/org/apache/cordova/CordovaWebView.java     |   38 +-
 .../framework/src/org/apache/cordova/Device.java   |    3 +-
 .../framework/src/org/apache/cordova/DroidGap.java |    1 -
 .../src/org/apache/cordova/ExposedJsApi.java       |    1 -
 .../src/org/apache/cordova/FileTransfer.java       |  119 ++--
 .../src/org/apache/cordova/FileUtils.java          |   68 +-
 .../src/org/apache/cordova/InAppBrowser.java       |   52 ++-
 .../framework/src/org/apache/cordova/Storage.java  |    1 -
 .../org/apache/cordova/api/CordovaInterface.java   |    1 -
 .../src/org/apache/cordova/api/PluginManager.java  |    4 -
 lib/cordova-android/test/res/xml/config.xml        |    3 +-
 .../org/apache/cordova/test/ActivityPlugin.java    |   26 +-
 lib/cordova-blackberry/README.md                   |    8 +-
 lib/cordova-blackberry/VERSION                     |    2 +-
 .../project/lib/ant-contrib/ant-contrib-1.0b3.jar  |  Bin 0 -> 224277 bytes
 .../bin/templates/project/www/VERSION              |    2 +-
 .../bin/templates/project/www/index.html           |    2 +-
 .../ext/src/org/apache/cordova/device/Device.java  |    2 +-
 .../javascript/cordova.blackberry.js               |  550 +++++++------
 .../CordovaLib/Classes/CDVAvailability.h           |    3 +-
 lib/cordova-ios/CordovaLib/Classes/CDVCamera.m     |  100 ++--
 lib/cordova-ios/CordovaLib/Classes/CDVCapture.m    |    1 -
 .../CordovaLib/Classes/CDVCommandDelegate.h        |    5 +
 .../CordovaLib/Classes/CDVCommandDelegateImpl.m    |   11 +
 .../CordovaLib/Classes/CDVConfigParser.h           |    3 +-
 .../CordovaLib/Classes/CDVConfigParser.m           |   31 +-
 lib/cordova-ios/CordovaLib/Classes/CDVDevice.m     |    1 +
 lib/cordova-ios/CordovaLib/Classes/CDVFile.m       |  301 +++++---
 .../CordovaLib/Classes/CDVFileTransfer.h           |    4 +-
 .../CordovaLib/Classes/CDVFileTransfer.m           |   99 ++-
 .../CordovaLib/Classes/CDVInAppBrowser.m           |   21 +-
 .../CordovaLib/Classes/CDVLocalStorage.h           |    2 +-
 .../CordovaLib/Classes/CDVLocalStorage.m           |   48 +-
 lib/cordova-ios/CordovaLib/Classes/CDVLocation.m   |   14 +-
 lib/cordova-ios/CordovaLib/Classes/CDVPlugin.h     |    4 +-
 lib/cordova-ios/CordovaLib/Classes/CDVPlugin.m     |   51 +-
 lib/cordova-ios/CordovaLib/Classes/CDVSound.h      |    8 +-
 lib/cordova-ios/CordovaLib/Classes/CDVSound.m      |  153 +++-
 .../CordovaLib/Classes/CDVSplashScreen.h           |    6 +-
 .../CordovaLib/Classes/CDVSplashScreen.m           |  151 ++++-
 .../CordovaLib/Classes/CDVURLProtocol.m            |   83 ++-
 .../CordovaLib/Classes/CDVUserAgentUtil.h          |    2 +-
 .../CordovaLib/Classes/CDVUserAgentUtil.m          |   10 +-
 .../CordovaLib/Classes/CDVViewController.h         |    7 +-
 .../CordovaLib/Classes/CDVViewController.m         |  230 ++-----
 .../CordovaLib/Classes/CDVWebViewDelegate.h        |   37 +
 .../CordovaLib/Classes/CDVWebViewDelegate.m        |  157 ++++
 .../CordovaLib.xcodeproj/project.pbxproj           |   20 +-
 lib/cordova-ios/CordovaLib/VERSION                 |    2 +-
 lib/cordova-ios/CordovaLib/cordova.ios.js          |  497 ++++++------
 .../CordovaLibTests/CordovaLibApp/config.xml       |    6 +-
 lib/cordova-ios/bin/create                         |    8 +-
 .../project/__TESTING__.xcodeproj/project.pbxproj  |   46 +-
 .../project/__TESTING__/Classes/AppDelegate.m      |   10 +
 .../bin/templates/project/__TESTING__/config.xml   |    6 +-
 .../bin/templates/project/cordova/emulate          |   15 +-
 .../guides/Cordova Custom URL Scheme Handling.md   |    4 +-
 package.json                                       |    2 +-
 spec/metadata/blackberry_parser.spec.js            |    5 -
 72 files changed, 2103 insertions(+), 1612 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/VERSION
----------------------------------------------------------------------
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..aa0822f
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+2.5.0rc1

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/README.md
----------------------------------------------------------------------
diff --git a/lib/cordova-android/README.md b/lib/cordova-android/README.md
index cf7e83f..5d2f7de 100755
--- a/lib/cordova-android/README.md
+++ b/lib/cordova-android/README.md
@@ -5,7 +5,7 @@ Cordova Android is an Android application library that allows for Cordova-based
 projects to be built for the Android Platform. Cordova based applications are,
 at the core, applications written with web technology: HTML, CSS and JavaScript. 
 
-Apache Cordova is a project at The Apache Software Foundation (ASF).
+[Apache Cordova](http://cordova.io) is a project at The Apache Software Foundation (ASF).
 
 
 Requires
@@ -23,7 +23,7 @@ Test Requirements
 Building
 ---
 
-To create your cordova.jar, copy the commons codec:
+To create your `cordova.jar` file, copy the commons codec:
 
     mv commons-codec-1.7.jar framework/libs
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/VERSION
----------------------------------------------------------------------
diff --git a/lib/cordova-android/VERSION b/lib/cordova-android/VERSION
index 197c4d5..aa0822f 100644
--- a/lib/cordova-android/VERSION
+++ b/lib/cordova-android/VERSION
@@ -1 +1 @@
-2.4.0
+2.5.0rc1

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/bin/create
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/create b/lib/cordova-android/bin/create
index c92acb4..ea214ac 100755
--- a/lib/cordova-android/bin/create
+++ b/lib/cordova-android/bin/create
@@ -98,6 +98,13 @@ MANIFEST_PATH="$PROJECT_PATH"/AndroidManifest.xml
 TARGET=$("$ANDROID_BIN" list targets | grep id: | tail -1 | cut -f 2 -d ' ' )
 API_LEVEL=$("$ANDROID_BIN" list target | grep "API level:" | tail -n 1 | cut -f 2 -d ':' | tr -d ' ')
 
+# check that build targets exist
+if [ -z "$TARGET" ] || [ -z "$API_LEVEL" ]
+then
+    echo "No Android Targets are installed. Please install at least one via the android SDK"
+    exit 1
+fi
+
 # if this a distribution release no need to build a jar
 if [ ! -e "$BUILD_PATH"/cordova-$VERSION.jar ] && [ -d "$BUILD_PATH"/framework ]
 then

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/bin/templates/cordova/appinfo.jar
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/templates/cordova/appinfo.jar b/lib/cordova-android/bin/templates/cordova/appinfo.jar
index 743a8d6..1a088c5 100644
Binary files a/lib/cordova-android/bin/templates/cordova/appinfo.jar and b/lib/cordova-android/bin/templates/cordova/appinfo.jar differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/bin/templates/project/assets/www/index.html
----------------------------------------------------------------------
diff --git a/lib/cordova-android/bin/templates/project/assets/www/index.html b/lib/cordova-android/bin/templates/project/assets/www/index.html
index a6a5ff3..bc06b24 100644
--- a/lib/cordova-android/bin/templates/project/assets/www/index.html
+++ b/lib/cordova-android/bin/templates/project/assets/www/index.html
@@ -33,7 +33,7 @@
                 <p class="event received">Device is Ready</p>
             </div>
         </div>
-        <script type="text/javascript" src="cordova-2.4.0.js"></script>
+        <script type="text/javascript" src="cordova-2.5.0rc1.js"></script>
         <script type="text/javascript" src="js/index.js"></script>
         <script type="text/javascript">
             app.initialize();

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/assets/js/cordova.android.js
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/assets/js/cordova.android.js b/lib/cordova-android/framework/assets/js/cordova.android.js
index 1eb1ca8..19c9281 100644
--- a/lib/cordova-android/framework/assets/js/cordova.android.js
+++ b/lib/cordova-android/framework/assets/js/cordova.android.js
@@ -1,8 +1,8 @@
 // Platform: android
 
-// commit ac725f6ae0bd655789771e2a40b8d60cb4c8c221
+// commit 521bbd64ed729ca76b6646d25bb01b76ee8a54b5
 
-// File generated at :: Mon Feb 04 2013 10:59:03 GMT-0800 (PST)
+// File generated at :: Wed Feb 20 2013 13:49:25 GMT-0800 (PST)
 
 /*
  Licensed to the Apache Software Foundation (ASF) under one
@@ -399,6 +399,7 @@ function each(objects, func, context) {
 }
 
 function clobber(obj, key, value) {
+    exports.replaceHookForTesting(obj, key);
     obj[key] = value;
     // Getters can only be overridden by getters.
     if (obj[key] !== value) {
@@ -482,19 +483,18 @@ function recursiveMerge(target, src) {
     }
 }
 
-module.exports = {
-    buildIntoButDoNotClobber: function(objects, target) {
-        include(target, objects, false, false);
-    },
-    buildIntoAndClobber: function(objects, target) {
-        include(target, objects, true, false);
-    },
-    buildIntoAndMerge: function(objects, target) {
-        include(target, objects, true, true);
-    },
-    recursiveMerge: recursiveMerge,
-    assignOrWrapInDeprecateGetter: assignOrWrapInDeprecateGetter
+exports.buildIntoButDoNotClobber = function(objects, target) {
+    include(target, objects, false, false);
 };
+exports.buildIntoAndClobber = function(objects, target) {
+    include(target, objects, true, false);
+};
+exports.buildIntoAndMerge = function(objects, target) {
+    include(target, objects, true, true);
+};
+exports.recursiveMerge = recursiveMerge;
+exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
+exports.replaceHookForTesting = function() {};
 
 });
 
@@ -774,176 +774,6 @@ module.exports = {
 };
 });
 
-// file: lib/common/common.js
-define("cordova/common", function(require, exports, module) {
-
-module.exports = {
-    defaults: {
-        cordova: {
-            path: 'cordova',
-            children: {
-                exec: {
-                    path: 'cordova/exec'
-                },
-                logger: {
-                    path: 'cordova/plugin/logger'
-                }
-            }
-        },
-        Cordova: {
-            children: {
-                exec: {
-                    path: 'cordova/exec'
-                }
-            }
-        },
-        open : {
-            path: 'cordova/plugin/InAppBrowser'
-        },
-        navigator: {
-            children: {
-                notification: {
-                    path: 'cordova/plugin/notification'
-                },
-                accelerometer: {
-                    path: 'cordova/plugin/accelerometer'
-                },
-                battery: {
-                    path: 'cordova/plugin/battery'
-                },
-                camera:{
-                    path: 'cordova/plugin/Camera'
-                },
-                compass:{
-                    path: 'cordova/plugin/compass'
-                },
-                contacts: {
-                    path: 'cordova/plugin/contacts'
-                },
-                device:{
-                    children:{
-                        capture: {
-                            path: 'cordova/plugin/capture'
-                        }
-                    }
-                },
-                geolocation: {
-                    path: 'cordova/plugin/geolocation'
-                },
-                globalization: {
-                    path: 'cordova/plugin/globalization'
-                },
-                network: {
-                    children: {
-                        connection: {
-                            path: 'cordova/plugin/network',
-                            deprecated: 'navigator.network.connection is deprecated. Use navigator.connection instead.'
-                        }
-                    }
-                },
-                splashscreen: {
-                    path: 'cordova/plugin/splashscreen'
-                }
-            }
-        },
-        Acceleration: {
-            path: 'cordova/plugin/Acceleration'
-        },
-        Camera:{
-            path: 'cordova/plugin/CameraConstants'
-        },
-        CameraPopoverOptions: {
-            path: 'cordova/plugin/CameraPopoverOptions'
-        },
-        CaptureError: {
-            path: 'cordova/plugin/CaptureError'
-        },
-        CaptureAudioOptions:{
-            path: 'cordova/plugin/CaptureAudioOptions'
-        },
-        CaptureImageOptions: {
-            path: 'cordova/plugin/CaptureImageOptions'
-        },
-        CaptureVideoOptions: {
-            path: 'cordova/plugin/CaptureVideoOptions'
-        },
-        CompassHeading:{
-            path: 'cordova/plugin/CompassHeading'
-        },
-        CompassError:{
-            path: 'cordova/plugin/CompassError'
-        },
-        ConfigurationData: {
-            path: 'cordova/plugin/ConfigurationData'
-        },
-        Connection: {
-            path: 'cordova/plugin/Connection'
-        },
-        Contact: {
-            path: 'cordova/plugin/Contact'
-        },
-        ContactAddress: {
-            path: 'cordova/plugin/ContactAddress'
-        },
-        ContactError: {
-            path: 'cordova/plugin/ContactError'
-        },
-        ContactField: {
-            path: 'cordova/plugin/ContactField'
-        },
-        ContactFindOptions: {
-            path: 'cordova/plugin/ContactFindOptions'
-        },
-        ContactName: {
-            path: 'cordova/plugin/ContactName'
-        },
-        ContactOrganization: {
-            path: 'cordova/plugin/ContactOrganization'
-        },
-        Coordinates: {
-            path: 'cordova/plugin/Coordinates'
-        },
-        device: {
-            path: 'cordova/plugin/device'
-        },
-        GlobalizationError: {
-            path: 'cordova/plugin/GlobalizationError'
-        },
-        Media: {
-            path: 'cordova/plugin/Media'
-        },
-        MediaError: {
-            path: 'cordova/plugin/MediaError'
-        },
-        MediaFile: {
-            path: 'cordova/plugin/MediaFile'
-        },
-        MediaFileData:{
-            path: 'cordova/plugin/MediaFileData'
-        },
-        Position: {
-            path: 'cordova/plugin/Position'
-        },
-        PositionError: {
-            path: 'cordova/plugin/PositionError'
-        },
-        ProgressEvent: {
-            path: 'cordova/plugin/ProgressEvent'
-        }
-    },
-    clobbers: {
-        navigator: {
-            children: {
-                connection: {
-                    path: 'cordova/plugin/network'
-                }
-            }
-        }
-    }
-};
-
-});
-
 // file: lib/android/exec.js
 define("cordova/exec", function(require, exports, module) {
 
@@ -1222,9 +1052,9 @@ function prepareNamespace(symbolPath, context) {
     var parts = symbolPath.split('.');
     var cur = context;
     for (var i = 0, part; part = parts[i]; ++i) {
-        cur[part] = cur[part] || {};
+        cur = cur[part] = cur[part] || {};
     }
-    return cur[parts[i-1]];
+    return cur;
 }
 
 exports.mapModules = function(context) {
@@ -1246,7 +1076,7 @@ exports.mapModules = function(context) {
         if (strategy == 'm' && target) {
             builder.recursiveMerge(target, module);
         } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
-            if (target) {
+            if (!(symbolPath in origSymbols)) {
                 origSymbols[symbolPath] = target;
             }
             builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
@@ -1292,6 +1122,8 @@ module.exports = {
             modulemapper = require('cordova/modulemapper');
 
         modulemapper.loadMatchingModules(/cordova.*\/symbols$/);
+        modulemapper.clobbers('cordova/plugin/android/app', 'navigator.app');
+
         modulemapper.mapModules(window);
 
         // Inject a listener for the backbutton on the document.
@@ -1306,88 +1138,11 @@ module.exports = {
         cordova.addDocumentEventHandler('menubutton');
         cordova.addDocumentEventHandler('searchbutton');
 
-        // Figure out if we need to shim-in localStorage and WebSQL
-        // support from the native side.
-        var storage = require('cordova/plugin/android/storage');
-
-        // First patch WebSQL if necessary
-        if (typeof window.openDatabase == 'undefined') {
-            // Not defined, create an openDatabase function for all to use!
-            window.openDatabase = storage.openDatabase;
-        } else {
-            // Defined, but some Android devices will throw a SECURITY_ERR -
-            // so we wrap the whole thing in a try-catch and shim in our own
-            // if the device has Android bug 16175.
-            var originalOpenDatabase = window.openDatabase;
-            window.openDatabase = function(name, version, desc, size) {
-                var db = null;
-                try {
-                    db = originalOpenDatabase(name, version, desc, size);
-                }
-                catch (ex) {
-                    if (ex.code === 18) {
-                        db = null;
-                    } else {
-                        throw ex;
-                    }
-                }
-
-                if (db === null) {
-                    return storage.openDatabase(name, version, desc, size);
-                }
-                else {
-                    return db;
-                }
-
-            };
-        }
-
-        // Patch localStorage if necessary
-        if (typeof window.localStorage == 'undefined' || window.localStorage === null) {
-            window.localStorage = new storage.CupcakeLocalStorage();
-        }
-
         // Let native code know we are all done on the JS side.
         // Native code will then un-hide the WebView.
         channel.join(function() {
             exec(null, null, "App", "show", []);
         }, [channel.onCordovaReady]);
-    },
-    clobbers: {
-        navigator: {
-            children: {
-                app:{
-                    path: "cordova/plugin/android/app"
-                }
-            }
-        },
-        File: { // exists natively on Android WebView, override
-            path: "cordova/plugin/File"
-        },
-        FileReader: { // exists natively on Android WebView, override
-            path: "cordova/plugin/FileReader"
-        },
-        FileError: { //exists natively on Android WebView on Android 4.x
-            path: "cordova/plugin/FileError"
-        },
-        MediaError: { // exists natively on Android WebView on Android 4.x
-            path: "cordova/plugin/MediaError"
-        },
-        open: {
-            path: "cordova/plugin/InAppBrowser"
-        }
-    },
-    merges: {
-        device: {
-            path: 'cordova/plugin/android/device'
-        },
-        navigator: {
-            children: {
-                notification: {
-                    path: 'cordova/plugin/android/notification'
-                }
-            }
-        }
     }
 };
 
@@ -1621,9 +1376,9 @@ module.exports = CompassError;
 define("cordova/plugin/CompassHeading", function(require, exports, module) {
 
 var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
-  this.magneticHeading = magneticHeading || null;
-  this.trueHeading = trueHeading || null;
-  this.headingAccuracy = headingAccuracy || null;
+  this.magneticHeading = magneticHeading;
+  this.trueHeading = trueHeading;
+  this.headingAccuracy = headingAccuracy;
   this.timestamp = timestamp || new Date().getTime();
 };
 
@@ -2996,11 +2751,12 @@ define("cordova/plugin/FileTransferError", function(require, exports, module) {
  * FileTransferError
  * @constructor
  */
-var FileTransferError = function(code, source, target, status) {
+var FileTransferError = function(code, source, target, status, body) {
     this.code = code || null;
     this.source = source || null;
     this.target = target || null;
     this.http_status = status || null;
+    this.body = body || null;
 };
 
 FileTransferError.FILE_NOT_FOUND_ERR = 1;
@@ -3404,8 +3160,6 @@ module.exports = function(strUrl, strWindowName, strWindowFeatures) {
     return iab;
 };
 
-//Export the original open so it can be used if needed
-module.exports._orig = window.open;
 
 });
 
@@ -3976,6 +3730,17 @@ module.exports = accelerometer;
 
 });
 
+// file: lib/common/plugin/accelerometer/symbols.js
+define("cordova/plugin/accelerometer/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.defaults('cordova/plugin/Acceleration', 'Acceleration');
+modulemapper.defaults('cordova/plugin/accelerometer', 'navigator.accelerometer');
+
+});
+
 // file: lib/android/plugin/android/app.js
 define("cordova/plugin/android/app", function(require, exports, module) {
 
@@ -4480,100 +4245,57 @@ var DroidDB_openDatabase = function(name, version, display_name, size) {
     return db;
 };
 
-/**
- * For browsers with no localStorage we emulate it with SQLite. Follows the w3c api.
- * TODO: Do similar for sessionStorage.
- * @constructor
- */
-var CupcakeLocalStorage = function() {
-    channel.waitForInitialization("cupcakeStorage");
 
-    try {
+module.exports = {
+  openDatabase:DroidDB_openDatabase,
+  failQuery:failQuery,
+  completeQuery:completeQuery
+};
 
-      this.db = openDatabase('localStorage', '1.0', 'localStorage', 2621440);
-      var storage = {};
-      this.length = 0;
-      function setLength (length) {
-        this.length = length;
-        localStorage.length = length;
-      }
-      this.db.transaction(
-        function (transaction) {
-            var i;
-          transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))');
-          transaction.executeSql('SELECT * FROM storage', [], function(tx, result) {
-            for(var i = 0; i < result.rows.length; i++) {
-              storage[result.rows.item(i).id] =  result.rows.item(i).body;
-            }
-            setLength(result.rows.length);
-            channel.initializationComplete("cupcakeStorage");
-          });
+});
 
-        },
-        function (err) {
-          utils.alert(err.message);
-        }
-      );
-      this.setItem = function(key, val) {
-        if (typeof(storage[key])=='undefined') {
-          this.length++;
-        }
-        storage[key] = val;
-        this.db.transaction(
-          function (transaction) {
-            transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))');
-            transaction.executeSql('REPLACE INTO storage (id, body) values(?,?)', [key,val]);
-          }
-        );
-      };
-      this.getItem = function(key) {
-        return storage[key];
-      };
-      this.removeItem = function(key) {
-        delete storage[key];
-        this.length--;
-        this.db.transaction(
-          function (transaction) {
-            transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))');
-            transaction.executeSql('DELETE FROM storage where id=?', [key]);
-          }
-        );
-      };
-      this.clear = function() {
-        storage = {};
-        this.length = 0;
-        this.db.transaction(
-          function (transaction) {
-            transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))');
-            transaction.executeSql('DELETE FROM storage', []);
-          }
-        );
-      };
-      this.key = function(index) {
-        var i = 0;
-        for (var j in storage) {
-          if (i==index) {
-            return j;
-          } else {
-            i++;
-          }
-        }
-        return null;
-      };
+// file: lib/android/plugin/android/storage/openDatabase.js
+define("cordova/plugin/android/storage/openDatabase", function(require, exports, module) {
 
-    } catch(e) {
-          utils.alert("Database error "+e+".");
-        return;
+
+var modulemapper = require('cordova/modulemapper'),
+    storage = require('cordova/plugin/android/storage');
+
+var originalOpenDatabase = modulemapper.getOriginalSymbol(window, 'openDatabase');
+
+module.exports = function(name, version, desc, size) {
+    // First patch WebSQL if necessary
+    if (!originalOpenDatabase) {
+        // Not defined, create an openDatabase function for all to use!
+        return storage.openDatabase.apply(this, arguments);
     }
-};
 
-module.exports = {
-  openDatabase:DroidDB_openDatabase,
-  CupcakeLocalStorage:CupcakeLocalStorage,
-  failQuery:failQuery,
-  completeQuery:completeQuery
+    // Defined, but some Android devices will throw a SECURITY_ERR -
+    // so we wrap the whole thing in a try-catch and shim in our own
+    // if the device has Android bug 16175.
+    try {
+        return originalOpenDatabase(name, version, desc, size);
+    } catch (ex) {
+        if (ex.code !== 18) {
+            throw ex;
+        }
+    }
+    return storage.openDatabase(name, version, desc, size);
 };
 
+
+
+});
+
+// file: lib/android/plugin/android/storage/symbols.js
+define("cordova/plugin/android/storage/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.clobbers('cordova/plugin/android/storage/openDatabase', 'openDatabase');
+
+
 });
 
 // file: lib/common/plugin/battery.js
@@ -4660,6 +4382,28 @@ module.exports = battery;
 
 });
 
+// file: lib/common/plugin/battery/symbols.js
+define("cordova/plugin/battery/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.defaults('cordova/plugin/battery', 'navigator.battery');
+
+});
+
+// file: lib/common/plugin/camera/symbols.js
+define("cordova/plugin/camera/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.defaults('cordova/plugin/Camera', 'navigator.camera');
+modulemapper.defaults('cordova/plugin/CameraConstants', 'Camera');
+modulemapper.defaults('cordova/plugin/CameraPopoverOptions', 'CameraPopoverOptions');
+
+});
+
 // file: lib/common/plugin/capture.js
 define("cordova/plugin/capture", function(require, exports, module) {
 
@@ -4738,6 +4482,22 @@ module.exports = new Capture();
 
 });
 
+// file: lib/common/plugin/capture/symbols.js
+define("cordova/plugin/capture/symbols", function(require, exports, module) {
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.clobbers('cordova/plugin/CaptureError', 'CaptureError');
+modulemapper.clobbers('cordova/plugin/CaptureAudioOptions', 'CaptureAudioOptions');
+modulemapper.clobbers('cordova/plugin/CaptureImageOptions', 'CaptureImageOptions');
+modulemapper.clobbers('cordova/plugin/CaptureVideoOptions', 'CaptureVideoOptions');
+modulemapper.clobbers('cordova/plugin/ConfigurationData', 'ConfigurationData');
+modulemapper.clobbers('cordova/plugin/MediaFile', 'MediaFile');
+modulemapper.clobbers('cordova/plugin/MediaFileData', 'MediaFileData');
+modulemapper.clobbers('cordova/plugin/capture', 'navigator.device.capture');
+
+});
+
 // file: lib/common/plugin/compass.js
 define("cordova/plugin/compass", function(require, exports, module) {
 
@@ -4825,6 +4585,18 @@ module.exports = compass;
 
 });
 
+// file: lib/common/plugin/compass/symbols.js
+define("cordova/plugin/compass/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.clobbers('cordova/plugin/CompassHeading', 'CompassHeading');
+modulemapper.clobbers('cordova/plugin/CompassError', 'CompassError');
+modulemapper.clobbers('cordova/plugin/compass', 'navigator.compass');
+
+});
+
 // file: lib/common/plugin/console-via-logger.js
 define("cordova/plugin/console-via-logger", function(require, exports, module) {
 
@@ -5058,6 +4830,23 @@ module.exports = contacts;
 
 });
 
+// file: lib/common/plugin/contacts/symbols.js
+define("cordova/plugin/contacts/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.clobbers('cordova/plugin/contacts', 'navigator.contacts');
+modulemapper.clobbers('cordova/plugin/Contact', 'Contact');
+modulemapper.clobbers('cordova/plugin/ContactAddress', 'ContactAddress');
+modulemapper.clobbers('cordova/plugin/ContactError', 'ContactError');
+modulemapper.clobbers('cordova/plugin/ContactField', 'ContactField');
+modulemapper.clobbers('cordova/plugin/ContactFindOptions', 'ContactFindOptions');
+modulemapper.clobbers('cordova/plugin/ContactName', 'ContactName');
+modulemapper.clobbers('cordova/plugin/ContactOrganization', 'ContactOrganization');
+
+});
+
 // file: lib/common/plugin/device.js
 define("cordova/plugin/device", function(require, exports, module) {
 
@@ -5117,6 +4906,17 @@ module.exports = new Device();
 
 });
 
+// file: lib/android/plugin/device/symbols.js
+define("cordova/plugin/device/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.clobbers('cordova/plugin/device', 'device');
+modulemapper.merges('cordova/plugin/android/device', 'device');
+
+});
+
 // file: lib/common/plugin/echo.js
 define("cordova/plugin/echo", function(require, exports, module) {
 
@@ -5163,20 +4963,30 @@ module.exports = function(exportFunc) {
     exportFunc('cordova/plugin/FileError', 'FileError');
     exportFunc('cordova/plugin/FileReader', 'FileReader');
     exportFunc('cordova/plugin/FileSystem', 'FileSystem');
-    exportFunc('cordova/plugin/FileTransfer', 'FileTransfer');
-    exportFunc('cordova/plugin/FileTransferError', 'FileTransferError');
     exportFunc('cordova/plugin/FileUploadOptions', 'FileUploadOptions');
     exportFunc('cordova/plugin/FileUploadResult', 'FileUploadResult');
     exportFunc('cordova/plugin/FileWriter', 'FileWriter');
     exportFunc('cordova/plugin/Flags', 'Flags');
     exportFunc('cordova/plugin/LocalFileSystem', 'LocalFileSystem');
     exportFunc('cordova/plugin/Metadata', 'Metadata');
+    exportFunc('cordova/plugin/ProgressEvent', 'ProgressEvent');
     exportFunc('cordova/plugin/requestFileSystem', 'requestFileSystem');
     exportFunc('cordova/plugin/resolveLocalFileSystemURI', 'resolveLocalFileSystemURI');
 };
 
 });
 
+// file: lib/common/plugin/filetransfer/symbols.js
+define("cordova/plugin/filetransfer/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.clobbers('cordova/plugin/FileTransfer', 'FileTransfer');
+modulemapper.clobbers('cordova/plugin/FileTransferError', 'FileTransferError');
+
+});
+
 // file: lib/common/plugin/geolocation.js
 define("cordova/plugin/geolocation", function(require, exports, module) {
 
@@ -5373,6 +5183,19 @@ module.exports = geolocation;
 
 });
 
+// file: lib/common/plugin/geolocation/symbols.js
+define("cordova/plugin/geolocation/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.defaults('cordova/plugin/geolocation', 'navigator.geolocation');
+modulemapper.clobbers('cordova/plugin/PositionError', 'PositionError');
+modulemapper.clobbers('cordova/plugin/Position', 'Position');
+modulemapper.clobbers('cordova/plugin/Coordinates', 'Coordinates');
+
+});
+
 // file: lib/common/plugin/globalization.js
 define("cordova/plugin/globalization", function(require, exports, module) {
 
@@ -5749,6 +5572,27 @@ module.exports = globalization;
 
 });
 
+// file: lib/common/plugin/globalization/symbols.js
+define("cordova/plugin/globalization/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.clobbers('cordova/plugin/globalization', 'navigator.globalization');
+modulemapper.clobbers('cordova/plugin/GlobalizationError', 'GlobalizationError');
+
+});
+
+// file: lib/android/plugin/inappbrowser/symbols.js
+define("cordova/plugin/inappbrowser/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.clobbers('cordova/plugin/InAppBrowser', 'open');
+
+});
+
 // file: lib/common/plugin/logger.js
 define("cordova/plugin/logger", function(require, exports, module) {
 
@@ -5977,6 +5821,27 @@ document.addEventListener("deviceready", logger.__onDeviceReady, false);
 
 });
 
+// file: lib/common/plugin/logger/symbols.js
+define("cordova/plugin/logger/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.clobbers('cordova/plugin/logger', 'cordova.logger');
+
+});
+
+// file: lib/android/plugin/media/symbols.js
+define("cordova/plugin/media/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.defaults('cordova/plugin/Media', 'Media');
+modulemapper.clobbers('cordova/plugin/MediaError', 'MediaError');
+
+});
+
 // file: lib/common/plugin/network.js
 define("cordova/plugin/network", function(require, exports, module) {
 
@@ -6049,6 +5914,18 @@ module.exports = me;
 
 });
 
+// file: lib/common/plugin/networkstatus/symbols.js
+define("cordova/plugin/networkstatus/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.clobbers('cordova/plugin/network', 'navigator.network.connection', 'navigator.network.connection is deprecated. Use navigator.connection instead.');
+modulemapper.clobbers('cordova/plugin/network', 'navigator.connection');
+modulemapper.defaults('cordova/plugin/Connection', 'Connection');
+
+});
+
 // file: lib/common/plugin/notification.js
 define("cordova/plugin/notification", function(require, exports, module) {
 
@@ -6111,6 +5988,17 @@ module.exports = {
 
 });
 
+// file: lib/android/plugin/notification/symbols.js
+define("cordova/plugin/notification/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.clobbers('cordova/plugin/notification', 'navigator.notification');
+modulemapper.merges('cordova/plugin/android/notification', 'navigator.notification');
+
+});
+
 // file: lib/common/plugin/requestFileSystem.js
 define("cordova/plugin/requestFileSystem", function(require, exports, module) {
 
@@ -6224,6 +6112,29 @@ module.exports = splashscreen;
 
 });
 
+// file: lib/common/plugin/splashscreen/symbols.js
+define("cordova/plugin/splashscreen/symbols", function(require, exports, module) {
+
+
+var modulemapper = require('cordova/modulemapper');
+
+modulemapper.clobbers('cordova/plugin/splashscreen', 'navigator.splashscreen');
+
+});
+
+// file: lib/common/symbols.js
+define("cordova/symbols", function(require, exports, module) {
+
+var modulemapper = require('cordova/modulemapper');
+
+// Use merges here in case others symbols files depend on this running first,
+// but fail to declare the dependency with a require().
+modulemapper.merges('cordova', 'cordova');
+modulemapper.clobbers('cordova/exec', 'cordova.exec');
+modulemapper.clobbers('cordova/exec', 'Cordova.exec');
+
+});
+
 // file: lib/common/utils.js
 define("cordova/utils", function(require, exports, module) {
 
@@ -6492,14 +6403,8 @@ window.cordova = require('cordova');
                  */
                 channel.join(function() {
                     var builder = require('cordova/builder'),
-                        base = require('cordova/common'),
                         platform = require('cordova/platform');
 
-                    // Drop the common globals into the window object, but be nice and don't overwrite anything.
-                    builder.buildIntoButDoNotClobber(base.defaults, context);
-                    builder.buildIntoAndClobber(base.clobbers, context);
-                    builder.buildIntoAndMerge(base.merges, context);
-
                     builder.buildIntoButDoNotClobber(platform.defaults, context);
                     builder.buildIntoAndClobber(platform.clobbers, context);
                     builder.buildIntoAndMerge(platform.merges, context);

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/assets/www/index.html
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/assets/www/index.html b/lib/cordova-android/framework/assets/www/index.html
index ffcaf02..209e0b5 100644
--- a/lib/cordova-android/framework/assets/www/index.html
+++ b/lib/cordova-android/framework/assets/www/index.html
@@ -19,7 +19,7 @@
 <html>
   <head>
     <title></title>
-    <script src="cordova-2.4.0.js"></script>
+    <script src="cordova-2.5.0rc1.js"></script>
   </head>
   <body>
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/project.properties
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/project.properties b/lib/cordova-android/framework/project.properties
index 2f39d91..d556741 100644
--- a/lib/cordova-android/framework/project.properties
+++ b/lib/cordova-android/framework/project.properties
@@ -10,7 +10,7 @@
 # Indicates whether an apk should be generated for each density.
 split.density=false
 # Project target.
-target=android-17
+target=Google Inc.:Google APIs:17
 apk-configurations=
 renderscript.opt.level=O0
 android.library=true

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java b/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java
index 3012ee3..aec0def 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/CameraLauncher.java
@@ -58,6 +58,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
 
     private static final int DATA_URL = 0;              // Return base64 encoded string
     private static final int FILE_URI = 1;              // Return file uri (content://media/external/images/media/2 for Android)
+    private static final int NATIVE_URI = 2;			// On Android, this is the same as FILE_URI
 
     private static final int PHOTOLIBRARY = 0;          // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
     private static final int CAMERA = 1;                // Take picture from camera
@@ -310,7 +311,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
                     }
 
                     // If sending filename back
-                    else if (destType == FILE_URI) {
+                    else if (destType == FILE_URI || destType == NATIVE_URI) {
                         if (!this.saveToPhotoAlbum) {
                             uri = Uri.fromFile(new File(DirectoryManager.getTempDirectoryPath(this.cordova.getActivity()), System.currentTimeMillis() + ".jpg"));
                         } else {
@@ -388,9 +389,9 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
                 }
                 else {
                     // This is a special case to just return the path as no scaling,
-                    // rotating or compression needs to be done
+                    // rotating, nor compressing needs to be done
                     if (this.targetHeight == -1 && this.targetWidth == -1 &&
-                            this.mQuality == 100 && destType == FILE_URI && !this.correctOrientation) {
+                            (destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation) {
                         this.callbackContext.success(uri.toString());
                     } else {
                         // Get the path to the image. Makes loading so much easier.
@@ -434,7 +435,7 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
                         }
 
                         // If sending filename back
-                        else if (destType == FILE_URI) {
+                        else if (destType == FILE_URI || destType == NATIVE_URI) {
                             // Do we need to scale the returned file
                             if (this.targetHeight > 0 && this.targetWidth > 0) {
                                 try {

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/ContactAccessor.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/ContactAccessor.java b/lib/cordova-android/framework/src/org/apache/cordova/ContactAccessor.java
index 44bed23..04b4342 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/ContactAccessor.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/ContactAccessor.java
@@ -18,7 +18,6 @@ package org.apache.cordova;
 
 import java.util.HashMap;
 
-import android.content.Context;
 import android.util.Log;
 import android.webkit.WebView;
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/ContactAccessorSdk5.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/ContactAccessorSdk5.java b/lib/cordova-android/framework/src/org/apache/cordova/ContactAccessorSdk5.java
index 3d81648..47336c0 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/ContactAccessorSdk5.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/ContactAccessorSdk5.java
@@ -860,8 +860,7 @@ public class ContactAccessorSdk5 extends ContactAccessor {
             im.put("id", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Im._ID)));
             im.put("pref", false); // Android does not store pref attribute
             im.put("value", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA)));
-            String type = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Im.PROTOCOL));
-            im.put("type", getImType(new Integer(type).intValue()));
+            im.put("type", getImType(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Im.PROTOCOL))));
         } catch (JSONException e) {
             Log.e(LOG_TAG, e.getMessage(), e);
         }

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
index 4b30894..e650781 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/CordovaChromeClient.java
@@ -24,12 +24,10 @@ import org.json.JSONArray;
 import org.json.JSONException;
 
 import android.annotation.TargetApi;
-import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.net.Uri;
-import android.util.Log;
 import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.View;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java b/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
index 44c9299..4731adb 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/CordovaWebView.java
@@ -27,7 +27,6 @@ import java.util.Stack;
 
 import org.apache.cordova.Config;
 import org.apache.cordova.api.CordovaInterface;
-import org.apache.cordova.api.CordovaPlugin;
 import org.apache.cordova.api.LOG;
 import org.apache.cordova.api.PluginManager;
 import org.apache.cordova.api.PluginResult;
@@ -263,6 +262,7 @@ public class CordovaWebView extends WebView {
         settings.setDatabaseEnabled(true);
         String databasePath = this.cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
         settings.setDatabasePath(databasePath);
+        settings.setGeolocationDatabasePath(databasePath);
 
         // Enable DOM storage
         settings.setDomStorageEnabled(true);
@@ -270,6 +270,13 @@ public class CordovaWebView extends WebView {
         // Enable built-in geolocation
         settings.setGeolocationEnabled(true);
         
+        // Enable AppCache
+        // Fix for CB-2282
+        settings.setAppCacheMaxSize(5 * 1048576);
+        String pathToCache = this.cordova.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
+        settings.setAppCachePath(pathToCache);
+        settings.setAppCacheEnabled(true);
+        
         // Fix for CB-1405
         // Google issue 4641
         this.updateUserAgentString();
@@ -554,15 +561,14 @@ public class CordovaWebView extends WebView {
 
         // Check webview first to see if there is a history
         // This is needed to support curPage#diffLink, since they are added to appView's history, but not our history url array (JQMobile behavior)
-        if (super.canGoBack()) {
+        if (super.canGoBack() && this.useBrowserHistory) {
             printBackForwardList();
             super.goBack();
             
             return true;
         }
-
         // If our managed history has prev url
-        if (this.urls.size() > 1 && !this.useBrowserHistory) {
+        else if (this.urls.size() > 1 && !this.useBrowserHistory) {
             this.urls.pop();                // Pop current url
             String url = this.urls.pop();   // Pop prev url that we want to load, since it will be added back by loadUrl()
             this.loadUrl(url);
@@ -578,10 +584,10 @@ public class CordovaWebView extends WebView {
      * @return
      */
     public boolean canGoBack() {
-        if (super.canGoBack()) {
+        if (super.canGoBack() && this.useBrowserHistory) {
             return true;
         }
-        if (this.urls.size() > 1) {
+        else if (this.urls.size() > 1) {
             return true;
         }
         return false;
@@ -749,7 +755,9 @@ public class CordovaWebView extends WebView {
                     // If not, then invoke default behaviour
                     else {
                         //this.activityState = ACTIVITY_EXITING;
-                        return false;
+                    	//return false;
+                    	// If they hit back button when app is initializing, app should exit instead of hang until initilazation (CB2-458)
+                    	this.cordova.getActivity().finish();
                     }
                 }
             }
@@ -847,7 +855,8 @@ public class CordovaWebView extends WebView {
     public void handleDestroy()
     {
         // Send destroy event to JavaScript
-        this.loadUrl("javascript:try{cordova.require('cordova/channel').onDestroy.fire();}catch(e){console.log('exception firing destroy event from native');};");
+    	// Since baseUrl is set in loadUrlIntoView, if user hit Back button before loadUrl was called, we'll get an NPE on baseUrl (CB-2458)
+        this.loadUrlIntoView("javascript:try{cordova.require('cordova/channel').onDestroy.fire();}catch(e){console.log('exception firing destroy event from native');};");
 
         // Load blank page so that JavaScript onunload is called
         this.loadUrl("about:blank");
@@ -910,11 +919,14 @@ public class CordovaWebView extends WebView {
     {
         WebBackForwardList currentList = this.copyBackForwardList();
         WebHistoryItem item = currentList.getItemAtIndex(0);
-        String url = item.getUrl();
-        String currentUrl = this.getUrl();
-        LOG.d(TAG, "The current URL is: " + currentUrl);
-        LOG.d(TAG, "The URL at item 0 is:" + url);
-        return currentUrl.equals(url);
+        if( item!=null){	// Null-fence in case they haven't called loadUrl yet (CB-2458)
+	        String url = item.getUrl();
+	        String currentUrl = this.getUrl();
+	        LOG.d(TAG, "The current URL is: " + currentUrl);
+	        LOG.d(TAG, "The URL at item 0 is:" + url);
+	        return currentUrl.equals(url);
+        }
+        return false;
     }
 
     public void showCustomView(View view, WebChromeClient.CustomViewCallback callback) {

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/Device.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/Device.java b/lib/cordova-android/framework/src/org/apache/cordova/Device.java
index 883fc55..cbf49fd 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/Device.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/Device.java
@@ -24,7 +24,6 @@ import org.apache.cordova.api.CallbackContext;
 import org.apache.cordova.api.CordovaPlugin;
 import org.apache.cordova.api.LOG;
 import org.apache.cordova.api.CordovaInterface;
-import org.apache.cordova.api.PluginResult;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -39,7 +38,7 @@ import android.telephony.TelephonyManager;
 public class Device extends CordovaPlugin {
     public static final String TAG = "Device";
 
-    public static String cordovaVersion = "2.4.0";              // Cordova version
+    public static String cordovaVersion = "2.5.0rc1";              // Cordova version
     public static String platform = "Android";                  // Device OS
     public static String uuid;                                  // Device UUID
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/DroidGap.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/DroidGap.java b/lib/cordova-android/framework/src/org/apache/cordova/DroidGap.java
index ee21eb8..9a7be4e 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/DroidGap.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/DroidGap.java
@@ -51,7 +51,6 @@ import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowManager;
 import android.webkit.ValueCallback;
-import android.webkit.WebView;
 import android.webkit.WebViewClient;
 import android.widget.LinearLayout;
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/ExposedJsApi.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/ExposedJsApi.java b/lib/cordova-android/framework/src/org/apache/cordova/ExposedJsApi.java
index a36bb62..48e7102 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/ExposedJsApi.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/ExposedJsApi.java
@@ -20,7 +20,6 @@ package org.apache.cordova;
 
 import android.webkit.JavascriptInterface;
 import org.apache.cordova.api.PluginManager;
-import org.apache.cordova.api.PluginResult;
 import org.json.JSONException;
 
 /**

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/FileTransfer.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/FileTransfer.java b/lib/cordova-android/framework/src/org/apache/cordova/FileTransfer.java
index 783a71b..623baf8 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/FileTransfer.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/FileTransfer.java
@@ -20,7 +20,6 @@ package org.apache.cordova;
 
 import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
-import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -33,6 +32,7 @@ import java.io.UnsupportedEncodingException;
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.net.URLConnection;
 import java.net.URLDecoder;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
@@ -77,6 +77,7 @@ public class FileTransfer extends CordovaPlugin {
     private static final class RequestContext {
         String source;
         String target;
+        File targetFile;
         CallbackContext callbackContext;
         InputStream currentInputStream;
         OutputStream currentOutputStream;
@@ -200,7 +201,7 @@ public class FileTransfer extends CordovaPlugin {
             callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
             return;
         }
-        final boolean useHttps = url.getProtocol().toLowerCase().equals("https");
+        final boolean useHttps = url.getProtocol().equals("https");
 
         final RequestContext context = new RequestContext(source, target, callbackContext);
         synchronized (activeRequests) {
@@ -258,7 +259,6 @@ public class FileTransfer extends CordovaPlugin {
 
                     // Use a post method.
                     conn.setRequestMethod("POST");
-                    conn.setRequestProperty("Connection", "Keep-Alive");
                     conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);
 
                     // Set the cookies on the response
@@ -291,37 +291,35 @@ public class FileTransfer extends CordovaPlugin {
                         * Store the non-file portions of the multipart data as a string, so that we can add it
                         * to the contentSize, since it is part of the body of the HTTP request.
                         */
-                    String extraParams = "";
+                    StringBuilder beforeData = new StringBuilder();
                     try {
                         for (Iterator<?> iter = params.keys(); iter.hasNext();) {
                             Object key = iter.next();
                             if(!String.valueOf(key).equals("headers"))
                             {
-                              extraParams += LINE_START + BOUNDARY + LINE_END;
-                              extraParams += "Content-Disposition: form-data; name=\"" +  key.toString() + "\";";
-                              extraParams += LINE_END + LINE_END;
-                              extraParams += params.getString(key.toString());
-                              extraParams += LINE_END;
+                              beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END);
+                              beforeData.append("Content-Disposition: form-data; name=\"").append(key.toString()).append('"');
+                              beforeData.append(LINE_END).append(LINE_END);
+                              beforeData.append(params.getString(key.toString()));
+                              beforeData.append(LINE_END);
                             }
                         }
                     } catch (JSONException e) {
                         Log.e(LOG_TAG, e.getMessage(), e);
                     }
 
-                    extraParams += LINE_START + BOUNDARY + LINE_END;
-                    extraParams += "Content-Disposition: form-data; name=\"" + fileKey + "\";" + " filename=\"";
-                    byte[] extraBytes = extraParams.getBytes("UTF-8");
-
-                    String midParams = "\"" + LINE_END + "Content-Type: " + mimeType + LINE_END + LINE_END;
-                    String tailParams = LINE_END + LINE_START + BOUNDARY + LINE_START + LINE_END;
-                    byte[] fileNameBytes = fileName.getBytes("UTF-8");
+                    beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END);
+                    beforeData.append("Content-Disposition: form-data; name=\"").append(fileKey).append("\";");
+                    beforeData.append(" filename=\"").append(fileName).append('"').append(LINE_END);
+                    beforeData.append("Content-Type: ").append(mimeType).append(LINE_END).append(LINE_END);
+                    byte[] beforeDataBytes = beforeData.toString().getBytes("UTF-8");
+                    byte[] tailParamsBytes = (LINE_END + LINE_START + BOUNDARY + LINE_START + LINE_END).getBytes("UTF-8");
 
                     
                     // Get a input stream of the file on the phone
                     InputStream sourceInputStream = getPathFromUri(source);
                     
-                    int stringLength = extraBytes.length + midParams.length() + tailParams.length() + fileNameBytes.length;
-                    Log.d(LOG_TAG, "String Length: " + stringLength);
+                    int stringLength = beforeDataBytes.length + tailParamsBytes.length;
                     if (sourceInputStream instanceof FileInputStream) {
                         fixedLength = (int) ((FileInputStream)sourceInputStream).getChannel().size() + stringLength;
                         progress.setLengthComputable(true);
@@ -333,7 +331,7 @@ public class FileTransfer extends CordovaPlugin {
                     // It also causes OOM if HTTPS is used, even on newer devices.
                     boolean useChunkedMode = chunkedMode && (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO || useHttps);
                     useChunkedMode = useChunkedMode || (fixedLength == -1);
-                            
+
                     if (useChunkedMode) {
                         conn.setChunkedStreamingMode(MAX_BUFFER_SIZE);
                         // Although setChunkedStreamingMode sets this header, setting it explicitly here works
@@ -343,19 +341,20 @@ public class FileTransfer extends CordovaPlugin {
                         conn.setFixedLengthStreamingMode(fixedLength);
                     }
 
-                    DataOutputStream dos = null;
+                    conn.connect();
+                    
+                    OutputStream sendStream = null;
                     try {
-                        dos = new DataOutputStream( conn.getOutputStream() );
+                        sendStream = conn.getOutputStream();
                         synchronized (context) {
                             if (context.aborted) {
                                 return;
                             }
-                            context.currentOutputStream = dos;
+                            context.currentOutputStream = sendStream;
                         }
                         //We don't want to change encoding, we just want this to write for all Unicode.
-                        dos.write(extraBytes);
-                        dos.write(fileNameBytes);
-                        dos.writeBytes(midParams);
+                        sendStream.write(beforeDataBytes);
+                        totalBytes += beforeDataBytes.length;
     
                         // create a buffer of maximum size
                         int bytesAvailable = sourceInputStream.available();
@@ -367,9 +366,9 @@ public class FileTransfer extends CordovaPlugin {
     
                         long prevBytesRead = 0;
                         while (bytesRead > 0) {
-                            totalBytes += bytesRead;
                             result.setBytesSent(totalBytes);
-                            dos.write(buffer, 0, bytesRead);
+                            sendStream.write(buffer, 0, bytesRead);
+                            totalBytes += bytesRead;
                             if (totalBytes > prevBytesRead + 102400) {
                                 prevBytesRead = totalBytes;
                                 Log.d(LOG_TAG, "Uploaded " + totalBytes + " of " + fixedLength + " bytes");
@@ -386,17 +385,21 @@ public class FileTransfer extends CordovaPlugin {
                         }
     
                         // send multipart form data necessary after file data...
-                        dos.writeBytes(tailParams);
-                        dos.flush();
+                        sendStream.write(tailParamsBytes);
+                        totalBytes += tailParamsBytes.length;
+                        sendStream.flush();
                     } finally {
                         safeClose(sourceInputStream);
-                        safeClose(dos);
+                        safeClose(sendStream);
                     }
                     context.currentOutputStream = null;
+                    Log.d(LOG_TAG, "Sent " + totalBytes + " of " + fixedLength);
 
                     //------------------ read the SERVER RESPONSE
                     String responseString;
                     int responseCode = conn.getResponseCode();
+                    Log.d(LOG_TAG, "response code: " + responseCode);
+                    Log.d(LOG_TAG, "response headers: " + conn.getHeaderFields());
                     InputStream inStream = null;
                     try {
                         inStream = getInputStream(conn);
@@ -407,8 +410,7 @@ public class FileTransfer extends CordovaPlugin {
                             context.currentInputStream = inStream;
                         }
                         
-    
-                        ByteArrayOutputStream out = new ByteArrayOutputStream();
+                        ByteArrayOutputStream out = new ByteArrayOutputStream(Math.max(1024, conn.getContentLength()));
                         byte[] buffer = new byte[1024];
                         int bytesRead = 0;
                         // write bytes to file
@@ -459,8 +461,6 @@ public class FileTransfer extends CordovaPlugin {
                             https.setHostnameVerifier(oldHostnameVerifier);
                             https.setSSLSocketFactory(oldSocketFactory);
                         }
-
-                        conn.disconnect();
                     }
                 }                
             }
@@ -476,7 +476,7 @@ public class FileTransfer extends CordovaPlugin {
         }
     }
 
-    private static InputStream getInputStream(HttpURLConnection conn) throws IOException {
+    private static InputStream getInputStream(URLConnection conn) throws IOException {
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
             return new DoneHandlerInputStream(conn.getInputStream());
         }
@@ -527,13 +527,15 @@ public class FileTransfer extends CordovaPlugin {
         return oldFactory;
     }
 
-    private static JSONObject createFileTransferError(int errorCode, String source, String target, HttpURLConnection connection) {
+    private static JSONObject createFileTransferError(int errorCode, String source, String target, URLConnection connection) {
 
-        Integer httpStatus = null;
+        int httpStatus = 0;
 
         if (connection != null) {
             try {
-                httpStatus = connection.getResponseCode();
+                if (connection instanceof HttpURLConnection) {
+                    httpStatus = ((HttpURLConnection)connection).getResponseCode();
+                }
             } catch (IOException e) {
                 Log.w(LOG_TAG, "Error getting HTTP status code from connection.", e);
             }
@@ -602,7 +604,7 @@ public class FileTransfer extends CordovaPlugin {
             callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
             return;
         }
-        final boolean useHttps = url.getProtocol().toLowerCase().equals("https");
+        final boolean useHttps = url.getProtocol().equals("https");
 
         if (!Config.isUrlWhiteListed(source)) {
             Log.w(LOG_TAG, "Source URL is not in white list: '" + source + "'");
@@ -622,14 +624,16 @@ public class FileTransfer extends CordovaPlugin {
                 if (context.aborted) {
                     return;
                 }
-                HttpURLConnection connection = null;
+                URLConnection connection = null;
                 HostnameVerifier oldHostnameVerifier = null;
                 SSLSocketFactory oldSocketFactory = null;
+                File file = null;
+                PluginResult result = null;
 
                 try {
-
+                    file = getFileFromPath(target);
+                    context.targetFile = file;
                     // create needed directories
-                    File file = getFileFromPath(target);
                     file.getParentFile().mkdirs();
         
                     // connect to server
@@ -654,10 +658,12 @@ public class FileTransfer extends CordovaPlugin {
                     }
                     // Return a standard HTTP connection
                     else {
-                          connection = (HttpURLConnection) url.openConnection();
+                          connection = url.openConnection();
                     }
     
-                    connection.setRequestMethod("GET");
+                    if (connection instanceof HttpURLConnection) {
+                        ((HttpURLConnection)connection).setRequestMethod("GET");
+                    }
     
                     //Add cookie support
                     String cookie = CookieManager.getInstance().getCookie(source);
@@ -715,22 +721,22 @@ public class FileTransfer extends CordovaPlugin {
                     FileUtils fileUtil = new FileUtils();
                     JSONObject fileEntry = fileUtil.getEntry(file);
                     
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileEntry));
+                    result = new PluginResult(PluginResult.Status.OK, fileEntry);
                 } catch (FileNotFoundException e) {
                     JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, connection);
                     Log.e(LOG_TAG, error.toString(), e);
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
+                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
                 } catch (IOException e) {
                     JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection);
                     Log.e(LOG_TAG, error.toString(), e);
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
+                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
                 } catch (JSONException e) {
                     Log.e(LOG_TAG, e.getMessage(), e);
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                    result = new PluginResult(PluginResult.Status.JSON_EXCEPTION);
                 } catch (Throwable e) {
                     JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection);
                     Log.e(LOG_TAG, error.toString(), e);
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
+                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
                 } finally {
                     synchronized (activeRequests) {
                         activeRequests.remove(objectId);
@@ -743,9 +749,16 @@ public class FileTransfer extends CordovaPlugin {
                             https.setHostnameVerifier(oldHostnameVerifier);
                             https.setSSLSocketFactory(oldSocketFactory);
                         }
-    
-                        connection.disconnect();
                     }
+
+                    if (result == null) {
+                        result = new PluginResult(PluginResult.Status.ERROR, createFileTransferError(CONNECTION_ERR, source, target, connection));
+                    }
+                    // Remove incomplete download.
+                    if (result.getStatus() != PluginResult.Status.OK.ordinal() && file != null) {
+                        file.delete();
+                    }
+                    context.sendPluginResult(result);
                 }
             }
         });
@@ -808,6 +821,10 @@ public class FileTransfer extends CordovaPlugin {
             context = activeRequests.remove(objectId);
         }
         if (context != null) {
+            File file = context.targetFile;
+            if (file != null) {
+                file.delete();
+            }
             // Trigger the abort callback immediately to minimize latency between it and abort() being called.
             JSONObject error = createFileTransferError(ABORTED_ERR, context.source, context.target, -1);
             synchronized (context) {

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/FileUtils.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/FileUtils.java b/lib/cordova-android/framework/src/org/apache/cordova/FileUtils.java
index 554458b..b461b02 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/FileUtils.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/FileUtils.java
@@ -43,7 +43,6 @@ import android.database.Cursor;
 import android.net.Uri;
 import android.os.Environment;
 import android.provider.MediaStore;
-import android.util.Log;
 import android.webkit.MimeTypeMap;
 
 //import android.app.Activity;
@@ -89,7 +88,7 @@ public class FileUtils extends CordovaPlugin {
      * Executes the request and returns whether the action was valid.
      *
      * @param action 		The action to execute.
-     * @param args 		JSONArry of arguments for the plugin.
+     * @param args 		JSONArray of arguments for the plugin.
      * @param callbackContext	The callback context used when calling back into JavaScript.
      * @return 			True if the action was valid, false otherwise.
      */
@@ -238,7 +237,7 @@ public class FileUtils extends CordovaPlugin {
      * @param filePath the path to check
      */
     private void notifyDelete(String filePath) {
-        String newFilePath = stripFileProtocol(filePath);
+        String newFilePath = getRealPathFromURI(Uri.parse(filePath), cordova);
         try {
             this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                 MediaStore.Images.Media.DATA + " = ?",
@@ -342,18 +341,18 @@ public class FileUtils extends CordovaPlugin {
      * @throws InvalidModificationException
      * @throws EncodingException
      * @throws JSONException
-     * @throws FileExistsException 
+     * @throws FileExistsException
      */
     private JSONObject transferTo(String fileName, String newParent, String newName, boolean move) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
-        fileName = stripFileProtocol(fileName);
-        newParent = stripFileProtocol(newParent);
+        String newFileName = getRealPathFromURI(Uri.parse(fileName), cordova);
+        newParent = getRealPathFromURI(Uri.parse(newParent), cordova);
 
         // Check for invalid file name
         if (newName != null && newName.contains(":")) {
             throw new EncodingException("Bad file name");
         }
 
-        File source = new File(fileName);
+        File source = new File(newFileName);
 
         if (!source.exists()) {
             // The file/directory we are copying doesn't exist so we should fail.
@@ -385,7 +384,14 @@ public class FileUtils extends CordovaPlugin {
             }
         } else {
             if (move) {
-                return moveFile(source, destination);
+            	JSONObject newFileEntry = moveFile(source, destination);
+
+            	// If we've moved a file given its content URI, we need to clean up.
+            	if (fileName.startsWith("content://")) {
+            		notifyDelete(fileName);
+            	}
+
+            	return newFileEntry;
             } else {
                 return copyFile(source, destination);
             }
@@ -483,7 +489,7 @@ public class FileUtils extends CordovaPlugin {
         if (!destinationDir.exists()) {
             if (!destinationDir.mkdir()) {
                 // If we can't create the directory then fail
-                throw new NoModificationAllowedException("Couldn't create the destination direcotry");
+                throw new NoModificationAllowedException("Couldn't create the destination directory");
             }
         }
 
@@ -561,8 +567,8 @@ public class FileUtils extends CordovaPlugin {
      * @throws JSONException
      * @throws IOException
      * @throws InvalidModificationException
-     * @throws NoModificationAllowedException 
-     * @throws FileExistsException 
+     * @throws NoModificationAllowedException
+     * @throws FileExistsException
      */
     private JSONObject moveDirectory(File srcDir, File destinationDir) throws IOException, JSONException, InvalidModificationException, NoModificationAllowedException, FileExistsException {
         // Renaming a file to an existing directory should fail
@@ -742,7 +748,7 @@ public class FileUtils extends CordovaPlugin {
         if (fileName.startsWith("/")) {
             fp = new File(fileName);
         } else {
-            dirPath = stripFileProtocol(dirPath);
+            dirPath = getRealPathFromURI(Uri.parse(dirPath), cordova);
             fp = new File(dirPath + File.separator + fileName);
         }
         return fp;
@@ -757,7 +763,7 @@ public class FileUtils extends CordovaPlugin {
      * @throws JSONException
      */
     private JSONObject getParent(String filePath) throws JSONException {
-        filePath = stripFileProtocol(filePath);
+        filePath = getRealPathFromURI(Uri.parse(filePath), cordova);
 
         if (atRootDirectory(filePath)) {
             return getEntry(filePath);
@@ -773,7 +779,7 @@ public class FileUtils extends CordovaPlugin {
      * @return true if we are at the root, false otherwise.
      */
     private boolean atRootDirectory(String filePath) {
-        filePath = stripFileProtocol(filePath);
+        filePath = getRealPathFromURI(Uri.parse(filePath), cordova);
 
         if (filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + cordova.getActivity().getPackageName() + "/cache") ||
                 filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath()) ||
@@ -803,7 +809,7 @@ public class FileUtils extends CordovaPlugin {
      * @return
      */
     private File createFileObject(String filePath) {
-        filePath = stripFileProtocol(filePath);
+    	filePath = getRealPathFromURI(Uri.parse(filePath), cordova);
 
         File file = new File(filePath);
         return file;
@@ -845,7 +851,7 @@ public class FileUtils extends CordovaPlugin {
         metadata.put("size", file.length());
         metadata.put("type", getMimeType(filePath));
         metadata.put("name", file.getName());
-        metadata.put("fullPath", file.getAbsolutePath());
+        metadata.put("fullPath", filePath);
         metadata.put("lastModifiedDate", file.lastModified());
 
         return metadata;
@@ -1028,7 +1034,7 @@ public class FileUtils extends CordovaPlugin {
         if (filename != null) {
             // Stupid bug in getFileExtensionFromUrl when the file name has a space
             // So we need to replace the space with a url encoded %20
-            
+
             // CB-2185: Stupid bug not putting JPG extension in the mime-type map
             String url = filename.replace(" ", "%20").toLowerCase();
             MimeTypeMap map = MimeTypeMap.getSingleton();
@@ -1050,10 +1056,15 @@ public class FileUtils extends CordovaPlugin {
      * @param data				The contents of the file.
      * @param offset			The position to begin writing the file.
      * @throws FileNotFoundException, IOException
+     * @throws NoModificationAllowedException
      */
     /**/
-    public long write(String filename, String data, int offset) throws FileNotFoundException, IOException {
-        filename = stripFileProtocol(filename);
+    public long write(String filename, String data, int offset) throws FileNotFoundException, IOException, NoModificationAllowedException {
+    	if (filename.startsWith("content://")) {
+    		throw new NoModificationAllowedException("Couldn't write to file given its content URI");
+    	}
+
+        filename = getRealPathFromURI(Uri.parse(filename), cordova);
 
         boolean append = false;
         if (offset > 0) {
@@ -1079,9 +1090,14 @@ public class FileUtils extends CordovaPlugin {
      * @param filename
      * @param size
      * @throws FileNotFoundException, IOException
+     * @throws NoModificationAllowedException
      */
-    private long truncateFile(String filename, long size) throws FileNotFoundException, IOException {
-        filename = stripFileProtocol(filename);
+    private long truncateFile(String filename, long size) throws FileNotFoundException, IOException, NoModificationAllowedException {
+    	if (filename.startsWith("content://")) {
+    		throw new NoModificationAllowedException("Couldn't truncate file given its content URI");
+    	}
+
+        filename = getRealPathFromURI(Uri.parse(filename), cordova);
 
         RandomAccessFile raf = new RandomAccessFile(filename, "rw");
         try {
@@ -1090,7 +1106,7 @@ public class FileUtils extends CordovaPlugin {
                 channel.truncate(size);
                 return size;
             }
-    
+
             return raf.length();
         } finally {
             raf.close();
@@ -1110,7 +1126,7 @@ public class FileUtils extends CordovaPlugin {
             return cordova.getActivity().getContentResolver().openInputStream(uri);
         }
         else {
-            path = stripFileProtocol(path);
+            path = getRealPathFromURI(Uri.parse(path), cordova);
             return new FileInputStream(path);
         }
     }
@@ -1125,8 +1141,10 @@ public class FileUtils extends CordovaPlugin {
     @SuppressWarnings("deprecation")
     protected static String getRealPathFromURI(Uri contentUri, CordovaInterface cordova) {
         final String scheme = contentUri.getScheme();
-        
-        if (scheme.compareTo("content") == 0) {
+
+        if (scheme == null) {
+        	return contentUri.toString();
+    	} else if (scheme.compareTo("content") == 0) {
             String[] proj = { _DATA };
             Cursor cursor = cordova.getActivity().managedQuery(contentUri, proj, null, null, null);
             int column_index = cursor.getColumnIndexOrThrow(_DATA);

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/InAppBrowser.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/InAppBrowser.java b/lib/cordova-android/framework/src/org/apache/cordova/InAppBrowser.java
index 0d83432..7e7f862 100644
--- a/lib/cordova-android/framework/src/org/apache/cordova/InAppBrowser.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/InAppBrowser.java
@@ -23,6 +23,7 @@ import java.util.StringTokenizer;
 
 import org.apache.cordova.api.CallbackContext;
 import org.apache.cordova.api.CordovaPlugin;
+import org.apache.cordova.api.LOG;
 import org.apache.cordova.api.PluginResult;
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -48,6 +49,7 @@ import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.webkit.WebChromeClient;
 import android.webkit.WebSettings;
+import android.webkit.WebStorage;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 import android.widget.Button;
@@ -67,13 +69,14 @@ public class InAppBrowser extends CordovaPlugin {
     private static final String EXIT_EVENT = "exit";
     private static final String LOAD_START_EVENT = "loadstart";
     private static final String LOAD_STOP_EVENT = "loadstop";
+    private long MAX_QUOTA = 100 * 1024 * 1024;
 
     private Dialog dialog;
     private WebView inAppWebView;
     private EditText edittext;
     private boolean showLocationBar = true;
     private CallbackContext callbackContext;
-
+    
     /**
      * Executes the request and returns PluginResult.
      *
@@ -108,6 +111,17 @@ public class InAppBrowser extends CordovaPlugin {
                             || Config.isUrlWhiteListed(url)) {
                         this.webView.loadUrl(url);
                     }
+                    //Load the dialer
+                    else if (url.startsWith(WebView.SCHEME_TEL))
+                    {
+                        try {
+                            Intent intent = new Intent(Intent.ACTION_DIAL);
+                            intent.setData(Uri.parse(url));
+                            this.cordova.getActivity().startActivity(intent);
+                        } catch (android.content.ActivityNotFoundException e) {
+                            LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
+                        }
+                    }
                     // load in InAppBrowser
                     else {
                         result = this.showWebPage(url, features);
@@ -401,7 +415,7 @@ public class InAppBrowser extends CordovaPlugin {
                 // WebView
                 inAppWebView = new WebView(cordova.getActivity());
                 inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
-                inAppWebView.setWebChromeClient(new WebChromeClient());
+                inAppWebView.setWebChromeClient(new InAppChromeClient());
                 WebViewClient client = new InAppBrowserClient(thatWebView, edittext);
                 inAppWebView.setWebViewClient(client);
                 WebSettings settings = inAppWebView.getSettings();
@@ -468,6 +482,40 @@ public class InAppBrowser extends CordovaPlugin {
         this.callbackContext.sendPluginResult(result);
     }
 
+    public class InAppChromeClient extends WebChromeClient {
+
+        /**
+         * Handle database quota exceeded notification.
+         *
+         * @param url
+         * @param databaseIdentifier
+         * @param currentQuota
+         * @param estimatedSize
+         * @param totalUsedQuota
+         * @param quotaUpdater
+         */
+        @Override
+        public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,
+                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)
+        {
+            LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d  currentQuota: %d  totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota);
+
+            if (estimatedSize < MAX_QUOTA)
+            {
+                //increase for 1Mb
+                long newQuota = estimatedSize;
+                LOG.d(LOG_TAG, "calling quotaUpdater.updateQuota newQuota: %d", newQuota);
+                quotaUpdater.updateQuota(newQuota);
+            }
+            else
+            {
+                // Set the quota to whatever it is and force an error
+                // TODO: get docs on how to handle this properly
+                quotaUpdater.updateQuota(currentQuota);
+            }
+        }
+    }
+    
     /**
      * The webview client receives notifications about appView
      */

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/Storage.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/Storage.java b/lib/cordova-android/framework/src/org/apache/cordova/Storage.java
index 5ec3068..34ebf38 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/Storage.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/Storage.java
@@ -22,7 +22,6 @@ import java.io.File;
 
 import org.apache.cordova.api.CallbackContext;
 import org.apache.cordova.api.CordovaPlugin;
-import org.apache.cordova.api.PluginResult;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/api/CordovaInterface.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/api/CordovaInterface.java b/lib/cordova-android/framework/src/org/apache/cordova/api/CordovaInterface.java
index 22e36b6..aaa5885 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/api/CordovaInterface.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/api/CordovaInterface.java
@@ -19,7 +19,6 @@
 package org.apache.cordova.api;
 
 import android.app.Activity;
-import android.content.Context;
 import android.content.Intent;
 
 import java.util.concurrent.ExecutorService;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2bb8baca/lib/cordova-android/framework/src/org/apache/cordova/api/PluginManager.java
----------------------------------------------------------------------
diff --git a/lib/cordova-android/framework/src/org/apache/cordova/api/PluginManager.java b/lib/cordova-android/framework/src/org/apache/cordova/api/PluginManager.java
index 98bb157..d0e6aef 100755
--- a/lib/cordova-android/framework/src/org/apache/cordova/api/PluginManager.java
+++ b/lib/cordova-android/framework/src/org/apache/cordova/api/PluginManager.java
@@ -22,17 +22,13 @@ import java.io.IOException;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map.Entry;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 
 import org.apache.cordova.CordovaWebView;
-import org.json.JSONArray;
 import org.json.JSONException;
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.content.Intent;
 import android.content.res.XmlResourceParser;
-import android.util.Log;
 
 /**
  * PluginManager is exposed to JavaScript in the Cordova WebView.