mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-22 00:32:55 +08:00
Merge branch 'master' into 4.0.x (ConfigXmlParser breakout)
Conflicts: framework/src/org/apache/cordova/CordovaActivity.java framework/src/org/apache/cordova/PluginManager.java
This commit is contained in:
commit
bdf2f22f81
@ -2,8 +2,8 @@
|
||||
<classpath>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
|
@ -19,184 +19,31 @@
|
||||
|
||||
package org.apache.cordova;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.cordova.LOG;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.graphics.Color;
|
||||
import android.util.Log;
|
||||
|
||||
public class Config {
|
||||
private static final String TAG = "Config";
|
||||
|
||||
public static final String TAG = "Config";
|
||||
private static ConfigXmlParser parser;
|
||||
|
||||
private Whitelist whitelist = new Whitelist();
|
||||
private String startUrl;
|
||||
|
||||
private static String errorUrl;
|
||||
|
||||
private static Config self = null;
|
||||
private Config() {
|
||||
}
|
||||
|
||||
public static void init(Activity action) {
|
||||
//Just re-initialize this! Seriously, we lose this all the time
|
||||
self = new Config(action);
|
||||
parser = new ConfigXmlParser();
|
||||
parser.parse(action);
|
||||
parser.getPreferences().setPreferencesBundle(action.getIntent().getExtras());
|
||||
parser.getPreferences().copyIntoIntentExtras(action);
|
||||
}
|
||||
|
||||
// Intended to be used for testing only; creates an empty configuration.
|
||||
public static void init() {
|
||||
if (self == null) {
|
||||
self = new Config();
|
||||
if (parser == null) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add entry to approved list of URLs (whitelist)
|
||||
*
|
||||
@ -204,11 +51,11 @@ public class Config {
|
||||
* @param subdomains T=include all subdomains under origin
|
||||
*/
|
||||
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)?");
|
||||
return;
|
||||
}
|
||||
self.whitelist.addWhiteListEntry(origin, subdomains);
|
||||
parser.getWhitelist().addWhiteListEntry(origin, subdomains);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -218,21 +65,21 @@ public class Config {
|
||||
* @return true if whitelisted
|
||||
*/
|
||||
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)?");
|
||||
return false;
|
||||
}
|
||||
return self.whitelist.isUrlWhiteListed(url);
|
||||
return parser.getWhitelist().isUrlWhiteListed(url);
|
||||
}
|
||||
|
||||
public static String getStartUrl() {
|
||||
if (self == null || self.startUrl == null) {
|
||||
if (parser == null) {
|
||||
return "file:///android_asset/www/index.html";
|
||||
}
|
||||
return self.startUrl;
|
||||
return parser.getLaunchUrl();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -39,7 +39,6 @@ import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
@ -54,7 +53,6 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.webkit.ValueCallback;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.LinearLayout;
|
||||
@ -98,15 +96,9 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
protected CordovaWebViewClient webViewClient;
|
||||
|
||||
protected LinearLayout root;
|
||||
protected boolean cancelLoadUrl = false;
|
||||
protected ProgressDialog spinnerDialog = null;
|
||||
private final ExecutorService threadPool = Executors.newCachedThreadPool();
|
||||
|
||||
|
||||
// The initial URL for our app
|
||||
// ie http://server/path/index.html#abc?query
|
||||
//private String url = null;
|
||||
|
||||
private static int ACTIVITY_STARTING = 0;
|
||||
private static int ACTIVITY_RUNNING = 1;
|
||||
private static int ACTIVITY_EXITING = 2;
|
||||
@ -137,29 +129,16 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
// when another application (activity) is started.
|
||||
protected boolean keepRunning = true;
|
||||
|
||||
private int lastRequestCode;
|
||||
|
||||
private Object responseCode;
|
||||
|
||||
private Intent lastIntent;
|
||||
|
||||
private Object lastResponseCode;
|
||||
|
||||
private String initCallbackClass;
|
||||
|
||||
private Object LOG_TAG;
|
||||
|
||||
|
||||
/**
|
||||
* Called when the activity is first created.
|
||||
*
|
||||
* @param savedInstanceState
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
Config.init(this);
|
||||
LOG.i(TAG, "Apache Cordova native platform version " + appView.CORDOVA_VERSION + " is starting");
|
||||
LOG.i(TAG, "Apache Cordova native platform version " + CordovaWebView.CORDOVA_VERSION + " is starting");
|
||||
LOG.d(TAG, "CordovaActivity.onCreate()");
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
@ -316,16 +295,10 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
this.appView.setVisibility(View.INVISIBLE);
|
||||
this.root.addView((View) this.appView.getView());
|
||||
setContentView(this.root);
|
||||
|
||||
// Clear cancel flag
|
||||
this.cancelLoadUrl = false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the url into the webview.
|
||||
*
|
||||
* @param url
|
||||
*/
|
||||
public void loadUrl(String url) {
|
||||
|
||||
@ -380,7 +353,6 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
|
||||
this.splashscreenTime = time;
|
||||
this.loadUrl(url);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -416,7 +388,6 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear the resource cache.
|
||||
*/
|
||||
@ -446,17 +417,6 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Called by the system when the device configuration changes while your activity is running.
|
||||
*
|
||||
* @param Configuration newConfig
|
||||
*/
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
//don't reload the current page when the orientation is changed
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get boolean property for activity.
|
||||
*
|
||||
@ -558,10 +518,10 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
return p.doubleValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Called when the system is about to start resuming a previous activity.
|
||||
*/
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
@ -584,10 +544,10 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
this.removeSplashScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Called when the activity receives a new intent
|
||||
**/
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
//Forward to plugins
|
||||
@ -595,22 +555,16 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
this.appView.onNewIntent(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Called when the activity will start interacting with the user.
|
||||
*/
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
LOG.d(TAG, "Resuming the App");
|
||||
//Reload the configuration
|
||||
Config.init(this);
|
||||
|
||||
LOG.d(TAG, "Resuming the App");
|
||||
|
||||
|
||||
//Code to test CB-3064
|
||||
String errorUrl = Config.getErrorUrl();
|
||||
LOG.d(TAG, "CB-3064: The errorUrl is " + errorUrl);
|
||||
|
||||
if (this.activityState == ACTIVITY_STARTING) {
|
||||
this.activityState = ACTIVITY_RUNNING;
|
||||
return;
|
||||
@ -633,10 +587,10 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* The final call you receive before your activity is destroyed.
|
||||
*/
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
LOG.d(TAG, "CordovaActivity.onDestroy()");
|
||||
super.onDestroy();
|
||||
@ -654,9 +608,6 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
|
||||
/**
|
||||
* Send a message to all plugins.
|
||||
*
|
||||
* @param id The message id
|
||||
* @param data The message data
|
||||
*/
|
||||
public void postMessage(String id, Object data) {
|
||||
if (this.appView != null) {
|
||||
@ -664,7 +615,6 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send JavaScript statement back to JavaScript.
|
||||
* (This is a convenience method)
|
||||
@ -739,7 +689,6 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
super.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Called when an activity you launched exits, giving you the requestCode you started it with,
|
||||
* the resultCode it returned, and any additional data from it.
|
||||
@ -749,6 +698,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
* @param resultCode The integer result code returned by the child activity through its setResult().
|
||||
* @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
|
||||
*/
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
LOG.d(TAG, "Incoming Result");
|
||||
super.onActivityResult(requestCode, resultCode, intent);
|
||||
@ -760,8 +710,6 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
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;
|
||||
}
|
||||
@ -823,11 +771,6 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
|
||||
/**
|
||||
* Display an error dialog and optionally exit application.
|
||||
*
|
||||
* @param title
|
||||
* @param message
|
||||
* @param button
|
||||
* @param exit
|
||||
*/
|
||||
public void displayError(final String title, final String message, final String button, final boolean exit) {
|
||||
final CordovaActivity me = this;
|
||||
@ -858,9 +801,6 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
|
||||
/**
|
||||
* Determine if URL is in approved list of URLs to load.
|
||||
*
|
||||
* @param url
|
||||
* @return true if the url is whitelisted
|
||||
*/
|
||||
public boolean isUrlWhiteListed(String url) {
|
||||
return Config.isUrlWhiteListed(url);
|
||||
@ -868,7 +808,6 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
|
||||
/*
|
||||
* Hook in Cordova for menu plugins
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
@ -890,9 +829,6 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
||||
|
||||
/**
|
||||
* Get Activity context.
|
||||
*
|
||||
* @return self
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public Context getContext() {
|
||||
|
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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -32,10 +30,8 @@ import org.apache.cordova.CordovaPlugin;
|
||||
import org.apache.cordova.PluginEntry;
|
||||
import org.apache.cordova.PluginResult;
|
||||
import org.json.JSONException;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.net.Uri;
|
||||
import android.os.Debug;
|
||||
import android.util.Log;
|
||||
@ -56,25 +52,15 @@ public class PluginManager {
|
||||
private final CordovaInterface ctx;
|
||||
private final CordovaWebView app;
|
||||
|
||||
// Flag to track first time through
|
||||
private boolean firstRun;
|
||||
|
||||
// Stores mapping of Plugin Name -> <url-filter> values.
|
||||
// Using <url-filter> is deprecated.
|
||||
protected HashMap<String, List<String>> urlMap = new HashMap<String, List<String>>();
|
||||
protected HashMap<String, List<String>> urlMap;
|
||||
|
||||
private Set<String> pluginIdWhitelist;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param app
|
||||
* @param ctx
|
||||
*/
|
||||
public PluginManager(CordovaWebView app, CordovaInterface ctx) {
|
||||
this.ctx = ctx;
|
||||
this.app = app;
|
||||
this.firstRun = true;
|
||||
}
|
||||
|
||||
public void setPluginIdWhitelist(Set<String> pluginIdWhitelist) {
|
||||
@ -88,9 +74,8 @@ public class PluginManager {
|
||||
LOG.d(TAG, "init()");
|
||||
|
||||
// If first time, then load plugins from config.xml file
|
||||
if (this.firstRun) {
|
||||
if (urlMap == null) {
|
||||
this.loadPlugins();
|
||||
this.firstRun = false;
|
||||
}
|
||||
|
||||
// Stop plugins on current HTML page and discard plugin objects
|
||||
@ -108,72 +93,12 @@ public class PluginManager {
|
||||
* Load plugins from res/xml/config.xml
|
||||
*/
|
||||
public void loadPlugins() {
|
||||
// First checking the class namespace for config.xml
|
||||
int id = this.ctx.getActivity().getResources().getIdentifier("config", "xml", this.ctx.getActivity().getClass().getPackage().getName());
|
||||
if (id == 0) {
|
||||
// If we couldn't find config.xml there, we'll look in the namespace from AndroidManifest.xml
|
||||
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();
|
||||
}
|
||||
}
|
||||
ConfigXmlParser parser = new ConfigXmlParser();
|
||||
parser.parse(ctx.getActivity());
|
||||
for (PluginEntry entry : parser.getPluginEntries()) {
|
||||
addService(entry);
|
||||
}
|
||||
urlMap = parser.getPluginUrlMap();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -408,14 +333,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) {
|
||||
for (PluginEntry entry : this.entries.values()) {
|
||||
if (entry.plugin != null) {
|
||||
|
@ -98,6 +98,10 @@ public class Whitelist {
|
||||
|
||||
public Whitelist() {
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user