cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject [08/17] added fireos code from https://github.com/archananaik/cordova-amazon-fireos sans history
Date Mon, 25 Nov 2013 23:43:41 GMT
http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/blob/b3b7c0b9/framework/src/com/squareup/okhttp/internal/spdy/SpdyWriter.java
----------------------------------------------------------------------
diff --git a/framework/src/com/squareup/okhttp/internal/spdy/SpdyWriter.java b/framework/src/com/squareup/okhttp/internal/spdy/SpdyWriter.java
new file mode 100644
index 0000000..b3d1d1f
--- /dev/null
+++ b/framework/src/com/squareup/okhttp/internal/spdy/SpdyWriter.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed 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 com.squareup.okhttp.internal.spdy;
+
+import com.squareup.okhttp.internal.Platform;
+import com.squareup.okhttp.internal.Util;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.zip.Deflater;
+
+/** Write spdy/3 frames. */
+final class SpdyWriter implements Closeable {
+  final DataOutputStream out;
+  private final ByteArrayOutputStream nameValueBlockBuffer;
+  private final DataOutputStream nameValueBlockOut;
+
+  SpdyWriter(OutputStream out) {
+    this.out = new DataOutputStream(out);
+
+    Deflater deflater = new Deflater();
+    deflater.setDictionary(SpdyReader.DICTIONARY);
+    nameValueBlockBuffer = new ByteArrayOutputStream();
+    nameValueBlockOut = new DataOutputStream(
+        Platform.get().newDeflaterOutputStream(nameValueBlockBuffer, deflater, true));
+  }
+
+  public synchronized void synStream(int flags, int streamId, int associatedStreamId, int priority,
+      int slot, List<String> nameValueBlock) throws IOException {
+    writeNameValueBlockToBuffer(nameValueBlock);
+    int length = 10 + nameValueBlockBuffer.size();
+    int type = SpdyConnection.TYPE_SYN_STREAM;
+
+    int unused = 0;
+    out.writeInt(0x80000000 | (SpdyConnection.VERSION & 0x7fff) << 16 | type & 0xffff);
+    out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+    out.writeInt(streamId & 0x7fffffff);
+    out.writeInt(associatedStreamId & 0x7fffffff);
+    out.writeShort((priority & 0x7) << 13 | (unused & 0x1f) << 8 | (slot & 0xff));
+    nameValueBlockBuffer.writeTo(out);
+    out.flush();
+  }
+
+  public synchronized void synReply(int flags, int streamId, List<String> nameValueBlock)
+      throws IOException {
+    writeNameValueBlockToBuffer(nameValueBlock);
+    int type = SpdyConnection.TYPE_SYN_REPLY;
+    int length = nameValueBlockBuffer.size() + 4;
+
+    out.writeInt(0x80000000 | (SpdyConnection.VERSION & 0x7fff) << 16 | type & 0xffff);
+    out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+    out.writeInt(streamId & 0x7fffffff);
+    nameValueBlockBuffer.writeTo(out);
+    out.flush();
+  }
+
+  public synchronized void headers(int flags, int streamId, List<String> nameValueBlock)
+      throws IOException {
+    writeNameValueBlockToBuffer(nameValueBlock);
+    int type = SpdyConnection.TYPE_HEADERS;
+    int length = nameValueBlockBuffer.size() + 4;
+
+    out.writeInt(0x80000000 | (SpdyConnection.VERSION & 0x7fff) << 16 | type & 0xffff);
+    out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+    out.writeInt(streamId & 0x7fffffff);
+    nameValueBlockBuffer.writeTo(out);
+    out.flush();
+  }
+
+  public synchronized void rstStream(int streamId, int statusCode) throws IOException {
+    int flags = 0;
+    int type = SpdyConnection.TYPE_RST_STREAM;
+    int length = 8;
+    out.writeInt(0x80000000 | (SpdyConnection.VERSION & 0x7fff) << 16 | type & 0xffff);
+    out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+    out.writeInt(streamId & 0x7fffffff);
+    out.writeInt(statusCode);
+    out.flush();
+  }
+
+  public synchronized void data(int flags, int streamId, byte[] data) throws IOException {
+    int length = data.length;
+    out.writeInt(streamId & 0x7fffffff);
+    out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+    out.write(data);
+    out.flush();
+  }
+
+  private void writeNameValueBlockToBuffer(List<String> nameValueBlock) throws IOException {
+    nameValueBlockBuffer.reset();
+    int numberOfPairs = nameValueBlock.size() / 2;
+    nameValueBlockOut.writeInt(numberOfPairs);
+    for (String s : nameValueBlock) {
+      nameValueBlockOut.writeInt(s.length());
+      nameValueBlockOut.write(s.getBytes("UTF-8"));
+    }
+    nameValueBlockOut.flush();
+  }
+
+  public synchronized void settings(int flags, Settings settings) throws IOException {
+    int type = SpdyConnection.TYPE_SETTINGS;
+    int size = settings.size();
+    int length = 4 + size * 8;
+    out.writeInt(0x80000000 | (SpdyConnection.VERSION & 0x7fff) << 16 | type & 0xffff);
+    out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+    out.writeInt(size);
+    for (int i = 0; i <= Settings.COUNT; i++) {
+      if (!settings.isSet(i)) continue;
+      int settingsFlags = settings.flags(i);
+      out.writeInt((settingsFlags & 0xff) << 24 | (i & 0xffffff));
+      out.writeInt(settings.get(i));
+    }
+    out.flush();
+  }
+
+  public synchronized void noop() throws IOException {
+    int type = SpdyConnection.TYPE_NOOP;
+    int length = 0;
+    int flags = 0;
+    out.writeInt(0x80000000 | (SpdyConnection.VERSION & 0x7fff) << 16 | type & 0xffff);
+    out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+    out.flush();
+  }
+
+  public synchronized void ping(int flags, int id) throws IOException {
+    int type = SpdyConnection.TYPE_PING;
+    int length = 4;
+    out.writeInt(0x80000000 | (SpdyConnection.VERSION & 0x7fff) << 16 | type & 0xffff);
+    out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+    out.writeInt(id);
+    out.flush();
+  }
+
+  public synchronized void goAway(int flags, int lastGoodStreamId, int statusCode)
+      throws IOException {
+    int type = SpdyConnection.TYPE_GOAWAY;
+    int length = 8;
+    out.writeInt(0x80000000 | (SpdyConnection.VERSION & 0x7fff) << 16 | type & 0xffff);
+    out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+    out.writeInt(lastGoodStreamId);
+    out.writeInt(statusCode);
+    out.flush();
+  }
+
+  public synchronized void windowUpdate(int streamId, int deltaWindowSize) throws IOException {
+    int type = SpdyConnection.TYPE_WINDOW_UPDATE;
+    int flags = 0;
+    int length = 8;
+    out.writeInt(0x80000000 | (SpdyConnection.VERSION & 0x7fff) << 16 | type & 0xffff);
+    out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+    out.writeInt(streamId);
+    out.writeInt(deltaWindowSize);
+    out.flush();
+  }
+
+  @Override public void close() throws IOException {
+    Util.closeAll(out, nameValueBlockOut);
+  }
+}

http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/blob/b3b7c0b9/framework/src/org/apache/cordova/App.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/App.java b/framework/src/org/apache/cordova/App.java
new file mode 100755
index 0000000..86c6572
--- /dev/null
+++ b/framework/src/org/apache/cordova/App.java
@@ -0,0 +1,225 @@
+/*
+       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.CallbackContext;
+import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.LOG;
+import org.apache.cordova.PluginResult;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.HashMap;
+
+/**
+ * This class exposes methods in Cordova that can be called from JavaScript.
+ */
+public class App extends CordovaPlugin {
+
+    /**
+     * Executes the request and returns PluginResult.
+     *
+     * @param action            The action to execute.
+     * @param args              JSONArry of arguments for the plugin.
+     * @param callbackContext   The callback context from which we were invoked.
+     * @return                  A PluginResult object with a status and message.
+     */
+    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
+        PluginResult.Status status = PluginResult.Status.OK;
+        String result = "";
+
+        try {
+            if (action.equals("clearCache")) {
+                this.clearCache();
+            }
+            else if (action.equals("show")) {
+                // This gets called from JavaScript onCordovaReady to show the webview.
+                // I recommend we change the name of the Message as spinner/stop is not
+                // indicative of what this actually does (shows the webview).
+                cordova.getActivity().runOnUiThread(new Runnable() {
+                    public void run() {
+                        webView.postMessage("spinner", "stop");
+                    }
+                });
+            }
+            else if (action.equals("loadUrl")) {
+                this.loadUrl(args.getString(0), args.optJSONObject(1));
+            }
+            else if (action.equals("cancelLoadUrl")) {
+                //this.cancelLoadUrl();
+            }
+            else if (action.equals("clearHistory")) {
+                this.clearHistory();
+            }
+            else if (action.equals("backHistory")) {
+                this.backHistory();
+            }
+            else if (action.equals("overrideButton")) {
+                this.overrideButton(args.getString(0), args.getBoolean(1));
+            }
+            else if (action.equals("overrideBackbutton")) {
+                this.overrideBackbutton(args.getBoolean(0));
+            }
+            else if (action.equals("exitApp")) {
+                this.exitApp();
+            }
+            callbackContext.sendPluginResult(new PluginResult(status, result));
+            return true;
+        } catch (JSONException e) {
+            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+            return false;
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // LOCAL METHODS
+    //--------------------------------------------------------------------------
+
+    /**
+     * Clear the resource cache.
+     */
+    public void clearCache() {
+        cordova.getActivity().runOnUiThread(new Runnable() {
+            public void run() {
+                webView.clearCache(true);
+            }
+        });
+    }
+
+    /**
+     * Load the url into the webview.
+     *
+     * @param url
+     * @param props			Properties that can be passed in to the Cordova activity (i.e. loadingDialog, wait, ...)
+     * @throws JSONException
+     */
+    public void loadUrl(String url, JSONObject props) throws JSONException {
+        LOG.d("App", "App.loadUrl("+url+","+props+")");
+        int wait = 0;
+        boolean openExternal = false;
+        boolean clearHistory = false;
+
+        // If there are properties, then set them on the Activity
+        HashMap<String, Object> params = new HashMap<String, Object>();
+        if (props != null) {
+            JSONArray keys = props.names();
+            for (int i = 0; i < keys.length(); i++) {
+                String key = keys.getString(i);
+                if (key.equals("wait")) {
+                    wait = props.getInt(key);
+                }
+                else if (key.equalsIgnoreCase("openexternal")) {
+                    openExternal = props.getBoolean(key);
+                }
+                else if (key.equalsIgnoreCase("clearhistory")) {
+                    clearHistory = props.getBoolean(key);
+                }
+                else {
+                    Object value = props.get(key);
+                    if (value == null) {
+
+                    }
+                    else if (value.getClass().equals(String.class)) {
+                        params.put(key, (String)value);
+                    }
+                    else if (value.getClass().equals(Boolean.class)) {
+                        params.put(key, (Boolean)value);
+                    }
+                    else if (value.getClass().equals(Integer.class)) {
+                        params.put(key, (Integer)value);
+                    }
+                }
+            }
+        }
+
+        // If wait property, then delay loading
+
+        if (wait > 0) {
+            try {
+                synchronized(this) {
+                    this.wait(wait);
+                }
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        this.webView.showWebPage(url, openExternal, clearHistory, params);
+    }
+
+    /**
+     * Clear page history for the app.
+     */
+    public void clearHistory() {
+        this.webView.clearHistory();
+    }
+
+    /**
+     * Go to previous page displayed.
+     * This is the same as pressing the backbutton on Android device.
+     */
+    public void backHistory() {
+        cordova.getActivity().runOnUiThread(new Runnable() {
+            public void run() {
+                webView.backHistory();
+            }
+        });
+    }
+
+    /**
+     * Override the default behavior of the Android back button.
+     * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired.
+     *
+     * @param override		T=override, F=cancel override
+     */
+    public void overrideBackbutton(boolean override) {
+        LOG.i("App", "WARNING: Back Button Default Behaviour will be overridden.  The backbutton event will be fired!");
+        webView.bindButton(override);
+    }
+
+    /**
+     * Override the default behavior of the Android volume buttons.
+     * If overridden, when the volume button is pressed, the "volume[up|down]button" JavaScript event will be fired.
+     *
+     * @param button        volumeup, volumedown
+     * @param override      T=override, F=cancel override
+     */
+    public void overrideButton(String button, boolean override) {
+        LOG.i("App", "WARNING: Volume Button Default Behaviour will be overridden.  The volume event will be fired!");
+        webView.bindButton(button, override);
+    }
+
+    /**
+     * Return whether the Android back button is overridden by the user.
+     *
+     * @return boolean
+     */
+    public boolean isBackbuttonOverridden() {
+        return webView.isBackButtonBound();
+    }
+
+    /**
+     * Exit the Android application.
+     */
+    public void exitApp() {
+        this.webView.postMessage("exit", null);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/blob/b3b7c0b9/framework/src/org/apache/cordova/AuthenticationToken.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/AuthenticationToken.java b/framework/src/org/apache/cordova/AuthenticationToken.java
new file mode 100644
index 0000000..d3a231a
--- /dev/null
+++ b/framework/src/org/apache/cordova/AuthenticationToken.java
@@ -0,0 +1,69 @@
+/*
+       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;
+
+/**
+ * The Class AuthenticationToken defines the userName and password to be used for authenticating a web resource
+ */
+public class AuthenticationToken {
+    private String userName;
+    private String password;
+
+    /**
+     * Gets the user name.
+     *
+     * @return the user name
+     */
+    public String getUserName() {
+        return userName;
+    }
+
+    /**
+     * Sets the user name.
+     *
+     * @param userName
+     *            the new user name
+     */
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    /**
+     * Gets the password.
+     *
+     * @return the password
+     */
+    public String getPassword() {
+        return password;
+    }
+
+    /**
+     * Sets the password.
+     *
+     * @param password
+     *            the new password
+     */
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+
+
+
+}

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

http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/blob/b3b7c0b9/framework/src/org/apache/cordova/Config.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/Config.java b/framework/src/org/apache/cordova/Config.java
new file mode 100644
index 0000000..716b795
--- /dev/null
+++ b/framework/src/org/apache/cordova/Config.java
@@ -0,0 +1,230 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+package org.apache.cordova;
+
+import java.io.IOException;
+
+import java.util.Locale;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.cordova.LOG;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.app.Activity;
+
+import android.content.res.XmlResourceParser;
+import android.graphics.Color;
+
+import android.util.Log;
+
+public class Config {
+
+    public static final String TAG = "Config";
+
+    private Whitelist whitelist = new Whitelist();
+    private String startUrl;
+
+    private static Config self = null;
+
+    public static void init(Activity action) {
+        //Just re-initialize this! Seriously, we lose this all the time
+        self = new Config(action);
+    }
+
+    // Intended to be used for testing only; creates an empty configuration.
+    public static void init() {
+        if (self == null) {
+            self = new Config();
+        }
+    }
+
+    // Intended to be used for testing only; creates an empty configuration.
+    private Config() {
+    }
+
+    private Config(Activity action) {
+        if (action == null) {
+            LOG.i("CordovaLog", "There is no activity. Is this on the lock screen?");
+            return;
+        }
+
+        int id = action.getResources().getIdentifier("config", "xml", action.getPackageName());
+        if (id == 0) {
+            id = action.getResources().getIdentifier("cordova", "xml", action.getPackageName());
+            LOG.i("CordovaLog", "config.xml missing, reverting to cordova.xml");
+        }
+        if (id == 0) {
+            LOG.i("CordovaLog", "cordova.xml missing. Ignoring...");
+            return;
+        }
+
+        // Add implicitly allowed URLs
+        whitelist.addWhiteListEntry("file:///*", false);
+        whitelist.addWhiteListEntry("content:///*", false);
+        whitelist.addWhiteListEntry("data:*", false);
+
+        XmlResourceParser xml = action.getResources().getXml(id);
+        int eventType = -1;
+        while (eventType != XmlResourceParser.END_DOCUMENT) {
+            if (eventType == XmlResourceParser.START_TAG) {
+                String strNode = xml.getName();
+
+                if (strNode.equals("access")) {
+                    String origin = xml.getAttributeValue(null, "origin");
+                    String subdomains = xml.getAttributeValue(null, "subdomains");
+                    if (origin != null) {
+                        whitelist.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0));
+                    }
+                }
+                else if (strNode.equals("log")) {
+                    String level = xml.getAttributeValue(null, "level");
+                    Log.d(TAG, "The <log> tags is deprecated. Use <preference name=\"loglevel\" value=\"" + level + "\"/> instead.");
+                    if (level != null) {
+                        LOG.setLogLevel(level);
+                    }
+                }
+                else if (strNode.equals("preference")) {
+                    String name = xml.getAttributeValue(null, "name").toLowerCase(Locale.getDefault());
+                    /* Java 1.6 does not support switch-based strings
+                       Java 7 does, but we're using Dalvik, which is apparently not Java.
+                       Since we're reading XML, this has to be an ugly if/else.
+                       
+                       Also, due to cast issues, each of them has to call their separate putExtra!  
+                       Wheee!!! Isn't Java FUN!?!?!?
+                       
+                       Note: We should probably pass in the classname for the variable splash on splashscreen!
+                       */
+                    if (name.equalsIgnoreCase("LogLevel")) {
+                        String level = xml.getAttributeValue(null, "value");
+                        LOG.setLogLevel(level);
+                    } else if (name.equalsIgnoreCase("SplashScreen")) {
+                        String value = xml.getAttributeValue(null, "value");
+                        int resource = 0;
+                        if (value == null)
+                        {
+                            value = "splash";
+                        }
+                        resource = action.getResources().getIdentifier(value, "drawable", action.getPackageName());
+                        
+                        action.getIntent().putExtra(name, resource);
+                    }
+                    else if(name.equalsIgnoreCase("BackgroundColor")) {
+                        int value = xml.getAttributeIntValue(null, "value", Color.BLACK);
+                        action.getIntent().putExtra(name, value);
+                    }
+                    else if(name.equalsIgnoreCase("LoadUrlTimeoutValue")) {
+                        int value = xml.getAttributeIntValue(null, "value", 20000);
+                        action.getIntent().putExtra(name, value);
+                    }
+                    else if(name.equalsIgnoreCase("SplashScreenDelay")) {
+                        int value = xml.getAttributeIntValue(null, "value", 3000);
+                        action.getIntent().putExtra(name, value);
+                    }
+                    else if(name.equalsIgnoreCase("KeepRunning"))
+                    {
+                        boolean value = xml.getAttributeValue(null, "value").equals("true");
+                        action.getIntent().putExtra(name, value);
+                    }
+                    else if(name.equalsIgnoreCase("InAppBrowserStorageEnabled"))
+                    {
+                        boolean value = xml.getAttributeValue(null, "value").equals("true");
+                        action.getIntent().putExtra(name, value);
+                    }
+                    else if(name.equalsIgnoreCase("DisallowOverscroll"))
+                    {
+                        boolean value = xml.getAttributeValue(null, "value").equals("true");
+                        action.getIntent().putExtra(name, value);
+                    }
+                    else
+                    {
+                        String value = xml.getAttributeValue(null, "value");
+                        action.getIntent().putExtra(name, value);
+                    }
+                    /*
+                    LOG.i("CordovaLog", "Found preference for %s=%s", name, value);
+                     */
+                }
+                else if (strNode.equals("content")) {
+                    String src = xml.getAttributeValue(null, "src");
+
+                    LOG.i("CordovaLog", "Found start page location: %s", src);
+
+                    if (src != null) {
+                        Pattern schemeRegex = Pattern.compile("^[a-z-]+://");
+                        Matcher matcher = schemeRegex.matcher(src);
+                        if (matcher.find()) {
+                            startUrl = src;
+                        } else {
+                            if (src.charAt(0) == '/') {
+                                src = src.substring(1);
+                            }
+                            startUrl = "file:///android_asset/www/" + src;
+                        }
+                    }
+                }
+
+            }
+
+            try {
+                eventType = xml.next();
+            } catch (XmlPullParserException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Add entry to approved list of URLs (whitelist)
+     *
+     * @param origin        URL regular expression to allow
+     * @param subdomains    T=include all subdomains under origin
+     */
+    public static void addWhiteListEntry(String origin, boolean subdomains) {
+        if (self == null) {
+            return;
+        }
+        self.whitelist.addWhiteListEntry(origin, subdomains);
+    }
+
+    /**
+     * Determine if URL is in approved list of URLs to load.
+     *
+     * @param url
+     * @return
+     */
+    public static boolean isUrlWhiteListed(String url) {
+        if (self == null) {
+            return false;
+        }
+        return self.whitelist.isUrlWhiteListed(url);
+    }
+
+    public static String getStartUrl() {
+        if (self == null || self.startUrl == null) {
+            return "file:///android_asset/www/index.html";
+        }
+        return self.startUrl;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/blob/b3b7c0b9/framework/src/org/apache/cordova/CordovaActivity.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaActivity.java b/framework/src/org/apache/cordova/CordovaActivity.java
new file mode 100755
index 0000000..897b54e
--- /dev/null
+++ b/framework/src/org/apache/cordova/CordovaActivity.java
@@ -0,0 +1,1251 @@
+/*
+       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.HashMap;
+import java.util.Locale;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.apache.cordova.CordovaInterface;
+import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.LOG;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.Color;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.Display;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import com.amazon.android.webkit.AmazonValueCallback;
+import com.amazon.android.webkit.AmazonWebViewClient;
+import com.amazon.android.webkit.AmazonWebKitFactory;
+import com.amazon.android.webkit.AmazonWebKitFactories;
+import android.widget.LinearLayout;
+
+/**
+ * This class is the main Android activity that represents the Cordova
+ * application.  It should be extended by the user to load the specific
+ * html file that contains the application.
+ *
+ * As an example:
+ *
+ *     package org.apache.cordova.examples;
+ *     import android.os.Bundle;
+ *     import org.apache.cordova.*;
+ *
+ *     public class Example extends CordovaActivity {
+ *       @Override
+ *       public void onCreate(Bundle savedInstanceState) {
+ *         super.onCreate(savedInstanceState);
+ *
+ *         // Set properties for activity
+ *         super.setStringProperty("loadingDialog", "Title,Message"); // show loading dialog
+ *         super.setStringProperty("errorUrl", "file:///android_asset/www/error.html"); // if error loading file in super.loadUrl().
+ *
+ *         // Clear cache if you want
+ *         super.appView.clearCache(true);
+ *
+ *         // Load your application
+ *         super.setIntegerProperty("splashscreen", R.drawable.splash); // load splash.jpg image from the resource drawable directory
+ *         super.loadUrl("file:///android_asset/www/index.html", 3000); // show splash screen 3 sec before loading app
+ *       }
+ *     }
+ *
+ * Properties: The application can be configured using the following properties:
+ *
+ *      // Display a native loading dialog when loading app.  Format for value = "Title,Message".
+ *      // (String - default=null)
+ *      super.setStringProperty("loadingDialog", "Wait,Loading Demo...");
+ *
+ *      // Display a native loading dialog when loading sub-pages.  Format for value = "Title,Message".
+ *      // (String - default=null)
+ *      super.setStringProperty("loadingPageDialog", "Loading page...");
+ *
+ *      // Load a splash screen image from the resource drawable directory.
+ *      // (Integer - default=0)
+ *      super.setIntegerProperty("splashscreen", R.drawable.splash);
+ *
+ *      // Set the background color.
+ *      // (Integer - default=0 or BLACK)
+ *      super.setIntegerProperty("backgroundColor", Color.WHITE);
+ *
+ *      // Time in msec to wait before triggering a timeout error when loading
+ *      // with super.loadUrl().  (Integer - default=20000)
+ *      super.setIntegerProperty("loadUrlTimeoutValue", 60000);
+ *
+ *      // URL to load if there's an error loading specified URL with loadUrl().
+ *      // Should be a local URL starting with file://. (String - default=null)
+ *      super.setStringProperty("errorUrl", "file:///android_asset/www/error.html");
+ *
+ *      // Enable app to keep running in background. (Boolean - default=true)
+ *      super.setBooleanProperty("keepRunning", false);
+ *
+ * Cordova.xml configuration:
+ *      Cordova uses a configuration file at res/xml/cordova.xml to specify the following settings.
+ *
+ *      Approved list of URLs that can be loaded into Cordova
+ *          <access origin="http://server regexp" subdomains="true" />
+ *      Log level: ERROR, WARN, INFO, DEBUG, VERBOSE (default=ERROR)
+ *          <log level="DEBUG" />
+ *
+ */
+public class CordovaActivity extends Activity implements CordovaInterface {
+    public static String TAG = "CordovaActivity";
+
+    // The webview for our app
+    protected CordovaWebView appView;
+    protected CordovaWebViewClient webViewClient;
+
+    protected LinearLayout root;
+    protected boolean cancelLoadUrl = false;
+    protected ProgressDialog spinnerDialog = null;
+    private final ExecutorService threadPool = Executors.newCachedThreadPool();
+
+
+    // The initial URL for our app
+    // ie http://server/path/index.html#abc?query
+    //private String url = null;
+
+    private static int ACTIVITY_STARTING = 0;
+    private static int ACTIVITY_RUNNING = 1;
+    private static int ACTIVITY_EXITING = 2;
+    private int activityState = 0;  // 0=starting, 1=running (after 1st resume), 2=shutting down
+
+    // Plugin to call when activity result is received
+    protected CordovaPlugin activityResultCallback = null;
+    protected boolean activityResultKeepRunning;
+
+    // Default background color for activity
+    // (this is not the color for the webview, which is set in HTML)
+    private int backgroundColor = Color.BLACK;
+
+    /*
+     * The variables below are used to cache some of the activity properties.
+     */
+
+    // Draw a splash screen using an image located in the drawable resource directory.
+    // This is not the same as calling super.loadSplashscreen(url)
+    protected int splashscreen = 0;
+    protected int splashscreenTime = 3000;
+
+    // LoadUrl timeout value in msec (default of 20 sec)
+    protected int loadUrlTimeoutValue = 20000;
+
+    // Keep app running when pause is received. (default = true)
+    // If true, then the JavaScript and native code continue to run in the background
+    // when another application (activity) is started.
+    protected boolean keepRunning = true;
+
+    private int lastRequestCode;
+
+    private Object responseCode;
+
+    private Intent lastIntent;
+
+    private Object lastResponseCode;
+
+    private String initCallbackClass;
+
+    private Object LOG_TAG;
+
+    private static boolean sFactoryInit = false;
+    private AmazonWebKitFactory factory = null;
+
+    private static final String AMAZON_WEBVIEW_LIB_PACKAGE="com.amazon.webview";
+    private static final String ANDROID_WEBKIT_FACTORY_MISSING = "AndroidWebKit classes are missing. Please copy android_interface.jar from AmazonWebView SDK to app's libs folder and then rebuild the app.";
+    private static final String ERROR_DIALOG_TITLE = "Application Error";
+    private static final String ERROR_DIALOG_OK_BUTTON = "OK";
+    /**
+    * Sets the authentication token.
+    *
+    * @param authenticationToken
+    * @param host
+    * @param realm
+    */
+    public void setAuthenticationToken(AuthenticationToken authenticationToken, String host, String realm) {
+        if (this.appView != null && this.appView.viewClient != null) {
+            this.appView.viewClient.setAuthenticationToken(authenticationToken, host, realm);
+        }
+    }
+
+    /**
+     * Removes the authentication token.
+     *
+     * @param host
+     * @param realm
+     *
+     * @return the authentication token or null if did not exist
+     */
+    public AuthenticationToken removeAuthenticationToken(String host, String realm) {
+        if (this.appView != null && this.appView.viewClient != null) {
+            return this.appView.viewClient.removeAuthenticationToken(host, realm);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the authentication token.
+     *
+     * In order it tries:
+     * 1- host + realm
+     * 2- host
+     * 3- realm
+     * 4- no host, no realm
+     *
+     * @param host
+     * @param realm
+     *
+     * @return the authentication token
+     */
+    public AuthenticationToken getAuthenticationToken(String host, String realm) {
+        if (this.appView != null && this.appView.viewClient != null) {
+            return this.appView.viewClient.getAuthenticationToken(host, realm);
+        }
+        return null;
+    }
+
+    /**
+     * Clear all authentication tokens.
+     */
+    public void clearAuthenticationTokens() {
+        if (this.appView != null && this.appView.viewClient != null) {
+            this.appView.viewClient.clearAuthenticationTokens();
+        }
+    }
+
+    /**
+     * Called when the activity is first created.
+     *
+     * @param savedInstanceState
+     */
+    @SuppressWarnings("deprecation")
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        Config.init(this);
+        LOG.d(TAG, "CordovaActivity.onCreate()");
+        super.onCreate(savedInstanceState);
+        try {
+        	if (!sFactoryInit) {
+                // To override the default factory (Chromium-based or Android WebKit factory), uncomment one of the following lines:
+                // AmazonWebKitFactories.setDefaultFactory("com.amazon.android.webkit.embedded.EmbeddedWebKitFactory");
+                // AmazonWebKitFactories.setDefaultFactory("com.amazon.android.webkit.android.AndroidWebKitFactory");
+                
+                factory = AmazonWebKitFactories.getDefaultFactory();
+                if (factory.isRenderProcess(this)) {
+                    return; // Do nothing if this is on render process
+                }
+                factory.setNativeLibraryPackage(AMAZON_WEBVIEW_LIB_PACKAGE);
+                factory.initialize(this);
+                factory.disableDeveloperTools();
+                // factory configuration
+                factory.getCookieManager().setAcceptCookie(true);
+
+                sFactoryInit = true;
+            } else {
+                factory = AmazonWebKitFactories.getDefaultFactory();
+            }
+
+        } catch (ExceptionInInitializerError e) {
+        	LOG.e(TAG, "WebKit factory initialization failed. Make sure you have android_interface.jar in libs folder.");
+        	displayError(ERROR_DIALOG_TITLE, ANDROID_WEBKIT_FACTORY_MISSING, ERROR_DIALOG_OK_BUTTON, true);
+        } catch (NoClassDefFoundError e) {
+        	LOG.e(TAG, "WebKit factory initialization failed. Make sure you have android_interface.jar in libs folder.");
+        	displayError(ERROR_DIALOG_TITLE, ANDROID_WEBKIT_FACTORY_MISSING, ERROR_DIALOG_OK_BUTTON, true);
+        } catch (Exception e) {
+        	LOG.e(TAG, "WebKit factory initialization failed.");
+        	displayError(ERROR_DIALOG_TITLE, ANDROID_WEBKIT_FACTORY_MISSING, ERROR_DIALOG_OK_BUTTON, true);
+        }
+        
+        if (savedInstanceState != null)
+        {
+            initCallbackClass = savedInstanceState.getString("callbackClass");
+        }
+
+        if (!this.getBooleanProperty("ShowTitle", false))
+        {
+            getWindow().requestFeature(Window.FEATURE_NO_TITLE);
+        }
+
+        if (this.getBooleanProperty("SetFullscreen", false))
+        {
+            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+                WindowManager.LayoutParams.FLAG_FULLSCREEN);
+        }
+        else
+        {
+            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,
+                WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+        }
+        // This builds the view. We could probably get away with NOT having a LinearLayout, but I like having a bucket!
+        Display display = getWindowManager().getDefaultDisplay();
+        int width = display.getWidth();
+        int height = display.getHeight();
+
+        root = new LinearLayoutSoftKeyboardDetect(this, width, height);
+        root.setOrientation(LinearLayout.VERTICAL);
+        root.setBackgroundColor(this.backgroundColor);
+        root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+            ViewGroup.LayoutParams.MATCH_PARENT, 0.0F));
+
+        // Setup the hardware volume controls to handle volume control
+        setVolumeControlStream(AudioManager.STREAM_MUSIC);
+    }
+
+    /**
+     * Get the Android activity.
+     *
+     * @return
+     */
+    public Activity getActivity() {
+        return this;
+    }
+    
+    /**
+     * Get the WebKit factory.
+     *
+     * @return
+     */
+    public AmazonWebKitFactory getFactory() {
+        return this.factory;
+    }
+
+    /**
+     * Construct the default web view object.
+     *
+     * This is intended to be overridable by subclasses of CordovaIntent which
+     * require a more specialized web view.
+     */
+    protected CordovaWebView makeWebView() {
+        return new CordovaWebView(CordovaActivity.this);
+    }
+
+    /**
+     * Construct the client for the default web view object.
+     *
+     * This is intended to be overridable by subclasses of CordovaIntent which
+     * require a more specialized web view.
+     *
+     * @param webView the default constructed web view object
+     */
+    protected CordovaWebViewClient makeWebViewClient(CordovaWebView webView) {
+        if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) {
+            return new CordovaWebViewClient(this, webView);
+        } else {
+            return new IceCreamCordovaWebViewClient(this, webView);
+        }
+    }
+
+    /**
+     * Construct the chrome client for the default web view object.
+     *
+     * This is intended to be overridable by subclasses of CordovaIntent which
+     * require a more specialized web view.
+     *
+     * @param webView the default constructed web view object
+     */
+    protected CordovaChromeClient makeChromeClient(CordovaWebView webView) {
+        return new CordovaChromeClient(this, webView);
+    }
+
+    /**
+     * Create and initialize web container with default web view objects.
+     */
+    public void init() {
+    	if (factory != null) {
+    		CordovaWebView webView = makeWebView();
+    		this.init(webView, makeWebViewClient(webView), makeChromeClient(webView));
+    	}
+    }
+
+    /**
+     * Initialize web container with web view objects.
+     *
+     * @param webView
+     * @param webViewClient
+     * @param webChromeClient
+     */
+    @SuppressLint("NewApi")
+    public void init(CordovaWebView webView, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient) {
+        LOG.d(TAG, "CordovaActivity.init()");
+
+        // Set up web container
+        this.appView = webView;
+        this.appView.setId(100);
+
+        this.appView.setWebViewClient(webViewClient);
+        this.appView.setWebChromeClient(webChromeClient);
+        webViewClient.setWebView(this.appView);
+        webChromeClient.setWebView(this.appView);
+
+        this.appView.setLayoutParams(new LinearLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                1.0F));
+
+        if (this.getBooleanProperty("DisallowOverscroll", false)) {
+            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD) {
+                this.appView.setOverScrollMode(CordovaWebView.OVER_SCROLL_NEVER);
+            }
+        }
+
+        // Add web view but make it invisible while loading URL
+        this.appView.setVisibility(View.INVISIBLE);
+        this.root.addView(this.appView);
+        setContentView(this.root);
+
+        // Clear cancel flag
+        this.cancelLoadUrl = false;
+        
+    }
+
+    /**
+     * Load the url into the webview.
+     *
+     * @param url
+     */
+    public void loadUrl(String url) {
+
+        // Init web view if not already done
+        if (this.appView == null) {
+            this.init();
+            // check again if its still null then exit. Something is wrong - factory is not initialized or webview is not created
+            if (this.appView == null) {
+            	return;
+            }
+        }
+
+        this.splashscreenTime = this.getIntegerProperty("SplashScreenDelay", this.splashscreenTime);
+        if(this.splashscreenTime > 0)
+        {
+            this.splashscreen = this.getIntegerProperty("SplashScreen", 0);
+            if(this.splashscreen != 0)
+            {
+                this.showSplashScreen(this.splashscreenTime);
+            }
+        }
+        
+        // Set backgroundColor
+        this.backgroundColor = this.getIntegerProperty("BackgroundColor", Color.BLACK);
+        this.root.setBackgroundColor(this.backgroundColor);
+
+        // If keepRunning
+        this.keepRunning = this.getBooleanProperty("KeepRunning", true);
+
+        //Check if the view is attached to anything
+        if(appView.getParent() != null)
+        {
+            // Then load the spinner
+            this.loadSpinner();
+        }
+        //Load the correct splashscreen
+        
+        if(this.splashscreen != 0)
+        {
+            this.appView.loadUrl(url, this.splashscreenTime);
+        }
+        else
+        {
+            this.appView.loadUrl(url);
+        }
+    }
+
+    /**
+     * Load the url into the webview after waiting for period of time.
+     * This is used to display the splashscreen for certain amount of time.
+     *
+     * @param url
+     * @param time              The number of ms to wait before loading webview
+     */
+    public void loadUrl(final String url, int time) {
+
+        this.splashscreenTime = time;
+        this.loadUrl(url);
+        
+        /*
+        // Init web view if not already done
+        if (this.appView == null) {
+            this.init();
+        }
+
+        this.splashscreenTime = time;
+        this.splashscreen = this.getIntegerProperty("SplashScreen", 0);
+        this.showSplashScreen(this.splashscreenTime);
+        this.appView.loadUrl(url, time);
+        */
+    }
+    
+    /*
+     * Load the spinner
+     */
+    void loadSpinner() {
+
+        // If loadingDialog property, then show the App loading dialog for first page of app
+        String loading = null;
+        if ((this.appView == null) || !this.appView.canGoBack()) {
+            loading = this.getStringProperty("LoadingDialog", null);
+        }
+        else {
+            loading = this.getStringProperty("LoadingPageDialog", null);
+        }
+        if (loading != null) {
+
+            String title = "";
+            String message = "Loading Application...";
+
+            if (loading.length() > 0) {
+                int comma = loading.indexOf(',');
+                if (comma > 0) {
+                    title = loading.substring(0, comma);
+                    message = loading.substring(comma + 1);
+                }
+                else {
+                    title = "";
+                    message = loading;
+                }
+            }
+            this.spinnerStart(title, message);
+        }
+    }
+
+
+    /**
+     * Cancel loadUrl before it has been loaded.
+     */
+    // TODO NO-OP
+    @Deprecated
+    public void cancelLoadUrl() {
+        this.cancelLoadUrl = true;
+    }
+
+    /**
+     * Clear the resource cache.
+     */
+    public void clearCache() {
+        if (this.appView == null) {
+            this.init();
+        }
+        this.appView.clearCache(true);
+    }
+
+    /**
+     * Clear web history in this web view.
+     */
+    public void clearHistory() {
+        this.appView.clearHistory();
+    }
+
+    /**
+     * Go to previous page in history.  (We manage our own history)
+     *
+     * @return true if we went back, false if we are already at top
+     */
+    public boolean backHistory() {
+        if (this.appView != null) {
+            return appView.backHistory();
+        }
+        return false;
+    }
+
+    @Override
+    /**
+     * Called by the system when the device configuration changes while your activity is running.
+     *
+     * @param Configuration newConfig
+     */
+    public void onConfigurationChanged(Configuration newConfig) {
+        //don't reload the current page when the orientation is changed
+        super.onConfigurationChanged(newConfig);
+    }
+
+    /**
+     * Get boolean property for activity.
+     *
+     * @param name
+     * @param defaultValue
+     * @return
+     */
+    public boolean getBooleanProperty(String name, boolean defaultValue) {
+        Bundle bundle = this.getIntent().getExtras();
+        if (bundle == null) {
+            return defaultValue;
+        }
+        name = name.toLowerCase(Locale.getDefault());
+        Boolean p;
+        try {
+            p = (Boolean) bundle.get(name);
+        } catch (ClassCastException e) {
+            String s = bundle.get(name).toString();
+            if ("true".equals(s)) {
+                p = true;
+            }
+            else {
+                p = false;
+            }
+        }
+        if (p == null) {
+            return defaultValue;
+        }
+        return p.booleanValue();
+    }
+
+    /**
+     * Get int property for activity.
+     *
+     * @param name
+     * @param defaultValue
+     * @return
+     */
+    public int getIntegerProperty(String name, int defaultValue) {
+        Bundle bundle = this.getIntent().getExtras();
+        if (bundle == null) {
+            return defaultValue;
+        }
+        name = name.toLowerCase(Locale.getDefault());
+        Integer p;
+        try {
+            p = (Integer) bundle.get(name);
+        } catch (ClassCastException e) {
+            p = Integer.parseInt(bundle.get(name).toString());
+        }
+        if (p == null) {
+            return defaultValue;
+        }
+        return p.intValue();
+    }
+
+    /**
+     * Get string property for activity.
+     *
+     * @param name
+     * @param defaultValue
+     * @return
+     */
+    public String getStringProperty(String name, String defaultValue) {
+        Bundle bundle = this.getIntent().getExtras();
+        if (bundle == null) {
+            return defaultValue;
+        }
+        name = name.toLowerCase(Locale.getDefault());
+        String p = bundle.getString(name);
+        if (p == null) {
+            return defaultValue;
+        }
+        return p;
+    }
+
+    /**
+     * Get double property for activity.
+     *
+     * @param name
+     * @param defaultValue
+     * @return
+     */
+    public double getDoubleProperty(String name, double defaultValue) {
+        Bundle bundle = this.getIntent().getExtras();
+        if (bundle == null) {
+            return defaultValue;
+        }
+        name = name.toLowerCase(Locale.getDefault());
+        Double p;
+        try {
+            p = (Double) bundle.get(name);
+        } catch (ClassCastException e) {
+            p = Double.parseDouble(bundle.get(name).toString());
+        }
+        if (p == null) {
+            return defaultValue;
+        }
+        return p.doubleValue();
+    }
+
+    /**
+     * Set boolean property on activity.
+     *
+     * @param name
+     * @param value
+     */
+    public void setBooleanProperty(String name, boolean value) {
+        Log.d(TAG, "Setting boolean properties in CordovaActivity will be deprecated in 3.0 on July 2013, please use config.xml");
+        this.getIntent().putExtra(name.toLowerCase(), value);
+    }
+
+    /**
+     * Set int property on activity.
+     *
+     * @param name
+     * @param value
+     */
+    public void setIntegerProperty(String name, int value) {
+        Log.d(TAG, "Setting integer properties in CordovaActivity will be deprecated in 3.0 on July 2013, please use config.xml");
+        this.getIntent().putExtra(name.toLowerCase(), value);
+    }
+
+    /**
+     * Set string property on activity.
+     *
+     * @param name
+     * @param value
+     */
+    public void setStringProperty(String name, String value) {
+        Log.d(TAG, "Setting string properties in CordovaActivity will be deprecated in 3.0 on July 2013, please use config.xml");
+        this.getIntent().putExtra(name.toLowerCase(), value);
+    }
+
+    /**
+     * Set double property on activity.
+     *
+     * @param name
+     * @param value
+     */
+    public void setDoubleProperty(String name, double value) {
+        Log.d(TAG, "Setting double properties in CordovaActivity will be deprecated in 3.0 on July 2013, please use config.xml");
+        this.getIntent().putExtra(name.toLowerCase(), value);
+    }
+
+    @Override
+    /**
+     * Called when the system is about to start resuming a previous activity.
+     */
+    protected void onPause() {
+        super.onPause();
+
+        LOG.d(TAG, "Paused the application!");
+
+        // Don't process pause if shutting down, since onDestroy() will be called
+        if (this.activityState == ACTIVITY_EXITING) {
+            return;
+        }
+
+        if (this.appView == null) {
+            return;
+        }
+        else
+        {
+            this.appView.handlePause(this.keepRunning);
+        }
+
+        // hide the splash screen to avoid leaking a window
+        this.removeSplashScreen();
+    }
+
+    @Override
+    /**
+     * Called when the activity receives a new intent
+     **/
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        //Forward to plugins
+        if (this.appView != null)
+           this.appView.onNewIntent(intent);
+    }
+
+    @Override
+    /**
+     * Called when the activity will start interacting with the user.
+     */
+    protected void onResume() {
+        super.onResume();
+        //Reload the configuration
+        Config.init(this);
+
+        LOG.d(TAG, "Resuming the App");
+        
+
+        //Code to test CB-3064
+        String errorUrl = this.getStringProperty("ErrorUrl", null);
+        LOG.d(TAG, "CB-3064: The errorUrl is " + errorUrl);
+          
+        if (this.activityState == ACTIVITY_STARTING) {
+            this.activityState = ACTIVITY_RUNNING;
+            return;
+        }
+
+        if (this.appView == null) {
+            return;
+        }
+
+        this.appView.handleResume(this.keepRunning, this.activityResultKeepRunning);
+
+        // If app doesn't want to run in background
+        if (!this.keepRunning || this.activityResultKeepRunning) {
+
+            // Restore multitasking state
+            if (this.activityResultKeepRunning) {
+                this.keepRunning = this.activityResultKeepRunning;
+                this.activityResultKeepRunning = false;
+            }
+        }
+    }
+
+    @Override
+    /**
+     * The final call you receive before your activity is destroyed.
+     */
+    public void onDestroy() {
+        LOG.d(TAG, "CordovaActivity.onDestroy()");
+        super.onDestroy();
+
+        // hide the splash screen to avoid leaking a window
+        this.removeSplashScreen();
+
+        if (this.appView != null) {
+            appView.handleDestroy();
+        }
+        else {
+            this.activityState = ACTIVITY_EXITING; 
+        }
+    }
+
+    /**
+     * Send a message to all plugins.
+     *
+     * @param id            The message id
+     * @param data          The message data
+     */
+    public void postMessage(String id, Object data) {
+        if (this.appView != null) {
+            this.appView.postMessage(id, data);
+        }
+    }
+
+    /**
+     * @deprecated
+     * Add services to res/xml/plugins.xml instead.
+     *
+     * Add a class that implements a service.
+     *
+     * @param serviceType
+     * @param className
+     */
+    public void addService(String serviceType, String className) {
+        if (this.appView != null && this.appView.pluginManager != null) {
+            this.appView.pluginManager.addService(serviceType, className);
+        }
+    }
+
+    /**
+     * Send JavaScript statement back to JavaScript.
+     * (This is a convenience method)
+     *
+     * @param statement
+     */
+    public void sendJavascript(String statement) {
+        if (this.appView != null) {
+            this.appView.jsMessageQueue.addJavaScript(statement);
+        }
+    }
+
+    /**
+     * Show the spinner.  Must be called from the UI thread.
+     *
+     * @param title         Title of the dialog
+     * @param message       The message of the dialog
+     */
+    public void spinnerStart(final String title, final String message) {
+        if (this.spinnerDialog != null) {
+            this.spinnerDialog.dismiss();
+            this.spinnerDialog = null;
+        }
+        final CordovaActivity me = this;
+        this.spinnerDialog = ProgressDialog.show(CordovaActivity.this, title, message, true, true,
+                new DialogInterface.OnCancelListener() {
+                    public void onCancel(DialogInterface dialog) {
+                        me.spinnerDialog = null;
+                    }
+                });
+    }
+
+    /**
+     * Stop spinner - Must be called from UI thread
+     */
+    public void spinnerStop() {
+        if (this.spinnerDialog != null && this.spinnerDialog.isShowing()) {
+            this.spinnerDialog.dismiss();
+            this.spinnerDialog = null;
+        }
+    }
+
+    /**
+     * End this activity by calling finish for activity
+     */
+    public void endActivity() {
+        this.activityState = ACTIVITY_EXITING;
+        super.finish();
+    }
+
+
+    /**
+     * Launch an activity for which you would like a result when it finished. When this activity exits,
+     * your onActivityResult() method will be called.
+     *
+     * @param command           The command object
+     * @param intent            The intent to start
+     * @param requestCode       The request code that is passed to callback to identify the activity
+     */
+    public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
+        this.activityResultCallback = command;
+        this.activityResultKeepRunning = this.keepRunning;
+
+        // If multitasking turned on, then disable it for activities that return results
+        if (command != null) {
+            this.keepRunning = false;
+        }
+
+        // Start activity
+        super.startActivityForResult(intent, requestCode);
+    }
+
+    @Override
+    /**
+     * Called when an activity you launched exits, giving you the requestCode you started it with,
+     * the resultCode it returned, and any additional data from it.
+     *
+     * @param requestCode       The request code originally supplied to startActivityForResult(),
+     *                          allowing you to identify who this result came from.
+     * @param resultCode        The integer result code returned by the child activity through its setResult().
+     * @param data              An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
+     */
+    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
+        LOG.d(TAG, "Incoming Result");
+        super.onActivityResult(requestCode, resultCode, intent);
+        Log.d(TAG, "Request code = " + requestCode);
+        if (appView != null && requestCode == CordovaChromeClient.FILECHOOSER_RESULTCODE) {
+            AmazonValueCallback<Uri> mUploadMessage = this.appView.getWebChromeClient().getValueCallback();
+            Log.d(TAG, "did we get here?");
+            if (null == mUploadMessage)
+                return;
+            Uri result = intent == null || resultCode != Activity.RESULT_OK ? null : intent.getData();
+            Log.d(TAG, "result = " + result);
+//            Uri filepath = Uri.parse("file://" + FileUtils.getRealPathFromURI(result, this));
+//            Log.d(TAG, "result = " + filepath);
+            mUploadMessage.onReceiveValue(result);
+            mUploadMessage = null;
+        }
+        CordovaPlugin callback = this.activityResultCallback;
+        if(callback == null && initCallbackClass != null) {
+            // The application was restarted, but had defined an initial callback
+            // before being shut down.
+            this.activityResultCallback = appView.pluginManager.getPlugin(initCallbackClass);
+            callback = this.activityResultCallback;
+        }
+        if(callback != null) {
+            LOG.d(TAG, "We have a callback to send this result to");
+            callback.onActivityResult(requestCode, resultCode, intent);
+        }
+    }
+
+    public void setActivityResultCallback(CordovaPlugin plugin) {
+        this.activityResultCallback = plugin;
+    }
+
+    /**
+     * Report an error to the host application. These errors are unrecoverable (i.e. the main resource is unavailable).
+     * The errorCode parameter corresponds to one of the ERROR_* constants.
+     *
+     * @param errorCode    The error code corresponding to an ERROR_* value.
+     * @param description  A String describing the error.
+     * @param failingUrl   The url that failed to load.
+     */
+    public void onReceivedError(final int errorCode, final String description, final String failingUrl) {
+        final CordovaActivity me = this;
+
+        // If errorUrl specified, then load it
+        final String errorUrl = me.getStringProperty("errorUrl", null);
+        if ((errorUrl != null) && (errorUrl.startsWith("file://") || Config.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) {
+
+            // Load URL on UI thread
+            me.runOnUiThread(new Runnable() {
+                public void run() {
+                    // Stop "app loading" spinner if showing
+                    me.spinnerStop();
+                    me.appView.showWebPage(errorUrl, false, true, null);
+                }
+            });
+        }
+        // If not, then display error dialog
+        else {
+            final boolean exit = !(errorCode == AmazonWebViewClient.ERROR_HOST_LOOKUP);
+            me.runOnUiThread(new Runnable() {
+                public void run() {
+                    if (exit) {
+                        me.appView.setVisibility(View.GONE);
+                        me.displayError("Application Error", description + " (" + failingUrl + ")", "OK", exit);
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Display an error dialog and optionally exit application.
+     *
+     * @param title
+     * @param message
+     * @param button
+     * @param exit
+     */
+    public void displayError(final String title, final String message, final String button, final boolean exit) {
+        final CordovaActivity me = this;
+        me.runOnUiThread(new Runnable() {
+            public void run() {
+                try {
+                    AlertDialog.Builder dlg = new AlertDialog.Builder(me);
+                    dlg.setMessage(message);
+                    dlg.setTitle(title);
+                    dlg.setCancelable(false);
+                    dlg.setPositiveButton(button,
+                            new AlertDialog.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int which) {
+                                    dialog.dismiss();
+                                    if (exit) {
+                                        endActivity();
+                                    }
+                                }
+                            });
+                    dlg.create();
+                    dlg.show();
+                } catch (Exception e) {
+                    finish();
+                }
+            }
+        });
+    }
+
+    /**
+     * Determine if URL is in approved list of URLs to load.
+     *
+     * @param url
+     * @return
+     */
+    public boolean isUrlWhiteListed(String url) {
+        return Config.isUrlWhiteListed(url);
+    }
+
+    /*
+     * Hook in Cordova for menu plugins
+     *
+     */
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        this.postMessage("onCreateOptionsMenu", menu);
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        this.postMessage("onPrepareOptionsMenu", menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        this.postMessage("onOptionsItemSelected", item);
+        return true;
+    }
+
+    /**
+     * Get Activity context.
+     *
+     * @return
+     */
+    public Context getContext() {
+        LOG.d(TAG, "This will be deprecated December 2012");
+        return this;
+    }
+
+    /**
+     * Load the specified URL in the Cordova webview or a new browser instance.
+     *
+     * NOTE: If openExternal is false, only URLs listed in whitelist can be loaded.
+     *
+     * @param url           The url to load.
+     * @param openExternal  Load url in browser instead of Cordova webview.
+     * @param clearHistory  Clear the history stack, so new page becomes top of history
+     * @param params        Parameters for new app
+     */
+    public void showWebPage(String url, boolean openExternal, boolean clearHistory, HashMap<String, Object> params) {
+        if (this.appView != null) {
+            appView.showWebPage(url, openExternal, clearHistory, params);
+        }
+    }
+
+    protected Dialog splashDialog;
+
+    /**
+     * Removes the Dialog that displays the splash screen
+     */
+    public void removeSplashScreen() {
+        if (splashDialog != null && splashDialog.isShowing()) {
+            splashDialog.dismiss();
+            splashDialog = null;
+        }
+    }
+
+    /**
+     * Shows the splash screen over the full Activity
+     */
+    @SuppressWarnings("deprecation")
+    protected void showSplashScreen(final int time) {
+        final CordovaActivity that = this;
+
+        Runnable runnable = new Runnable() {
+            public void run() {
+                // Get reference to display
+                Display display = getWindowManager().getDefaultDisplay();
+
+                // Create the layout for the dialog
+                LinearLayout root = new LinearLayout(that.getActivity());
+                root.setMinimumHeight(display.getHeight());
+                root.setMinimumWidth(display.getWidth());
+                root.setOrientation(LinearLayout.VERTICAL);
+                root.setBackgroundColor(that.getIntegerProperty("backgroundColor", Color.BLACK));
+                root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                        ViewGroup.LayoutParams.MATCH_PARENT, 0.0F));
+                root.setBackgroundResource(that.splashscreen);
+                
+                // Create and show the dialog
+                splashDialog = new Dialog(that, android.R.style.Theme_Translucent_NoTitleBar);
+                // check to see if the splash screen should be full screen
+                if ((getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN)
+                        == WindowManager.LayoutParams.FLAG_FULLSCREEN) {
+                    splashDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+                            WindowManager.LayoutParams.FLAG_FULLSCREEN);
+                }
+                splashDialog.setContentView(root);
+                splashDialog.setCancelable(false);
+                splashDialog.show();
+
+                // Set Runnable to remove splash screen just in case
+                final Handler handler = new Handler();
+                handler.postDelayed(new Runnable() {
+                    public void run() {
+                        removeSplashScreen();
+                    }
+                }, time);
+            }
+        };
+        this.runOnUiThread(runnable);
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event)
+    {
+        if (appView != null && (appView.isCustomViewShowing() || appView.getFocusedChild() != null ) &&
+                (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU)) {
+            return appView.onKeyUp(keyCode, event);
+        } else {
+            return super.onKeyUp(keyCode, event);
+        }
+    }
+    
+    /*
+     * Android 2.x needs to be able to check where the cursor is.  Android 4.x does not
+     * 
+     * (non-Javadoc)
+     * @see android.app.Activity#onKeyDown(int, android.view.KeyEvent)
+     */
+    
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event)
+    {
+        //Determine if the focus is on the current view or not
+        if (appView != null && appView.getFocusedChild() != null && (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU)) {
+                    return appView.onKeyDown(keyCode, event);
+        }
+        else
+            return super.onKeyDown(keyCode, event);
+    }
+    
+    
+    /**
+     * Called when a message is sent to plugin.
+     *
+     * @param id            The message id
+     * @param data          The message data
+     * @return              Object or null
+     */
+    public Object onMessage(String id, Object data) {
+        LOG.d(TAG, "onMessage(" + id + "," + data + ")");
+        if ("splashscreen".equals(id)) {
+            if ("hide".equals(data.toString())) {
+                this.removeSplashScreen();
+            }
+            else {
+                // If the splash dialog is showing don't try to show it again
+                if (this.splashDialog == null || !this.splashDialog.isShowing()) {
+                    this.splashscreen = this.getIntegerProperty("SplashScreen", 0);
+                    this.showSplashScreen(this.splashscreenTime);
+                }
+            }
+        }
+        else if ("spinner".equals(id)) {
+            if ("stop".equals(data.toString())) {
+                this.spinnerStop();
+                this.appView.setVisibility(View.VISIBLE);
+            }
+        }
+        else if ("onReceivedError".equals(id)) {
+            JSONObject d = (JSONObject) data;
+            try {
+                this.onReceivedError(d.getInt("errorCode"), d.getString("description"), d.getString("url"));
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+        }
+        else if ("exit".equals(id)) {
+            this.endActivity();
+        }
+        return null;
+    }
+
+    public ExecutorService getThreadPool() {
+        return threadPool;
+    }
+    
+    protected void onSaveInstanceState(Bundle outState)
+    {
+        super.onSaveInstanceState(outState);
+        if(this.activityResultCallback != null)
+        {
+            String cClass = this.activityResultCallback.getClass().getName();
+            outState.putString("callbackClass", cClass);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/blob/b3b7c0b9/framework/src/org/apache/cordova/CordovaArgs.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaArgs.java b/framework/src/org/apache/cordova/CordovaArgs.java
new file mode 100644
index 0000000..d40d26e
--- /dev/null
+++ b/framework/src/org/apache/cordova/CordovaArgs.java
@@ -0,0 +1,113 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+package org.apache.cordova;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.util.Base64;
+
+public class CordovaArgs {
+    private JSONArray baseArgs;
+
+    public CordovaArgs(JSONArray args) {
+        this.baseArgs = args;
+    }
+
+
+    // Pass through the basics to the base args.
+    public Object get(int index) throws JSONException {
+        return baseArgs.get(index);
+    }
+
+    public boolean getBoolean(int index) throws JSONException {
+        return baseArgs.getBoolean(index);
+    }
+
+    public double getDouble(int index) throws JSONException {
+        return baseArgs.getDouble(index);
+    }
+
+    public int getInt(int index) throws JSONException {
+        return baseArgs.getInt(index);
+    }
+
+    public JSONArray getJSONArray(int index) throws JSONException {
+        return baseArgs.getJSONArray(index);
+    }
+
+    public JSONObject getJSONObject(int index) throws JSONException {
+        return baseArgs.getJSONObject(index);
+    }
+
+    public long getLong(int index) throws JSONException {
+        return baseArgs.getLong(index);
+    }
+
+    public String getString(int index) throws JSONException {
+        return baseArgs.getString(index);
+    }
+
+
+    public Object opt(int index) {
+        return baseArgs.opt(index);
+    }
+
+    public boolean optBoolean(int index) {
+        return baseArgs.optBoolean(index);
+    }
+
+    public double optDouble(int index) {
+        return baseArgs.optDouble(index);
+    }
+
+    public int optInt(int index) {
+        return baseArgs.optInt(index);
+    }
+
+    public JSONArray optJSONArray(int index) {
+        return baseArgs.optJSONArray(index);
+    }
+
+    public JSONObject optJSONObject(int index) {
+        return baseArgs.optJSONObject(index);
+    }
+
+    public long optLong(int index) {
+        return baseArgs.optLong(index);
+    }
+
+    public String optString(int index) {
+        return baseArgs.optString(index);
+    }
+
+    public boolean isNull(int index) {
+        return baseArgs.isNull(index);
+    }
+
+
+    // The interesting custom helpers.
+    public byte[] getArrayBuffer(int index) throws JSONException {
+        String encoded = baseArgs.getString(index);
+        return Base64.decode(encoded, Base64.DEFAULT);
+    }
+}
+
+


Mime
View raw message