cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject [30/53] merge issues
Date Tue, 30 Apr 2013 21:35:46 GMT
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3b1a8317/framework/src/org/apache/cordova/ContactManager.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/ContactManager.java b/framework/src/org/apache/cordova/ContactManager.java
deleted file mode 100755
index 8ea64a6..0000000
--- a/framework/src/org/apache/cordova/ContactManager.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
-       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.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;
-import android.util.Log;
-
-public class ContactManager extends CordovaPlugin {
-
-    private ContactAccessor contactAccessor;
-    private static final String LOG_TAG = "Contact Query";
-
-    public static final int UNKNOWN_ERROR = 0;
-    public static final int INVALID_ARGUMENT_ERROR = 1;
-    public static final int TIMEOUT_ERROR = 2;
-    public static final int PENDING_OPERATION_ERROR = 3;
-    public static final int IO_ERROR = 4;
-    public static final int NOT_SUPPORTED_ERROR = 5;
-    public static final int PERMISSION_DENIED_ERROR = 20;
-
-    /**
-     * Constructor.
-     */
-    public ContactManager() {
-    }
-
-    /**
-     * Executes the request and returns PluginResult.
-     *
-     * @param action            The action to execute.
-     * @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.
-     */
-    public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
-        /**
-         * Check to see if we are on an Android 1.X device.  If we are return an error as we
-         * do not support this as of Cordova 1.0.
-         */
-        if (android.os.Build.VERSION.RELEASE.startsWith("1.")) {
-            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, ContactManager.NOT_SUPPORTED_ERROR));
-            return true;
-        }
-
-        /**
-         * Only create the contactAccessor after we check the Android version or the program will crash
-         * older phones.
-         */
-        if (this.contactAccessor == null) {
-            this.contactAccessor = new ContactAccessorSdk5(this.webView, this.cordova);
-        }
-
-        if (action.equals("search")) {
-            final JSONArray filter = args.getJSONArray(0);
-            final JSONObject options = args.getJSONObject(1);
-            this.cordova.getThreadPool().execute(new Runnable() {
-                public void run() {
-                    JSONArray res = contactAccessor.search(filter, options);
-                    callbackContext.success(res);
-                }
-            });
-        }
-        else if (action.equals("save")) {
-            final JSONObject contact = args.getJSONObject(0);
-            this.cordova.getThreadPool().execute(new Runnable() {
-                public void run() {
-                    JSONObject res = null;
-                    String id = contactAccessor.save(contact);
-                    if (id != null) {
-                        try {
-                            res = contactAccessor.getContactById(id);
-                        } catch (JSONException e) {
-                            Log.e(LOG_TAG, "JSON fail.", e);
-                        }
-                    }
-                    if (res != null) {
-                        callbackContext.success(res);
-                    } else {
-                        callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, UNKNOWN_ERROR));
-                    }
-                }
-            });
-        }
-        else if (action.equals("remove")) {
-            final String contactId = args.getString(0);
-            this.cordova.getThreadPool().execute(new Runnable() {
-                public void run() {
-                    if (contactAccessor.remove(contactId)) {
-                        callbackContext.success();
-                    } else {
-                        callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, UNKNOWN_ERROR));
-                    }
-                }
-            });
-        }
-        else {
-            return false;
-        }
-        return true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3b1a8317/framework/src/org/apache/cordova/CordovaLocationListener.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaLocationListener.java b/framework/src/org/apache/cordova/CordovaLocationListener.java
deleted file mode 100644
index 01c828b..0000000
--- a/framework/src/org/apache/cordova/CordovaLocationListener.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
-       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.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import org.apache.cordova.api.CallbackContext;
-
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.os.Bundle;
-import android.util.Log;
-
-public class CordovaLocationListener implements LocationListener {
-    public static int PERMISSION_DENIED = 1;
-    public static int POSITION_UNAVAILABLE = 2;
-    public static int TIMEOUT = 3;
-
-    protected LocationManager locationManager;
-    private GeoBroker owner;
-    protected boolean running = false;
-
-    public HashMap<String, CallbackContext> watches = new HashMap<String, CallbackContext>();
-    private List<CallbackContext> callbacks = new ArrayList<CallbackContext>();
-    
-    private Timer timer = null;
-
-    private String TAG = "[Cordova Location Listener]";
-
-    public CordovaLocationListener(LocationManager manager, GeoBroker broker, String tag) {
-        this.locationManager = manager;
-        this.owner = broker;
-        this.TAG = tag;
-    }
-
-    protected void fail(int code, String message) {
-    	this.cancelTimer();
-        for (CallbackContext callbackContext: this.callbacks)
-        {
-            this.owner.fail(code, message, callbackContext, false);
-        }
-        if(this.owner.isGlobalListener(this) && this.watches.size() == 0)
-        {
-        	Log.d(TAG, "Stopping global listener");
-        	this.stop();
-        }
-        this.callbacks.clear();
-
-        Iterator<CallbackContext> it = this.watches.values().iterator();
-        while (it.hasNext()) {
-            this.owner.fail(code, message, it.next(), true);
-        }
-    }
-
-    private void win(Location loc) {
-    	this.cancelTimer();
-        for (CallbackContext callbackContext: this.callbacks)
-        {
-            this.owner.win(loc, callbackContext, false);
-        }
-        if(this.owner.isGlobalListener(this) && this.watches.size() == 0)
-        {
-        	Log.d(TAG, "Stopping global listener");
-        	this.stop();
-        }
-        this.callbacks.clear();
-
-        Iterator<CallbackContext> it = this.watches.values().iterator();
-        while (it.hasNext()) {
-            this.owner.win(loc, it.next(), true);
-        }
-    }
-
-    /**
-     * Location Listener Methods
-     */
-
-    /**
-     * Called when the provider is disabled by the user.
-     *
-     * @param provider
-     */
-    public void onProviderDisabled(String provider) {
-        Log.d(TAG, "Location provider '" + provider + "' disabled.");
-        this.fail(POSITION_UNAVAILABLE, "GPS provider disabled.");
-    }
-
-    /**
-     * Called when the provider is enabled by the user.
-     *
-     * @param provider
-     */
-    public void onProviderEnabled(String provider) {
-        Log.d(TAG, "Location provider "+ provider + " has been enabled");
-    }
-
-    /**
-     * Called when the provider status changes. This method is called when a
-     * provider is unable to fetch a location or if the provider has recently
-     * become available after a period of unavailability.
-     *
-     * @param provider
-     * @param status
-     * @param extras
-     */
-    public void onStatusChanged(String provider, int status, Bundle extras) {
-        Log.d(TAG, "The status of the provider " + provider + " has changed");
-        if (status == 0) {
-            Log.d(TAG, provider + " is OUT OF SERVICE");
-            this.fail(CordovaLocationListener.POSITION_UNAVAILABLE, "Provider " + provider + " is out of service.");
-        }
-        else if (status == 1) {
-            Log.d(TAG, provider + " is TEMPORARILY_UNAVAILABLE");
-        }
-        else {
-            Log.d(TAG, provider + " is AVAILABLE");
-        }
-    }
-
-    /**
-     * Called when the location has changed.
-     *
-     * @param location
-     */
-    public void onLocationChanged(Location location) {
-        Log.d(TAG, "The location has been updated!");
-        this.win(location);
-    }
-
-    // PUBLIC
-
-    public int size() {
-        return this.watches.size() + this.callbacks.size();
-    }
-
-    public void addWatch(String timerId, CallbackContext callbackContext) {
-        this.watches.put(timerId, callbackContext);
-        if (this.size() == 1) {
-            this.start();
-        }
-    }
-    public void addCallback(CallbackContext callbackContext, int timeout) {
-    	if(this.timer == null) {
-    		this.timer = new Timer();
-    	}
-    	this.timer.schedule(new LocationTimeoutTask(callbackContext, this), timeout);
-        this.callbacks.add(callbackContext);        
-        if (this.size() == 1) {
-            this.start();
-        }
-    }
-    public void clearWatch(String timerId) {
-        if (this.watches.containsKey(timerId)) {
-            this.watches.remove(timerId);
-        }
-        if (this.size() == 0) {
-            this.stop();
-        }
-    }
-
-    /**
-     * Destroy listener.
-     */
-    public void destroy() {    	
-        this.stop();
-    }
-
-    // LOCAL
-
-    /**
-     * Start requesting location updates.
-     *
-     * @param interval
-     */
-    protected void start() {
-        if (!this.running) {
-            if (this.locationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
-                this.running = true;
-                this.locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 10, this);
-            } else {
-                this.fail(CordovaLocationListener.POSITION_UNAVAILABLE, "Network provider is not available.");
-            }
-        }
-    }
-
-    /**
-     * Stop receiving location updates.
-     */
-    private void stop() {
-    	this.cancelTimer();
-        if (this.running) {
-            this.locationManager.removeUpdates(this);
-            this.running = false;
-        }
-    }
-    
-    private void cancelTimer() {
-    	if(this.timer != null) {
-    		this.timer.cancel();
-        	this.timer.purge();
-        	this.timer = null;
-    	}
-    }
-    
-    private class LocationTimeoutTask extends TimerTask {
-    	
-    	private CallbackContext callbackContext = null;
-    	private CordovaLocationListener listener = null;
-    	
-    	public LocationTimeoutTask(CallbackContext callbackContext, CordovaLocationListener listener) {
-    		this.callbackContext = callbackContext;
-    		this.listener = listener;
-    	}
-
-		@Override
-		public void run() {
-			for (CallbackContext callbackContext: listener.callbacks) {
-				if(this.callbackContext == callbackContext) {
-					listener.callbacks.remove(callbackContext);
-					break;
-				}
-			}
-			
-			if(listener.size() == 0) {
-				listener.stop();
-			}
-		}    	
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3b1a8317/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebView.java b/framework/src/org/apache/cordova/CordovaWebView.java
index 5dd061e..518b7c9 100755
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@ -31,6 +31,8 @@ import org.apache.cordova.api.CordovaInterface;
 import org.apache.cordova.api.LOG;
 import org.apache.cordova.api.PluginManager;
 import org.apache.cordova.api.PluginResult;
+import org.apache.cordova.ExposedJsApi;
+import org.apache.cordova.NativeToJsMessageQueue;
 
 import android.annotation.SuppressLint;
 import android.annotation.TargetApi;

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3b1a8317/framework/src/org/apache/cordova/CordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebViewClient.java b/framework/src/org/apache/cordova/CordovaWebViewClient.java
index 4b00615..13b9455 100755
--- a/framework/src/org/apache/cordova/CordovaWebViewClient.java
+++ b/framework/src/org/apache/cordova/CordovaWebViewClient.java
@@ -24,6 +24,7 @@ import java.util.Hashtable;
 import org.apache.cordova.api.CordovaInterface;
 
 import org.apache.cordova.api.LOG;
+import org.apache.cordova.NativeToJsMessageQueue;
 import org.json.JSONException;
 import org.json.JSONObject;
 

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3b1a8317/framework/src/org/apache/cordova/Device.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/Device.java b/framework/src/org/apache/cordova/Device.java
deleted file mode 100644
index aa316c5..0000000
--- a/framework/src/org/apache/cordova/Device.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
-       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.util.TimeZone;
-
-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.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.provider.Settings;
-import android.telephony.TelephonyManager;
-
-public class Device extends CordovaPlugin {
-    public static final String TAG = "Device";
-
-    public static String cordovaVersion = "2.6.0";              // Cordova version
-    public static String platform = "Android";                  // Device OS
-    public static String uuid;                                  // Device UUID
-
-    BroadcastReceiver telephonyReceiver = null;
-
-    /**
-     * Constructor.
-     */
-    public Device() {
-    }
-
-    /**
-     * Sets the context of the Command. This can then be used to do things like
-     * get file paths associated with the Activity.
-     *
-     * @param cordova The context of the main Activity.
-     * @param webView The CordovaWebView Cordova is running in.
-     */
-    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
-        super.initialize(cordova, webView);
-        Device.uuid = getUuid();
-        this.initTelephonyReceiver();
-    }
-
-    /**
-     * Executes the request and returns PluginResult.
-     *
-     * @param action            The action to execute.
-     * @param args              JSONArry of arguments for the plugin.
-     * @param callbackContext   The callback id used when calling back into JavaScript.
-     * @return                  True if the action was valid, false if not.
-     */
-    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
-        if (action.equals("getDeviceInfo")) {
-            JSONObject r = new JSONObject();
-            r.put("uuid", Device.uuid);
-            r.put("version", this.getOSVersion());
-            r.put("platform", Device.platform);
-            r.put("cordova", Device.cordovaVersion);
-            r.put("model", this.getModel());
-            callbackContext.success(r);
-        }
-        else {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Unregister receiver.
-     */
-    public void onDestroy() {
-        this.cordova.getActivity().unregisterReceiver(this.telephonyReceiver);
-    }
-
-    //--------------------------------------------------------------------------
-    // LOCAL METHODS
-    //--------------------------------------------------------------------------
-
-    /**
-     * Listen for telephony events: RINGING, OFFHOOK and IDLE
-     * Send these events to all plugins using
-     *      DroidGap.onMessage("telephone", "ringing" | "offhook" | "idle")
-     */
-    private void initTelephonyReceiver() {
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
-        //final CordovaInterface mycordova = this.cordova;
-        this.telephonyReceiver = new BroadcastReceiver() {
-
-            @Override
-            public void onReceive(Context context, Intent intent) {
-
-                // If state has changed
-                if ((intent != null) && intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
-                    if (intent.hasExtra(TelephonyManager.EXTRA_STATE)) {
-                        String extraData = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
-                        if (extraData.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
-                            LOG.i(TAG, "Telephone RINGING");
-                            webView.postMessage("telephone", "ringing");
-                        }
-                        else if (extraData.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
-                            LOG.i(TAG, "Telephone OFFHOOK");
-                            webView.postMessage("telephone", "offhook");
-                        }
-                        else if (extraData.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
-                            LOG.i(TAG, "Telephone IDLE");
-                            webView.postMessage("telephone", "idle");
-                        }
-                    }
-                }
-            }
-        };
-
-        // Register the receiver
-        this.cordova.getActivity().registerReceiver(this.telephonyReceiver, intentFilter);
-    }
-
-    /**
-     * Get the OS name.
-     *
-     * @return
-     */
-    public String getPlatform() {
-        return Device.platform;
-    }
-
-    /**
-     * Get the device's Universally Unique Identifier (UUID).
-     *
-     * @return
-     */
-    public String getUuid() {
-        String uuid = Settings.Secure.getString(this.cordova.getActivity().getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
-        return uuid;
-    }
-
-    /**
-     * Get the Cordova version.
-     *
-     * @return
-     */
-    public String getCordovaVersion() {
-        return Device.cordovaVersion;
-    }
-
-    public String getModel() {
-        String model = android.os.Build.MODEL;
-        return model;
-    }
-
-    public String getProductName() {
-        String productname = android.os.Build.PRODUCT;
-        return productname;
-    }
-
-    /**
-     * Get the OS version.
-     *
-     * @return
-     */
-    public String getOSVersion() {
-        String osversion = android.os.Build.VERSION.RELEASE;
-        return osversion;
-    }
-
-    public String getSDKVersion() {
-        @SuppressWarnings("deprecation")
-        String sdkversion = android.os.Build.VERSION.SDK;
-        return sdkversion;
-    }
-
-    public String getTimeZoneID() {
-        TimeZone tz = TimeZone.getDefault();
-        return (tz.getID());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3b1a8317/framework/src/org/apache/cordova/DirectoryManager.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/DirectoryManager.java b/framework/src/org/apache/cordova/DirectoryManager.java
deleted file mode 100644
index 292f402..0000000
--- a/framework/src/org/apache/cordova/DirectoryManager.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
-       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.File;
-
-import android.content.Context;
-import android.os.Environment;
-import android.os.StatFs;
-
-/**
- * This class provides file directory utilities.
- * All file operations are performed on the SD card.
- *
- * It is used by the FileUtils class.
- */
-public class DirectoryManager {
-
-    @SuppressWarnings("unused")
-    private static final String LOG_TAG = "DirectoryManager";
-
-    /**
-     * Determine if a file or directory exists.
-     * @param name				The name of the file to check.
-     * @return					T=exists, F=not found
-     */
-    protected static boolean testFileExists(String name) {
-        boolean status;
-
-        // If SD card exists
-        if ((testSaveLocationExists()) && (!name.equals(""))) {
-            File path = Environment.getExternalStorageDirectory();
-            File newPath = constructFilePaths(path.toString(), name);
-            status = newPath.exists();
-        }
-        // If no SD card
-        else {
-            status = false;
-        }
-        return status;
-    }
-
-    /**
-     * Get the free disk space
-     * 
-     * @return 		Size in KB or -1 if not available
-     */
-    protected static long getFreeDiskSpace(boolean checkInternal) {
-        String status = Environment.getExternalStorageState();
-        long freeSpace = 0;
-
-        // If SD card exists
-        if (status.equals(Environment.MEDIA_MOUNTED)) {
-            freeSpace = freeSpaceCalculation(Environment.getExternalStorageDirectory().getPath());
-        }
-        else if (checkInternal) {
-            freeSpace = freeSpaceCalculation("/");
-        }
-        // If no SD card and we haven't been asked to check the internal directory then return -1
-        else {
-            return -1;
-        }
-
-        return freeSpace;
-    }
-
-    /**
-     * Given a path return the number of free KB
-     * 
-     * @param path to the file system
-     * @return free space in KB
-     */
-    private static long freeSpaceCalculation(String path) {
-        StatFs stat = new StatFs(path);
-        long blockSize = stat.getBlockSize();
-        long availableBlocks = stat.getAvailableBlocks();
-        return availableBlocks * blockSize / 1024;
-    }
-
-    /**
-     * Determine if SD card exists.
-     * 
-     * @return				T=exists, F=not found
-     */
-    protected static boolean testSaveLocationExists() {
-        String sDCardStatus = Environment.getExternalStorageState();
-        boolean status;
-
-        // If SD card is mounted
-        if (sDCardStatus.equals(Environment.MEDIA_MOUNTED)) {
-            status = true;
-        }
-
-        // If no SD card
-        else {
-            status = false;
-        }
-        return status;
-    }
-
-    /**
-     * Create a new file object from two file paths.
-     *
-     * @param file1			Base file path
-     * @param file2			Remaining file path
-     * @return				File object
-     */
-    private static File constructFilePaths (String file1, String file2) {
-        File newPath;
-        if (file2.startsWith(file1)) {
-            newPath = new File(file2);
-        }
-        else {
-            newPath = new File(file1 + "/" + file2);
-        }
-        return newPath;
-    }
-
-    /**
-     * Determine if we can use the SD Card to store the temporary file.  If not then use
-     * the internal cache directory.
-     *
-     * @return the absolute path of where to store the file
-     */
-    protected static String getTempDirectoryPath(Context ctx) {
-        File cache = null;
-
-        // SD Card Mounted
-        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-            cache = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
-                    "/Android/data/" + ctx.getPackageName() + "/cache/");
-        }
-        // Use internal storage
-        else {
-            cache = ctx.getCacheDir();
-        }
-
-        // Create the cache directory if it doesn't exist
-        if (!cache.exists()) {
-            cache.mkdirs();
-        }
-
-        return cache.getAbsolutePath();
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3b1a8317/framework/src/org/apache/cordova/DroidGap.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/DroidGap.java b/framework/src/org/apache/cordova/DroidGap.java
index 3c6610f..213471d 100755
--- a/framework/src/org/apache/cordova/DroidGap.java
+++ b/framework/src/org/apache/cordova/DroidGap.java
@@ -22,6 +22,13 @@ import java.util.HashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
+import org.apache.cordova.AuthenticationToken;
+import org.apache.cordova.Config;
+import org.apache.cordova.CordovaChromeClient;
+import org.apache.cordova.CordovaWebView;
+import org.apache.cordova.CordovaWebViewClient;
+import org.apache.cordova.IceCreamCordovaWebViewClient;
+import org.apache.cordova.LinearLayoutSoftKeyboardDetect;
 import org.apache.cordova.api.CordovaInterface;
 import org.apache.cordova.api.CordovaPlugin;
 import org.apache.cordova.api.LOG;
@@ -447,15 +454,6 @@ public class DroidGap extends Activity implements CordovaInterface {
     }
 
     /**
-     * Cancel loadUrl before it has been loaded.
-     */
-    // TODO NO-OP
-    @Deprecated
-    public void cancelLoadUrl() {
-        this.cancelLoadUrl = true;
-    }
-
-    /**
      * Clear the resource cache.
      */
     public void clearCache() {
@@ -502,6 +500,7 @@ public class DroidGap extends Activity implements CordovaInterface {
      * @param defaultValue
      * @return
      */
+    @Deprecated
     public boolean getBooleanProperty(String name, boolean defaultValue) {
         Bundle bundle = this.getIntent().getExtras();
         if (bundle == null) {
@@ -532,6 +531,7 @@ public class DroidGap extends Activity implements CordovaInterface {
      * @param defaultValue
      * @return
      */
+    @Deprecated
     public int getIntegerProperty(String name, int defaultValue) {
         Bundle bundle = this.getIntent().getExtras();
         if (bundle == null) {
@@ -556,6 +556,7 @@ public class DroidGap extends Activity implements CordovaInterface {
      * @param defaultValue
      * @return
      */
+    @Deprecated
     public String getStringProperty(String name, String defaultValue) {
         Bundle bundle = this.getIntent().getExtras();
         if (bundle == null) {
@@ -575,6 +576,7 @@ public class DroidGap extends Activity implements CordovaInterface {
      * @param defaultValue
      * @return
      */
+    @Deprecated
     public double getDoubleProperty(String name, double defaultValue) {
         Bundle bundle = this.getIntent().getExtras();
         if (bundle == null) {
@@ -598,6 +600,7 @@ public class DroidGap extends Activity implements CordovaInterface {
      * @param name
      * @param value
      */
+    @Deprecated
     public void setBooleanProperty(String name, boolean value) {
         Log.d(TAG, "Setting boolean properties in DroidGap will be deprecated in 3.0 on July 2013, please use config.xml");
         this.getIntent().putExtra(name, value);
@@ -609,6 +612,7 @@ public class DroidGap extends Activity implements CordovaInterface {
      * @param name
      * @param value
      */
+    @Deprecated
     public void setIntegerProperty(String name, int value) {
         Log.d(TAG, "Setting integer properties in DroidGap will be deprecated in 3.1 on August 2013, please use config.xml");
         this.getIntent().putExtra(name, value);
@@ -620,6 +624,7 @@ public class DroidGap extends Activity implements CordovaInterface {
      * @param name
      * @param value
      */
+    @Deprecated
     public void setStringProperty(String name, String value) {
         Log.d(TAG, "Setting string properties in DroidGap will be deprecated in 3.0 on July 2013, please use config.xml");
         this.getIntent().putExtra(name, value);
@@ -631,6 +636,7 @@ public class DroidGap extends Activity implements CordovaInterface {
      * @param name
      * @param value
      */
+    @Deprecated
     public void setDoubleProperty(String name, double value) {
         Log.d(TAG, "Setting double properties in DroidGap will be deprecated in 3.0 on July 2013, please use config.xml");
         this.getIntent().putExtra(name, value);

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3b1a8317/framework/src/org/apache/cordova/Echo.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/Echo.java b/framework/src/org/apache/cordova/Echo.java
deleted file mode 100644
index aaebe02..0000000
--- a/framework/src/org/apache/cordova/Echo.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-       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.api.CallbackContext;
-import org.apache.cordova.api.CordovaPlugin;
-import org.json.JSONException;
-
-public class Echo extends CordovaPlugin {
-
-    @Override
-    public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {
-        if ("echo".equals(action)) {
-            final String result = args.isNull(0) ? null : args.getString(0);
-            callbackContext.success(result);
-            return true;
-        } else if ("echoAsync".equals(action)) {
-            final String result = args.isNull(0) ? null : args.getString(0);
-            cordova.getThreadPool().execute(new Runnable() {
-                public void run() {
-                    callbackContext.success(result);
-                }
-            });
-            return true;
-        } else if ("echoArrayBuffer".equals(action)) {
-            final byte[] result = args.getArrayBuffer(0);
-            callbackContext.success(result);
-            return true;
-        }
-        return false;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3b1a8317/framework/src/org/apache/cordova/ExifHelper.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/ExifHelper.java b/framework/src/org/apache/cordova/ExifHelper.java
deleted file mode 100644
index 38ad0a6..0000000
--- a/framework/src/org/apache/cordova/ExifHelper.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
-       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 android.media.ExifInterface;
-
-public class ExifHelper {
-    private String aperture = null;
-    private String datetime = null;
-    private String exposureTime = null;
-    private String flash = null;
-    private String focalLength = null;
-    private String gpsAltitude = null;
-    private String gpsAltitudeRef = null;
-    private String gpsDateStamp = null;
-    private String gpsLatitude = null;
-    private String gpsLatitudeRef = null;
-    private String gpsLongitude = null;
-    private String gpsLongitudeRef = null;
-    private String gpsProcessingMethod = null;
-    private String gpsTimestamp = null;
-    private String iso = null;
-    private String make = null;
-    private String model = null;
-    private String orientation = null;
-    private String whiteBalance = null;
-
-    private ExifInterface inFile = null;
-    private ExifInterface outFile = null;
-
-    /**
-     * The file before it is compressed
-     *
-     * @param filePath
-     * @throws IOException
-     */
-    public void createInFile(String filePath) throws IOException {
-        this.inFile = new ExifInterface(filePath);
-    }
-
-    /**
-     * The file after it has been compressed
-     *
-     * @param filePath
-     * @throws IOException
-     */
-    public void createOutFile(String filePath) throws IOException {
-        this.outFile = new ExifInterface(filePath);
-    }
-
-    /**
-     * Reads all the EXIF data from the input file.
-     */
-    public void readExifData() {
-        this.aperture = inFile.getAttribute(ExifInterface.TAG_APERTURE);
-        this.datetime = inFile.getAttribute(ExifInterface.TAG_DATETIME);
-        this.exposureTime = inFile.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
-        this.flash = inFile.getAttribute(ExifInterface.TAG_FLASH);
-        this.focalLength = inFile.getAttribute(ExifInterface.TAG_FOCAL_LENGTH);
-        this.gpsAltitude = inFile.getAttribute(ExifInterface.TAG_GPS_ALTITUDE);
-        this.gpsAltitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF);
-        this.gpsDateStamp = inFile.getAttribute(ExifInterface.TAG_GPS_DATESTAMP);
-        this.gpsLatitude = inFile.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
-        this.gpsLatitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF);
-        this.gpsLongitude = inFile.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
-        this.gpsLongitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF);
-        this.gpsProcessingMethod = inFile.getAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD);
-        this.gpsTimestamp = inFile.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP);
-        this.iso = inFile.getAttribute(ExifInterface.TAG_ISO);
-        this.make = inFile.getAttribute(ExifInterface.TAG_MAKE);
-        this.model = inFile.getAttribute(ExifInterface.TAG_MODEL);
-        this.orientation = inFile.getAttribute(ExifInterface.TAG_ORIENTATION);
-        this.whiteBalance = inFile.getAttribute(ExifInterface.TAG_WHITE_BALANCE);
-    }
-
-    /**
-     * Writes the previously stored EXIF data to the output file.
-     *
-     * @throws IOException
-     */
-    public void writeExifData() throws IOException {
-        // Don't try to write to a null file
-        if (this.outFile == null) {
-            return;
-        }
-
-        if (this.aperture != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_APERTURE, this.aperture);
-        }
-        if (this.datetime != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_DATETIME, this.datetime);
-        }
-        if (this.exposureTime != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_EXPOSURE_TIME, this.exposureTime);
-        }
-        if (this.flash != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_FLASH, this.flash);
-        }
-        if (this.focalLength != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_FOCAL_LENGTH, this.focalLength);
-        }
-        if (this.gpsAltitude != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_GPS_ALTITUDE, this.gpsAltitude);
-        }
-        if (this.gpsAltitudeRef != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF, this.gpsAltitudeRef);
-        }
-        if (this.gpsDateStamp != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_GPS_DATESTAMP, this.gpsDateStamp);
-        }
-        if (this.gpsLatitude != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_GPS_LATITUDE, this.gpsLatitude);
-        }
-        if (this.gpsLatitudeRef != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, this.gpsLatitudeRef);
-        }
-        if (this.gpsLongitude != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, this.gpsLongitude);
-        }
-        if (this.gpsLongitudeRef != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, this.gpsLongitudeRef);
-        }
-        if (this.gpsProcessingMethod != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD, this.gpsProcessingMethod);
-        }
-        if (this.gpsTimestamp != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_GPS_TIMESTAMP, this.gpsTimestamp);
-        }
-        if (this.iso != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_ISO, this.iso);
-        }
-        if (this.make != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_MAKE, this.make);
-        }
-        if (this.model != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_MODEL, this.model);
-        }
-        if (this.orientation != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_ORIENTATION, this.orientation);
-        }
-        if (this.whiteBalance != null) {
-            this.outFile.setAttribute(ExifInterface.TAG_WHITE_BALANCE, this.whiteBalance);
-        }
-
-        this.outFile.saveAttributes();
-    }
-
-    public int getOrientation() {
-        int o = Integer.parseInt(this.orientation);
-
-        if (o == ExifInterface.ORIENTATION_NORMAL) {
-            return 0;
-        } else if (o == ExifInterface.ORIENTATION_ROTATE_90) {
-            return 90;
-        } else if (o == ExifInterface.ORIENTATION_ROTATE_180) {
-            return 180;
-        } else if (o == ExifInterface.ORIENTATION_ROTATE_270) {
-            return 270;
-        } else {
-            return 0;
-        }
-    }
-
-    public void resetOrientation() {
-        this.orientation = "" + ExifInterface.ORIENTATION_NORMAL;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3b1a8317/framework/src/org/apache/cordova/ExposedJsApi.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/ExposedJsApi.java b/framework/src/org/apache/cordova/ExposedJsApi.java
index 7702d35..1b13bce 100755
--- a/framework/src/org/apache/cordova/ExposedJsApi.java
+++ b/framework/src/org/apache/cordova/ExposedJsApi.java
@@ -19,6 +19,7 @@
 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-android/blob/3b1a8317/framework/src/org/apache/cordova/FileProgressResult.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/FileProgressResult.java b/framework/src/org/apache/cordova/FileProgressResult.java
deleted file mode 100644
index d981175..0000000
--- a/framework/src/org/apache/cordova/FileProgressResult.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-       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.JSONException;
-import org.json.JSONObject;
-
-/**
- * Encapsulates in-progress status of uploading or downloading a file to a remote server.
- */
-public class FileProgressResult {
-
-    private boolean lengthComputable = false; // declares whether total is known
-    private long loaded = 0;                  // bytes sent so far
-    private long total = 0;                   // bytes total, if known
-
-    public boolean getLengthComputable() {
-        return lengthComputable;
-    }
-
-    public void setLengthComputable(boolean computable) {
-        this.lengthComputable = computable;
-    }
-
-    public long getLoaded() {
-        return loaded;
-    }
-
-    public void setLoaded(long bytes) {
-        this.loaded = bytes;
-    }
-
-    public long getTotal() {
-        return total;
-    }
-
-    public void setTotal(long bytes) {
-        this.total = bytes;
-    }
-
-    public JSONObject toJSONObject() throws JSONException {
-        return new JSONObject(
-                "{loaded:" + loaded +
-                ",total:" + total +
-                ",lengthComputable:" + (lengthComputable ? "true" : "false") + "}");
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3b1a8317/framework/src/org/apache/cordova/FileTransfer.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/FileTransfer.java b/framework/src/org/apache/cordova/FileTransfer.java
deleted file mode 100644
index 3216a45..0000000
--- a/framework/src/org/apache/cordova/FileTransfer.java
+++ /dev/null
@@ -1,964 +0,0 @@
-/*
-       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.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.StringWriter;
-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;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.Inflater;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
-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;
-
-import android.net.Uri;
-import android.os.Build;
-import android.util.Log;
-import android.webkit.CookieManager;
-
-import com.squareup.okhttp.OkHttpClient;
-
-public class FileTransfer extends CordovaPlugin {
-
-    private static final String LOG_TAG = "FileTransfer";
-    private static final String LINE_START = "--";
-    private static final String LINE_END = "\r\n";
-    private static final String BOUNDARY =  "+++++";
-
-    public static int FILE_NOT_FOUND_ERR = 1;
-    public static int INVALID_URL_ERR = 2;
-    public static int CONNECTION_ERR = 3;
-    public static int ABORTED_ERR = 4;
-
-    private static HashMap<String, RequestContext> activeRequests = new HashMap<String, RequestContext>();
-    private static final int MAX_BUFFER_SIZE = 16 * 1024;
-
-    private static OkHttpClient httpClient = new OkHttpClient();
-
-    private static final class RequestContext {
-        String source;
-        String target;
-        File targetFile;
-        CallbackContext callbackContext;
-        InputStream currentInputStream;
-        OutputStream currentOutputStream;
-        boolean aborted;
-        RequestContext(String source, String target, CallbackContext callbackContext) {
-            this.source = source;
-            this.target = target;
-            this.callbackContext = callbackContext;
-        }
-        void sendPluginResult(PluginResult pluginResult) {
-            synchronized (this) {
-                if (!aborted) {
-                    callbackContext.sendPluginResult(pluginResult);
-                }
-            }
-        }
-    }
-
-    /**
-     * Adds an interface method to an InputStream to return the number of bytes
-     * read from the raw stream. This is used to track total progress against
-     * the HTTP Content-Length header value from the server.
-     */
-    private static abstract class TrackingInputStream extends FilterInputStream {
-    	public TrackingInputStream(final InputStream in) {
-    		super(in);
-    	}
-        public abstract long getTotalRawBytesRead();
-	}
-
-    private static class ExposedGZIPInputStream extends GZIPInputStream {
-	    public ExposedGZIPInputStream(final InputStream in) throws IOException {
-	    	super(in);
-	    }
-	    public Inflater getInflater() {
-	    	return inf;
-	    }
-	}
-
-    /**
-     * Provides raw bytes-read tracking for a GZIP input stream. Reports the
-     * total number of compressed bytes read from the input, rather than the
-     * number of uncompressed bytes.
-     */
-    private static class TrackingGZIPInputStream extends TrackingInputStream {
-    	private ExposedGZIPInputStream gzin;
-	    public TrackingGZIPInputStream(final ExposedGZIPInputStream gzin) throws IOException {
-	    	super(gzin);
-	    	this.gzin = gzin;
-	    }
-	    public long getTotalRawBytesRead() {
-	    	return gzin.getInflater().getBytesRead();
-	    }
-	}
-
-    /**
-     * Provides simple total-bytes-read tracking for an existing InputStream
-     */
-    private static class TrackingHTTPInputStream extends TrackingInputStream {
-        private long bytesRead = 0;
-        public TrackingHTTPInputStream(InputStream stream) {
-            super(stream);
-        }
-
-        private int updateBytesRead(int newBytesRead) {
-        	if (newBytesRead != -1) {
-        		bytesRead += newBytesRead;
-        	}
-        	return newBytesRead;
-        }
-
-        @Override
-        public int read() throws IOException {
-            return updateBytesRead(super.read());
-        }
-
-        @Override
-        public int read(byte[] buffer) throws IOException {
-            return updateBytesRead(super.read(buffer));
-        }
-
-        @Override
-        public int read(byte[] bytes, int offset, int count) throws IOException {
-            return updateBytesRead(super.read(bytes, offset, count));
-        }
-
-        public long getTotalRawBytesRead() {
-        	return bytesRead;
-        }
-    }
-
-    /**
-     * Works around a bug on Android 2.3.
-     * http://code.google.com/p/android/issues/detail?id=14562
-     */
-    private static final class DoneHandlerInputStream extends TrackingHTTPInputStream {
-        private boolean done;
-        
-        public DoneHandlerInputStream(InputStream stream) {
-            super(stream);
-        }
-        
-        @Override
-        public int read() throws IOException {
-            int result = done ? -1 : super.read();
-            done = (result == -1);
-            return result;
-        }
-
-        @Override
-        public int read(byte[] buffer) throws IOException {
-            int result = done ? -1 : super.read(buffer);
-            done = (result == -1);
-            return result;
-        }
-
-        @Override
-        public int read(byte[] bytes, int offset, int count) throws IOException {
-            int result = done ? -1 : super.read(bytes, offset, count);
-            done = (result == -1);
-            return result;
-        }
-    }
-    
-    @Override
-    public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
-        if (action.equals("upload") || action.equals("download")) {
-            String source = args.getString(0);
-            String target = args.getString(1);
-
-            if (action.equals("upload")) {
-                try {
-                    source = URLDecoder.decode(source, "UTF-8");
-                    upload(source, target, args, callbackContext);
-                } catch (UnsupportedEncodingException e) {
-                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.MALFORMED_URL_EXCEPTION, "UTF-8 error."));
-                }
-            } else {
-                download(source, target, args, callbackContext);
-            }
-            return true;
-        } else if (action.equals("abort")) {
-            String objectId = args.getString(0);
-            abort(objectId);
-            callbackContext.success();
-            return true;
-        }
-        return false;
-    }
-
-    private static void addHeadersToRequest(URLConnection connection, JSONObject headers) {
-        try {
-            for (Iterator<?> iter = headers.keys(); iter.hasNext(); ) {
-                String headerKey = iter.next().toString();
-                JSONArray headerValues = headers.optJSONArray(headerKey);
-                if (headerValues == null) {
-                    headerValues = new JSONArray();
-                    headerValues.put(headers.getString(headerKey));
-                }
-                connection.setRequestProperty(headerKey, headerValues.getString(0));
-                for (int i = 1; i < headerValues.length(); ++i) {
-                    connection.addRequestProperty(headerKey, headerValues.getString(i));
-                }
-            }
-        } catch (JSONException e1) {
-          // No headers to be manipulated!
-        }
-    }
-
-    /**
-     * Uploads the specified file to the server URL provided using an HTTP multipart request.
-     * @param source        Full path of the file on the file system
-     * @param target        URL of the server to receive the file
-     * @param args          JSON Array of args
-     * @param callbackContext    callback id for optional progress reports
-     *
-     * args[2] fileKey       Name of file request parameter
-     * args[3] fileName      File name to be used on server
-     * args[4] mimeType      Describes file content type
-     * args[5] params        key:value pairs of user-defined parameters
-     * @return FileUploadResult containing result of upload request
-     */
-    private void upload(final String source, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException {
-        Log.d(LOG_TAG, "upload " + source + " to " +  target);
-
-        // Setup the options
-        final String fileKey = getArgument(args, 2, "file");
-        final String fileName = getArgument(args, 3, "image.jpg");
-        final String mimeType = getArgument(args, 4, "image/jpeg");
-        final JSONObject params = args.optJSONObject(5) == null ? new JSONObject() : args.optJSONObject(5);
-        final boolean trustEveryone = args.optBoolean(6);
-        // Always use chunked mode unless set to false as per API
-        final boolean chunkedMode = args.optBoolean(7) || args.isNull(7);
-        // Look for headers on the params map for backwards compatibility with older Cordova versions.
-        final JSONObject headers = args.optJSONObject(8) == null ? params.optJSONObject("headers") : args.optJSONObject(8);
-        final String objectId = args.getString(9);
-        final String httpMethod = getArgument(args, 10, "POST");
-
-        Log.d(LOG_TAG, "fileKey: " + fileKey);
-        Log.d(LOG_TAG, "fileName: " + fileName);
-        Log.d(LOG_TAG, "mimeType: " + mimeType);
-        Log.d(LOG_TAG, "params: " + params);
-        Log.d(LOG_TAG, "trustEveryone: " + trustEveryone);
-        Log.d(LOG_TAG, "chunkedMode: " + chunkedMode);
-        Log.d(LOG_TAG, "headers: " + headers);
-        Log.d(LOG_TAG, "objectId: " + objectId);
-        Log.d(LOG_TAG, "httpMethod: " + httpMethod);
-        
-        final URL url;
-        try {
-            url = new URL(target);
-        } catch (MalformedURLException e) {
-            JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0);
-            Log.e(LOG_TAG, error.toString(), e);
-            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
-            return;
-        }
-        final boolean useHttps = url.getProtocol().equals("https");
-
-        final RequestContext context = new RequestContext(source, target, callbackContext);
-        synchronized (activeRequests) {
-            activeRequests.put(objectId, context);
-        }
-        
-        cordova.getThreadPool().execute(new Runnable() {
-            public void run() {
-                if (context.aborted) {
-                    return;
-                }
-                HttpURLConnection conn = null;
-                HostnameVerifier oldHostnameVerifier = null;
-                SSLSocketFactory oldSocketFactory = null;
-                int totalBytes = 0;
-                int fixedLength = -1;
-                try {
-                    // Create return object
-                    FileUploadResult result = new FileUploadResult();
-                    FileProgressResult progress = new FileProgressResult();
-
-                    //------------------ CLIENT REQUEST
-                    // Open a HTTP connection to the URL based on protocol
-                    if (useHttps) {
-                        // Using standard HTTPS connection. Will not allow self signed certificate
-                        if (!trustEveryone) {
-                            conn = (HttpsURLConnection) httpClient.open(url);
-                        }
-                        // Use our HTTPS connection that blindly trusts everyone.
-                        // This should only be used in debug environments
-                        else {
-                            // Setup the HTTPS connection class to trust everyone
-                            HttpsURLConnection https = (HttpsURLConnection) httpClient.open(url);
-                            oldSocketFactory  = trustAllHosts(https);
-                            // Save the current hostnameVerifier
-                            oldHostnameVerifier = https.getHostnameVerifier();
-                            // Setup the connection not to verify hostnames
-                            https.setHostnameVerifier(DO_NOT_VERIFY);
-                            conn = https;
-                        }
-                    }
-                    // Return a standard HTTP connection
-                    else {
-                        conn = httpClient.open(url);
-                    }
-
-                    // Allow Inputs
-                    conn.setDoInput(true);
-
-                    // Allow Outputs
-                    conn.setDoOutput(true);
-
-                    // Don't use a cached copy.
-                    conn.setUseCaches(false);
-
-                    // Use a post method.
-                    conn.setRequestMethod(httpMethod);
-                    conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);
-
-                    // Set the cookies on the response
-                    String cookie = CookieManager.getInstance().getCookie(target);
-                    if (cookie != null) {
-                        conn.setRequestProperty("Cookie", cookie);
-                    }
-
-                    // Handle the other headers
-                    if (headers != null) {
-                        addHeadersToRequest(conn, headers);
-                    }
-
-                    /*
-                        * 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.
-                        */
-                    StringBuilder beforeData = new StringBuilder();
-                    try {
-                        for (Iterator<?> iter = params.keys(); iter.hasNext();) {
-                            Object key = iter.next();
-                            if(!String.valueOf(key).equals("headers"))
-                            {
-                              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);
-                    }
-
-                    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 = beforeDataBytes.length + tailParamsBytes.length;
-                    if (sourceInputStream instanceof FileInputStream) {
-                        fixedLength = (int) ((FileInputStream)sourceInputStream).getChannel().size() + stringLength;
-                        progress.setLengthComputable(true);
-                        progress.setTotal(fixedLength);
-                    }
-                    Log.d(LOG_TAG, "Content Length: " + fixedLength);
-                    // setFixedLengthStreamingMode causes and OutOfMemoryException on pre-Froyo devices.
-                    // http://code.google.com/p/android/issues/detail?id=3164
-                    // 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
-                        // around an OutOfMemoryException when using https.
-                        conn.setRequestProperty("Transfer-Encoding", "chunked");
-                    } else {
-                        conn.setFixedLengthStreamingMode(fixedLength);
-                    }
-
-                    conn.connect();
-                    
-                    OutputStream sendStream = null;
-                    try {
-                        sendStream = conn.getOutputStream();
-                        synchronized (context) {
-                            if (context.aborted) {
-                                return;
-                            }
-                            context.currentOutputStream = sendStream;
-                        }
-                        //We don't want to change encoding, we just want this to write for all Unicode.
-                        sendStream.write(beforeDataBytes);
-                        totalBytes += beforeDataBytes.length;
-    
-                        // create a buffer of maximum size
-                        int bytesAvailable = sourceInputStream.available();
-                        int bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
-                        byte[] buffer = new byte[bufferSize];
-    
-                        // read file and write it into form...
-                        int bytesRead = sourceInputStream.read(buffer, 0, bufferSize);
-    
-                        long prevBytesRead = 0;
-                        while (bytesRead > 0) {
-                            result.setBytesSent(totalBytes);
-                            sendStream.write(buffer, 0, bytesRead);
-                            totalBytes += bytesRead;
-                            if (totalBytes > prevBytesRead + 102400) {
-                                prevBytesRead = totalBytes;
-                                Log.d(LOG_TAG, "Uploaded " + totalBytes + " of " + fixedLength + " bytes");
-                            }
-                            bytesAvailable = sourceInputStream.available();
-                            bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
-                            bytesRead = sourceInputStream.read(buffer, 0, bufferSize);
-
-                            // Send a progress event.
-                            progress.setLoaded(totalBytes);
-                            PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject());
-                            progressResult.setKeepCallback(true);
-                            context.sendPluginResult(progressResult);
-                        }
-    
-                        // send multipart form data necessary after file data...
-                        sendStream.write(tailParamsBytes);
-                        totalBytes += tailParamsBytes.length;
-                        sendStream.flush();
-                    } finally {
-                        safeClose(sourceInputStream);
-                        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());
-                    TrackingInputStream inStream = null;
-                    try {
-                        inStream = getInputStream(conn);
-                        synchronized (context) {
-                            if (context.aborted) {
-                                return;
-                            }
-                            context.currentInputStream = inStream;
-                        }
-                        
-                        ByteArrayOutputStream out = new ByteArrayOutputStream(Math.max(1024, conn.getContentLength()));
-                        byte[] buffer = new byte[1024];
-                        int bytesRead = 0;
-                        // write bytes to file
-                        while ((bytesRead = inStream.read(buffer)) > 0) {
-                            out.write(buffer, 0, bytesRead);
-                        }
-                        responseString = out.toString("UTF-8");
-                    } finally {
-                        context.currentInputStream = null;
-                        safeClose(inStream);
-                    }
-                    
-                    Log.d(LOG_TAG, "got response from server");
-                    Log.d(LOG_TAG, responseString.substring(0, Math.min(256, responseString.length())));
-                    
-                    // send request and retrieve response
-                    result.setResponseCode(responseCode);
-                    result.setResponse(responseString);
-
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.OK, result.toJSONObject()));
-                } catch (FileNotFoundException e) {
-                    JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, conn);
-                    Log.e(LOG_TAG, error.toString(), e);
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
-                } catch (IOException e) {
-                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn);
-                    Log.e(LOG_TAG, error.toString(), e);
-                    Log.e(LOG_TAG, "Failed after uploading " + totalBytes + " of " + fixedLength + " bytes.");
-                    context.sendPluginResult(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));
-                } catch (Throwable t) {
-                    // Shouldn't happen, but will
-                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn);
-                    Log.e(LOG_TAG, error.toString(), t);
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
-                } finally {
-                    synchronized (activeRequests) {
-                        activeRequests.remove(objectId);
-                    }
-
-                    if (conn != null) {
-                        // Revert back to the proper verifier and socket factories
-                        // Revert back to the proper verifier and socket factories
-                        if (trustEveryone && useHttps) {
-                            HttpsURLConnection https = (HttpsURLConnection) conn;
-                            https.setHostnameVerifier(oldHostnameVerifier);
-                            https.setSSLSocketFactory(oldSocketFactory);
-                        }
-                    }
-                }                
-            }
-        });
-    }
-
-    private static void safeClose(Closeable stream) {
-        if (stream != null) {
-            try {
-                stream.close();
-            } catch (IOException e) {
-            }
-        }
-    }
-
-    private static TrackingInputStream getInputStream(URLConnection conn) throws IOException {
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
-            return new DoneHandlerInputStream(conn.getInputStream());
-        }
-        String encoding = conn.getContentEncoding();
-        if (encoding != null && encoding.equalsIgnoreCase("gzip")) {
-        	return new TrackingGZIPInputStream(new ExposedGZIPInputStream(conn.getInputStream()));
-        }
-        return new TrackingHTTPInputStream(conn.getInputStream());
-    }
-
-    // always verify the host - don't check for certificate
-    private static final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
-        public boolean verify(String hostname, SSLSession session) {
-            return true;
-        }
-    };
-    // Create a trust manager that does not validate certificate chains
-    private static final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
-        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
-            return new java.security.cert.X509Certificate[] {};
-        }
-        
-        public void checkClientTrusted(X509Certificate[] chain,
-                String authType) throws CertificateException {
-        }
-        
-        public void checkServerTrusted(X509Certificate[] chain,
-                String authType) throws CertificateException {
-        }
-    } };
-
-    /**
-     * This function will install a trust manager that will blindly trust all SSL
-     * certificates.  The reason this code is being added is to enable developers
-     * to do development using self signed SSL certificates on their web server.
-     *
-     * The standard HttpsURLConnection class will throw an exception on self
-     * signed certificates if this code is not run.
-     */
-    private static SSLSocketFactory trustAllHosts(HttpsURLConnection connection) {
-        // Install the all-trusting trust manager
-        SSLSocketFactory oldFactory = connection.getSSLSocketFactory();
-        try {
-            // Install our all trusting manager
-            SSLContext sc = SSLContext.getInstance("TLS");
-            sc.init(null, trustAllCerts, new java.security.SecureRandom());
-            SSLSocketFactory newFactory = sc.getSocketFactory();
-            connection.setSSLSocketFactory(newFactory);
-        } catch (Exception e) {
-            Log.e(LOG_TAG, e.getMessage(), e);
-        }
-        return oldFactory;
-    }
-
-    private static JSONObject createFileTransferError(int errorCode, String source, String target, URLConnection connection) {
-
-        int httpStatus = 0;
-        StringBuilder bodyBuilder = new StringBuilder();
-        String body = null;
-        if (connection != null) {
-            try {
-                if (connection instanceof HttpURLConnection) {
-                    httpStatus = ((HttpURLConnection)connection).getResponseCode();
-                    InputStream err = ((HttpURLConnection) connection).getErrorStream();
-                    if(err != null)
-                    {
-                        BufferedReader reader = new BufferedReader(new InputStreamReader(err, "UTF-8"));
-                        String line = reader.readLine();
-                        while(line != null)
-                        {
-                            bodyBuilder.append(line);
-                            line = reader.readLine();
-                            if(line != null)
-                                bodyBuilder.append('\n');
-                        }
-                        body = bodyBuilder.toString();
-                    }
-                }
-            } catch (IOException e) {
-                Log.w(LOG_TAG, "Error getting HTTP status code from connection.", e);
-            }
-        }
-
-        return createFileTransferError(errorCode, source, target, body, httpStatus);
-    }
-
-        /**
-        * Create an error object based on the passed in errorCode
-        * @param errorCode 	the error
-        * @return JSONObject containing the error
-        */
-    private static JSONObject createFileTransferError(int errorCode, String source, String target, String body, Integer httpStatus) {
-        JSONObject error = null;
-        try {
-            error = new JSONObject();
-            error.put("code", errorCode);
-            error.put("source", source);
-            error.put("target", target);
-            if(body != null)
-            {
-                error.put("body", body);
-            }   
-            if (httpStatus != null) {
-                error.put("http_status", httpStatus);
-            }
-        } catch (JSONException e) {
-            Log.e(LOG_TAG, e.getMessage(), e);
-        }
-        return error;
-    }
-
-    /**
-     * Convenience method to read a parameter from the list of JSON args.
-     * @param args			the args passed to the Plugin
-     * @param position		the position to retrieve the arg from
-     * @param defaultString the default to be used if the arg does not exist
-     * @return String with the retrieved value
-     */
-    private static String getArgument(JSONArray args, int position, String defaultString) {
-        String arg = defaultString;
-        if (args.length() >= position) {
-            arg = args.optString(position);
-            if (arg == null || "null".equals(arg)) {
-                arg = defaultString;
-            }
-        }
-        return arg;
-    }
-
-    /**
-     * Downloads a file form a given URL and saves it to the specified directory.
-     *
-     * @param source        URL of the server to receive the file
-     * @param target      	Full path of the file on the file system
-     */
-    private void download(final String source, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException {
-        Log.d(LOG_TAG, "download " + source + " to " +  target);
-
-        final boolean trustEveryone = args.optBoolean(2);
-        final String objectId = args.getString(3);
-        final JSONObject headers = args.optJSONObject(4);
-
-        final URL url;
-        try {
-            url = new URL(source);
-        } catch (MalformedURLException e) {
-            JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0);
-            Log.e(LOG_TAG, error.toString(), e);
-            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
-            return;
-        }
-        final boolean useHttps = url.getProtocol().equals("https");
-
-        if (!Config.isUrlWhiteListed(source)) {
-            Log.w(LOG_TAG, "Source URL is not in white list: '" + source + "'");
-            JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, null, 401);
-            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
-            return;
-        }
-
-        
-        final RequestContext context = new RequestContext(source, target, callbackContext);
-        synchronized (activeRequests) {
-            activeRequests.put(objectId, context);
-        }
-        
-        cordova.getThreadPool().execute(new Runnable() {
-            public void run() {
-                if (context.aborted) {
-                    return;
-                }
-                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.getParentFile().mkdirs();
-        
-                    // connect to server
-                    // Open a HTTP connection to the URL based on protocol
-                    if (useHttps) {
-                        // Using standard HTTPS connection. Will not allow self signed certificate
-                        if (!trustEveryone) {
-                            connection = (HttpsURLConnection) httpClient.open(url);
-                        }
-                        // Use our HTTPS connection that blindly trusts everyone.
-                        // This should only be used in debug environments
-                        else {
-                            // Setup the HTTPS connection class to trust everyone
-                            HttpsURLConnection https = (HttpsURLConnection) httpClient.open(url);
-                            oldSocketFactory = trustAllHosts(https);
-                            // Save the current hostnameVerifier
-                            oldHostnameVerifier = https.getHostnameVerifier();
-                            // Setup the connection not to verify hostnames
-                            https.setHostnameVerifier(DO_NOT_VERIFY);
-                            connection = https;
-                        }
-                    }
-                    // Return a standard HTTP connection
-                    else {
-                          connection = httpClient.open(url);
-
-                    }
-    
-                    if (connection instanceof HttpURLConnection) {
-                        ((HttpURLConnection)connection).setRequestMethod("GET");
-                    }
-    
-                    //Add cookie support
-                    String cookie = CookieManager.getInstance().getCookie(source);
-                    if(cookie != null)
-                    {
-                        connection.setRequestProperty("cookie", cookie);
-                    }
-                    
-                    // This must be explicitly set for gzip progress tracking to work.
-                    connection.setRequestProperty("Accept-Encoding", "gzip");
-
-                    // Handle the other headers
-                    if (headers != null) {
-                        addHeadersToRequest(connection, headers);
-                    }
-    
-                    connection.connect();
-    
-                    Log.d(LOG_TAG, "Download file:" + url);
-
-                    FileProgressResult progress = new FileProgressResult();
-                    if (connection.getContentEncoding() == null || connection.getContentEncoding().equalsIgnoreCase("gzip")) {
-                        // Only trust content-length header if we understand
-                        // the encoding -- identity or gzip
-                        progress.setLengthComputable(true);
-                        progress.setTotal(connection.getContentLength());
-                    }
-                    
-                    FileOutputStream outputStream = null;
-                    TrackingInputStream inputStream = null;
-                    
-                    try {
-                        inputStream = getInputStream(connection);
-                        outputStream = new FileOutputStream(file);
-                        synchronized (context) {
-                            if (context.aborted) {
-                                return;
-                            }
-                            context.currentInputStream = inputStream;
-                        }
-                        
-                        // write bytes to file
-                        byte[] buffer = new byte[MAX_BUFFER_SIZE];
-                        int bytesRead = 0;
-                        while ((bytesRead = inputStream.read(buffer)) > 0) {
-                            outputStream.write(buffer, 0, bytesRead);
-                            // Send a progress event.
-                            progress.setLoaded(inputStream.getTotalRawBytesRead());
-                            PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject());
-                            progressResult.setKeepCallback(true);
-                            context.sendPluginResult(progressResult);
-                        }
-                    } finally {
-                        context.currentInputStream = null;
-                        safeClose(inputStream);
-                        safeClose(outputStream);
-                    }
-    
-                    Log.d(LOG_TAG, "Saved file: " + target);
-    
-                    // create FileEntry object
-                    JSONObject fileEntry = FileUtils.getEntry(file);
-                    
-                    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);
-                    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);
-                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
-                } catch (JSONException e) {
-                    Log.e(LOG_TAG, e.getMessage(), e);
-                    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);
-                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
-                } finally {
-                    synchronized (activeRequests) {
-                        activeRequests.remove(objectId);
-                    }
-
-                    if (connection != null) {
-                        // Revert back to the proper verifier and socket factories
-                        if (trustEveryone && useHttps) {
-                            HttpsURLConnection https = (HttpsURLConnection) connection;
-                            https.setHostnameVerifier(oldHostnameVerifier);
-                            https.setSSLSocketFactory(oldSocketFactory);
-                        }
-                    }
-
-                    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);
-                }
-            }
-        });
-    }
-
-    /**
-     * Get an input stream based on file path or content:// uri
-     *
-     * @param path foo
-     * @return an input stream
-     * @throws FileNotFoundException
-     */
-    private InputStream getPathFromUri(String path) throws FileNotFoundException {
-        if (path.startsWith("content:")) {
-            Uri uri = Uri.parse(path);
-            return cordova.getActivity().getContentResolver().openInputStream(uri);
-        }
-        else if (path.startsWith("file://")) {
-            int question = path.indexOf("?");
-            if (question == -1) {
-                return new FileInputStream(path.substring(7));
-            } else {
-                return new FileInputStream(path.substring(7, question));
-            }
-        }
-        else {
-            return new FileInputStream(path);
-        }
-    }
-
-    /**
-     * Get a File object from the passed in path
-     *
-     * @param path file path
-     * @return file object
-     */
-    private File getFileFromPath(String path) throws FileNotFoundException {
-        File file;
-        String prefix = "file://";
-
-        if (path.startsWith(prefix)) {
-            file = new File(path.substring(prefix.length()));
-        } else {
-            file = new File(path);
-        }
-
-        if (file.getParent() == null) {
-            throw new FileNotFoundException();
-        }
-
-        return file;
-    }
-
-    /**
-     * Abort an ongoing upload or download.
-     */
-    private void abort(String objectId) {
-        final RequestContext context;
-        synchronized (activeRequests) {
-            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, null, -1);
-            synchronized (context) {
-                context.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, error));
-                context.aborted = true;
-            }
-            // Closing the streams can block, so execute on a background thread.
-            cordova.getThreadPool().execute(new Runnable() {
-                public void run() {
-                    synchronized (context) {
-                        safeClose(context.currentInputStream);
-                        safeClose(context.currentOutputStream);
-                    }
-                }
-            });
-        }
-    }
-}


Mime
View raw message