mirror of
https://github.com/apache/cordova-android.git
synced 2026-05-30 00:00:04 +08:00
Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d9b15cf69e | |||
| dbfe12a993 | |||
| 2b32dfd99d | |||
| 679de40780 | |||
| 038f0e45b1 | |||
| 033bfcc804 | |||
| fa87c08a29 | |||
| dfb799739a | |||
| 1193f7ed22 | |||
| 7530c21a9f | |||
| a120614617 | |||
| 0311f0db38 | |||
| 547b683e61 | |||
| ff1d943a69 | |||
| 15a5c89e86 | |||
| 03b974ee3f | |||
| f145605c63 | |||
| 29230d0316 | |||
| 57fc49ddc2 | |||
| 5ac6853fed | |||
| b870214cca | |||
| 55074b925f | |||
| 958424ce59 | |||
| d04fc289ac | |||
| e14edf134d | |||
| dbb127447f | |||
| dc94fc39ec | |||
| 6db9a7cb12 | |||
| 1f39386616 | |||
| 25aef945d1 | |||
| c9aa43afe0 | |||
| 913e177f6f | |||
| ae431aec12 | |||
| 8ac15048cd | |||
| a1cfe87f1e | |||
| c130396d4e | |||
| bc2e7cf317 | |||
| 7ace1d652d | |||
| 26effd1def | |||
| 5f6824e5dd | |||
| 4589bdd31f | |||
| 72e0b49e0b | |||
| 552885dbd3 | |||
| c8ec7e5191 | |||
| a0d2b96de6 | |||
| 5ca233779d |
+1
-1
@@ -69,7 +69,7 @@ function on_error {
|
|||||||
echo "An unexpected error occurred: $previous_command exited with $?"
|
echo "An unexpected error occurred: $previous_command exited with $?"
|
||||||
echo "Deleting project..."
|
echo "Deleting project..."
|
||||||
[ -d "$PROJECT_PATH" ] && rm -rf "$PROJECT_PATH"
|
[ -d "$PROJECT_PATH" ] && rm -rf "$PROJECT_PATH"
|
||||||
exit "$?"
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function replace {
|
function replace {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package __ID__;
|
package __ID__;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import org.apache.cordova.*;
|
import org.apache.cordova.*;
|
||||||
|
|
||||||
@@ -29,7 +28,9 @@ public class __ACTIVITY__ extends DroidGap
|
|||||||
public void onCreate(Bundle savedInstanceState)
|
public void onCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
super.loadUrl("file:///android_asset/www/index.html");
|
// Set by <content src="index.html" /> in config.xml
|
||||||
|
super.loadUrl(Config.getStartUrl());
|
||||||
|
//super.loadUrl("file:///android_asset/www/index.html")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
<p class="event received">Device is Ready</p>
|
<p class="event received">Device is Ready</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="cordova-2.3.0.js"></script>
|
<script type="text/javascript" src="cordova-2.4.0rc1.js"></script>
|
||||||
<script type="text/javascript" src="js/index.js"></script>
|
<script type="text/javascript" src="js/index.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
app.initialize();
|
app.initialize();
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title></title>
|
<title></title>
|
||||||
<script src="cordova-2.3.0.js"></script>
|
<script src="cordova-2.4.0rc1.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# Indicates whether an apk should be generated for each density.
|
# Indicates whether an apk should be generated for each density.
|
||||||
split.density=false
|
split.density=false
|
||||||
# Project target.
|
# Project target.
|
||||||
target=Google Inc.:Google APIs:17
|
target=android-17
|
||||||
apk-configurations=
|
apk-configurations=
|
||||||
renderscript.opt.level=O0
|
renderscript.opt.level=O0
|
||||||
android.library=true
|
android.library=true
|
||||||
|
|||||||
@@ -29,6 +29,9 @@
|
|||||||
<!-- <access origin="https://example.com" subdomains="true" /> such as above, but including subdomains, such as www -->
|
<!-- <access origin="https://example.com" subdomains="true" /> such as above, but including subdomains, such as www -->
|
||||||
<access origin=".*"/>
|
<access origin=".*"/>
|
||||||
|
|
||||||
|
<!-- <content src="http://mysite.com/myapp.html" /> for external pages -->
|
||||||
|
<content src="index.html" />
|
||||||
|
|
||||||
<log level="DEBUG"/>
|
<log level="DEBUG"/>
|
||||||
<preference name="useBrowserHistory" value="true" />
|
<preference name="useBrowserHistory" value="true" />
|
||||||
<preference name="exit-on-suspend" value="false" />
|
<preference name="exit-on-suspend" value="false" />
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class App extends CordovaPlugin {
|
|||||||
this.loadUrl(args.getString(0), args.optJSONObject(1));
|
this.loadUrl(args.getString(0), args.optJSONObject(1));
|
||||||
}
|
}
|
||||||
else if (action.equals("cancelLoadUrl")) {
|
else if (action.equals("cancelLoadUrl")) {
|
||||||
this.cancelLoadUrl();
|
//this.cancelLoadUrl();
|
||||||
}
|
}
|
||||||
else if (action.equals("clearHistory")) {
|
else if (action.equals("clearHistory")) {
|
||||||
this.clearHistory();
|
this.clearHistory();
|
||||||
@@ -160,14 +160,6 @@ public class App extends CordovaPlugin {
|
|||||||
this.webView.showWebPage(url, openExternal, clearHistory, params);
|
this.webView.showWebPage(url, openExternal, clearHistory, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancel loadUrl before it has been loaded (Only works on a CordovaInterface class)
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public void cancelLoadUrl() {
|
|
||||||
this.cordova.cancelLoadUrl();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear page history for the app.
|
* Clear page history for the app.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -322,7 +322,8 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If all this is true we shouldn't compress the image.
|
// If all this is true we shouldn't compress the image.
|
||||||
if (this.targetHeight == -1 && this.targetWidth == -1 && this.mQuality == 100 && rotate == 0) {
|
if (this.targetHeight == -1 && this.targetWidth == -1 && this.mQuality == 100 &&
|
||||||
|
!this.correctOrientation) {
|
||||||
writeUncompressedImage(uri);
|
writeUncompressedImage(uri);
|
||||||
|
|
||||||
this.callbackContext.success(uri.toString());
|
this.callbackContext.success(uri.toString());
|
||||||
|
|||||||
@@ -0,0 +1,228 @@
|
|||||||
|
/*
|
||||||
|
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.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.cordova.api.LOG;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
|
||||||
|
import android.content.res.XmlResourceParser;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class Config {
|
||||||
|
|
||||||
|
public static final String TAG = "Config";
|
||||||
|
|
||||||
|
private ArrayList<Pattern> whiteList = new ArrayList<Pattern>();
|
||||||
|
private HashMap<String, Boolean> whiteListCache = new HashMap<String, Boolean>();
|
||||||
|
private String startUrl;
|
||||||
|
|
||||||
|
private static Config self = null;
|
||||||
|
|
||||||
|
public static void init(Activity action) {
|
||||||
|
if (self == null) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
this._addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strNode.equals("log")) {
|
||||||
|
String level = xml.getAttributeValue(null, "level");
|
||||||
|
LOG.i("CordovaLog", "Found log level %s", level);
|
||||||
|
if (level != null) {
|
||||||
|
LOG.setLogLevel(level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strNode.equals("preference")) {
|
||||||
|
String name = xml.getAttributeValue(null, "name");
|
||||||
|
String value = xml.getAttributeValue(null, "value");
|
||||||
|
|
||||||
|
LOG.i("CordovaLog", "Found preference for %s=%s", name, value);
|
||||||
|
Log.d("CordovaLog", "Found preference for " + name + "=" + value);
|
||||||
|
|
||||||
|
action.getIntent().putExtra(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._addWhiteListEntry(origin, subdomains);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void _addWhiteListEntry(String origin, boolean subdomains) {
|
||||||
|
try {
|
||||||
|
// Unlimited access to network resources
|
||||||
|
if (origin.compareTo("*") == 0) {
|
||||||
|
LOG.d(TAG, "Unlimited access to network resources");
|
||||||
|
this.whiteList.add(Pattern.compile(".*"));
|
||||||
|
} else { // specific access
|
||||||
|
// check if subdomains should be included
|
||||||
|
// TODO: we should not add more domains if * has already been added
|
||||||
|
if (subdomains) {
|
||||||
|
// XXX making it stupid friendly for people who forget to include protocol/SSL
|
||||||
|
if (origin.startsWith("http")) {
|
||||||
|
this.whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://(.*\\.)?")));
|
||||||
|
} else {
|
||||||
|
this.whiteList.add(Pattern.compile("^https?://(.*\\.)?" + origin));
|
||||||
|
}
|
||||||
|
LOG.d(TAG, "Origin to allow with subdomains: %s", origin);
|
||||||
|
} else {
|
||||||
|
// XXX making it stupid friendly for people who forget to include protocol/SSL
|
||||||
|
if (origin.startsWith("http")) {
|
||||||
|
this.whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://")));
|
||||||
|
} else {
|
||||||
|
this.whiteList.add(Pattern.compile("^https?://" + origin));
|
||||||
|
}
|
||||||
|
LOG.d(TAG, "Origin to allow: %s", origin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.d(TAG, "Failed to add origin %s", origin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see if we have matched url previously
|
||||||
|
if (self.whiteListCache.get(url) != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for match in white list
|
||||||
|
Iterator<Pattern> pit = self.whiteList.iterator();
|
||||||
|
while (pit.hasNext()) {
|
||||||
|
Pattern p = pit.next();
|
||||||
|
Matcher m = p.matcher(url);
|
||||||
|
|
||||||
|
// If match found, then cache it to speed up subsequent comparisons
|
||||||
|
if (m.find()) {
|
||||||
|
self.whiteListCache.put(url, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getStartUrl() {
|
||||||
|
if (self == null || self.startUrl == null) {
|
||||||
|
return "file:///android_asset/www/index.html";
|
||||||
|
}
|
||||||
|
return self.startUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
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 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 Object 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 Object 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -24,8 +24,12 @@ import org.json.JSONArray;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -33,6 +37,7 @@ import android.view.ViewGroup.LayoutParams;
|
|||||||
import android.webkit.ConsoleMessage;
|
import android.webkit.ConsoleMessage;
|
||||||
import android.webkit.JsPromptResult;
|
import android.webkit.JsPromptResult;
|
||||||
import android.webkit.JsResult;
|
import android.webkit.JsResult;
|
||||||
|
import android.webkit.ValueCallback;
|
||||||
import android.webkit.WebChromeClient;
|
import android.webkit.WebChromeClient;
|
||||||
import android.webkit.WebStorage;
|
import android.webkit.WebStorage;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
@@ -47,6 +52,8 @@ import android.widget.RelativeLayout;
|
|||||||
*/
|
*/
|
||||||
public class CordovaChromeClient extends WebChromeClient {
|
public class CordovaChromeClient extends WebChromeClient {
|
||||||
|
|
||||||
|
public static final int FILECHOOSER_RESULTCODE = 5173;
|
||||||
|
private static final String LOG_TAG = "CordovaChromeClient";
|
||||||
private String TAG = "CordovaLog";
|
private String TAG = "CordovaLog";
|
||||||
private long MAX_QUOTA = 100 * 1024 * 1024;
|
private long MAX_QUOTA = 100 * 1024 * 1024;
|
||||||
private CordovaInterface cordova;
|
private CordovaInterface cordova;
|
||||||
@@ -55,6 +62,9 @@ public class CordovaChromeClient extends WebChromeClient {
|
|||||||
// the video progress view
|
// the video progress view
|
||||||
private View mVideoProgressView;
|
private View mVideoProgressView;
|
||||||
|
|
||||||
|
// File Chooser
|
||||||
|
public ValueCallback<Uri> mUploadMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
@@ -197,7 +207,7 @@ public class CordovaChromeClient extends WebChromeClient {
|
|||||||
// Security check to make sure any requests are coming from the page initially
|
// Security check to make sure any requests are coming from the page initially
|
||||||
// loaded in webview and not another loaded in an iframe.
|
// loaded in webview and not another loaded in an iframe.
|
||||||
boolean reqOk = false;
|
boolean reqOk = false;
|
||||||
if (url.startsWith("file://") || url.indexOf(this.appView.baseUrl) == 0 || this.appView.isUrlWhiteListed(url)) {
|
if (url.startsWith("file://") || url.indexOf(this.appView.baseUrl) == 0 || Config.isUrlWhiteListed(url)) {
|
||||||
reqOk = true;
|
reqOk = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,5 +379,26 @@ public class CordovaChromeClient extends WebChromeClient {
|
|||||||
}
|
}
|
||||||
return mVideoProgressView;
|
return mVideoProgressView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
|
||||||
|
this.openFileChooser(uploadMsg, "*/*");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void openFileChooser( ValueCallback<Uri> uploadMsg, String acceptType ) {
|
||||||
|
this.openFileChooser(uploadMsg, acceptType, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)
|
||||||
|
{
|
||||||
|
mUploadMessage = uploadMsg;
|
||||||
|
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
|
||||||
|
i.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
|
i.setType("*/*");
|
||||||
|
this.cordova.getActivity().startActivityForResult(Intent.createChooser(i, "File Browser"),
|
||||||
|
FILECHOOSER_RESULTCODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueCallback<Uri> getValueCallback() {
|
||||||
|
return this.mUploadMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,30 +19,25 @@
|
|||||||
|
|
||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
|
import org.apache.cordova.Config;
|
||||||
import org.apache.cordova.api.CordovaInterface;
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
|
import org.apache.cordova.api.CordovaPlugin;
|
||||||
import org.apache.cordova.api.LOG;
|
import org.apache.cordova.api.LOG;
|
||||||
import org.apache.cordova.api.PluginManager;
|
import org.apache.cordova.api.PluginManager;
|
||||||
import org.apache.cordova.api.PluginResult;
|
import org.apache.cordova.api.PluginResult;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.res.XmlResourceParser;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -65,15 +60,12 @@ public class CordovaWebView extends WebView {
|
|||||||
|
|
||||||
public static final String TAG = "CordovaWebView";
|
public static final String TAG = "CordovaWebView";
|
||||||
|
|
||||||
/** The whitelist **/
|
|
||||||
private ArrayList<Pattern> whiteList = new ArrayList<Pattern>();
|
|
||||||
private HashMap<String, Boolean> whiteListCache = new HashMap<String, Boolean>();
|
|
||||||
private ArrayList<Integer> keyDownCodes = new ArrayList<Integer>();
|
private ArrayList<Integer> keyDownCodes = new ArrayList<Integer>();
|
||||||
private ArrayList<Integer> keyUpCodes = new ArrayList<Integer>();
|
private ArrayList<Integer> keyUpCodes = new ArrayList<Integer>();
|
||||||
|
|
||||||
public PluginManager pluginManager;
|
public PluginManager pluginManager;
|
||||||
private boolean paused;
|
private boolean paused;
|
||||||
|
|
||||||
private BroadcastReceiver receiver;
|
private BroadcastReceiver receiver;
|
||||||
|
|
||||||
|
|
||||||
@@ -105,6 +97,23 @@ public class CordovaWebView extends WebView {
|
|||||||
/** custom view created by the browser (a video player for example) */
|
/** custom view created by the browser (a video player for example) */
|
||||||
private View mCustomView;
|
private View mCustomView;
|
||||||
private WebChromeClient.CustomViewCallback mCustomViewCallback;
|
private WebChromeClient.CustomViewCallback mCustomViewCallback;
|
||||||
|
|
||||||
|
private ActivityResult mResult = null;
|
||||||
|
|
||||||
|
class ActivityResult {
|
||||||
|
|
||||||
|
int request;
|
||||||
|
int result;
|
||||||
|
Intent incoming;
|
||||||
|
|
||||||
|
public ActivityResult(int req, int res, Intent intent) {
|
||||||
|
request = req;
|
||||||
|
result = res;
|
||||||
|
incoming = intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
|
static final FrameLayout.LayoutParams COVER_SCREEN_GRAVITY_CENTER =
|
||||||
new FrameLayout.LayoutParams(
|
new FrameLayout.LayoutParams(
|
||||||
@@ -324,71 +333,9 @@ public class CordovaWebView extends WebView {
|
|||||||
this.chromeClient = client;
|
this.chromeClient = client;
|
||||||
super.setWebChromeClient(client);
|
super.setWebChromeClient(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public CordovaChromeClient getWebChromeClient() {
|
||||||
* Add entry to approved list of URLs (whitelist)
|
return this.chromeClient;
|
||||||
*
|
|
||||||
* @param origin URL regular expression to allow
|
|
||||||
* @param subdomains T=include all subdomains under origin
|
|
||||||
*/
|
|
||||||
public void addWhiteListEntry(String origin, boolean subdomains) {
|
|
||||||
try {
|
|
||||||
// Unlimited access to network resources
|
|
||||||
if (origin.compareTo("*") == 0) {
|
|
||||||
LOG.d(TAG, "Unlimited access to network resources");
|
|
||||||
this.whiteList.add(Pattern.compile(".*"));
|
|
||||||
} else { // specific access
|
|
||||||
// check if subdomains should be included
|
|
||||||
// TODO: we should not add more domains if * has already been added
|
|
||||||
if (subdomains) {
|
|
||||||
// XXX making it stupid friendly for people who forget to include protocol/SSL
|
|
||||||
if (origin.startsWith("http")) {
|
|
||||||
this.whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://(.*\\.)?")));
|
|
||||||
} else {
|
|
||||||
this.whiteList.add(Pattern.compile("^https?://(.*\\.)?" + origin));
|
|
||||||
}
|
|
||||||
LOG.d(TAG, "Origin to allow with subdomains: %s", origin);
|
|
||||||
} else {
|
|
||||||
// XXX making it stupid friendly for people who forget to include protocol/SSL
|
|
||||||
if (origin.startsWith("http")) {
|
|
||||||
this.whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://")));
|
|
||||||
} else {
|
|
||||||
this.whiteList.add(Pattern.compile("^https?://" + origin));
|
|
||||||
}
|
|
||||||
LOG.d(TAG, "Origin to allow: %s", origin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG.d(TAG, "Failed to add origin %s", origin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if URL is in approved list of URLs to load.
|
|
||||||
*
|
|
||||||
* @param url
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean isUrlWhiteListed(String url) {
|
|
||||||
|
|
||||||
// Check to see if we have matched url previously
|
|
||||||
if (this.whiteListCache.get(url) != null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look for match in white list
|
|
||||||
Iterator<Pattern> pit = this.whiteList.iterator();
|
|
||||||
while (pit.hasNext()) {
|
|
||||||
Pattern p = pit.next();
|
|
||||||
Matcher m = p.matcher(url);
|
|
||||||
|
|
||||||
// If match found, then cache it to speed up subsequent comparisons
|
|
||||||
if (m.find()) {
|
|
||||||
this.whiteListCache.put(url, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -514,8 +461,8 @@ public class CordovaWebView extends WebView {
|
|||||||
if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) {
|
if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) {
|
||||||
LOG.d(TAG, ">>> loadUrlNow()");
|
LOG.d(TAG, ">>> loadUrlNow()");
|
||||||
}
|
}
|
||||||
if (url.startsWith("file://") || url.indexOf(this.baseUrl) == 0 || url.startsWith("javascript:") || this.isUrlWhiteListed(url)) {
|
if (url.startsWith("file://") || url.indexOf(this.baseUrl) == 0 || url.startsWith("javascript:") || Config.isUrlWhiteListed(url)) {
|
||||||
super.loadUrl(url);
|
super.loadUrl(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,7 +609,7 @@ public class CordovaWebView extends WebView {
|
|||||||
if (!openExternal) {
|
if (!openExternal) {
|
||||||
|
|
||||||
// Make sure url is in whitelist
|
// Make sure url is in whitelist
|
||||||
if (url.startsWith("file://") || url.indexOf(this.baseUrl) == 0 || isUrlWhiteListed(url)) {
|
if (url.startsWith("file://") || url.indexOf(this.baseUrl) == 0 || Config.isUrlWhiteListed(url)) {
|
||||||
// TODO: What about params?
|
// TODO: What about params?
|
||||||
|
|
||||||
// Clear out current url from history, since it will be replacing it
|
// Clear out current url from history, since it will be replacing it
|
||||||
@@ -699,68 +646,14 @@ public class CordovaWebView extends WebView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load Cordova configuration from res/xml/cordova.xml.
|
* Check configuration parameters from Config.
|
||||||
* Approved list of URLs that can be loaded into DroidGap
|
* Approved list of URLs that can be loaded into DroidGap
|
||||||
* <access origin="http://server regexp" subdomains="true" />
|
* <access origin="http://server regexp" subdomains="true" />
|
||||||
* Log level: ERROR, WARN, INFO, DEBUG, VERBOSE (default=ERROR)
|
* Log level: ERROR, WARN, INFO, DEBUG, VERBOSE (default=ERROR)
|
||||||
* <log level="DEBUG" />
|
* <log level="DEBUG" />
|
||||||
*/
|
*/
|
||||||
private void loadConfiguration() {
|
private void loadConfiguration() {
|
||||||
Activity action = this.cordova.getActivity();
|
// Config has already been loaded, and it stores these preferences on the Intent.
|
||||||
if(action == null)
|
|
||||||
{
|
|
||||||
LOG.i("CordovaLog", "There is no activity. Is this on the lock screen?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int id = getResources().getIdentifier("config", "xml", this.cordova.getActivity().getPackageName());
|
|
||||||
if(id == 0)
|
|
||||||
{
|
|
||||||
id = getResources().getIdentifier("cordova", "xml", this.cordova.getActivity().getPackageName());
|
|
||||||
Log.i("CordovaLog", "config.xml missing, reverting to cordova.xml");
|
|
||||||
}
|
|
||||||
if (id == 0) {
|
|
||||||
LOG.i("CordovaLog", "cordova.xml missing. Ignoring...");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
XmlResourceParser xml = 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) {
|
|
||||||
this.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (strNode.equals("log")) {
|
|
||||||
String level = xml.getAttributeValue(null, "level");
|
|
||||||
LOG.i("CordovaLog", "Found log level %s", level);
|
|
||||||
if (level != null) {
|
|
||||||
LOG.setLogLevel(level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (strNode.equals("preference")) {
|
|
||||||
String name = xml.getAttributeValue(null, "name");
|
|
||||||
String value = xml.getAttributeValue(null, "value");
|
|
||||||
|
|
||||||
LOG.i("CordovaLog", "Found preference for %s=%s", name, value);
|
|
||||||
Log.d("CordovaLog", "Found preference for " + name + "=" + value);
|
|
||||||
|
|
||||||
// Save preferences in Intent
|
|
||||||
this.cordova.getActivity().getIntent().putExtra(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
eventType = xml.next();
|
|
||||||
} catch (XmlPullParserException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if("false".equals(this.getProperty("useBrowserHistory", "true")))
|
if("false".equals(this.getProperty("useBrowserHistory", "true")))
|
||||||
{
|
{
|
||||||
//Switch back to the old browser history and state the six month policy
|
//Switch back to the old browser history and state the six month policy
|
||||||
@@ -939,9 +832,8 @@ public class CordovaWebView extends WebView {
|
|||||||
public void handleResume(boolean keepRunning, boolean activityResultKeepRunning)
|
public void handleResume(boolean keepRunning, boolean activityResultKeepRunning)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Send resume event to JavaScript
|
|
||||||
this.loadUrl("javascript:try{cordova.fireDocumentEvent('resume');}catch(e){console.log('exception firing resume event from native');};");
|
this.loadUrl("javascript:try{cordova.fireDocumentEvent('resume');}catch(e){console.log('exception firing resume event from native');};");
|
||||||
|
|
||||||
// Forward to plugins
|
// Forward to plugins
|
||||||
if (this.pluginManager != null) {
|
if (this.pluginManager != null) {
|
||||||
this.pluginManager.onResume(keepRunning);
|
this.pluginManager.onResume(keepRunning);
|
||||||
@@ -1077,4 +969,17 @@ public class CordovaWebView extends WebView {
|
|||||||
public boolean isCustomViewShowing() {
|
public boolean isCustomViewShowing() {
|
||||||
return mCustomView != null;
|
return mCustomView != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WebBackForwardList restoreState(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
WebBackForwardList myList = super.restoreState(savedInstanceState);
|
||||||
|
Log.d(TAG, "WebView restoration crew now restoring!");
|
||||||
|
//Initialize the plugin manager once more
|
||||||
|
this.pluginManager.init();
|
||||||
|
return myList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void storeResult(int requestCode, int resultCode, Intent intent) {
|
||||||
|
mResult = new ActivityResult(requestCode, resultCode, intent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ package org.apache.cordova;
|
|||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
|
||||||
import org.apache.cordova.api.CordovaInterface;
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
import org.apache.cordova.api.PluginResult;
|
|
||||||
|
|
||||||
import org.apache.cordova.api.LOG;
|
import org.apache.cordova.api.LOG;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@@ -193,7 +192,7 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
|
|
||||||
// If our app or file:, then load into a new Cordova webview container by starting a new instance of our activity.
|
// If our app or file:, then load into a new Cordova webview container by starting a new instance of our activity.
|
||||||
// Our app continues to run. When BACK is pressed, our app is redisplayed.
|
// Our app continues to run. When BACK is pressed, our app is redisplayed.
|
||||||
if (url.startsWith("file://") || url.startsWith("data:") || url.indexOf(this.appView.baseUrl) == 0 || this.appView.isUrlWhiteListed(url)) {
|
if (url.startsWith("file://") || url.startsWith("data:") || url.indexOf(this.appView.baseUrl) == 0 || Config.isUrlWhiteListed(url)) {
|
||||||
//This will fix iFrames
|
//This will fix iFrames
|
||||||
if (appView.useBrowserHistory || url.startsWith("data:"))
|
if (appView.useBrowserHistory || url.startsWith("data:"))
|
||||||
return false;
|
return false;
|
||||||
@@ -295,6 +294,7 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
// not loaded yet then just set a flag so that the onNativeReady can be fired
|
// not loaded yet then just set a flag so that the onNativeReady can be fired
|
||||||
// from the JS side when the JS gets to that code.
|
// from the JS side when the JS gets to that code.
|
||||||
if (!url.equals("about:blank")) {
|
if (!url.equals("about:blank")) {
|
||||||
|
LOG.d(TAG, "Trying to fire onNativeReady");
|
||||||
this.appView.loadUrl("javascript:try{ cordova.require('cordova/channel').onNativeReady.fire();}catch(e){_nativeReady = true;}");
|
this.appView.loadUrl("javascript:try{ cordova.require('cordova/channel').onNativeReady.fire();}catch(e){_nativeReady = true;}");
|
||||||
this.appView.postMessage("onNativeReady", null);
|
this.appView.postMessage("onNativeReady", null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import android.telephony.TelephonyManager;
|
|||||||
public class Device extends CordovaPlugin {
|
public class Device extends CordovaPlugin {
|
||||||
public static final String TAG = "Device";
|
public static final String TAG = "Device";
|
||||||
|
|
||||||
public static String cordovaVersion = "2.3.0"; // Cordova version
|
public static String cordovaVersion = "2.4.0rc1"; // Cordova version
|
||||||
public static String platform = "Android"; // Device OS
|
public static String platform = "Android"; // Device OS
|
||||||
public static String uuid; // Device UUID
|
public static String uuid; // Device UUID
|
||||||
|
|
||||||
|
|||||||
@@ -38,8 +38,10 @@ import android.content.Intent;
|
|||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@@ -48,6 +50,7 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.webkit.ValueCallback;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.webkit.WebViewClient;
|
import android.webkit.WebViewClient;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
@@ -170,7 +173,7 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
// Draw a splash screen using an image located in the drawable resource directory.
|
// Draw a splash screen using an image located in the drawable resource directory.
|
||||||
// This is not the same as calling super.loadSplashscreen(url)
|
// This is not the same as calling super.loadSplashscreen(url)
|
||||||
protected int splashscreen = 0;
|
protected int splashscreen = 0;
|
||||||
protected int splashscreenTime = 0;
|
protected int splashscreenTime = 3000;
|
||||||
|
|
||||||
// LoadUrl timeout value in msec (default of 20 sec)
|
// LoadUrl timeout value in msec (default of 20 sec)
|
||||||
protected int loadUrlTimeoutValue = 20000;
|
protected int loadUrlTimeoutValue = 20000;
|
||||||
@@ -180,6 +183,18 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
// when another application (activity) is started.
|
// when another application (activity) is started.
|
||||||
protected boolean keepRunning = true;
|
protected boolean keepRunning = true;
|
||||||
|
|
||||||
|
private int lastRequestCode;
|
||||||
|
|
||||||
|
private Object responseCode;
|
||||||
|
|
||||||
|
private Intent lastIntent;
|
||||||
|
|
||||||
|
private Object lastResponseCode;
|
||||||
|
|
||||||
|
private String initCallbackClass;
|
||||||
|
|
||||||
|
private Object LOG_TAG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the authentication token.
|
* Sets the authentication token.
|
||||||
*
|
*
|
||||||
@@ -246,11 +261,15 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
//preferences = new PreferenceSet();
|
Config.init(this);
|
||||||
|
|
||||||
LOG.d(TAG, "DroidGap.onCreate()");
|
LOG.d(TAG, "DroidGap.onCreate()");
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
if(savedInstanceState != null)
|
||||||
|
{
|
||||||
|
initCallbackClass = savedInstanceState.getString("callbackClass");
|
||||||
|
}
|
||||||
|
|
||||||
if(!this.getBooleanProperty("showTitle", false))
|
if(!this.getBooleanProperty("showTitle", false))
|
||||||
{
|
{
|
||||||
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
|
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
|
||||||
@@ -338,6 +357,7 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
|
|
||||||
// Clear cancel flag
|
// Clear cancel flag
|
||||||
this.cancelLoadUrl = false;
|
this.cancelLoadUrl = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -800,9 +820,35 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
* @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
|
* @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) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||||
|
LOG.d(TAG, "Incoming Result");
|
||||||
super.onActivityResult(requestCode, resultCode, intent);
|
super.onActivityResult(requestCode, resultCode, intent);
|
||||||
|
Log.d(TAG, "Request code = " + requestCode);
|
||||||
|
ValueCallback<Uri> mUploadMessage = this.appView.getWebChromeClient().getValueCallback();
|
||||||
|
if (requestCode == CordovaChromeClient.FILECHOOSER_RESULTCODE) {
|
||||||
|
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;
|
CordovaPlugin callback = this.activityResultCallback;
|
||||||
if (callback != null) {
|
if(callback == null)
|
||||||
|
{
|
||||||
|
if(initCallbackClass != null)
|
||||||
|
{
|
||||||
|
this.activityResultCallback = appView.pluginManager.getPlugin(initCallbackClass);
|
||||||
|
callback = activityResultCallback;
|
||||||
|
LOG.d(TAG, "We have a callback to send this result to");
|
||||||
|
callback.onActivityResult(requestCode, resultCode, intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG.d(TAG, "We have a callback to send this result to");
|
||||||
callback.onActivityResult(requestCode, resultCode, intent);
|
callback.onActivityResult(requestCode, resultCode, intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -824,7 +870,7 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
|
|
||||||
// If errorUrl specified, then load it
|
// If errorUrl specified, then load it
|
||||||
final String errorUrl = me.getStringProperty("errorUrl", null);
|
final String errorUrl = me.getStringProperty("errorUrl", null);
|
||||||
if ((errorUrl != null) && (errorUrl.startsWith("file://") || this.appView.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) {
|
if ((errorUrl != null) && (errorUrl.startsWith("file://") || Config.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) {
|
||||||
|
|
||||||
// Load URL on UI thread
|
// Load URL on UI thread
|
||||||
me.runOnUiThread(new Runnable() {
|
me.runOnUiThread(new Runnable() {
|
||||||
@@ -840,8 +886,7 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
final boolean exit = !(errorCode == WebViewClient.ERROR_HOST_LOOKUP);
|
final boolean exit = !(errorCode == WebViewClient.ERROR_HOST_LOOKUP);
|
||||||
me.runOnUiThread(new Runnable() {
|
me.runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (exit)
|
if (exit) {
|
||||||
{
|
|
||||||
me.appView.setVisibility(View.GONE);
|
me.appView.setVisibility(View.GONE);
|
||||||
me.displayError("Application Error", description + " (" + failingUrl + ")", "OK", exit);
|
me.displayError("Application Error", description + " (" + failingUrl + ")", "OK", exit);
|
||||||
}
|
}
|
||||||
@@ -892,11 +937,7 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean isUrlWhiteListed(String url) {
|
public boolean isUrlWhiteListed(String url) {
|
||||||
// Check to see if we have matched url previously
|
return Config.isUrlWhiteListed(url);
|
||||||
if (this.appView != null) {
|
|
||||||
return this.appView.isUrlWhiteListed(url);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1053,9 +1094,9 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// If the splash dialog is showing don't try to show it again
|
// If the splash dialog is showing don't try to show it again
|
||||||
if (this.splashDialog != null && !this.splashDialog.isShowing()) {
|
if (this.splashDialog == null || !this.splashDialog.isShowing()) {
|
||||||
this.splashscreen = this.getIntegerProperty("splashscreen", 0);
|
this.splashscreen = this.getIntegerProperty("splashscreen", 0);
|
||||||
this.showSplashScreen(this.splashscreenTime);
|
this.showSplashScreen(this.splashscreenTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1082,4 +1123,15 @@ public class DroidGap extends Activity implements CordovaInterface {
|
|||||||
public ExecutorService getThreadPool() {
|
public ExecutorService getThreadPool() {
|
||||||
return threadPool;
|
return threadPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void onSaveInstanceState(Bundle outState)
|
||||||
|
{
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
if(this.activityResultCallback != null)
|
||||||
|
{
|
||||||
|
String cClass = this.activityResultCallback.getClass().getName();
|
||||||
|
outState.putString("callbackClass", cClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,24 +20,28 @@ package org.apache.cordova;
|
|||||||
|
|
||||||
import org.apache.cordova.api.CallbackContext;
|
import org.apache.cordova.api.CallbackContext;
|
||||||
import org.apache.cordova.api.CordovaPlugin;
|
import org.apache.cordova.api.CordovaPlugin;
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
|
||||||
public class Echo extends CordovaPlugin {
|
public class Echo extends CordovaPlugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
|
public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {
|
||||||
final String result = args.isNull(0) ? null : args.getString(0);
|
|
||||||
if ("echo".equals(action)) {
|
if ("echo".equals(action)) {
|
||||||
|
final String result = args.isNull(0) ? null : args.getString(0);
|
||||||
callbackContext.success(result);
|
callbackContext.success(result);
|
||||||
return true;
|
return true;
|
||||||
} else if ("echoAsync".equals(action)) {
|
} else if ("echoAsync".equals(action)) {
|
||||||
|
final String result = args.isNull(0) ? null : args.getString(0);
|
||||||
cordova.getThreadPool().execute(new Runnable() {
|
cordova.getThreadPool().execute(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
callbackContext.success(result);
|
callbackContext.success(result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
} else if ("echoArrayBuffer".equals(action)) {
|
||||||
|
final byte[] result = args.getArrayBuffer(0);
|
||||||
|
callbackContext.success(result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -602,8 +602,8 @@ public class FileTransfer extends CordovaPlugin {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final boolean useHttps = url.getProtocol().toLowerCase().equals("https");
|
final boolean useHttps = url.getProtocol().toLowerCase().equals("https");
|
||||||
|
|
||||||
if (!webView.isUrlWhiteListed(source)) {
|
if (!Config.isUrlWhiteListed(source)) {
|
||||||
Log.w(LOG_TAG, "Source URL is not in white list: '" + source + "'");
|
Log.w(LOG_TAG, "Source URL is not in white list: '" + source + "'");
|
||||||
JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, 401);
|
JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, 401);
|
||||||
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
|
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
|
||||||
@@ -676,11 +676,12 @@ public class FileTransfer extends CordovaPlugin {
|
|||||||
progress.setTotal(connection.getContentLength());
|
progress.setTotal(connection.getContentLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
FileOutputStream outputStream = new FileOutputStream(file);
|
FileOutputStream outputStream = null;
|
||||||
InputStream inputStream = null;
|
InputStream inputStream = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
inputStream = getInputStream(connection);
|
inputStream = getInputStream(connection);
|
||||||
|
outputStream = new FileOutputStream(file);
|
||||||
synchronized (context) {
|
synchronized (context) {
|
||||||
if (context.aborted) {
|
if (context.aborted) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -112,11 +112,29 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));
|
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));
|
||||||
}
|
}
|
||||||
else if (action.equals("readAsText")) {
|
else if (action.equals("readAsText")) {
|
||||||
String s = this.readAsText(args.getString(0), args.getString(1));
|
int start = 0;
|
||||||
|
int end = Integer.MAX_VALUE;
|
||||||
|
if (args.length() >= 3) {
|
||||||
|
start = args.getInt(2);
|
||||||
|
}
|
||||||
|
if (args.length() >= 4) {
|
||||||
|
end = args.getInt(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
String s = this.readAsText(args.getString(0), args.getString(1), start, end);
|
||||||
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, s));
|
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, s));
|
||||||
}
|
}
|
||||||
else if (action.equals("readAsDataURL")) {
|
else if (action.equals("readAsDataURL")) {
|
||||||
String s = this.readAsDataURL(args.getString(0));
|
int start = 0;
|
||||||
|
int end = Integer.MAX_VALUE;
|
||||||
|
if (args.length() >= 2) {
|
||||||
|
start = args.getInt(1);
|
||||||
|
}
|
||||||
|
if (args.length() >= 3) {
|
||||||
|
end = args.getInt(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
String s = this.readAsDataURL(args.getString(0), start, end);
|
||||||
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, s));
|
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, s));
|
||||||
}
|
}
|
||||||
else if (action.equals("write")) {
|
else if (action.equals("write")) {
|
||||||
@@ -221,9 +239,15 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
*/
|
*/
|
||||||
private void notifyDelete(String filePath) {
|
private void notifyDelete(String filePath) {
|
||||||
String newFilePath = stripFileProtocol(filePath);
|
String newFilePath = stripFileProtocol(filePath);
|
||||||
this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
try {
|
||||||
MediaStore.Images.Media.DATA + " = ?",
|
this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
||||||
new String[] { newFilePath });
|
MediaStore.Images.Media.DATA + " = ?",
|
||||||
|
new String[] { newFilePath });
|
||||||
|
} catch (UnsupportedOperationException t) {
|
||||||
|
// Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator.
|
||||||
|
// The ContentResolver applies only when the file was registered in the
|
||||||
|
// first case, which is generally only the case with images.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -932,17 +956,27 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
* @param filename The name of the file.
|
* @param filename The name of the file.
|
||||||
* @param encoding The encoding to return contents as. Typical value is UTF-8.
|
* @param encoding The encoding to return contents as. Typical value is UTF-8.
|
||||||
* (see http://www.iana.org/assignments/character-sets)
|
* (see http://www.iana.org/assignments/character-sets)
|
||||||
|
* @param start Start position in the file.
|
||||||
|
* @param end End position to stop at (exclusive).
|
||||||
* @return Contents of file.
|
* @return Contents of file.
|
||||||
* @throws FileNotFoundException, IOException
|
* @throws FileNotFoundException, IOException
|
||||||
*/
|
*/
|
||||||
public String readAsText(String filename, String encoding) throws FileNotFoundException, IOException {
|
public String readAsText(String filename, String encoding, int start, int end) throws FileNotFoundException, IOException {
|
||||||
|
int diff = end - start;
|
||||||
byte[] bytes = new byte[1000];
|
byte[] bytes = new byte[1000];
|
||||||
BufferedInputStream bis = new BufferedInputStream(getPathFromUri(filename), 1024);
|
BufferedInputStream bis = new BufferedInputStream(getPathFromUri(filename), 1024);
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
int numRead = 0;
|
int numRead = 0;
|
||||||
while ((numRead = bis.read(bytes, 0, 1000)) >= 0) {
|
|
||||||
|
if (start > 0) {
|
||||||
|
bis.skip(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( diff > 0 && (numRead = bis.read(bytes, 0, Math.min(1000, diff))) >= 0) {
|
||||||
|
diff -= numRead;
|
||||||
bos.write(bytes, 0, numRead);
|
bos.write(bytes, 0, numRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new String(bos.toByteArray(), encoding);
|
return new String(bos.toByteArray(), encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -953,12 +987,19 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
* @return Contents of file = data:<media type>;base64,<data>
|
* @return Contents of file = data:<media type>;base64,<data>
|
||||||
* @throws FileNotFoundException, IOException
|
* @throws FileNotFoundException, IOException
|
||||||
*/
|
*/
|
||||||
public String readAsDataURL(String filename) throws FileNotFoundException, IOException {
|
public String readAsDataURL(String filename, int start, int end) throws FileNotFoundException, IOException {
|
||||||
|
int diff = end - start;
|
||||||
byte[] bytes = new byte[1000];
|
byte[] bytes = new byte[1000];
|
||||||
BufferedInputStream bis = new BufferedInputStream(getPathFromUri(filename), 1024);
|
BufferedInputStream bis = new BufferedInputStream(getPathFromUri(filename), 1024);
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
int numRead = 0;
|
int numRead = 0;
|
||||||
while ((numRead = bis.read(bytes, 0, 1000)) >= 0) {
|
|
||||||
|
if (start > 0) {
|
||||||
|
bis.skip(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (diff > 0 && (numRead = bis.read(bytes, 0, Math.min(1000, diff))) >= 0) {
|
||||||
|
diff -= numRead;
|
||||||
bos.write(bytes, 0, numRead);
|
bos.write(bytes, 0, numRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -984,15 +1025,21 @@ public class FileUtils extends CordovaPlugin {
|
|||||||
* @return a mime type
|
* @return a mime type
|
||||||
*/
|
*/
|
||||||
public static String getMimeType(String filename) {
|
public static String getMimeType(String filename) {
|
||||||
// Stupid bug in getFileExtensionFromUrl when the file name has a space
|
if (filename != null) {
|
||||||
// So we need to replace the space with a url encoded %20
|
// Stupid bug in getFileExtensionFromUrl when the file name has a space
|
||||||
String url = filename.replace(" ", "%20");
|
// So we need to replace the space with a url encoded %20
|
||||||
MimeTypeMap map = MimeTypeMap.getSingleton();
|
|
||||||
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
|
// CB-2185: Stupid bug not putting JPG extension in the mime-type map
|
||||||
if (extension.toLowerCase().equals("3ga")) {
|
String url = filename.replace(" ", "%20").toLowerCase();
|
||||||
return "audio/3gpp";
|
MimeTypeMap map = MimeTypeMap.getSingleton();
|
||||||
|
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
|
||||||
|
if (extension.toLowerCase().equals("3ga")) {
|
||||||
|
return "audio/3gpp";
|
||||||
|
} else {
|
||||||
|
return map.getMimeTypeFromExtension(extension);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return map.getMimeTypeFromExtension(extension);
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
Log.d(LOG_TAG, "in self");
|
Log.d(LOG_TAG, "in self");
|
||||||
// load in webview
|
// load in webview
|
||||||
if (url.startsWith("file://") || url.startsWith("javascript:")
|
if (url.startsWith("file://") || url.startsWith("javascript:")
|
||||||
|| this.webView.isUrlWhiteListed(url)) {
|
|| Config.isUrlWhiteListed(url)) {
|
||||||
this.webView.loadUrl(url);
|
this.webView.loadUrl(url);
|
||||||
}
|
}
|
||||||
// load in InAppBrowser
|
// load in InAppBrowser
|
||||||
@@ -414,6 +414,9 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
*/
|
*/
|
||||||
// @TODO: replace with settings.setPluginState(android.webkit.WebSettings.PluginState.ON)
|
// @TODO: replace with settings.setPluginState(android.webkit.WebSettings.PluginState.ON)
|
||||||
settings.setPluginsEnabled(true);
|
settings.setPluginsEnabled(true);
|
||||||
|
settings.setDatabaseEnabled(true);
|
||||||
|
String databasePath = cordova.getActivity().getApplicationContext().getDir("inAppBrowserDB", Context.MODE_PRIVATE).getPath();
|
||||||
|
settings.setDatabasePath(databasePath);
|
||||||
settings.setDomStorageEnabled(true);
|
settings.setDomStorageEnabled(true);
|
||||||
inAppWebView.loadUrl(url);
|
inAppWebView.loadUrl(url);
|
||||||
inAppWebView.setId(6);
|
inAppWebView.setId(6);
|
||||||
@@ -528,4 +531,4 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,8 @@ public class NativeToJsMessageQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void packMessage(JsMessage message, StringBuilder sb) {
|
private void packMessage(JsMessage message, StringBuilder sb) {
|
||||||
sb.append(message.calculateEncodedLength())
|
int len = message.calculateEncodedLength();
|
||||||
|
sb.append(len)
|
||||||
.append(' ');
|
.append(' ');
|
||||||
message.encodeAsMessage(sb);
|
message.encodeAsMessage(sb);
|
||||||
}
|
}
|
||||||
@@ -166,7 +167,8 @@ public class NativeToJsMessageQueue {
|
|||||||
// Attach a char to indicate that there are more messages pending.
|
// Attach a char to indicate that there are more messages pending.
|
||||||
sb.append('*');
|
sb.append('*');
|
||||||
}
|
}
|
||||||
return sb.toString();
|
String ret = sb.toString();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +211,8 @@ public class NativeToJsMessageQueue {
|
|||||||
for (int i = willSendAllMessages ? 1 : 0; i < numMessagesToSend; ++i) {
|
for (int i = willSendAllMessages ? 1 : 0; i < numMessagesToSend; ++i) {
|
||||||
sb.append('}');
|
sb.append('}');
|
||||||
}
|
}
|
||||||
return sb.toString();
|
String ret = sb.toString();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,6 +409,9 @@ public class NativeToJsMessageQueue {
|
|||||||
case PluginResult.MESSAGE_TYPE_STRING: // s
|
case PluginResult.MESSAGE_TYPE_STRING: // s
|
||||||
ret += 1 + pluginResult.getStrMessage().length();
|
ret += 1 + pluginResult.getStrMessage().length();
|
||||||
break;
|
break;
|
||||||
|
case PluginResult.MESSAGE_TYPE_ARRAYBUFFER:
|
||||||
|
ret += 1 + pluginResult.getMessage().length();
|
||||||
|
break;
|
||||||
case PluginResult.MESSAGE_TYPE_JSON:
|
case PluginResult.MESSAGE_TYPE_JSON:
|
||||||
default:
|
default:
|
||||||
ret += pluginResult.getMessage().length();
|
ret += pluginResult.getMessage().length();
|
||||||
@@ -445,6 +451,10 @@ public class NativeToJsMessageQueue {
|
|||||||
sb.append('s');
|
sb.append('s');
|
||||||
sb.append(pluginResult.getStrMessage());
|
sb.append(pluginResult.getStrMessage());
|
||||||
break;
|
break;
|
||||||
|
case PluginResult.MESSAGE_TYPE_ARRAYBUFFER:
|
||||||
|
sb.append('A');
|
||||||
|
sb.append(pluginResult.getMessage());
|
||||||
|
break;
|
||||||
case PluginResult.MESSAGE_TYPE_JSON:
|
case PluginResult.MESSAGE_TYPE_JSON:
|
||||||
default:
|
default:
|
||||||
sb.append(pluginResult.getMessage()); // [ or {
|
sb.append(pluginResult.getMessage()); // [ or {
|
||||||
|
|||||||
@@ -71,6 +71,15 @@ public class CallbackContext {
|
|||||||
sendPluginResult(new PluginResult(PluginResult.Status.OK, 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
|
* Helper for success callbacks that just returns the Status.OK by default
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -54,11 +54,6 @@ public interface CordovaInterface {
|
|||||||
*/
|
*/
|
||||||
public abstract Activity getActivity();
|
public abstract Activity getActivity();
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public abstract Context getContext();
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public abstract void cancelLoadUrl();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a message is sent to plugin.
|
* Called when a message is sent to plugin.
|
||||||
|
|||||||
@@ -18,12 +18,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova.api;
|
package org.apache.cordova.api;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaArgs;
|
||||||
import org.apache.cordova.CordovaWebView;
|
import org.apache.cordova.CordovaWebView;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugins must extend this class and override one of the execute methods.
|
* Plugins must extend this class and override one of the execute methods.
|
||||||
*/
|
*/
|
||||||
@@ -76,9 +76,28 @@ public class CordovaPlugin {
|
|||||||
* @return Whether the action was valid.
|
* @return Whether the action was valid.
|
||||||
*/
|
*/
|
||||||
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
||||||
|
CordovaArgs cordovaArgs = new CordovaArgs(args);
|
||||||
|
return execute(action, cordovaArgs, callbackContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the request.
|
||||||
|
*
|
||||||
|
* This method is called from the WebView thread. To do a non-trivial amount of work, use:
|
||||||
|
* cordova.getThreadPool().execute(runnable);
|
||||||
|
*
|
||||||
|
* To run on the UI thread, use:
|
||||||
|
* cordova.getActivity().runOnUiThread(runnable);
|
||||||
|
*
|
||||||
|
* @param action The action to execute.
|
||||||
|
* @param args The exec() arguments, wrapped with some Cordova helpers.
|
||||||
|
* @param callbackContext The callback context used when calling back into JavaScript.
|
||||||
|
* @return Whether the action was valid.
|
||||||
|
*/
|
||||||
|
public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the system is about to start resuming a previous activity.
|
* Called when the system is about to start resuming a previous activity.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ public class LegacyContext implements CordovaInterface {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public void cancelLoadUrl() {
|
public void cancelLoadUrl() {
|
||||||
Log.i(LOG_TAG, "Replace ctx.cancelLoadUrl() with cordova.cancelLoadUrl()");
|
Log.i(LOG_TAG, "Replace ctx.cancelLoadUrl() with cordova.cancelLoadUrl()");
|
||||||
this.cordova.cancelLoadUrl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@@ -55,7 +54,7 @@ public class LegacyContext implements CordovaInterface {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public Context getContext() {
|
public Context getContext() {
|
||||||
Log.i(LOG_TAG, "Replace ctx.getContext() with cordova.getContext()");
|
Log.i(LOG_TAG, "Replace ctx.getContext() with cordova.getContext()");
|
||||||
return this.cordova.getContext();
|
return this.cordova.getActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ public class PluginManager {
|
|||||||
* @param service The name of the service.
|
* @param service The name of the service.
|
||||||
* @return CordovaPlugin or null
|
* @return CordovaPlugin or null
|
||||||
*/
|
*/
|
||||||
private CordovaPlugin getPlugin(String service) {
|
public CordovaPlugin getPlugin(String service) {
|
||||||
PluginEntry entry = this.entries.get(service);
|
PluginEntry entry = this.entries.get(service);
|
||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ package org.apache.cordova.api;
|
|||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
public class PluginResult {
|
public class PluginResult {
|
||||||
private final int status;
|
private final int status;
|
||||||
private final int messageType;
|
private final int messageType;
|
||||||
@@ -68,6 +70,12 @@ public class PluginResult {
|
|||||||
this.encodedMessage = Boolean.toString(b);
|
this.encodedMessage = Boolean.toString(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PluginResult(Status status, byte[] data) {
|
||||||
|
this.status = status.ordinal();
|
||||||
|
this.messageType = MESSAGE_TYPE_ARRAYBUFFER;
|
||||||
|
this.encodedMessage = Base64.encodeToString(data, Base64.NO_WRAP);
|
||||||
|
}
|
||||||
|
|
||||||
public void setKeepCallback(boolean b) {
|
public void setKeepCallback(boolean b) {
|
||||||
this.keepCallback = b;
|
this.keepCallback = b;
|
||||||
}
|
}
|
||||||
@@ -79,7 +87,7 @@ public class PluginResult {
|
|||||||
public int getMessageType() {
|
public int getMessageType() {
|
||||||
return messageType;
|
return messageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
if (encodedMessage == null) {
|
if (encodedMessage == null) {
|
||||||
encodedMessage = JSONObject.quote(strMessage);
|
encodedMessage = JSONObject.quote(strMessage);
|
||||||
@@ -134,7 +142,8 @@ public class PluginResult {
|
|||||||
public static final int MESSAGE_TYPE_NUMBER = 3;
|
public static final int MESSAGE_TYPE_NUMBER = 3;
|
||||||
public static final int MESSAGE_TYPE_BOOLEAN = 4;
|
public static final int MESSAGE_TYPE_BOOLEAN = 4;
|
||||||
public static final int MESSAGE_TYPE_NULL = 5;
|
public static final int MESSAGE_TYPE_NULL = 5;
|
||||||
|
public static final int MESSAGE_TYPE_ARRAYBUFFER = 6;
|
||||||
|
|
||||||
public static String[] StatusMessages = new String[] {
|
public static String[] StatusMessages = new String[] {
|
||||||
"No result",
|
"No result",
|
||||||
"OK",
|
"OK",
|
||||||
|
|||||||
@@ -8,5 +8,5 @@
|
|||||||
# project structure.
|
# project structure.
|
||||||
|
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-16
|
target=android-17
|
||||||
android.library.reference.1=../framework
|
android.library.reference.1=../framework
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ public class basicauth extends DroidGap {
|
|||||||
super.setAuthenticationToken(token, "browserspy.dk:80", "BrowserSpy.dk - HTTP Password Test");
|
super.setAuthenticationToken(token, "browserspy.dk:80", "BrowserSpy.dk - HTTP Password Test");
|
||||||
|
|
||||||
// Add web site to whitelist
|
// Add web site to whitelist
|
||||||
super.appView.addWhiteListEntry("http://browserspy.dk*", true);
|
Config.init();
|
||||||
|
Config.addWhiteListEntry("http://browserspy.dk*", true);
|
||||||
|
|
||||||
// Load test
|
// Load test
|
||||||
super.loadUrl("file:///android_asset/www/basicauth/index.html");
|
super.loadUrl("file:///android_asset/www/basicauth/index.html");
|
||||||
|
|||||||
Reference in New Issue
Block a user