mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-26 20:33:07 +08:00
Refactor Config into ConfigXmlParser, CordovaPreferences
Intention here is to be 100% backwards compatible.
This commit is contained in:
parent
f577af0886
commit
3bab41f138
@ -19,181 +19,28 @@
|
|||||||
|
|
||||||
package org.apache.cordova;
|
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.app.Activity;
|
||||||
import android.content.res.XmlResourceParser;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
public class Config {
|
public class Config {
|
||||||
|
private static final String TAG = "Config";
|
||||||
|
|
||||||
public static final String TAG = "Config";
|
private static ConfigXmlParser parser;
|
||||||
|
|
||||||
private Whitelist whitelist = new Whitelist();
|
private Config() {
|
||||||
private String startUrl;
|
}
|
||||||
|
|
||||||
private static String errorUrl;
|
|
||||||
|
|
||||||
private static Config self = null;
|
|
||||||
|
|
||||||
public static void init(Activity action) {
|
public static void init(Activity action) {
|
||||||
//Just re-initialize this! Seriously, we lose this all the time
|
parser = new ConfigXmlParser();
|
||||||
self = new Config(action);
|
parser.parse(action);
|
||||||
|
parser.getPreferences().setPreferencesBundle(action.getIntent().getExtras());
|
||||||
|
parser.getPreferences().copyIntoIntentExtras(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intended to be used for testing only; creates an empty configuration.
|
// Intended to be used for testing only; creates an empty configuration.
|
||||||
public static void init() {
|
public static void init() {
|
||||||
if (self == null) {
|
if (parser == null) {
|
||||||
self = new Config();
|
parser = new ConfigXmlParser();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// First checking the class namespace for config.xml
|
|
||||||
int id = action.getResources().getIdentifier("config", "xml", action.getClass().getPackage().getName());
|
|
||||||
if (id == 0) {
|
|
||||||
// If we couldn't find config.xml there, we'll look in the namespace from AndroidManifest.xml
|
|
||||||
id = action.getResources().getIdentifier("config", "xml", action.getPackageName());
|
|
||||||
if (id == 0) {
|
|
||||||
LOG.i("CordovaLog", "config.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> tag 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.getClass().getPackage().getName());
|
|
||||||
|
|
||||||
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 if(name.equalsIgnoreCase("errorurl"))
|
|
||||||
{
|
|
||||||
errorUrl = xml.getAttributeValue(null, "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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,11 +51,11 @@ public class Config {
|
|||||||
* @param subdomains T=include all subdomains under origin
|
* @param subdomains T=include all subdomains under origin
|
||||||
*/
|
*/
|
||||||
public static void addWhiteListEntry(String origin, boolean subdomains) {
|
public static void addWhiteListEntry(String origin, boolean subdomains) {
|
||||||
if (self == null) {
|
if (parser == null) {
|
||||||
Log.e(TAG, "Config was not initialised. Did you forget to Config.init(this)?");
|
Log.e(TAG, "Config was not initialised. Did you forget to Config.init(this)?");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.whitelist.addWhiteListEntry(origin, subdomains);
|
parser.getWhitelist().addWhiteListEntry(origin, subdomains);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -218,21 +65,21 @@ public class Config {
|
|||||||
* @return true if whitelisted
|
* @return true if whitelisted
|
||||||
*/
|
*/
|
||||||
public static boolean isUrlWhiteListed(String url) {
|
public static boolean isUrlWhiteListed(String url) {
|
||||||
if (self == null) {
|
if (parser == null) {
|
||||||
Log.e(TAG, "Config was not initialised. Did you forget to Config.init(this)?");
|
Log.e(TAG, "Config was not initialised. Did you forget to Config.init(this)?");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return self.whitelist.isUrlWhiteListed(url);
|
return parser.getWhitelist().isUrlWhiteListed(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getStartUrl() {
|
public static String getStartUrl() {
|
||||||
if (self == null || self.startUrl == null) {
|
if (parser == null) {
|
||||||
return "file:///android_asset/www/index.html";
|
return "file:///android_asset/www/index.html";
|
||||||
}
|
}
|
||||||
return self.startUrl;
|
return parser.getLaunchUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getErrorUrl() {
|
public static String getErrorUrl() {
|
||||||
return errorUrl;
|
return parser.getPreferences().getString("errorurl", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
163
framework/src/org/apache/cordova/ConfigXmlParser.java
Normal file
163
framework/src/org/apache/cordova/ConfigXmlParser.java
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
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.List;
|
||||||
|
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.util.Log;
|
||||||
|
|
||||||
|
public class ConfigXmlParser {
|
||||||
|
private static String TAG = "ConfigXmlParser";
|
||||||
|
|
||||||
|
private String launchUrl = "file:///android_asset/www/index.html";
|
||||||
|
private CordovaPreferences prefs = new CordovaPreferences();
|
||||||
|
private Whitelist whitelist = new Whitelist();
|
||||||
|
private ArrayList<PluginEntry> pluginEntries = new ArrayList<PluginEntry>(20);
|
||||||
|
private HashMap<String, List<String>> urlMap = new HashMap<String, List<String>>();
|
||||||
|
|
||||||
|
public Whitelist getWhitelist() {
|
||||||
|
return whitelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CordovaPreferences getPreferences() {
|
||||||
|
return prefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<PluginEntry> getPluginEntries() {
|
||||||
|
return pluginEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLaunchUrl() {
|
||||||
|
return launchUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<String, List<String>> getPluginUrlMap() {
|
||||||
|
return urlMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void parse(Activity action) {
|
||||||
|
// First checking the class namespace for config.xml
|
||||||
|
int id = action.getResources().getIdentifier("config", "xml", action.getClass().getPackage().getName());
|
||||||
|
if (id == 0) {
|
||||||
|
// If we couldn't find config.xml there, we'll look in the namespace from AndroidManifest.xml
|
||||||
|
id = action.getResources().getIdentifier("config", "xml", action.getPackageName());
|
||||||
|
if (id == 0) {
|
||||||
|
LOG.e(TAG, "res/xml/config.xml is missing!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parse(action.getResources().getXml(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void parse(XmlResourceParser xml) {
|
||||||
|
int eventType = -1;
|
||||||
|
String service = "", pluginClass = "", paramType = "";
|
||||||
|
boolean onload = false;
|
||||||
|
boolean insideFeature = false;
|
||||||
|
while (eventType != XmlResourceParser.END_DOCUMENT) {
|
||||||
|
if (eventType == XmlResourceParser.START_TAG) {
|
||||||
|
String strNode = xml.getName();
|
||||||
|
if (strNode.equals("url-filter")) {
|
||||||
|
Log.w(TAG, "Plugin " + service + " is using deprecated tag <url-filter>");
|
||||||
|
if (urlMap.get(service) == null) {
|
||||||
|
urlMap.put(service, new ArrayList<String>(2));
|
||||||
|
}
|
||||||
|
List<String> filters = urlMap.get(service);
|
||||||
|
filters.add(xml.getAttributeValue(null, "value"));
|
||||||
|
} else if (strNode.equals("feature")) {
|
||||||
|
//Check for supported feature sets aka. plugins (Accelerometer, Geolocation, etc)
|
||||||
|
//Set the bit for reading params
|
||||||
|
insideFeature = true;
|
||||||
|
service = xml.getAttributeValue(null, "name");
|
||||||
|
}
|
||||||
|
else if (insideFeature && strNode.equals("param")) {
|
||||||
|
paramType = xml.getAttributeValue(null, "name");
|
||||||
|
if (paramType.equals("service")) // check if it is using the older service param
|
||||||
|
service = xml.getAttributeValue(null, "value");
|
||||||
|
else if (paramType.equals("package") || paramType.equals("android-package"))
|
||||||
|
pluginClass = xml.getAttributeValue(null,"value");
|
||||||
|
else if (paramType.equals("onload"))
|
||||||
|
onload = "true".equals(xml.getAttributeValue(null, "value"));
|
||||||
|
}
|
||||||
|
else if (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("preference")) {
|
||||||
|
String name = xml.getAttributeValue(null, "name").toLowerCase(Locale.ENGLISH);
|
||||||
|
String value = xml.getAttributeValue(null, "value");
|
||||||
|
prefs.set(name, value);
|
||||||
|
}
|
||||||
|
else if (strNode.equals("content")) {
|
||||||
|
String src = xml.getAttributeValue(null, "src");
|
||||||
|
if (src != null) {
|
||||||
|
setStartUrl(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventType == XmlResourceParser.END_TAG)
|
||||||
|
{
|
||||||
|
String strNode = xml.getName();
|
||||||
|
if (strNode.equals("feature")) {
|
||||||
|
pluginEntries.add(new PluginEntry(service, pluginClass, onload));
|
||||||
|
|
||||||
|
service = "";
|
||||||
|
pluginClass = "";
|
||||||
|
insideFeature = false;
|
||||||
|
onload = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
eventType = xml.next();
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setStartUrl(String src) {
|
||||||
|
Pattern schemeRegex = Pattern.compile("^[a-z-]+://");
|
||||||
|
Matcher matcher = schemeRegex.matcher(src);
|
||||||
|
if (matcher.find()) {
|
||||||
|
launchUrl = src;
|
||||||
|
} else {
|
||||||
|
if (src.charAt(0) == '/') {
|
||||||
|
src = src.substring(1);
|
||||||
|
}
|
||||||
|
launchUrl = "file:///android_asset/www/" + src;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
158
framework/src/org/apache/cordova/CordovaPreferences.java
Normal file
158
framework/src/org/apache/cordova/CordovaPreferences.java
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
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.Map;
|
||||||
|
|
||||||
|
import org.apache.cordova.LOG;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
public class CordovaPreferences {
|
||||||
|
private HashMap<String, String> prefs = new HashMap<String, String>(20);
|
||||||
|
private Bundle preferencesBundleExtras;
|
||||||
|
|
||||||
|
public void setPreferencesBundle(Bundle extras) {
|
||||||
|
preferencesBundleExtras = extras;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(String name, String value) {
|
||||||
|
prefs.put(name.toLowerCase(Locale.ENGLISH), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getAll() {
|
||||||
|
return prefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getBoolean(String name, boolean defaultValue) {
|
||||||
|
name = name.toLowerCase(Locale.ENGLISH);
|
||||||
|
String value = prefs.get(name);
|
||||||
|
if (value != null) {
|
||||||
|
return "true".equals(value);
|
||||||
|
} else if (preferencesBundleExtras != null) {
|
||||||
|
Object bundleValue = preferencesBundleExtras.get(name);
|
||||||
|
if (bundleValue instanceof String) {
|
||||||
|
return "true".equals(bundleValue);
|
||||||
|
}
|
||||||
|
// Gives a nice warning if type is wrong.
|
||||||
|
return preferencesBundleExtras.getBoolean(name, defaultValue);
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInteger(String name, int defaultValue) {
|
||||||
|
name = name.toLowerCase(Locale.ENGLISH);
|
||||||
|
String value = prefs.get(name);
|
||||||
|
if (value != null) {
|
||||||
|
return Integer.valueOf(value);
|
||||||
|
} else if (preferencesBundleExtras != null) {
|
||||||
|
Object bundleValue = preferencesBundleExtras.get(name);
|
||||||
|
if (bundleValue instanceof String) {
|
||||||
|
return Integer.valueOf((String)bundleValue);
|
||||||
|
}
|
||||||
|
// Gives a nice warning if type is wrong.
|
||||||
|
return preferencesBundleExtras.getInt(name, defaultValue);
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDouble(String name, double defaultValue) {
|
||||||
|
name = name.toLowerCase(Locale.ENGLISH);
|
||||||
|
String value = prefs.get(name);
|
||||||
|
if (value != null) {
|
||||||
|
return Double.valueOf(value);
|
||||||
|
} else if (preferencesBundleExtras != null) {
|
||||||
|
Object bundleValue = preferencesBundleExtras.get(name);
|
||||||
|
if (bundleValue instanceof String) {
|
||||||
|
return Double.valueOf((String)bundleValue);
|
||||||
|
}
|
||||||
|
// Gives a nice warning if type is wrong.
|
||||||
|
return preferencesBundleExtras.getDouble(name, defaultValue);
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getString(String name, String defaultValue) {
|
||||||
|
name = name.toLowerCase(Locale.ENGLISH);
|
||||||
|
String value = prefs.get(name);
|
||||||
|
if (value != null) {
|
||||||
|
return value;
|
||||||
|
} else if (preferencesBundleExtras != null && !"errorurl".equals(name)) {
|
||||||
|
Object bundleValue = preferencesBundleExtras.get(name);
|
||||||
|
if (bundleValue != null) {
|
||||||
|
return bundleValue.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plugins should not rely on values within the intent since this does not work
|
||||||
|
// for apps with multiple webviews. Instead, they should retrieve prefs from the
|
||||||
|
// Config object associated with their webview.
|
||||||
|
public void copyIntoIntentExtras(Activity action) {
|
||||||
|
for (String name : prefs.keySet()) {
|
||||||
|
String value = prefs.get(name);
|
||||||
|
if (value == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (name.equals("loglevel")) {
|
||||||
|
LOG.setLogLevel(value);
|
||||||
|
} else if (name.equals("splashscreen")) {
|
||||||
|
// Note: We should probably pass in the classname for the variable splash on splashscreen!
|
||||||
|
int resource = action.getResources().getIdentifier(value, "drawable", action.getClass().getPackage().getName());
|
||||||
|
action.getIntent().putExtra(name, resource);
|
||||||
|
}
|
||||||
|
else if(name.equals("backgroundcolor")) {
|
||||||
|
int asInt = Integer.valueOf(value);
|
||||||
|
action.getIntent().putExtra(name, asInt);
|
||||||
|
}
|
||||||
|
else if(name.equals("loadurltimeoutvalue")) {
|
||||||
|
int asInt = Integer.valueOf(value);
|
||||||
|
action.getIntent().putExtra(name, asInt);
|
||||||
|
}
|
||||||
|
else if(name.equals("splashscreendelay")) {
|
||||||
|
int asInt = Integer.valueOf(value);
|
||||||
|
action.getIntent().putExtra(name, asInt);
|
||||||
|
}
|
||||||
|
else if(name.equals("keeprunning"))
|
||||||
|
{
|
||||||
|
boolean asBool = "true".equals(value);
|
||||||
|
action.getIntent().putExtra(name, asBool);
|
||||||
|
}
|
||||||
|
else if(name.equals("inappbrowserstorageenabled"))
|
||||||
|
{
|
||||||
|
boolean asBool = "true".equals(value);
|
||||||
|
action.getIntent().putExtra(name, asBool);
|
||||||
|
}
|
||||||
|
else if(name.equals("disallowoverscroll"))
|
||||||
|
{
|
||||||
|
boolean asBool = "true".equals(value);
|
||||||
|
action.getIntent().putExtra(name, asBool);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
action.getIntent().putExtra(name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,8 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -31,11 +29,8 @@ import org.apache.cordova.CordovaPlugin;
|
|||||||
import org.apache.cordova.PluginEntry;
|
import org.apache.cordova.PluginEntry;
|
||||||
import org.apache.cordova.PluginResult;
|
import org.apache.cordova.PluginResult;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.XmlResourceParser;
|
|
||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Debug;
|
import android.os.Debug;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -56,23 +51,13 @@ public class PluginManager {
|
|||||||
private final CordovaInterface ctx;
|
private final CordovaInterface ctx;
|
||||||
private final CordovaWebView app;
|
private final CordovaWebView app;
|
||||||
|
|
||||||
// Flag to track first time through
|
|
||||||
private boolean firstRun;
|
|
||||||
|
|
||||||
// Stores mapping of Plugin Name -> <url-filter> values.
|
// Stores mapping of Plugin Name -> <url-filter> values.
|
||||||
// Using <url-filter> is deprecated.
|
// Using <url-filter> is deprecated.
|
||||||
protected HashMap<String, List<String>> urlMap = new HashMap<String, List<String>>();
|
protected HashMap<String, List<String>> urlMap;
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param app
|
|
||||||
* @param ctx
|
|
||||||
*/
|
|
||||||
public PluginManager(CordovaWebView app, CordovaInterface ctx) {
|
public PluginManager(CordovaWebView app, CordovaInterface ctx) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.firstRun = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,9 +67,8 @@ public class PluginManager {
|
|||||||
LOG.d(TAG, "init()");
|
LOG.d(TAG, "init()");
|
||||||
|
|
||||||
// If first time, then load plugins from config.xml file
|
// If first time, then load plugins from config.xml file
|
||||||
if (this.firstRun) {
|
if (urlMap == null) {
|
||||||
this.loadPlugins();
|
this.loadPlugins();
|
||||||
this.firstRun = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop plugins on current HTML page and discard plugin objects
|
// Stop plugins on current HTML page and discard plugin objects
|
||||||
@ -102,72 +86,12 @@ public class PluginManager {
|
|||||||
* Load plugins from res/xml/config.xml
|
* Load plugins from res/xml/config.xml
|
||||||
*/
|
*/
|
||||||
public void loadPlugins() {
|
public void loadPlugins() {
|
||||||
// First checking the class namespace for config.xml
|
ConfigXmlParser parser = new ConfigXmlParser();
|
||||||
int id = this.ctx.getActivity().getResources().getIdentifier("config", "xml", this.ctx.getActivity().getClass().getPackage().getName());
|
parser.parse(ctx.getActivity());
|
||||||
if (id == 0) {
|
for (PluginEntry entry : parser.getPluginEntries()) {
|
||||||
// If we couldn't find config.xml there, we'll look in the namespace from AndroidManifest.xml
|
addService(entry);
|
||||||
id = this.ctx.getActivity().getResources().getIdentifier("config", "xml", this.ctx.getActivity().getPackageName());
|
|
||||||
if (id == 0) {
|
|
||||||
this.pluginConfigurationMissing();
|
|
||||||
//We have the error, we need to exit without crashing!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
XmlResourceParser xml = this.ctx.getActivity().getResources().getXml(id);
|
|
||||||
int eventType = -1;
|
|
||||||
String service = "", pluginClass = "", paramType = "";
|
|
||||||
boolean onload = false;
|
|
||||||
boolean insideFeature = false;
|
|
||||||
while (eventType != XmlResourceParser.END_DOCUMENT) {
|
|
||||||
if (eventType == XmlResourceParser.START_TAG) {
|
|
||||||
String strNode = xml.getName();
|
|
||||||
if (strNode.equals("url-filter")) {
|
|
||||||
Log.w(TAG, "Plugin " + service + " is using deprecated tag <url-filter>");
|
|
||||||
if (urlMap.get(service) == null) {
|
|
||||||
urlMap.put(service, new ArrayList<String>(2));
|
|
||||||
}
|
|
||||||
List<String> filters = urlMap.get(service);
|
|
||||||
filters.add(xml.getAttributeValue(null, "value"));
|
|
||||||
}
|
|
||||||
else if (strNode.equals("feature")) {
|
|
||||||
//Check for supported feature sets aka. plugins (Accelerometer, Geolocation, etc)
|
|
||||||
//Set the bit for reading params
|
|
||||||
insideFeature = true;
|
|
||||||
service = xml.getAttributeValue(null, "name");
|
|
||||||
}
|
|
||||||
else if (insideFeature && strNode.equals("param")) {
|
|
||||||
paramType = xml.getAttributeValue(null, "name");
|
|
||||||
if (paramType.equals("service")) // check if it is using the older service param
|
|
||||||
service = xml.getAttributeValue(null, "value");
|
|
||||||
else if (paramType.equals("package") || paramType.equals("android-package"))
|
|
||||||
pluginClass = xml.getAttributeValue(null,"value");
|
|
||||||
else if (paramType.equals("onload"))
|
|
||||||
onload = "true".equals(xml.getAttributeValue(null, "value"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (eventType == XmlResourceParser.END_TAG)
|
|
||||||
{
|
|
||||||
String strNode = xml.getName();
|
|
||||||
if (strNode.equals("feature") || strNode.equals("plugin"))
|
|
||||||
{
|
|
||||||
PluginEntry entry = new PluginEntry(service, pluginClass, onload);
|
|
||||||
this.addService(entry);
|
|
||||||
|
|
||||||
//Empty the strings to prevent plugin loading bugs
|
|
||||||
service = "";
|
|
||||||
pluginClass = "";
|
|
||||||
insideFeature = false;
|
|
||||||
onload = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
eventType = xml.next();
|
|
||||||
} catch (XmlPullParserException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
urlMap = parser.getPluginUrlMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -396,14 +320,6 @@ public class PluginManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void pluginConfigurationMissing() {
|
|
||||||
LOG.e(TAG, "=====================================================================================");
|
|
||||||
LOG.e(TAG, "ERROR: config.xml is missing. Add res/xml/config.xml to your project.");
|
|
||||||
LOG.e(TAG, "https://git-wip-us.apache.org/repos/asf?p=cordova-android.git;a=blob;f=framework/res/xml/config.xml");
|
|
||||||
LOG.e(TAG, "=====================================================================================");
|
|
||||||
}
|
|
||||||
|
|
||||||
Uri remapUri(Uri uri) {
|
Uri remapUri(Uri uri) {
|
||||||
for (PluginEntry entry : this.entries.values()) {
|
for (PluginEntry entry : this.entries.values()) {
|
||||||
if (entry.plugin != null) {
|
if (entry.plugin != null) {
|
||||||
|
@ -98,6 +98,10 @@ public class Whitelist {
|
|||||||
|
|
||||||
public Whitelist() {
|
public Whitelist() {
|
||||||
this.whiteList = new ArrayList<URLPattern>();
|
this.whiteList = new ArrayList<URLPattern>();
|
||||||
|
// Add implicitly allowed URLs
|
||||||
|
addWhiteListEntry("file:///*", false);
|
||||||
|
addWhiteListEntry("content:///*", false);
|
||||||
|
addWhiteListEntry("data:*", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Match patterns (from http://developer.chrome.com/extensions/match_patterns.html)
|
/* Match patterns (from http://developer.chrome.com/extensions/match_patterns.html)
|
||||||
|
Loading…
Reference in New Issue
Block a user